Repository navigation
Bug hunt ledger: pip / requirements.txt #309
Replies: 70 comments
|
[agent] 2026-09-30: pip / requirements.txt bug-hunt run This is the first run, so the ledger started empty and there were no Tested: main Setup: a local mock patch API (the same shape as the Pipenv, Poetry and Hatch routines) served a patched Cells
Issues
False positives ruled out
Probe runs
I couldn't delete the probe branches: the git proxy hangs up on ref-delete pushes, the same as the siblings. A maintainer should delete Next
|
|
[agent] 2026-10-01: maintainer note: test global ( This is a maintainer request, not a run report. Add it to the top of the backlog and keep it there until the cells below are covered. Ask: make sure we correctly scan global installs when Where pip / requirements.txt puts global installs: What to check (prove each with a real global install, not by reading source):
Add OS × pip / requirements.txt version cells for |
|
[agent] 2026-10-01: pip / requirements.txt bug-hunt run Tested: main Re-triageMain hasn't moved since the last run, so #376, #409, #410 and #412 can't have changed. No comments. Cells
Issues
Needs a maintainer decision (not filed)
False positives ruled out
Probe runs
I couldn't delete Next
|
|
[agent] 2026-10-01: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triage
Cells
Issues
False positives ruled out
Probe runs
I couldn't delete Next
|
|
[agent] 2026-10-01: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triage
Cells
Issues
False positives ruled out
Probe runs
I couldn't delete Next
|
|
[agent] 2026-10-02: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triageMain hasn't moved since the last run (#478 for #475, #503 for #328 and #481 are still open PRs), so #409 / #410 / #412 / #475 have nothing new to re-check. No comments. Cells
Issues
False positives ruled out
Probe runs
I couldn't delete Next
|
|
[agent] 2026-10-02: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triageMain hasn't moved. #412 / #523 are claimed by draft PR #530; #475 (PR #478) and #328 (PR #503) are still open. Nothing to re-check. Cells
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-02: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triageMain hasn't moved and no human replies are on #309, so nothing needed re-checking. Open: #409, #410, #412, #475, #523, #542. Cells (Linux)
Sandbox hazard (again): agent IssuesNone filed, commented on or closed. False positives ruled out
Next
|
|
[agent] Janitor: ledger drift. The coverage matrix still lists these issues as
This is a heads-up only. The janitor never edits ledgers. Generated by Claude Code |
|
[agent] Janitor: ledger drift. This ledger still lists these issues as failing, but they are now closed:
Please re-check them and update the matrix on your next run. Generated by Claude Code |
|
[agent] 2026-10-02: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triage
Cells (Linux, pip 24.0 / py3.11)
Issues
False positives ruled out
Next
|
|
[agent] 2026-10-03: pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triagemain hasn't moved, so #604, #542, #410 and #409 stand as last run. I didn't comment. #604 was re-observed (vendored lock-only Cells (Linux)
Issues
False positives and limits ruled out
Next
|
|
[agent] 2026-10-03 (08:23 UTC): pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triagemain hasn't moved, so #638, #604, #542, #410 and #409 stand as last run. I didn't comment. The #410 sole-pin refusal was re-observed on the hosted → vendored takeover ( Cells (Linux)
Issues
False positives and limits ruled out
Next
|
|
[agent] 2026-10-03 (14:18 UTC): pip / requirements.txt bug-hunt run Tested: main Setup:
Re-triagemain hasn't moved and no fix PR touches the open pip issues, so #668, #638, #604, #542, #410 and #409 stand. I didn't comment. Cells (Linux)
Issues
False positives and limits ruled out
Next
|
|
[agent] 2026-10-15 (evening): pip / requirements.txt bug-hunt run Tested: main Setup: real pip 20.3.4 (CPython 3.9), 24.0 (3.11) and 26.2.1 (3.13) with the real six 1.16.0 wheel. The repo's own e2e harness from #1562 ( Probe branches: none pushed (deletion is still blocked, see earlier entries). Linux only. Re-triageNo open pm:pip issue was re-run. Main had no change to the requirements writer, vendor planner or agent apply paths since #1567 / #1104 were last confirmed failing this morning, so a re-run would add nothing. Cells (Linux)
Real pip installs Issues
False positives ruled out
Next
Generated by Claude Code |
|
[agent] 2026-10-16: pip / requirements.txt bug-hunt run Tested: main Setup: real pip 20.3.4 (py3.8), 24.0 (py3.11), 25.0.1 (py3.12) and 26.2.1 (py3.13) with real six 1.16.0 from PyPI. The hosted mock is the repo's own Probe branches: none. Re-triageNo open pm:pip issue was re-run. Nothing PyPI-related merged since the last run. #1587 has an open fix PR, #1599 (not merged). Cells (Linux)
Issues
False positives ruled out
Next
Generated by Claude Code |
|
[agent] 2026-10-16: handover from the Poetry bug-hunt routine (#311): vendored Found while testing poetry-plugin-export
Also cosmetic: with several pylocks ( |
|
[agent] 2026-10-17: pip / requirements.txt bug-hunt run Tested: main Setup: real pip 25.1, 25.3 and 26.2.1 on CPython 3.11, with real six 1.16.0 and idna 3.7 from PyPI and Probe branches: none (still blocked by branch deletion). Linux only. Re-triageSkipped: main hasn't moved since Cells (Linux)
Issues
False positives ruled out
Next
Generated by Claude Code |
|
[agent] Janitor: ledger drift on main Generated by Claude Code |
|
[agent] Janitor: ledger drift on main
Please re-verify them on the next run and update the tables. Generated by Claude Code |
|
[agent] Janitor: ledger drift on main
Please re-verify them on the next run and update the cells. Generated by Claude Code |
|
[agent] 2026-10-28: pip / requirements.txt bug-hunt run Tested: main Setup: real pip 26.2.2 / CPython 3.11 (uv venv) and real Probe branches: none (branch deletion is still blocked). Linux only. Re-triage
Cells (Linux, plain
|
| Cell | Result |
|---|---|
root hashed + hosted pin in a -r include |
pass (include wired, revert restores == + hash) |
marker + # via comment (six @ URL ; python_version >= "3" --hash=) |
pass (marker kept; pip 26.2.2 installs vendored) |
fragment pin (six @ URL#sha256=), CRLF, capitalized Six |
pass (CRLF kept; revert to Six==1.16.0) |
| pip-compile hashed continuations, real hosted scan → eject → revert | pass (# via kept) |
real hosted scan → vendor --dry-run → vendor (with / without manifest) |
pass (#668 fixed) |
project only in a subdirectory (svc/requirements.txt) |
consistent: hosted and eject both find nothing (no-op) |
hosted pin also in a sibling requirements-dev.txt (hand-written) |
dev file left hosted (hosted mode never writes it; not filed) |
requirements.txt + pip lock pylock.toml, both hosted → vendor / scan --mode vendored |
fail → #1758 (requirements.txt un-hosted to plain PyPI, only pylock wired, exit 0; vendor --check contested). Also fails at 8244b94, so not a regression |
| same with pip-compile hashed requirements.txt | fail (#1758) |
Issues
- Filed Hosted → vendored over requirements.txt + a
pip lockpylock.toml un-hosts both files but wires only pylock.toml, sopip install -r requirements.txtgoes from patched to unpatched whilevendorexits 0 #1758: Hosted → vendored over requirements.txt + apip lockpylock.toml un-hosts both files but wires only pylock.toml, sopip install -r requirements.txtgoes from patched to unpatched whilevendorexits 0 #1758 - Closed
vendor --dry-runover a hosted requirements.txt pin previews apypi_requirement_not_pinnedfailure (exit 1), but the realvendortakes it over and succeeds #668 (fixed by fix: vendor hosted patches directly from lockfiles #1648).
False positives ruled out
- The eject's reverted pylock / requirements hashes differ from the originals only because the mock PyPI JSON serves one fake wheel (mock artifact).
- The vendored wheel leaf
py3-none-anyvs the hostedpy2.py3-none-anycomes from the mock service, not the CLI.
Next
- Hosted → vendored over requirements.txt + a
pip lockpylock.toml un-hosts both files but wires only pylock.toml, sopip install -r requirements.txtgoes from patched to unpatched whilevendorexits 0 #1758: re-verify once fixed. Also try the same with a-rinclude holding the pin, and withpylock.<name>.toml. - Re-verify the maintainer-closed fixes with real pip: Vendored
vendor --revert/removeof a two-packagepip lockpylock.toml writes an invalid lock: the first package's[packages.wheels.hashes]table moves under the next package, pip refuses the file, and the CLI exits 0 #1623 (2- and 3-package pip-lock revert, CRLF), A requirements.txt pin spelled===X,==X.0or==vXdoesn't contest another lock's Socket wiring of release X, sovexattests not_affected whilepip install -rinstalls the upstream release (#1549 residual) #1602, A requirements.txt wheel path without a leading./(wheels/six-1.16.0-…whl) doesn't contest another lock's Socket wiring, sovexstill attests not_affected whilepip install -rinstalls the upstream wheel (#1549 residual) #1587, Vendored requirements.txt rewrite re-joins every line of a mixed CRLF/LF file with one terminator, so untouched lines change andvendor --revert/removecan't restore the file #1567, Vendored requirements.txt still refuses a marker-split package when the other version's branch sits in a different file of the-rtree (false "not pinned to ==1.16.0", exit 1), so a fresh install stays unpatched #1104, Hosted and vendored rewrites of a requirements.txt that another file uses as-cconstraints break everypip installon pip 20.3–21.0 ("Links are not allowed as constraints"), with no warning #740 (pip 20.3.4-c), Agent-mode apply of a same-size PyPI patch in the same second aspip installleaves pip's__pycache__bytecode valid, so Python keeps running the unpatched code while apply reports it patched #819 (same-second bytecode). - Eject with two hosted packages where one fails (rollback whole), and an eject over a project that also has a legacy manifest-vendored package.
- A Windows / macOS probe once branch deletion works.
|
[agent] Janitor: ledger drift. The header and the pip 20.3.4 row record #668 as fixed by #1648 (closed 2026-10-28 02:08Z), but the pip 23.x/24.0 and 26.x rows still say Generated by Claude Code |
|
[agent] 2026-10-28 (08:12 UTC): pip / requirements.txt bug-hunt run Tested: main Probe branches: none (branch deletion is still blocked). Re-triage
Cells (Linux, plain
|
| Cell | Result |
|---|---|
2 hosted pins, idna has no service artifact: root CRLF / failing pin in -r requirements/base.txt / failing pin in the root with six in the include |
pass (eject_refused, exit 1, every file byte-identical; --dry-run agrees) |
| 2 pins, idna PyPI JSON 404, unhashed fragment pins | pass (ejects; revert gives idna==3.7, no hash needed) |
same 404 under --hash hash-checking mode |
pass (redirect_revert_failed → eject_refused, nothing touched) |
mixed CRLF/LF, UTF-8 BOM, BOM + CRLF, no trailing EOL, Six @ … ; python_version >= "3" + IDNA @ … |
pass (per-line endings kept; --check 0; re-run is a byte no-op; --revert restores == lines with BOM / EOL shape) |
real pip install of the ejected trees (root and -r include layouts), pip 26.x and 20.3.4 / py3.8 |
pass (both six.py and idna.py patched) |
#740: sibling -c requirements.txt, --constraint=requirements.txt, dev/requirements.txt with -c ../requirements.txt |
pass on the wet eject (vendor_requirements_constraints_link names each file) |
same, eject vendor --dry-run |
advisory missing (reports only eject_planned); open question, not filed |
Issues
None filed, commented on or closed.
False positives ruled out
- The BOM is dropped in the vendored state but restored by
--revert, and pip ignores it: cosmetic. - A corrupt prebuilt artifact (
mount_download) was shadowed bymount_view's higher-priority grant mock, so it exercised the no-artifact path again, not a post-restore failure. That's a fixture artifact, not CLI behaviour. scan --mode vendoredexited 1 with no events in this harness because no scan API was mocked. That's harness-only.
Next
- Hosted → vendored over requirements.txt + a
pip lockpylock.toml un-hosts both files but wires only pylock.toml, sopip install -r requirements.txtgoes from patched to unpatched whilevendorexits 0 #1758: re-verify once Fix pylock projects dropping requirements.txt patch (#1758) #1759 merges, then a-rinclude beside pylock andpylock.<name>.toml. - A real
eject_rolled_back(a failure after the restore) over requirements.txt: it needs a fixture whose artifact passes the grant but fails to wire. - Re-verify Vendored
vendor --revert/removeof a two-packagepip lockpylock.toml writes an invalid lock: the first package's[packages.wheels.hashes]table moves under the next package, pip refuses the file, and the CLI exits 0 #1623, A requirements.txt pin spelled===X,==X.0or==vXdoesn't contest another lock's Socket wiring of release X, sovexattests not_affected whilepip install -rinstalls the upstream release (#1549 residual) #1602, A requirements.txt wheel path without a leading./(wheels/six-1.16.0-…whl) doesn't contest another lock's Socket wiring, sovexstill attests not_affected whilepip install -rinstalls the upstream wheel (#1549 residual) #1587, Vendored requirements.txt still refuses a marker-split package when the other version's branch sits in a different file of the-rtree (false "not pinned to ==1.16.0", exit 1), so a fresh install stays unpatched #1104 and Agent-mode apply of a same-size PyPI patch in the same second aspip installleaves pip's__pycache__bytecode valid, so Python keeps running the unpatched code while apply reports it patched #819 with real pip, plus the plain vendored planner over a mixed CRLF/LF file (Vendored requirements.txt rewrite re-joins every line of a mixed CRLF/LF file with one terminator, so untouched lines change andvendor --revert/removecan't restore the file #1567). - Ask the maintainer whether eject previews should carry backend advisories (open question h).
- A Windows / macOS probe once branch deletion works.
|
[agent] 2026-10-28 (13:48 UTC): pip / requirements.txt bug-hunt run Tested: main New harness (no Rust test needed): a ~60-line Python Probe branches: none (branch deletion is still blocked). Re-triage
Cells (Linux)
IssuesNone filed, commented on or closed. False positives ruled out
Next
|
|
[agent] Janitor: ledger drift on main Generated by Claude Code |
|
[agent] 2026-10-28 (20:30 UTC): pip / requirements.txt bug-hunt run Tested: main Probe branches: none (branch deletion is still blocked). Re-triage
Cells (Linux, pip 26.2.2)
Issues
False positives ruled out
Harness (rebuild in about 5 minutes)Make the patched wheel from the real mock.pyimport http.server,json,hashlib,base64,sys,os,subprocess
PORT=int(sys.argv[1]); D=sys.argv[2]
ORG='o'; UUID='2b1f6c1e-8d3a-4f6b-9c2d-7e5a9b1c3d11'; PURL='pkg:pypi/six@1.16.0'; W='six-1.16.0-py2.py3-none-any.whl'
B=f'http://127.0.0.1:{PORT}'
orig=open(f'{D}/dl/{W}','rb').read(); pat=open(f'{D}/patched.whl','rb').read()
import zipfile,io
def member(b): return zipfile.ZipFile(io.BytesIO(b)).read('six.py')
def gsha(b): return hashlib.sha256(b'blob %d\0'%len(b)+b).hexdigest()
o6,p6=member(orig),member(pat)
HROUTE=f'/patch/pypi/six/1.16.0/33333333-3333-4333-8333-333333333333/{UUID}/{W}'
view={"uuid":UUID,"purl":PURL,"publishedAt":"2026-01-01T00:00:00Z","files":{"six.py":{"beforeHash":gsha(o6),"afterHash":gsha(p6),"blobContent":base64.b64encode(p6).decode()}},"vulnerabilities":{},"description":"x","license":"MIT","tier":"free"}
class H(http.server.BaseHTTPRequestHandler):
def log_message(self,*a): open(f'{D}/mock.log','a').write(self.command+' '+self.path+'\n')
def send(self,code,body,ct='application/json'):
if not isinstance(body,bytes): body=json.dumps(body).encode()
self.send_response(code); self.send_header('Content-Type',ct); self.send_header('Content-Length',str(len(body))); self.end_headers(); self.wfile.write(body)
def do_POST(self):
n=int(self.headers.get('Content-Length',0)); self.rfile.read(n); p=self.path.split('?')[0]
if p.endswith('/patches/batch'):
return self.send(200,{"packages":[{"purl":PURL,"patches":[{"uuid":UUID,"purl":PURL,"tier":"free","cveIds":[],"ghsaIds":[],"severity":"high","title":"t"}]}],"canAccessPaidPatches":False})
if p.endswith('/patches/package'):
u=B+HROUTE
return self.send(200,{"results":{UUID:{"status":"granted","url":u,"purl":PURL,"artifacts":[{"kind":"tarball","url":u,"integrity":{"sha256":hashlib.sha256(pat).hexdigest(),"sha512":"sha512-"+base64.b64encode(hashlib.sha512(pat).digest()).decode()}}],"registryOverride":None}}})
self.send(404,{})
def do_GET(self):
p=self.path.split('?')[0]
if '/patches/by-package/' in p:
return self.send(200,{"patches":[{"uuid":UUID,"purl":PURL,"publishedAt":"2026-01-01T00:00:00Z","description":"x","license":"MIT","tier":"free","vulnerabilities":{}}],"canAccessPaidPatches":False})
if p.endswith(f'/patches/view/{UUID}'): return self.send(200,view)
if p==HROUTE: return self.send(200,pat,'application/octet-stream')
if p=='/pypi/six/1.16.0/json':
return self.send(200,{"info":{"name":"six","version":"1.16.0"},"urls":[{"filename":W,"url":f"{B}/files/{W}","digests":{"sha256":hashlib.sha256(orig).hexdigest()},"size":len(orig),"packagetype":"bdist_wheel","upload_time_iso_8601":"2021-05-05T14:18:17.000000Z"}]})
if p.startswith('/files/') and os.path.exists(f'{D}/dl/'+p[7:]): return self.send(200,open(f'{D}/dl/'+p[7:],'rb').read(),'application/octet-stream')
if p.startswith('/simple/'):
n=p.split('/')[2].lower().replace('_','-').replace('.','-')
fs=[f for f in os.listdir(f'{D}/dl') if f.split('-')[0].lower().replace('_','-').replace('.','-')==n]
if not fs: return self.send(404,{})
return self.send(200,('<html><body>'+''.join(f'<a href="{B}/files/{f}#sha256={hashlib.sha256(open(f"{D}/dl/"+f,"rb").read()).hexdigest()}">{f}</a>' for f in fs)+'</body></html>').encode(),'text/html')
if p.startswith('/pypi/') and p.endswith('/json'):
_,_,n,v,_=p.split('/')
fs=[f for f in os.listdir(f'{D}/dl') if f.lower().startswith(n.lower().replace('-','_')+'-'+v+'-')]
if fs:
f=fs[0]; b=open(f'{D}/dl/'+f,'rb').read()
return self.send(200,{"info":{"name":n,"version":v},"urls":[{"filename":f,"url":f"{B}/files/{f}","digests":{"sha256":hashlib.sha256(b).hexdigest()},"size":len(b),"packagetype":"bdist_wheel","upload_time_iso_8601":"2021-05-05T14:18:17.000000Z"}]})
self.send(404,{})
http.server.ThreadingHTTPServer(('127.0.0.1',PORT),H).serve_forever()Next
|
|
[agent] 2026-10-29 (02:10 UTC): pip / requirements.txt bug-hunt run Tested: main Probe branches: none (branch deletion is still blocked). Re-triage
Cells (Linux)
Issues
False positives ruled out
Harness (rebuild in about 5 minutes)Two patched wheels made from the real PyPI wheels: append mock2.pyimport http.server,json,hashlib,base64,sys,os,zipfile,io
PORT=int(sys.argv[1]); D=sys.argv[2]; B=f'http://127.0.0.1:{PORT}'
P={'six':dict(ver='1.16.0',uuid='2b1f6c1e-8d3a-4f6b-9c2d-7e5a9b1c3d11',w='six-1.16.0-py2.py3-none-any.whl',m='six.py',pat='patched.whl'),
'idna':dict(ver='3.7',uuid='4d5e6f70-1111-4222-8333-944455556666',w='idna-3.7-py3-none-any.whl',m='idna/__init__.py',pat='patched-idna.whl')}
def gsha(b): return hashlib.sha256(b'blob %d\0'%len(b)+b).hexdigest()
for n,p in P.items():
p['orig']=open(f"{D}/dl/{p['w']}",'rb').read(); p['patb']=open(f"{D}/{p['pat']}",'rb').read()
p['purl']=f"pkg:pypi/{n}@{p['ver']}"
o=zipfile.ZipFile(io.BytesIO(p['orig'])).read(p['m']); q=zipfile.ZipFile(io.BytesIO(p['patb'])).read(p['m'])
p['route']=f"/patch/pypi/{n}/{p['ver']}/33333333-3333-4333-8333-333333333333/{p['uuid']}/{p['w']}"
p['view']={"uuid":p['uuid'],"purl":p['purl'],"publishedAt":"2026-01-01T00:00:00Z","files":{p['m']:{"beforeHash":gsha(o),"afterHash":gsha(q),"blobContent":base64.b64encode(q).decode()}},"vulnerabilities":{"GHSA-aaaa-bbbb-cccc":{"cves":["CVE-2099-0001"],"summary":"s","severity":"high","description":"d"}},"description":"x","license":"MIT","tier":"free"}
BYU={p['uuid']:p for p in P.values()}
class H(http.server.BaseHTTPRequestHandler):
def log_message(self,*a): open(f'{D}/mock.log','a').write(self.command+' '+self.path+'\n')
def send(self,code,body,ct='application/json'):
if not isinstance(body,bytes): body=json.dumps(body).encode()
self.send_response(code); self.send_header('Content-Type',ct); self.send_header('Content-Length',str(len(body))); self.end_headers(); self.wfile.write(body)
def do_POST(self):
n=int(self.headers.get('Content-Length',0)); body=self.rfile.read(n).decode('utf-8','replace'); p=self.path.split('?')[0]
if p.endswith('/patches/batch'):
return self.send(200,{"packages":[{"purl":q['purl'],"patches":[{"uuid":q['uuid'],"purl":q['purl'],"tier":"free","cveIds":[],"ghsaIds":[],"severity":"high","title":"t"}]} for q in P.values() if q['purl'] in body],"canAccessPaidPatches":False})
if p.endswith('/patches/package'):
res={}
for u,q in BYU.items():
if u in body or q['purl'] in body:
url=B+q['route']
res[u]={"status":"granted","url":url,"purl":q['purl'],"artifacts":[{"kind":"tarball","url":url,"integrity":{"sha256":hashlib.sha256(q['patb']).hexdigest(),"sha512":"sha512-"+base64.b64encode(hashlib.sha512(q['patb']).digest()).decode()}}],"registryOverride":None}
return self.send(200,{"results":res})
self.send(404,{})
def do_GET(self):
p=self.path.split('?')[0]
if '/patches/by-package/' in p:
return self.send(200,{"patches":[{"uuid":q['uuid'],"purl":q['purl'],"publishedAt":"2026-01-01T00:00:00Z","description":"x","license":"MIT","tier":"free","vulnerabilities":{"GHSA-aaaa-bbbb-cccc":{"cves":["CVE-2099-0001"],"summary":"s","severity":"high","description":"d"}}} for q in P.values() if q['purl'].replace('pkg:pypi/','') in p.replace('%40','@') or ('/'+q['purl'].split('/')[1].split('@')[0]) in p],"canAccessPaidPatches":False})
for u,q in BYU.items():
if p.endswith(f'/patches/view/{u}'): return self.send(200,q['view'])
if p==q['route']: return self.send(200,q['patb'],'application/octet-stream')
self.send(404,{})
http.server.ThreadingHTTPServer(('127.0.0.1',PORT),H).serve_forever()Next
|
|
[agent] 2026-10-29 (08:30 UTC): pip / requirements.txt bug-hunt run Tested: main Probe branches: none (branch deletion is still blocked, see backlog 3). Re-triage
Cells (Linux)
Issues
False positives ruled out
Next
|
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
[agent] Progress ledger for the scheduled pip / requirements.txt bug-hunt routine (label pm:pip).
Last run: 2026-10-29 ~08:30 UTC (fifty-second run), main
ecd4924(unchanged), latest release v5.0.1. pip 24.0 / 25.0.1 hosted → eject → revert spot-checks pass (backlog 5 done); 1q (vendor line copied into-c/ requirements-dev.txt, thenrollback) passes; marker-split hosted,-e .transitive vendoring (pip 20.3.4 / 24.0),--no-binary, and concurrent vendored scans pass. No new issues. Harness: the two-package (six + idna) Python mock in entry 20261029T021000Z. Probe branches are still blocked. Open: #1794, #977, #638 (+ #836 enhancement).Coverage matrix
-rinclude, lock-only==1.16)-g(--user)six == X)six @ mirror)==1.16)--json)vendor)vendor --dry-runover hostedget --mode vendoredover hosted-cby a sibling--prune)pip lockpylock.toml (hosted / vendored)__pycache__--max-new-patches(hosted)get <name>PyPI spelling--max-new-patches(vendored)${VAR}-rinclude (lock-only)-ron one line (lock-only)-rinclude (vex / rollback)apply --check(agent, #1029)scan --pruneliveness (#1050)pip freeze-rinclude (--require-hashes)\continuation at EOF (lock-only)list(hosted / marker split / include)redirect_requirements_takeover_unreachable, verified 2026-10-05)pip lockneeds pip ≥ 25.1)6fe81ad)--global-prefix, unwritable)-rinclude, marker, spellings, transitive, URL includes; 2026-10-06)-r,-csupersede, pip-tools regen pass 2026-10-07)6fe81ad)pip install/pip sync)redirect_requirements_takeover_unreachable, verified 2026-10-05)b96a785: hosted refusescandidate_file_unreadable, lock-only decodes)--prune); moved-into-include / root-level sibling revert fixed #867 (verified 2026-10-08 ona845bf9); subdirectoryrequirements/*.txtfail #1167vendor --checkpass; hosted scan + vendored pass; rollback / remove fixed #804 (verified 2026-10-05 on main9c43dfc, byte-identical; re-check the takeover and the pip 25.1 lock);pylock.<name>.toml, sdist-only, + requirements.txt,--dry-runpass (2026-10-05)__pycache__+-OO)-spelling, retained / floor /enabled: falsepass)6fe81ad)b96a785)a845bf9: vex attests, rollback byte-identical, both-rorders)VIRTUAL_ENV, downgrade skip,-g; 2026-10-08)file:///drift-kept (known non-bug); revert / remove / takeover with the file inrequirements/fail #1167--user)Scripts/+Lib/)--user,%APPDATA%\Python)pip 20.3.4 on py3.13 is blocked (no
distutils).setupwas removed in v5, so the old setup column (#377, #378) is retired; both issues are closed.Run forty-eight (2026-10-28 08:12 UTC, pip 26.x / py3.11 and 20.3.4 / py3.8, main
b787454): plain-vendoreject over hosted requirements.txt. Two hosted packages where one can't be vendored (no service artifact) or can't be restored (PyPI JSON 404 under--hashmode) are refused up front (eject_refused, files byte-identical), in root CRLF,-rinclude (failing pin in the include or in the root) layouts: pass. PyPI JSON 404 with unhashed fragment pins ejects (no hash needed) and reverts to==: pass. Mixed CRLF/LF, UTF-8 BOM (+ CRLF), no trailing EOL, capitalized names + markers: eject,--check, re-run (byte no-op) and--revertpass; real pip 26.x and 20.3.4 install both patched wheels from root and-r requirements/base.txtlayouts. #740 fix (#1726) verified on the eject wet run (vendor_requirements_constraints_linkfor-c,--constraint=anddev/requirements.txt-c ../requirements.txt); the eject--dry-rundoesn't preview it (open question h).Run forty-seven (2026-10-28, pip 26.2.2 / py3.11, main
b787454, bisect control8244b94): the #1648 plain-vendoreject over real hosted-scan output passes for a-rinclude pin, a marker + comment line, a fragment pin, CRLF, a capitalized name and pip-compile hash continuations (pip 26.2.2 installs the vendored wheel; revert restores==+ hash). #668 is fixed. requirements.txt +pip lockpylock.toml both hosted → eject orscan --mode vendoredfails → #1758 (requirements.txt un-hosted to plain PyPI, only pylock wired,vendor --checkcontested; not a regression).Run forty-six (2026-10-17, pip 25.1 / 25.3 / 26.2.1 on py3.11, uv 0.11.32, main
657fce2, release v5.0.1): the Poetry handover (pylock comments dropped on a two-package revert) led to #1623: a two-packagepip lockpylock.toml revert writes an invalid lock (2/2, also v5.0.1). Vendored install of the same file in a fresh venv andvendor --checkpass. A uv-written pylock with 2 vendored packages, and each package alone, revert byte-identical.Run forty-three (2026-10-15, pip 26.2.1 / py3.11, main
e76cb9b): vendored over a mixed CRLF/LF requirements.txt fails → #1567 (LF-majority: untouched CRLF lines become LF; CRLF-majority: the pin's own LF becomes CRLF;vendor --revertandremoveexit 0 but don't restore the file; pip installs patched). #1104 re-checked: still fails.Run forty-two (2026-10-14 evening, pip 26.2.1 / py3.13, 25.1.1 / py3.12, 23.0.1, 21.3.1, 20.3.4 / py3.8, CPython 3.14.6 and 3.14.6t, main
306ec81): #1524 verified fixed (vendor --revert,removeand the hosted takeover of a requirements.txt + pylock.toml entry restore both files; pip 26.2.1 and 25.1.1). Mixed entries also pass with the pin in a-rinclude, two pylocks (pylock.toml+pylock.dev.toml), uvpip compile --format pylock.toml, and a pylock deleted by the user. Vendoredrepairrebuilds a deleted, corrupted or whole-dir-deleted wheel (fresh--no-indexinstall patched), a mixed entry's wheel, and a manifest-less checkout; a ledger-less one refusesvendor_ledger_missing(exit 1). Format-control lines (--no-binary :all:/six,--only-binary :none:,--no-index,--prefer-binary) pass hosted and vendored. Split-line continuations (six==\/1.16.0,six \/==X, marker on the next line,\then a blank line,# c \swallowing the next line) pass hosted, vendored, install and revert. Agent / hosted / vex on CPython 3.14 and free-threaded 3.14t (lib/python3.14t) pass.Run forty-one (2026-10-14, pip 26.2.1 / py3.13, 25.0.1 / py3.12, 24.0 / py3.11, 20.3.4 / py3.8, main
313d532): dotted / underscored PyPI names with odd spellings pass hosted (plain, extras + markers, pip-compile hashed shapes under--require-hashes), agent and vendored (byte-identical revert), with vex and rollback; a unicode + space project path passes agent / hosted. Backlog 1h found #1524: a vendored requirements.txt plus a laterpip lock .pylock.toml leaves a mixedpython-lockentry that revert / remove / hosted takeover can't unwind.Run forty (2026-10-13 evening, pip 26.2.1 / py3.13, 24.0 / py3.11, 20.3.4 / py3.8, virtualenv 21.4.3 over Debian py3.11, main
d4af25a): #1486 regression pass (hosted hashed continuation andpip lockpylock.toml, install patched, vex attests); pyproject +uv.lock+uv exportrequirements.txt vendored pass (all three wired once,uv sync --lockedandpip install --require-hashespatched, byte-identical revert; backlog 3k done); virtualenv-made system-site venv hosted pass (stale warning names the Debian dir, vex omits);--grouphosted = #638 class; sha512-hashed continuation hosted pass, rollback restores the PyPI sha256 form (installs). #1104 / #977 still fail.Run thirty-nine (2026-10-13, pip 26.2.1 / py3.13, 24.0 / py3.11 (Debian), 20.3.4 / py3.8 (uv-managed base), pip-tools on 26.2.1, main
15c2c83): #409 verified fixed: hosted over a system-site venv now warnsredirect_pypi_stale_installandvexomits (not_applied) for a base copy in Debian/usr/lib/python3/dist-packages, inPYTHONUSERBASE, and in a uv-managed basesite-packages(stdlib venv anduv venv --system-site-packages); afterpip install --force-reinstallthe venv copy shadows andvexattests. Agent mode over a system-site venv now patches the base copy (root: apply + rollback byte-identical; non-root:apply_failedPermission denied, exit 1, vex omits). #1437 verified for pip: a vendor ledger beside a hosted pin ismode_ambiguous(exit 2, nothing written) for plain, CRLF, BOM, hashed continuation, marker, comment,Six, extras, a-rinclude,pylock.tomlandpylock.dev.toml, onscanand bareget(name, purl, uuid). Hosted supersede A → B over a pip-compile--generate-hashesfile passes (--require-hashesinstall, vex names B), and rollback restores the original two-hash block byte for byte.Run thirty-eight (2026-10-12, pip 26.2.1 / py3.13 and 20.3.4 / py3.8, pip-tools 7.6.2, main
7236190): #1365 and #604 verified fixed. The #1381 shared grammar passes hosted, vendored, vex and real pip for the space-form--hash, space-less markers, paren pins with markers, markers on continuation lines, upper-case names and long--config-settings. A crash at eachgroup_commitfailpoint during a vendored → hosted takeover recovers requirements.txt but leaves an orphan vendored unit (not filed, SIGKILL scope). Lock-only missessix==X -C a=b(not filed, exotic). #1167 holds with realpip freeze > requirements/lock.txt.Run thirty-seven (2026-10-09 evening, pip 26.2.1 / py3.13 and 20.3.4 / py3.8, pip-tools on pip 25.2, main
7eec31b): #542 verified fixed (mirror /file:/// sdist direct refs refused withredirect_requirements_direct_reference, file byte-identical, twice). #1034 target grammar passes over a hosted pin:rollback/removewithsix,Six,SIX, versionless and versioned purls (any case) and the uuid all restoresix==1.16.0;six_is correctly not found. Hosted over a CR-only / stray-CR / FF root refuses (redirect_requirements_entry_not_found/_version_ambiguous), nothing written. Vendored over a CR-only root appends a(transitive)line that pip 20.3.4 / 26.2.1 install patched;vendor --revertleaves the file pip-equivalent (final CR becomes LF). Realpip-compile --generate-hashesoutput: hosted rewrite, patched install on pip 20.3.4 / 26.2.1, byte-identical rollback. Revert residual probe: a rootrequirements.pip,requirements.in,Requirements-Prod.TXTor extensionless file naming the vendored wheel does not keep it (only*.txt/*.lock); not filed, see backlog question 0f.Run thirty-six (2026-10-09 afternoon, pip 26.2.1 / py3.13 and 20.3.4 / py3.8, main
40de3d5): #1249 verified fixed (EOF\with no newline, CRLF, and a-rinclude).-r dev.txt \as the last line, plus-e ./--editable ./pkgbeside a pin, pass lock-only. New fail #1281: bare-CR / FF / NEL / U+2028 line breaks (v4.0.0 finds only the first pin; main finds none). Noted in #1281 but not filed separately:six==1.16.0 \\(two backslashes) at EOF. pip'sstrip("\\")removes both and v4.0.0 discovers it, but main drops it.Run thirty-five (2026-10-09, pip 26.2.1 / py3.13, 24.0 / py3.12 and 20.3.4 / py3.8, main
e03a666): #1212 verified fixed (four codecs; root file and-rinclude). New fail #1249 (dangling\on the last line, every mode, root and include, LF and CRLF). A lock-only parser sweep passes: a continuation inside the name or version, a# …\comment line, a tab-spaced pin, a marker without spaces, uppercase names,_/.names normalised to-, extras, and hashed continuations at EOF.Run thirty-four (2026-10-09, pip 26.2.1 / py3.11 and 20.3.4 / py3.8, main
793edd4): #1119 verified fixed (a latin-1 coding line with a non-ASCII comment is discovered lock-only). Hosted over a non-UTF-8 latin-1 root refuses loudly (candidate_file_unreadable, exit 1, nothing written). A UTF-8 root with a latin-1-rinclude rewrites, attests (vex) and rolls back fine. An unmodelled-codec coding line (iso-8859-15 / cp1250 / latin-9 / mac-roman / gbk) on an ASCII file fails #1212 (first bad 793edd4 / #1152). #604 still fails. The uv handover (hosted rollback of a-c-constrained unpinned line restoressix==1.16.0) is backlog question 0c; not filed.Run thirty-three (2026-10-08 evening, pip 26.2.1 / py3.11 and 20.3.4 / py3.8, main
a845bf9): the #867 and #1086 fixes are verified. A vendor line in an unincluded subdirectory requirements file (moved there, or written bypip freeze > requirements/lock.txt) loses its wheel onvendor --revert,removeand the hosted takeover (#1167). The root-levellock.txtcontrol is kept.Run thirty-two (2026-10-08 afternoon, pip 26.2.1 / py3.11 and 20.3.4 / py3.8, main
3b4ac84): #1050 prune liveness passes (bumped pin reverted; quoted include, missing wheel kept). Agent mode in a stdlib venv withlib64 → libpasses. Hosted →pip freezeregen re-scans byte-identical and rolls back. Hosted hashed root + hashed include under--require-hashespasses. A lock-only PEP 735--groupproject finds nothing (documented). #1104, #977 still fail.Run forty-four (2026-10-15 evening, pip 20.3.4 / py3.9, 24.0 / py3.11, 26.2.1 / py3.13, main
4cc50f4): #1562 (#1549) requirements.txt direct-ref contest against a wired Pipfile.lock:name @ urlwith a marker, with a--hashcontinuation,file:///…whl, a mixed-case name and./wheels/…whlall contest.wheels/…whl, a barex-1.2.3-…whlanddist/x-1.2.3.tar.gzdon't (fail → #1587, hosted and vendored).--editable git+…#egg=xcontests as any-version (message: not "same version").Run thirty-one (2026-10-08 morning, pip 26.2.1 / py3.11, 24.0 / py3.12 and 20.3.4 / py3.8, main
b96a785): #721 and #1028 fixes verified.apply --check(#1029) passes on venv, multi-venv, externalVIRTUAL_ENV, downgrade,-gand egg-info. Hostedredirect.patches[]rows and #1035's uuid / purl remove and rollback pass. Latin-1 + coding line lock-only fails (#1119).Run thirty (2026-10-08, pip 26.2.1 / py3.11 and pip 20.3.4 / py3.8, main
d7f8679): vendored marker split in one file (#929) passes, and so does its vendored → hosted takeover. A marker split across a-rinclude fails (#1104); hosted handles it. The vendored → hosted takeover over a drifted vendor comment refuses cleanly (redirect_vendored_revert_failed). Vendored root pin + the same pin in-c constraints.txtpasses (install, vex, byte-identical revert).Run twenty-one (2026-10-05, pip 26.2.1 / py3.11, main
9c43dfc): #858 atomic writes (file mode, CRLF, revert byte-identity) and #865 digests (hashed hosted / vendored requirements.txt with--require-hashes, vendored pylock hashes) pass; vendored continuation grammar (six==\+ newline, a comment ending in\) passes.Commands covered on Linux: scan (all modes), get (hosted, agent
-g), rollback, remove, vendored takeover, vex (hosted with the mock origin, vendored,-g), repair, list, concurrent runs. Also covered (2026-10-02): free-threaded CPython 3.13t venvs, a.venvsymlink to an out-of-tree venv, a 16-case hosted grammar sweep with fresh installs and rollbacks, virtualenv layouts, pip-toolspip-compile --generate-hashes/pip-syncover a hosted file plus rollback,-cconstraints with an unpinned root,pip install --targettrees,--jsonenvelopes of rollback / remove failures, and interrupted (SIGTERM / SIGKILL) hosted scans. Run ten (2026-10-03, pip 26.2.1 / py3.13 and pip 20.3.4 / py3.8): an 18-shape hosted and vendored grammar sweep with freshpip install -rplus rollback and reinstall, vendored lock-onlyscanover-r/-rX/--requirement=/ CRLF / subdirectory includes,-cconstraints, and grant-token re-pin: all pass or refuse explicitly. Run eight (pip 24.0 / py3.11 and pip 20.3.4 / py3.8): PEP 503 name normalisation (_/-/./ case, venv and lock-only), duplicate and marker-split pins, BOM, no trailing newline,--no-index+--find-links, per-line--config-settings,--require-hasheswith multiple and sha384 hashes,-e/ VCS neighbours (lock-only +vex), symlinked root and include files, out-of-root includes,--prefixtrees: all pass or refuse explicitly.Run 50 (Linux, pip 26.2.2 / CPython 3.11, lock-only + pylock): hosted → vendored eject and
scan --mode vendoredover requirements.txt + pylock.toml: exact pin pass, marker pin pass,-rinclude pin (vendored) pass, pip-compile CRLF--hash+pylock.dev.tomlpass,vendor --revertbyte-identical pass; extras pin fail #1794; hosted with the pin only in a-rinclude beside a pylock:redirect_unattributable, fail-closed (known non-bug class).Backlog
1q. done 2026-10-29 run 52 for the
-cconstraints file andrequirements-dev.txtsibling underrollback(fail-safe residual keep, re-run finishes). Still open: the two-package dotted-name CRLF-rinclude takeover. Run 49 follow-ups: reuse the Python mock (entry 20261028T134832Z) for a two-package vendored → hosted takeover with dotted names in a CRLF-rinclude, and an orphan wire in a-cconstraints file /requirements-dev.txtsibling underrollback(unscoped refusal).1r. #1794: re-verify once fixed (eject and
scan --mode vendored; also--dry-runpreviews); still reproduces onecd4924. Othersibling_pin_wirable-rejected shapes: a symlinked root requirements.txt is refused up front by hosted (redirect_symlinked_file_unsupported, nothing written), so the eject can't reach it (run 51); a transitive-only package (not in requirements.txt) is left with the documentedinstalls driven by requirements.txt retain their existing sourceswarning on both hosted and eject (pass). Still open: an include outside the root, a pin whose package also has a vendor line for another version.1o. done 2026-10-28 run 50: #1758 verified fixed; the
-rinclude andpylock.<name>.tomlcells pass. (The two-package eject refusal / rollback over requirements.txt alone passed on run 48; a failure that only surfaces after the restore, i.e. a trueeject_rolled_back, wasn't reachable with the fixtures: a corrupt artifact is refused at the grant step.)1p. Re-verify the maintainer-closed fixes with real pip (closed 2026-10-22 to 10-27): #1104, #819. (Done 2026-10-29 run 51: #1623 two-package
pip lockrevert byte-identical, comments above restored keys kept,removeof the first-vendored package clean; #1602===contests,==X.0/==vX/==1.16/SIX == Xare wired as siblings; #1587wheels/…,wheels//…,wheels/./…,wheels\…,file:wheels/…all contest.) (#740 verified on the eject path on run 48; #1567's mixed-EOL case passes on the eject path; the plain vendored planner over a mixed file is still to re-check.)1n. #1623 follow-ups: re-verify once fixed (
vendor --revert,removeof the first-vendored package, three packages, CRLF pip-lock file). Also check that comments above restored keys survive (the Poetry handover 20261016T202635Z-from-poetry; root cause noted in #1623), and a hosted → vendored takeover over a two-packagepip lockfile.1m. #1602 follow-ups: re-verify once fixed. Also check the reverse direction (a requirements.txt wiring vs a hand-edited Pipfile.lock
"version": "===X"/"==X.0"), and get a maintainer call on single-version ranges (~=X,==X.*,>=X,<=X).1l. done 2026-10-29: #1587 verified; the Windows
wheels\six-…whlline contests. The name-less source directory is a deliberate exclusion (see Known non-bugs).1k. #1567 follow-ups: a mixed CRLF/LF
-rinclude, the superseding re-vendor (plan_rewire), and the hosted → vendored takeover over a mixed file (hosted keeps per-line endings, so it should be clean). Re-verify once fixed.1j. #1281 was closed not planned (2026-10-09). Hosted and vendored over CR-only roots were checked on run 37 and are fail-closed or install patched; nothing left to do unless the maintainer reopens it.
vexattests a hosted pin (six@1.16.0) from the lockfile basis when the venv holds a different version (six 1.15.0), with no warning (see the 20261002T142728Z entry). (b) The non--gno-venv fallback to global site-packages (20261001T083942Z). (c) Hosted rollback restores an unpinnedsix(or-c-constrained root) assix==1.16.0, because hosted mode is stateless; should the rewrite refuse unpinned roots, or keep them unpinned on restore? The uv routine handed over the same case on 2026-10-08 (entry 20261008T213301Z-from-uv), and it still waits on a maintainer call. (e) resolved: Fix remove/rollback missing PyPI name spellings (#1024) #1025 fixed non-canonical purls inremove/rollback(verified 2026-10-07 on05ecc6e). (d) Vendored mode wires a root(transitive)line but leaves a directsix==Xpin in a siblingrequirements-dev.txt, sopip install -r requirements-dev.txtalone stays unpatched (same class as Vendored mode in a Pipenv project wires only Pipfile.lock and silently leaves a sibling requirements.txt unpatched, and the hosted → vendored takeover reverts that file's hosted pin to plain PyPI #612 / PyPI hosted scan lacks a specific missing-requirements warning after redirect_unconfirmed reporting #638). (g) Plain-pip hostedredirect_pypi_stale_installfor a base-interpreter copy in a--system-site-packagesvenv says "Reinstall from the rewritten lock … or uninstall this package before installing": plainpip install -ris a no-op over the base copy andpip uninstallrefuses ("outside environment"); only--force-reinstall/--ignore-installedworks. This is the pip twin of Pipenv Pipenv stale-install remedy can't replace a base-interpreter copy in a--site-packagesvenv:pip uninstallrefuses it andpipenv synckeeps it, so following the warning leaves the package unpatched #1450 (fixed by Fix Pipenv remedy for base-interpreter copies (#1450) #1455 for Pipenv only). Not filed, because it matches CLI_CONTRACT.md's generic remedy and vex fails closed (2026-10-13). (h) The fix: vendor hosted patches directly from lockfiles #1648 ejectvendor --dry-runreports onlyeject_plannedand omits thevendor_requirements_constraints_linkadvisory that the wet eject emits, though the CLI_CONTRACT.md row says "dry run included" (run 48). Low impact: the hosted file was already a link and hosted mode warned. Not filed; ask whether eject previews should carry backend advisories. (f) The vendored revert residual probe (vendor/pypi.rsis_export_name) reads only*.txt/*.lock(case-sensitive) at the root and in subdirectories, so a rootrequirements.pip(legacy convention),requirements.in,Requirements.TXTor extensionless requirements file that installs from the vendored wheel doesn't keep it:vendor --revertdeletes the wheel (exit 0) andpip install -rfrom that file then fails. Not filed: under the v5 normal-toolchain scope no standard tool writes the vendored path into such a file (pip-compile output is.txtand is guarded). (i) After a one-sided git merge of.socket/vendor/state.json(Vendored yarn classic: after a git merge resolves .socket/vendor/state.json to one side,vendor --checkandrollbackexit 0 while the other side's package stays wired, and rollback deletes the ledger, stranding it #991 shape), unscopedvendor --revertexits 0 (success), reverts the owned entries, deletesstate.json, and leaves the orphan pin wired, reporting only avendor_orphan_still_wiredskip.rollbackrefuses the same state up front (vendor_ledger_missing, Fix rollback over unledgered vendor wiring (#991) #1739). CLI_CONTRACT.md describes the advisory as following "a revert that already rewrote the lockfile", so this looks deliberate. Not filed (2026-10-28, run 49): ask whethervendor --revertshould refuse likerollback. It is generic, not pip-only.1a. Since #1152, a plain-ASCII requirements.txt whose coding line names an unmodelled codec (iso-8859-15, cp1250, gbk…) is read as absent: scan finds nothing (exit 0), and vex / rollback can't see an existing hosted pin #1212 lock-only is verified fixed (2026-10-09). Still open: hosted / vex / rollback and the vendored planner over such a file. Lock-only requirements.txt discovery drops a pin whose last line ends in a dangling
\continuation (six==1.16.0 \at EOF): scan exits 0 with "No patches", but pip installs it #1249 was verified fixed on 2026-10-09 (lock-only). Still open: check that hosted surfacesredirect_requirements_continuationon a lock-only checkout.-rtree (false "not pinned to ==1.16.0", exit 1), so a fresh install stays unpatched #1104, Vendored requirements.txt can't be reverted once the user touches the# socket-patch vendor:comment:vendor --revertdrift-keeps forever (exit 0), and the suggested "re-vendor" remedy is a no-op or adds a duplicate line #977, Agent-mode apply of a same-size PyPI patch in the same second aspip installleaves pip's__pycache__bytecode valid, so Python keeps running the unpatched code while apply reports it patched #819, Hosted and vendored rewrites of a requirements.txt that another file uses as-cconstraints break everypip installon pip 20.3–21.0 ("Links are not allowed as constraints"), with no warning #740,vendor --dry-runover a hosted requirements.txt pin previews apypi_requirement_not_pinnedfailure (exit 1), but the realvendortakes it over and succeeds #668 and PyPI hosted scan lacks a specific missing-requirements warning after redirect_unconfirmed reporting #638 as fixes land (In a--system-site-packagesvenv, pip keeps the base interpreter's unpatched copy after a hosted rewrite, no stale-install warning fires, andvexattests it as patched #409 verified fixed on Linux 2026-10-13; macOS / Windows re-verify needs a probe). Vendored requirements.txt still refuses a marker-split package when the other version's branch sits in a different file of the-rtree (false "not pinned to ==1.16.0", exit 1), so a fresh install stays unpatched #1104 /vendor --dry-runover a hosted requirements.txt pin previews apypi_requirement_not_pinnedfailure (exit 1), but the realvendortakes it over and succeeds #668 weren't re-checked on run 39 (no vendoring-service mock this run). Verify the merged fixes for Hostedrollback,removeand the vendored takeover refuse a requirements.txt whose only requirements are hosted pins (six==1.16.0alone can be patched but never unpatched) #410,get <name>doesn't PEP 503-normalise PyPI names, soget typing_extensionsorget ruamel.yamlreports "No packages matching" (exit 0) for an installed, patchable package #926, socket.ymlignorePackages/packagesandscan --packagedon't PEP 503-normalise PyPI names, soignorePackages: ["typing_extensions"]is silently ignored and the package is patched anyway #910 and Vendored requirements.txt fromuv pip compile --universalrefuses a marker-split package (six==1.16.0 ; python < 3.12+six==1.17.0 ; python >= 3.12) as "not pinned to ==1.16.0", while --dry-run previews would_vendor and hosted / vendored pylock handle the same split #928 with real pip. Poetry hosted ⇄ vendored mode switch is refused, and blames a "user-authored" source that socket-patch wrote itself #328 / Hosted requirements.txt rewrite skips PEP 440-equivalent pins likesix==1.16for an installed 1.16.0, soscanexits 0 and pip installs the unpatched release (regression from v4.0.0) #475 re-verify on pip 20.3.4 / 26.x is still open; Vendored requirements.txt never picks up a superseding patch: the re-vendor to a new uuid fails with pypi_requirements_already_vendored (exit 1), though--dry-runpreviewswould_revendorand the contract says it re-vendors automatically #765 on pip 20.3.4. Poetry hosted ⇄ vendored mode switch is refused, and blames a "user-authored" source that socket-patch wrote itself #328 / Hosted requirements.txt rewrite skips PEP 440-equivalent pins likesix==1.16for an installed 1.16.0, soscanexits 0 and pip installs the unpatched release (regression from v4.0.0) #475 re-verify on pip 20.3.4 / 26.x is still open.1b. Agent-mode apply of a same-size PyPI patch in the same second as
pip installleaves pip's__pycache__bytecode valid, so Python keeps running the unpatched code while apply reports it patched #819 on-g/--usersite-packages. (The rollback variant is in the Agent-mode apply of a same-size PyPI patch in the same second aspip installleaves pip's__pycache__bytecode valid, so Python keeps running the unpatched code while apply reports it patched #819 body; the pip-lock variants were done 2026-10-05; the new-file case became Agent-mode rollback / remove of a PyPI patch that added a file in a new directory leaves the empty directory in site-packages, so Python still imports it as a namespace package #838.)1g. done 2026-10-08: a hashed include beside a hashed hosted root under
--require-hashespasses on pip 26.2.1 and 20.3.4.1h. done: Vendored requirements.txt can't be reverted or removed once a later scan also wires a pylock.toml: the entry flips to flavor
python-lock, whose revert calls its ownrequirements_linewiring "unexpected" drift (exit 0, nothing restored) #1524 fixed by Fix vendored PyPI revert of entries wired across flavors (#1524) #1526 and verified 2026-10-14 evening (include pin, two pylocks, uv-written pylock, pylock deleted). A vendor line moved by hand into a-cconstraints file drift-keeps (fail-safe, user edit). Still open: a uv.lock (not pylock) added after vendoring requirements.txt.1i. Make the vendored-to-hosted takeover atomic #1039 crash cells done on 2026-10-12 (they recover, with an orphan unit left). Still open: a Windows backslash vendored path vs the residual probe's forward-slash needle.
1f. Fix hosted PyPI pinning platform-only wheels (#701, #932) #984 follow-up:
cp311-none-anygrants stay redirectable by design. Check pip 3.12 against such a hosted pin, and a build-tag wheel name inwheel_platform_from_filename.1e. Lock-only requirements.txt discovery skips
-rincludes that are quoted, backslash-escaped or use${VAR}(-r "dev reqs.txt",--requirement="dev.txt",-r ${DIR}/dev.txt), so the scan exits 0 with "No patches" while pip installs the include's unpatched pins #994 follow-ups: done 2026-10-08. A quoted include's pin is vendored in place (no root(transitive)line), andvexand prune see it.1d.
get <name>follow-ups afterget <name>doesn't PEP 503-normalise PyPI names, soget typing_extensionsorget ruamel.yamlreports "No packages matching" (exit 0) for an installed, patchable package #926 (fuzzy prefix picks such asget ruamelvsruamel.yaml.clib;policy_bypassedunder Fix PyPI package specs ignoring PEP 503 spellings (#910) #911). The vendored supersede under cap 0 and the deferred hashed-include pin passed on 2026-10-06; next is a supersede with the pin also in a-cconstraints file.1c. Hosted rollback and remove always refuse a
pip lockpylock.toml ("no sibling registry package shows the registry and artifact fields"), because pip writes[[packages.wheels]]tables, not uv's inlinewheels = [...]#804 follow-ups: re-check the hosted → vendored takeover over apip lockfile and a pip 25.1 lock on main.3k. done 2026-10-13: pyproject +
uv.lock+uv exportrequirements.txt vendored wires each file once and reverts byte for byte.pip freeze >(UTF-16) file end to end (blocked while probe branches can't be deleted: on 2026-10-12git push --deletefailed and was then denied, and nine oldbughunt/pip/*branches are still on the remote).3b. UTF-32 BOM: re-check with the Hosted and lock-only scans treat a UTF-16 requirements.txt (what Windows PowerShell's
pip freeze >writes) as absent: exit 0, no warning, and pip keeps installing the unpatched pin #721 fix (Fix UTF-16 requirements.txt silently skipped (#721) #724 decodes UTF-32 BE; an LE BOM matches the UTF-16 LE prefix first, as in pip's own BOM order). The PEP 263 coding line is Lock-only scans still drop a requirements.txt pip decodes through a PEP 263 coding line (latin-1): "No pypi packages found", exit 0, while the same project with a venv refusescandidate_file_unreadable#1119; after it's fixed, check the vendored wet run andvexover it.3d. pip ≥ 25.1
--group: lock-only finds nothing (documented, see Known non-bugs). Hosted with a venv is still untested (expectredirect_unconfirmed, the PyPI hosted scan lacks a specific missing-requirements warning after redirect_unconfirmed reporting #638 class).3c. PyPy venvs (
lib/pypy3.X/site-packagesis not matched by the crawler'spython3.*glob): blocked in the sandbox (uv can't download PyPy), and outside the CPython scope.-g) mode: Homebrew / PEP 668 interpreters, the py launcher with several interpreters, pipx venvs (Fix global scan missing pipx venvs (#415) #418), non-root unwritable prefixes on CI, Windows all-usersC:\Program Files\Python3XXwhen it isn't on PATH (not in the well-known list).--require-hashesinstall → eject → install → check → revert all pass (21.3–23.1 agent mode was done earlier).Known non-bugs
A name-less local source directory in requirements.txt (
./src/six,-e ./src/sixwithout#egg=) doesn't contest another lock's wiring of the samename@version, whilesix @ ./src/sixand-e ./src/six#egg=sixdo. Deliberate:vex/discover/pypi_other.rsforeign_referencesays a requirements line names its package only through its filename or#egg=, "so one with neither (a source directory) is left out" (run 51).A symlinked
-rinclude (target inside or outside the root) makes vendored refuse that package withredirect_symlinked_file_unsupported, exit 1; the other packages are still wired. Fail-closed and loud (run 51).Hosted scan with the pin only in a
-rinclude beside apip lockpylock skips withredirect_unattributable(pylock wired vs include unpatched) and writes nothing, exit 0. This is the same class as "hosted rewrites only the root requirements.txt"; it's fail-closed (2026-10-28, run 50).A pylock whose packages carry files from a non-PyPI index and record no
indexmakes the hosted → vendored restore refuse (redirect_revert_failed, "restore it from version control"). That's correct fail-closed behaviour, and also a harness trap (2026-10-28).A requirements.txt only in a subdirectory (
svc/requirements.txt, not-r-included from the root) is found by neither hosted scan nor the eject (consistent no-op, 2026-10-28).Since fix: vendor hosted patches directly from lockfiles #1648, plain
vendorwith any hosted pin in scope ejects only the hosted pins and ignores.socket/manifest.json(documented in CLI_CONTRACT.md "Takeover reconciliation"); vendoring manifest patches takesscan --mode vendored.A requirements.txt whose only hosted mention is a commented-out line (
# six @ <hosted url>), or a hosted url quoted in an inline comment, makeslist/rollback/removerefusehosted_wiring_contested(exit 1). CLI_CONTRACT.md documents this: a recognised uuid that discovery rejected counts as contested (2026-10-16).Harness: dash's
printf(sh -c "printf '\xef…'") doesn't expand\xescapes, so a "BOM" fixture written that way holds a literal\xef\xbb\xbfand looks contested. Real BOM files list fine (2026-10-16).vexon a plain requirements.txt project with no pyproject.toml / setup.py needs--product(product_undetected, documented).Harness tip (2026-10-15): a throwaway
#[ignore]test in crates/socket-patch-cli/tests that startsprebuilt_common::Server::project_with_env(root, &[("VIRTUAL_ENV", venv)]), writes its uri to a file and waits on a stop file serves the vendoring grant + wheel for a staged.socket/manifest.json+ blob. PointSOCKET_VENDOR_URLand--patch-server-urlat it. No hand-written mock needed for vendored cells. Delete the file afterwards.Harness: a venv copied with
cp -akeeps the original venv's absolute path inbin/pip's shebang, so.venv/bin/pip installin the copy installs into the ORIGINAL venv. Use.venv/bin/python -m pipin copied fixtures (a false "hosted install stays unpatched" on 2026-10-14).After a requirements.txt + pylock.toml entry is vendored, regenerating pylock.toml with
pip lock -r requirements.txt(archiveurl = "file:///<abs>/.socket/vendor/…whl") makesvendor --revertdrift-keep the whole entry (vendor_lock_entry_drifted, requirements.txt left vendored, exit 0), whilevendor --checkpasses. User edit of a wired file; same family as Vendored requirements.txt can't be reverted once the user touches the# socket-patch vendor:comment:vendor --revertdrift-keeps forever (exit 0), and the suggested "re-vendor" remedy is a no-op or adds a duplicate line #977 / thepip freezecase (2026-10-14).A mock whose
viewrecord purl spells a PyPI name differently from itsbatchpurl (zope.eventvszope-event) splits the vendored ledger into two entries per package on a later scan; consistent purls merge. Harness artifact (2026-10-14).VEX subcomponent ids echo the patch record's purl spelling (not PEP 503-canonicalised); unverified against the live API, so not filed (2026-10-14).
A requirements.txt still listing
socket-patch[hook]after v5 gets no stale-hook warning; docs/migrating-to-v5.md documents manual cleanup (2026-10-14).A vendored plain-pip project over a base-interpreter copy (system-site venv) gets no scan-time stale warning, and
pip install -rkeeps the base copy ("already installed with the same version"); vex warnsvendored_tree_out_of_sync. Same class as the documented plain-venv case (2026-10-13).Hosted rollback of a
pip hash -a sha512continuation restoressix==1.16.0with PyPI's sha256 hashes on one line;--require-hashesinstalls it. That's the documented pip-equivalent restore (2026-10-13).Since Fix crawl of --system-site-packages venvs (#409) #1419, agent mode in a
--system-site-packagesvenv patches the base interpreter's copy (for example Debian/usr/lib/python3/dist-packages/six.py, which other interpreters' users import too) when the venv has no copy of its own. That's the fix's stated intent ("agent mode said not installed"); as root it round-trips withrollback, and as non-root it fails loud (apply_failed, Permission denied, exit 1). 2026-10-13.An agent manifest beside a hosted requirements.txt pin: a bare
scankeeps agent mode (already_in_manifest), as CLI_CONTRACT.md documents ("keeps the mode of a project that already holds vendored or agent-mode patches";hosted_wiring_retained). It doesn't rewrite the hosted pin, so it isn't the A bare scan or get on a project holding both vendored packages and hosted pins silently converts every hosted pin to vendored (exit 0, no warning), so it undoes a partial hosted takeover #1437 class. 2026-10-13.A vendored → hosted takeover killed at a
group_commitfailpoint (group_commit_journal,group_commit_file,durability_barrier) recovers on the next run: requirements.txt is hosted, pip installs patched, vex is correct. The reverted.socket/vendor/pypi/<uuid>/(wheel +socket-patch.vendor.json) stays as an orphan, becausedefer_removalstrees aren't journaled. It's harmless cruft, inherent to SIGKILL and cross-ecosystem (2026-10-12).Lock-only discovery skips
six==X -C a=b(a short per-requirement option), while pip installs it. The pin is hand-written, so this is the Lock-only requirements.txt discovery reads a file with bare-CR (classic Mac), form-feed, NEL or U+2028 line breaks as one line, so scan exits 0 with "No patches" while pip installs every pin #1281 exotic class. With a venv the hosted refusal is loud (redirect_requirements_version_ambiguous), 2026-10-12.pip-compileover arequirements.inthat names the vendored wheel path writessix @ file:///<abs>/…whl: the same shape and outcome as thepip freezecase below (2026-10-12).A root
NOTES.txtthat only mentions the vendored wheel path keeps the wheel onvendor --revert(vendor_revert_residual_reference). That's a fail-safe false keep (2026-10-12).Lock-only requirements.txt discovery reads a file with bare-CR (classic Mac), form-feed, NEL or U+2028 line breaks as one line, so scan exits 0 with "No patches" while pip installs every pin #1281 (bare-CR, form-feed, NEL, U+2028 line breaks; doubled trailing backslash) was closed not planned by the maintainer on 2026-10-09: exotic inputs outside the v5 normal-toolchain scope. Don't re-file unless a normal tool generates such a file.
Since Use one package target grammar for get, remove, rollback and the UUID shortcut #1034,
remove six/rollback Six(bare names, PEP 503-folded) and versionless purls target a hosted pin;six_is a different PEP 503 name and is correctly not found (2026-10-09).pip-compileregenerating a hosted requirements.txt from requirements.in drops the hosted URL back tosix==1.16.0+ PyPI hashes; re-runscanafterwards. The regenerated file is the tool's output, not a socket-patch rewrite (2026-10-09).Compound or non-exact pins that pip resolves to one version (
six==1.16.0, !=1.15,six>=1.16.0,<=1.16.0,six~=1.16.0) and marker-only unpinned lines (six; python_version=="3.11") aren't lock-only discovered. Discovery is defined as exact==pins only (2026-10-09).six==v1.16.0is the Lock-only requirements.txt discovery sends PEP 440-equivalent pins verbatim (six==1.16→pkg:pypi/six@1.16), so a fresh checkout reports "No patches available" while the same file with a venv is patched #604 normalisation class.A vendored requirements.txt regenerated with
pip freeze(six @ file:///<abs>/.socket/vendor/pypi/<uuid>/….whl#sha256=…) isn't attested (ref_invalid, a machine-specific path), andvendor --checkexits 1 with a "dependency removed …scan --prune" remedy. The wet prune drift-keeps the entry, so nothing breaks; the dry run lists it as revertable (the contract's preview caveat). 2026-10-08.A plain-pip project with only PEP 735
[dependency-groups]/[project].dependenciespins (no requirements.txt, no lock) is invisible to lock-only discovery. Plain pip routes only through requirements.txt; PEP 735 groups are documented for Hatch only (docs/testing/hatch.md). 2026-10-08.Vendored
scan --dry-runpreviewswould_vendorfor requirements.txt pins the wet run refuses (six[x]==X→pypi_extras_unsupported;===,==X.*,--config-settings,name @ url, unpinned →pypi_requirement_not_pinned). This is documented: CLI_CONTRACT.md defines the vendored preview as a ledger classification that predicts only the npm-family preflights (uv handover 20261007T204038Z, checked 2026-10-08).A vendored → hosted takeover after the user edited the
# socket-patch vendor:comment refusesredirect_vendored_revert_failedand keeps the package vendored, on the dry run and the wet run alike (2026-10-08).A hosted root pin next to the same pin in a
-cconstraints file, a non-included siblingrequirements-dev.txt, or an include range (six>=1.0) attests fine (2026-10-07). Only an exact duplicate inside the-rtree is Lockfile discovery treats a requirements.txt-rinclude as a competing lock, so after a hosted rewritevexattests nothing (exit 2) androllbackrefuses (exit 1), althoughpip install -r requirements.txtinstalls the patched wheel #1086.--requirement= dev.txtand-r=dev.txt: socket-patch followsdev.txt(or not), but pip refuses both lines. The vendored root(transitive)append next to an include pin that the walk can't see still installs the patched wheel on pip 24.0 / 26.2.1 (2026-10-07).-r<TAB>dev.txtis followed (2026-10-07). A lock-onlysix==${VAR}pin isn't discovered; that's the same family as the documented hosted${VAR}refusal, so it's noted, not filed.A vendored
-rinclude diamond, an include cycle and the same include listed twice are all wired once and revert cleanly (2026-10-07).After pip-tools regenerates a vendored requirements.txt back to
six==1.16.0,vendor --checkexits 1 andvexomits the package (vendor_unwired) until a re-vendorre-wires it. That is the intended flow.Hosted mode rewrites only the root
requirements.txt; an installed pin reached only through-rgetsredirect_requirements_entry_not_found(vendored follows includes). The lock-only discovery gap is Lockfile-onlyscanignores pins in requirements.txt-rincludes, so a fresh checkout reports "No patches available" and installs unpatched (hosted and vendored) #412.A warm plain venv keeps the upstream same-version install after a hosted rewrite; this is warned (
redirect_pypi_stale_install) andvexomits it. The system-site-venv variant is In a--system-site-packagesvenv, pip keeps the base interpreter's unpatched copy after a hosted rewrite, no stale-install warning fires, andvexattests it as patched #409.Vendored
vexattests from the committed artifact even when a plain venv still holds upstream bytes; it warnsvendored_tree_out_of_sync(documented).The v5 upstream restore of a hosted line lowercases the name (
Six→six) and normalises spacing before a trailing comment; pip reads both forms the same way.Hosted rollback refuses a file that mixes hashed and unhashed requirements ("not derivable"); pip can't install such a file anyway.
Vendored refuses
===pins,==X.*wildcards and a tab before--hash(pypi_requirement_not_pinned). This is fail-closed and isn't filed (the==1.16zero-padding case is part of Hosted requirements.txt rewrite skips PEP 440-equivalent pins likesix==1.16for an installed 1.16.0, soscanexits 0 and pip installs the unpatched release (regression from v4.0.0) #475).--vendor-source buildwas removed in v5; vendoring always needs a patch-service artifact.rollbackin agent mode drops the manifest entry, so a laterapplyis a no-op (documented).A venv directory not named
.venv/venvis only found throughVIRTUAL_ENV.SOCKET_API_TOKENformat warnings and theuv pipHEAD 501 are mock artifacts.vex -ois--org, not--output.vex --jsonrequires--output.scan --mode agentafter a failedget(unwritable target) skips the recorded entry ("already recorded … runsocket-patch apply") and exits 0. This is documented, and the failedgetitself exits 1.Hosted
vexignores hosted URLs that aren't onpatch.socket.dev. Pass--patch-server-url <mock origin>to attest mock-hosted projects locally.A concurrent second run in the same project exits 1 with "Another socket-patch process is operating in this directory" (by design).
A requirements.txt that v4.0.0 (or a pre-Fix requirements.txt writers ignoring pip hash mode (#376) #383 build) hosted with
--hashin an otherwise unhashed file stays in that shape on a re-scan (exit 0), so pip still fails in hash mode. This is documented in Fix requirements.txt writers ignoring pip hash mode (#376) #383;socket-patch rollbackthen a re-scan rewrites it to the fragment form (verified).Hosted decides hash mode from the root file only, while vendored checks the whole
-rtree. That's harmless: in hash mode pip accepts a user-supplied direct URL's#sha256=fragment as its hash (pip 20.3.4–26.0).The vendored wheel path is CWD-relative;
pip install -rmust run from the project root (documented in CLI_CONTRACT.md).Hosted
rollbackonly recognises hosted URLs of the shape/patch/pypi/<name>/<ver>/<tok>/<uuid>/<file>; a mock without that path gets "Manifest not found".Agent mode doesn't crawl
pip install --target <dir>trees; it reports the package[NOT INSTALLED]with a skip hint (not silent). Hosted works for such projects.In the sandbox, the CLI can't reach pypi.org directly (
NO_PROXYlists it), so hostedrollback's upstream lookup fails with "error sending request". Run withNO_PROXY=localhost,127.0.0.1.pip 24 refuses hashed constraints next to an unhashed root, so constraint-only hash layouts aren't a socket-patch case.
A SIGKILLed scan can leave
.socket-stage-<file>-<uuid>in the project root, and later runs don't remove it; SIGTERM leaves nothing. Not filed (inherent to SIGKILL, cross-ecosystem).Hosted refuses bare URL / bare path lines (no
name @) and${VAR}pins withredirect_requirements_entry_not_found, exit 0 (the documented hosted-refusal posture).A hosted rollback restores a pip-equivalent line, not the original bytes (comment spacing, joined continuations,
(==X)→==X, case).Vendored refuses a per-line option such as
--config-settingson the patched pin, and aname @ <url/file>direct reference, with "not pinned to ==X" (fail-closed; the wording is imprecise). Hosted rewrites--config-settingslines fine.A symlinked
requirements.txtor a symlinked-rinclude is refused explicitly (redirect_symlinked_file_unsupported/pypi_requirements_symlink_unsupported), and so is an include outside the project root (vendored). Nothing is written.Agent mode doesn't crawl
pip install --prefix <dir>trees either ([NOT INSTALLED]+ skip hint), same as--target.With a mock origin, hosted
rollback/vexneedSOCKET_PATCH_SERVER_URL(or--patch-server-url) set to it; vendored needs the mock to serve sha512 integrity.Lock-only cells need
VIRTUAL_ENVpointing at an EMPTY venv: an emptyVIRTUAL_ENV=falls back to the system dist-packages (Ubuntu's python3-six 1.16.0) and masks lock-only behaviour.Vendored refuses
six[extra]==X(pypi_extras_unsupported), and an unpinned root pinned only through-c constraints.txt(pypi_requirement_not_pinned; the wording says "not pinned" although the constraint pins it). Both are fail-closed.Hosted rollback restores
===Xas==Xand an unpinnedsixassix==<installed>. Hosted mode keeps no state, so the line is derived from the hosted URL (see backlog question 0c).A file with a single
--hashline next to unhashed lines is already uninstallable by pip; hosted keeps that shape and rollback drops the lone hash. Garbage in, garbage out.record_fetch_failedon a hosted scan means the mock lacks theviewroute; it isn't a CLI bug.Agent mode doesn't patch editable installs: a PEP 660 finder (
apply_failed"File not found") or a legacy.egg-link("matched no installed package"). Both exit 1 and leave the user's source untouched (fail-closed).The vendored takeover's
vendor_prebuilt_required404 in a local harness means--patch-server-urlrewrote the artifact host to a mock without the prebuilt routes (harness artifact).get --mode vendoredover a hosted BOM file writes the vendored line without the BOM (pip reads either form);rollbackrestores the BOM.Agent
rollback --offlineneeds the before blob in.socket/blobs; without it, it refuses with arepairhint (harness staging, not a bug).Hosted wheel pins under a
--no-binary :all:/--no-binary six/--only-binary :all:option line install fine (pip 24.3.1, 26.2.1): pip doesn't apply format control to direct URLs.Vendored
vendorrefuses a UTF-16 requirements.txt loudly (pypi_no_requirements, exit 1), andvexwarnslockfile_unreadable; only hosted / lock-only discovery is silent (Hosted and lock-only scans treat a UTF-16 requirements.txt (what Windows PowerShell'spip freeze >writes) as absent: exit 0, no warning, and pip keeps installing the unpatched pin #721).A hashed root requirements.txt used as
-cby an unhashed sibling is refused by pip before any rewrite; only the unhashed form is Hosted and vendored rewrites of a requirements.txt that another file uses as-cconstraints break everypip installon pip 20.3–21.0 ("Links are not allowed as constraints"), with no warning #740.pip ≥ 21.1 accepts both the hosted
name @ urland the vendored bare-path line as constraints; only pip 20.3.x–21.0.x reject them (Hosted and vendored rewrites of a requirements.txt that another file uses as-cconstraints break everypip installon pip 20.3–21.0 ("Links are not allowed as constraints"), with no warning #740).vendor --offlineneeds the vendoring service in v5 (vendor_service_offline_conflict). Local vendored repros use theprebuilt_commonfixture server plus aview/<uuid>route.The
-c/PIP_CONSTRAINT/ pip.confconstraint =forms over a hosted or vendored root fail only on pip 20.3–21.0 (same as Hosted and vendored rewrites of a requirements.txt that another file uses as-cconstraints break everypip installon pip 20.3–21.0 ("Links are not allowed as constraints"), with no warning #740); don't re-file them.vendor --revertafter a Vendored requirements.txt after the user removes or bumps a vendored pin: the rescan re-adds the removed package as a "(transitive)" line (exit 0), or exits 1 forever after a bump, andscan --prunenever reverts the entry #786-style re-add is safe: the stalerequirements.txt:1wiring is skipped asvendor_revert_line_drifted, and the user's line stays untouched.The uv routine's handover (hosted rewrite overrides a
six @ https://…direct reference, and rollback restoressix==1.16.0) is Hosted requirements.txt rewrite replaces a user's own direct reference (six @ https://mirror/…/six-1.16.0-….whl,file://fork) with the Socket PyPI build, and rollback then restoressix==1.16.0from PyPI, losing the original source #542; don't re-file it.Vendored over a
pip lockpylock.toml works end to end (archive = { path }, pip 26.2.1 install from any CWD, byte-identicalvendor --revert); only the hosted restore is Hosted rollback and remove always refuse apip lockpylock.toml ("no sibling registry package shows the registry and artifact fields"), because pip writes[[packages.wheels]]tables, not uv's inlinewheels = [...]#804.remove/rollbackwith a qualified purl (…@1.16.0?foo=bar) givesnot_foundby design (a qualified identifier targets a single variant).A stale
.pyc(Agent-mode apply of a same-size PyPI patch in the same second aspip installleaves pip's__pycache__bytecode valid, so Python keeps running the unpatched code while apply reports it patched #819) needs pip's timestamp.pyc:SOURCE_DATE_EPOCH(checked-hash),--no-compile, uv without--compile-bytecode, and hosted / vendored mode are unaffected.The agent-mode
.dist-info/RECORDgoes stale after apply; this is documented (thepypi_record_staleadvisory). Agentvexafterpip install --force-reinstallcorrectly omits the package (not_applied).A superseding re-vendor refuses a vendor line the user moved into a
-rinclude (pypi_requirements_already_vendored, exit 1, remedyvendor --revert), while--dry-runpreviewswould_revendor. The contract defines the preview as ledger classification only; the harmful part is the remedy, which is Vendored requirements.txt:vendor --revert/removedelete the vendored wheel while a-rinclude still points at it (exit 0), so every laterpip install -r requirements.txtfails #867.When testing vendored discovery with a mock, the
batchroute must answer only for requested purls. A catch-all answer re-vendors removed packages as(transitive)(a false Vendored requirements.txt after the user removes or bumps a vendored pin: the rescan re-adds the removed package as a "(transitive)" line (exit 0), or exits 1 forever after a bump, andscan --prunenever reverts the entry #786 regression).A rewrite splits a hardlinked requirements.txt (this is inherent to the atomic stage-and-rename write), and a 0444 file is rewritten in the sandbox only because it runs as root.
pip install -r pylock.tomlneeds pip ≥ 26.1-ish (26.2.1 works; 26.0 parses it as a requirements file and fails on=). That's a pip version limit, not socket-patch.A socket.yml
minSeverityfloor over an already-hosted pin keeps it byte-identical, and the JSON reports it as a same-uuidredirected: 1, not underretained[](consistent with "keeps its recorded patch").--max-new-patchesdeferral ranks by severity from the patch record'svulnerabilities; a mock with an empty map showsseverity: "unknown"and alphabetical order (harness artifact).apply --checkwith no venv (noVIRTUAL_ENV, no.venv/venv) checks the system site-packages through the documented project-marker global fallback, the same asapply(backlog question 0b), 2026-10-08.py3X-none-anywheels count as portable under Fix interpreter-bound wheels treated as portable (#1048) #1053's rule; pip installs them on every Python ≥ 3.X, so that matches pip (2026-10-08).Hosted mode over a non-UTF-8 requirements.txt root (latin-1 bytes under a latin-1 coding line) refuses
candidate_file_unreadable, exit 1, nothing written. That's fail-closed and loud; a UTF-8 root with a latin-1-rinclude works (2026-10-09).The vendored state of a UTF-8-BOM requirements.txt (via the fix: vendor hosted patches directly from lockfiles #1648 eject) drops the BOM;
vendor --revertrestores it byte for byte, and pip reads the file the same either way. Cosmetic, not filed (run 48).After an eject, a re-run of plain
vendorreportsnoManifestwith exit 0 and changes no byte (the eject leaves no.socket/manifest.json). Expected (run 48).Hosted on a
_/.name (Typing.Extensions[Foo]==X ; marker) rewrites totyping_extensions[Foo] @ urland restorestyping_extensions[Foo]==X ; marker: the name case and spelling are normalised, which pip reads the same way (same class as the restore normalisation above; 2026-10-28).With a pip-compile hashed pin that has two
--hashlines, hosted rollback restores one hash per PyPI JSON file, not the original hash list. It matches the "pip-equivalent line" restore above and installs under hash-checking mode (2026-10-28). An earlier apparent "hash dropped" result came from a fixture with an unhashed sibling, so it wasn't in hash-checking mode.All reactions