fix(aep): autopilot worktree guard + Phase 12 merge-completion contract (v2.5.0)#18
Merged
Merged
Conversation
…ct (v2.5.0) Fix the autopilot "PR-ready stop" + "feat branch in the main checkout" failure mode (latent since v1.6.0, surfaced on the Codex backend, MITS-036/PR#28). Root cause: the worktree binding and the autopilot-mode merge decision were both unenforced soft contracts inferred from cwd; /aep-build had no entry guard; and a global "always confirm before merging" guardrail contradicted Phase 12's autopilot exception. On Codex codex-subagent (spawn_agent has no cwd parameter) a worker could build in the main checkout and then park a CLEAN, no-required-checks PR at "ready" forever. - D0: worktree entry guard in /aep-build Phase 0 + worktree-onboarding — verifies the worktree and self-heals; never builds/branches in the main checkout. - D2: explicit .dev-workflow/signals/mode autonomy marker written by /aep-launch, read by Phase 12 (cwd is now only a fallback hint); documented in signals-spec. - D1: resolve the merge contradiction — guardrail + onboarding Key Rule now carry the interactive-only caveat; Phase 12 gains a "PR ready is NOT a stop condition" allowlist. - D4: "no required checks configured" + mergeStateStatus=CLEAN ⇒ proceed. - D3: pair "main NEVER merges" with the positive worker obligation; strengthen merge nudges + the Codex aep-builder role. - D5: merge-decision-cases.md regression fixture. - chore: anchor the unanchored `build` .gitignore pattern to /build/ (it silently ignored new files inside the build/ skill dir). Not a 2.4.0 regression; minor bump for the additive `mode` signal + guard. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WFAeDemRdH8KzcYhiDTrto
…ntract Self-review of the PR surfaced a regression I introduced plus several half-applied edges. Fixes (no behavior beyond the original intent): - mode marker is now the SOLE autopilot authority; dropped the Phase 12 cwd fallback. The Phase 0 guard relocates EVERY build (incl. interactive) into a worktree, so "cwd under .feature-workspaces/" no longer distinguishes autonomous from interactive — the old fallback auto-merged interactive (Case C) builds without asking. Ambiguous signal now defaults to interactive. Aligns build/SKILL.md, worktree-onboarding, signals-spec, and the Guardrail. - readiness keys on mergeStateStatus (CLEAN/UNSTABLE proceed; BLOCKED/DIRTY stop) instead of counting raw statusCheckRollup (which conflated required vs optional and "none configured" vs "not yet reported"). - merge nudges now enumerate the full 6-item stop list (added the two safety stops: human-approval gate + policy pause) — no half-applied subset. - worker no longer told to run /aep-wrap (boundary: /opsx:archive runs on the integration branch); it ends at merge + status.json completed. - Phase 0 guard hardened: anchor to the main repo root (correct from any cwd), and handle "feat/<name> already checked out in main" (the resume case) so the advertised self-heal actually self-heals; dropped the dead $BRANCH==$BASE term. - .gitignore: /build/ alone un-ignored apps/*/build and packages/*/build in this turbo monorepo; added per-workspace anchors that still keep the skill dir tracked. - merge-decision-cases.md no longer over-claims the taxonomy is identical across six files; names build Phase 12 as the canonical source. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WFAeDemRdH8KzcYhiDTrto
…ate, fix nudge/readiness drift The full-coverage re-review showed my round-1 "self-heal by creating worktrees" was the source of most findings. Reverting to the original AEP architecture (/aep-launch owns worktree creation; build verifies + enters) eliminates the whole cluster at once: - Phase 0 guard is now enter-or-escalate and <name>-specific: it enters the worktree /aep-launch already made (anchored to the main repo root) and ESCALATES if absent — never creates a branch/worktree, never `git switch`es the main checkout (which could strand uncommitted WIP), never builds in a sibling worktree. Removes the dangerous recovery paths and the wrong-base/prune/origin edges. - mode marker read is now anchored to the worktree root (was cwd-relative — a build phase that cd'd into a subdir would miss it and wrongly park as interactive). - Phase 12 readiness: UNSTABLE no longer blanket-merges (stop if a check is failing, even with no required checks configured); UNKNOWN re-reads (the normal state right after the force-push) instead of having no rule. - stuck merge nudges (autopilot/SKILL.md, tick-protocol.md) still said "Verify CI green" (the retired gate) and omitted the do-not-wrap guard — both fixed; the primary tick nudge said "rebase on main" (wrong on develop repos) → integration branch. - merge-decision-cases: Case A clarifies worker-merges/orchestrator-wraps; Case B is enter-or-escalate; dropped the stale "cwd fallback" reference. - CHANGELOG updated to match; documented the stale-marker edge in signals-spec. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WFAeDemRdH8KzcYhiDTrto
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WFAeDemRdH8KzcYhiDTrto
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.
Why
An autopilot worker (MITS-036 / PR #28, Codex backend, AEP 2.4.0) built a story, opened a CLEAN PR with no required checks, and stopped at "PR ready" instead of completing Phase 12 merge + wrap. Upstream of that, the user found the worker had never created a worktree — it created
feat/<name>directly in the main checkout.These are one bug, not two. The worktree binding and the autopilot-mode merge decision were both unenforced soft contracts inferred from cwd,
/aep-buildhad no entry guard, and a global "always confirm before merging" guardrail contradicted Phase 12's autopilot exception. No worktree → cwd not under.feature-workspaces/→ Phase 12 detects "interactive mode" → stop at ready. On Codexcodex-subagent(spawn_agenthas no cwd parameter) the failure is near-deterministic.Not a 2.4.0 regression — latent since v1.6.0
git blame+git tag --contains: the contradicting guardrail (f6222ba, 2026-03-26), the autopilot "merge immediately" + cwd detection (108d4c1/4225bf2, v1.6.0), and the entire Codex backend (108d4c1, v1.6.0) all predate 2.4.0. v2.4.0'sbuild/SKILL.mdchange was journey-authoring (lines 512–650); Phase 12 / the guardrail were untouched.What changed
/aep-buildhad no worktree guard; binding was a soft contractshow-toplevelunder.feature-workspaces/onfeat/*; self-heal (enter/create), never build in main; escalate if it can't/aep-launchwrites.dev-workflow/signals/**mode**(autopilot); Phase 12 reads the marker, cwd is fallback-onlymergeStateStatus=CLEANaep-builderrole verifies its worktreemerge-decision-cases.mdpins the two scenariosPlus a
.gitignorefix: the unanchoredbuildpattern silently ignored new files inside thebuild/skill dir (it hid this PR's new fixture) → anchored to/build/.Version: minor bump 2.5.0 — additive
modesignal + guard, backward-compatible (cwd fallback preserved).Verification
grepacrossbuild/autopilot/tick-protocol/launch/signals-spec/onboarding: every remaining "ask before merge" is now interactive-only; the only "do not merge"/"stop at ready" strings are guidance forbidding them; the stop-condition allowlist is identical across files.merge-decision-cases.mdencodes the regression cases (clean PR + no checks ⇒ merge/wrap; build outside worktree ⇒ self-heal).🤖 Generated with Claude Code