@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,340 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ /**
5
+ * lint-eslint-glob-coverage.cjs — ESLint `files:` glob coverage drift guard (#3059).
6
+ *
7
+ * ## What this enforces
8
+ *
9
+ * `eslint.config.mjs` is a flat config: a tracked source file is only linted
10
+ * if it matches at least one config object's `files:` glob (or a global,
11
+ * files-less block). A file matching NO glob resolves to zero reachable
12
+ * rules and `eslint .` silently exits 0 on it — the #3059 defect class (62
13
+ * tracked source files found with this shape). This guard walks every
14
+ * tracked `.cjs/.cts/.js/.mjs` source file, resolves its real ESLint config,
15
+ * and fails when a file resolves to zero rules and isn't a deliberately
16
+ * exempted, reasoned allowlist entry.
17
+ *
18
+ * This checks rule REACHABILITY (does at least one rule apply to this file
19
+ * at all, any severity), not rule SEVERITY (whether an applicable rule is
20
+ * `error` vs `warn` vs `off`) — severity coverage is a separate gate, #1885
21
+ * F17. A file with one `off` rule reachable still counts as "covered" here:
22
+ * it proves the file was deliberately targeted by a `files:` glob, which is
23
+ * the thing #3059 is about.
24
+ *
25
+ * ## Goodhart rationale
26
+ *
27
+ * A coverage metric is trivially gameable by padding the allowlist instead
28
+ * of fixing the glob, so every knob here is built to resist that:
29
+ * - Every allowlist entry MUST carry a non-empty `reason` — an unreasoned
30
+ * entry is indistinguishable from "quietly made the metric look better".
31
+ * - The allowlist only ratchets DOWN: an entry whose path now resolves to
32
+ * >=1 rule (`allowlist_stale`) is a failure, forcing prompt removal
33
+ * rather than letting stale exemptions accumulate as free cover for
34
+ * future accidental escapes at the same path.
35
+ * - A tracked-file-count floor (`tracked_count_below_floor`) exists so a
36
+ * broken or empty `git ls-files` (e.g. wrong cwd, detached worktree)
37
+ * can't report a vacuous "0 escapes out of 0 checked" clean run.
38
+ *
39
+ * ## Ignored vs. unmatched (the discrimination this script makes)
40
+ *
41
+ * ESLint's `ignores:` blocks are the one legitimate "this file is not meant
42
+ * to be linted" decision (e.g. the ADR-457 tsc-emitted `.cjs` artifacts
43
+ * under `gsd-core/bin/lib/`) and must NOT be reported as uncovered. But
44
+ * `ESLint#isPathIgnored` cannot be trusted uniformly across extensions:
45
+ * for ESLint's default-lintable extensions (`.js`/`.mjs`/`.cjs`), it
46
+ * reports `true` only when the path matches an explicit `ignores:` glob —
47
+ * verified empirically: an unmatched top-level `.cjs` probe file reports
48
+ * `isPathIgnored() === false` with an empty resolved rule set, not `true`.
49
+ * For `.cts` (and any other non-default extension), flat config requires an
50
+ * EXPLICIT `files:` glob match to be linted at all; a `.cts` file matching
51
+ * no `files:` glob ALSO reports `isPathIgnored() === true` — indistinguishable,
52
+ * via this API, from a genuine `ignores:` entry (verified with a scratch
53
+ * `.cts` fixture under `tests/fixtures/`). This repo's `ignores:` list never
54
+ * contains a `.cts` path (ADR-457 retires only the emitted `.cjs`; the
55
+ * `.cts` source is always meant to stay linted), so for `.cts` specifically
56
+ * an `isPathIgnored() === true` verdict can only mean "matches no `files:`
57
+ * glob" and is therefore treated as UNCOVERED, not ignored. See
58
+ * `resolveFileCoverage` below.
59
+ *
60
+ * ## Why `bin/install.js` is NOT in the allowlist
61
+ *
62
+ * The allowlist below is exclusively for files that resolve to ZERO rules —
63
+ * it is a registry of accepted escapes, not a general-purpose "reasons for
64
+ * how a file is configured" log. The `bin/install.js` / `bin/gsd-mcp-server.js`
65
+ * / `scripts/build-hooks.js` family is deliberately covered by a minimal,
66
+ * 2-rule block in `eslint.config.mjs` per ADR-1703 (targeting only the
67
+ * portability defect surface, not a full style sweep of ~12k lines of
68
+ * generated code) — see the comment at that block in `eslint.config.mjs`.
69
+ * Because 2 rules is non-empty, that family already passes this guard
70
+ * without needing an allowlist entry, and adding one anyway would itself be
71
+ * flagged `allowlist_stale` (see the ratchet above). The allowlist exemption
72
+ * surface deliberately cannot be used to re-state a decision that is already
73
+ * recorded in the config; #3059 is the guard, ADR-1703 is the decision.
74
+ */
75
+
76
+ const fs = require('fs');
77
+ const path = require('path');
78
+
79
+ const ROOT = path.join(__dirname, '..');
80
+ const ALLOWLIST_PATH = path.join(__dirname, 'lint-eslint-glob-coverage.allowlist.json');
81
+
82
+ const SOURCE_EXT_RE = /\.(cjs|cts|js|mjs)$/;
83
+
84
+ // ESLint's flat-config default-lintable extensions: a file with one of these
85
+ // extensions that matches no `files:` glob still reports `isPathIgnored()
86
+ // === false` (with an empty resolved rule set) — so for these extensions,
87
+ // `isPathIgnored() === true` reliably means an explicit `ignores:` match.
88
+ const DEFAULT_LINTABLE_EXT_RE = /\.(js|mjs|cjs)$/;
89
+
90
+ const MIN_TRACKED_SOURCE_FILES = 500;
91
+
92
+ /**
93
+ * Runs `git ls-files` and returns the tracked source files (repo-relative,
94
+ * POSIX-normalized, filtered to SOURCE_EXT_RE). Never throws: a git failure
95
+ * (non-zero exit or timeout) produces a degraded `{ ok: false }` result so
96
+ * callers can turn it into a `git_failed` violation instead of crashing.
97
+ *
98
+ * @param {object} [opts]
99
+ * @param {Function} [opts.execFile] - injectable sync exec function with the
100
+ * `execFileSync(cmd, args, options)` signature; defaults to
101
+ * `child_process.execFileSync`.
102
+ */
103
+ function listTrackedSourceFiles({ execFile } = {}) {
104
+ const run = execFile || require('child_process').execFileSync;
105
+ let stdout;
106
+ try {
107
+ // The test runner and CI execute inside a container where this repo is
108
+ // owned by a different UID than the running user; bare `git ls-files`
109
+ // then refuses with "detected dubious ownership" unless the path is in
110
+ // `safe.directory`, and this guard degrades to a `git_failed` violation
111
+ // — exactly where it must run to be a useful gate (#3059). `-c
112
+ // safe.directory=*` scopes the override to THIS invocation only (it
113
+ // never writes to any config file, global or local), and the wildcard
114
+ // is fine here because this command only ever enumerates tracked paths
115
+ // in the repo the guard is already executing inside.
116
+ stdout = run('git', ['-c', 'safe.directory=*', 'ls-files'], {
117
+ cwd: ROOT,
118
+ encoding: 'utf8',
119
+ // 30s — `git ls-files` on this tree returns ~1175 paths in <1s; 30s is
120
+ // the CLAUDE.md git ceiling, generous for a cold index.
121
+ timeout: 30000,
122
+ });
123
+ } catch (err) {
124
+ return { ok: false, files: [], error: (err && err.message) || String(err) };
125
+ }
126
+
127
+ const files = String(stdout)
128
+ // CRLF-safe: `git ls-files` output may carry \r\n on a Windows checkout
129
+ // or a git config with core.autocrlf set (DEFECT.CRLF class).
130
+ .split(/\r?\n/)
131
+ .filter((line) => line.length > 0)
132
+ // Unconditional backslash normalization (never path.sep-gated): the
133
+ // guard's own process may run on any platform regardless of what
134
+ // produced the tracked-file listing.
135
+ .map((line) => line.replace(/\\/g, '/'))
136
+ .filter((line) => SOURCE_EXT_RE.test(line));
137
+
138
+ return { ok: true, files };
139
+ }
140
+
141
+ /** Loads and parses the allowlist JSON file. */
142
+ function loadAllowlist() {
143
+ const raw = fs.readFileSync(ALLOWLIST_PATH, 'utf8');
144
+ return JSON.parse(raw);
145
+ }
146
+
147
+ /**
148
+ * Resolves the ESLint coverage verdict for a single tracked file. See the
149
+ * "Ignored vs. unmatched" header section for the extension-dependent
150
+ * discrimination rationale.
151
+ *
152
+ * @param {import('eslint').ESLint} eslint
153
+ * @param {string} relPath - repo-relative POSIX path
154
+ * @returns {Promise<{ ignored: boolean, ruleCount: number }>}
155
+ */
156
+ async function resolveFileCoverage(eslint, relPath) {
157
+ const absPath = path.join(ROOT, relPath);
158
+ const ignored = await eslint.isPathIgnored(absPath);
159
+
160
+ if (ignored) {
161
+ if (DEFAULT_LINTABLE_EXT_RE.test(relPath)) {
162
+ // .js/.mjs/.cjs: isPathIgnored() only reports true for an explicit
163
+ // `ignores:` glob match — a recorded decision.
164
+ return { ignored: true, ruleCount: 0 };
165
+ }
166
+ // .cts (or any non-default extension): isPathIgnored() can't
167
+ // distinguish "explicit ignores: match" from "no files: glob matched
168
+ // it at all" — and this repo's ignores: list never targets .cts, so
169
+ // treat it as the latter (uncovered), never as ignored.
170
+ return { ignored: false, ruleCount: 0 };
171
+ }
172
+
173
+ const config = await eslint.calculateConfigForFile(absPath);
174
+ const ruleCount = config && config.rules ? Object.keys(config.rules).length : 0;
175
+ return { ignored: false, ruleCount };
176
+ }
177
+
178
+ /** Builds the default real-ESLint-backed resolveConfig function. */
179
+ function createDefaultResolveConfig() {
180
+ const { ESLint } = require('eslint');
181
+ const eslint = new ESLint({ cwd: ROOT });
182
+ return (relPath) => resolveFileCoverage(eslint, relPath);
183
+ }
184
+
185
+ /**
186
+ * The pure coverage predicate. All I/O is injectable via `deps` so tests
187
+ * never need a temp repo, a real subprocess, or a real ESLint instance:
188
+ *
189
+ * @param {object} [deps]
190
+ * @param {string[] | { ok: boolean, files?: string[], error?: string }} [deps.trackedFiles]
191
+ * Either a plain array of tracked source paths (success shorthand), or a
192
+ * `listTrackedSourceFiles()`-shaped result object (so a git failure can be
193
+ * injected directly). Defaults to a real `listTrackedSourceFiles()` call.
194
+ * @param {(relPath: string) => Promise<{ignored:boolean,ruleCount:number}> | {ignored:boolean,ruleCount:number}} [deps.resolveConfig]
195
+ * Per-file coverage resolver. Defaults to a real ESLint instance.
196
+ * @param {Array<{path:string,reason?:string}>} [deps.allowlist] - defaults to
197
+ * the real `loadAllowlist()`.
198
+ * @param {number} [deps.minTrackedFiles] - defaults to MIN_TRACKED_SOURCE_FILES.
199
+ * @returns {Promise<{ ok: boolean, escapes: Array<{path:string}>, violations: Array<{kind:string,path:string|null,detail:string}>, checked: number }>}
200
+ */
201
+ async function checkGlobCoverage(deps = {}) {
202
+ const minTrackedFiles =
203
+ typeof deps.minTrackedFiles === 'number' ? deps.minTrackedFiles : MIN_TRACKED_SOURCE_FILES;
204
+
205
+ const violations = [];
206
+
207
+ let trackedResult;
208
+ if (deps.trackedFiles === undefined) {
209
+ trackedResult = listTrackedSourceFiles();
210
+ } else if (Array.isArray(deps.trackedFiles)) {
211
+ trackedResult = { ok: true, files: deps.trackedFiles };
212
+ } else {
213
+ trackedResult = deps.trackedFiles;
214
+ }
215
+
216
+ if (!trackedResult.ok) {
217
+ violations.push({
218
+ kind: 'git_failed',
219
+ path: null,
220
+ detail: trackedResult.error || 'listTrackedSourceFiles() failed',
221
+ });
222
+ return { ok: false, escapes: [], violations, checked: 0 };
223
+ }
224
+
225
+ const trackedFiles = trackedResult.files;
226
+
227
+ if (trackedFiles.length < minTrackedFiles) {
228
+ violations.push({
229
+ kind: 'tracked_count_below_floor',
230
+ path: null,
231
+ detail: `tracked source file count ${trackedFiles.length} is below the floor of ${minTrackedFiles} — a broken or empty git ls-files must never report a vacuous clean run`,
232
+ });
233
+ }
234
+
235
+ const trackedSet = new Set(trackedFiles);
236
+ const allowlist = deps.allowlist === undefined ? loadAllowlist() : deps.allowlist;
237
+
238
+ const seenAllowlistPaths = new Set();
239
+ const allowlistPathSet = new Set();
240
+ for (const entry of allowlist) {
241
+ const entryPath = entry && entry.path;
242
+
243
+ if (seenAllowlistPaths.has(entryPath)) {
244
+ violations.push({
245
+ kind: 'allowlist_duplicate',
246
+ path: entryPath,
247
+ detail: 'path appears more than once in the allowlist',
248
+ });
249
+ } else {
250
+ seenAllowlistPaths.add(entryPath);
251
+ }
252
+ allowlistPathSet.add(entryPath);
253
+
254
+ if (!Object.prototype.hasOwnProperty.call(entry, 'reason')) {
255
+ violations.push({
256
+ kind: 'allowlist_missing_reason',
257
+ path: entryPath,
258
+ detail: 'allowlist entry is missing a "reason" key',
259
+ });
260
+ } else if (typeof entry.reason !== 'string' || entry.reason.trim() === '') {
261
+ violations.push({
262
+ kind: 'allowlist_empty_reason',
263
+ path: entryPath,
264
+ detail: 'allowlist entry "reason" is empty or whitespace-only',
265
+ });
266
+ }
267
+
268
+ if (!trackedSet.has(entryPath)) {
269
+ violations.push({
270
+ kind: 'allowlist_missing_path',
271
+ path: entryPath,
272
+ detail: 'allowlisted path is not a tracked source file',
273
+ });
274
+ }
275
+ }
276
+
277
+ const resolveConfig = deps.resolveConfig || createDefaultResolveConfig();
278
+
279
+ const escapes = [];
280
+ let checked = 0;
281
+
282
+ for (const file of trackedFiles) {
283
+ checked += 1;
284
+ const result = await resolveConfig(file);
285
+ const isAllowlisted = allowlistPathSet.has(file);
286
+
287
+ if (result.ignored) {
288
+ // A recorded ESLint `ignores:` decision — never an escape, regardless
289
+ // of allowlist membership.
290
+ continue;
291
+ }
292
+
293
+ if (result.ruleCount === 0) {
294
+ if (isAllowlisted) continue;
295
+ escapes.push({ path: file });
296
+ violations.push({
297
+ kind: 'uncovered',
298
+ path: file,
299
+ detail: 'resolves to 0 reachable ESLint rules and is not allowlisted',
300
+ });
301
+ } else if (isAllowlisted) {
302
+ violations.push({
303
+ kind: 'allowlist_stale',
304
+ path: file,
305
+ detail: 'allowlisted path now resolves to >=1 ESLint rule — prune the entry, the allowlist only ratchets down',
306
+ });
307
+ }
308
+ }
309
+
310
+ return { ok: violations.length === 0, escapes, violations, checked };
311
+ }
312
+
313
+ if (require.main === module) {
314
+ checkGlobCoverage()
315
+ .then((result) => {
316
+ if (result.violations.length > 0) {
317
+ console.error(
318
+ `lint-eslint-glob-coverage: ${result.violations.length} violation(s) across ${result.checked} tracked source file(s) (${result.escapes.length} uncovered escape(s))`
319
+ );
320
+ for (const v of result.violations) {
321
+ console.error(` [${v.kind}] ${v.path === null ? '(n/a)' : v.path}${v.detail ? ' — ' + v.detail : ''}`);
322
+ }
323
+ process.exitCode = 1;
324
+ } else {
325
+ console.log(`ok lint-eslint-glob-coverage: ${result.checked} tracked source file(s), 0 escapes`);
326
+ }
327
+ })
328
+ .catch((err) => {
329
+ console.error(err && err.stack ? err.stack : String(err));
330
+ process.exitCode = 1;
331
+ });
332
+ }
333
+
334
+ module.exports = {
335
+ checkGlobCoverage,
336
+ listTrackedSourceFiles,
337
+ loadAllowlist,
338
+ SOURCE_EXT_RE,
339
+ MIN_TRACKED_SOURCE_FILES,
340
+ };