@opengsd/gsd-core 1.11.0 → 1.13.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 (498) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.opencode/plugins/gsd-core.js +12 -0
  4. package/agents/gsd-code-fixer.md +1 -1
  5. package/agents/gsd-debug-session-manager.md +1 -1
  6. package/agents/gsd-debugger.md +1 -1
  7. package/agents/gsd-dom-verifier.md +169 -0
  8. package/agents/gsd-eval-auditor.md +1 -1
  9. package/agents/gsd-executor.md +78 -42
  10. package/agents/gsd-framework-selector.md +1 -3
  11. package/agents/gsd-intel-updater.md +1 -1
  12. package/agents/gsd-mempalace-curator.md +0 -1
  13. package/agents/gsd-pattern-mapper.md +11 -0
  14. package/agents/gsd-phase-researcher.md +3 -1
  15. package/agents/gsd-plan-checker.md +91 -112
  16. package/agents/gsd-planner.md +20 -4
  17. package/agents/gsd-project-researcher.md +1 -1
  18. package/agents/gsd-research-synthesizer.md +2 -2
  19. package/agents/gsd-roadmapper.md +15 -11
  20. package/agents/gsd-ui-checker.md +82 -7
  21. package/agents/gsd-ui-researcher.md +70 -3
  22. package/agents/gsd-verifier.md +24 -2
  23. package/bin/install.js +847 -200
  24. package/commands/gsd/discuss-phase.md +1 -1
  25. package/commands/gsd/execute-phase.md +1 -1
  26. package/commands/gsd/import.md +1 -1
  27. package/commands/gsd/ns-workflow.md +2 -1
  28. package/commands/gsd/phase.md +1 -1
  29. package/commands/gsd/quick-batch.md +105 -0
  30. package/commands/gsd/quick.md +8 -4
  31. package/commands/gsd/surface.md +18 -8
  32. package/gsd-core/bin/gsd-tools.cjs +761 -100
  33. package/gsd-core/bin/lib/active-workstream-store.cjs +8 -0
  34. package/gsd-core/bin/lib/adr-parser.cjs +13 -7
  35. package/gsd-core/bin/lib/agent-install-check.cjs +162 -0
  36. package/gsd-core/bin/lib/api-coverage.cjs +30 -9
  37. package/gsd-core/bin/lib/artifacts.cjs +2 -0
  38. package/gsd-core/bin/lib/assumption-delta.cjs +30 -11
  39. package/gsd-core/bin/lib/audit.cjs +163 -41
  40. package/gsd-core/bin/lib/broken-windows.cjs +306 -28
  41. package/gsd-core/bin/lib/capability-activation.cjs +27 -0
  42. package/gsd-core/bin/lib/capability-lock.cjs +10 -4
  43. package/gsd-core/bin/lib/capability-registry.cjs +785 -144
  44. package/gsd-core/bin/lib/capability-state.cjs +25 -4
  45. package/gsd-core/bin/lib/capability-validator.cjs +321 -18
  46. package/gsd-core/bin/lib/capability-writer.cjs +14 -4
  47. package/gsd-core/bin/lib/check-command-router.cjs +229 -6
  48. package/gsd-core/bin/lib/claude-orchestration.cjs +10 -25
  49. package/gsd-core/bin/lib/cli-exit.cjs +496 -10
  50. package/gsd-core/bin/lib/clusters.cjs +1 -0
  51. package/gsd-core/bin/lib/code-review-depth.cjs +288 -0
  52. package/gsd-core/bin/lib/codex-agent-toml.cjs +410 -4
  53. package/gsd-core/bin/lib/command-aliases.cjs +16 -0
  54. package/gsd-core/bin/lib/command-arg-projection.cjs +144 -14
  55. package/gsd-core/bin/lib/command-routing-hub.cjs +31 -2
  56. package/gsd-core/bin/lib/commands.cjs +877 -54
  57. package/gsd-core/bin/lib/complexity-trigger.cjs +26 -6
  58. package/gsd-core/bin/lib/config-loader.cjs +121 -29
  59. package/gsd-core/bin/lib/config.cjs +92 -2
  60. package/gsd-core/bin/lib/configuration.cjs +129 -37
  61. package/gsd-core/bin/lib/core-utils.cjs +118 -14
  62. package/gsd-core/bin/lib/decisions.cjs +213 -1
  63. package/gsd-core/bin/lib/edge-probe.cjs +23 -2
  64. package/gsd-core/bin/lib/estimate-cli.cjs +55 -11
  65. package/gsd-core/bin/lib/exit-code-registry.cjs +98 -0
  66. package/gsd-core/bin/lib/file-overlap-partitioner.cjs +74 -0
  67. package/gsd-core/bin/lib/frontmatter.cjs +975 -326
  68. package/gsd-core/bin/lib/gap-checker.cjs +41 -8
  69. package/gsd-core/bin/lib/git-base-branch.cjs +182 -39
  70. package/gsd-core/bin/lib/health-diagnostic-rules/consistency.cjs +7 -3
  71. package/gsd-core/bin/lib/health-diagnostic-rules/phase-structure.cjs +8 -2
  72. package/gsd-core/bin/lib/health-diagnostic-rules/roadmap-disk-consistency.cjs +60 -14
  73. package/gsd-core/bin/lib/health-diagnostic-rules/state-consistency.cjs +75 -22
  74. package/gsd-core/bin/lib/health-diagnostic-rules/worktree-health.cjs +22 -8
  75. package/gsd-core/bin/lib/health-diagnostic.cjs +23 -3
  76. package/gsd-core/bin/lib/host-integration.cjs +96 -11
  77. package/gsd-core/bin/lib/init-command-router.cjs +132 -21
  78. package/gsd-core/bin/lib/init.cjs +252 -56
  79. package/gsd-core/bin/lib/install-engine.cjs +252 -15
  80. package/gsd-core/bin/lib/install-model-override-resolver.cjs +78 -1
  81. package/gsd-core/bin/lib/install-profiles.cjs +100 -18
  82. package/gsd-core/bin/lib/installer-migration-report.cjs +4 -0
  83. package/gsd-core/bin/lib/installer-migrations/010-antigravity-retire-confighome-artifacts.cjs +169 -0
  84. package/gsd-core/bin/lib/installer-migrations.cjs +10 -7
  85. package/gsd-core/bin/lib/intel.cjs +101 -26
  86. package/gsd-core/bin/lib/io.cjs +195 -15
  87. package/gsd-core/bin/lib/learnings.cjs +85 -14
  88. package/gsd-core/bin/lib/legacy-cleanup.cjs +8 -2
  89. package/gsd-core/bin/lib/loop-resolver.cjs +14 -8
  90. package/gsd-core/bin/lib/markdown-table.cjs +175 -4
  91. package/gsd-core/bin/lib/milestone.cjs +112 -7
  92. package/gsd-core/bin/lib/model-catalog.cjs +177 -19
  93. package/gsd-core/bin/lib/model-resolver.cjs +10 -28
  94. package/gsd-core/bin/lib/onboard-projection.cjs +5 -1
  95. package/gsd-core/bin/lib/phase-command-router.cjs +13 -6
  96. package/gsd-core/bin/lib/phase-estimation.cjs +17 -8
  97. package/gsd-core/bin/lib/phase-id.cjs +321 -13
  98. package/gsd-core/bin/lib/phase-lifecycle.cjs +24 -16
  99. package/gsd-core/bin/lib/phase-locator.cjs +138 -17
  100. package/gsd-core/bin/lib/phase.cjs +1175 -115
  101. package/gsd-core/bin/lib/plan-document.cjs +273 -0
  102. package/gsd-core/bin/lib/plan-scan.cjs +13 -2
  103. package/gsd-core/bin/lib/planning-command-router.cjs +61 -0
  104. package/gsd-core/bin/lib/planning-inspect.cjs +1168 -0
  105. package/gsd-core/bin/lib/planning-snapshot.cjs +165 -34
  106. package/gsd-core/bin/lib/planning-workspace.cjs +159 -28
  107. package/gsd-core/bin/lib/probe-core.cjs +4 -1
  108. package/gsd-core/bin/lib/profile-pipeline-command-router.cjs +50 -7
  109. package/gsd-core/bin/lib/profile-pipeline.cjs +6 -3
  110. package/gsd-core/bin/lib/quick-batch-command-router.cjs +285 -0
  111. package/gsd-core/bin/lib/quick-batch-dispatch.cjs +250 -0
  112. package/gsd-core/bin/lib/quick-batch.cjs +840 -0
  113. package/gsd-core/bin/lib/real-home-guard.cjs +419 -0
  114. package/gsd-core/bin/lib/refactor-trigger-command-router.cjs +71 -45
  115. package/gsd-core/bin/lib/review-lane-descriptor.cjs +62 -14
  116. package/gsd-core/bin/lib/review-lane-invocation.cjs +73 -1
  117. package/gsd-core/bin/lib/review-lane-runner.cjs +136 -10
  118. package/gsd-core/bin/lib/roadmap-command-router.cjs +45 -31
  119. package/gsd-core/bin/lib/roadmap-parser.cjs +577 -41
  120. package/gsd-core/bin/lib/roadmap.cjs +248 -64
  121. package/gsd-core/bin/lib/runtime-artifact-conversion.cjs +329 -41
  122. package/gsd-core/bin/lib/runtime-artifact-install-plan.cjs +16 -17
  123. package/gsd-core/bin/lib/runtime-artifact-layout.cjs +320 -109
  124. package/gsd-core/bin/lib/runtime-hooks-surface.cjs +487 -83
  125. package/gsd-core/bin/lib/runtime-identity.cjs +234 -0
  126. package/gsd-core/bin/lib/runtime-slash.cjs +72 -2
  127. package/gsd-core/bin/lib/shell-command-projection.cjs +75 -8
  128. package/gsd-core/bin/lib/smart-entry.cjs +19 -31
  129. package/gsd-core/bin/lib/spec-section.cjs +12 -7
  130. package/gsd-core/bin/lib/state-command-router.cjs +47 -18
  131. package/gsd-core/bin/lib/state-contract.cjs +359 -0
  132. package/gsd-core/bin/lib/state-document.cjs +216 -5
  133. package/gsd-core/bin/lib/state-md-schema.cjs +231 -0
  134. package/gsd-core/bin/lib/state-transition.cjs +850 -145
  135. package/gsd-core/bin/lib/state.cjs +1629 -287
  136. package/gsd-core/bin/lib/surface.cjs +33 -10
  137. package/gsd-core/bin/lib/task-command-router.cjs +111 -1
  138. package/gsd-core/bin/lib/task-content-resolution.cjs +368 -0
  139. package/gsd-core/bin/lib/tdd-red-evidence.cjs +133 -0
  140. package/gsd-core/bin/lib/teams-status.cjs +4 -1
  141. package/gsd-core/bin/lib/uat-predicate.cjs +58 -20
  142. package/gsd-core/bin/lib/uat.cjs +2542 -387
  143. package/gsd-core/bin/lib/ui-consideration-probe.cjs +9 -1
  144. package/gsd-core/bin/lib/ui-safety-gate.cjs +37 -7
  145. package/gsd-core/bin/lib/unusable-input.cjs +13 -0
  146. package/gsd-core/bin/lib/update-context.cjs +6 -2
  147. package/gsd-core/bin/lib/validate-command-router.cjs +2 -2
  148. package/gsd-core/bin/lib/validate.cjs +230 -12
  149. package/gsd-core/bin/lib/vendor/README.md +43 -5
  150. package/gsd-core/bin/lib/vendor/js-yaml.cjs +3014 -0
  151. package/gsd-core/bin/lib/verification-command-router.cjs +2 -1
  152. package/gsd-core/bin/lib/verification.cjs +287 -13
  153. package/gsd-core/bin/lib/verify-command-grounding.cjs +846 -0
  154. package/gsd-core/bin/lib/verify-command-router.cjs +1 -0
  155. package/gsd-core/bin/lib/verify.cjs +441 -56
  156. package/gsd-core/bin/lib/workstream-inventory.cjs +20 -2
  157. package/gsd-core/bin/lib/workstream-name-policy.cjs +25 -4
  158. package/gsd-core/bin/lib/worktree-base-ref.cjs +66 -12
  159. package/gsd-core/bin/lib/worktree-safety.cjs +185 -21
  160. package/gsd-core/bin/shared/config-defaults.manifest.json +7 -1
  161. package/gsd-core/bin/shared/config-schema.manifest.json +13 -0
  162. package/gsd-core/bin/shared/exit-codes.json +8 -0
  163. package/gsd-core/bin/shared/exit-codes.sh +20 -0
  164. package/gsd-core/bin/shared/model-catalog.json +8 -1
  165. package/gsd-core/bin/verify-reapply-patches.cjs +70 -3
  166. package/gsd-core/references/agent-contracts.md +6 -5
  167. package/gsd-core/references/api-coverage.md +24 -2
  168. package/gsd-core/references/autonomous-smart-discuss.md +3 -3
  169. package/gsd-core/references/checkpoints.md +37 -19
  170. package/gsd-core/references/decimal-phase-calculation.md +5 -5
  171. package/gsd-core/references/edge-probe.md +17 -5
  172. package/gsd-core/references/execute-mvp-tdd.md +18 -18
  173. package/gsd-core/references/execute-phase-between-wave-reset.md +9 -12
  174. package/gsd-core/references/execute-phase-response-language.md +6 -0
  175. package/gsd-core/references/execute-phase-wave-guard.md +11 -9
  176. package/gsd-core/references/executor-examples.md +42 -0
  177. package/gsd-core/references/failing-direction.md +78 -0
  178. package/gsd-core/references/few-shot-examples/plan-checker.md +15 -15
  179. package/gsd-core/references/gate-prompts.md +1 -1
  180. package/gsd-core/references/git-integration.md +5 -5
  181. package/gsd-core/references/git-planning-commit.md +3 -3
  182. package/gsd-core/references/gsd-run-resolver.md +1 -1
  183. package/gsd-core/references/loop-hook-dispatch.md +22 -0
  184. package/gsd-core/references/model-profiles.md +1 -1
  185. package/gsd-core/references/mvp-concepts.md +2 -2
  186. package/gsd-core/references/nyquist-compliance.md +74 -0
  187. package/gsd-core/references/offer-next.md +3 -5
  188. package/gsd-core/references/phase-argument-parsing.md +3 -3
  189. package/gsd-core/references/plan-checker-examples.md +41 -0
  190. package/gsd-core/references/planner-antipatterns.md +25 -0
  191. package/gsd-core/references/planner-chunked.md +5 -1
  192. package/gsd-core/references/planner-coupling.md +42 -0
  193. package/gsd-core/references/planner-failing-direction.md +53 -0
  194. package/gsd-core/references/planner-human-verify-mode.md +15 -1
  195. package/gsd-core/references/planner-quick-batch.md +71 -0
  196. package/gsd-core/references/planner-reviews.md +47 -0
  197. package/gsd-core/references/planner-revision.md +76 -3
  198. package/gsd-core/references/planner-verify-command-grounding.md +17 -0
  199. package/gsd-core/references/planning-config.md +39 -9
  200. package/gsd-core/references/response-language-directive.md +9 -0
  201. package/gsd-core/references/reviewer-instances.md +31 -0
  202. package/gsd-core/references/revision-loop.md +118 -11
  203. package/gsd-core/references/runtime-aware-dispatch.md +1 -1
  204. package/gsd-core/references/tdd.md +15 -12
  205. package/gsd-core/references/ui-brand.md +65 -21
  206. package/gsd-core/references/ui-consideration-probe.md +1 -1
  207. package/gsd-core/references/universal-anti-patterns.md +2 -2
  208. package/gsd-core/references/verifier-evidence-gate.md +160 -0
  209. package/gsd-core/references/verify-command-path-resolvability.md +42 -0
  210. package/gsd-core/references/verify-mvp-mode.md +1 -1
  211. package/gsd-core/references/workstream-flag.md +11 -11
  212. package/gsd-core/templates/README.md +1 -1
  213. package/gsd-core/templates/SECURITY.md +3 -3
  214. package/gsd-core/templates/UI-SPEC.md +25 -3
  215. package/gsd-core/templates/VALIDATION.md +3 -3
  216. package/gsd-core/templates/phase-prompt.md +7 -0
  217. package/gsd-core/templates/state.md +7 -0
  218. package/gsd-core/templates/verification-report.md +5 -0
  219. package/gsd-core/workflows/_runtime-launcher.snippet.sh +1 -1
  220. package/gsd-core/workflows/add-backlog.md +3 -1
  221. package/gsd-core/workflows/add-phase.md +5 -3
  222. package/gsd-core/workflows/add-tests.md +4 -9
  223. package/gsd-core/workflows/add-todo.md +2 -2
  224. package/gsd-core/workflows/ai-integration-phase.md +5 -10
  225. package/gsd-core/workflows/analyze-dependencies.md +2 -0
  226. package/gsd-core/workflows/audit-fix.md +14 -3
  227. package/gsd-core/workflows/audit-milestone.md +11 -9
  228. package/gsd-core/workflows/audit-uat.md +19 -2
  229. package/gsd-core/workflows/autonomous/steps/converge-fail-fast.md +2 -2
  230. package/gsd-core/workflows/autonomous.md +12 -26
  231. package/gsd-core/workflows/check-todos.md +2 -2
  232. package/gsd-core/workflows/cleanup.md +3 -3
  233. package/gsd-core/workflows/code-review/steps/structural-pre-pass.md +16 -14
  234. package/gsd-core/workflows/code-review-fix.md +3 -1
  235. package/gsd-core/workflows/code-review.md +192 -69
  236. package/gsd-core/workflows/complete-milestone.md +28 -14
  237. package/gsd-core/workflows/debug.md +6 -4
  238. package/gsd-core/workflows/diagnose-issues.md +17 -7
  239. package/gsd-core/workflows/discuss-phase/modes/advisor.md +3 -1
  240. package/gsd-core/workflows/discuss-phase/modes/all.md +2 -0
  241. package/gsd-core/workflows/discuss-phase/modes/analyze.md +2 -0
  242. package/gsd-core/workflows/discuss-phase/modes/auto.md +2 -0
  243. package/gsd-core/workflows/discuss-phase/modes/batch.md +2 -0
  244. package/gsd-core/workflows/discuss-phase/modes/chain.md +5 -7
  245. package/gsd-core/workflows/discuss-phase/modes/default.md +2 -0
  246. package/gsd-core/workflows/discuss-phase/modes/power.md +2 -0
  247. package/gsd-core/workflows/discuss-phase/modes/text.md +3 -1
  248. package/gsd-core/workflows/discuss-phase/templates/context.md +2 -0
  249. package/gsd-core/workflows/discuss-phase/templates/discussion-log.md +2 -0
  250. package/gsd-core/workflows/discuss-phase-assumptions/steps/auto-advance-dispatch.md +1 -3
  251. package/gsd-core/workflows/discuss-phase-assumptions.md +3 -3
  252. package/gsd-core/workflows/discuss-phase-power.md +2 -0
  253. package/gsd-core/workflows/discuss-phase.md +2 -2
  254. package/gsd-core/workflows/do.md +46 -19
  255. package/gsd-core/workflows/docs-update.md +6 -5
  256. package/gsd-core/workflows/edit-phase.md +3 -1
  257. package/gsd-core/workflows/eval-review.md +5 -10
  258. package/gsd-core/workflows/execute-phase/steps/codebase-drift-gate.md +3 -1
  259. package/gsd-core/workflows/execute-phase/steps/executor-isolation-dispatch.md +129 -11
  260. package/gsd-core/workflows/execute-phase/steps/gap-closure-artifacts.md +1 -1
  261. package/gsd-core/workflows/execute-phase/steps/partial-wave.md +1 -1
  262. package/gsd-core/workflows/execute-phase/steps/per-plan-executor-routing.md +1 -1
  263. package/gsd-core/workflows/execute-phase/steps/per-plan-worktree-gate.md +29 -5
  264. package/gsd-core/workflows/execute-phase/steps/post-merge-gate.md +2 -2
  265. package/gsd-core/workflows/execute-phase/steps/protected-branch.md +21 -0
  266. package/gsd-core/workflows/execute-phase/steps/regression-gate-run.md +4 -2
  267. package/gsd-core/workflows/execute-phase/steps/tdd-applicability-resolution.md +25 -0
  268. package/gsd-core/workflows/execute-phase/steps/wave-post-gate-hooks.md +39 -0
  269. package/gsd-core/workflows/execute-phase/steps/worktree-recovery-policy.md +2 -0
  270. package/gsd-core/workflows/execute-phase.md +68 -66
  271. package/gsd-core/workflows/execute-plan.md +25 -20
  272. package/gsd-core/workflows/explore.md +3 -1
  273. package/gsd-core/workflows/extract-learnings.md +3 -1
  274. package/gsd-core/workflows/fast.md +8 -2
  275. package/gsd-core/workflows/forensics.md +3 -1
  276. package/gsd-core/workflows/graduation.md +6 -6
  277. package/gsd-core/workflows/health.md +4 -7
  278. package/gsd-core/workflows/help/modes/brief.md +2 -0
  279. package/gsd-core/workflows/help/modes/default.md +2 -0
  280. package/gsd-core/workflows/help/modes/full.md +12 -0
  281. package/gsd-core/workflows/help/modes/topic.md +2 -0
  282. package/gsd-core/workflows/help.md +2 -0
  283. package/gsd-core/workflows/import.md +17 -14
  284. package/gsd-core/workflows/inbox.md +5 -6
  285. package/gsd-core/workflows/ingest-docs.md +45 -12
  286. package/gsd-core/workflows/insert-phase.md +7 -5
  287. package/gsd-core/workflows/list-phase-assumptions.md +2 -0
  288. package/gsd-core/workflows/list-seeds.md +7 -3
  289. package/gsd-core/workflows/list-workspaces.md +3 -1
  290. package/gsd-core/workflows/manager.md +15 -26
  291. package/gsd-core/workflows/map-codebase.md +3 -1
  292. package/gsd-core/workflows/milestone-summary.md +3 -1
  293. package/gsd-core/workflows/mvp-phase.md +3 -3
  294. package/gsd-core/workflows/new-milestone.md +10 -22
  295. package/gsd-core/workflows/new-project/steps/auto-mode-config.md +1 -1
  296. package/gsd-core/workflows/new-project.md +17 -29
  297. package/gsd-core/workflows/new-workspace.md +2 -2
  298. package/gsd-core/workflows/next.md +4 -2
  299. package/gsd-core/workflows/node-repair.md +2 -0
  300. package/gsd-core/workflows/note.md +2 -0
  301. package/gsd-core/workflows/onboard.md +1 -1
  302. package/gsd-core/workflows/pause-work.md +20 -5
  303. package/gsd-core/workflows/plan-phase/steps/adr-ingest-express-path.md +1 -1
  304. package/gsd-core/workflows/plan-phase/steps/chunked-planning-mode.md +100 -18
  305. package/gsd-core/workflows/plan-phase/steps/prd-express-path.md +4 -4
  306. package/gsd-core/workflows/plan-phase/steps/stall-detection-helpers.md +12 -3
  307. package/gsd-core/workflows/plan-phase.md +251 -54
  308. package/gsd-core/workflows/plan-review-convergence.md +148 -19
  309. package/gsd-core/workflows/plant-seed.md +3 -3
  310. package/gsd-core/workflows/pr-branch.md +195 -51
  311. package/gsd-core/workflows/profile-user.md +17 -15
  312. package/gsd-core/workflows/progress/steps/forensic-audit.md +1 -1
  313. package/gsd-core/workflows/progress.md +52 -15
  314. package/gsd-core/workflows/quick/steps/discussion-phase.md +1 -3
  315. package/gsd-core/workflows/quick/steps/plan-checker-loop.md +38 -5
  316. package/gsd-core/workflows/quick/steps/quick-verification.md +2 -4
  317. package/gsd-core/workflows/quick/steps/research-phase.md +5 -7
  318. package/gsd-core/workflows/quick/steps/worktree-pre-dispatch-commit.md +3 -3
  319. package/gsd-core/workflows/quick-batch/steps/batch-init.md +55 -0
  320. package/gsd-core/workflows/quick-batch/steps/completion.md +65 -0
  321. package/gsd-core/workflows/quick-batch/steps/merge-wave.md +100 -0
  322. package/gsd-core/workflows/quick-batch/steps/plan-checker-loop.md +147 -0
  323. package/gsd-core/workflows/quick-batch/steps/planner-wave.md +158 -0
  324. package/gsd-core/workflows/quick-batch/steps/research-phase.md +95 -0
  325. package/gsd-core/workflows/quick-batch/steps/resume-mode.md +49 -0
  326. package/gsd-core/workflows/quick-batch/steps/verification-wave.md +73 -0
  327. package/gsd-core/workflows/quick-batch/steps/worktree-dispatch.md +169 -0
  328. package/gsd-core/workflows/quick-batch.md +203 -0
  329. package/gsd-core/workflows/quick.md +33 -32
  330. package/gsd-core/workflows/reapply-patches.md +2 -0
  331. package/gsd-core/workflows/remove-phase.md +6 -4
  332. package/gsd-core/workflows/remove-workspace.md +3 -3
  333. package/gsd-core/workflows/resume-project.md +14 -14
  334. package/gsd-core/workflows/review.md +404 -21
  335. package/gsd-core/workflows/scan.md +3 -1
  336. package/gsd-core/workflows/section-manifest.json +12 -0
  337. package/gsd-core/workflows/secure-phase.md +3 -3
  338. package/gsd-core/workflows/session-report.md +2 -0
  339. package/gsd-core/workflows/settings-advanced.md +9 -9
  340. package/gsd-core/workflows/settings-integrations.md +66 -32
  341. package/gsd-core/workflows/settings.md +4 -6
  342. package/gsd-core/workflows/ship.md +22 -16
  343. package/gsd-core/workflows/sketch-wrap-up.md +13 -17
  344. package/gsd-core/workflows/sketch.md +13 -19
  345. package/gsd-core/workflows/smart-entry.md +4 -6
  346. package/gsd-core/workflows/spec-phase.md +31 -4
  347. package/gsd-core/workflows/spike-wrap-up.md +9 -11
  348. package/gsd-core/workflows/spike.md +21 -32
  349. package/gsd-core/workflows/stats.md +4 -2
  350. package/gsd-core/workflows/sync-skills.md +13 -5
  351. package/gsd-core/workflows/thread.md +13 -7
  352. package/gsd-core/workflows/transition.md +7 -5
  353. package/gsd-core/workflows/ui-phase.md +36 -21
  354. package/gsd-core/workflows/ui-review.md +7 -11
  355. package/gsd-core/workflows/ultraplan-phase.md +7 -13
  356. package/gsd-core/workflows/undo.md +9 -17
  357. package/gsd-core/workflows/update.md +47 -48
  358. package/gsd-core/workflows/validate-phase.md +3 -3
  359. package/gsd-core/workflows/verify-work/steps/automated-ui-verification.md +25 -1
  360. package/gsd-core/workflows/verify-work/steps/mvp-uat-framing.md +1 -1
  361. package/gsd-core/workflows/verify-work.md +106 -21
  362. package/hooks/dist/gsd-agent-isolation-guard.js +77 -38
  363. package/hooks/dist/gsd-check-update-worker.js +19 -2
  364. package/hooks/dist/gsd-config-reload.js +18 -12
  365. package/hooks/dist/gsd-context-monitor.js +302 -22
  366. package/hooks/dist/gsd-cursor-post-tool.js +3 -1
  367. package/hooks/dist/gsd-cursor-pre-tool.js +3 -1
  368. package/hooks/dist/gsd-cursor-session-start.js +2 -1
  369. package/hooks/dist/gsd-cursor-stop.js +2 -1
  370. package/hooks/dist/gsd-cursor-subagent-start.js +28 -23
  371. package/hooks/dist/gsd-cursor-subagent-stop.js +3 -1
  372. package/hooks/dist/gsd-ensure-canonical-path.js +2 -1
  373. package/hooks/dist/gsd-graphify-update.sh +22 -18
  374. package/hooks/dist/gsd-node-runner.sh +77 -0
  375. package/hooks/dist/gsd-phase-boundary.sh +1 -0
  376. package/hooks/dist/gsd-prompt-guard.js +46 -12
  377. package/hooks/dist/gsd-read-guard.js +18 -7
  378. package/hooks/dist/gsd-read-injection-scanner.js +22 -13
  379. package/hooks/dist/gsd-secret-read-guard.js +1079 -0
  380. package/hooks/dist/gsd-session-state.sh +1 -0
  381. package/hooks/dist/gsd-statusline.js +222 -29
  382. package/hooks/dist/gsd-validate-commit.sh +523 -12
  383. package/hooks/dist/gsd-windsurf-pre-command.js +16 -11
  384. package/hooks/dist/gsd-windsurf-pre-write.js +22 -13
  385. package/hooks/dist/gsd-workflow-guard.js +36 -17
  386. package/hooks/dist/gsd-worktree-path-guard.js +36 -21
  387. package/hooks/dist/gsd-write-guard.js +35 -25
  388. package/hooks/dist/lib/cli-exit.js +560 -0
  389. package/hooks/dist/lib/exit-code-registry.js +98 -0
  390. package/hooks/dist/lib/git-cmd.js +210 -1
  391. package/hooks/dist/lib/git-probe.js +84 -0
  392. package/hooks/dist/lib/hook-exit.js +81 -0
  393. package/hooks/dist/lib/injection-patterns.js +36 -6
  394. package/hooks/dist/managed-hooks-registry.cjs +4 -0
  395. package/hooks/gsd-agent-isolation-guard.js +77 -38
  396. package/hooks/gsd-check-update-worker.js +19 -2
  397. package/hooks/gsd-config-reload.js +18 -12
  398. package/hooks/gsd-context-monitor.js +302 -22
  399. package/hooks/gsd-cursor-post-tool.js +3 -1
  400. package/hooks/gsd-cursor-pre-tool.js +3 -1
  401. package/hooks/gsd-cursor-session-start.js +2 -1
  402. package/hooks/gsd-cursor-stop.js +2 -1
  403. package/hooks/gsd-cursor-subagent-start.js +28 -23
  404. package/hooks/gsd-cursor-subagent-stop.js +3 -1
  405. package/hooks/gsd-ensure-canonical-path.js +2 -1
  406. package/hooks/gsd-graphify-update.sh +22 -18
  407. package/hooks/gsd-node-runner.sh +77 -0
  408. package/hooks/gsd-phase-boundary.sh +1 -0
  409. package/hooks/gsd-prompt-guard.js +46 -12
  410. package/hooks/gsd-read-guard.js +18 -7
  411. package/hooks/gsd-read-injection-scanner.js +22 -13
  412. package/hooks/gsd-secret-read-guard.js +1079 -0
  413. package/hooks/gsd-session-state.sh +1 -0
  414. package/hooks/gsd-statusline.js +222 -29
  415. package/hooks/gsd-validate-commit.sh +523 -12
  416. package/hooks/gsd-windsurf-pre-command.js +16 -11
  417. package/hooks/gsd-windsurf-pre-write.js +22 -13
  418. package/hooks/gsd-workflow-guard.js +36 -17
  419. package/hooks/gsd-worktree-path-guard.js +36 -21
  420. package/hooks/gsd-write-guard.js +35 -25
  421. package/hooks/hooks.json +6 -0
  422. package/hooks/lib/cli-exit.js +560 -0
  423. package/hooks/lib/exit-code-registry.js +98 -0
  424. package/hooks/lib/git-cmd.js +210 -1
  425. package/hooks/lib/git-probe.js +84 -0
  426. package/hooks/lib/hook-exit.js +81 -0
  427. package/hooks/lib/injection-patterns.js +36 -6
  428. package/hooks/managed-hooks-registry.cjs +4 -0
  429. package/package.json +14 -9
  430. package/scripts/base64-scan.sh +74 -12
  431. package/scripts/build-hooks.js +12 -0
  432. package/scripts/check-glossary-refs.cjs +77 -15
  433. package/scripts/check-mutation-score-ratchet.cjs +156 -0
  434. package/scripts/ci-check-job-near-cap.cjs +49 -0
  435. package/scripts/ci-pr-mergeability.cjs +262 -0
  436. package/scripts/ci-test-scope.cjs +52 -12
  437. package/scripts/ci-timeout-report.cjs +230 -0
  438. package/scripts/docs-guard-registry.cjs +406 -0
  439. package/scripts/gen-capability-registry.cjs +8 -6
  440. package/scripts/gen-exit-code-docs.cjs +318 -0
  441. package/scripts/gen-exit-code-registry.cjs +891 -0
  442. package/scripts/gen-features.cjs +836 -0
  443. package/scripts/gen-hooks-cli-exit.cjs +239 -0
  444. package/scripts/gen-install-tree-fixtures.cjs +2 -2
  445. package/scripts/gen-loop-host-contract.cjs +189 -4
  446. package/scripts/gen-scripts-cli-exit.cjs +185 -0
  447. package/scripts/gen-state-md-docs.cjs +727 -0
  448. package/scripts/{test-failure-reasons.cjs → gsd-test-gate-reasons.cjs} +6 -0
  449. package/scripts/lib/ci-job-timing.cjs +72 -0
  450. package/scripts/lib/cli-exit.cjs +546 -44
  451. package/scripts/lib/drift-scan.cjs +32 -2
  452. package/scripts/lib/exit-code-registry.cjs +98 -0
  453. package/scripts/lib/ndjson-reporter.cjs +119 -0
  454. package/scripts/lib/shellcheck-fetch.cjs +247 -0
  455. package/scripts/lint-allow-test-rule-refs.allowlist.json +0 -6
  456. package/scripts/lint-allow-test-rule-refs.effective-ceiling.json +1 -1
  457. package/scripts/lint-allow-test-rule-refs.unverified-ceiling.json +1 -1
  458. package/scripts/lint-docs-guard-registration.cjs +495 -0
  459. package/scripts/lint-docs-guard-registration.exempt-baseline.cjs +198 -0
  460. package/scripts/lint-eslint-glob-coverage.allowlist.json +4 -0
  461. package/scripts/{lint-fix-has-regression-test.cjs → lint-fix-has-regression-tests.cjs} +12 -6
  462. package/scripts/lint-health-diagnostic-rule-table.cjs +65 -8
  463. package/scripts/lint-mutation-test-derivation-drift.cjs +86 -0
  464. package/scripts/lint-phase-enumeration-drift.cjs +45 -14
  465. package/scripts/lint-phase-id-drift.cjs +133 -8
  466. package/scripts/lint-planning-prompt-drift.cjs +38 -1
  467. package/scripts/lint-portable-grep.cjs +176 -0
  468. package/scripts/lint-removed-but-needed.cjs +184 -16
  469. package/scripts/lint-response-language-coverage.cjs +524 -0
  470. package/scripts/lint-seam-enforcement.cjs +182 -0
  471. package/scripts/lint-slug-derivation-drift.cjs +921 -0
  472. package/scripts/lint-source-test-name-collision.cjs +241 -0
  473. package/scripts/lint-state-write-path-drift.cjs +337 -432
  474. package/scripts/lint-test-file-count.allowlist.json +124 -4
  475. package/scripts/lint-test-file-count.cjs +25 -3
  476. package/scripts/lint-unreachable-guard-drift.cjs +51 -64
  477. package/scripts/lint-vendored-deps.cjs +208 -35
  478. package/scripts/lint-workflow-shellcheck-baseline.json +1027 -0
  479. package/scripts/lint-workflow-shellcheck.cjs +614 -0
  480. package/scripts/mutation-matrix.cjs +599 -50
  481. package/scripts/npm-audit-baseline.cjs +376 -0
  482. package/scripts/prompt-injection-scan.sh +83 -14
  483. package/scripts/require-issue-link-policy.cjs +16 -1
  484. package/scripts/secret-scan.sh +75 -13
  485. package/scripts/select-docs-guards.cjs +56 -0
  486. package/scripts/sync-runtime-launcher.cjs +22 -3
  487. package/skills/gsd-discuss-phase/SKILL.md +1 -1
  488. package/skills/gsd-execute-phase/SKILL.md +1 -1
  489. package/skills/gsd-import/SKILL.md +1 -1
  490. package/skills/gsd-ns-workflow/SKILL.md +1 -0
  491. package/skills/gsd-phase/SKILL.md +1 -1
  492. package/skills/gsd-quick/SKILL.md +8 -4
  493. package/skills/gsd-quick-batch/SKILL.md +105 -0
  494. package/skills/gsd-surface/SKILL.md +18 -8
  495. package/vscode/package.json +1 -1
  496. package/bin/lib/ui-safety-gate.cjs +0 -109
  497. package/scripts/lint-emitted-drift-ack.cjs +0 -344
  498. package/scripts/state-write-path-drift-baseline.json +0 -19
