Hacktoberfest 2026: die Issues, die Maintainer für den Oktober markiert haben – offen und einsteigerfreundlich. Hacktoberfest-Issues durchsuchen

scan --sync / --mode agent never re-applies an already-recorded patch, so after a fresh Hatch env (or any reinstall) it exits 0 with the package unpatched

Offen
#454 3 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen

Maintainer antworten meist innerhalb von 1 Tag

Dieses Issue hat noch niemand übernommen.

Bewertung

Schwierigkeit
3/5
Geschätzter Aufwand
1-2 Tage
Anfängerfreundlichkeit
72/100
Issue-Typ
Bug
Klarheit
Klar beschrieben
Aktivitätsstatus
Aktiv
Tech-Stack
python, rust
Bereich
cli

Rechercherichtung

Start in crates/socket-patch-cli/src/commands/get.rs at the downloaded > 0 gates around lines 2438 and 2485, then trace how scan --mode agent and --sync call download_and_apply_patches_with. Use the provided Hatch reproduction to verify that a second scan after recreating the environment reapplies the recorded patch and does not report success when application fails. The issue does not name a test file.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Beschreibung

agent:claimed agent:triaged bug bughunt pm:hatch priority:p1

[agent] Found by the scheduled Hatch bug-hunt routine (ledger #314).

Summary

scan --mode agent and scan --sync only run the nested apply when the run downloaded a new or updated patch record. When every discovered patch is already in .socket/manifest.json, the records come back skipped and apply never runs. The installed files aren't checked or re-patched, and the scan reports "status": "success", applied: 0, exit 0.

So after anything that reinstalls the package (hatch env remove + hatch env create, hatch env prune, a CI cache miss, a new matrix env, pip install --force-reinstall, or a failed first apply), re-running the scan leaves the environment unpatched and reports success. The same happens with --global-prefix / -g after a first run whose apply failed: once the prefix is writable again, the re-run exits 0 and still doesn't patch it.

This isn't Hatch-specific. The gate is in the shared download_and_apply_patches_with. I found it with real Hatch, where recreating envs is routine.

Impact

--sync is documented as the one-shot reconciliation: the help text at crates/socket-patch-cli/src/commands/scan/mod.rs:289 says "a cron job or CI workflow can run socket-patch scan --json --sync to end up fully reconciled in one invocation". A CI job that runs hatch env create && socket-patch scan --sync --json passes green on every run after the first while the env runs the vulnerable code. The only signal is that vex afterwards refuses to attest (not_applied), which is correct but easy to miss.

Repro (Linux, Hatch 1.18.1, mock patch API serving a six 1.16.0 patch)

mkdir rr && cd rr && mkdir app && touch app/__init__.py
cat > pyproject.toml <<'EOF'
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[project]
name = "app"
version = "0.1.0"
dependencies = ["six==1.16.0"]

[tool.hatch.build.targets.wheel]
packages = ["app"]

[tool.hatch.envs.default]
path = ".venv"
EOF
export SOCKET_API_URL=http://127.0.0.1:8765 SOCKET_API_TOKEN=fake SOCKET_ORG_SLUG=org SOCKET_PATCH_SERVER_URL=http://127.0.0.1:8765
hatch env create
socket-patch scan --mode agent --json --yes      # applied 1, six patched
hatch env remove default && hatch env create      # fresh env, pristine six
socket-patch scan --mode agent --json --yes; echo $?   # success, skipped 1, applied 0, exit 0, six NOT patched
hatch env remove default && hatch env create
socket-patch scan --sync --json --yes; echo $?         # same: success, skipped 1, exit 0, six NOT patched
socket-patch apply --json                              # applied 1: the only thing that actually reconciles

Output on 1.18.1 (the 1.7.0 output is identical):

  scan --mode agent: success applied 1 skipped 0 exit=0 import_patched=True
 -- hatch env remove + create
  scan --mode agent: success applied 0 skipped 1 exit=0 import_patched=False
 -- hatch env remove + create
  scan --sync: success applied 0 skipped 1 exit=0 import_patched=False
Warning: omitting pkg:pypi/[email protected] from VEX: the patched files still hold the original content (not_applied)

Global-prefix variant, without Hatch: pip install --target <prefix> six==1.16.0, then scan --global-prefix <prefix> --mode agent (applied 1), reinstall six, then re-scan. The re-scan gives success, skipped 1, exit 0, unpatched. --sync does the same, and each ran twice. Starting from a read-only prefix as non-root (runuser -u nobody), the first scan exits 1 (its JSON is the #424 shape), and the second scan exits 0 with success even after the prefix is made writable again.

Expected vs actual

  • Expected: scan --mode agent records and applies (docs/usage.md "Agent mode records patches and applies them to installed files"), and --sync ends "fully reconciled in one invocation". A record that's already in the manifest but not applied to the installed copy should be applied, as apply does. At minimum, the scan shouldn't report success / exit 0 while a discovered, recorded patch is unapplied.
  • Actual: skipped records short-circuit the nested apply, and the installed tree is never looked at.

OS × version

Cell Result
Linux, Hatch 1.18.1, .venv env, scan --mode agent after env recreate ❌ exit 0, unpatched
Linux, Hatch 1.18.1, scan --sync after env recreate ❌ exit 0, unpatched
Linux, Hatch 1.7.0, both of the above ❌
Linux, --global-prefix (pip --target), after reinstall, agent and --sync ❌
Linux, --global-prefix read-only then writable, non-root ❌ second run exits 0
socket-patch apply in the same states (control) ✅ re-applies
vex in the same states (control) ✅ omits not_applied

The logic is OS-independent (no path or filesystem handling is involved).

First bad version

Released v4.0.0 (PyPI socket-patch==4.0.0) behaves the same, so this isn't a v5 regression.

Suspect code

  • crates/socket-patch-cli/src/commands/get.rs:2438: let apply_lock = if !params.save_only && downloaded > 0 {. The nested apply (and its lock) only exists when something was downloaded.
  • crates/socket-patch-cli/src/commands/get.rs:2485: apply_failed is gated on downloaded > 0 too, so an all-skipped run can never fail.

Related, but a separate defect: #424 (the scan JSON drops the apply failure on the first run).

Vorherrschende Sprache
Rust
Sterne
8
Forks
0
Ø Merge
19 Std. 56 Min.
Gemergte PRs (30 T.)
51

Entwicklungsumgebung

Erste Schritte

  1. Lesen Sie das ganze Issue und danach den Beitragsleitfaden des Projekts.
  2. Schreiben Sie ins Issue, dass Sie es übernehmen — das erspart doppelte Arbeit.
  3. Forken Sie das Repository und arbeiten Sie in einem Branch.
  4. Öffnen Sie einen Pull Request, der die Issue-Nummer nennt.

Mehr aus SocketDev/socket-patch

Alle Issues in SocketDev/socket-patch

Ähnliche Issues

Weitere Issues zu Rust

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.