Bug hunt ledger: Hatch #314
Replies: 7 comments
|
[agent] 2026-09-30: Hatch bug-hunt run First run. The ledger was empty and there were no earlier Tested: main Filed
Cells covered (Linux, Hatch 1.18.1 unless noted)
Ruled out / not filed
Housekeeping
Next
|
|
[agent] 2026-09-30: Hatch bug-hunt run Tested: main Filed
Commented
Re-triage
Cells covered (Linux)
Ruled out / not filed
Housekeeping
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 Hatch puts global installs: Hatch has no global install. Check What to check (prove each with a real global install, not by reading source):
Add OS × Hatch version cells for |
|
[agent] 2026-10-01: Hatch bug-hunt run Tested: main Filed
Re-triage
Global (
|
| Check | Linux (sandbox + ubuntu) | macOS | Windows |
|---|---|---|---|
scan -g report-only, inside a Hatch project; pyproject untouched, Hatch env dir not crawled |
pass | pass | pass |
scan -g --mode hosted / --global-prefix … --mode hosted / SOCKET_GLOBAL=1 … --mode hosted: exit 2, nothing written |
pass | pass (-g) |
pass (-g) |
pipx-installed Hatch dependency, scan -g --mode agent |
fail #415 | fail #415 | fail #415 |
uv-tool-installed Hatch dependency, -g agent apply + rollback byte-exact |
pass | untested | untested |
--global-prefix "<space>/ünï/site-packages" agent apply / vex not_affected / rollback byte-exact / vex after rollback refuses |
pass | pass | pass |
Agent scan without -g in a Hatch project: falls back to the global interpreter, applied 0, exit 1 |
as #335 (system copy not modified) | ||
| Read-only global prefix | blocked (sandbox runs as root) | untested | untested |
Ruled out / not filed
scan -g"finding" six in every run: an artifact of the mock, whose/patches/batchanswers six for any purl.scannedPackagesand the apply result are the real signal.- Debian's apt
python3-six(six-1.16.0.egg-infoin/usr/lib/python3/dist-packages) is not crawled at all: egg-info-only packages are invisible. This isn't Hatch-specific, it's generic to pip/distro packages, and I didn't verify whether it's intended, so it's noted here for the pip routine rather than filed. apply -gprinting "The targeted manifest patch matched no installed package" with exit 0: this happens after a prior agent run recorded the patch. Not investigated further.
Housekeeping
- The probe branches
bughunt/hatch/20261001-global-pipxandbughunt/hatch/20260930-stale-envstill can't be deleted (the git proxy hangs up on ref deletes). A maintainer should delete them.
Next
-gon macOS / Windows with a uv-tool Hatch, and a read-only prefix (probe, non-root runner).- The vendored Hatch rollback and remove refuse with "configuration drifted" after the project version is bumped or a dependency is added, in both hosted and vendored mode #385 / Hosted Hatch rewrite leaves an existing Hatch environment unpatched with no stale-install warning, and vex still attests not_affected #335 cells on Hatch 1.7.0 and with
installer = "uv"envs. - Refusal correctness:
overrides,template,[env]collectors, hatch-pip-compile env type, hatch.tomlenvsnon-table. - Multi-patch
rollback <purl>/--preserve-stateandallow-direct-referencesownership (the mock needs a second package). - Hatch 1.0 / 1.1 / 1.2 vendored-env boundary; 1.14.x with a pinned virtualenv.
|
[agent] 2026-10-01: Hatch bug-hunt run Tested: main Filed
Commented
Re-triage
Global (
|
| Check | Linux | macOS | Windows |
|---|---|---|---|
uv-tool Hatch (1.9.7 / 1.16.5 / 1.18.1): scan -g report-only, pyproject untouched |
pass | pass (job green) | pass (report) |
uv-tool Hatch -g agent apply / vex / rollback byte-exact |
pass | pass (job green; the log wasn't retrievable, 404) | fail #449 |
UV_TOOL_DIR custom tool dir |
fail #449 | untested | untested |
Read-only prefix, root-owned, non-root user (runuser -u nobody) |
scan exits 1, but the JSON has failed: 0 and no error (#424); apply exits 1 apply_failed "Permission denied"; the re-run exits 0 (#454) |
||
| Read-only prefix the user owns (chmod 0444/0555) | patched (the owner can write; not a bug) | attrib +R: exit 1, unpatched, vex omits not_applied |
|
| Read-only, then writable again: re-scan | fail #454 (exit 0, unpatched) |
Probe: https://github.com/SocketDev/socket-patch/actions/runs/36845418214
Refusal / shape matrix (Linux, Hatch 1.18.1, hosted, fresh hatch env create from the rewrite)
- Pass (rewritten, and the fresh env imports the patched six):
templateinheritance, dottedenvs.default.dependencies, matrix env (test.py3.11),features→ optional-dependencies,detachedenv, and hatch.toml[envs]overriding pyproject envs (only hatch.toml is rewritten, matching hatchling's top-levelupdate()merge). - Refused with nothing written (documented): env
overrides,[tool.hatch.env] requires,type = "pip-compile", hatch.tomlenvs = 1. - Observation, not filed:
six==1.16(PEP 440-equal to 1.16.0) is refused with "requires an exact ==1.16.0 declaration". It's a minor over-refusal that fails closed.
Ruled out / not filed
- Hosted
rollback→Manifest not foundwhen the mock URL host isn't--patch-server-url: a harness artifact (see above). - The ubuntu probe "read-only" prefix getting patched: the runner user owned the files, so it could restore write permission. A root-owned prefix fails as expected.
Housekeeping
- Probe branches
bughunt/hatch/20260930-stale-env,bughunt/hatch/20261001-global-pipxand nowbughunt/hatch/20261001-uvtool-rostill can't be deleted (the git proxy hangs up on ref deletes). A maintainer should delete them.
Next
- Vendored → hosted takeover for Hatch, when Poetry hosted ⇄ vendored mode switch is refused, and blames a "user-authored" source that socket-patch wrote itself #328 moves; multi-patch
rollback <purl>(the mock needs a second package). - Vendored Hatch rollback and remove refuse with "configuration drifted" after the project version is bumped or a dependency is added, in both hosted and vendored mode #385 / Hosted Hatch rewrite leaves an existing Hatch environment unpatched with no stale-install warning, and vex still attests not_affected #335 cells on Hatch 1.7.0 and with
installer = "uv"envs. - Hatch 1.0 / 1.1 / 1.2 vendored-env boundary; 1.14.x with a pinned virtualenv.
- Workspaces (Hatch 1.16+
workspace.members) on v5; CRLF / BOM pyproject on v5. - Re-triage Hosted Hatch rewrite leaves an existing Hatch environment unpatched with no stale-install warning, and vex still attests not_affected #335, Hatch rollback and remove refuse with "configuration drifted" after the project version is bumped or a dependency is added, in both hosted and vendored mode #385, Global scan (-g) never crawls pipx venvs, so the dependencies of a pipx-installed Hatch are never reported, patched or rolled back on any OS #415 (Fix global scan missing pipx venvs (#415) #418), 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 #454 when main moves.
|
[agent] 2026-10-01: Hatch bug-hunt run Tested: main Filed
Re-triage (main
|
| Cell | Result |
|---|---|
Locked env (locked = true, uv locker), hosted, 1.17.0 / 1.18.1, L/M/W |
fail #479 |
| Locked env, vendored, 1.17.0 / 1.18.1, L/M/W | fail #479 |
Locked named env (pylock.test.toml), hosted, 1.18.1 Linux |
fail #479 |
hatch dep lock --export pylock.toml, non-locked env, hosted, 1.18.1 Linux |
fail #479 |
| Locked env with no committed pylock (pyproject lane), hosted, 1.18.1 Linux | pass |
Locked env, installer = "pip" |
n/a: Hatch's pip locker can't apply lockfiles (LockerUnsupportedError) |
Ruled out / not filed
- Hatch's sync under
uv tool runwith uv 0.12 left six uninstalled. This is a harness artifact: uv exportsUV/UV_INTERNAL__PARENT_INTERPRETERinto the child, so the probe now calls installed Hatch binaries with those variables removed. hatch dep lock --checkexits 2 on 1.17.0 (the CLI shape differs); it isn't used as evidence there.
Housekeeping
- Probe branch
bughunt/hatch/20261001-pylock-relockcouldn't be deleted (the git proxy hangs up on ref deletes, as before). A maintainer should delete it, along withbughunt/hatch/20260930-stale-env,bughunt/hatch/20261001-global-pipxandbughunt/hatch/20261001-uvtool-ro.
Next
- Lock follow-ups (Hatch 1.17+ projects with a hatch-generated pylock.toml get only the lock rewritten, and Hatch regenerates it from pyproject, so hosted and vendored patches are silently dropped #479 siblings):
lock-filenamewith context formatting,lock-envs = trueglobally, matrix envs sharing a lock,hatch dep sync, and rollback / remove on a pylock-wired Hatch project (also see Hosted rollback, remove and vendored takeover always refuse on auv pip compilepylock.toml because its packages carry noindexkey #407). - Global-mode remainder:
UV_TOOL_DIRon macOS / Windows; a read-only root-owned prefix on macOS; Windows Program Files. - Vendored → hosted takeover (Poetry hosted ⇄ vendored mode switch is refused, and blames a "user-authored" source that socket-patch wrote itself #328) once it moves; multi-patch
rollback <purl>(second mock package). - Workspaces (1.16+
workspace.members) and CRLF / BOM pyproject on v5; Hatch 1.0–1.2 vendored boundary. - Re-triage Hosted Hatch rewrite leaves an existing Hatch environment unpatched with no stale-install warning, and vex still attests not_affected #335, Hatch rollback and remove refuse with "configuration drifted" after the project version is bumped or a dependency is added, in both hosted and vendored mode #385, Global scan (-g) never crawls pipx venvs, so the dependencies of a pipx-installed Hatch are never reported, patched or rolled back on any OS #415, 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 #454 (Fix agent scan/get skipping apply for recorded patches (#454) #456), Hatch 1.17+ projects with a hatch-generated pylock.toml get only the lock rewritten, and Hatch regenerates it from pyproject, so hosted and vendored patches are silently dropped #479 when main moves.
|
[agent] 2026-10-01: Hatch bug-hunt run Tested: main Filed
Re-triage (main
|
| Cell | Result |
|---|---|
| CRLF pyproject, hosted / vendored, 1.18.1: fresh env patched, rollback byte-exact | pass / pass |
| BOM pyproject (± CRLF) | n/a: Hatch's tomllib rejects a BOM (TOMLDecodeError at 1:1). Hosted strips the BOM and rollback doesn't restore it; vendored keeps it. Not filed. |
| Workspace (1.16+), member-only dep scanned from root, hosted | refused as documented |
| Workspace, scanned from member, hosted, 1.18.1 | pass (fresh root env patched) |
| Workspace, scanned from member, vendored, 1.16.5 / 1.18.1 | fail #505 |
| #385 rollback after version bump / added dep, hosted | pass |
| #385 rollback after version bump, vendored | fail #385 |
Ruled out / not filed
- The vex
not_appliedon Hosted Hatch rewrite leaves an existing Hatch environment unpatched with no stale-install warning, and vex still attests not_affected #335 comes from the sandbox's system six (/usr/lib/python3/dist-packages), not from discovery of the Hatch env. - BOM pyproject: Hatch itself can't load it.
--vendor-source buildwas removed on v5 (useservice), so it's a harness change, not a bug.
Next
- Vendored scan in a Hatch workspace member writes {root:uri} that the workspace root env never expands, so every hatch run at the root fails to install #505 follow-ups: a workspace member with features (
members = [{path=…, features=[…]}]), a member with dynamic deps,[envs.*.workspace]in hatch.toml, and probing Vendored scan in a Hatch workspace member writes {root:uri} that the workspace root env never expands, so every hatch run at the root fails to install #505 on macOS / Windows. - Hatch 1.17+ projects with a hatch-generated pylock.toml get only the lock rewritten, and Hatch regenerates it from pyproject, so hosted and vendored patches are silently dropped #479 follow-ups:
lock-filenamecontext formatting, globallock-envs, matrix envs sharing a lock,hatch dep sync, rollback / remove on a pylock-wired project. - Global-mode remainder:
UV_TOOL_DIRon macOS / Windows; a read-only root-owned prefix on macOS; Windows Program Files. - Vendored → hosted takeover (Poetry hosted ⇄ vendored mode switch is refused, and blames a "user-authored" source that socket-patch wrote itself #328); multi-patch
rollback <purl>(second mock package). - Hatch 1.0–1.2 vendored boundary; re-triage Hosted Hatch rewrite leaves an existing Hatch environment unpatched with no stale-install warning, and vex still attests not_affected #335, Hatch rollback and remove refuse with "configuration drifted" after the project version is bumped or a dependency is added, in both hosted and vendored mode #385 (vendored), Hatch 1.17+ projects with a hatch-generated pylock.toml get only the lock rewritten, and Hatch regenerates it from pyproject, so hosted and vendored patches are silently dropped #479, Vendored scan in a Hatch workspace member writes {root:uri} that the workspace root env never expands, so every hatch run at the root fails to install #505 when main moves.
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 Hatch bug-hunt routine (label pm:hatch).
Last run: 2026-10-01 21:53Z on main
61cfb9b. The latest tag v4.0.0 predates Hatch support (#244). Linux runs use real Hatch against a local mock patch API (six 1.16.0; v5 vendored uses--vendor-source service(localbuildwas removed) and needsintegrity.sha512in the mock, the grant artifactkindmust betarball, andSOCKET_PATCH_SERVER_URLmust point at the mock so hosted wiring is recognised). macOS and Windows use probe branches.Coverage matrix
-g, pipx-installed (L / M / W)-g, uv-tool-installed (L / M / W)hatch lock)hatch lock)hatch lock)hatch lock)hatch lock)61cfb9b) / fail #385UV_TOOL_DIRfail #449 (Linux)Also on v5:
scan -gis report-only and never touches pyproject or the Hatch env dirs;-g/--global-prefix/SOCKET_GLOBAL=1with--mode hostedexit 2 and write nothing. Fresh-environment installs of hosted and vendored rewrites pass on 1.18.1 (and on 1.7.0 for vendored). Locked env with no committed pylock (pyproject lane) passes on 1.18.1. On main6e7ef74: #335 and the vendored #385 cell still reproduce, and the hosted version-bump rollback passes. Workspaces (1.16.5 / 1.18.1, v5): a member-only dependency is refused from the root with a warning. Scanned from the member, hosted passes (fresh root env patched) but vendored fails #505: the root env doesn't expand{root:uri}in member deps. CRLF pyproject on v5: hosted and vendored pass, with fresh env patched and rollback byte-exact (1.18.1). On main61cfb9b: #335 and the vendored #385 cell still reproduce; the hosted #385 cells (version bump, added dependency) pass. #454 and #415 are fixed and closed.Backlog
features, dynamic-dep members,workspacedeclared in hatch.toml; probe Vendored scan in a Hatch workspace member writes {root:uri} that the workspace root env never expands, so every hatch run at the root fails to install #505 on macOS / Windows.lock-filenamecontext formatting, globallock-envs, matrix envs sharing a lock,hatch dep sync, rollback / remove on a pylock-wired Hatch project (see Hosted rollback, remove and vendored takeover always refuse on auv pip compilepylock.toml because its packages carry noindexkey #407).UV_TOOL_DIRon macOS / Windows; a read-only, root-owned prefix on macOS (needs sudo on the runner); Windows Program Files prefix.rollback <purl>/--preserve-stateandallow-direct-referencesownership (the mock needs a second package).installer = "uv"envs.Known non-bugs
installer = "pip": Hatch's pip locker can't apply lockfiles (LockerUnsupportedError), so it's a Hatch limitation.uv tool runwith uv 0.12 leaksUV/UV_INTERNAL__PARENT_INTERPRETERand breaks Hatch's locked sync: a harness artifact. Use installed Hatch binaries.{root:uri}there): documented.installer = "uv"/uv-pathis refused: documented. Note that uv 0.12 does enforce local wheel hashes, so the documented rationale looks outdated. Hatch's internal uv envs (hatch-testetc.) aren't covered by the refusal, but the hash is still enforced (verified with a tampered wheel).hatch>= 1.2 on PATH (preflightpypi_hatch_unsupported): documented, including forpipx run/uvxusers.Requires-Dist(so the result can't be uploaded to PyPI): inherent to the design.rollbackwith nothing ever written exits 2Manifest not found.removeafter a full rollback givesmanifest_not_found.vendor_prebuilt_requiredunless the grant's artifact carriesintegrity.sha512(v5): a harness requirement, not a bug.scannedPackagesand the apply results, notpackages[], to judge discovery.scan -g, and the bare-ghosted refusal, print the usage error to stderr only, even with--json(exit 2): this matches the exit-code table.rollbackonly recognises wiring onpatch.socket.devor the--patch-server-urlorigin. A mock URL on another origin givesManifest not found, which is a harness artifact.overrides,[tool.hatch.env](requires / collectors), custom envtype, and a non-tableenvsin hatch.toml are refused with nothing written: documented.six==1.16(PEP 440-equal to the installed 1.16.0) is refused as not exact. It's a minor over-refusal that fails closed, logged rather than filed.TOMLDecodeErrorat 1:1). Hosted strips the BOM and rollback doesn't restore it; vendored preserves it. Not filed, because the input is invalid for Hatch.not_appliedbecause of the system/usr/lib/python3/dist-packages/six.py: a sandbox artifact.All reactions