@opengsd/gsd-core 1.9.1 → 1.11.0

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 (426) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +2 -3
  3. package/.opencode/plugins/gsd-core.js +8 -1
  4. package/agents/gsd-code-fixer.md +27 -3
  5. package/agents/gsd-debug-session-manager.md +11 -0
  6. package/agents/gsd-debugger.md +12 -246
  7. package/agents/gsd-doc-synthesizer.md +2 -4
  8. package/agents/gsd-executor.md +12 -10
  9. package/agents/gsd-integration-checker.md +3 -0
  10. package/agents/gsd-mempalace-curator.md +5 -2
  11. package/agents/gsd-phase-researcher.md +20 -1
  12. package/agents/gsd-plan-checker.md +46 -0
  13. package/agents/gsd-planner.md +49 -54
  14. package/agents/gsd-roadmapper.md +21 -3
  15. package/agents/gsd-user-profiler.md +3 -0
  16. package/agents/gsd-verifier.md +26 -73
  17. package/bin/install.js +1272 -1238
  18. package/bin/lib/ui-safety-gate.cjs +2 -0
  19. package/commands/gsd/code-review.md +1 -1
  20. package/commands/gsd/execute-phase.md +1 -1
  21. package/commands/gsd/map-codebase.md +1 -1
  22. package/commands/gsd/mempalace-capture.md +2 -2
  23. package/commands/gsd/mempalace-recall.md +1 -1
  24. package/commands/gsd/new-milestone.md +2 -2
  25. package/commands/gsd/plan-phase.md +1 -1
  26. package/commands/gsd/quick.md +1 -1
  27. package/commands/gsd/review-backlog.md +2 -1
  28. package/commands/gsd/verify-work.md +1 -1
  29. package/gsd-core/bin/gsd-tools.cjs +1009 -115
  30. package/gsd-core/bin/lib/active-workstream-store.cjs +153 -12
  31. package/gsd-core/bin/lib/agent-install-check.cjs +268 -38
  32. package/gsd-core/bin/lib/api-coverage.cjs +123 -5
  33. package/gsd-core/bin/lib/artifacts.cjs +3 -0
  34. package/gsd-core/bin/lib/assumption-delta.cjs +2 -4
  35. package/gsd-core/bin/lib/audit-command-router.cjs +9 -2
  36. package/gsd-core/bin/lib/audit.cjs +926 -202
  37. package/gsd-core/bin/lib/broken-windows.cjs +36 -6
  38. package/gsd-core/bin/lib/capability-consent.cjs +149 -15
  39. package/gsd-core/bin/lib/capability-lifecycle.cjs +45 -0
  40. package/gsd-core/bin/lib/capability-registry.cjs +608 -148
  41. package/gsd-core/bin/lib/capability-source.cjs +92 -0
  42. package/gsd-core/bin/lib/capability-trust.cjs +444 -25
  43. package/gsd-core/bin/lib/capability-validator.cjs +507 -24
  44. package/gsd-core/bin/lib/capability-writer.cjs +3 -2
  45. package/gsd-core/bin/lib/check-command-router.cjs +114 -38
  46. package/gsd-core/bin/lib/claude-orchestration.cjs +56 -3
  47. package/gsd-core/bin/lib/codex-agent-toml.cjs +329 -0
  48. package/gsd-core/bin/lib/command-aliases.cjs +94 -0
  49. package/gsd-core/bin/lib/command-roster.cjs +44 -1
  50. package/gsd-core/bin/lib/commands.cjs +665 -99
  51. package/gsd-core/bin/lib/commonjs-marker.cjs +142 -0
  52. package/gsd-core/bin/lib/complexity-trigger.cjs +1172 -0
  53. package/gsd-core/bin/lib/config-loader.cjs +76 -0
  54. package/gsd-core/bin/lib/config.cjs +22 -2
  55. package/gsd-core/bin/lib/context-composer.cjs +278 -0
  56. package/gsd-core/bin/lib/context-predicates.cjs +506 -0
  57. package/gsd-core/bin/lib/core-utils.cjs +217 -40
  58. package/gsd-core/bin/lib/decisions.cjs +23 -0
  59. package/gsd-core/bin/lib/docs.cjs +3 -2
  60. package/gsd-core/bin/lib/external-job.cjs +19 -4
  61. package/gsd-core/bin/lib/fallow-runner.cjs +20 -44
  62. package/gsd-core/bin/lib/frontmatter.cjs +239 -32
  63. package/gsd-core/bin/lib/gap-checker.cjs +68 -7
  64. package/gsd-core/bin/lib/gate-predicate-evaluator.cjs +57 -6
  65. package/gsd-core/bin/lib/git-base-branch.cjs +160 -15
  66. package/gsd-core/bin/lib/graphify.cjs +142 -27
  67. package/gsd-core/bin/lib/gsd2-import.cjs +37 -5
  68. package/gsd-core/bin/lib/health-diagnostic-rules/agent-install.cjs +101 -0
  69. package/gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs +348 -0
  70. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +145 -0
  71. package/gsd-core/bin/lib/health-diagnostic-rules/install-surface-shadowing.cjs +98 -0
  72. package/gsd-core/bin/lib/health-diagnostic-rules/milestone-archive-hygiene.cjs +100 -0
  73. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +222 -0
  74. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +265 -0
  75. package/gsd-core/bin/lib/health-diagnostic-rules/root-existence.cjs +161 -0
  76. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +303 -0
  77. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +173 -0
  78. package/gsd-core/bin/lib/health-diagnostic-types.cjs +68 -0
  79. package/gsd-core/bin/lib/health-diagnostic.cjs +431 -0
  80. package/gsd-core/bin/lib/host-integration.cjs +13 -1
  81. package/gsd-core/bin/lib/host-runtime-detection.cjs +134 -0
  82. package/gsd-core/bin/lib/init-command-router.cjs +83 -8
  83. package/gsd-core/bin/lib/init.cjs +1325 -169
  84. package/gsd-core/bin/lib/install-effort-resolver.cjs +73 -30
  85. package/gsd-core/bin/lib/install-engine.cjs +805 -264
  86. package/gsd-core/bin/lib/install-fs-adapter.cjs +262 -0
  87. package/gsd-core/bin/lib/install-model-override-resolver.cjs +203 -0
  88. package/gsd-core/bin/lib/install-profiles.cjs +160 -57
  89. package/gsd-core/bin/lib/install-scope.cjs +270 -0
  90. package/gsd-core/bin/lib/install-shadow-report.cjs +385 -0
  91. package/gsd-core/bin/lib/installed-surface-resolver.cjs +381 -0
  92. package/gsd-core/bin/lib/installer-migration-authoring.cjs +3 -1
  93. package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
  94. package/gsd-core/bin/lib/installer-migrations/007-retire-config-root-commonjs-marker.cjs +149 -0
  95. package/gsd-core/bin/lib/installer-migrations/008-cursor-retire-commands-surface.cjs +55 -0
  96. package/gsd-core/bin/lib/installer-migrations/009-pi-retire-reserved-hooks-dir.cjs +199 -0
  97. package/gsd-core/bin/lib/installer-migrations.cjs +206 -13
  98. package/gsd-core/bin/lib/io.cjs +38 -3
  99. package/gsd-core/bin/lib/markdown-sectionizer.cjs +8 -1
  100. package/gsd-core/bin/lib/markdown-table.cjs +133 -20
  101. package/gsd-core/bin/lib/mcp-catalog.cjs +518 -0
  102. package/gsd-core/bin/lib/mcp-server.cjs +135 -3
  103. package/gsd-core/bin/lib/milestone-lock.cjs +248 -0
  104. package/gsd-core/bin/lib/milestone.cjs +821 -109
  105. package/gsd-core/bin/lib/model-catalog.cjs +59 -1
  106. package/gsd-core/bin/lib/model-resolver.cjs +183 -40
  107. package/gsd-core/bin/lib/normalize-test-command.cjs +1 -1
  108. package/gsd-core/bin/lib/pattern.cjs +122 -0
  109. package/gsd-core/bin/lib/phase-estimation.cjs +1 -1
  110. package/gsd-core/bin/lib/phase-id.cjs +507 -36
  111. package/gsd-core/bin/lib/phase-lifecycle.cjs +28 -3
  112. package/gsd-core/bin/lib/phase-locator.cjs +258 -58
  113. package/gsd-core/bin/lib/phase.cjs +891 -156
  114. package/gsd-core/bin/lib/plan-dependency-graph.cjs +303 -0
  115. package/gsd-core/bin/lib/plan-drift-guard.cjs +120 -0
  116. package/gsd-core/bin/lib/plan-scan.cjs +86 -2
  117. package/gsd-core/bin/lib/planning-scope.cjs +31 -0
  118. package/gsd-core/bin/lib/planning-snapshot.cjs +890 -0
  119. package/gsd-core/bin/lib/planning-workspace.cjs +60 -6
  120. package/gsd-core/bin/lib/probe-core.cjs +1 -1
  121. package/gsd-core/bin/lib/profile-output.cjs +1 -1
  122. package/gsd-core/bin/lib/prompt-budget.cjs +128 -165
  123. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +740 -0
  124. package/gsd-core/bin/lib/retired-artifact-cleanup.cjs +85 -0
  125. package/gsd-core/bin/lib/review-lane-descriptor.cjs +108 -0
  126. package/gsd-core/bin/lib/review-lane-invocation.cjs +30 -0
  127. package/gsd-core/bin/lib/review-lane-runner.cjs +447 -68
  128. package/gsd-core/bin/lib/review-reviewer-selection.cjs +13 -18
  129. package/gsd-core/bin/lib/roadmap-command-router.cjs +76 -9
  130. package/gsd-core/bin/lib/roadmap-parser.cjs +1035 -194
  131. package/gsd-core/bin/lib/roadmap-upgrade.cjs +37 -10
  132. package/gsd-core/bin/lib/roadmap.cjs +405 -84
  133. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +795 -100
  134. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +14 -2
  135. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +440 -57
  136. package/gsd-core/bin/lib/runtime-config-adapter-registry.cjs +3 -2
  137. package/gsd-core/bin/lib/runtime-homes.cjs +220 -41
  138. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +220 -44
  139. package/gsd-core/bin/lib/runtime-name-policy.cjs +3 -1
  140. package/gsd-core/bin/lib/runtime-slash.cjs +27 -9
  141. package/gsd-core/bin/lib/section-manifest.cjs +209 -0
  142. package/gsd-core/bin/lib/security.cjs +104 -5
  143. package/gsd-core/bin/lib/shell-command-projection.cjs +388 -30
  144. package/gsd-core/bin/lib/smart-entry.cjs +154 -22
  145. package/gsd-core/bin/lib/state-command-router.cjs +5 -1
  146. package/gsd-core/bin/lib/state-document.cjs +152 -8
  147. package/gsd-core/bin/lib/state-transition.cjs +424 -105
  148. package/gsd-core/bin/lib/state.cjs +1927 -401
  149. package/gsd-core/bin/lib/surface.cjs +35 -10
  150. package/gsd-core/bin/lib/text-lines.cjs +80 -0
  151. package/gsd-core/bin/lib/token-scanner.cjs +76 -0
  152. package/gsd-core/bin/lib/uat-predicate.cjs +20 -4
  153. package/gsd-core/bin/lib/uat.cjs +706 -64
  154. package/gsd-core/bin/lib/ui-frontend-evidence.cjs +157 -0
  155. package/gsd-core/bin/lib/ui-safety-gate.cjs +14 -5
  156. package/gsd-core/bin/lib/unusable-input.cjs +33 -0
  157. package/gsd-core/bin/lib/update-context.cjs +8 -2
  158. package/gsd-core/bin/lib/user-artifact-staging.cjs +705 -0
  159. package/gsd-core/bin/lib/validate.cjs +20 -6
  160. package/gsd-core/bin/lib/vendor/README.md +37 -0
  161. package/gsd-core/bin/lib/vendor/re2js.cjs +6480 -0
  162. package/gsd-core/bin/lib/vendor/re2js.d.cts +938 -0
  163. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  164. package/gsd-core/bin/lib/verification.cjs +287 -20
  165. package/gsd-core/bin/lib/verify.cjs +368 -880
  166. package/gsd-core/bin/lib/workflow-fragments.cjs +557 -0
  167. package/gsd-core/bin/lib/workstream-inventory-builder.cjs +203 -19
  168. package/gsd-core/bin/lib/workstream-inventory.cjs +576 -31
  169. package/gsd-core/bin/lib/workstream.cjs +8 -2
  170. package/gsd-core/bin/lib/worktree-base-ref.cjs +50 -6
  171. package/gsd-core/bin/lib/worktree-safety.cjs +450 -125
  172. package/gsd-core/bin/shared/config-defaults.manifest.json +1 -0
  173. package/gsd-core/bin/shared/config-schema.manifest.json +9 -1
  174. package/gsd-core/references/agent-contracts.md +43 -26
  175. package/gsd-core/references/artifact-types.md +10 -3
  176. package/gsd-core/references/autonomous-ui-design-contract.md +42 -0
  177. package/gsd-core/references/checkpoints.md +2 -2
  178. package/gsd-core/references/context-budget.md +1 -1
  179. package/gsd-core/references/debugger-techniques.md +255 -0
  180. package/gsd-core/references/dispatch-isolation-gate.md +138 -0
  181. package/gsd-core/references/doc-conflict-engine.md +1 -1
  182. package/gsd-core/references/execute-mvp-tdd.md +3 -3
  183. package/gsd-core/references/execute-phase-between-wave-reset.md +6 -2
  184. package/gsd-core/references/execute-phase-context-guard.md +1 -1
  185. package/gsd-core/references/execute-phase-response-language.md +1 -1
  186. package/gsd-core/references/execute-phase-wave-guard.md +6 -2
  187. package/gsd-core/references/gate-prompts.md +1 -1
  188. package/gsd-core/references/git-planning-commit.md +2 -1
  189. package/gsd-core/references/loop-hook-dispatch.md +39 -2
  190. package/gsd-core/references/model-profiles.md +12 -4
  191. package/gsd-core/references/mvp-concepts.md +9 -9
  192. package/gsd-core/references/planner-guidance.md +3 -9
  193. package/gsd-core/references/planner-preconditions.md +1 -1
  194. package/gsd-core/references/planner-reviews.md +1 -1
  195. package/gsd-core/references/planning-config.md +8 -6
  196. package/gsd-core/references/research-documentation-lookup.md +5 -3
  197. package/gsd-core/references/revision-loop.md +1 -1
  198. package/gsd-core/references/specless-probe-fallback.md +8 -7
  199. package/gsd-core/references/universal-anti-patterns.md +3 -3
  200. package/gsd-core/references/verifier-phase-gates.md +192 -0
  201. package/gsd-core/references/verifier-wiring-patterns.md +100 -0
  202. package/gsd-core/references/verify-mvp-mode.md +1 -1
  203. package/gsd-core/references/workstream-flag.md +22 -6
  204. package/gsd-core/references/worktree-branch-check.md +2 -2
  205. package/gsd-core/templates/discussion-log.md +1 -1
  206. package/gsd-core/templates/phase-prompt.md +2 -4
  207. package/gsd-core/templates/state.md +4 -4
  208. package/gsd-core/templates/summary-complex.md +2 -0
  209. package/gsd-core/templates/summary-minimal.md +2 -0
  210. package/gsd-core/templates/summary-standard.md +2 -0
  211. package/gsd-core/templates/summary.md +2 -0
  212. package/gsd-core/templates/verification-report.md +9 -1
  213. package/gsd-core/workflows/ai-integration-phase.md +9 -11
  214. package/gsd-core/workflows/audit-milestone.md +3 -0
  215. package/gsd-core/workflows/autonomous/steps/converge-banner.md +1 -0
  216. package/gsd-core/workflows/autonomous/steps/converge-dispatch-bg.md +11 -0
  217. package/gsd-core/workflows/autonomous/steps/converge-dispatch-inline.md +7 -0
  218. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +21 -0
  219. package/gsd-core/workflows/autonomous/steps/converge-loop.md +7 -0
  220. package/gsd-core/workflows/autonomous.md +33 -70
  221. package/gsd-core/workflows/cleanup.md +62 -3
  222. package/gsd-core/workflows/code-review/steps/dispatch-fix.md +39 -0
  223. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +93 -0
  224. package/gsd-core/workflows/code-review-fix.md +37 -10
  225. package/gsd-core/workflows/code-review.md +74 -166
  226. package/gsd-core/workflows/complete-milestone/steps/git-tag.md +29 -0
  227. package/gsd-core/workflows/complete-milestone.md +160 -95
  228. package/gsd-core/workflows/debug.md +16 -17
  229. package/gsd-core/workflows/diagnose-issues.md +56 -8
  230. package/gsd-core/workflows/discuss-phase/modes/chain.md +2 -1
  231. package/gsd-core/workflows/discuss-phase/modes/default.md +1 -1
  232. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +15 -0
  233. package/gsd-core/workflows/discuss-phase-assumptions.md +7 -17
  234. package/gsd-core/workflows/docs-update/steps/dispatch-monorepo-packages.md +51 -0
  235. package/gsd-core/workflows/docs-update.md +8 -51
  236. package/gsd-core/workflows/edit-phase.md +26 -1
  237. package/gsd-core/workflows/eval-review.md +3 -5
  238. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +64 -7
  239. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +50 -0
  240. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +31 -0
  241. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +77 -0
  242. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +21 -0
  243. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +42 -0
  244. package/gsd-core/workflows/execute-phase/steps/regression-gate.md +43 -37
  245. package/gsd-core/workflows/execute-phase.md +103 -187
  246. package/gsd-core/workflows/execute-plan.md +36 -4
  247. package/gsd-core/workflows/explore.md +131 -4
  248. package/gsd-core/workflows/fast.md +10 -2
  249. package/gsd-core/workflows/health.md +73 -4
  250. package/gsd-core/workflows/help/modes/full.md +6 -1
  251. package/gsd-core/workflows/import.md +4 -4
  252. package/gsd-core/workflows/ingest-docs.md +7 -6
  253. package/gsd-core/workflows/mvp-phase.md +6 -3
  254. package/gsd-core/workflows/new-milestone/steps/project-md-milestone-write.md +16 -0
  255. package/gsd-core/workflows/new-milestone/steps/reset-phase-safety.md +19 -0
  256. package/gsd-core/workflows/new-milestone.md +35 -47
  257. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +176 -0
  258. package/gsd-core/workflows/new-project/steps/auto-mode-detection.md +32 -0
  259. package/gsd-core/workflows/new-project/steps/codebase-map-offer.md +18 -0
  260. package/gsd-core/workflows/new-project.md +27 -240
  261. package/gsd-core/workflows/next.md +12 -0
  262. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +15 -0
  263. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +110 -0
  264. package/gsd-core/workflows/plan-phase/steps/prd-express-gate.md +8 -0
  265. package/gsd-core/workflows/plan-phase/steps/research-only-early-exit.md +17 -0
  266. package/gsd-core/workflows/plan-phase/steps/research-only-modifiers.md +16 -0
  267. package/gsd-core/workflows/plan-phase/steps/reviews-prerequisite.md +17 -0
  268. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +149 -0
  269. package/gsd-core/workflows/plan-phase.md +89 -209
  270. package/gsd-core/workflows/plan-review-convergence.md +50 -2
  271. package/gsd-core/workflows/progress/steps/forensic-audit.md +125 -0
  272. package/gsd-core/workflows/progress/steps/mvp-display.md +18 -0
  273. package/gsd-core/workflows/progress.md +45 -159
  274. package/gsd-core/workflows/quick/steps/discussion-phase.md +124 -0
  275. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +111 -0
  276. package/gsd-core/workflows/quick/steps/quick-verification.md +67 -0
  277. package/gsd-core/workflows/quick/steps/research-phase.md +72 -0
  278. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +37 -0
  279. package/gsd-core/workflows/quick.md +55 -405
  280. package/gsd-core/workflows/resume-project.md +3 -0
  281. package/gsd-core/workflows/review/steps/reviewer-instances-note-1.md +4 -0
  282. package/gsd-core/workflows/review/steps/reviewer-instances-note-2.md +3 -0
  283. package/gsd-core/workflows/review.md +41 -13
  284. package/gsd-core/workflows/section-manifest.json +219 -0
  285. package/gsd-core/workflows/secure-phase.md +1 -1
  286. package/gsd-core/workflows/session-report.md +2 -1
  287. package/gsd-core/workflows/settings.md +66 -2
  288. package/gsd-core/workflows/ship.md +104 -44
  289. package/gsd-core/workflows/sketch.md +1 -1
  290. package/gsd-core/workflows/spec-phase.md +41 -20
  291. package/gsd-core/workflows/spike-wrap-up.md +20 -5
  292. package/gsd-core/workflows/spike.md +50 -16
  293. package/gsd-core/workflows/sync-skills.md +106 -13
  294. package/gsd-core/workflows/transition/steps/workstream-collision-check.md +17 -0
  295. package/gsd-core/workflows/transition.md +53 -31
  296. package/gsd-core/workflows/ui-phase.md +13 -12
  297. package/gsd-core/workflows/ui-review.md +2 -2
  298. package/gsd-core/workflows/update/steps/channel-banner.md +7 -0
  299. package/gsd-core/workflows/update.md +19 -8
  300. package/gsd-core/workflows/validate-phase.md +1 -1
  301. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +36 -0
  302. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +21 -0
  303. package/gsd-core/workflows/verify-work.md +17 -65
  304. package/hooks/dist/gsd-agent-isolation-guard.js +517 -0
  305. package/hooks/dist/gsd-check-update-worker.js +64 -12
  306. package/hooks/dist/gsd-check-update.js +19 -1
  307. package/hooks/dist/gsd-cursor-pre-tool.js +0 -3
  308. package/hooks/dist/gsd-cursor-subagent-start.js +607 -26
  309. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -2
  310. package/hooks/dist/gsd-prompt-guard.js +21 -20
  311. package/hooks/dist/gsd-read-injection-scanner.js +45 -24
  312. package/hooks/dist/gsd-statusline.js +90 -6
  313. package/hooks/dist/gsd-update-banner.js +22 -1
  314. package/hooks/dist/gsd-workflow-guard.js +134 -36
  315. package/hooks/dist/gsd-worktree-path-guard.js +2 -1
  316. package/hooks/dist/gsd-write-guard.js +359 -0
  317. package/hooks/dist/lib/git-cmd.js +92 -59
  318. package/hooks/dist/lib/injection-patterns.js +45 -0
  319. package/hooks/dist/lib/isolation-deny-reason.js +39 -0
  320. package/hooks/dist/lib/isolation-sentinel.js +277 -0
  321. package/hooks/dist/managed-hooks-registry.cjs +2 -0
  322. package/hooks/gsd-agent-isolation-guard.js +517 -0
  323. package/hooks/gsd-check-update-worker.js +64 -12
  324. package/hooks/gsd-check-update.js +19 -1
  325. package/hooks/gsd-cursor-pre-tool.js +0 -3
  326. package/hooks/gsd-cursor-subagent-start.js +607 -26
  327. package/hooks/gsd-cursor-subagent-stop.js +3 -2
  328. package/hooks/gsd-prompt-guard.js +21 -20
  329. package/hooks/gsd-read-injection-scanner.js +45 -24
  330. package/hooks/gsd-statusline.js +90 -6
  331. package/hooks/gsd-update-banner.js +22 -1
  332. package/hooks/gsd-workflow-guard.js +134 -36
  333. package/hooks/gsd-worktree-path-guard.js +2 -1
  334. package/hooks/gsd-write-guard.js +359 -0
  335. package/hooks/hooks.json +12 -0
  336. package/hooks/lib/git-cmd.js +92 -59
  337. package/hooks/lib/injection-patterns.js +45 -0
  338. package/hooks/lib/isolation-deny-reason.js +39 -0
  339. package/hooks/lib/isolation-sentinel.js +277 -0
  340. package/hooks/managed-hooks-registry.cjs +2 -0
  341. package/package.json +31 -10
  342. package/pi/gsd.cjs +71 -12
  343. package/scripts/baselines/planning-prompt-drift-baseline.json +4 -0
  344. package/scripts/baselines/planning-snapshot-bypass-baseline.json +12 -0
  345. package/scripts/baselines/unreachable-guard-drift-baseline.json +4 -0
  346. package/scripts/build-hooks.js +9 -0
  347. package/scripts/changeset/lint.cjs +68 -6
  348. package/scripts/changeset/serialize.cjs +5 -1
  349. package/scripts/check-alias-drift.cjs +7 -43
  350. package/scripts/check-contract-drift.cjs +297 -0
  351. package/scripts/ci-test-scope.cjs +19 -2
  352. package/scripts/command-contract-helpers.cjs +903 -1
  353. package/scripts/gen-adr-index.cjs +728 -38
  354. package/scripts/gen-capability-matrix.cjs +1 -1
  355. package/scripts/gen-capability-registry.cjs +3 -15
  356. package/scripts/gen-context-index.cjs +439 -0
  357. package/scripts/gen-health-docs.cjs +390 -0
  358. package/scripts/gen-inventory-manifest.cjs +150 -4
  359. package/scripts/gen-loop-host-contract.cjs +4 -24
  360. package/scripts/gen-prompt-budget-parity-corpus.cjs +645 -0
  361. package/scripts/gen-registry.cjs +3 -14
  362. package/scripts/gen-section-manifest.cjs +638 -0
  363. package/scripts/generate-package-identity.cjs +4 -2
  364. package/scripts/lib/alias-drift-families.cjs +46 -0
  365. package/scripts/lib/drift-scan.cjs +278 -0
  366. package/scripts/lint-allow-test-rule-refs.allowlist.json +15 -54
  367. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +4 -0
  368. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +3 -0
  369. package/scripts/lint-canary-version-leak.cjs +73 -0
  370. package/scripts/lint-command-contract.cjs +96 -13
  371. package/scripts/lint-compiled-artifact-sync.cjs +6 -1
  372. package/scripts/lint-completion-predicate-drift.cjs +933 -0
  373. package/scripts/lint-completion-ratio-drift.cjs +214 -0
  374. package/scripts/lint-default-flip-documentation.cjs +193 -0
  375. package/scripts/lint-docs-command-form.cjs +195 -0
  376. package/scripts/lint-docs-required.cjs +9 -1
  377. package/scripts/lint-emitted-drift-ack.cjs +215 -20
  378. package/scripts/lint-eslint-glob-coverage.allowlist.json +34 -0
  379. package/scripts/lint-eslint-glob-coverage.cjs +340 -0
  380. package/scripts/lint-example-parser-parity.cjs +395 -0
  381. package/scripts/lint-frontmatter-scalar-broad-grep.cjs +237 -0
  382. package/scripts/lint-health-diagnostic-rule-table.cjs +404 -0
  383. package/scripts/lint-hooks-runtime-build-seam.cjs +262 -0
  384. package/scripts/lint-milestone-window-drift.cjs +468 -0
  385. package/scripts/lint-phase-enumeration-drift.cjs +479 -0
  386. package/scripts/lint-plan-count-drift.cjs +318 -0
  387. package/scripts/lint-planning-artifact-writer-drift.cjs +398 -0
  388. package/scripts/lint-planning-prompt-drift.cjs +434 -0
  389. package/scripts/lint-planning-snapshot-bypass-drift.cjs +544 -0
  390. package/scripts/lint-regression-test-names.cjs +15 -13
  391. package/scripts/lint-removed-but-needed.cjs +320 -0
  392. package/scripts/lint-state-field-drift.cjs +805 -0
  393. package/scripts/lint-state-write-path-drift.cjs +1045 -0
  394. package/scripts/lint-test-file-count.allowlist.json +40 -3
  395. package/scripts/lint-unreachable-guard-drift.cjs +843 -0
  396. package/scripts/lint-vendored-deps.cjs +124 -0
  397. package/scripts/mutation-matrix.cjs +13 -0
  398. package/scripts/pr-changed-files.cjs +63 -0
  399. package/scripts/pr-template-policy.cjs +14 -4
  400. package/scripts/prompt-injection-scan.sh +52 -6
  401. package/scripts/require-issue-link-policy.cjs +192 -0
  402. package/scripts/state-write-path-drift-baseline.json +19 -0
  403. package/scripts/sync-runtime-launcher.cjs +2 -4
  404. package/skills/gsd-autonomous/SKILL.md +0 -1
  405. package/skills/gsd-code-review/SKILL.md +1 -1
  406. package/skills/gsd-execute-phase/SKILL.md +1 -2
  407. package/skills/gsd-map-codebase/SKILL.md +1 -1
  408. package/skills/gsd-mempalace-capture/SKILL.md +2 -2
  409. package/skills/gsd-mempalace-recall/SKILL.md +1 -1
  410. package/skills/gsd-new-milestone/SKILL.md +2 -2
  411. package/skills/gsd-next/SKILL.md +0 -1
  412. package/skills/gsd-plan-phase/SKILL.md +1 -2
  413. package/skills/gsd-progress/SKILL.md +0 -1
  414. package/skills/gsd-quick/SKILL.md +1 -1
  415. package/skills/gsd-review-backlog/SKILL.md +2 -1
  416. package/skills/gsd-stats/SKILL.md +0 -1
  417. package/skills/gsd-verify-work/SKILL.md +1 -1
  418. package/vscode/package.json +1 -1
  419. package/gsd-core/workflows/discovery-phase.md +0 -298
  420. package/gsd-core/workflows/plan-milestone-gaps.md +0 -281
  421. package/gsd-core/workflows/verify-phase.md +0 -577
  422. package/scripts/affected-tests-lib.cjs +0 -554
  423. package/scripts/gen-emitted-baseline.cjs +0 -145
  424. package/scripts/lint-allow-test-rule-refs.cjs +0 -162
  425. package/scripts/run-affected-tests.cjs +0 -7
  426. package/scripts/run-tests.cjs +0 -1050
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ /**
3
+ * Agent Install rule (Phase 11, #3309, ADR-3180 §8.2/§8.3/§8.5).
4
+ *
5
+ * One code, W010, ported behavior-preserving from `cmdValidateHealth`'s
6
+ * agent-install block (`src/verify.cts:1992-2027`). That block wraps a
7
+ * single `checkAgentsInstalled(_slashRuntime, cwd)` call in a try/catch that
8
+ * swallows any thrown exception silently ("agent check is non-blocking",
9
+ * `verify.cts:2025-2027`) and then branches on the SAME subject —
10
+ * "agent installation is incomplete" — across four mutually exclusive
11
+ * combinations of `missing_agents`/`incomplete_agents`, firing at most one
12
+ * `addIssue('warning', 'W010', ...)` per call. Per this phase's design doc
13
+ * ("Rejected alternatives" §3), these four sites are confirmed to be one
14
+ * subject varying only in trigger detail, not four subjects — W010 stays a
15
+ * single code.
16
+ *
17
+ * `snapshot.agentInstall` (`src/planning-snapshot.cts`'s `buildAgentInstallField`)
18
+ * already performs the try/catch this rule used to need: `scope` is
19
+ * `UNREADABLE` only when the scan itself threw, mirroring
20
+ * `cmdValidateHealth`'s silent catch — this rule reproduces that silence by
21
+ * returning no diagnostic for `UNREADABLE`, rather than inventing a new,
22
+ * more severe 5th case the original never had.
23
+ *
24
+ * Design: .gsd/phase/refactor-3309-health-diagnostic-rule-table/40-design.md
25
+ * ("Rule table organization" — Agent installation group)
26
+ */
27
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- health-diagnostic-types.cjs is an export= CommonJS module
28
+ const healthDiagnosticMod = require("../health-diagnostic-types.cjs");
29
+ const { SEVERITY, adviseRemedy } = healthDiagnosticMod;
30
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
31
+ const planningScopeMod = require("../planning-scope.cjs");
32
+ const { SCOPE } = planningScopeMod;
33
+ const package_identity_cjs_1 = require("../package-identity.cjs");
34
+ /**
35
+ * `check(snapshot)` for W010 — see module header for the exact 4-way
36
+ * branching this ports from `verify.cts:1992-2027`, and its message/fix
37
+ * templates copied verbatim (only the interpolated `agentStatus.*` values
38
+ * differ per call).
39
+ */
40
+ function checkAgentInstall(snapshot) {
41
+ const { value: status, scope } = snapshot.agentInstall;
42
+ // Mirrors verify.cts:2025-2027's try/catch around the checkAgentsInstalled
43
+ // call itself — a thrown scan is swallowed, not reported. `scope` here is
44
+ // UNREADABLE only in that same case (buildAgentInstallField's own catch).
45
+ if (scope === SCOPE.UNREADABLE)
46
+ return [];
47
+ if (status.agents_installed)
48
+ return [];
49
+ // verify.cts:1995 — zero agents installed at all.
50
+ if (status.installed_agents.length === 0) {
51
+ return [
52
+ {
53
+ code: 'W010',
54
+ severity: SEVERITY.WARNING,
55
+ message: `No GSD agents found in ${status.agents_dir} — Task(subagent_type="gsd-*") will fall back to general-purpose`,
56
+ remedy: adviseRemedy(`Run the GSD installer: npx ${package_identity_cjs_1.PACKAGE_NAME}@latest`),
57
+ },
58
+ ];
59
+ }
60
+ // verify.cts:2002 — some agents incomplete (missing a generated file), zero fully missing.
61
+ if (status.incomplete_agents.length > 0 && status.missing_agents.length === 0) {
62
+ return [
63
+ {
64
+ code: 'W010',
65
+ severity: SEVERITY.WARNING,
66
+ message: `Incomplete agent installs (missing generated file): ${status.incomplete_agents.join(', ')} — affected workflows may fall back to general-purpose`,
67
+ remedy: adviseRemedy(`Re-run the GSD installer to complete the install: npx ${package_identity_cjs_1.PACKAGE_NAME}@latest`),
68
+ },
69
+ ];
70
+ }
71
+ // verify.cts:2009 — both missing AND incomplete agents present.
72
+ if (status.incomplete_agents.length > 0) {
73
+ return [
74
+ {
75
+ code: 'W010',
76
+ severity: SEVERITY.WARNING,
77
+ message: `Missing ${status.missing_agents.length} GSD agents: ${status.missing_agents.join(', ')}; incomplete agent installs (missing generated file): ${status.incomplete_agents.join(', ')} — affected workflows will fall back to general-purpose`,
78
+ remedy: adviseRemedy(`Run the GSD installer: npx ${package_identity_cjs_1.PACKAGE_NAME}@latest`),
79
+ },
80
+ ];
81
+ }
82
+ // verify.cts:2017 — agents missing only (no incomplete).
83
+ return [
84
+ {
85
+ code: 'W010',
86
+ severity: SEVERITY.WARNING,
87
+ message: `Missing ${status.missing_agents.length} GSD agents: ${status.missing_agents.join(', ')} — affected workflows will fall back to general-purpose`,
88
+ remedy: adviseRemedy(`Run the GSD installer: npx ${package_identity_cjs_1.PACKAGE_NAME}@latest`),
89
+ },
90
+ ];
91
+ }
92
+ const RULES = [
93
+ {
94
+ code: 'W010',
95
+ severity: SEVERITY.WARNING,
96
+ description: 'GSD agent installation missing or incomplete',
97
+ repairable: false,
98
+ check: checkAgentInstall,
99
+ },
100
+ ];
101
+ module.exports = { RULES };
@@ -0,0 +1,348 @@
1
+ "use strict";
2
+ /**
3
+ * Health Diagnostic — config.json validation rules (Phase 11, #3309,
4
+ * ADR-3180 §8.2/§8.3/§8.5).
5
+ *
6
+ * Group: "config.json validation" (design doc, "Rule table organization"
7
+ * table) — W003, W004, W022 (one rule, three internal conditions), E005,
8
+ * W008, W016, W012, W013, W014, W015.
9
+ *
10
+ * Ported behavior-preserving from `cmdValidateHealth`'s config.json blocks
11
+ * (`src/verify.cts:1777-1835` for W003/W004/W022/E005,
12
+ * `src/verify.cts:1837-1865` for W008/W016,
13
+ * `src/verify.cts:2136-2191` for W012/W013/W014/W015). Every rule here reads
14
+ * ONLY `snapshot.config` (`{value, scope, exists}`, `src/planning-snapshot.cts`'s
15
+ * `buildConfigField`).
16
+ *
17
+ * W022 stays a SINGLE code across its three call sites per the design doc's
18
+ * "Rejected alternatives" §3: all three are variations on one question ("is
19
+ * `models` well-formed"), not a genuine multi-subject conflation. This rule's
20
+ * `checkW022` mirrors the original's exact if / else-if control flow
21
+ * (`verify.cts:1799-1824`): the object-shaped branch loops every `models`
22
+ * entry (0-N diagnostics, one per malformed entry); the non-object branch
23
+ * fires independently and ONLY when the object-shaped branch did not run —
24
+ * `models` is never checked against both.
25
+ *
26
+ * Two disclosed fidelity reductions, forced by `snapshot.config`'s shape
27
+ * (neither is available without violating §8.1 rule 1's "no ambient I/O in a
28
+ * rule's `check`"):
29
+ *
30
+ * - E005's original message interpolates the live `JSON.parse` error text
31
+ * (`config.json: JSON parse error - ${err.message}`, `verify.cts:1829`).
32
+ * `buildConfigField` (`src/planning-snapshot.cts:268-281`) catches and
33
+ * discards that error, collapsing an unparseable config.json to
34
+ * `{value: null, scope: UNREADABLE, exists: true}` with no error text
35
+ * anywhere in the snapshot. This rule's message drops the interpolated
36
+ * suffix rather than fabricate error text the snapshot never carried.
37
+ * - W016's original message interpolates `${slash('ai-integration-phase')}`
38
+ * (`verify.cts:1856`), a per-project runtime-resolved value
39
+ * (`formatGsdSlash`, `src/runtime-slash.cts`) this rule's `(snapshot) =>
40
+ * Diagnostic[]` signature has no access to. Hardcodes the canonical
41
+ * `/gsd-ai-integration-phase` hyphen form instead, mirroring the sibling
42
+ * "Phase directory structure" group's W009 rule
43
+ * (`src/health-diagnostic-rules/phase-structure.cts`), which hardcodes
44
+ * `/gsd-plan-phase` the same way for the identical reason.
45
+ *
46
+ * Design: .gsd/phase/refactor-3309-health-diagnostic-rule-table/40-design.md
47
+ *
48
+ * ADR-457 build-at-publish: source in
49
+ * src/health-diagnostic-rules/config-validation.cts, compiled to
50
+ * gsd-core/bin/lib/health-diagnostic-rules/config-validation.cjs (gitignored).
51
+ */
52
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- health-diagnostic-types.cjs is an export= CommonJS module
53
+ const healthDiagnosticMod = require("../health-diagnostic-types.cjs");
54
+ const { SEVERITY, REMEDY_ACTION, REMEDY_RISK, adviseRemedy } = healthDiagnosticMod;
55
+ const model_catalog_cjs_1 = require("../model-catalog.cjs");
56
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
57
+ const planningScopeMod = require("../planning-scope.cjs");
58
+ const { SCOPE } = planningScopeMod;
59
+ // verify.cts:2141 — inlined literal, not exported from anywhere; same list.
60
+ const VALID_BRANCHING_STRATEGIES = ['none', 'phase', 'milestone'];
61
+ // ─── W003 — config.json not found (verify.cts:1777-1785) ───────────────────
62
+ function checkW003(snapshot) {
63
+ if (snapshot.config.exists)
64
+ return [];
65
+ return [
66
+ {
67
+ code: 'W003',
68
+ severity: SEVERITY.WARNING,
69
+ message: 'config.json not found',
70
+ remedy: { action: REMEDY_ACTION.CREATE_CONFIG, risk: REMEDY_RISK.NONE, args: {} },
71
+ },
72
+ ];
73
+ }
74
+ // ─── E005 — config.json JSON parse error (verify.cts:1825-1834) ────────────
75
+ //
76
+ // `exists: true, value: null` is exactly `buildConfigField`'s "present but
77
+ // unparseable" contract (planning-snapshot.cts:268-281) — the same
78
+ // discriminator that separates this from W003's "absent" case.
79
+ function checkE005(snapshot) {
80
+ if (!snapshot.config.exists || snapshot.config.value !== null)
81
+ return [];
82
+ return [
83
+ {
84
+ code: 'E005',
85
+ severity: SEVERITY.ERROR,
86
+ message: 'config.json: JSON parse error',
87
+ remedy: { action: REMEDY_ACTION.RESET_CONFIG, risk: REMEDY_RISK.DESTRUCTIVE, args: {} },
88
+ },
89
+ ];
90
+ }
91
+ // ─── W004 — invalid model_profile (verify.cts:1790-1797) ───────────────────
92
+ function checkW004(snapshot) {
93
+ const value = snapshot.config.value;
94
+ if (!value)
95
+ return [];
96
+ const profile = value['model_profile'];
97
+ if (profile && !model_catalog_cjs_1.VALID_PROFILES.includes(profile)) {
98
+ return [
99
+ {
100
+ code: 'W004',
101
+ severity: SEVERITY.WARNING,
102
+ message: `config.json: invalid model_profile "${profile}"`,
103
+ remedy: adviseRemedy(`Valid values: ${model_catalog_cjs_1.VALID_PROFILES.join(', ')}`),
104
+ },
105
+ ];
106
+ }
107
+ return [];
108
+ }
109
+ // ─── W008 — workflow.nyquist_validation absent (verify.cts:1841-1851) ──────
110
+ function checkW008(snapshot) {
111
+ const value = snapshot.config.value;
112
+ const workflow = value ? value['workflow'] : undefined;
113
+ if (workflow && workflow['nyquist_validation'] === undefined) {
114
+ return [
115
+ {
116
+ code: 'W008',
117
+ severity: SEVERITY.WARNING,
118
+ message: 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)',
119
+ remedy: { action: REMEDY_ACTION.ADD_NYQUIST_KEY, risk: REMEDY_RISK.NONE, args: {} },
120
+ },
121
+ ];
122
+ }
123
+ return [];
124
+ }
125
+ // ─── W016 — workflow.ai_integration_phase absent (verify.cts:1852-1861) ────
126
+ function checkW016(snapshot) {
127
+ const value = snapshot.config.value;
128
+ const workflow = value ? value['workflow'] : undefined;
129
+ if (workflow && workflow['ai_integration_phase'] === undefined) {
130
+ return [
131
+ {
132
+ code: 'W016',
133
+ severity: SEVERITY.WARNING,
134
+ message: 'config.json: workflow.ai_integration_phase absent (defaults to enabled — run /gsd-ai-integration-phase before planning AI system phases)',
135
+ remedy: { action: REMEDY_ACTION.ADD_AI_INTEGRATION_PHASE_KEY, risk: REMEDY_RISK.NONE, args: {} },
136
+ },
137
+ ];
138
+ }
139
+ return [];
140
+ }
141
+ // ─── W012 — invalid branching_strategy (verify.cts:2141-2152) ──────────────
142
+ function checkW012(snapshot) {
143
+ const value = snapshot.config.value;
144
+ if (!value)
145
+ return [];
146
+ const strategy = value['branching_strategy'];
147
+ if (strategy && !VALID_BRANCHING_STRATEGIES.includes(strategy)) {
148
+ return [
149
+ {
150
+ code: 'W012',
151
+ severity: SEVERITY.WARNING,
152
+ message: `config.json: invalid branching_strategy "${strategy}"`,
153
+ remedy: adviseRemedy(`Valid values: ${VALID_BRANCHING_STRATEGIES.join(', ')}`),
154
+ },
155
+ ];
156
+ }
157
+ return [];
158
+ }
159
+ // ─── W013 — context_window not a positive integer (verify.cts:2154-2164) ───
160
+ function checkW013(snapshot) {
161
+ const value = snapshot.config.value;
162
+ if (!value)
163
+ return [];
164
+ const cw = value['context_window'];
165
+ if (cw !== undefined && (typeof cw !== 'number' || cw <= 0 || !Number.isInteger(cw))) {
166
+ return [
167
+ {
168
+ code: 'W013',
169
+ severity: SEVERITY.WARNING,
170
+ message: `config.json: context_window should be a positive integer, got "${cw}"`,
171
+ remedy: adviseRemedy('Set to 200000 (default) or 1000000 (for 1M models)'),
172
+ },
173
+ ];
174
+ }
175
+ return [];
176
+ }
177
+ // ─── W014 — phase_branch_template missing {phase} (verify.cts:2166-2176) ───
178
+ function checkW014(snapshot) {
179
+ const value = snapshot.config.value;
180
+ if (!value)
181
+ return [];
182
+ const tmpl = value['phase_branch_template'];
183
+ if (tmpl && !tmpl.includes('{phase}')) {
184
+ return [
185
+ {
186
+ code: 'W014',
187
+ severity: SEVERITY.WARNING,
188
+ message: 'config.json: phase_branch_template missing {phase} placeholder',
189
+ remedy: adviseRemedy('Template must include {phase} for phase number substitution'),
190
+ },
191
+ ];
192
+ }
193
+ return [];
194
+ }
195
+ // ─── W015 — milestone_branch_template missing {milestone} (verify.cts:2177-2187) ─
196
+ function checkW015(snapshot) {
197
+ const value = snapshot.config.value;
198
+ if (!value)
199
+ return [];
200
+ const tmpl = value['milestone_branch_template'];
201
+ if (tmpl && !tmpl.includes('{milestone}')) {
202
+ return [
203
+ {
204
+ code: 'W015',
205
+ severity: SEVERITY.WARNING,
206
+ message: 'config.json: milestone_branch_template missing {milestone} placeholder',
207
+ remedy: adviseRemedy('Template must include {milestone} for version substitution'),
208
+ },
209
+ ];
210
+ }
211
+ return [];
212
+ }
213
+ // ─── W022 — models malformed, 3 internal conditions (verify.cts:1798-1824) ─
214
+ //
215
+ // Mirrors the original if / else-if chain exactly: the object-shaped branch
216
+ // (a: unknown phase type, b: invalid tier value) loops every `models` entry,
217
+ // pushing 0-N diagnostics; the non-object branch (c) is an ELSE-IF, so it
218
+ // only runs when `models` is truthy but did NOT satisfy "object, not array" —
219
+ // (a)/(b) are never evaluated against a non-object `models`.
220
+ function checkW022(snapshot) {
221
+ const value = snapshot.config.value;
222
+ if (!value)
223
+ return [];
224
+ const diagnostics = [];
225
+ const configModels = value['models'];
226
+ if (configModels && typeof configModels === 'object' && !Array.isArray(configModels)) {
227
+ for (const [phaseType, tierValue] of Object.entries(configModels)) {
228
+ if (!model_catalog_cjs_1.VALID_PHASE_TYPES.has(phaseType)) {
229
+ diagnostics.push({
230
+ code: 'W022',
231
+ severity: SEVERITY.WARNING,
232
+ message: `config.json: models has an unknown phase type "${phaseType}" which will be ignored`,
233
+ remedy: adviseRemedy(`Valid phase types: ${[...model_catalog_cjs_1.VALID_PHASE_TYPES].join(', ')}`),
234
+ });
235
+ }
236
+ else if (typeof tierValue !== 'string' || !model_catalog_cjs_1.VALID_TIERS.has(tierValue)) {
237
+ diagnostics.push({
238
+ code: 'W022',
239
+ severity: SEVERITY.WARNING,
240
+ message: `config.json: models.${phaseType} has an invalid tier value ${JSON.stringify(tierValue)} which will be ignored`,
241
+ remedy: adviseRemedy(`Valid tiers: ${[...model_catalog_cjs_1.VALID_TIERS].join(', ')}`),
242
+ });
243
+ }
244
+ }
245
+ }
246
+ else if (configModels !== undefined && configModels !== null) {
247
+ diagnostics.push({
248
+ code: 'W022',
249
+ severity: SEVERITY.WARNING,
250
+ message: `config.json: models is set to ${JSON.stringify(configModels)}, but must be an object mapping phase types to tiers — this value will be ignored`,
251
+ remedy: adviseRemedy('Set models to an object like {"planning": "sonnet"}, or remove the key to use profile defaults'),
252
+ });
253
+ }
254
+ return diagnostics;
255
+ }
256
+ // ─── W029 — `.planning/` ignored but still tracked (#3586, epic #2292) ─────
257
+ //
258
+ // Not a config.json-sourced check (unlike every other rule in this file) —
259
+ // registered here per the phase brief rather than in a new file, reading
260
+ // only `snapshot.planningTracked` (`src/planning-snapshot.cts`'s
261
+ // `buildPlanningTrackedField`). Fires ONLY when the probe's scope is
262
+ // COMPLETE and both `ignored` and `tracked` are true: `.gitignore` has no
263
+ // effect on files git already tracks, so a project that committed
264
+ // `.planning/` before ignoring it keeps staging those files forever even
265
+ // though `commit_docs` correctly auto-resolves `false`. Any other COMPLETE
266
+ // combination (most importantly `ignored: false, tracked: true` — the
267
+ // default, healthy state of every normal project) is silent; a degraded
268
+ // (non-COMPLETE) scope is ALSO silent — a probe that could not run must
269
+ // never manufacture a finding. ADVISE-only: auto-untracking is destructive
270
+ // and outside this phase's stated boundary (design doc, "Rejected" #3).
271
+ function checkW029(snapshot) {
272
+ const field = snapshot.planningTracked;
273
+ if (!field || field.scope !== SCOPE.COMPLETE)
274
+ return [];
275
+ if (!field.value.ignored || !field.value.tracked)
276
+ return [];
277
+ return [
278
+ {
279
+ code: 'W029',
280
+ severity: SEVERITY.WARNING,
281
+ message: '.planning/ matches a gitignore rule but is still tracked by git — .gitignore has no effect on already-tracked files, so staging keeps picking them up',
282
+ remedy: adviseRemedy('Run `git rm -r --cached .planning/` to untrack it (the ignore rule then takes effect); this does not delete the files on disk'),
283
+ },
284
+ ];
285
+ }
286
+ // ─── Exports ────────────────────────────────────────────────────────────────
287
+ const RULES = [
288
+ { code: 'W003', severity: SEVERITY.WARNING, description: 'config.json not found', repairable: true, check: checkW003 },
289
+ { code: 'E005', severity: SEVERITY.ERROR, description: 'config.json parse error', repairable: false, check: checkE005 },
290
+ { code: 'W004', severity: SEVERITY.WARNING, description: 'config.json invalid field value', repairable: false, check: checkW004 },
291
+ {
292
+ code: 'W008',
293
+ severity: SEVERITY.WARNING,
294
+ description: 'config.json: workflow.nyquist_validation absent (defaults to enabled but agents may skip)',
295
+ repairable: true,
296
+ check: checkW008,
297
+ },
298
+ {
299
+ code: 'W016',
300
+ severity: SEVERITY.WARNING,
301
+ description: 'config.json: workflow.ai_integration_phase absent (defaults to enabled but agents may skip AI-integration-phase planning)',
302
+ repairable: true,
303
+ check: checkW016,
304
+ },
305
+ {
306
+ code: 'W012',
307
+ severity: SEVERITY.WARNING,
308
+ description: 'config.json invalid branching_strategy value',
309
+ repairable: false,
310
+ check: checkW012,
311
+ },
312
+ {
313
+ code: 'W013',
314
+ severity: SEVERITY.WARNING,
315
+ description: 'config.json context_window not a positive integer',
316
+ repairable: false,
317
+ check: checkW013,
318
+ },
319
+ {
320
+ code: 'W014',
321
+ severity: SEVERITY.WARNING,
322
+ description: 'config.json phase_branch_template missing {phase} placeholder',
323
+ repairable: false,
324
+ check: checkW014,
325
+ },
326
+ {
327
+ code: 'W015',
328
+ severity: SEVERITY.WARNING,
329
+ description: 'config.json milestone_branch_template missing {milestone} placeholder',
330
+ repairable: false,
331
+ check: checkW015,
332
+ },
333
+ {
334
+ code: 'W022',
335
+ severity: SEVERITY.WARNING,
336
+ description: 'config.json models entry malformed (unknown phase type, invalid tier, or non-object value)',
337
+ repairable: false,
338
+ check: checkW022,
339
+ },
340
+ {
341
+ code: 'W029',
342
+ severity: SEVERITY.WARNING,
343
+ description: '.planning/ matches a gitignore rule but is still tracked by git (gitignore has no effect on already-tracked files)',
344
+ repairable: false,
345
+ check: checkW029,
346
+ },
347
+ ];
348
+ module.exports = { RULES };
@@ -0,0 +1,145 @@
1
+ "use strict";
2
+ /**
3
+ * Health Diagnostic — `validate.consistency`-only rules (Phase 12, #3310,
4
+ * ADR-3180 §8.4).
5
+ *
6
+ * Group: "consistency" — a NEW `C0NN` code namespace, parallel to (not part
7
+ * of) `validate.health`'s `E`/`W`/`I` space Phase 11 minted. These four
8
+ * subjects are `cmdValidateConsistency`'s (`src/verify.cts:1466-1612`)
9
+ * own findings, not `validate.health` findings — see the design doc's
10
+ * "Code namespace" section for why they get their own prefix instead of
11
+ * competing for the next free `W0NN` number.
12
+ *
13
+ * Ported behavior-preserving from `cmdValidateConsistency`
14
+ * (`src/verify.cts:1504-1519` for C001, `:1570-1576` for C002, `:1584-1587`
15
+ * for C003, `:1596-1602` for C004) — relocated, not reinvented. The
16
+ * duplicate subjects `cmdValidateConsistency` also computed (phase-in-
17
+ * roadmap-no-dir / dir-on-disk-not-in-roadmap) are NOT here: those are
18
+ * W006/W007, reused verbatim from
19
+ * `src/health-diagnostic-rules/roadmap-disk-consistency.cts` via
20
+ * `health-diagnostic.cts`'s `CONSISTENCY_RULES` composition, not
21
+ * reimplemented in this file (design doc, "Which rules run where").
22
+ *
23
+ * All four remedies are `ADVISE` — none of these four subjects had a repair
24
+ * path in the pre-migration code either, matching Phase 11's own convention
25
+ * for message-only findings with no automated fix.
26
+ *
27
+ * Design: .gsd/phase/feat-3310-enhance-3180-the-sibling-validators-shar/40-design.md
28
+ * Test matrix: .gsd/phase/feat-3310-enhance-3180-the-sibling-validators-shar/50-test-matrix.md
29
+ *
30
+ * ADR-457 build-at-publish: source in src/health-diagnostic-rules/consistency.cts,
31
+ * compiled to gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs (gitignored).
32
+ */
33
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
34
+ const healthDiagnosticMod = require("../health-diagnostic-types.cjs");
35
+ const { SEVERITY, adviseRemedy } = healthDiagnosticMod;
36
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
37
+ const phaseIdMod = require("../phase-id.cjs");
38
+ const { isSentinelPhaseId } = phaseIdMod;
39
+ // ─── C001 — gap in disk phase numbering (integer sequence) ────────────────
40
+ // (verify.cts:1504-1519)
41
+ function checkC001(snapshot) {
42
+ // verify.cts:1505 — `if (config.phase_naming !== 'custom')`; the
43
+ // integer-sequence gap check is skipped entirely under custom phase
44
+ // naming, since a custom naming scheme has no integer sequence to have a
45
+ // gap in.
46
+ if (snapshot.config.value?.['phase_naming'] === 'custom')
47
+ return [];
48
+ const integerPhases = snapshot.allPhaseDirNames.value
49
+ // #3225: exclude sentinel phase ids (999.x/0.x) — never part of the
50
+ // sequential numbering, mirrors verify.cts:1510 verbatim.
51
+ .filter((p) => !p.includes('.') && !isSentinelPhaseId(p))
52
+ .map((p) => parseInt(p, 10))
53
+ .filter((n) => !Number.isNaN(n))
54
+ .sort((a, b) => a - b);
55
+ const diagnostics = [];
56
+ for (let i = 1; i < integerPhases.length; i++) {
57
+ if (integerPhases[i] !== integerPhases[i - 1] + 1) {
58
+ diagnostics.push({
59
+ code: 'C001',
60
+ severity: SEVERITY.WARNING,
61
+ message: `Gap in phase numbering: ${integerPhases[i - 1]} → ${integerPhases[i]}`,
62
+ remedy: adviseRemedy('Create the missing phase directory or renumber to close the gap'),
63
+ });
64
+ }
65
+ }
66
+ return diagnostics;
67
+ }
68
+ // ─── C002 — gap in plan numbering within a phase ───────────────────────────
69
+ // (verify.cts:1570-1576)
70
+ // Fidelity note: the original's `phaseLabel` (verify.cts:1532,
71
+ // `posixNormalize(path.relative(planBase, phasePath))`) is a
72
+ // `.planning/`-relative posix path, which for the flat `phases/<dir>` case
73
+ // this rule scans reduces to the bare directory name (`phaseDir` below) —
74
+ // same string, not a narrower one, since `perPhasePlanNumbering` only
75
+ // enumerates the flat `phases/` root (see `PlanningSnapshot`'s own doc
76
+ // comment on this field for the one disclosed scope reduction, an active
77
+ // archived milestone's second phase root, which is out of scope here too).
78
+ function checkC002(snapshot) {
79
+ const diagnostics = [];
80
+ for (const { phaseDir, planNums } of snapshot.perPhasePlanNumbering.value) {
81
+ for (let i = 1; i < planNums.length; i++) {
82
+ if (planNums[i] !== planNums[i - 1] + 1) {
83
+ diagnostics.push({
84
+ code: 'C002',
85
+ severity: SEVERITY.WARNING,
86
+ message: `Gap in plan numbering in ${phaseDir}: plan ${planNums[i - 1]} → ${planNums[i]}`,
87
+ remedy: adviseRemedy('Create the missing plan or renumber to close the gap'),
88
+ });
89
+ }
90
+ }
91
+ }
92
+ return diagnostics;
93
+ }
94
+ // ─── C003 — orphan SUMMARY with no matching live PLAN ──────────────────────
95
+ // (verify.cts:1584-1587)
96
+ function checkC003(snapshot) {
97
+ return snapshot.perPhaseOrphanSummaries.value.map(({ phaseDir, orphanSummary }) => ({
98
+ code: 'C003',
99
+ severity: SEVERITY.WARNING,
100
+ message: `Summary ${orphanSummary} in ${phaseDir} has no matching PLAN.md`,
101
+ remedy: adviseRemedy('Create the matching PLAN.md or remove the orphan summary'),
102
+ }));
103
+ }
104
+ // ─── C004 — PLAN missing `wave` frontmatter ────────────────────────────────
105
+ // (verify.cts:1596-1602)
106
+ function checkC004(snapshot) {
107
+ return snapshot.perPhaseWaveMissingPlans.value.map(({ phaseDir, plan }) => ({
108
+ code: 'C004',
109
+ severity: SEVERITY.WARNING,
110
+ message: `${phaseDir}/${plan}: missing 'wave' in frontmatter`,
111
+ remedy: adviseRemedy("Add a 'wave' key to the plan's frontmatter"),
112
+ }));
113
+ }
114
+ // ─── Exports ────────────────────────────────────────────────────────────────
115
+ const RULES = [
116
+ {
117
+ code: 'C001',
118
+ severity: SEVERITY.WARNING,
119
+ description: 'Gap in disk phase numbering (integer sequence)',
120
+ repairable: false,
121
+ check: checkC001,
122
+ },
123
+ {
124
+ code: 'C002',
125
+ severity: SEVERITY.WARNING,
126
+ description: 'Gap in plan numbering within a phase',
127
+ repairable: false,
128
+ check: checkC002,
129
+ },
130
+ {
131
+ code: 'C003',
132
+ severity: SEVERITY.WARNING,
133
+ description: 'Orphan SUMMARY with no matching live PLAN',
134
+ repairable: false,
135
+ check: checkC003,
136
+ },
137
+ {
138
+ code: 'C004',
139
+ severity: SEVERITY.WARNING,
140
+ description: "PLAN missing 'wave' in frontmatter",
141
+ repairable: false,
142
+ check: checkC004,
143
+ },
144
+ ];
145
+ module.exports = { RULES };