Overview
Three defects, one root cause: the dev-workflow helper scripts resolve paths under $HOME/Code/PyAutoLabs, which does not exist in a cloud, web or CI session. All three were hit in sequence during the PyAutoBrain#224 session on 2026-08-10, and each silently did the wrong thing rather than complaining.
Filed high because #2 is a safety defect, not an inconvenience: a guard that returns "all clear" when it cannot read its input is worse than no guard, because the workflow documents it and skills act on its answer.
Plan
prompt_sync_push — push the current branch, or refuse when the checkout is not on main. It currently hardcodes git push origin main.
worktree_check_conflict — fail closed when the registry cannot be resolved, naming the path it tried. It currently returns 0, meaning "no conflict".
test_skill_install.py — skip with a reason on the web-github installer path instead of failing. It currently fails in any cloud session and passes in real CI.
1. prompt_sync_push hardcodes git push origin main
PyAutoMind scripts/prompt_sync.sh — the helper every Mind-writing skill is told to call. create_issue step 6 and start_dev step 7 both instruct the agent to call it. A branch-scoped session that follows the documented steps verbatim pushes Mind straight to main, bypassing review. In the #224 session this was caught only because the helper was inspected before use; the documented path would have violated the session's branch requirement.
2. worktree_check_conflict fails open — the important one
bin/worktree.sh, in worktree_list_claimed:
if [[ ! -f "$active" ]]; then
return 0
fi
No registry → returns 0 → worktree_check_conflict reports no conflict. The guard cannot distinguish "nothing claims this repo" from "I could not read the registry", and answers the former.
Reproduced: worktree_check_conflict reconcile-upstream-repo-mode PyAutoBrain PyAutoMind returned 0 and was recorded as a clean check. Re-run with PYAUTO_MAIN=/workspace it worked and returned the same verdict — but the first answer was worth nothing, and had a conflict existed the session would have started conflicting work on a green light. This is the guard that serialises two agents wanting the same repo.
3. test_skill_install.py fails locally, passes in CI
Two tests assert on installer output that only appears on the local-dev path (assert "SKIP intake (Codex skill" in result.stdout). bin/install.sh already knows the difference — it prints Environment: local-dev vs Environment: web-github / ci-only — and skips the skill-symlink work on the latter.
Consequence, observed: Heart is unreachable from a cloud session, so ship_library falls back to pytest -x and treats any failure as RED. These two failures made that gate spuriously RED on #224 and cost a human acknowledgement to override. CI on that PR then went green on both legs, confirming the diff was never implicated.
The unifying point
bin/install.sh already detects and prints its execution environment, and WORKFLOW.md already names them (local-dev, web-github, ci-only). The helpers should consult that same notion and either adapt or fail closed. None of the three should silently do the wrong thing.
Test Plan
Affected Repositories
- PyAutoBrain (primary) —
bin/worktree.sh, tests/test_skill_install.py
- PyAutoMind —
scripts/prompt_sync.sh
Suggested branch: feature/dev-workflow-helpers-laptop-paths
Branched from main, independent of #224 (disjoint files), so the two can land in either order.
Original Prompt
Filed at PyAutoMind draft/bug/pyautobrain/dev_workflow_helpers_assume_laptop_paths.md.
Overview
Three defects, one root cause: the dev-workflow helper scripts resolve paths under
$HOME/Code/PyAutoLabs, which does not exist in a cloud, web or CI session. All three were hit in sequence during the PyAutoBrain#224 session on 2026-08-10, and each silently did the wrong thing rather than complaining.Filed
highbecause #2 is a safety defect, not an inconvenience: a guard that returns "all clear" when it cannot read its input is worse than no guard, because the workflow documents it and skills act on its answer.Plan
prompt_sync_push— push the current branch, or refuse when the checkout is not onmain. It currently hardcodesgit push origin main.worktree_check_conflict— fail closed when the registry cannot be resolved, naming the path it tried. It currently returns 0, meaning "no conflict".test_skill_install.py— skip with a reason on the web-github installer path instead of failing. It currently fails in any cloud session and passes in real CI.1.
prompt_sync_pushhardcodesgit push origin mainPyAutoMind
scripts/prompt_sync.sh— the helper every Mind-writing skill is told to call.create_issuestep 6 andstart_devstep 7 both instruct the agent to call it. A branch-scoped session that follows the documented steps verbatim pushes Mind straight tomain, bypassing review. In the #224 session this was caught only because the helper was inspected before use; the documented path would have violated the session's branch requirement.2.
worktree_check_conflictfails open — the important onebin/worktree.sh, inworktree_list_claimed:No registry → returns 0 →
worktree_check_conflictreports no conflict. The guard cannot distinguish "nothing claims this repo" from "I could not read the registry", and answers the former.Reproduced:
worktree_check_conflict reconcile-upstream-repo-mode PyAutoBrain PyAutoMindreturned 0 and was recorded as a clean check. Re-run withPYAUTO_MAIN=/workspaceit worked and returned the same verdict — but the first answer was worth nothing, and had a conflict existed the session would have started conflicting work on a green light. This is the guard that serialises two agents wanting the same repo.3.
test_skill_install.pyfails locally, passes in CITwo tests assert on installer output that only appears on the local-dev path (
assert "SKIP intake (Codex skill" in result.stdout).bin/install.shalready knows the difference — it printsEnvironment: local-devvsEnvironment: web-github / ci-only— and skips the skill-symlink work on the latter.Consequence, observed: Heart is unreachable from a cloud session, so
ship_libraryfalls back topytest -xand treats any failure as RED. These two failures made that gate spuriously RED on #224 and cost a human acknowledgement to override. CI on that PR then went green on both legs, confirming the diff was never implicated.The unifying point
bin/install.shalready detects and prints its execution environment, andWORKFLOW.mdalready names them (local-dev,web-github,ci-only). The helpers should consult that same notion and either adapt or fail closed. None of the three should silently do the wrong thing.Test Plan
prompt_sync_pushon a non-mainbranch pushes that branch, or refuses; never pushes tomainfrom a branch-scoped checkout. Covered by a test.worktree_check_conflictreturns non-zero when it cannot resolveactive.md, naming the path it tried. Covered by a test pointing$PYAUTO_MAINat an empty dir. The "registry present, no claim" case still returns 0.test_skill_install.pypasses on both paths — skipping with a reason on web-github, still asserting fully on local-dev.pytest tests/green in a cloud session, so theship_libraryfallback gate stops producing false REDs.Affected Repositories
bin/worktree.sh,tests/test_skill_install.pyscripts/prompt_sync.shSuggested branch:
feature/dev-workflow-helpers-laptop-pathsBranched from
main, independent of #224 (disjoint files), so the two can land in either order.Original Prompt
Filed at PyAutoMind
draft/bug/pyautobrain/dev_workflow_helpers_assume_laptop_paths.md.