Files
msd-core/get-shit-done/workflows/validate-phase.md
Tom Boucher e3bc53f835 enhancement(#558): add liveness hints to all GSD spawn announcements (#566)
* enhancement(#558): add liveness hints to all GSD spawn announcements

Append '(runs in a subagent — no output until it returns, ~1–5 min; expected,
not a freeze)' inline to every ◆ Spawning… banner and subagent dispatch
instruction across 26 workflows. Silent subagents look identical to frozen
sessions — this note sets the expectation so users wait instead of killing
healthy in-progress work.

Changes:
- references/ui-brand.md: document liveness convention under Spawning Indicators
- 10 banner workflows: append liveness note to ◆ Spawning… lines in-place
- 18 subagent-only workflows: add print instruction with liveness phrase
- tests/spawn-liveness-banner.test.cjs: new test; fails if any workflow with
  subagent_type omits 'runs in a subagent'
- docs/USER-GUIDE.md: troubleshooting entry for frozen-looking spawns
- .changeset/558-spawn-liveness-banner.md: changeset fragment

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#558): add missing pr field to changeset fragment

The changeset lint requires pr: <NNN> in frontmatter; the fragment was
written without it, causing parse.cjs to reject it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#558): address codex review — missed spawns and tighten test

- plan-phase.md: add liveness note to chunked outline planner and
  per-plan chunked planner banners (two missed ◆ Spawning… lines)
- quick.md: add liveness note to research banner and add missing
  display line before planner spawn in Step 5
- plan-review-convergence.md: add liveness note to initial planning
  and review-agent spawn Display lines
- docs-update.md: add Print instructions with liveness note before
  gsd-doc-verifier spawns in Phase 1 and Phase 2
- autonomous.md: add Print instruction with liveness note before
  background plan-phase agent dispatch in step 3b
- tests/spawn-liveness-banner.test.cjs: replace single file-level
  check with two assertions:
  (1) every ◆ Spawning… banner line carries the phrase on that line
  (2) every file with subagent_type contains the phrase somewhere
  The tighter test would have caught all five missed spawns.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#558): tighten spawn-liveness test regex to catch spawn-word-anywhere variants

Previous SPAWN_BANNER_RE only matched ◆ immediately followed by Spawning|spawning.
Replace with /◆[^\n]*\bspawning?\b/i which matches the spawn word anywhere on the
◆ line — catching "◆ Chunked mode: spawning outline planner..." and similar.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* fix(#558): rename changeset to PR number 566 and correct pr field

Changeset was filed as 558-spawn-liveness-banner.md (issue#) but the
convention is the PR number. Renamed to 566-spawn-liveness-banner.md
and updated pr: 558 → pr: 566 so release notes link to the right PR.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-31 23:33:49 -04:00

182 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<purpose>
Audit Nyquist validation gaps for a completed phase. Generate missing tests. Update VALIDATION.md.
</purpose>
<required_reading>
@~/.claude/get-shit-done/references/ui-brand.md
</required_reading>
<available_agent_types>
Valid GSD subagent types (use exact names — do not fall back to 'general-purpose'):
- gsd-nyquist-auditor — Validates verification coverage
</available_agent_types>
<process>
## 0. Initialize
```bash
_GSD_SHIM_NAME="gsd-tools.cjs"; _GSD_RUNTIME_ROOT="${RUNTIME_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)}"; GSD_TOOLS="${_GSD_RUNTIME_ROOT}/get-shit-done/bin/${_GSD_SHIM_NAME}"; if [ -f "$GSD_TOOLS" ]; then gsd_run() { node "$GSD_TOOLS" "$@"; }; elif [ -f "${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="${_GSD_RUNTIME_ROOT}/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; elif command -v gsd-tools >/dev/null 2>&1; then GSD_TOOLS="$(command -v gsd-tools)"; gsd_run() { "$GSD_TOOLS" "$@"; }; elif [ -f "$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}" ]; then GSD_TOOLS="$HOME/.claude/get-shit-done/bin/${_GSD_SHIM_NAME}"; gsd_run() { node "$GSD_TOOLS" "$@"; }; else echo "ERROR: gsd-tools.cjs not found at $GSD_TOOLS and gsd-tools is not on PATH. Run: npx -y @opengsd/gsd-core@latest --claude --local" >&2; exit 1; fi
INIT=$(gsd_run query init.phase-op "${PHASE_ARG}")
if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
AGENT_SKILLS_AUDITOR=$(gsd_run query agent-skills gsd-nyquist-auditor)
```
Parse: `phase_dir`, `phase_number`, `phase_name`, `phase_slug`, `padded_phase`.
```bash
AUDITOR_MODEL=$(gsd_run query resolve-model gsd-nyquist-auditor --raw)
NYQUIST_CFG=$(gsd_run query config-get workflow.nyquist_validation --raw --default true)
```
If `NYQUIST_CFG` is `false`: exit with "Nyquist validation is disabled. Enable via /gsd:settings."
Display banner: `GSD > VALIDATE PHASE {N}: {name}`
## 1. Detect Input State
```bash
VALIDATION_FILE=$(ls "${PHASE_DIR}"/*-VALIDATION.md 2>/dev/null | head -1)
SUMMARY_FILES=$(ls "${PHASE_DIR}"/*-SUMMARY.md 2>/dev/null)
```
- **State A** (`VALIDATION_FILE` non-empty): Audit existing
- **State B** (`VALIDATION_FILE` empty, `SUMMARY_FILES` non-empty): Reconstruct from artifacts
- **State C** (`SUMMARY_FILES` empty): Exit — "Phase {N} not executed. Run /gsd:execute-phase {N} ${GSD_WS} first."
## 2. Discovery
### 2a. Read Phase Artifacts
Read all PLAN and SUMMARY files. Extract: task lists, requirement IDs, key-files changed, verify blocks.
### 2b. Build Requirement-to-Task Map
Per task: `{ task_id, plan_id, wave, requirement_ids, has_automated_command }`
### 2c. Detect Test Infrastructure
State A: Parse from existing VALIDATION.md Test Infrastructure table.
State B: Filesystem scan:
```bash
find . -name "pytest.ini" -o -name "jest.config.*" -o -name "vitest.config.*" -o -name "pyproject.toml" 2>/dev/null | head -10
find . \( -name "*.test.*" -o -name "*.spec.*" -o -name "test_*" \) -not -path "*/node_modules/*" 2>/dev/null | head -40
```
### 2d. Cross-Reference
Match each requirement to existing tests by filename, imports, test descriptions. Record: requirement → test_file → status.
## 3. Gap Analysis
Classify each requirement:
| Status | Criteria |
|--------|----------|
| COVERED | Test exists, targets behavior, runs green |
| PARTIAL | Test exists, failing or incomplete |
| MISSING | No test found |
Build: `{ task_id, requirement, gap_type, suggested_test_path, suggested_command }`
No gaps → skip to Step 6, set `nyquist_compliant: true`.
## 4. Present Gap Plan
**Text mode (`workflow.text_mode: true` in config or `--text` flag):** Set `TEXT_MODE=true` if `--text` is present in `$ARGUMENTS` OR `text_mode` from init JSON is `true`. When TEXT_MODE is active, replace every `AskUserQuestion` call with a plain-text numbered list and ask the user to type their choice number. This is required for non-Claude runtimes (OpenAI Codex, Gemini CLI, etc.) where `AskUserQuestion` is not available.
Call AskUserQuestion with gap table and options:
1. "Fix all gaps" → Step 5
2. "Skip — mark manual-only" → add to Manual-Only, Step 6
3. "Cancel" → exit
## 5. Spawn gsd-nyquist-auditor
Print: `◆ Spawning nyquist auditor... (runs in a subagent — no output until it returns, ~1–5 min; expected, not a freeze)`
```
Agent(
prompt="Read ~/.claude/agents/gsd-nyquist-auditor.md for instructions.\n\n" +
"<files_to_read>{PLAN, SUMMARY, impl files, VALIDATION.md}</files_to_read>" +
"<gaps>{gap list}</gaps>" +
"<test_infrastructure>{framework, config, commands}</test_infrastructure>" +
"<constraints>Never modify impl files. Max 3 debug iterations. Escalate impl bugs.</constraints>" +
"${AGENT_SKILLS_AUDITOR}",
subagent_type="gsd-nyquist-auditor",
model="{AUDITOR_MODEL}",
description="Fill validation gaps for Phase {N}"
)
```
> **ORCHESTRATOR RULE — CODEX RUNTIME**: After calling Agent() above, stop working on this task immediately. Do not read more files, edit code, or run tests related to this task while the subagent is active. Wait for the subagent to return its result. This prevents duplicate work, conflicting edits, and wasted context. Only resume when the subagent result is available.
Handle return:
- `## GAPS FILLED` → record tests + map updates, Step 6
- `## PARTIAL` → record resolved, move escalated to manual-only, Step 6
- `## ESCALATE` → move all to manual-only, Step 6
## 6. Generate/Update VALIDATION.md
**State B (create):**
1. Read template from `~/.claude/get-shit-done/templates/VALIDATION.md`
2. Fill: frontmatter, Test Infrastructure, Per-Task Map, Manual-Only, Sign-Off
3. Write to `${PHASE_DIR}/${PADDED_PHASE}-VALIDATION.md`
**State A (update):**
1. Update Per-Task Map statuses, add escalated to Manual-Only, update frontmatter
2. Append audit trail:
```markdown
## Validation Audit {date}
| Metric | Count |
|--------|-------|
| Gaps found | {N} |
| Resolved | {M} |
| Escalated | {K} |
```
## 7. Commit
```bash
git add {test_files}
git commit -m "test(phase-${PHASE}): add Nyquist validation tests"
gsd_run query commit "docs(phase-${PHASE}): add/update validation strategy"
```
## 8. Results + Routing
**Compliant:**
```
GSD > PHASE {N} IS NYQUIST-COMPLIANT
All requirements have automated verification.
▶ Next: /gsd:audit-milestone ${GSD_WS}
```
**Partial:**
```
GSD > PHASE {N} VALIDATED (PARTIAL)
{M} automated, {K} manual-only.
▶ Retry: /gsd:validate-phase {N} ${GSD_WS}
```
Display `/clear` reminder.
</process>
<success_criteria>
- [ ] Nyquist config checked (exit if disabled)
- [ ] Input state detected (A/B/C)
- [ ] State C exits cleanly
- [ ] PLAN/SUMMARY files read, requirement map built
- [ ] Test infrastructure detected
- [ ] Gaps classified (COVERED/PARTIAL/MISSING)
- [ ] User gate with gap table
- [ ] Auditor spawned with complete context
- [ ] All three return formats handled
- [ ] VALIDATION.md created or updated
- [ ] Test files committed separately
- [ ] Results with routing presented
</success_criteria>