@@ -25,6 +25,10 @@ const node_os_1 = __importDefault(require("node:os"));
25
25
  // eslint-disable-next-line @typescript-eslint/no-require-imports
26
26
  const installFsAdapter = require("./install-fs-adapter.cjs");
27
27
  const { installFs, mkInstallTempDir } = installFsAdapter;
28
+ // Reuse the install manifest's existing parser and streamed SHA-256
29
+ // classification instead of deriving a second integrity implementation here.
30
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
31
+ const installerMigrations = require("./installer-migrations.cjs");
28
32
  // eslint-disable-next-line @typescript-eslint/no-require-imports
29
33
  const installProfiles = require("./install-profiles.cjs");
30
34
  const { stageSkillsForProfile, stageAgentsForRuntimeWithConverter, stageSkillsForRuntimeAsSkills, stageCommandsForRuntimeFlat, } = installProfiles;
@@ -36,6 +40,10 @@ const conversionExports = runtimeArtifactConversion;
36
40
  // rather than re-deriving the chain per runtime.
37
41
  // eslint-disable-next-line @typescript-eslint/no-require-imports
38
42
  const installModelOverrideResolver = require("./install-model-override-resolver.cjs");
43
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- export= CommonJS module, same as the sibling resolver import above
44
+ const installEffortResolver = require("./install-effort-resolver.cjs");
45
+ // eslint-disable-next-line @typescript-eslint/no-require-imports -- export= CommonJS module, same as the sibling resolver import above
46
+ const modelCatalog = require("./model-catalog.cjs");
39
47
  const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs");
