Skip to content

Commit 62869a2

Browse files
authored
Merge pull request #152 from PyAutoLabs/claude/automind-task-planning-163wk7
prompt: file + fix pre_build untracked-staging leak
2 parents f715790 + 0f97997 commit 62869a2

3 files changed

Lines changed: 92 additions & 2 deletions

File tree

active.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
- validation: Stage 0/1 preflight PASS. Stage 2 rehearsal run 31192317261 (PyAutoHands release.yml, rehearsal:true) → testpypi 2026.8.7.1.dev70601. Stage 3 integrate run 31193443960 (PyAutoHeart release-integrate.yml) → 51/51 jobs green, `status: pass`, 657p/0f/101s/0t, verify_install checks A–F all PASS. Artifacts `~/.pyauto-heart/manual_validation_20260807`.
5757
- MGE-regression NOT reproduced: the 2026-08-06 integrate failed on `scripts/interferometer/features/multi_gaussian_expansion/likelihood_function.py` (numpy LinAlgError: Singular matrix). It passed here — and the script genuinely RAN rather than being silently dropped, proven by the count moving 324p+1f → 325p+0f with the total unchanged.
5858
- ingest-trap (cost one cycle): the first readiness tick after a clean ingest came back RED with `stale_reasons: []` and only `PyAutoGalaxy/PyAutoLens: 4 commit(s) behind origin`. That is a LOCAL-clone signal, not a validation failure — the merged workflow_dispatch PRs had never been pulled. Fast-forwarding both local mains to the validated SHAs re-ticked GREEN score 100. Do not `--force` past this; sync the clone.
59-
- pre_build-trap (caught before it fired): `pre_build` runs `black scripts/` then `git add scripts/`, and `git add` on a directory stages UNTRACKED files too — an uncommitted WIP script in `autolens_assistant/scripts/` would have been reformatted and pushed public inside the "pre build" commit. This is the same leak class the script's own comments describe fixing for `dataset/`/`config/` (#126); the `scripts/` path still has the hole. Mitigation used: move the file out of the repo before the run, restore after (verified byte-identical by md5). Worth a real fix so it is not left to operator vigilance.
59+
- pre_build-trap (caught before it fired): `pre_build` runs `black scripts/` then `git add scripts/`, and `git add` on a directory stages UNTRACKED files too — an uncommitted WIP script in `autolens_assistant/scripts/` would have been reformatted and pushed public inside the "pre build" commit. This is the same leak class the script's own comments describe fixing for `dataset/`/`config/` (#126); the `scripts/` path still has the hole. Mitigation used: move the file out of the repo before the run, restore after (verified byte-identical by md5). Worth a real fix so it is not left to operator vigilance. FIXED 2026-08-08 on branch `claude/automind-task-planning-163wk7` (PyAutoHands) — prompt `draft/bug/pyautohands/pre_build_stages_untracked_wip.md`. The hazard was first REPRODUCED against the pre-fix script on throwaway fixture repos (private file committed as "pre build" and pushed to the remote, exit 0, silently), then closed by two legs: a fail-fast preflight sweeping all 13 repos for untracked files under `notebooks/`/`scripts/`/`slam_pipeline/` before the first is touched (it must precede everything — run_workspace pushes each repo before moving to the next), and staging narrowed to `git add -u` plus explicit adds of run-created files, so the directory-wide form cannot return. Covered by `tests/test_pre_build_staging.py`, which runs the real script against fixture git repos with real bare remotes. No `--allow-dirty` override by design. Also answers the open atomicity question in PyAutoHands `docs/pre_build_failure_audit.md` §6. NOT YET ISSUED/PR'd — no GitHub issue filed, branch not merged.
6060
- release-run: 31200419263 (PyAutoHands release.yml, rehearsal:false → live). All five `release (...)` publish jobs SUCCESS; tags pushed and PyPI agree, so the line-428 hazard (upload timing out AFTER tagging) did not occur.
6161
- post-publish failures (do NOT re-drive the release for these — the publish is complete and correct): (1) `wiki_currency_check` autolens — died on `No matching distribution found for autolens==2026.8.7.1` ~4 min after upload; a PyPI index-propagation race, proven by `wiki_currency_check_autofit` starting 2s earlier and PASSING, and by the wheel downloading fine minutes later. RESOLVED 2026-08-07 — autolens_assistant is CLEAN on all five legs, so the race was the whole story and no autolens follow-up is owed. A CI job re-run was impossible (`HTTP 403: The workflow run containing this job is already running`), so it was graded locally by the documented method instead: a fresh venv with `autolens==2026.8.7.1` from PyPI, `PYTHONPATH` cleared, and all four libraries verified to resolve to venv site-packages rather than this workspace's source checkouts (the `baseline-repin-TRAP` — grading against source installs would have been meaningless). Results: `--check-version` clean (baseline matches autolens 2026.8.7.1), `--scope all` 68 files / 143 symbols / **0 missing-broken**, `--lint-idioms` clean (214 files), `--check-citations` 105 files / 413 citations / **0 missing, 0 warnings**, `--check-provenance` **0 errors** (49 pages). Contrast autogalaxy's 5 provenance errors — the two failures shared a red badge but not a cause. (2) `wiki_drift_issue` — pure fallout, `Artifact not found: wiki-drift-report`, because (1) died before writing it. (3) `wiki_currency_check_autogalaxy` — REAL drift, see the provenance prompt filed under draft/maintenance/autogalaxy_assistant/.
6262
- artifacts-are-laptop-only: Actions artifact downloads are blocked from cloud/mobile sessions (egress policy 403s `productionresultssa2.blob.core.windows.net` on CONNECT) — this is what stopped the cloud session finishing the ingest. Both wiki drift reports were captured to `~/.pyauto-heart/release_20260807_wiki_drift/` while on the laptop.

