gsd-opencode 1.20.4 → 1.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. package/agents/gsd-codebase-mapper.md +10 -1
  2. package/agents/gsd-debugger.md +67 -10
  3. package/agents/gsd-executor.md +37 -16
  4. package/agents/gsd-integration-checker.md +3 -0
  5. package/agents/gsd-nyquist-auditor.md +179 -0
  6. package/agents/gsd-phase-researcher.md +29 -34
  7. package/agents/gsd-plan-checker.md +43 -78
  8. package/agents/gsd-planner.md +140 -24
  9. package/agents/gsd-project-researcher.md +12 -1
  10. package/agents/gsd-research-synthesizer.md +14 -3
  11. package/agents/gsd-roadmapper.md +26 -15
  12. package/agents/gsd-verifier.md +30 -6
  13. package/bin/dm/lib/constants.js +6 -1
  14. package/bin/dm/src/services/file-ops.js +14 -1
  15. package/commands/gsd/gsd-add-phase.md +6 -6
  16. package/commands/gsd/gsd-add-tests.md +41 -0
  17. package/commands/gsd/gsd-add-todo.md +7 -7
  18. package/commands/gsd/gsd-audit-milestone.md +9 -9
  19. package/commands/gsd/gsd-check-profile.md +3 -3
  20. package/commands/gsd/gsd-check-todos.md +7 -7
  21. package/commands/gsd/gsd-cleanup.md +2 -2
  22. package/commands/gsd/gsd-complete-milestone.md +6 -6
  23. package/commands/gsd/gsd-debug.md +11 -7
  24. package/commands/gsd/gsd-discuss-phase.md +26 -19
  25. package/commands/gsd/gsd-execute-phase.md +13 -13
  26. package/commands/gsd/gsd-health.md +7 -7
  27. package/commands/gsd/gsd-help.md +2 -2
  28. package/commands/gsd/gsd-insert-phase.md +6 -6
  29. package/commands/gsd/gsd-join-discord.md +1 -1
  30. package/commands/gsd/gsd-list-phase-assumptions.md +6 -6
  31. package/commands/gsd/gsd-map-codebase.md +8 -8
  32. package/commands/gsd/gsd-new-milestone.md +12 -12
  33. package/commands/gsd/gsd-new-project.md +12 -12
  34. package/commands/gsd/gsd-pause-work.md +6 -6
  35. package/commands/gsd/gsd-plan-milestone-gaps.md +9 -9
  36. package/commands/gsd/gsd-plan-phase.md +14 -13
  37. package/commands/gsd/gsd-progress.md +8 -8
  38. package/commands/gsd/gsd-quick.md +17 -13
  39. package/commands/gsd/gsd-reapply-patches.md +20 -9
  40. package/commands/gsd/gsd-remove-phase.md +7 -7
  41. package/commands/gsd/gsd-research-phase.md +12 -11
  42. package/commands/gsd/gsd-resume-work.md +8 -8
  43. package/commands/gsd/gsd-set-profile.md +6 -6
  44. package/commands/gsd/gsd-settings.md +7 -7
  45. package/commands/gsd/gsd-update.md +5 -5
  46. package/commands/gsd/gsd-validate-phase.md +35 -0
  47. package/commands/gsd/gsd-verify-work.md +11 -11
  48. package/get-shit-done/bin/gsd-tools.cjs +45 -6
  49. package/get-shit-done/bin/lib/commands.cjs +11 -19
  50. package/get-shit-done/bin/lib/config.cjs +8 -1
  51. package/get-shit-done/bin/lib/core.cjs +131 -16
  52. package/get-shit-done/bin/lib/init.cjs +28 -12
  53. package/get-shit-done/bin/lib/milestone.cjs +34 -8
  54. package/get-shit-done/bin/lib/phase.cjs +74 -50
  55. package/get-shit-done/bin/lib/roadmap.cjs +7 -7
  56. package/get-shit-done/bin/lib/state.cjs +294 -63
  57. package/get-shit-done/bin/lib/template.cjs +3 -3
  58. package/get-shit-done/bin/lib/verify.cjs +56 -8
  59. package/get-shit-done/references/checkpoints.md +1 -1
  60. package/get-shit-done/references/decimal-phase-calculation.md +6 -6
  61. package/get-shit-done/references/git-integration.md +3 -3
  62. package/get-shit-done/references/git-planning-commit.md +2 -2
  63. package/get-shit-done/references/model-profile-resolution.md +1 -1
  64. package/get-shit-done/references/model-profiles.md +1 -0
  65. package/get-shit-done/references/phase-argument-parsing.md +4 -4
  66. package/get-shit-done/references/planning-config.md +10 -6
  67. package/get-shit-done/references/questioning.md +17 -0
  68. package/get-shit-done/references/verification-patterns.md +1 -1
  69. package/get-shit-done/templates/DEBUG.md +7 -2
  70. package/get-shit-done/templates/VALIDATION.md +18 -46
  71. package/get-shit-done/templates/codebase/structure.md +3 -3
  72. package/get-shit-done/templates/config.json +2 -2
  73. package/get-shit-done/templates/context.md +14 -0
  74. package/get-shit-done/templates/phase-prompt.md +10 -10
  75. package/get-shit-done/templates/retrospective.md +54 -0
  76. package/get-shit-done/templates/roadmap.md +1 -1
  77. package/get-shit-done/workflows/add-phase.md +3 -2
  78. package/get-shit-done/workflows/add-tests.md +351 -0
  79. package/get-shit-done/workflows/add-todo.md +4 -3
  80. package/get-shit-done/workflows/audit-milestone.md +40 -5
  81. package/get-shit-done/workflows/check-todos.md +3 -2
  82. package/get-shit-done/workflows/cleanup.md +1 -1
  83. package/get-shit-done/workflows/complete-milestone.md +69 -5
  84. package/get-shit-done/workflows/diagnose-issues.md +2 -2
  85. package/get-shit-done/workflows/discovery-phase.md +6 -6
  86. package/get-shit-done/workflows/discuss-phase.md +194 -58
  87. package/get-shit-done/workflows/execute-phase.md +29 -23
  88. package/get-shit-done/workflows/execute-plan.md +22 -18
  89. package/get-shit-done/workflows/health.md +5 -2
  90. package/get-shit-done/workflows/help.md +4 -1
  91. package/get-shit-done/workflows/insert-phase.md +3 -2
  92. package/get-shit-done/workflows/map-codebase.md +3 -2
  93. package/get-shit-done/workflows/new-milestone.md +12 -10
  94. package/get-shit-done/workflows/new-project.md +44 -49
  95. package/get-shit-done/workflows/pause-work.md +2 -2
  96. package/get-shit-done/workflows/plan-milestone-gaps.md +3 -3
  97. package/get-shit-done/workflows/plan-phase.md +155 -73
  98. package/get-shit-done/workflows/progress.md +8 -7
  99. package/get-shit-done/workflows/quick.md +158 -10
  100. package/get-shit-done/workflows/remove-phase.md +5 -4
  101. package/get-shit-done/workflows/research-phase.md +5 -4
  102. package/get-shit-done/workflows/resume-project.md +3 -2
  103. package/get-shit-done/workflows/set-profile.md +3 -2
  104. package/get-shit-done/workflows/settings.md +6 -6
  105. package/get-shit-done/workflows/transition.md +5 -5
  106. package/get-shit-done/workflows/update.md +45 -19
  107. package/get-shit-done/workflows/validate-phase.md +167 -0
  108. package/get-shit-done/workflows/verify-phase.md +10 -9
  109. package/get-shit-done/workflows/verify-work.md +18 -4
  110. package/package.json +1 -1