40
48
  // #2870: `isGlobalScope` centralizes the `scope === 'global'` boolean
41
49
  // projection both kind-builder closures below need at the converters'
@@ -44,127 +52,288 @@ const shell_command_projection_cjs_1 = require("./shell-command-projection.cjs")
44
52
  const install_scope_cjs_1 = require("./install-scope.cjs");
45
53
  // In .cts (CommonJS output) files, `require` is available as a global.
46
54
  const _require = require;
55
+ function requiredRuntimeSurfaceSourceClasses(kinds) {
56
+ const required = new Set();
57
+ for (const kind of kinds) {
58
+ if (kind.kind === 'commands' || kind.kind === 'skills')
59
+ required.add('commands');
60
+ if (kind.kind === 'agents' || kind.kind === 'kimi-agents')
61
+ required.add('agents');
62
+ }
63
+ return required;
64
+ }
47
65
  // ---------------------------------------------------------------------------
48
66
  // Source root finders
49
67
  // ---------------------------------------------------------------------------
50
- /**
51
- * Locate the GSD commands/gsd source directory.
52
- *
53
- * Resolution order:
54
- * 1. If runtimeConfigDir provided, check <runtimeConfigDir>/.gsd-source marker.
55
- * 2. Walk up from __dirname using path.dirname (no literal .. segments).
56
- * 3. Throw a descriptive error if neither succeeds.
57
- */
58
- function findInstallSourceRoot(runtimeConfigDir) {
59
- // Step 1: marker check — reads `<runtimeConfigDir>/.gsd-source`, a path
60
- // under the INSTALL DESTINATION, so this probe goes through the injected
61
- // adapter (installFs()).
62
- if (runtimeConfigDir) {
63
- const markerPath = node_path_1.default.join(runtimeConfigDir, '.gsd-source');
64
- if (installFs().existsSync(markerPath)) {
65
- try {
66
- const src = installFs().readFileSync(markerPath, 'utf8').trim();
67
- if (src && installFs().existsSync(src))
68
- return src;
68
+ function isReadableDirectory(candidate, routed) {
69
+ try {
70
+ const io = routed ? installFs() : node_fs_1.default;
71
+ const stat = io.lstatSync(candidate);
72
+ if (!stat.isDirectory() || stat.isSymbolicLink())
73
+ return false;
74
+ const entries = io.readdirSync(candidate);
75
+ let readableFiles = 0;
76
+ for (const name of entries) {
77
+ const child = node_path_1.default.join(candidate, name);
78
+ const childStat = io.lstatSync(child);
79
+ if (childStat.isSymbolicLink())
80
+ return false;
81
+ if (childStat.isDirectory()) {
82
+ if (!isReadableDirectory(child, routed))
83
+ return false;
84
+ readableFiles += 1;
85
+ }
86
+ else if (childStat.isFile()) {
87
+ if (routed)
88
+ io.readFileSync(child);
89
+ else
90
+ node_fs_1.default.accessSync(child, node_fs_1.default.constants.R_OK);
91
+ readableFiles += 1;
92
+ }
93
+ else {
94
+ return false;
69
95
  }
70
- catch { /* fall through */ }
71
96
  }
97
+ return readableFiles > 0;
72
98
  }
73
- // Step 2: walk up from __dirname to locate the GSD PACKAGE'S OWN source
74
- // tree (commands/gsd/) — this resolves where the installer's own code is
75
- // running FROM, not anything under the install destination, so it is
76
- // deliberately NOT routed through the injected fs adapter (#2874): a fake
77
- // "destination" adapter has no reason to know about the real package's own
78
- // on-disk layout (an injected adapter's store starts empty and is never
79
- // seeded with real repo paths), and routing it through would make this
80
- // resolution unconditionally throw rather than gracefully staging nothing.
81
- //
82
- // Uses `fs.statSync` in a try/catch rather than `fs.existsSync` — this is
83
- // LOAD-BEARING, not a style choice: tests/executed-plan.test.cjs's F2 cases
84
- // poison every method on the ROUTED fs surface (including `existsSync`,
85
- // since installFs()'s REAL_ADAPTER also calls it) to prove nothing on the
86
- // installRuntimeArtifacts call tree reaches real fs. The F2 "nativePlugin
87
- // runtime: pi" test calls this function (via findInstallSourceRoot()) AFTER
88
- // installing that poison, specifically to resolve the pi nativePlugin
89
- // source path against this repo's own real layout — an operation this
90
- // function must still be able to perform even while `existsSync` is
91
- // poisoned, because this Step 2 walk is real-fs-only by design and was
92
- // never meant to be covered by that poison list. `statSync` is not on the
93
- // poisoned surface, so this probe survives; switching back to `existsSync`
94
- // makes that F2 test throw (verified: reverting this to `existsSync` trips
95
- // the poison and breaks the pi nativePlugin case).
96
- let dir = __dirname;
97
- for (let i = 0; i < 6; i++) {
98
- const candidate = node_path_1.default.join(dir, 'commands', 'gsd');
99
- try {
100
- node_fs_1.default.statSync(candidate);
101
- return candidate;
99
+ catch {
100
+ return false;
101
+ }
102
+ }
103
+ function isPhysicallyConfinedTo(root, candidate) {
104
+ try {
105
+ const physicalRoot = installFs().realpathSync(root);
106
+ const physicalCandidate = installFs().realpathSync(candidate);
107
+ return physicalCandidate === physicalRoot || physicalCandidate.startsWith(physicalRoot + node_path_1.default.sep);
108
+ }
109
+ catch {
110
+ return false;
111
+ }
112
+ }
113
+ function installedManifestIsComplete(runtimeConfigDir, required) {
114
+ // This synchronous admission check binds provider selection to the corpus
115
+ // observed here. Same-user mutation after resolution is outside #4132's
116
+ // threat model and would require a broader snapshot/transaction design.
117
+ const io = installFs();
118
+ const manifestPath = node_path_1.default.join(runtimeConfigDir, 'gsd-file-manifest.json');
119
+ if (!io.existsSync(manifestPath))
120
+ return false;
121
+ if (!isPhysicallyConfinedTo(runtimeConfigDir, manifestPath))
122
+ return false;
123
+ try {
124
+ const manifest = installerMigrations.readInstallManifest(runtimeConfigDir);
125
+ if (manifest.manifestVersion === null)
126
+ return false;
127
+ const keys = Object.keys(manifest.files);
128
+ const prefixes = [];
129
+ if (required.has('commands'))
130
+ prefixes.push('gsd-core/commands/gsd/');
131
+ if (required.has('agents'))
132
+ prefixes.push('gsd-core/agents/');
133
+ for (const prefix of prefixes) {
134
+ const expected = keys.filter((key) => key.startsWith(prefix));
135
+ if (expected.length === 0)
136
+ return false;
137
+ const expectedSet = new Set(expected);
138
+ const corpusRoot = node_path_1.default.resolve(runtimeConfigDir, ...prefix.slice(0, -1).split('/'));
139
+ if (!isPhysicallyConfinedTo(runtimeConfigDir, corpusRoot))
140
+ return false;
141
+ let actualFiles = 0;
142
+ const visit = (dir) => {
143
+ for (const name of io.readdirSync(dir)) {
144
+ const candidate = node_path_1.default.join(dir, name);
145
+ const stat = io.lstatSync(candidate);
146
+ if (stat.isSymbolicLink())
147
+ return false;
148
+ if (stat.isDirectory()) {
149
+ if (!visit(candidate))
150
+ return false;
151
+ }
152
+ else if (stat.isFile()) {
153
+ const relative = node_path_1.default.relative(corpusRoot, candidate).split(node_path_1.default.sep).join('/');
154
+ if (!expectedSet.has(prefix + relative))
155
+ return false;
156
+ actualFiles += 1;
157
+ }
158
+ else {
159
+ return false;
160
+ }
161
+ }
162
+ return true;
163
+ };
164
+ if (!visit(corpusRoot) || actualFiles !== expected.length)
165
+ return false;
166
+ for (const key of expected) {
167
+ const parts = key.split('/');
168
+ if (parts.some((part) => part === '' || part === '.' || part === '..'))
169
+ return false;
170
+ const candidate = node_path_1.default.resolve(runtimeConfigDir, ...parts);
171
+ const root = node_path_1.default.resolve(runtimeConfigDir);
172
+ if (!candidate.startsWith(root + node_path_1.default.sep))
173
+ return false;
174
+ const stat = io.lstatSync(candidate);
175
+ if (!stat.isFile() || stat.isSymbolicLink())
176
+ return false;
177
+ if (installerMigrations.classifyArtifact(runtimeConfigDir, key, manifest).classification !== 'managed-pristine') {
178
+ return false;
179
+ }
180
+ }
102
181
  }
103
- catch { /* not here — keep walking up */ }
104
- const parent = node_path_1.default.dirname(dir);
105
- if (parent === dir)
106
- break;
107
- dir = parent;
182
+ return true;
183
+ }
184
+ catch {
185
+ return false;
108
186
  }
109
- throw new Error(`findInstallSourceRoot: could not locate commands/gsd from ${__dirname}`);
110
187
  }
111
- /**
112
- * Locate the GSD agents source directory.
113
- *
114
- * Resolution order:
115
- * 1. If runtimeConfigDir provided, check <runtimeConfigDir>/.gsd-source marker.
116
- * 2. Walk up from __dirname using path.dirname (no literal .. segments).
117
- * 3. Throw a descriptive error if neither succeeds.
118
- */
119
- function findAgentsSourceRoot(runtimeConfigDir) {
120
- // Step 1: marker check (destination-relative — routed through installFs()).
121
- if (runtimeConfigDir) {
122
- const markerPath = node_path_1.default.join(runtimeConfigDir, '.gsd-source');
123
- if (installFs().existsSync(markerPath)) {
124
- try {
125
- const src = installFs().readFileSync(markerPath, 'utf8').trim();
126
- if (src && installFs().existsSync(src)) {
127
- // Marker points to commands/gsd; agents/ is a sibling of commands/
128
- const agentsCandidate = node_path_1.default.resolve(node_path_1.default.dirname(src), '..', 'agents');
129
- if (installFs().existsSync(agentsCandidate))
130
- return agentsCandidate;
188
+ function providerHasRequiredClasses(provider, required, routed, runtimeConfigDir) {
189
+ if (provider.kind === 'installed' && runtimeConfigDir) {
190
+ return installedManifestIsComplete(runtimeConfigDir, required);
191
+ }
192
+ return (!required.has('commands') || isReadableDirectory(provider.commandsRoot, routed)) &&
193
+ (!required.has('agents') || isReadableDirectory(provider.agentsRoot, routed));
194
+ }
195
+ function providersShareRequiredRoots(left, right, required) {
196
+ const leftFs = left.kind === 'package' ? node_fs_1.default : installFs();
197
+ const rightFs = right.kind === 'package' ? node_fs_1.default : installFs();
198
+ const physicalRootsOverlap = (leftRoot, rightRoot) => {
199
+ const canonicalize = (io, root) => {
200
+ let existing = node_path_1.default.resolve(root);
201
+ const missingSegments = [];
202
+ while (true) {
203
+ try {
204
+ return node_path_1.default.resolve(io.realpathSync(existing), ...missingSegments);
205
+ }
206
+ catch (error) {
207
+ if (error.code !== 'ENOENT')
208
+ return null;
209
+ const parent = node_path_1.default.dirname(existing);
210
+ if (parent === existing)
211
+ return null;
212
+ missingSegments.unshift(node_path_1.default.basename(existing));
213
+ existing = parent;
131
214
  }
132
215
  }
133
- catch { /* fall through */ }
216
+ };
217
+ const overlap = (leftPath, rightPath) => {
218
+ const relative = node_path_1.default.relative(leftPath, rightPath);
219
+ return relative === '' ||
220
+ (relative !== '..' && !relative.startsWith(`..${node_path_1.default.sep}`) && !node_path_1.default.isAbsolute(relative));
221
+ };
222
+ const physicalLeft = canonicalize(leftFs, leftRoot);
223
+ const physicalRight = canonicalize(rightFs, rightRoot);
224
+ if (!physicalLeft || !physicalRight)
225
+ return true;
226
+ return overlap(physicalLeft, physicalRight) || overlap(physicalRight, physicalLeft);
227
+ };
228
+ return (required.has('commands') && physicalRootsOverlap(left.commandsRoot, right.commandsRoot)) ||
229
+ (required.has('agents') && physicalRootsOverlap(left.agentsRoot, right.agentsRoot));
230
+ }
231
+ function markerProvider(runtimeConfigDir) {
232
+ const markerPath = node_path_1.default.join(runtimeConfigDir, '.gsd-source');
233
+ try {
234
+ if (!installFs().existsSync(markerPath))
235
+ return null;
236
+ const markerStat = installFs().lstatSync(markerPath);
237
+ if (!markerStat.isFile() || markerStat.isSymbolicLink())
238
+ return null;
239
+ const commandsRoot = installFs().readFileSync(markerPath, 'utf8').trim();
240
+ if (!commandsRoot)
241
+ return null;
242
+ // A marker written by the installer may point at this process's executing
243
+ // package. Preserve package-source IO on real fs so the existing injected
244
+ // destination adapter remains destination-only (#2874).
245
+ const packaged = packageProvider(new Set(['commands']));
246
+ if (packaged && node_path_1.default.resolve(commandsRoot) === node_path_1.default.resolve(packaged.commandsRoot)) {
247
+ return packaged;
134
248
  }
249
+ return {
250
+ kind: 'marker',
251
+ commandsRoot,
252
+ agentsRoot: node_path_1.default.resolve(node_path_1.default.dirname(commandsRoot), '..', 'agents'),
253
+ };
135
254
  }
136
- // Step 2: walk up from __dirname — locates THIS package's own agents/
137
- // source tree, not the install destination. See findInstallSourceRoot's
138
- // Step 2 comment (#2874) for why this stays unrouted, real-fs-only, and why
139
- // it uses `statSync` rather than `existsSync` (load-bearing against F2's
140
- // poison of the routed fs surface, not a style choice).
255
+ catch {
256
+ return null;
257
+ }
258
+ }
259
+ function packageProvider(required) {
260
+ // Package-source IO deliberately stays on real fs; injected install adapters
261
+ // model destinations, not the executing package tree (#2874).
141
262
  let dir = __dirname;
142
263
  for (let i = 0; i < 6; i++) {
143
- const candidate = node_path_1.default.join(dir, 'agents');
144
- try {
145
- node_fs_1.default.statSync(candidate);
264
+ const candidate = {
265
+ kind: 'package',
266
+ commandsRoot: node_path_1.default.join(dir, 'commands', 'gsd'),
267
+ agentsRoot: node_path_1.default.join(dir, 'agents'),
268
+ };
269
+ if (providerHasRequiredClasses(candidate, required, false))
146
270
  return candidate;
147
- }
148
- catch { /* not here — keep walking up */ }
149
271
  const parent = node_path_1.default.dirname(dir);
150
272
  if (parent === dir)
151
273
  break;
152
274
  dir = parent;
153
275
  }
154
- throw new Error(`findAgentsSourceRoot: could not locate agents/ from ${__dirname}`);
276
+ return null;
277
+ }
278
+ /**
279
+ * Select one complete source provider for an entire resolved layout.
280
+ * Provider mixing is forbidden: a skills+agents layout cannot take commands
281
+ * from one package version and agents from another.
282
+ */
283
+ function resolveSourceProvider(runtimeConfigDir, requiredClasses, scope = 'global', authority = 'compatible') {
284
+ const required = new Set(requiredClasses);
285
+ let rejectedInstalled = null;
286
+ if (required.size === 0) {
287
+ return { kind: 'package', commandsRoot: '', agentsRoot: '' };
288
+ }
289
+ if (runtimeConfigDir && scope === 'global') {
290
+ const installed = {
291
+ kind: 'installed',
292
+ commandsRoot: node_path_1.default.join(runtimeConfigDir, 'gsd-core', 'commands', 'gsd'),
293
+ agentsRoot: node_path_1.default.join(runtimeConfigDir, 'gsd-core', 'agents'),
294
+ };
295
+ if (providerHasRequiredClasses(installed, required, true, runtimeConfigDir))
296
+ return installed;
297
+ rejectedInstalled = installed;
298
+ const marker = markerProvider(runtimeConfigDir);
299
+ if (marker && !providersShareRequiredRoots(marker, installed, required) && providerHasRequiredClasses(marker, required, marker.kind !== 'package')) {
300
+ return marker;
301
+ }
302
+ }
303
+ else if (runtimeConfigDir) {
304
+ const marker = markerProvider(runtimeConfigDir);
305
+ if (marker && providerHasRequiredClasses(marker, required, marker.kind !== 'package'))
306
+ return marker;
307
+ }
308
+ if (authority === 'compatible') {
309
+ const packaged = packageProvider(required);
310
+ if (packaged &&
311
+ (!rejectedInstalled || !providersShareRequiredRoots(packaged, rejectedInstalled, required))) {
312
+ return packaged;
313
+ }
314
+ }
315
+ throw new Error(`Runtime Surface source is unavailable or incomplete for ${[...required].sort().join('+')}; ` +
316
+ 'install or upgrade gsd-core before materializing this surface.');
317
+ }
318
+ function sourceRootFor(context, sourceClass) {
319
+ context.provider ??= resolveSourceProvider(context.runtimeConfigDir, context.required, context.scope, context.authority);
320
+ return sourceClass === 'commands' ? context.provider.commandsRoot : context.provider.agentsRoot;
321
+ }
322
+ function findInstallSourceRoot(runtimeConfigDir) {
323
+ return resolveSourceProvider(runtimeConfigDir, ['commands']).commandsRoot;
155
324
  }
156
325
  // ---------------------------------------------------------------------------
157
326
  // Layout table builders
158
327
  // ---------------------------------------------------------------------------
159
- function commandsKind(destSubpath, prefix, configDir) {
328
+ function commandsKind(destSubpath, prefix, sourceContext) {
160
329
  return {
161
330
  kind: 'commands',
162
331
  destSubpath,
163
332
  prefix,
164
- stage: (resolved) => stageSkillsForProfile(findInstallSourceRoot(configDir), resolved),
333
+ stage: (resolved) => stageSkillsForProfile(sourceRootFor(sourceContext, 'commands'), resolved),
165
334
  };
166
335
  }
167
- function agentsKind(destSubpath, prefix, configDir) {
336
+ function agentsKind(destSubpath, prefix, configDir, sourceContext) {
168
337
  return {
169
338
  kind: 'agents',
170
339
  destSubpath,
@@ -187,7 +356,7 @@ function agentsKind(destSubpath, prefix, configDir) {
187
356
  // signature silently dropped the second arg every caller already passed —
188
357
  // a caller with NO agentCtx in scope is unaffected (row I2: converter-only,
189
358
  // as today), matching stageAgentsForRuntimeWithConverter's own contract.
190
- stage: (resolved, agentCtx) => stageAgentsForRuntimeWithConverter(findAgentsSourceRoot(configDir), resolved, (content) => content, false, agentCtx),
359
+ stage: (resolved, agentCtx) => stageAgentsForRuntimeWithConverter(sourceRootFor(sourceContext, 'agents'), resolved, (content) => content, false, agentCtx?.runtime ? agentCtx : undefined),
191
360
  };
192
361
  }
193
362
  /**
@@ -319,7 +488,7 @@ function _resolveNamedConverter(converterName, kindLabel) {
319
488
  * @param converterName name of converter function in Runtime Artifact Conversion exports
320
489
  * @param configDir runtime config dir (for .gsd-source marker resolution)
321
490
  */
322
- function convertedAgentsKind(destSubpath, prefix, converterName, configDir, scope = 'global') {
491
+ function convertedAgentsKind(destSubpath, prefix, converterName, configDir, sourceContext, scope) {
323
492
  return {
324
493
  kind: 'agents',
325
494
  destSubpath,
@@ -346,11 +515,40 @@ function convertedAgentsKind(destSubpath, prefix, converterName, configDir, scop
346
515
  const overrideTargetDir = agentCtx?.targetDir ?? configDir;
347
516
  const modelOverrides = installModelOverrideResolver.readGsdEffectiveModelOverrides(overrideTargetDir);
348
517
  const runtimeResolver = installModelOverrideResolver.readGsdRuntimeProfileResolver(overrideTargetDir);
518
+ // #3706: the resolved reasoning effort, threaded exactly as the model is —
519
+ // config read ONCE per stage(), per-agent value resolved per file.
520
+ //
521
+ // Gated on the effort config being PRESENT, not on a value coming back.
522
+ // `resolveInstallTimeEffort` always returns something (measured: 'high'
523
+ // even with no project config and no effort block), so "skip when
524
+ // resolution yields no value" has no trigger and would stamp `variant:`
525
+ // into every generated agent file for every existing install. OpenCode's
526
+ // built-in variant sets are provider-specific upstream (Anthropic ships
527
+ // only `high`/`max`), so a level GSD resolved is not guaranteed to name a
528
+ // variant the user's provider actually has — emitting one unasked-for is
529
+ // the risk this gate avoids. #1156's rule for `model: inherit` is the
530
+ // precedent: do not emit a key the runtime may not understand.
531
+ //
532
+ // OpenCode only; the kilo converter ignores the field (no EFFORT_ARGV.kilo).
533
+ const effortConfig = converterName === 'convertClaudeToOpencodeFrontmatter'
534
+ ? installEffortResolver.readGsdEffectiveEffortConfig(overrideTargetDir)
535
+ : null;
349
536
  converter = (content, _isGlobal, meta) => {
350
537
  const modelOverride = meta
351
538
  ? installModelOverrideResolver.resolveAgentModelOverride(meta.agentName, modelOverrides, runtimeResolver)
352
539
  : null;
353
- return rawConverter(content, { isAgent: true, modelOverride });
540
+ // The universal level is NOT emitted raw. `clampEffortForHost` is the
541
+ // declared OpenCode effort capability (EFFORT_ARGV.opencode: its own
542
+ // `supported` set + `clamp`), and it is what rejects a level that is
543
+ // not a wire value — most importantly `inherit`, which per #3533 (10d)
544
+ // means "omit the key and follow the host default" and must never be
545
+ // written literally. Anything unsupported clamps to null, which omits
546
+ // the key rather than inventing one.
547
+ const universal = effortConfig && meta
548
+ ? installEffortResolver.resolveInstallTimeEffort(effortConfig, meta.agentName)
549
+ : null;
550
+ const variant = universal ? modelCatalog.clampEffortForHost('opencode', universal) : null;
551
+ return rawConverter(content, { isAgent: true, modelOverride, variant });
354
552
  };
355
553
  }
356
554
  else {
@@ -363,20 +561,20 @@ function convertedAgentsKind(destSubpath, prefix, converterName, configDir, scop
363
561
  // ADR-1235 §1: when agentCtx is provided (by createRuntimeArtifactInstallPlan
364
562
  // for descriptor-driven runtimes), thread it through so stageAgentsForRuntimeWithConverter
365
563
  // can apply the full pre-converter + post-converter sequence in the correct order.
366
- return stageAgentsForRuntimeWithConverter(findAgentsSourceRoot(configDir), resolved, converter, (0, install_scope_cjs_1.isGlobalScope)(scope), agentCtx);
564
+ return stageAgentsForRuntimeWithConverter(sourceRootFor(sourceContext, 'agents'), resolved, converter, (0, install_scope_cjs_1.isGlobalScope)(scope), agentCtx?.runtime ? agentCtx : undefined);
367
565
  },
368
566
  };
369
567
  }
370
- function kimiAgentsKind(destSubpath, prefix, configDir) {
568
+ function kimiAgentsKind(destSubpath, prefix, configDir, sourceContext) {
371
569
  return {
372
570
  kind: 'kimi-agents',
373
571
  destSubpath,
374
572
  prefix,
375
- stage: (resolved) => {
573
+ stage: (resolved, agentCtx) => {
376
574
  const buildKimiAgentArtifacts = conversionExports['buildKimiAgentArtifacts'];
377
575
  // #2995: compose at staging (identity converter) so the readFileSync below
378
576
  // sees marker-free content — same single composing stager as agentsKind.
379
- const stagedAgents = stageAgentsForRuntimeWithConverter(findAgentsSourceRoot(configDir), resolved, (content) => content);
577
+ const stagedAgents = stageAgentsForRuntimeWithConverter(sourceRootFor(sourceContext, 'agents'), resolved, (content) => content, false, agentCtx);
380
578
  const subagents = [];
381
579
  if (installFs().existsSync(stagedAgents)) {
382
580
  for (const entry of installFs().readdirSync(stagedAgents, { withFileTypes: true })) {
@@ -423,7 +621,7 @@ function kimiAgentsKind(destSubpath, prefix, configDir) {
423
621
  * their declaring capId at staging time. Absent -> stage() stages
424
622
  * nothing third-party (fail closed).
425
623
  */
426
- function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nested = false, scope = 'global', capabilityRegistry) {
624
+ function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nested, scope, sourceContext, capabilityRegistry) {
427
625
  return {
428
626
  kind: 'skills',
429
627
  destSubpath,
@@ -456,7 +654,7 @@ function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nest
456
654
  // it must run AFTER it instead, once the `@`-include is in its final
457
655
  // rewritten shape.
458
656
  const wrappedConverter = (content, skillName) => realConverter(content, skillName, runtime, cmdNames, isGlobal);
459
- return stageSkillsForRuntimeAsSkills(findInstallSourceRoot(configDir), resolved, wrappedConverter, prefix, nested, capabilityRegistry);
657
+ return stageSkillsForRuntimeAsSkills(sourceRootFor(sourceContext, 'commands'), resolved, wrappedConverter, prefix, nested, capabilityRegistry);
460
658
  },
461
659
  };
462
660
  }
@@ -476,14 +674,14 @@ function skillsKind(destSubpath, prefix, converterName, runtime, configDir, nest
476
674
  * @param converterName name of converter function in Runtime Artifact Conversion exports
477
675
  * @param configDir runtime config dir (for .gsd-source marker resolution)
478
676
  */
479
- function convertedCommandsKind(destSubpath, prefix, converterName, configDir) {
677
+ function convertedCommandsKind(destSubpath, prefix, converterName, sourceContext) {
480
678
  return {
481
679
  kind: 'commands',
482
680
  destSubpath,
483
681
  prefix,
484
682
  stage: (resolved) => {
485
683
  const converter = _resolveNamedConverter(converterName, 'commands');
486
- return stageCommandsForRuntimeFlat(findInstallSourceRoot(configDir), resolved, converter, prefix);
684
+ return stageCommandsForRuntimeFlat(sourceRootFor(sourceContext, 'commands'), resolved, converter, prefix);
487
685
  },
488
686
  };
489
687
  }
@@ -494,29 +692,29 @@ function getRegistry() {
494
692
  * Map a single ArtifactKindDescriptor entry to an ArtifactKind using the
495
693
  * matching builder function. Mirrors the hand-built calls in the old switch.
496
694
  */
497
- function dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry) {
695
+ function dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry, sourceContext) {
498
696
  const { kind, destSubpath, prefix, nesting, converter } = entry;
499
697
  const nested = nesting === 'nested';
500
698
  let result;
501
699
  switch (kind) {
502
700
  case 'commands':
503
701
  result = converter == null
504
- ? commandsKind(destSubpath, prefix, configDir)
505
- : convertedCommandsKind(destSubpath, prefix, converter, configDir);
702
+ ? commandsKind(destSubpath, prefix, sourceContext)
703
+ : convertedCommandsKind(destSubpath, prefix, converter, sourceContext);
506
704
  break;
507
705
  case 'agents':
508
706
  result = converter == null
509
- ? agentsKind(destSubpath, prefix, configDir)
510
- : convertedAgentsKind(destSubpath, prefix, converter, configDir, scope);
707
+ ? agentsKind(destSubpath, prefix, configDir, sourceContext)
708
+ : convertedAgentsKind(destSubpath, prefix, converter, configDir, sourceContext, scope);
511
709
  break;
512
710
  case 'skills':
513
711
  if (converter == null) {
514
712
  throw new TypeError(`resolveRuntimeArtifactLayout: skills entry for '${runtime}' has converter=null (converter is required for skills)`);
515
713
  }
516
- result = skillsKind(destSubpath, prefix, converter, runtime, configDir, nested, scope, capabilityRegistry);
714
+ result = skillsKind(destSubpath, prefix, converter, runtime, configDir, nested, scope, sourceContext, capabilityRegistry);
517
715
  break;
518
716
  case 'kimi-agents':
519
- result = kimiAgentsKind(destSubpath, prefix, configDir);
717
+ result = kimiAgentsKind(destSubpath, prefix, configDir, sourceContext);
520
718
  break;
521
719
  default:
522
720
  throw new TypeError(`resolveRuntimeArtifactLayout: unknown kind '${kind}' in descriptor for runtime '${runtime}'`);
@@ -561,7 +759,20 @@ function resolveRuntimeArtifactLayoutFromRegistry(registry, runtime, configDir,
561
759
  throw new TypeError(`Unknown runtime: '${runtime}' — add to runtime-artifact-layout.cjs table`);
562
760
  }
563
761
  const entries = desc[scope] ?? [];
564
- const kinds = entries.map((entry) => dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry));
762
+ const required = requiredRuntimeSurfaceSourceClasses(entries);
763
+ // Stage closures share one lazy source-resolution context, so the first kind
764
+ // to stage selects and caches one complete provider for every required source
765
+ // class. Global layouts accept only installed or marker providers; the
766
+ // installer owns its private package fallback by retrying through a transient
767
+ // compatibility marker after source resolution fails. Local layouts retain
768
+ // compatible marker/package resolution and never provision the global corpus.
769
+ const sourceContext = {
770
+ runtimeConfigDir: configDir,
771
+ scope,
772
+ required,
773
+ authority: scope === 'local' ? 'compatible' : 'runtime',
774
+ };
775
+ const kinds = entries.map((entry) => dispatchKindEntry(entry, runtime, configDir, scope, capabilityRegistry, sourceContext));
565
776
  return { runtime, configDir, scope, kinds };
566
777
  }
567
778
  function getTriggerRegistry() {