* chore: rename npm package + bin to @opengsd/gsd-core (functional) - package.json: name @opengsd/get-shit-done-redux → @opengsd/gsd-core, bin key get-shit-done-redux → gsd-core, repository/homepage/bugs URLs - package-lock.json: regenerated (npm install --package-lock-only) - tests/**, scripts/**, bin/**, .github/**, agents/**, commands/**, get-shit-done/bin/**, get-shit-done/workflows/**: applied the 4-rule replacement (scoped npm ref, GitHub repo path, bin/clone invocations) per #505 single-source refactor Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: sweep live references to @opengsd/gsd-core Update all live documentation (README.md + translations, docs/**, CONTRIBUTING.md, VERSIONING.md, SECURITY.md, CONTEXT.md, docs/CANARY.md) to reflect the renamed package and repository. Rules applied: - @opengsd/get-shit-done-redux → @opengsd/gsd-core (scoped npm name) - open-gsd/get-shit-done-redux → open-gsd/gsd-core (GitHub repo) - GSD-redux/get-shit-done-redux → open-gsd/gsd-core (stale badge org) - bare bin/clone refs → gsd-core CHANGELOG.md, docs/adr/**, docs/RELEASE-*.md, docs/research/**, and .changeset/** are preserved byte-identical. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * fix: add negative lookbehind to slash-command regex in bug-2954 test The extractSlashReferences regex matched /gsd-core inside npm package URLs (@opengsd/gsd-core), producing a false /gsd:core command reference. Adding a negative lookbehind (?<![a-z]) excludes matches preceded by a letter, so only standalone /gsd-<cmd> and /gsd:<cmd> tokens are found. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#518): add changeset for package rename Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * test(#518): update package-identity expectations to the renamed coordinates The rebase regenerated the seam to @opengsd/gsd-core (bin gsd-core, repo open-gsd/gsd-core). The #498 seam tests assert deriveIdentity against the REAL package.json, so their expected literals must follow the rename. The drift-lint unit test is left as-is — its SEAM is a self-consistent fixture and its stale-literal detection cases would shift if altered; the live-repo scan in it already passes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
6.8 KiB
<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>
0. Initialize
_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.
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
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_FILEnon-empty): Audit existing - State B (
VALIDATION_FILEempty,SUMMARY_FILESnon-empty): Reconstruct from artifacts - State C (
SUMMARY_FILESempty): 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:
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:
- "Fix all gaps" → Step 5
- "Skip — mark manual-only" → add to Manual-Only, Step 6
- "Cancel" → exit
5. Spawn gsd-nyquist-auditor
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):
- Read template from
~/.claude/get-shit-done/templates/VALIDATION.md - Fill: frontmatter, Test Infrastructure, Per-Task Map, Manual-Only, Sign-Off
- Write to
${PHASE_DIR}/${PADDED_PHASE}-VALIDATION.md
State A (update):
- Update Per-Task Map statuses, add escalated to Manual-Only, update frontmatter
- Append audit trail:
## Validation Audit {date}
| Metric | Count |
|--------|-------|
| Gaps found | {N} |
| Resolved | {M} |
| Escalated | {K} |
7. Commit
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.
<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>