@@ -6,6 +6,7 @@ const fs = require('fs');
6
6
  const path = require('path');
7
7
  const { safeReadFile, normalizePhaseName, execGit, findPhaseInternal, getMilestoneInfo, output, error } = require('./core.cjs');
8
8
  const { extractFrontmatter, parseMustHavesBlock } = require('./frontmatter.cjs');
9
+ const { writeStateMd } = require('./state.cjs');
9
10
 
10
11
  function cmdVerifySummary(cwd, summaryPath, checkFileCount, raw) {
11
12
  if (!summaryPath) {
@@ -410,7 +411,7 @@ function cmdValidateConsistency(cwd, raw) {
410
411
 
411
412
  // Extract phases from ROADMAP
412
413
  const roadmapPhases = new Set();
413
- const phasePattern = /#{2,4}\s*Phase\s+(\d+(?:\.\d+)?)\s*:/gi;
414
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
414
415
  let m;
415
416
  while ((m = phasePattern.exec(roadmapContent)) !== null) {
416
417
  roadmapPhases.add(m[1]);
@@ -422,7 +423,7 @@ function cmdValidateConsistency(cwd, raw) {
422
423
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
423
424
  const dirs = entries.filter(e => e.isDirectory()).map(e => e.name);
424
425
  for (const dir of dirs) {
425
- const dm = dir.match(/^(\d+(?:\.\d+)?)/);
426
+ const dm = dir.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);
426
427
  if (dm) diskPhases.add(dm[1]);
427
428
  }
428
429
  } catch {}
@@ -572,14 +573,14 @@ function cmdValidateHealth(cwd, options, raw) {
572
573
  } else {
573
574
  const stateContent = fs.readFileSync(statePath, 'utf-8');
574
575
  // Extract phase references from STATE.md
575
- const phaseRefs = [...stateContent.matchAll(/[Pp]hase\s+(\d+(?:\.\d+)?)/g)].map(m => m[1]);
576
+ const phaseRefs = [...stateContent.matchAll(/[Pp]hase\s+(\d+(?:\.\d+)*)/g)].map(m => m[1]);
576
577
  // Get disk phases
577
578
  const diskPhases = new Set();
578
579
  try {
579
580
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
580
581
  for (const e of entries) {
581
582
  if (e.isDirectory()) {
582
- const m = e.name.match(/^(\d+(?:\.\d+)?)/);
583
+ const m = e.name.match(/^(\d+(?:\.\d+)*)/);
583
584
  if (m) diskPhases.add(m[1]);
584
585
  }
585
586
  }
@@ -616,11 +617,23 @@ function cmdValidateHealth(cwd, options, raw) {
616
617
  }
617
618
  }
618
619
 
620
+ // ─── Check 5b: Nyquist validation key presence ──────────────────────────
621
+ if (fs.existsSync(configPath)) {
622
+ try {
623
+ const configRaw = fs.readFileSync(configPath, 'utf-8');
624
+ const configParsed = JSON.parse(configRaw);
625
+ if (configParsed.workflow && configParsed.workflow.nyquist_validation === undefined) {
626
+ addIssue('warning', 'W008', 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)', 'Run /gsd-health --repair to add key', true);
627
+ if (!repairs.includes('addNyquistKey')) repairs.push('addNyquistKey');
628
+ }
629
+ } catch {}
630
+ }
631
+
619
632
  // ─── Check 6: Phase directory naming (NN-name format) ─────────────────────
620
633
  try {
621
634
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
622
635
  for (const e of entries) {
623
- if (e.isDirectory() && !e.name.match(/^\d{2}(?:\.\d+)?-[\w-]+$/)) {
636
+ if (e.isDirectory() && !e.name.match(/^\d{2}(?:\.\d+)*-[\w-]+$/)) {
624
637
  addIssue('warning', 'W005', `Phase directory "${e.name}" doesn't follow NN-name format`, 'Rename to match pattern (e.g., 01-setup)');
625
638
  }
626
639
  }
@@ -645,12 +658,30 @@ function cmdValidateHealth(cwd, options, raw) {
645
658
  }
646
659
  } catch {}
647
660
 
661
+ // ─── Check 7b: Nyquist VALIDATION.md consistency ────────────────────────
662
+ try {
663
+ const phaseEntries = fs.readdirSync(phasesDir, { withFileTypes: true });
664
+ for (const e of phaseEntries) {
665
+ if (!e.isDirectory()) continue;
666
+ const phaseFiles = fs.readdirSync(path.join(phasesDir, e.name));
667
+ const hasResearch = phaseFiles.some(f => f.endsWith('-RESEARCH.md'));
668
+ const hasValidation = phaseFiles.some(f => f.endsWith('-VALIDATION.md'));
669
+ if (hasResearch && !hasValidation) {
670
+ const researchFile = phaseFiles.find(f => f.endsWith('-RESEARCH.md'));
671
+ const researchContent = fs.readFileSync(path.join(phasesDir, e.name, researchFile), 'utf-8');
672
+ if (researchContent.includes('## Validation Architecture')) {
673
+ addIssue('warning', 'W009', `Phase ${e.name}: has Validation Architecture in RESEARCH.md but no VALIDATION.md`, 'Re-run /gsd-plan-phase with --research to regenerate');
674
+ }
675
+ }
676
+ }
677
+ } catch {}
678
+
648
679
  // ─── Check 8: Run existing consistency checks ─────────────────────────────
649
680
  // Inline subset of cmdValidateConsistency
650
681
  if (fs.existsSync(roadmapPath)) {
651
682
  const roadmapContent = fs.readFileSync(roadmapPath, 'utf-8');
652
683
  const roadmapPhases = new Set();
653
- const phasePattern = /#{2,4}\s*Phase\s+(\d+(?:\.\d+)?)\s*:/gi;
684
+ const phasePattern = /#{2,4}\s*Phase\s+(\d+[A-Z]?(?:\.\d+)*)\s*:/gi;
654
685
  let m;
655
686
  while ((m = phasePattern.exec(roadmapContent)) !== null) {
656
687
  roadmapPhases.add(m[1]);
@@ -661,7 +692,7 @@ function cmdValidateHealth(cwd, options, raw) {
661
692
  const entries = fs.readdirSync(phasesDir, { withFileTypes: true });
662
693
  for (const e of entries) {
663
694
  if (e.isDirectory()) {
664
- const dm = e.name.match(/^(\d+(?:\.\d+)?)/);
695
+ const dm = e.name.match(/^(\d+[A-Z]?(?:\.\d+)*)/i);
665
696
  if (dm) diskPhases.add(dm[1]);
666
697
  }
667
698
  }
@@ -725,10 +756,27 @@ function cmdValidateHealth(cwd, options, raw) {
725
756
  stateContent += `**Status:** Resuming\n\n`;
726
757
  stateContent += `## Session Log\n\n`;
727
758
  stateContent += `- ${new Date().toISOString().split('T')[0]}: STATE.md regenerated by /gsd-health --repair\n`;
728
- fs.writeFileSync(statePath, stateContent, 'utf-8');
759
+ writeStateMd(statePath, stateContent, cwd);
729
760
  repairActions.push({ action: repair, success: true, path: 'STATE.md' });
730
761
  break;
731
762
  }
763
+ case 'addNyquistKey': {
764
+ if (fs.existsSync(configPath)) {
765
+ try {
766
+ const configRaw = fs.readFileSync(configPath, 'utf-8');
767
+ const configParsed = JSON.parse(configRaw);
768
+ if (!configParsed.workflow) configParsed.workflow = {};
769
+ if (configParsed.workflow.nyquist_validation === undefined) {
770
+ configParsed.workflow.nyquist_validation = true;
771
+ fs.writeFileSync(configPath, JSON.stringify(configParsed, null, 2), 'utf-8');
772
+ }
773
+ repairActions.push({ action: repair, success: true, path: 'config.json' });
774
+ } catch (err) {
775
+ repairActions.push({ action: repair, success: false, error: err.message });
776
+ }
777
+ }
778
+ break;
779
+ }
732
780
  }
733
781
  } catch (err) {
734
782
  repairActions.push({ action: repair, success: false, error: err.message });
@@ -8,7 +8,7 @@ Plans execute autonomously. Checkpoints formalize interaction points where human
8
8
  2. **OpenCode sets up the verification environment** - Start dev servers, seed databases, configure env vars
9
9
  3. **User only does what requires human judgment** - Visual checks, UX evaluation, "does this feel right?"
10
10
  4. **Secrets come from user, automation comes from OpenCode** - Ask for API keys, then OpenCode uses them via CLI
11
- 5. **Auto-mode bypasses verification/decision checkpoints** — When `workflow.auto_advance` is true in config: human-verify auto-approves, decision auto-selects first option, human-action still stops (auth gates cannot be automated)
11
+ 5. **Auto-mode bypasses verification/decision checkpoints** — When `workflow._auto_chain_active` or `workflow.auto_advance` is true in config: human-verify auto-approves, decision auto-selects first option, human-action still stops (auth gates cannot be automated)
12
12
  </overview>
13
13
 
14
14
  <checkpoint_types>
@@ -6,7 +6,7 @@ Calculate the next decimal phase number for urgent insertions.
6
6
 
7
7
  ```bash
8
8
  # Get next decimal phase after phase 6
9
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs phase next-decimal 6
9
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" phase next-decimal 6
10
10
  ```
11
11
 
12
12
  Output:
@@ -32,14 +32,14 @@ With existing decimals:
32
32
  ## Extract Values
33
33
 
34
34
  ```bash
35
- DECIMAL_INFO=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs phase next-decimal "${AFTER_PHASE}")
36
- DECIMAL_PHASE=$(echo "$DECIMAL_INFO" | jq -r '.next')
37
- BASE_PHASE=$(echo "$DECIMAL_INFO" | jq -r '.base_phase')
35
+ DECIMAL_INFO=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" phase next-decimal "${AFTER_PHASE}")
36
+ DECIMAL_PHASE=$(printf '%s\n' "$DECIMAL_INFO" | jq -r '.next')
37
+ BASE_PHASE=$(printf '%s\n' "$DECIMAL_INFO" | jq -r '.base_phase')
38
38
  ```
39
39
 
40
40
  Or with --raw flag:
41
41
  ```bash
42
- DECIMAL_PHASE=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs phase next-decimal "${AFTER_PHASE}" --raw)
42
+ DECIMAL_PHASE=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" phase next-decimal "${AFTER_PHASE}" --raw)
43
43
  # Returns just: 06.1
44
44
  ```
45
45
 
@@ -57,7 +57,7 @@ DECIMAL_PHASE=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs phase ne
57
57
  Decimal phase directories use the full decimal number:
58
58
 
59
59
  ```bash
60
- SLUG=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs generate-slug "$DESCRIPTION" --raw)
60
+ SLUG=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" generate-slug "$DESCRIPTION" --raw)
61
61
  PHASE_DIR=".planning/phases/${DECIMAL_PHASE}-${SLUG}"
62
62
  mkdir -p "$PHASE_DIR"
63
63
  ```
@@ -51,7 +51,7 @@ Phases:
51
51
  What to commit:
52
52
 
53
53
  ```bash
54
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "docs: initialize [project-name] ([N] phases)" --files .planning/
54
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs: initialize [project-name] ([N] phases)" --files .planning/
55
55
  ```
56
56
 
57
57
  </format>
@@ -129,7 +129,7 @@ SUMMARY: .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md
129
129
  What to commit:
130
130
 
131
131
  ```bash
132
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "docs({phase}-{plan}): complete [plan-name] plan" --files .planning/phases/XX-name/{phase}-{plan}-PLAN.md .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md
132
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs({phase}-{plan}): complete [plan-name] plan" --files .planning/phases/XX-name/{phase}-{plan}-PLAN.md .planning/phases/XX-name/{phase}-{plan}-SUMMARY.md .planning/STATE.md .planning/ROADMAP.md
133
133
  ```
134
134
 
135
135
  **Note:** Code files NOT included - already committed per-task.
@@ -149,7 +149,7 @@ Current: [task name]
149
149
  What to commit:
150
150
 
151
151
  ```bash
152
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "wip: [phase-name] paused at task [X]/[Y]" --files .planning/
152
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "wip: [phase-name] paused at task [X]/[Y]" --files .planning/
153
153
  ```
154
154
 
155
155
  </format>
@@ -7,7 +7,7 @@ Commit planning artifacts using the gsd-tools CLI, which automatically checks `c
7
7
  Always use `gsd-tools.cjs commit` for `.planning/` files — it handles `commit_docs` and gitignore checks automatically:
8
8
 
9
9
  ```bash
10
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "docs({scope}): {description}" --files .planning/STATE.md .planning/ROADMAP.md
10
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs({scope}): {description}" --files .planning/STATE.md .planning/ROADMAP.md
11
11
  ```
12
12
 
13
13
  The CLI will return `skipped` (with reason) if `commit_docs` is `false` or `.planning/` is gitignored. No manual conditional checks needed.
@@ -17,7 +17,7 @@ The CLI will return `skipped` (with reason) if `commit_docs` is `false` or `.pla
17
17
  To fold `.planning/` file changes into the previous commit:
18
18
 
19
19
  ```bash
20
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "" --files .planning/codebase/*.md --amend
20
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "" --files .planning/codebase/*.md --amend
21
21
  ```
22
22
 
23
23
  ## Commit Message Patterns
@@ -12,7 +12,7 @@ Default: `simple` if not set or config missing.
12
12
 
13
13
  ## Lookup Table
14
14
 
15
- @~/.config/opencode/get-shit-done/references/model-profiles.md
15
+ @$HOME/.config/opencode/get-shit-done/references/model-profiles.md
16
16
 
17
17
  Look up the agent in the table for the resolved profile. Pass the model parameter to task calls:
18
18
 
@@ -17,6 +17,7 @@ Model profiles control which OpenCode model each GSD agent uses. This allows bal
17
17
  | gsd-verifier | sonnet | sonnet | haiku |
18
18
  | gsd-plan-checker | sonnet | sonnet | haiku |
19
19
  | gsd-integration-checker | sonnet | sonnet | haiku |
20
+ | gsd-nyquist-auditor | sonnet | sonnet | haiku |
20
21
 
21
22
  ## Profile Philosophy
22
23
 
@@ -14,7 +14,7 @@ From `$ARGUMENTS`:
14
14
  The `find-phase` command handles normalization and validation in one step:
15
15
 
16
16
  ```bash
17
- PHASE_INFO=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs find-phase "${PHASE}")
17
+ PHASE_INFO=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" find-phase "${PHASE}")
18
18
  ```
19
19
 
20
20
  Returns JSON with:
@@ -45,8 +45,8 @@ fi
45
45
  Use `roadmap get-phase` to validate phase exists:
46
46
 
47
47
  ```bash
48
- PHASE_CHECK=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs roadmap get-phase "${PHASE}")
49
- if [ "$(echo "$PHASE_CHECK" | jq -r '.found')" = "false" ]; then
48
+ PHASE_CHECK=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" roadmap get-phase "${PHASE}")
49
+ if [ "$(printf '%s\n' "$PHASE_CHECK" | jq -r '.found')" = "false" ]; then
50
50
  echo "ERROR: Phase ${PHASE} not found in roadmap"
51
51
  exit 1
52
52
  fi
@@ -57,5 +57,5 @@ fi
57
57
  Use `find-phase` for directory lookup:
58
58
 
59
59
  ```bash
60
- PHASE_DIR=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs find-phase "${PHASE}" --raw)
60
+ PHASE_DIR=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" find-phase "${PHASE}" --raw)
61
61
  ```
@@ -40,14 +40,16 @@ Configuration options for `.planning/` directory behavior.
40
40
 
41
41
  ```bash
42
42
  # Commit with automatic commit_docs + gitignore checks:
43
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "docs: update state" --files .planning/STATE.md
43
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs: update state" --files .planning/STATE.md
44
44
 
45
45
  # Load config via state load (returns JSON):
46
- INIT=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs state load)
46
+ INIT=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" state load)
47
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
47
48
  # commit_docs is available in the JSON output
48
49
 
49
50
  # Or use init commands which include commit_docs:
50
- INIT=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs init execute-phase "1")
51
+ INIT=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" init execute-phase "1")
52
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
51
53
  # commit_docs is included in all init command outputs
52
54
  ```
53
55
 
@@ -56,7 +58,7 @@ INIT=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs init execute-phas
56
58
  **Commit via CLI (handles checks automatically):**
57
59
 
58
60
  ```bash
59
- node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs commit "docs: update state" --files .planning/STATE.md
61
+ node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" commit "docs: update state" --files .planning/STATE.md
60
62
  ```
61
63
 
62
64
  The CLI checks `commit_docs` config and gitignore status internally — no manual conditionals needed.
@@ -144,13 +146,15 @@ To use uncommitted mode:
144
146
 
145
147
  Use `init execute-phase` which returns all config as JSON:
146
148
  ```bash
147
- INIT=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs init execute-phase "1")
149
+ INIT=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" init execute-phase "1")
150
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
148
151
  # JSON output includes: branching_strategy, phase_branch_template, milestone_branch_template
149
152
  ```
150
153
 
151
154
  Or use `state load` for the config values:
152
155
  ```bash
153
- INIT=$(node ~/.config/opencode/get-shit-done/bin/gsd-tools.cjs state load)
156
+ INIT=$(node "$HOME/.config/opencode/get-shit-done/bin/gsd-tools.cjs" state load)
157
+ if [[ "$INIT" == @file:* ]]; then INIT=$(cat "${INIT#@file:}"); fi
154
158
  # Parse branching_strategy, phase_branch_template, milestone_branch_template from JSON
155
159
  ```
156
160
 
@@ -100,6 +100,23 @@ Users who want a slightly modified version of an option can select "Other" and r
100
100
 
101
101
  </using_askuserquestion>
102
102
 
103
+ <freeform_rule>
104
+
105
+ **When the user wants to explain freely, STOP using question.**
106
+
107
+ If a user selects "Other" and their response signals they want to describe something in their own words (e.g., "let me describe it", "I'll explain", "something else", or any open-ended reply that isn't choosing/modifying an existing option), you MUST:
108
+
109
+ 1. **Ask your follow-up as plain text** — NOT via question
110
+ 2. **Wait for them to type at the normal prompt**
111
+ 3. **Resume question** only after processing their freeform response
112
+
113
+ The same applies if YOU include a freeform-indicating option (like "Let me explain" or "Describe in detail") and the user selects it.
114
+
115
+ **Wrong:** User says "let me describe it" → question("What feature?", ["Feature A", "Feature B", "Describe in detail"])
116
+ **Right:** User says "let me describe it" → "Go ahead — what are you thinking?"
117
+
118
+ </freeform_rule>
119
+
103
120
  <context_checklist>
104
121
 
105
122
  Use this as a **background checklist**, not a conversation structure. Check these mentally as you go. If gaps remain, weave questions naturally.
@@ -600,7 +600,7 @@ Some things can't be verified programmatically. Flag these for human testing:
600
600
 
601
601
  For automation-first checkpoint patterns, server lifecycle management, CLI installation handling, and error recovery protocols, see:
602
602
 
603
- **@~/.config/opencode/get-shit-done/references/checkpoints.md** → `<automation_reference>` section
603
+ **@$HOME/.config/opencode/get-shit-done/references/checkpoints.md** → `<automation_reference>` section
604
604
 
605
605
  Key principles:
606
606
  - OpenCode sets up verification environment BEFORE presenting checkpoints
@@ -8,7 +8,7 @@ Template for `.planning/debug/[slug].md` — active debug session tracking.
8
8
 
9
9
  ```markdown
10
10
  ---
11
- status: gathering | investigating | fixing | verifying | resolved
11
+ status: gathering | investigating | fixing | verifying | awaiting_human_verify | resolved
12
12
  trigger: "[verbatim user input]"
13
13
  created: [ISO timestamp]
14
14
  updated: [ISO timestamp]
@@ -127,9 +127,14 @@ files_changed: []
127
127
  - Update Resolution.verification with results
128
128
  - If verification fails: status → "investigating", try again
129
129
 
130
+ **After self-verification passes:**
131
+ - status -> "awaiting_human_verify"
132
+ - Request explicit user confirmation in a checkpoint
133
+ - Do NOT move file to resolved yet
134
+
130
135
  **On resolution:**
131
136
  - status → "resolved"
132
- - Move file to .planning/debug/resolved/
137
+ - Move file to .planning/debug/resolved/ (only after user confirms fix)
133
138
 
134
139
  </lifecycle>
135
140
 
@@ -9,9 +9,7 @@ created: {date}
9
9
 
10
10
  # Phase {N} — Validation Strategy
11
11
 
12
- > Generated by `gsd-phase-researcher` during `/gsd-plan-phase {N}`.
13
- > Updated by `gsd-plan-checker` after plan approval.
14
- > Governs feedback sampling during `/gsd-execute-phase {N}`.
12
+ > Per-phase validation contract for feedback sampling during execution.
15
13
 
16
14
  ---
17
15
 
@@ -20,22 +18,19 @@ created: {date}
20
18
  | Property | Value |
21
19
  |----------|-------|
22
20
  | **Framework** | {pytest 7.x / jest 29.x / vitest / go test / other} |
23
- | **Config file** | {path/to/pytest.ini or "none — Wave 0 installs"} |
24
- | **Quick run command** | `{e.g., pytest -x --tb=short}` |
25
- | **Full suite command** | `{e.g., pytest tests/ --tb=short}` |
21
+ | **Config file** | {path or "none — Wave 0 installs"} |
22
+ | **Quick run command** | `{quick command}` |
23
+ | **Full suite command** | `{full command}` |
26
24
  | **Estimated runtime** | ~{N} seconds |
27
- | **CI pipeline** | {.github/workflows/test.yml — exists / needs creation} |
28
25
 
29
26
  ---
30
27
 
31
- ## Nyquist Sampling Rate
32
-
33
- > The minimum feedback frequency required to reliably catch errors in this phase.
28
+ ## Sampling Rate
34
29
 
35
30
  - **After every task commit:** Run `{quick run command}`
36
31
  - **After every plan wave:** Run `{full suite command}`
37
32
  - **Before `/gsd-verify-work`:** Full suite must be green
38
- - **Maximum acceptable task feedback latency:** {N} seconds
33
+ - **Max feedback latency:** {N} seconds
39
34
 
40
35
  ---
41
36
 
@@ -43,62 +38,39 @@ created: {date}
43
38
 
44
39
  | task ID | Plan | Wave | Requirement | Test Type | Automated Command | File Exists | Status |
45
40
  |---------|------|------|-------------|-----------|-------------------|-------------|--------|
46
- | {N}-01-01 | 01 | 1 | REQ-{XX} | unit | `pytest tests/test_{module}.py::test_{name} -x` | ✅ / ❌ W0 | ⬜ pending |
47
- | {N}-01-02 | 01 | 1 | REQ-{XX} | integration | `pytest tests/test_{flow}.py -x` | ✅ / ❌ W0 | ⬜ pending |
48
- | {N}-02-01 | 02 | 2 | REQ-{XX} | smoke | `curl -s {endpoint} \| grep {expected}` | ✅ N/A | ⬜ pending |
41
+ | {N}-01-01 | 01 | 1 | REQ-{XX} | unit | `{command}` | ✅ / ❌ W0 | ⬜ pending |
49
42
 
50
- *Status values: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
43
+ *Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
51
44
 
52
45
  ---
53
46
 
54
47
  ## Wave 0 Requirements
55
48
 
56
- > Test scaffolding committed BEFORE any implementation task. Executor runs Wave 0 first.
57
-
58
- - [ ] `{tests/test_file.py}` — stubs for REQ-{XX}, REQ-{XX}
49
+ - [ ] `{tests/test_file.py}` stubs for REQ-{XX}
59
50
  - [ ] `{tests/conftest.py}` — shared fixtures
60
51
  - [ ] `{framework install}` — if no framework detected
61
52
 
62
- *If none required: "Existing infrastructure covers all phase requirements — no Wave 0 test tasks needed."*
53
+ *If none: "Existing infrastructure covers all phase requirements."*
63
54
 
64
55
  ---
65
56
 
66
57
  ## Manual-Only Verifications
67
58
 
68
- > Behaviors that genuinely cannot be automated, with justification.
69
- > These are surfaced during `/gsd-verify-work` UAT.
70
-
71
59
  | Behavior | Requirement | Why Manual | Test Instructions |
72
60
  |----------|-------------|------------|-------------------|
73
- | {behavior} | REQ-{XX} | {reason: visual, third-party auth, physical device...} | {step-by-step} |
61
+ | {behavior} | REQ-{XX} | {reason} | {steps} |
74
62
 
75
- *If none: "All phase behaviors have automated verification coverage."*
63
+ *If none: "All phase behaviors have automated verification."*
76
64
 
77
65
  ---
78
66
 
79
67
  ## Validation Sign-Off
80
68
 
81
- Updated by `gsd-plan-checker` when plans are approved:
82
-
83
- - [ ] All tasks have `<automated>` verify commands or Wave 0 dependencies
84
- - [ ] No 3 consecutive implementation tasks without automated verify (sampling continuity)
85
- - [ ] Wave 0 test files cover all MISSING references
86
- - [ ] No watch-mode flags in any automated command
87
- - [ ] Feedback latency per task: < {N}s ✅
69
+ - [ ] All tasks have `<automated>` verify or Wave 0 dependencies
70
+ - [ ] Sampling continuity: no 3 consecutive tasks without automated verify
71
+ - [ ] Wave 0 covers all MISSING references
72
+ - [ ] No watch-mode flags
73
+ - [ ] Feedback latency < {N}s
88
74
  - [ ] `nyquist_compliant: true` set in frontmatter
89
75
 
90
- **Plan-checker approval:** {pending / approved on YYYY-MM-DD}
91
-
92
- ---
93
-
94
- ## Execution Tracking
95
-
96
- Updated during `/gsd-execute-phase {N}`:
97
-
98
- | Wave | Tasks | Tests Run | Pass | Fail | Sampling Status |
99
- |------|-------|-----------|------|------|-----------------|
100
- | 0 | {N} | — | — | — | scaffold |
101
- | 1 | {N} | {command} | {N} | {N} | ✅ sampled |
102
- | 2 | {N} | {command} | {N} | {N} | ✅ sampled |
103
-
104
- **Phase validation complete:** {pending / YYYY-MM-DD HH:MM}
76
+ **Approval:** {pending / approved YYYY-MM-DD}
@@ -216,7 +216,7 @@ get-shit-done/
216
216
 
217
217
  **New Workflow:**
218
218
  - Implementation: `get-shit-done/workflows/{name}.md`
219
- - Usage: Reference from command with `@~/.config/opencode/get-shit-done/workflows/{name}.md`
219
+ - Usage: Reference from command with `@$HOME/.config/opencode/get-shit-done/workflows/{name}.md`
220
220
 
221
221
  **New Reference Document:**
222
222
  - Implementation: `get-shit-done/references/{name}.md`
@@ -229,12 +229,12 @@ get-shit-done/
229
229
  ## Special Directories
230
230
 
231
231
  **get-shit-done/**
232
- - Purpose: Resources installed to ~/.config/opencode/
232
+ - Purpose: Resources installed to $HOME/.config/opencode/
233
233
  - Source: Copied by bin/install.js during installation
234
234
  - Committed: Yes (source of truth)
235
235
 
236
236
  **commands/**
237
- - Purpose: Slash commands installed to ~/.config/opencode/commands/
237
+ - Purpose: Slash commands installed to $HOME/.config/opencode/commands/
238
238
  - Source: Copied by bin/install.js during installation
239
239
  - Committed: Yes (source of truth)
240
240
 
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "mode": "interactive",
3
- "depth": "standard",
3
+ "granularity": "standard",
4
4
  "workflow": {
5
5
  "research": true,
6
6
  "plan_check": true,
7
7
  "verifier": true,
8
8
  "auto_advance": false,
9
- "nyquist_validation": false
9
+ "nyquist_validation": true
10
10
  },
11
11
  "planning": {
12
12
  "commit_docs": true,
@@ -54,6 +54,20 @@ Template for `.planning/phases/XX-name/{phase_num}-CONTEXT.md` - captures implem
54
54
 
55
55
  </specifics>
56
56
 
57
+ <code_context>
58
+ ## Existing Code Insights
59
+
60
+ ### Reusable Assets
61
+ - [Component/hook/utility]: [How it could be used in this phase]
62
+
63
+ ### Established Patterns
64
+ - [Pattern]: [How it constrains/enables this phase]
65
+
66
+ ### Integration Points
67
+ - [Where new code connects to existing system]
68
+
69
+ </code_context>
70
+
57
71
  <deferred>
58
72
  ## Deferred Ideas
59
73
 
@@ -38,10 +38,10 @@ Output: [What artifacts will be created]
38
38
  </objective>
39
39
 
40
40
  <execution_context>
41
- @~/.config/opencode/get-shit-done/workflows/execute-plan.md
42
- @~/.config/opencode/get-shit-done/templates/summary.md
41
+ @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md
42
+ @$HOME/.config/opencode/get-shit-done/templates/summary.md
43
43
  [If plan contains checkpoint tasks (type="checkpoint:*"), add:]
44
- @~/.config/opencode/get-shit-done/references/checkpoints.md
44
+ @$HOME/.config/opencode/get-shit-done/references/checkpoints.md
45
45
  </execution_context>
46
46
 
47
47
  <context>
@@ -76,7 +76,7 @@ Output: [What artifacts will be created]
76
76
  <done>[Acceptance criteria]</done>
77
77
  </task>
78
78
 
79
- <!-- For checkpoint task examples and patterns, see @~/.config/opencode/get-shit-done/references/checkpoints.md -->
79
+ <!-- For checkpoint task examples and patterns, see @$HOME/.config/opencode/get-shit-done/references/checkpoints.md -->
80
80
  <!-- Key rule: OpenCode starts dev server BEFORE human-verify checkpoints. User only visits URLs. -->
81
81
 
82
82
  <task type="checkpoint:decision" gate="blocking">
@@ -270,7 +270,7 @@ TDD features get dedicated plans with `type: tdd`.
270
270
  → Yes: Create a TDD plan
271
271
  → No: Standard task in standard plan
272
272
 
273
- See `~/.config/opencode/get-shit-done/references/tdd.md` for TDD plan structure.
273
+ See `$HOME/.config/opencode/get-shit-done/references/tdd.md` for TDD plan structure.
274
274
 
275
275
  ---
276
276
 
@@ -374,9 +374,9 @@ Output: Working dashboard component.
374
374
  </objective>
375
375
 
376
376
  <execution_context>
377
- @~/.config/opencode/get-shit-done/workflows/execute-plan.md
378
- @~/.config/opencode/get-shit-done/templates/summary.md
379
- @~/.config/opencode/get-shit-done/references/checkpoints.md
377
+ @$HOME/.config/opencode/get-shit-done/workflows/execute-plan.md
378
+ @$HOME/.config/opencode/get-shit-done/templates/summary.md
379
+ @$HOME/.config/opencode/get-shit-done/references/checkpoints.md
380
380
  </execution_context>
381
381
 
382
382
  <context>
@@ -499,7 +499,7 @@ user_setup:
499
499
 
500
500
  **Result:** Execute-plan generates `{phase}-USER-SETUP.md` with checklist for the user.
501
501
 
502
- See `~/.config/opencode/get-shit-done/templates/user-setup.md` for full schema and examples
502
+ See `$HOME/.config/opencode/get-shit-done/templates/user-setup.md` for full schema and examples
503
503
 
504
504
  ---
505
505
 
@@ -566,4 +566,4 @@ task completion ≠ Goal achievement. A task "create chat component" can complet
566
566
  5. Gaps found → fix plans created → execute → re-verify
567
567
  6. All must_haves pass → phase complete
568
568
 
569
- See `~/.config/opencode/get-shit-done/workflows/verify-phase.md` for verification logic.
569
+ See `$HOME/.config/opencode/get-shit-done/workflows/verify-phase.md` for verification logic.