* fix(#1369): refresh wave manifest and re-check base before each wave in execute-phase Two compounding issues caused wave N+1 worktrees to fork from the stale pre-wave-N commit, immediately tripping the worktree_branch_check FATAL guard in every executor: 1. worktree.base-check auto-degrade only ran once at initialize time. After wave N merges advanced orchestrator HEAD past origin/HEAD, new worktrees were still forked from origin/HEAD (Claude Code "fresh" base). 2. WAVE_WORKTREE_MANIFEST was never unset between waves, so wave N+1 reused the consumed wave-N manifest file, which would have blocked the step 5.5 manifest guard (#3384) on subsequent waves. Fix: add two safeguards in execute-phase.md — - Step 0.5 (start of each wave): re-runs worktree.base-check; auto-degrades USE_WORKTREES=false for that wave when HEAD has diverged from origin/HEAD. - Step 7c (end of each wave): unsets WAVE_WORKTREE_MANIFEST so wave N+1 creates a fresh per-wave manifest; re-asserts worktree.set-baseref (idempotent) and re-evaluates base degradation after wave merges land. 17 regression tests added in tests/bug-1369-wave-stale-base.test.cjs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1369): rename test to fix-NNN convention; update workflow size baseline Rename tests/bug-1369-wave-stale-base.test.cjs → tests/fix-1369-wave-stale-base.test.cjs to satisfy the lint-regression-test-names gate (new files cannot use bug-NNN prefix). Update tests/workflow-size-baseline.json for execute-phase.md: 93157 → 97393 (LF-normalized byte count after adding step 0.5 inter-wave base re-check and step 7c between-wave manifest reset). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1369): add issue reference to allow-test-rule comment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1369): extract new execute-phase steps to references; satisfy ADR-857 cap Step 0.5 (inter-wave worktree base re-check) and steps 7b–7c (pre-wave dependency check + between-wave manifest reset/base refresh) added by this PR grew execute-phase.md to 97393 bytes, violating the ADR-857 phase-6 architectural mandate that host-loop bodies remain strictly below the pre-phase-6 baseline of 93166 bytes. Extract both new blocks into dedicated reference files: - gsd-core/references/execute-phase-wave-guard.md (step 0.5) - gsd-core/references/execute-phase-between-wave-reset.md (steps 7b + 7c) Replace inline prose with @-reference pointers. File now measures 92851 bytes (LF-normalized), satisfying the ADR-857 capstone conformance gate. Also update tests/workflow-size-baseline.json to 92851 and add both new reference files to docs/INVENTORY-MANIFEST.json. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(#1369): update regression tests to read from extracted reference files Steps 0.5 and 7b+7c were moved to reference files to satisfy the ADR-857 size cap on execute-phase.md. Tests now check @-reference pointers in the workflow for ordering and read content assertions from the reference files. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2.6 KiB
7b. Pre-wave dependency check (waves 2+ only):
Before wave N+1, run gsd-tools.cjs query verify.key-links {phase_dir}/{plan}-PLAN.md for each upcoming plan.
If any PRIOR-wave artifact link fails, present:
- ## Cross-Plan Wiring Gap with plan/link/from/pattern rows
- Options: investigate+fix before continue, or continue with cascade risk
Skip key-links that reference files in the CURRENT (upcoming) wave.
7c. Between-wave manifest reset and worktree base refresh (waves 2+ only — #1369):
REQUIRED before each wave transition when USE_WORKTREES != "false" and RUNTIME = "claude".
Wave N's WAVE_WORKTREE_MANIFEST was consumed by worktree.cleanup-wave in step 5.5. It must be
unset so wave N+1's step 3 creates a fresh manifest for the new wave's worktrees. Without this,
the wave N+1 manifest guard (step 5.5, #3384) blocks on the stale/empty consumed file.
After wave N merges and tracking commits, the orchestrator HEAD has advanced past the commit the
Claude Code harness may have cached as the worktree fork base at session start. New worktrees
spawned for wave N+1 could fork from the stale pre-wave-N HEAD, causing every executor to trip the
worktree_branch_check FATAL guard immediately (symptom: HEAD is <old-sha>, expected <new-sha>).
# Unset per-wave manifest so wave N+1 creates a fresh one (#3384, #1369).
unset WAVE_WORKTREE_MANIFEST
# Between-wave base refresh (#1369): after wave N merges and tracking commits, HEAD has
# advanced. Re-assert worktree.baseRef:"head" (idempotent — no-op if already set) so the
# Claude Code harness re-reads the live HEAD on the next Agent(isolation="worktree") call
# rather than using a cached session-start commit as the fork base.
if [ "$RUNTIME" = "claude" ] && [ "$USE_WORKTREES" != "false" ]; then
gsd_run query worktree.set-baseref 2>/dev/null || true
# Safety re-check: evaluate degradation AFTER the wave N commits. If HEAD has diverged
# from origin/HEAD and baseRef is NOT "head", degrade remaining waves to sequential to
# avoid the base-mismatch FATAL in executor agents.
_BETWEEN_DEGRADE=$(gsd_run query worktree.base-check --pick shouldDegrade 2>/dev/null || echo "false")
if [ "$_BETWEEN_DEGRADE" = "true" ]; then
_DEGRADE_MSG=$(gsd_run query worktree.base-check --pick message 2>/dev/null || true)
[ -n "$_DEGRADE_MSG" ] && printf '%s\n' "$_DEGRADE_MSG" >&2
printf 'Degrading to sequential mode for remaining waves: HEAD advanced past worktree fork base after wave %s merge (#1369).\n' "${N}" >&2
USE_WORKTREES=false
fi
fi