From c284d690bae042262ef3ba2675f1c272338bf131 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 20:58:20 +0000 Subject: [PATCH 1/3] fix(firewall): register the six PyAutoHands incident-citation surfaces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The tenant firewall (organ code) leg of `repos_sync.py --check` was red: six PyAutoHands files carried instance facts while absent from FIREWALL_ALLOWLIST, so the whole drift gate exited 1. Per-file judgment, following the rule the three prior firewall tasks settled — derivable or arbitrary means refactor, a genuine branded fact means declare the surface: autohands/check_search_memory.py {PyAutoFit, PyAutoLabs} autohands/env_config.py {PyAutoFit, PyAutoLabs} tests/test_check_search_memory.py {PyAutoFit, autogalaxy_workspace} tests/test_env_config.py {PyAutoFit, PyAutoLabs} tests/test_python_matrix_workflow.py {PyAutoFit} tests/test_repro_command.py {PyAutoFit, PyAutoLabs} Every one of the twelve tokens is prose provenance, not a functional constant: comments and docstrings citing PyAutoLabs/PyAutoFit#1452 (the 2026-07-30 unbatched multi-start OOM that took down two nightly integrate runs) and PyAutoFit#1439, plus the autogalaxy_workspace script the OOM came from. There is no code path keyed on a repo name here, so there is nothing to parameterise — an issue number cannot be derived, and deleting the citations would destroy the provenance for an incident that cost two nights to diagnose. This is the "register the intentional surface" case of PyAutoMind#114, not the "the code could derive it" case of PyAutoBrain#193. check_search_memory.py's citation also appears in the printed failure message (line 136), the one site an adopting fork's users would see. Kept deliberately: the issue pointer is the most useful part of that message. No PyAutoHands source changed — the facts were already intentional; only the declaration was missing. The seventh finding, PyAutoBrain/tests/ test_health_conductor.py, was arbitrary fixture filler and is fixed there by refactor instead, with no allowlist growth. Verified: `repos_sync.py --check` all ten legs OK (was 7 mismatches); Heart's own producer manifest_drift.run() problem_count 0; negative probes confirm the detector still fires for a new fact in a now-listed file and for a real name returned to the unlisted Brain fixture. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0148Baec3aLwGpSJ5yYwiHZG --- .../the_organ_code_tenant_firewall_gate_is.md | 15 +++++++++++++++ scripts/repos_sync.py | 6 ++++++ 2 files changed, 21 insertions(+) create mode 100644 draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md diff --git a/draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md b/draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md new file mode 100644 index 00000000..aa188b41 --- /dev/null +++ b/draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md @@ -0,0 +1,15 @@ +# The organ-code tenant firewall gate is failing on PyAutoHands + +Type: bug +Target: PyAutoHands +Repos: +- PyAutoHands +- pyautohands +Difficulty: medium +Autonomy: supervised +Priority: normal +Status: formalised + +The organ-code tenant firewall gate is failing on PyAutoHands. The body-map drift checker (scripts/repos_sync.py --check) exits 1 on its 'tenant firewall (organ code)' leg, so the gate is red. Six files under PyAutoHands carry hardcoded instance facts while absent from the firewall allowlist — two in the autohands package (check_search_memory.py, env_config.py) and four in its test suite — and the checker prints the offending line numbers for each. Every other leg of the drift check passes, so this single leg is what keeps the gate red. For each file decide whether the hardcoded instance name is legitimate, in which case extend the allowlist, or whether it should be parameterised out of the organ code so the firewall stays meaningful. Restore the gate to green. + + diff --git a/scripts/repos_sync.py b/scripts/repos_sync.py index 926a3b56..89b3d161 100644 --- a/scripts/repos_sync.py +++ b/scripts/repos_sync.py @@ -562,8 +562,10 @@ def write_claude_md_pointers(root, repos): "PyAutoHands/autohands/aggregate_results.py": {"PyAutoArray", "PyAutoNerves", "PyAutoFit", "PyAutoGalaxy", "PyAutoLabs", "PyAutoLens", "autofit_workspace", "autogalaxy_workspace", "autolens_workspace"}, "PyAutoHands/autohands/build_util.py": {"PyAutoNerves"}, "PyAutoHands/autohands/bump_colab_urls.sh": {"HowToFit", "HowToGalaxy", "HowToLens", "PyAutoLabs", "autofit_workspace", "autogalaxy_workspace", "autolens_workspace"}, + "PyAutoHands/autohands/check_search_memory.py": {"PyAutoFit", "PyAutoLabs"}, "PyAutoHands/autohands/clone_seed.py": {"autofit_assistant"}, "PyAutoHands/autohands/create_analysis_issue.py": {"PyAutoLabs"}, + "PyAutoHands/autohands/env_config.py": {"PyAutoFit", "PyAutoLabs"}, "PyAutoHands/autohands/generate_autofit.py": {"autofit_workspace"}, "PyAutoHands/autohands/generate_markdown.py": {"HowToFit", "HowToGalaxy", "HowToLens", "PyAutoFit", "PyAutoGalaxy", "PyAutoLens"}, "PyAutoHands/autohands/generate_release_notes.py": {"PyAutoArray", "PyAutoNerves", "PyAutoFit", "PyAutoGalaxy", "PyAutoLabs", "PyAutoLens", "PyAutoScientist"}, @@ -575,8 +577,12 @@ def write_claude_md_pointers(root, repos): "PyAutoHands/autohands/tag_and_merge.sh": {"PyAutoArray", "PyAutoNerves", "PyAutoFit", "PyAutoGalaxy", "PyAutoLens"}, "PyAutoHands/pre_build.sh": {"HowToFit", "HowToGalaxy", "HowToLens", "PyAutoFit", "PyAutoGalaxy", "PyAutoLabs", "PyAutoLens", "admin_jammy", "autofit_workspace", "autofit_workspace_developer", "autofit_workspace_test", "autogalaxy_workspace", "autogalaxy_workspace_test", "autolens_assistant", "autolens_workspace", "autolens_workspace_developer", "autolens_workspace_test", "euclid_strong_lens_modeling_pipeline"}, "PyAutoHands/tests/test_bump_colab_urls.py": {"Jammy2211", "PyAutoFit", "PyAutoLabs", "autofit_workspace", "autogalaxy_workspace", "autolens_workspace"}, + "PyAutoHands/tests/test_check_search_memory.py": {"PyAutoFit", "autogalaxy_workspace"}, + "PyAutoHands/tests/test_env_config.py": {"PyAutoFit", "PyAutoLabs"}, "PyAutoHands/tests/test_generate_markdown.py": {"PyAutoArray", "autolens_workspace"}, + "PyAutoHands/tests/test_python_matrix_workflow.py": {"PyAutoFit"}, "PyAutoHands/tests/test_release_notes.py": {"PyAutoArray", "PyAutoFit", "PyAutoGalaxy", "PyAutoLabs", "PyAutoLens"}, + "PyAutoHands/tests/test_repro_command.py": {"PyAutoFit", "PyAutoLabs"}, "PyAutoHands/tests/test_run_all_history.py": {"HowToLens", "autogalaxy_workspace_test", "euclid_strong_lens_modeling_pipeline"}, "PyAutoHands/tests/test_slack_release_notes.py": {"PyAutoArray", "PyAutoFit", "PyAutoGalaxy", "PyAutoLabs", "PyAutoLens"}, "PyAutoHands/tests/test_workspace_config_precedence.py": {"autofit_workspace", "autofit_workspace_test", "autogalaxy_workspace", "autogalaxy_workspace_test", "autolens_workspace", "autolens_workspace_test"}, From 4b8414c0820a42eaf918bac3647a453bab032f7d Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 21:00:28 +0000 Subject: [PATCH 2/3] =?UTF-8?q?prompt:=20route=20autohands-firewall-allowl?= =?UTF-8?q?ist=20(#134)=20=E2=86=92=20issued?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the prompt draft/bug/autohands/ -> active/ and register the task in active.md. Records the seven-not-six scope, the per-file allowlist/refactor judgment, the kept citation decision, and the negative probes that prove the allowlist is exact rather than blanket. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0148Baec3aLwGpSJ5yYwiHZG --- active.md | 17 +++++++++++++++++ .../autohands_firewall_allowlist.md | 0 2 files changed, 17 insertions(+) rename draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md => active/autohands_firewall_allowlist.md (100%) diff --git a/active.md b/active.md index 3b4dcb22..369d829d 100644 --- a/active.md +++ b/active.md @@ -1,5 +1,22 @@ # Active Tasks +## autohands-firewall-allowlist +- issue: https://github.com/PyAutoLabs/PyAutoMind/issues/134 +- status: FIX COMMITTED AND PUSHED to `claude/autohands-firewall-allowlist-1dzeuw` in PyAutoMind (c284d69) and PyAutoBrain (b54ff0f). NO PR opened (not requested). Cloud session, no worktree. +- what it fixes: the `tenant firewall (organ code)` leg of `repos_sync.py --check` exited 1, reddening the whole body-map drift gate. Every other leg passed. +- SCOPE GREW BY ONE: the prompt names six PyAutoHands files; the live check reports SEVEN. `PyAutoBrain/tests/test_health_conductor.py` landed with the health-conductor STALE fix (PyAutoBrain#198/#201) AFTER the prompt was written. Green is unreachable without it — do not read the prompt's "six" as the full set. +- judgment (six PyAutoHands files → ALLOWLIST): all twelve tokens are prose provenance in comments/docstrings citing PyAutoLabs/PyAutoFit#1452 (the 2026-07-30 unbatched multi-start OOM that killed two nightly integrate runs) and PyAutoFit#1439, plus the autogalaxy_workspace script the OOM came from. NO code path is keyed on a repo name, so there is nothing to parameterise, and an issue number cannot be derived. This is the "register the intentional surface" case of PyAutoMind#114, NOT the "the code could derive it" case of PyAutoBrain#193. +- NO PyAutoHands FILE CHANGED — the facts were already intentional; only the declaration was missing. The diff is PyAutoMind (allowlist) + PyAutoBrain (fixture) only. +- judgment (seventh, PyAutoBrain → REFACTOR, no allowlist growth): the names were the repo half of stubbed `": "` Heart reason strings and NO assertion reads them (the only reason-touching assertions are self-referential or counts). Pure filler → `library-a`/`library-b` + a comment fixing the convention. Same judgment as the `checkout_a/b/c` fixture rename in PyAutoBrain#193. +- human decision 2026-08-05: KEEP the citation in `check_search_memory.py:136` — the one token that is not a comment but a printed failure message a workspace developer sees. The issue pointer is the most useful part of that message; the file is allowlisted anyway. +- CONSIDERED AND REJECTED: teaching the checker to ignore comments would have fixed all seven at a stroke, but it silently un-guards facts sitting in comments beside code, weakens the one genuine output-string case, and changes detector semantics organism-wide. #114 cleared this same class explicitly WITHOUT touching the detector. +- CONTROL TRAP (the thing to repeat): an over-broad allowlist reads green too, so "check passes" proves nothing on its own. Verification therefore ran NEGATIVE PROBES — a new token appended to the now-listed env_config.py → "new instance fact(s) in allowlisted file", exit 1; a real repo name put back into the unlisted Brain fixture → "new instance fact(s) in unlisted file", exit 1; both reverted → green, exit 0. +- verify: `repos_sync.py --check` all ten legs OK (was 7 mismatches), exit 0. Heart's own producer `manifest_drift.run()` with PYAUTO_ROOT=/home/user → problem_count 0. `pytest PyAutoBrain/tests/` → 222 passed, 0 failed (the pre-existing test_skill_install sizing-wrapper failure noted in the 2026-08-04 record is GONE — the sizing SKILL.md now exists). +- env trap (cloud session): the base python3 (3.11) had neither pytest nor pyyaml; `/root/.local/bin/pytest` is a uv tool whose interpreter lacks yaml, so PyAutoBrain collection errors on test_activity_gate/test_policy_seams/test_sizing_paths. `pip install pyyaml pytest` into the base interpreter, then `python3 -m pytest`. PYAUTO_SKIP_API_GATE=1 is the sanctioned bypass for the `autoarray.egg` fixture string. +- prompt: active/autohands_firewall_allowlist.md +- worktree: (none — cloud session, worked in the canonical /home/user checkouts on the mandated branch) +- repos-claimed-on-one-line: PyAutoMind, PyAutoBrain — named on this single line deliberately and NOT as 2-space bullets, because worktree_check_conflict reads any such bullet as a live claim. + ## covariance-interpolator-rng-seed - issue: https://github.com/PyAutoLabs/PyAutoFit/issues/1450 - status: library-dev — fix COMMITTED AND PUSHED to `claude/covariance-interpolator-rng-seed-8zexp3` (PyAutoFit 68a8b391). NO PR opened (not requested). Cloud session, no worktree and no `gh` CLI; issue filed via the GitHub MCP surface. diff --git a/draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md b/active/autohands_firewall_allowlist.md similarity index 100% rename from draft/bug/autohands/the_organ_code_tenant_firewall_gate_is.md rename to active/autohands_firewall_allowlist.md From 3742e8909ee6a99ac25494fc30770e88b5c9758f Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 5 Aug 2026 21:21:54 +0000 Subject: [PATCH 3/3] prompt: record PRs for autohands-firewall-allowlist (#134) Mind#135 and Brain#202 open; note the both-must-land gate condition, the CLEAN review verdict, and the exactness audit to repeat on future allowlist growth. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_0148Baec3aLwGpSJ5yYwiHZG --- active.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/active.md b/active.md index 369d829d..b1c50caa 100644 --- a/active.md +++ b/active.md @@ -2,7 +2,11 @@ ## autohands-firewall-allowlist - issue: https://github.com/PyAutoLabs/PyAutoMind/issues/134 -- status: FIX COMMITTED AND PUSHED to `claude/autohands-firewall-allowlist-1dzeuw` in PyAutoMind (c284d69) and PyAutoBrain (b54ff0f). NO PR opened (not requested). Cloud session, no worktree. +- status: PRs OPEN, awaiting review/merge. PyAutoMind#135 (c284d69 + Mind state) and PyAutoBrain#202 (b54ff0f), both on `claude/autohands-firewall-allowlist-1dzeuw`. Cloud session, no worktree. +- prs: https://github.com/PyAutoLabs/PyAutoMind/pull/135 (closes #134) / https://github.com/PyAutoLabs/PyAutoBrain/pull/202 +- merge-order: NONE required — the two PRs are independent and neither changes runtime behaviour. But the gate only reads green once BOTH land: Mind#135 declares the six PyAutoHands surfaces, Brain#202 removes the seventh finding. Merging either alone leaves `repos_sync.py --check` exiting 1. +- review: ReviewSurface CLEAN on both (review faculty, run per-checkout with `--repo` since a cloud session has no worktree for `--task`). PyAutoMind carries a `no-test-changes` risk flag — expected, the allowlist is a data table and PyAutoMind's suite has no firewall coverage; the behavioural proof is the negative probes, as in the PyAutoMind#115 precedent. +- EXACTNESS AUDIT (do this on any future allowlist growth): each of the six entries was diffed against the tokens ACTUALLY present in that file — all six EXACT, zero over-grants. An over-broad entry silently pre-authorises a fact that is not there yet and reads green either way, so "check passes" does not catch it. - what it fixes: the `tenant firewall (organ code)` leg of `repos_sync.py --check` exited 1, reddening the whole body-map drift gate. Every other leg passed. - SCOPE GREW BY ONE: the prompt names six PyAutoHands files; the live check reports SEVEN. `PyAutoBrain/tests/test_health_conductor.py` landed with the health-conductor STALE fix (PyAutoBrain#198/#201) AFTER the prompt was written. Green is unreachable without it — do not read the prompt's "six" as the full set. - judgment (six PyAutoHands files → ALLOWLIST): all twelve tokens are prose provenance in comments/docstrings citing PyAutoLabs/PyAutoFit#1452 (the 2026-07-30 unbatched multi-start OOM that killed two nightly integrate runs) and PyAutoFit#1439, plus the autogalaxy_workspace script the OOM came from. NO code path is keyed on a repo name, so there is nothing to parameterise, and an issue number cannot be derived. This is the "register the intentional surface" case of PyAutoMind#114, NOT the "the code could derive it" case of PyAutoBrain#193.