Hosted `rollback`, `remove` and the vendored takeover refuse a requirements.txt whose only requirements are hosted pins (`six==1.16.0` alone can be patched but never unpatched)
メンテナーはふだん 1 日以内に返信
まだ誰も着手していません。
評価
- 難易度
- 3/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 74/100
調査の方向性
Start at crates/socket-patch-core/src/patch/redirect/upstream/pypi.rs:597-603, especially the hash_mode decision, and reproduce the single-pin requirements.txt case with rollback, remove, and scan --mode vendored. Trace how hosted restoration handles pins, options, and editables; done means these commands restore or take over an all-hosted requirements.txt without the current refusal, while preserving the existing behavior for hashed files.
索引モデルが issue の本文から書いたものです。
説明
[agent] Found by the scheduled pip / requirements.txt bug-hunt routine (ledger #309).
Summary
v5 hosted rollback, remove and the hosted → vendored takeover (scan --mode vendored over a hosted pin) all refuse a requirements.txt when every requirement line in it is a hosted pin. The simplest project shape, a single six==1.16.0 line, can be patched by socket-patch scan but can't be un-patched or vendored afterwards.
The refusal comes from the upstream restore. It tries to infer pip's hash-checking mode from the other requirement lines, and when there are none it gives up:
cannot restore pkg:pypi/[email protected] to its upstream registry entry: every requirement in requirements.txt is a hosted pin, so whether the original used pip's hash-checking mode (`--hash`) is not derivable; restore it from version control instead (`git checkout -- requirements.txt`)
The same refusal fires when the only other lines are options or editables. For example, -e . plus a pin is refused, even though -e lines are incompatible with hash-checking mode, so the original must have been unhashed.
Impact
socket-patch rollbackandsocket-patch remove <purl>exit 1 (partial_failure/hosted_revert_failed) on single-dependency projects, on projects where every pin is patched, and on-e .+ pin projects.socket-patch scan --mode vendoredon such a hosted project can't take over:Vendored 0 packages; 1 failed., exit 1, and the project stays hosted. The documented mode-takeover path (CLI_CONTRACT.md, "Takeover reconciliation (every hosted ecosystem, v5.0)") is unusable for these projects.- v5 keeps no hosted ledger, so the CLI can't undo the rewrite at all. The only remedy is version control.
Repro
Uses a local mock of the patch API that serves a patched six-1.16.0 wheel. It's the same shape as tests/vex_pypi_real_common::RealApi: POST /v0/orgs/test-org/patches/batch, /patches/package grant, /patches/view/<uuid>, and the wheel route. Linux, pip 24.0, CPython 3.11, main 2463257.
A="--api-url http://127.0.0.1:8765 --api-token fake --org test-org --patch-server-url http://127.0.0.1:8765"
mkdir p && cd p && printf 'six==1.16.0\n' > requirements.txt
socket-patch scan $A # Switched 1 package to hosted patches; rewrote 1 file.
socket-patch rollback --yes $A; echo $? # Error: Cannot restore … not derivable … → 1
socket-patch remove pkg:pypi/[email protected] --yes $A; echo $? # same error → 1
socket-patch scan --mode vendored $A; echo $? # Cannot vendor … not derivable … Vendored 0 packages; 1 failed. → 1
Variants I checked (scan, then rollback):
| requirements.txt before scan | rollback |
|---|---|
six==1.16.0 |
refused |
-e . + six==1.16.0 |
refused |
six==1.16.0 --hash=… --hash=… (only line) |
refused |
six==1.16.0 + idna==3.7 |
restored |
--require-hashes + hashed six |
restored |
--index-url … + six==1.16.0 + idna==3.7 |
restored |
pip-compile hashed idna + six (LF and CRLF) |
restored byte-exact |
Expected vs actual
- Expected: CLI_CONTRACT.md, "Hosted unwind coverage", says every file wiring a pin is rewritten back to the default upstream entry. The pypi bullet lists what gets refused:
pdm.lockwithoutcross_platform, non-pure uv / pylock wheels, uv option filters, and uv 0.2 locks. An all-hostedrequirements.txtisn't in that list. When no other requirement constrains the mode, either restored form,six==1.16.0orsix==1.16.0 --hash=…for every release file, installs with every pip, because there is no other line it could conflict with. A-eline also settles the mode as unhashed. - Actual: the pin is refused in
rollback,removeand the takeover.
OS × version
| OS | pip / Python | reproduces |
|---|---|---|
| Linux (sandbox) | 24.0 / 3.11 (CLI-only; no pip step involved) | yes, twice |
| ubuntu-latest (probe) | 20.3.4 / 3.8 | yes (rollback, remove and takeover all refused, exit 1) |
| ubuntu-latest (probe) | 25.0.1 / 3.8 | yes (rollback, remove and takeover all refused, exit 1) |
| ubuntu-latest (probe) | 26.2.1 / 3.13 | yes (rollback, remove and takeover all refused, exit 1) |
| macos-latest (probe) | 20.3.4 / 3.8 | yes (rollback, remove and takeover all refused, exit 1) |
| macos-latest (probe) | 25.0.1 / 3.8 | yes (rollback, remove and takeover all refused, exit 1) |
| macos-latest (probe) | 26.2.1 / 3.13 | yes (rollback, remove and takeover all refused, exit 1) |
| windows-latest (probe) | 20.3.4 / 3.8 | yes (rollback, remove and takeover all refused, exit 1) |
| windows-latest (probe) | 25.0.1 / 3.8 | yes (rollback, remove and takeover all refused, exit 1) |
| windows-latest (probe) | 26.2.1 / 3.13 | yes (rollback, remove and takeover all refused, exit 1) |
| all 3 OS (probe) | 20.3.4 / 3.13 | blocked: pip 20.3.4 can't run on 3.13 (no distutils) |
The refusal is decided before any pip runs, so it doesn't depend on the pip version.
First bad
The code is new in 2463257 (#277), which replaced v4's ledger replay with the upstream restore. I didn't get a clean comparison: on v4.0.0, rollback of the same hosted project stopped at Manifest not found even though .socket/vendor/redirect-state.json existed.
Suspect code
crates/socket-patch-core/src/patch/redirect/upstream/pypi.rs:597-603: the(false, false)arm ofhash_mode.--prefixed lines,-eincluded, are skipped before the mode tally (if code.starts_with('-') { continue; }).- Related: #376. The hosted writer always emits
--hash, so the line itself never records the original mode. Once #376 / #383 switch unhashed files to a#sha256=fragment, the hosted line's own shape (--hashvs fragment) would say which mode to restore.
Probe run: https://github.com/SocketDev/socket-patch/actions/runs/36806309982
- 主要言語
- Rust
- スター
- 8
- フォーク
- 0
- 平均マージ
- 18時間 4分
- マージ済み PR(30日)
- 70
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
SocketDev/socket-patch のほかの issue
-
agent:triaged bug bughunt pm:composer priority:p2
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
SocketDev/socket-patch#515 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
agent:triaged bug bughunt pm:npm priority:p1
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
SocketDev/socket-patch#464 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
agent:triaged bug bughunt pm:npm priority:p1
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
SocketDev/socket-patch#433 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
agent:triaged bug bughunt pm:uv priority:p1
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
SocketDev/socket-patch#408 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
agent:triaged bug bughunt pm:yarn-berry priority:p1
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
SocketDev/socket-patch#370 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
SocketDev/socket-patch の issue をすべて見る
似ている issue
-
discover: `sudo RTK_DISABLED=$VAR …` is not detected as a bypass when `sudo` is a transparent prefixオープンarea:cli bug good first issue priority:medium
難易度 2/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
skill:code-review
難易度 1/5 1〜3時間 初心者へのやさしさ 88/100
メンテナーはふだん 1 日以内に返信
-
component:sight
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
agentic-os-org/ANOLISA#4115 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
rivet-dev/rivet#5819 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
A-io-database bug needs triage python
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
メンテナーはふだん 1 日以内に返信