Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion active.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
- 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`.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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/.
- 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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,18 @@ Repos:
Difficulty: small
Autonomy: supervised
Priority: normal
Status: formalised
Status: SHELVED — OBSOLETE 2026-08-08

> **Obsolete: the line this describes no longer exists.** PyAutoBuild#156
> deleted the root-level glob `git add` from `pre_build.sh` outright, having
> measured it as a no-op in all 13 repos — so the unmatched-glob bug below was
> fixed by deletion rather than by the tolerant-glob fix proposed here. The
> surviving comment at that spot in the script records the removal. Verified
> against `pre_build.sh` on 2026-08-08 while fixing the sibling hazard in the
> same function (`draft/bug/pyautohands/pre_build_stages_untracked_wip.md`):
> `git add <dir>/` staging untracked files. Do not work this prompt.
>
> Original text follows.

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.

Expand Down
79 changes: 79 additions & 0 deletions draft/bug/pyautohands/pre_build_stages_untracked_wip.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# pre_build stages untracked files, publishing uncommitted human work

Type: bug
Target: PyAutoHands
Repos:
- PyAutoHands
Difficulty: small
Autonomy: supervised
Priority: high
Status: formalised

`pre_build.sh`'s `run_workspace` runs, for each of 13 workspace repos:

```bash
for d in scripts slam_pipeline; do black "$d/"; done
...
for d in notebooks scripts; do git add "$d/"; done
```

Both operations reach **untracked** files. `git add <dir>/` stages them, so any
uncommitted human work under `scripts/` or `notebooks/` is reformatted by black
and pushed inside the `"pre build"` commit — to a public repo, with no prompt
and exit status 0.

This is the same leak class as PyAutoBuild#126, which was fixed for `dataset/`
and `config/` by deleting their staging lines (#156). The `scripts/` path kept
the hole; the comment above the staging block asserts "Releases require clean
mains (Heart gates on it)" but nothing in the script enforces it for the 13
repos it actually commits to — the clean-main gate at the top covers PyAutoHands
alone.

## How it surfaced

A near-miss during the 2026-08-07 release drive (see `active.md`
→ `release-drive-2026-08-07`, `pre_build-trap`): an uncommitted WIP script in
`autolens_assistant/scripts/` would have been reformatted and published. It was
caught only because the operator noticed and moved the file out of the repo by
hand, restoring it afterwards and verifying it byte-identical by md5. The record
notes it is "worth a real fix so it is not left to operator vigilance."

Reproduced against the pre-fix script on throwaway fixture repos: the private
file was committed as `"pre build"` and pushed to the remote, exit 0, silently.

## The fix

1. **Fail-fast preflight over every repo, before the first is touched.**
`run_workspace` commits *and pushes* each repo before moving to the next, so
a per-repo check aborting midway would leave earlier repos already
published. This also answers the open atomicity question in
`docs/pre_build_failure_audit.md` §6 ("worth a fail-fast pre-pass?").
Uses `git ls-files --others --exclude-standard`, which honours `.gitignore`
and tolerates pathspecs matching nothing.
2. **Narrow the staging** to `git add -u` (tracked edits and deletions) plus
newly created files added by explicit path, so the directory-wide form
cannot return. New notebooks from `generate.py` must still be staged — that
is why plain `git add -u` alone is insufficient.
3. The repo list moves from `run_workspace "..."` call lines into a
`WORKSPACE_SPECS` array, because two passes now read it and a second
hand-maintained list would drift.

No `--allow-dirty` override: an override is exactly the operator vigilance the
change replaces.

## Verification

Text assertions cannot prove a gate fires, so `tests/test_pre_build_staging.py`
runs the real script against a throwaway `PYAUTOBASE` of fixture git repos with
`black`/`python`/`gh` stubbed and real bare remotes — covering the WIP abort,
multi-repo reporting, gitignored files not blocking a release, new generated
notebooks still being staged, tracked deletions, and the missing-checkout abort.

## Related

`draft/bug/pyautobuild/root_level_git_add_stages_nothing_on_unmatched_glob.md`
is **obsolete** — the root-level glob `git add` line it describes no longer
exists; #156 deleted it as a measured no-op in all 13 repos. Retired to
`complete/archive/shelved/` alongside this task.

<!-- filed 2026-08-08 from the release-drive-2026-08-07 pre_build-trap record -->
Loading