* test(#4682): add failing-first coverage for stale verification routing * fix(#4682): route stale verification to the verifier regeneration path The stale routing entry sent users to /gsd-verify-work — but verify-work never rewrites VERIFICATION.md (its only write is the human_needed canonicalization), so following the advice re-ran UAT, reached the same stale check, and looped. init's projector and execute-phase's generic next_command presentation both mirror this entry, so the dead end appeared on three surfaces. The stale entry now routes to execute-phase, and execute-phase's all-plans-complete resume tree gains a stale arm (as a steps/ part, keeping the spine under its frozen ADR-857 ceiling) mirroring the missing route: skip cross_ai_delegation/execute_waves/checkpoint_handling, continue at aggregate_results, and let verify_phase_goal re-dispatch the gsd-verifier — regenerating VERIFICATION.md and its digest, marked phase or not. The non-stale fall-through. Staleness detection, the digest format (#4623), every other routing entry, and the #3684 resume arms are untouched. Emitted-Drift-Ack-Growth: verify-work.md — stale stop rewritten to dispatch the verifier and re-check (#4682) Emitted-Drift-Ack-Growth: execute-phase.md — VERIFY_STATUS == stale resume arm added to condition 3 (#4682) * test(#4682): register the stale-reverification part and align projected commands The new steps/ part must be registered in the inventory manifest and the per-runtime golden install trees (regen:derived); the projected stale next_command is /gsd-execute-phase <phase> (formatGsdSlash prefixes the runtime surface), the human_needed bare-report probe keeps routing to verify-work (unchanged semantics), and init-manager's recommended action follows the new command. * test(#4682): prefix the remaining stale routing assertions with the runtime surface Nine stale next_command assertions and the human_needed bare-report probe still carried the unprefixed or flipped forms from the earlier line-number edit; all now assert the shipped /gsd-execute-phase <phase> projection, with the human_needed probe reverted to its unchanged verify-work routing. * test(#4682): align the last stale projection assertions with the execute-phase route * docs(#4682): backfill changeset PR number * test(#4682): refresh the compact-content baseline after the rebase The rebase onto the #4670 squash brought verify-work.md's bounded reconciliation text into this branch; the committed compact-content baseline now reflects the post-rebase split sizes. Local --check is clean; the previous bench drift (+243) was the baseline, not the diff. * fix(#4682): carry the response_language directive in the stale-reverification part The new steps/ part is its own coverage unit for lint-response-language-coverage; it takes the shared canonical directive line like its sibling execute-phase parts. --------- Co-authored-by: sim <sim@local>
This commit is contained in:
5
.changeset/vivid-deer-howl.md
Normal file
5
.changeset/vivid-deer-howl.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
type: Fixed
|
||||
pr: 4818
|
||||
---
|
||||
**Stale verification now routes to the verifier** — the `stale` status told users to re-run `/gsd-verify-work`, but that workflow never rewrites VERIFICATION.md, so following the advice looped forever. The routing now names the regeneration path (execute-phase resumes at the verification gates and re-runs the verifier), and verify-work's stale stop dispatches `gsd-verifier` and re-checks instead of self-referencing. (#4682)
|
||||
@@ -664,6 +664,7 @@
|
||||
"execute-phase/steps/regression-gate-run.md",
|
||||
"execute-phase/steps/regression-gate.md",
|
||||
"execute-phase/steps/sequential-root-pin.md",
|
||||
"execute-phase/steps/stale-reverification.md",
|
||||
"execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
@@ -366,6 +366,8 @@ later conditions once one matches:
|
||||
2b. **No filter is active, no blocked-plan skip occurred, and at least one filtered plan was skipped because `ready: false` (#4628)** — the phase is WAITING on incomplete predecessors, not finished: report it by name and exit before any completion state (`execute-phase/steps/ready-wave-gate.md`).
|
||||
3. **No filter is active, and every filtered plan was filtered by `has_summary` alone** (no
|
||||
blocked-plan skip occurred):
|
||||
- **`VERIFY_STATUS == stale` (#4682)**: covered source changed after the verifier ran —
|
||||
re-verify per `execute-phase/steps/stale-reverification.md`.
|
||||
- **`VERIFY_STATUS == missing`**: the plans are all summarized but the run never reached the
|
||||
tail gates. Report:
|
||||
`"All {plan_count} plans are summarized but no VERIFICATION.md exists — resuming at the phase gates (#2868)."`
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
Apply response_language to all user-facing prose — narration between tool calls, status updates, progress notes, and findings included; preserve code, paths, and identifiers.
|
||||
|
||||
<step name="stale_reverification">
|
||||
Covered source files changed after the verifier last ran — the recorded digest no longer
|
||||
matches, so the report cannot be trusted until the verifier re-runs (#4682). The plans are all
|
||||
summarized: there is no wave work to do.
|
||||
|
||||
Report:
|
||||
```
|
||||
"Verification is stale — covered source changed after the verifier ran (#4682). Re-running the verifier for this phase."
|
||||
```
|
||||
|
||||
SKIP `cross_ai_delegation`, `execute_waves` and `checkpoint_handling` — there is no wave work —
|
||||
and continue directly at `aggregate_results` exactly as the `missing` route (#2868): the tail
|
||||
steps re-run in their normal order (`aggregate_results` → `code_review_gate` →
|
||||
`close_parent_artifacts` → `regression_gate` → `verify_phase_goal` → `update_roadmap`), and
|
||||
`verify_phase_goal` re-dispatches the `gsd-verifier`, regenerating VERIFICATION.md and its
|
||||
digest. This holds whether or not the phase was already marked complete — a stale report on a
|
||||
marked phase is refreshed the same way. `verification.status`'s `next_command` routes here for
|
||||
exactly this state.
|
||||
|
||||
Never silently proceed past a stale gate: if the re-run verifier still produces a stale report,
|
||||
stop and present it (#4623 covers what the digest hashes).
|
||||
</step>
|
||||
@@ -673,15 +673,23 @@ if [ "$VERIFICATION_STATUS_VALUE" = "human_needed" ]; then
|
||||
fi
|
||||
```
|
||||
|
||||
If `PHASE_VERIFICATION_STATUS` is `stale`, stop before phase advancement and present:
|
||||
If `PHASE_VERIFICATION_STATUS` is `stale`, the covered source files changed after the verifier
|
||||
last ran — re-run the VERIFIER, not this workflow (`/gsd:verify-work` never rewrites
|
||||
VERIFICATION.md; its only write is the human_needed canonicalization, #4663). Spawn the
|
||||
verifier for this phase exactly as execute-phase's `verify_phase_goal` step does (subagent
|
||||
`gsd-verifier`; phase directory, goal, requirement IDs, and all SUMMARYs in
|
||||
`<required_reading>`), then re-read `verification.status` and continue at the fresh/passed
|
||||
case below. (#4682)
|
||||
|
||||
```
|
||||
All UAT tests passed, but phase advancement is blocked until canonical verification is fresh.
|
||||
Verification is stale: covered source files changed after the verifier last ran.
|
||||
|
||||
Blocking completion:
|
||||
verification is stale
|
||||
|
||||
- `/gsd:verify-work {phase}` — re-run verification against the latest summaries
|
||||
- Re-run the verifier for phase {phase} (dispatch `gsd-verifier` as in execute-phase's
|
||||
verify_phase_goal step) to regenerate VERIFICATION.md with a fresh digest, then re-run
|
||||
`/gsd:verify-work {phase}`
|
||||
```
|
||||
|
||||
Otherwise, check the shared UAT-plus-verification completion predicate before transition:
|
||||
|
||||
@@ -112,8 +112,14 @@ const VERIFICATION_ROUTING_TABLE: Record<string, VerificationRoute> = {
|
||||
},
|
||||
stale: {
|
||||
status: 'stale',
|
||||
next_action: 'Verification is stale. Re-run verify-work before transition.',
|
||||
next_command: '',
|
||||
// #4682: staleness means covered source files changed after the verifier
|
||||
// last ran — the only remedy is re-running the verifier.
|
||||
// /gsd-verify-work never rewrites VERIFICATION.md, so advising it from
|
||||
// here was an advice loop. execute-phase resumes at the verification
|
||||
// gates and re-runs the verifier (its resume tree routes a stale report
|
||||
// to re-verification), which regenerates VERIFICATION.md and its digest.
|
||||
next_action: 'Verification is stale — covered source files changed after the verifier last ran. Re-run execute-phase for this phase: it resumes at the verification gates and re-runs the verifier, regenerating VERIFICATION.md and its digest. verify-work alone cannot refresh a stale report.',
|
||||
next_command: 'execute-phase',
|
||||
},
|
||||
// INTERNAL SENTINEL: constructed when no *-VERIFICATION.md file exists or when
|
||||
// the file has no parseable frontmatter status. Never emitted by the verifier.
|
||||
@@ -1115,7 +1121,10 @@ function readVerificationStatus(
|
||||
return {
|
||||
status: entry.status,
|
||||
next_action: entry.next_action,
|
||||
next_command: projectNextCommand('verify-work', runtime, phaseArg),
|
||||
// #4682: execute-phase resumes at the verification gates and re-runs
|
||||
// the verifier, regenerating VERIFICATION.md and its digest — the same
|
||||
// routing the `missing` sentinel has used since #2868.
|
||||
next_command: projectNextCommand('execute-phase', runtime, phaseArg),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -18,9 +18,9 @@
|
||||
"reductionPct": 16.51
|
||||
},
|
||||
"execute-phase": {
|
||||
"offTokens": 26259,
|
||||
"onTokens": 23969,
|
||||
"reductionPct": 8.72
|
||||
"offTokens": 26297,
|
||||
"onTokens": 24007,
|
||||
"reductionPct": 8.71
|
||||
},
|
||||
"new-project": {
|
||||
"offTokens": 14308,
|
||||
@@ -33,14 +33,14 @@
|
||||
"reductionPct": 11.9
|
||||
},
|
||||
"verify-work": {
|
||||
"offTokens": 13235,
|
||||
"onTokens": 11262,
|
||||
"reductionPct": 14.91
|
||||
"offTokens": 13384,
|
||||
"onTokens": 11411,
|
||||
"reductionPct": 14.74
|
||||
}
|
||||
},
|
||||
"aggregate": {
|
||||
"offTokens": 108873,
|
||||
"onTokens": 92186,
|
||||
"reductionPct": 15.33
|
||||
"offTokens": 109060,
|
||||
"onTokens": 92373,
|
||||
"reductionPct": 15.3
|
||||
}
|
||||
}
|
||||
|
||||
1
tests/fixtures/install-tree/antigravity.json
vendored
1
tests/fixtures/install-tree/antigravity.json
vendored
@@ -453,6 +453,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/augment.json
vendored
1
tests/fixtures/install-tree/augment.json
vendored
@@ -525,6 +525,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
@@ -389,6 +389,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/claude.json
vendored
1
tests/fixtures/install-tree/claude.json
vendored
@@ -453,6 +453,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/cline.json
vendored
1
tests/fixtures/install-tree/cline.json
vendored
@@ -455,6 +455,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/codebuddy.json
vendored
1
tests/fixtures/install-tree/codebuddy.json
vendored
@@ -525,6 +525,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/codex.json
vendored
1
tests/fixtures/install-tree/codex.json
vendored
@@ -489,6 +489,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/copilot.json
vendored
1
tests/fixtures/install-tree/copilot.json
vendored
@@ -454,6 +454,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/cursor.json
vendored
1
tests/fixtures/install-tree/cursor.json
vendored
@@ -453,6 +453,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/hermes.json
vendored
1
tests/fixtures/install-tree/hermes.json
vendored
@@ -453,6 +453,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/kilo.json
vendored
1
tests/fixtures/install-tree/kilo.json
vendored
@@ -525,6 +525,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/kimi-code.json
vendored
1
tests/fixtures/install-tree/kimi-code.json
vendored
@@ -454,6 +454,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/kimi.json
vendored
1
tests/fixtures/install-tree/kimi.json
vendored
@@ -461,6 +461,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/opencode.json
vendored
1
tests/fixtures/install-tree/opencode.json
vendored
@@ -525,6 +525,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/pi.json
vendored
1
tests/fixtures/install-tree/pi.json
vendored
@@ -255,6 +255,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/qwen.json
vendored
1
tests/fixtures/install-tree/qwen.json
vendored
@@ -453,6 +453,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/trae.json
vendored
1
tests/fixtures/install-tree/trae.json
vendored
@@ -453,6 +453,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/windsurf.json
vendored
1
tests/fixtures/install-tree/windsurf.json
vendored
@@ -381,6 +381,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
1
tests/fixtures/install-tree/zcode.json
vendored
1
tests/fixtures/install-tree/zcode.json
vendored
@@ -525,6 +525,7 @@
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate-run.md",
|
||||
"gsd-core/workflows/execute-phase/steps/regression-gate.md",
|
||||
"gsd-core/workflows/execute-phase/steps/sequential-root-pin.md",
|
||||
"gsd-core/workflows/execute-phase/steps/stale-reverification.md",
|
||||
"gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md",
|
||||
"gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md",
|
||||
"gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md",
|
||||
|
||||
@@ -372,7 +372,7 @@ describe('init manager', () => {
|
||||
assert.strictEqual(output.phases[0].phase_complete, false);
|
||||
assert.strictEqual(output.recommended_actions[0].action, 'verify');
|
||||
assert.match(output.recommended_actions[0].reason, /verification stale/);
|
||||
assert.match(output.recommended_actions[0].command, /verify-work 1/);
|
||||
assert.match(output.recommended_actions[0].command, /execute-phase 1/);
|
||||
});
|
||||
|
||||
test('checked unpadded roadmap token does not satisfy padded unverified dependency', () => {
|
||||
|
||||
@@ -4367,7 +4367,7 @@ describe('phase complete canonical verification gate (#1522)', () => {
|
||||
// runtime's installed surface. This project has no runtime configured, so it
|
||||
// takes the `claude` default — the canonical `/gsd-` hyphen form. The colon
|
||||
// form this previously asserted is the deprecated shape #2617 removed.
|
||||
assert.match(errorPayload.message, /\/gsd-verify-work 0?1/);
|
||||
assert.match(errorPayload.message, /\/gsd-execute-phase 0?1/);
|
||||
assert.equal(fs.readFileSync(roadmapPath, 'utf-8'), beforeRoadmap);
|
||||
assert.equal(fs.readFileSync(statePath, 'utf-8'), beforeState);
|
||||
});
|
||||
|
||||
@@ -401,7 +401,15 @@ describe('verification-status', () => {
|
||||
const result = readVerificationStatus(dir, { phaseCleanCommitTimesMs: () => new Map() });
|
||||
assert.equal(result.status, 'stale');
|
||||
assert.match(result.next_action, /stale/i);
|
||||
assert.equal(result.next_command, '/gsd-verify-work 01');
|
||||
// #4682: stale means covered source changed after the verifier ran — the
|
||||
// only remedy is re-running the verifier. execute-phase resumes at the
|
||||
// verification gates and re-runs it (its resume tree routes a stale
|
||||
// report to re-verification); /gsd-verify-work never rewrote the report,
|
||||
// so routing there was an advice loop.
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 01');
|
||||
assert.doesNotMatch(result.next_command, /verify-work/);
|
||||
assert.match(result.next_action, /verifier/i,
|
||||
'the stale action must name the verifier re-run as the remedy');
|
||||
} finally {
|
||||
cleanup(baseDir);
|
||||
}
|
||||
@@ -444,7 +452,7 @@ describe('verification-status', () => {
|
||||
// git times unavailable → mtime-fallback path (#2348).
|
||||
const result = readVerificationStatus(dir, { phaseCleanCommitTimesMs: () => new Map() });
|
||||
assert.equal(result.status, 'stale');
|
||||
assert.equal(result.next_command, '/gsd-verify-work 01');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 01');
|
||||
} finally {
|
||||
cleanup(baseDir);
|
||||
}
|
||||
@@ -526,7 +534,7 @@ describe('verification-status', () => {
|
||||
|
||||
const result = readVerificationStatus(dir, { phaseCleanCommitTimesMs });
|
||||
assert.equal(result.status, 'stale');
|
||||
assert.equal(result.next_command, '/gsd-verify-work 02');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 02');
|
||||
} finally {
|
||||
cleanup(baseDir);
|
||||
}
|
||||
@@ -591,7 +599,7 @@ describe('verification-status', () => {
|
||||
'stale',
|
||||
'a dirty summary edited after the verification must stale it via mtime, not be shadowed by an equal/earlier commit time',
|
||||
);
|
||||
assert.equal(result.next_command, '/gsd-verify-work 02');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 02');
|
||||
} finally {
|
||||
cleanup(baseDir);
|
||||
}
|
||||
@@ -708,7 +716,7 @@ describe('verification-status', () => {
|
||||
'stale',
|
||||
'summary committed after the verification must read stale on the real git clock, and the dash-named file must resolve through the `--` pathspec guard',
|
||||
);
|
||||
assert.equal(result.next_command, '/gsd-verify-work 01');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 01');
|
||||
} finally {
|
||||
cleanup(repo);
|
||||
}
|
||||
@@ -756,7 +764,7 @@ describe('verification-status', () => {
|
||||
'stale',
|
||||
'a committed-then-edited (dirty) summary must read stale via mtime, not be shadowed by its now-stale commit time',
|
||||
);
|
||||
assert.equal(result.next_command, '/gsd-verify-work 01');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 01');
|
||||
} finally {
|
||||
cleanup(repo);
|
||||
}
|
||||
@@ -1396,7 +1404,7 @@ describe('#4187: status surface recognizes a bare VERIFICATION.md', () => {
|
||||
|
||||
const result = readVerificationStatus(dir, { phaseCleanCommitTimesMs: () => new Map() });
|
||||
assert.equal(result.status, 'stale', 'a bare report must be staleness-checked like a dashed one');
|
||||
assert.equal(result.next_command, '/gsd-verify-work 99');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 99');
|
||||
});
|
||||
|
||||
test('#4187 unit (findStaleVerificationSummary): staleness is computed against the bare report', (t) => {
|
||||
@@ -1446,7 +1454,7 @@ describe('#4142: opts.convention threads through findStaleVerificationSummary',
|
||||
'stale',
|
||||
'opts.convention must reach the legacy staleness seam so phase 03 is compared to 03-VERIFICATION.md',
|
||||
);
|
||||
assert.equal(result.next_command, '/gsd-verify-work');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -2025,7 +2033,7 @@ describe('#4155: readVerificationStatus — fingerprint supersedes legacy mtime
|
||||
|
||||
const result = readVerificationStatus(dir, { phaseCleanCommitTimesMs: () => new Map() });
|
||||
assert.equal(result.status, 'stale');
|
||||
assert.equal(result.next_command, '/gsd-verify-work 01');
|
||||
assert.equal(result.next_command, '/gsd-execute-phase 01');
|
||||
});
|
||||
|
||||
// Ponytail #4155 review finding: "disappeared" and "escapes confinement"
|
||||
@@ -2825,7 +2833,7 @@ for (const { id, prefix } of RUNTIMES) {
|
||||
makeStale();
|
||||
const result = read(id, NO_GIT);
|
||||
assert.equal(result.status, 'stale');
|
||||
assert.equal(result.next_command, `${prefix}verify-work 01`);
|
||||
assert.equal(result.next_command, `${prefix}execute-phase 01`);
|
||||
});
|
||||
|
||||
test('passed has no next step and stays empty, not a bare prefix', () => {
|
||||
|
||||
@@ -288,3 +288,23 @@ describe('bug #3381: verify-work forwards workstream context', () => {
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// ── #4682 — the stale stop routes to the verifier, not to itself ─────────────
|
||||
// A stale report means covered source files changed after the verifier ran;
|
||||
// the only remedy is re-running the verifier. /gsd-verify-work never rewrites
|
||||
// VERIFICATION.md, so advising it from its own stale block is an advice loop.
|
||||
describe('verify-work.md — stale stop routes to the verifier (#4682)', () => {
|
||||
test('the stale stop instructs re-running the verifier, not verify-work (#4682)', () => {
|
||||
const content = fs.readFileSync(VERIFY_WORK, 'utf-8');
|
||||
const staleIdx = content.indexOf('If `PHASE_VERIFICATION_STATUS` is `stale`');
|
||||
assert.ok(staleIdx !== -1, 'the stale stop must exist');
|
||||
const block = content.slice(staleIdx, staleIdx + 1600);
|
||||
|
||||
assert.match(block, /gsd-verifier/, 'the stale stop must route to the gsd-verifier agent');
|
||||
assert.match(block, /verification\.status/, 'it must re-check verification.status afterwards');
|
||||
assert.doesNotMatch(
|
||||
block, /`\/gsd:verify-work \{phase\}` — re-run verification/,
|
||||
'the self-referential re-run advice must be gone'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user