draft/bug/pyautobuild/root_level_git_add_stages_nothing_on_unmatched_glob.md renamed to complete/archive/shelved/root_level_git_add_stages_nothing_on_unmatched_glob.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,18 @@ Repos:
77
Difficulty: small
88
Autonomy: supervised
99
Priority: normal
10-
Status: formalised
10+
Status: SHELVED — OBSOLETE 2026-08-08
11+
12+
> **Obsolete: the line this describes no longer exists.** PyAutoBuild#156
13+
> deleted the root-level glob `git add` from `pre_build.sh` outright, having
14+
> measured it as a no-op in all 13 repos — so the unmatched-glob bug below was
15+
> fixed by deletion rather than by the tolerant-glob fix proposed here. The
16+
> surviving comment at that spot in the script records the removal. Verified
17+
> against `pre_build.sh` on 2026-08-08 while fixing the sibling hazard in the
18+
> same function (`draft/bug/pyautohands/pre_build_stages_untracked_wip.md`):
19+
> `git add <dir>/` staging untracked files. Do not work this prompt.
20+
>
21+
> Original text follows.
1122
1223
pre_build root-level git add stages nothing when a glob does not match. In pre_build.sh the root-level staging line runs 'git add -- *.py *.md *.txt *.cfg *.ini *.toml *.yml *.yaml LICENSE* requirements* setup* 2>/dev/null || true'. Bash leaves unmatched globs literal, so in any workspace lacking one of those extensions git rejects the ENTIRE pathspec list with 'fatal: pathspec *.cfg did not match any files' (exit 128) and the '|| true' silently swallows it - nothing from that line is staged at all. Measured in autofit_workspace, which has no .cfg/.ini/.toml: exit=128, so its README version bump and llms-full.txt regeneration are never committed by pre_build despite the log printing 'Bumping README version'. The effect is currently MASKED because release.yml's release_workspaces job regenerates and commits the same artifacts on the runner, so main ends up correct - this is latent, not a live breakage. Fix by making the glob tolerant (shopt -s nullglob, or add each pathspec only if it matches) so the line does what its log claims. Found during the 2026.7.15.1 manual release, alongside PyAutoBuild#154 which was the same class of bug: a git add failing under set -e or being swallowed by || true.
1324

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# pre_build stages untracked files, publishing uncommitted human work
2+
3+
Type: bug
4+
Target: PyAutoHands
5+
Repos:
6+
- PyAutoHands
7+
Difficulty: small
8+
Autonomy: supervised
9+
Priority: high
10+
Status: formalised
11+
12+
`pre_build.sh`'s `run_workspace` runs, for each of 13 workspace repos:
13+
14+
```bash
15+
for d in scripts slam_pipeline; do black "$d/"; done
16+
...
17+
for d in notebooks scripts; do git add "$d/"; done
18+
```
19+
20+
Both operations reach **untracked** files. `git add <dir>/` stages them, so any
21+
uncommitted human work under `scripts/` or `notebooks/` is reformatted by black
22+
and pushed inside the `"pre build"` commit — to a public repo, with no prompt
23+
and exit status 0.
24+
25+
This is the same leak class as PyAutoBuild#126, which was fixed for `dataset/`
26+
and `config/` by deleting their staging lines (#156). The `scripts/` path kept
27+
the hole; the comment above the staging block asserts "Releases require clean
28+
mains (Heart gates on it)" but nothing in the script enforces it for the 13
29+
repos it actually commits to — the clean-main gate at the top covers PyAutoHands
30+
alone.
31+
32+
## How it surfaced
33+
34+
A near-miss during the 2026-08-07 release drive (see `active.md`
35+
`release-drive-2026-08-07`, `pre_build-trap`): an uncommitted WIP script in
36+
`autolens_assistant/scripts/` would have been reformatted and published. It was
37+
caught only because the operator noticed and moved the file out of the repo by
38+
hand, restoring it afterwards and verifying it byte-identical by md5. The record
39+
notes it is "worth a real fix so it is not left to operator vigilance."
40+
41+
Reproduced against the pre-fix script on throwaway fixture repos: the private
42+
file was committed as `"pre build"` and pushed to the remote, exit 0, silently.
43+
44+
## The fix
45+
46+
1. **Fail-fast preflight over every repo, before the first is touched.**
47+
`run_workspace` commits *and pushes* each repo before moving to the next, so
48+
a per-repo check aborting midway would leave earlier repos already
49+
published. This also answers the open atomicity question in
50+
`docs/pre_build_failure_audit.md` §6 ("worth a fail-fast pre-pass?").
51+
Uses `git ls-files --others --exclude-standard`, which honours `.gitignore`
52+
and tolerates pathspecs matching nothing.
53+
2. **Narrow the staging** to `git add -u` (tracked edits and deletions) plus
54+
newly created files added by explicit path, so the directory-wide form
55+
cannot return. New notebooks from `generate.py` must still be staged — that
56+
is why plain `git add -u` alone is insufficient.
57+
3. The repo list moves from `run_workspace "..."` call lines into a
58+
`WORKSPACE_SPECS` array, because two passes now read it and a second
59+
hand-maintained list would drift.
60+
61+
No `--allow-dirty` override: an override is exactly the operator vigilance the
62+
change replaces.
63+
64+
## Verification
65+
66+
Text assertions cannot prove a gate fires, so `tests/test_pre_build_staging.py`
67+
runs the real script against a throwaway `PYAUTOBASE` of fixture git repos with
68+
`black`/`python`/`gh` stubbed and real bare remotes — covering the WIP abort,
69+
multi-repo reporting, gitignored files not blocking a release, new generated
70+
notebooks still being staged, tracked deletions, and the missing-checkout abort.
71+
72+
## Related
73+
74+
`draft/bug/pyautobuild/root_level_git_add_stages_nothing_on_unmatched_glob.md`
75+
is **obsolete** — the root-level glob `git add` line it describes no longer
76+
exists; #156 deleted it as a measured no-op in all 13 repos. Retired to
77+
`complete/archive/shelved/` alongside this task.
78+
79+
<!-- filed 2026-08-08 from the release-drive-2026-08-07 pre_build-trap record -->

0 commit comments

Comments
 (0)