fix: prompt_sync helpers push the current branch, not a hardcoded main - #178
Merged
Conversation
draft_staleness_detection_signals.md is DELIVERED for legs 1 and 2 (the lifecycle.py gate keys and the intake reconcile re-rank). Leg 3 — an upstream-repo read — is the only route to the two findings that leave no Mind-local evidence, and its own delivery note says so. One prompt is one task is one PR, so it is split out rather than re-opening a delivered prompt; the parent now points at it. Filed by hand after the Intake Agent mis-classified the raw text as bug/PyAutoFit — it latched onto the counter-example prose rather than the work. Corrected to feature/pyautobrain; the Feature Agent parses the result as feature/pyautobrain, medium, high, direct, library workflow. Baselines verified at split time and recorded in the prompt: reconcile flags 29 of 136 scanned (7 high); no --repo flag exists in _intake.py's argparse; and nothing under PyAutoBrain/agents/ performs any network access, which is why leg 3's opt-in flag needs an explicit policy line. Also verified the trap the acceptance criterion turns on: all five identifiers named by test_mode_bypass_ordered_assertion_ties.md are present on PyAutoFit main, yet that prompt is confirmed NOT shipped — so the mode must report needs-review with evidence, never a shipped verdict. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
Routes leg 3 of the staleness work into the dev workflow. PyAutoBrain#223 carries the two-level plan; the prompt advances draft/ -> active/ and is registered in active.md as library-dev. Conflict check clean at registration (worktree_check_conflict exit 0, no other task claims PyAutoBrain or PyAutoMind). The repos: list is left empty per the schema — no branch exists yet, and any 2-space `- Repo` bullet would read as a live worktree claim. Committed by hand rather than via prompt_sync_push: that helper hardcodes `git push origin main`, which is wrong for a branch-scoped session. Mind changes for this task go to claude/automind-task-planning-wxq004. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
Records the PyAutoBrain claim per start_library step 4's web-github variant (repos bullet, no worktree: field) now that feature/reconcile-upstream-repo-mode is pushed at 875330f. Corrects the conflict-check line: the run recorded at start_dev time was VACUOUS. worktree_check_conflict resolves active.md under $PYAUTO_MAIN, which defaults to $HOME/Code/PyAutoLabs and does not exist in a cloud session, so it read no file and returned 0 = "no conflict". Re-run with PYAUTO_MAIN=/workspace it confirms the same conclusion for real: the only other live claim is profile-validation-resample-recovery on PyAutoGalaxy, no overlap. The guard failing OPEN is logged as a follow-up. A cloud or CI session running the documented command gets a green light that means nothing. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
…n#224) Records the open PR and the ship-gate outcome. The documented fallback gate returned RED (Heart is unreachable from a cloud session, so pytest -x is the gate) on two tests/test_skill_install.py failures. A human acknowledged the reason and authorized the PR. CI then vindicated that call: both pytest legs (3.12, 3.13) are SUCCESS on 875330f, so those failures were purely local to this container — install.sh takes its web-github branch when $HOME/Code/PyAutoLabs is absent and never performs the work the test asserts on. They were also proven pre-existing at merge-base a50efc3 with the diff absent. The prompt stays in active/ until merge, when the ship skills advance it to complete/2026/08/. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
The PyAutoMind half of PyAutoBrain#225. Both helpers ended in `git push origin main` regardless of what was checked out. create_issue step 6 and start_dev step 7 both instruct an agent to call them, so a branch-scoped session — a cloud session with a designated branch, or any PR-based flow — that followed the documented steps verbatim pushed Mind straight to main, bypassing review. In this session it was caught only because the helper was inspected before use; the documented path would have violated the branch requirement. Pushing HEAD leaves the single-branch laptop flow byte-identical (there the current branch IS main) while making a branch-scoped checkout do the right thing. A detached HEAD is refused rather than guessed at. prompt_sync_push is restructured to drop its subshell: with the old `( ... ) && push` shape the "no-op if nothing is staged" early return would have fallen through to the push, so a caller with no changes would have pushed anyway. The early return now precedes the push. Tests drive the real script against throwaway repos with real bare remotes, because only that shows WHICH ref actually moved; grepping the source would pass on a script that still pushed the wrong branch by another route. Verified they fail against the pre-fix script — 3 of 5 do, including the detached-HEAD case, where the old script pushed `main -> main`. Also files the prompt for the whole three-defect task. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
Both PRs open. Records the three defects, the fixes, and a correction to the initial diagnosis of the installer-test failure: it was not the installer's web-github branch, it was PYAUTO_ROOT defaulting to the repo's grandparent, so a clone at lowercase pyautobrain never resolves PyAutoBrain/skills. The issue body was corrected before implementation. PyAutoBrain pytest is now 331 passed with nothing ignored — green in a cloud session for the first time, which retires the false-RED ship gate that cost a human acknowledgement on #224. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
lifecycle.py check flagged DRIFT: the prompt sat in draft/ while active.md listed it as an issued task. This is create_issue step 5, which was skipped when going prompt -> issue -> implementation directly. Caught late because the check ran in an `&& tail -2` pipeline, so the shell saw tail's exit status rather than the check's. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
…lly hits Found auditing this branch against origin/main. The write-up said the old helper "pushes Mind straight to main". Measuring it against real bare remotes shows that is only the half that needs local main to be AHEAD. `git push origin main` pushes the local main REF, never the commit just made on a feature branch. So when local main equals the remote — the normal case for a session that branched from it — the push is a no-op, exits 0, and the committed work never leaves the machine while the caller is told the sync succeeded. In an ephemeral cloud container that is silent loss, and it is the case that fires most often. Publishing unreviewed main commits is the other half. Two tests added for the two halves, since they are separate failures: test_committed_work_actually_reaches_the_remote (the work is ON the remote) and test_a_branch_push_never_advances_main (an unpushed local main commit is not published as a side effect). Both fail against origin/main's script; 5 of the 7 now do. 134 passed. The fix itself is unchanged and already correct — pushing HEAD addresses both halves. This corrects the description and the coverage, not the code. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
Conflict in active.md: main appended workspace repo bullets to the profile-validation-resample-recovery entry while this branch added two new task entries immediately after it. Both sides kept — their bullets complete that entry's repos: list, then the new entries follow. Verified the claim parser still reads every row (worktree_list_claimed returns all 7). Also corrects a stale count in this branch's own entry: the Mind tests that fail against the pre-fix script are 5 of 7, not 3 of 5, after the audit added a test per half of the prompt_sync defect. lifecycle check OK, 134 passed. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01PY39MRi1oPbxhhr6tDToQU
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The PyAutoMind half of PyAutoBrain#225, plus the Mind bookkeeping for PyAutoBrain#223/#224 that this session produced. Both are on this branch because the session was scoped to it; see "Scope note" below.
The defect — corrected after measurement
scripts/prompt_sync.sh— both helpers ended ingit push origin mainregardless of what was checked out:create_issuestep 6 andstart_devstep 7 both instruct an agent to call it.An earlier revision of this PR described this as "pushes Mind straight to
main". That was half right, and not the half that fires most often.git push origin mainpushes the localmainref — never the commit just made on a feature branch. Measured against real bare remotes, the old behaviour splits by the state of localmain:mainvs remotemainmain, unreviewed, and still leaves the branch work local.The first row is the common one and the quieter danger: in an ephemeral cloud container, "committed, reported synced, never pushed" is silent loss. The second is the review bypass. Same root cause; both fixed by pushing
HEAD.The single-branch laptop flow is byte-identical — there the current branch is
main. Verified across four scenarios (nothing staged, tracked change, untracked-only, deletion): old and new produce the same commit count, same refs, same remote state. A detached HEAD is now refused rather than guessed at.One regression caught while fixing it
prompt_sync_pushis restructured to drop its subshell. With the naive( ... ) && _pushshape, the documented "no-op if nothing is staged" early return falls through to the push, so a caller with no changes would push anyway. The early return now precedes the push, andtest_push_is_still_a_no_op_when_nothing_is_stagedpins it.Test Plan
pytest tests/— 134 passed (127 existing + 7 new)python3 scripts/lifecycle.py check— OKorigin/main's script, verified by swapping it in. A test that cannot fail is decoration.maincompared directly across 4 scenarios — identicalThe tests drive the real script against throwaway git repos with real bare remotes, because that is the only way to observe which ref actually moved; grepping the source for the string would pass on a script that still pushed the wrong branch by another route.
The two halves of the bug get their own tests, since they are separate failures:
test_committed_work_actually_reaches_the_remoteandtest_a_branch_push_never_advances_main.The most striking pre-fix failure: from a detached HEAD, the old script pushed
main -> main.Scope note — why this branch carries two things
The session was scoped to
claude/automind-task-planning-wxq004, so all Mind changes landed here. Alongside the fix, the branch carries the registry bookkeeping for the tasks that produced it — filing PyAutoBrain#223/#225, thedraft/→active/lifecycle moves, and theactive.mdentries.That bookkeeping is ordinary Mind state and should land regardless. If you would rather review the fix in isolation, say so and I will split the
scripts/+tests/changes onto their own branch.Related