@opengsd/gsd-pi 1.3.0 → 1.4.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 (912) hide show
  1. package/README.md +10 -10
  2. package/dist/cli.js +32 -4
  3. package/dist/headless-answers.js +1 -1
  4. package/dist/headless-context.js +0 -1
  5. package/dist/headless-ui.d.ts +1 -1
  6. package/dist/headless-ui.js +1 -1
  7. package/dist/headless.js +1 -1
  8. package/dist/help-text.js +29 -0
  9. package/dist/hermes-integration-install.d.ts +17 -0
  10. package/dist/hermes-integration-install.js +199 -0
  11. package/dist/jiti-workspace-aliases.d.ts +11 -2
  12. package/dist/jiti-workspace-aliases.js +19 -3
  13. package/dist/read-cli.d.ts +23 -0
  14. package/dist/read-cli.js +90 -0
  15. package/dist/resource-loader.d.ts +3 -3
  16. package/dist/resource-loader.js +4 -13
  17. package/dist/resources/.managed-resources-content-hash +1 -1
  18. package/dist/resources/GSD-WORKFLOW.md +22 -22
  19. package/dist/resources/extensions/claude-code-cli/index.js +7 -1
  20. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  21. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +84 -22
  22. package/dist/resources/extensions/google-cli/stream-adapter.js +82 -15
  23. package/dist/resources/extensions/gsd/artifact-verification.js +427 -0
  24. package/dist/resources/extensions/gsd/auto/dispatch-history.js +6 -1
  25. package/dist/resources/extensions/gsd/auto/loop.js +67 -2
  26. package/dist/resources/extensions/gsd/auto/orchestrator.js +28 -10
  27. package/dist/resources/extensions/gsd/auto/session.js +11 -0
  28. package/dist/resources/extensions/gsd/auto/verification-retry-policy.js +1 -1
  29. package/dist/resources/extensions/gsd/auto/workflow-kernel.js +15 -1
  30. package/dist/resources/extensions/gsd/auto-artifact-paths.js +108 -19
  31. package/dist/resources/extensions/gsd/auto-budget.js +5 -1
  32. package/dist/resources/extensions/gsd/auto-dispatch.js +62 -27
  33. package/dist/resources/extensions/gsd/auto-model-selection.js +8 -5
  34. package/dist/resources/extensions/gsd/auto-post-unit.js +28 -22
  35. package/dist/resources/extensions/gsd/auto-prompts.js +68 -43
  36. package/dist/resources/extensions/gsd/auto-recovery.js +14 -483
  37. package/dist/resources/extensions/gsd/auto-runtime-state.js +17 -5
  38. package/dist/resources/extensions/gsd/auto-start.js +56 -30
  39. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +3 -3
  40. package/dist/resources/extensions/gsd/auto-verification.js +10 -4
  41. package/dist/resources/extensions/gsd/auto-worktree.js +117 -91
  42. package/dist/resources/extensions/gsd/auto.js +40 -15
  43. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +141 -65
  44. package/dist/resources/extensions/gsd/bootstrap/core-session-tools.js +39 -0
  45. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +11 -5
  46. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +2 -0
  47. package/dist/resources/extensions/gsd/bootstrap/fallback-continuation.js +25 -0
  48. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +23 -1
  49. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +117 -27
  50. package/dist/resources/extensions/gsd/bootstrap/system-context.js +190 -43
  51. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +96 -10
  52. package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +22 -3
  53. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +73 -16
  54. package/dist/resources/extensions/gsd/closeout-consistency-gate.js +95 -5
  55. package/dist/resources/extensions/gsd/codebase-generator.js +5 -8
  56. package/dist/resources/extensions/gsd/commands/catalog.js +6 -0
  57. package/dist/resources/extensions/gsd/commands/dispatcher.js +3 -0
  58. package/dist/resources/extensions/gsd/commands/gsd-core-aliases-handler.js +39 -0
  59. package/dist/resources/extensions/gsd/commands/gsd-core-aliases.js +44 -0
  60. package/dist/resources/extensions/gsd/commands/handlers/auto.js +1 -1
  61. package/dist/resources/extensions/gsd/commands/handlers/core.js +30 -0
  62. package/dist/resources/extensions/gsd/commands/handlers/ops.js +225 -1
  63. package/dist/resources/extensions/gsd/commands-cmux.js +3 -1
  64. package/dist/resources/extensions/gsd/commands-context.js +19 -1
  65. package/dist/resources/extensions/gsd/commands-gsd-core.js +868 -0
  66. package/dist/resources/extensions/gsd/commands-handlers.js +67 -1
  67. package/dist/resources/extensions/gsd/commands-maintenance.js +79 -2
  68. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +23 -12
  69. package/dist/resources/extensions/gsd/commands-usage.js +1 -1
  70. package/dist/resources/extensions/gsd/commands-verdict.js +17 -11
  71. package/dist/resources/extensions/gsd/commands-worktree.js +12 -10
  72. package/dist/resources/extensions/gsd/compat/compat-marker.js +172 -0
  73. package/dist/resources/extensions/gsd/compat/index.js +3 -0
  74. package/dist/resources/extensions/gsd/compat/planning-compat.js +142 -0
  75. package/dist/resources/extensions/gsd/config-overlay.js +2 -2
  76. package/dist/resources/extensions/gsd/consent-question.js +12 -0
  77. package/dist/resources/extensions/gsd/consent-verdict.js +10 -0
  78. package/dist/resources/extensions/gsd/dashboard-overlay.js +71 -6
  79. package/dist/resources/extensions/gsd/db/engine.js +31 -1
  80. package/dist/resources/extensions/gsd/db/queries.js +114 -0
  81. package/dist/resources/extensions/gsd/db/unit-dispatches.js +22 -1
  82. package/dist/resources/extensions/gsd/db-memory-fts-schema.js +34 -0
  83. package/dist/resources/extensions/gsd/db-workspace.js +68 -4
  84. package/dist/resources/extensions/gsd/delegation-policy.js +1 -1
  85. package/dist/resources/extensions/gsd/discussion-handoff.js +9 -5
  86. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  87. package/dist/resources/extensions/gsd/doctor-engine-checks.js +192 -4
  88. package/dist/resources/extensions/gsd/doctor-git-checks.js +25 -3
  89. package/dist/resources/extensions/gsd/doctor-providers.js +92 -8
  90. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +5 -15
  91. package/dist/resources/extensions/gsd/doctor.js +28 -7
  92. package/dist/resources/extensions/gsd/error-classifier.js +13 -1
  93. package/dist/resources/extensions/gsd/escalation.js +11 -4
  94. package/dist/resources/extensions/gsd/exec-sandbox.js +53 -11
  95. package/dist/resources/extensions/gsd/export-html.js +10 -3
  96. package/dist/resources/extensions/gsd/export.js +73 -0
  97. package/dist/resources/extensions/gsd/file-lock.js +1 -1
  98. package/dist/resources/extensions/gsd/flat-phase-migration.js +221 -0
  99. package/dist/resources/extensions/gsd/forensics.js +4 -33
  100. package/dist/resources/extensions/gsd/git-service.js +68 -8
  101. package/dist/resources/extensions/gsd/gitignore.js +10 -3
  102. package/dist/resources/extensions/gsd/guidance.js +7 -7
  103. package/dist/resources/extensions/gsd/guided-flow-queue.js +66 -5
  104. package/dist/resources/extensions/gsd/guided-flow.js +11 -6
  105. package/dist/resources/extensions/gsd/health-widget.js +55 -29
  106. package/dist/resources/extensions/gsd/json-persistence.js +20 -0
  107. package/dist/resources/extensions/gsd/knowledge-backfill.js +18 -11
  108. package/dist/resources/extensions/gsd/layout-policy.js +77 -0
  109. package/dist/resources/extensions/gsd/markdown-renderer.js +396 -122
  110. package/dist/resources/extensions/gsd/mcp-filter.js +44 -10
  111. package/dist/resources/extensions/gsd/md-importer.js +153 -51
  112. package/dist/resources/extensions/gsd/memory-backfill.js +28 -21
  113. package/dist/resources/extensions/gsd/memory-consolidation-scanner.js +44 -21
  114. package/dist/resources/extensions/gsd/metrics.js +22 -14
  115. package/dist/resources/extensions/gsd/migrate/layout-detect.js +32 -0
  116. package/dist/resources/extensions/gsd/migrate/planning-writer.js +203 -0
  117. package/dist/resources/extensions/gsd/migrate-external.js +62 -8
  118. package/dist/resources/extensions/gsd/migration-auto-check.js +27 -14
  119. package/dist/resources/extensions/gsd/milestone-actions.js +5 -3
  120. package/dist/resources/extensions/gsd/milestone-closeout.js +12 -2
  121. package/dist/resources/extensions/gsd/milestone-ids.js +79 -18
  122. package/dist/resources/extensions/gsd/milestone-implementation-evidence.js +26 -20
  123. package/dist/resources/extensions/gsd/milestone-planning-persistence.js +8 -0
  124. package/dist/resources/extensions/gsd/milestone-validation-verdict.js +7 -4
  125. package/dist/resources/extensions/gsd/model-router.js +79 -20
  126. package/dist/resources/extensions/gsd/notification-store.js +22 -29
  127. package/dist/resources/extensions/gsd/notifications.js +36 -7
  128. package/dist/resources/extensions/gsd/observability-validator.js +12 -4
  129. package/dist/resources/extensions/gsd/orphan-stash-audit.js +92 -16
  130. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +133 -35
  131. package/dist/resources/extensions/gsd/parsers-legacy.js +40 -14
  132. package/dist/resources/extensions/gsd/paths.js +356 -44
  133. package/dist/resources/extensions/gsd/planning-depth.js +2 -1
  134. package/dist/resources/extensions/gsd/post-execution-checks.js +26 -3
  135. package/dist/resources/extensions/gsd/preferences-models.js +23 -11
  136. package/dist/resources/extensions/gsd/preferences.js +62 -13
  137. package/dist/resources/extensions/gsd/prompts/ai-integration-phase.md +28 -0
  138. package/dist/resources/extensions/gsd/prompts/audit-fix.md +39 -0
  139. package/dist/resources/extensions/gsd/prompts/audit-milestone.md +26 -0
  140. package/dist/resources/extensions/gsd/prompts/audit-uat.md +24 -0
  141. package/dist/resources/extensions/gsd/prompts/autonomous.md +31 -0
  142. package/dist/resources/extensions/gsd/prompts/code-review.md +39 -0
  143. package/dist/resources/extensions/gsd/prompts/complete-slice.md +21 -16
  144. package/dist/resources/extensions/gsd/prompts/discuss-phase.md +31 -0
  145. package/dist/resources/extensions/gsd/prompts/docs-update.md +13 -0
  146. package/dist/resources/extensions/gsd/prompts/execute-phase.md +33 -0
  147. package/dist/resources/extensions/gsd/prompts/explore.md +58 -0
  148. package/dist/resources/extensions/gsd/prompts/graphify.md +27 -0
  149. package/dist/resources/extensions/gsd/prompts/health.md +37 -0
  150. package/dist/resources/extensions/gsd/prompts/import.md +30 -0
  151. package/dist/resources/extensions/gsd/prompts/inbox.md +27 -0
  152. package/dist/resources/extensions/gsd/prompts/ingest-docs.md +30 -0
  153. package/dist/resources/extensions/gsd/prompts/manager.md +21 -0
  154. package/dist/resources/extensions/gsd/prompts/map-codebase.md +42 -0
  155. package/dist/resources/extensions/gsd/prompts/milestone-summary.md +27 -0
  156. package/dist/resources/extensions/gsd/prompts/mvp-phase.md +23 -0
  157. package/dist/resources/extensions/gsd/prompts/pause-work.md +24 -0
  158. package/dist/resources/extensions/gsd/prompts/phase.md +22 -0
  159. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  160. package/dist/resources/extensions/gsd/prompts/plan-phase.md +34 -0
  161. package/dist/resources/extensions/gsd/prompts/plan-review-convergence.md +34 -0
  162. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  163. package/dist/resources/extensions/gsd/prompts/profile-user.md +28 -0
  164. package/dist/resources/extensions/gsd/prompts/progress.md +30 -0
  165. package/dist/resources/extensions/gsd/prompts/resume-work.md +20 -0
  166. package/dist/resources/extensions/gsd/prompts/review-backlog.md +21 -0
  167. package/dist/resources/extensions/gsd/prompts/review.md +27 -0
  168. package/dist/resources/extensions/gsd/prompts/secure-phase.md +24 -0
  169. package/dist/resources/extensions/gsd/prompts/settings.md +24 -0
  170. package/dist/resources/extensions/gsd/prompts/sketch.md +59 -0
  171. package/dist/resources/extensions/gsd/prompts/spec-phase.md +29 -0
  172. package/dist/resources/extensions/gsd/prompts/spike.md +59 -0
  173. package/dist/resources/extensions/gsd/prompts/stats.md +43 -0
  174. package/dist/resources/extensions/gsd/prompts/surface.md +25 -0
  175. package/dist/resources/extensions/gsd/prompts/thread.md +24 -0
  176. package/dist/resources/extensions/gsd/prompts/ui-phase.md +29 -0
  177. package/dist/resources/extensions/gsd/prompts/ui-review.md +29 -0
  178. package/dist/resources/extensions/gsd/prompts/ultraplan-phase.md +24 -0
  179. package/dist/resources/extensions/gsd/prompts/validate-phase.md +26 -0
  180. package/dist/resources/extensions/gsd/prompts/verify-work.md +24 -0
  181. package/dist/resources/extensions/gsd/prompts/workspace.md +22 -0
  182. package/dist/resources/extensions/gsd/prompts/workstreams.md +24 -0
  183. package/dist/resources/extensions/gsd/queue-order.js +3 -2
  184. package/dist/resources/extensions/gsd/quick.js +45 -2
  185. package/dist/resources/extensions/gsd/recovery-classification.js +8 -0
  186. package/dist/resources/extensions/gsd/roadmap-slices.js +1 -1
  187. package/dist/resources/extensions/gsd/root-write-leak-guard.js +7 -1
  188. package/dist/resources/extensions/gsd/safety/content-validator.js +2 -1
  189. package/dist/resources/extensions/gsd/safety/destructive-guard.js +8 -1
  190. package/dist/resources/extensions/gsd/safety/evidence-collector.js +16 -1
  191. package/dist/resources/extensions/gsd/safety/evidence-cross-ref.js +43 -1
  192. package/dist/resources/extensions/gsd/safety/file-change-validator.js +5 -2
  193. package/dist/resources/extensions/gsd/service-tier.js +2 -1
  194. package/dist/resources/extensions/gsd/session-forensics.js +11 -1
  195. package/dist/resources/extensions/gsd/session-lock.js +7 -6
  196. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +3 -0
  197. package/dist/resources/extensions/gsd/skills/gsd-headless/references/commands.md +51 -0
  198. package/dist/resources/extensions/gsd/state/derive/cache.js +28 -0
  199. package/dist/resources/extensions/gsd/state/derive/db-open.js +39 -0
  200. package/dist/resources/extensions/gsd/state/derive/from-db.js +452 -0
  201. package/dist/resources/extensions/gsd/state/derive/index.js +75 -0
  202. package/dist/resources/extensions/gsd/state/derive/interrupted-work.js +21 -0
  203. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +38 -4
  204. package/dist/resources/extensions/gsd/state-reconciliation/drift/completion.js +24 -3
  205. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.js +82 -0
  206. package/dist/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.js +142 -0
  207. package/dist/resources/extensions/gsd/state-reconciliation/drift/project-md.js +19 -6
  208. package/dist/resources/extensions/gsd/state-reconciliation/drift/roadmap.js +2 -2
  209. package/dist/resources/extensions/gsd/state-reconciliation/drift/stale-render.js +138 -19
  210. package/dist/resources/extensions/gsd/state-reconciliation/index.js +84 -26
  211. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +34 -18
  212. package/dist/resources/extensions/gsd/state.js +13 -581
  213. package/dist/resources/extensions/gsd/sync-lock.js +11 -18
  214. package/dist/resources/extensions/gsd/tool-surface-readiness.js +205 -16
  215. package/dist/resources/extensions/gsd/tools/complete-milestone.js +8 -4
  216. package/dist/resources/extensions/gsd/tools/complete-slice.js +14 -4
  217. package/dist/resources/extensions/gsd/tools/complete-task.js +58 -15
  218. package/dist/resources/extensions/gsd/tools/exec-tool.js +7 -2
  219. package/dist/resources/extensions/gsd/tools/plan-slice.js +60 -47
  220. package/dist/resources/extensions/gsd/tools/plan-task.js +40 -2
  221. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +9 -3
  222. package/dist/resources/extensions/gsd/tools/validate-milestone.js +8 -3
  223. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +44 -5
  224. package/dist/resources/extensions/gsd/triage-resolution.js +14 -7
  225. package/dist/resources/extensions/gsd/undo.js +51 -15
  226. package/dist/resources/extensions/gsd/unit-context-composer.js +23 -7
  227. package/dist/resources/extensions/gsd/unit-registry.js +63 -9
  228. package/dist/resources/extensions/gsd/unmerged-milestone-guard.js +91 -5
  229. package/dist/resources/extensions/gsd/validation-block-guard.js +54 -4
  230. package/dist/resources/extensions/gsd/verification-gate.js +7 -0
  231. package/dist/resources/extensions/gsd/visualizer-data.js +35 -0
  232. package/dist/resources/extensions/gsd/visualizer-views.js +21 -2
  233. package/dist/resources/extensions/gsd/workflow-manifest.js +126 -13
  234. package/dist/resources/extensions/gsd/workflow-mcp.js +9 -1
  235. package/dist/resources/extensions/gsd/workflow-projections.js +44 -18
  236. package/dist/resources/extensions/gsd/workspace-git-preflight.js +30 -1
  237. package/dist/resources/extensions/gsd/worktree-command.js +6 -6
  238. package/dist/resources/extensions/gsd/worktree-health.js +6 -3
  239. package/dist/resources/extensions/gsd/worktree-manager.js +59 -17
  240. package/dist/resources/extensions/gsd/worktree-safety.js +20 -11
  241. package/dist/resources/extensions/mcp-client/manager.js +3 -3
  242. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  243. package/dist/update-check.js +15 -4
  244. package/dist/web/standalone/.next/BUILD_ID +1 -1
  245. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  246. package/dist/web/standalone/.next/build-manifest.json +3 -3
  247. package/dist/web/standalone/.next/react-loadable-manifest.json +9 -9
  248. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  249. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  250. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  251. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  252. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  253. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  254. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  255. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  256. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  257. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  258. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  259. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  260. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  261. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  262. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  263. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  264. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  265. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  266. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  267. package/dist/web/standalone/.next/server/app/index.html +1 -1
  268. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  269. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  270. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  271. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  272. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  273. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  274. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  275. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  276. package/dist/web/standalone/.next/server/chunks/1128.js +1 -1
  277. package/dist/web/standalone/.next/server/chunks/5124.js +1 -1
  278. package/dist/web/standalone/.next/server/chunks/8357.js +1 -1
  279. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  280. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  281. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  282. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  283. package/dist/web/standalone/.next/static/chunks/{2659.b7b129ee6a769448.js → 2659.58e950899a9bb82f.js} +1 -1
  284. package/dist/web/standalone/.next/static/chunks/2772.a7c1fcc69a4685ef.js +1 -0
  285. package/dist/web/standalone/.next/static/chunks/{3616.3c60753b8ffcbd2e.js → 3616.61a2af74bb8833c8.js} +1 -1
  286. package/dist/web/standalone/.next/static/chunks/{4283.e4873b058df143a1.js → 4283.d0d9e0a955e441cb.js} +2 -2
  287. package/dist/web/standalone/.next/static/chunks/{5826.a46ecdd1cfe8dabc.js → 5826.5421d66c72b9f34e.js} +1 -1
  288. package/dist/web/standalone/.next/static/chunks/8785.e29b3134cab1d153.js +1 -0
  289. package/dist/web/standalone/.next/static/chunks/8937.640dc9c2aaa1dfad.js +10 -0
  290. package/dist/web/standalone/.next/static/chunks/app/{page-a48b7c48333b31c8.js → page-bc4c723c6a19c6f0.js} +1 -1
  291. package/dist/web/standalone/.next/static/chunks/webpack-9c401904f87ded16.js +1 -0
  292. package/dist/web/standalone/node_modules/@gsd/native/package.json +1 -1
  293. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  294. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  295. package/dist/web-mode.d.ts +3 -1
  296. package/dist/web-mode.js +7 -5
  297. package/integrations/hermes/README.md +48 -0
  298. package/integrations/hermes/docs/setup.md +272 -0
  299. package/integrations/hermes/docs/upstream-hermes-pr.md +40 -0
  300. package/integrations/hermes/open_gsd_hermes/__init__.py +105 -0
  301. package/integrations/hermes/open_gsd_hermes/binding.py +107 -0
  302. package/integrations/hermes/open_gsd_hermes/commands.py +186 -0
  303. package/integrations/hermes/open_gsd_hermes/config.py +59 -0
  304. package/integrations/hermes/open_gsd_hermes/credentials.py +51 -0
  305. package/integrations/hermes/open_gsd_hermes/cron.py +85 -0
  306. package/integrations/hermes/open_gsd_hermes/formatting.py +13 -0
  307. package/integrations/hermes/open_gsd_hermes/gsd_client.py +269 -0
  308. package/integrations/hermes/open_gsd_hermes/inject.py +31 -0
  309. package/integrations/hermes/open_gsd_hermes/memory.py +66 -0
  310. package/integrations/hermes/open_gsd_hermes/notifications.py +71 -0
  311. package/integrations/hermes/open_gsd_hermes/snapshot.py +42 -0
  312. package/integrations/hermes/open_gsd_hermes/supervisor.py +180 -0
  313. package/integrations/hermes/open_gsd_hermes/types.py +100 -0
  314. package/integrations/hermes/plugin.yaml +38 -0
  315. package/integrations/hermes/pyproject.toml +32 -0
  316. package/integrations/hermes/scripts/preflight.sh +92 -0
  317. package/integrations/hermes/tests/fixtures/minimal-project/.gsd/STATE.md +17 -0
  318. package/integrations/hermes/tests/golden/memory_prefetch.txt +5 -0
  319. package/integrations/hermes/tests/golden/snapshot.txt +8 -0
  320. package/integrations/hermes/tests/test_binding.py +103 -0
  321. package/integrations/hermes/tests/test_config.py +36 -0
  322. package/integrations/hermes/tests/test_cron.py +34 -0
  323. package/integrations/hermes/tests/test_gsd_client_cache.py +120 -0
  324. package/integrations/hermes/tests/test_memory.py +59 -0
  325. package/integrations/hermes/tests/test_read_cli_contract.py +50 -0
  326. package/integrations/hermes/tests/test_register.py +56 -0
  327. package/integrations/hermes/tests/test_snapshot.py +53 -0
  328. package/integrations/hermes/tests/test_supervisor_fsm.py +581 -0
  329. package/package.json +7 -6
  330. package/packages/cloud-mcp-gateway/dist/runtime-registry.d.ts +8 -0
  331. package/packages/cloud-mcp-gateway/dist/runtime-registry.d.ts.map +1 -1
  332. package/packages/cloud-mcp-gateway/dist/runtime-registry.js +19 -2
  333. package/packages/cloud-mcp-gateway/dist/runtime-registry.js.map +1 -1
  334. package/packages/cloud-mcp-gateway/dist/runtime-registry.test.js +71 -2
  335. package/packages/cloud-mcp-gateway/dist/runtime-registry.test.js.map +1 -1
  336. package/packages/cloud-mcp-gateway/package.json +2 -2
  337. package/packages/contracts/dist/workflow.d.ts +1 -0
  338. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  339. package/packages/contracts/dist/workflow.js +2 -0
  340. package/packages/contracts/dist/workflow.js.map +1 -1
  341. package/packages/contracts/package.json +1 -1
  342. package/packages/daemon/package.json +4 -4
  343. package/packages/gsd-agent-core/dist/agent-session.d.ts +1 -0
  344. package/packages/gsd-agent-core/dist/agent-session.d.ts.map +1 -1
  345. package/packages/gsd-agent-core/dist/agent-session.js +3 -0
  346. package/packages/gsd-agent-core/dist/agent-session.js.map +1 -1
  347. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts +41 -0
  348. package/packages/gsd-agent-core/dist/extension-ui-snapshot.d.ts.map +1 -0
  349. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js +62 -0
  350. package/packages/gsd-agent-core/dist/extension-ui-snapshot.js.map +1 -0
  351. package/packages/gsd-agent-core/dist/index.d.ts +2 -0
  352. package/packages/gsd-agent-core/dist/index.d.ts.map +1 -1
  353. package/packages/gsd-agent-core/dist/index.js +2 -0
  354. package/packages/gsd-agent-core/dist/index.js.map +1 -1
  355. package/packages/gsd-agent-core/dist/session/agent-session-events.js +1 -1
  356. package/packages/gsd-agent-core/dist/session/agent-session-events.js.map +1 -1
  357. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts +1 -0
  358. package/packages/gsd-agent-core/dist/session/agent-session-host.d.ts.map +1 -1
  359. package/packages/gsd-agent-core/dist/session/agent-session-host.js.map +1 -1
  360. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts +5 -0
  361. package/packages/gsd-agent-core/dist/session/agent-session-prompt.d.ts.map +1 -1
  362. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js +60 -3
  363. package/packages/gsd-agent-core/dist/session/agent-session-prompt.js.map +1 -1
  364. package/packages/gsd-agent-core/dist/transcript-store.d.ts +58 -0
  365. package/packages/gsd-agent-core/dist/transcript-store.d.ts.map +1 -0
  366. package/packages/gsd-agent-core/dist/transcript-store.js +132 -0
  367. package/packages/gsd-agent-core/dist/transcript-store.js.map +1 -0
  368. package/packages/gsd-agent-core/package.json +5 -5
  369. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts +2 -0
  370. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  371. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +25 -11
  372. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  373. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts +4 -0
  374. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.d.ts.map +1 -0
  375. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js +7 -0
  376. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller-latency.js.map +1 -0
  377. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts +3 -24
  378. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  379. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js +26 -829
  380. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  381. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts +58 -0
  382. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.d.ts.map +1 -0
  383. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js +312 -0
  384. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-handoff-filter.js.map +1 -0
  385. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts +31 -0
  386. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.d.ts.map +1 -0
  387. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js +130 -0
  388. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-pinned-zone.js.map +1 -0
  389. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts +15 -0
  390. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.d.ts.map +1 -0
  391. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js +258 -0
  392. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-segment-walker.js.map +1 -0
  393. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts +13 -0
  394. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.d.ts.map +1 -0
  395. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js +118 -0
  396. package/packages/gsd-agent-modes/dist/modes/interactive/controllers/chat-tool-rollup.js.map +1 -0
  397. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts +9 -0
  398. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  399. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js +1 -1
  400. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  401. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts +54 -0
  402. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.d.ts.map +1 -0
  403. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js +20 -0
  404. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-ui-state.js.map +1 -0
  405. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts +4 -1
  406. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  407. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +9 -0
  408. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  409. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts +56 -0
  410. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.d.ts.map +1 -0
  411. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js +44 -0
  412. package/packages/gsd-agent-modes/dist/modes/interactive/streaming-render-state.js.map +1 -0
  413. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts +5 -0
  414. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.d.ts.map +1 -0
  415. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js +77 -0
  416. package/packages/gsd-agent-modes/dist/modes/interactive/tui-transcript-tracker.js.map +1 -0
  417. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts +2 -0
  418. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  419. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js +23 -5
  420. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-client.js.map +1 -1
  421. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  422. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js +18 -0
  423. package/packages/gsd-agent-modes/dist/modes/rpc/rpc-mode.js.map +1 -1
  424. package/packages/gsd-agent-modes/package.json +7 -7
  425. package/packages/mcp-server/README.md +11 -1
  426. package/packages/mcp-server/dist/cli-errors.d.ts +11 -0
  427. package/packages/mcp-server/dist/cli-errors.d.ts.map +1 -1
  428. package/packages/mcp-server/dist/cli-errors.js +12 -0
  429. package/packages/mcp-server/dist/cli-errors.js.map +1 -1
  430. package/packages/mcp-server/dist/cli-runner.d.ts.map +1 -1
  431. package/packages/mcp-server/dist/cli-runner.js +33 -0
  432. package/packages/mcp-server/dist/cli-runner.js.map +1 -1
  433. package/packages/mcp-server/dist/cli.d.ts +1 -0
  434. package/packages/mcp-server/dist/cli.d.ts.map +1 -1
  435. package/packages/mcp-server/dist/cli.js +1 -0
  436. package/packages/mcp-server/dist/cli.js.map +1 -1
  437. package/packages/mcp-server/dist/server.d.ts +30 -1
  438. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  439. package/packages/mcp-server/dist/server.js +85 -6
  440. package/packages/mcp-server/dist/server.js.map +1 -1
  441. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  442. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  443. package/packages/mcp-server/dist/workflow-tools.js +35 -21
  444. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  445. package/packages/mcp-server/package.json +21 -5
  446. package/packages/native/package.json +1 -1
  447. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  448. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  449. package/packages/pi-agent-core/package.json +1 -1
  450. package/packages/pi-ai/dist/models.generated.d.ts +46 -0
  451. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  452. package/packages/pi-ai/dist/models.generated.js +38 -0
  453. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  454. package/packages/pi-ai/package.json +1 -1
  455. package/packages/pi-coding-agent/README.md +3 -2
  456. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts +9 -0
  457. package/packages/pi-coding-agent/dist/core/session-manager-context.d.ts.map +1 -0
  458. package/packages/pi-coding-agent/dist/core/session-manager-context.js +94 -0
  459. package/packages/pi-coding-agent/dist/core/session-manager-context.js.map +1 -0
  460. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts +8 -0
  461. package/packages/pi-coding-agent/dist/core/session-manager-list.d.ts.map +1 -0
  462. package/packages/pi-coding-agent/dist/core/session-manager-list.js +244 -0
  463. package/packages/pi-coding-agent/dist/core/session-manager-list.js.map +1 -0
  464. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts +12 -0
  465. package/packages/pi-coding-agent/dist/core/session-manager-migration.d.ts.map +1 -0
  466. package/packages/pi-coding-agent/dist/core/session-manager-migration.js +84 -0
  467. package/packages/pi-coding-agent/dist/core/session-manager-migration.js.map +1 -0
  468. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts +135 -0
  469. package/packages/pi-coding-agent/dist/core/session-manager-types.d.ts.map +1 -0
  470. package/packages/pi-coding-agent/dist/core/session-manager-types.js +2 -0
  471. package/packages/pi-coding-agent/dist/core/session-manager-types.js.map +1 -0
  472. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +6 -154
  473. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  474. package/packages/pi-coding-agent/dist/core/session-manager.js +22 -459
  475. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  476. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts +75 -75
  477. package/packages/pi-coding-agent/dist/theme/theme-schema.d.ts.map +1 -1
  478. package/packages/pi-coding-agent/dist/theme/theme-schema.js +1 -1
  479. package/packages/pi-coding-agent/dist/theme/theme-schema.js.map +1 -1
  480. package/packages/pi-coding-agent/dist/theme/theme.d.ts.map +1 -1
  481. package/packages/pi-coding-agent/dist/theme/theme.js +11 -7
  482. package/packages/pi-coding-agent/dist/theme/theme.js.map +1 -1
  483. package/packages/pi-coding-agent/package.json +7 -7
  484. package/packages/pi-tui/package.json +2 -2
  485. package/packages/rpc-client/package.json +2 -2
  486. package/pkg/dist/theme/theme-schema.d.ts +75 -75
  487. package/pkg/dist/theme/theme-schema.d.ts.map +1 -1
  488. package/pkg/dist/theme/theme-schema.js +1 -1
  489. package/pkg/dist/theme/theme-schema.js.map +1 -1
  490. package/pkg/dist/theme/theme.d.ts.map +1 -1
  491. package/pkg/dist/theme/theme.js +11 -7
  492. package/pkg/dist/theme/theme.js.map +1 -1
  493. package/pkg/package.json +1 -1
  494. package/src/resources/GSD-WORKFLOW.md +22 -22
  495. package/src/resources/extensions/claude-code-cli/index.ts +8 -1
  496. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  497. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +103 -22
  498. package/src/resources/extensions/claude-code-cli/tests/index.test.ts +61 -0
  499. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +262 -10
  500. package/src/resources/extensions/google-cli/stream-adapter.ts +106 -19
  501. package/src/resources/extensions/gsd/artifact-verification.ts +464 -0
  502. package/src/resources/extensions/gsd/auto/dispatch-history.ts +19 -1
  503. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  504. package/src/resources/extensions/gsd/auto/loop.ts +69 -2
  505. package/src/resources/extensions/gsd/auto/orchestrator.ts +38 -13
  506. package/src/resources/extensions/gsd/auto/session.ts +14 -0
  507. package/src/resources/extensions/gsd/auto/verification-retry-policy.ts +3 -1
  508. package/src/resources/extensions/gsd/auto/workflow-kernel.ts +25 -3
  509. package/src/resources/extensions/gsd/auto-artifact-paths.ts +129 -20
  510. package/src/resources/extensions/gsd/auto-budget.ts +12 -1
  511. package/src/resources/extensions/gsd/auto-dispatch.ts +68 -34
  512. package/src/resources/extensions/gsd/auto-model-selection.ts +8 -1
  513. package/src/resources/extensions/gsd/auto-post-unit.ts +37 -23
  514. package/src/resources/extensions/gsd/auto-prompts.ts +81 -44
  515. package/src/resources/extensions/gsd/auto-recovery.ts +21 -484
  516. package/src/resources/extensions/gsd/auto-runtime-state.ts +17 -5
  517. package/src/resources/extensions/gsd/auto-start.ts +63 -34
  518. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +3 -2
  519. package/src/resources/extensions/gsd/auto-verification.ts +10 -8
  520. package/src/resources/extensions/gsd/auto-worktree.ts +48 -15
  521. package/src/resources/extensions/gsd/auto.ts +46 -11
  522. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +164 -71
  523. package/src/resources/extensions/gsd/bootstrap/core-session-tools.ts +44 -0
  524. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +11 -5
  525. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +2 -0
  526. package/src/resources/extensions/gsd/bootstrap/fallback-continuation.ts +31 -0
  527. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +23 -1
  528. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +139 -27
  529. package/src/resources/extensions/gsd/bootstrap/system-context.ts +219 -46
  530. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +49 -1
  531. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +104 -10
  532. package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +21 -3
  533. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +86 -18
  534. package/src/resources/extensions/gsd/closeout-consistency-gate.ts +109 -4
  535. package/src/resources/extensions/gsd/codebase-generator.ts +6 -9
  536. package/src/resources/extensions/gsd/commands/catalog.ts +6 -0
  537. package/src/resources/extensions/gsd/commands/dispatcher.ts +3 -0
  538. package/src/resources/extensions/gsd/commands/gsd-core-aliases-handler.ts +48 -0
  539. package/src/resources/extensions/gsd/commands/gsd-core-aliases.ts +63 -0
  540. package/src/resources/extensions/gsd/commands/handlers/auto.ts +1 -1
  541. package/src/resources/extensions/gsd/commands/handlers/core.ts +31 -0
  542. package/src/resources/extensions/gsd/commands/handlers/ops.ts +225 -1
  543. package/src/resources/extensions/gsd/commands-cmux.ts +3 -0
  544. package/src/resources/extensions/gsd/commands-context.ts +18 -1
  545. package/src/resources/extensions/gsd/commands-gsd-core.ts +1142 -0
  546. package/src/resources/extensions/gsd/commands-handlers.ts +76 -1
  547. package/src/resources/extensions/gsd/commands-maintenance.ts +98 -2
  548. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +21 -10
  549. package/src/resources/extensions/gsd/commands-usage.ts +1 -1
  550. package/src/resources/extensions/gsd/commands-verdict.ts +16 -15
  551. package/src/resources/extensions/gsd/commands-worktree.ts +12 -10
  552. package/src/resources/extensions/gsd/compat/compat-marker.ts +210 -0
  553. package/src/resources/extensions/gsd/compat/index.ts +12 -0
  554. package/src/resources/extensions/gsd/compat/planning-compat.ts +168 -0
  555. package/src/resources/extensions/gsd/config-overlay.ts +3 -1
  556. package/src/resources/extensions/gsd/consent-question.ts +11 -1
  557. package/src/resources/extensions/gsd/consent-verdict.ts +30 -1
  558. package/src/resources/extensions/gsd/dashboard-overlay.ts +73 -7
  559. package/src/resources/extensions/gsd/db/engine.ts +34 -1
  560. package/src/resources/extensions/gsd/db/queries.ts +157 -0
  561. package/src/resources/extensions/gsd/db/unit-dispatches.ts +24 -0
  562. package/src/resources/extensions/gsd/db-memory-fts-schema.ts +45 -0
  563. package/src/resources/extensions/gsd/db-workspace.ts +76 -3
  564. package/src/resources/extensions/gsd/delegation-policy.ts +1 -1
  565. package/src/resources/extensions/gsd/discussion-handoff.ts +9 -5
  566. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  567. package/src/resources/extensions/gsd/doctor-engine-checks.ts +233 -5
  568. package/src/resources/extensions/gsd/doctor-git-checks.ts +24 -2
  569. package/src/resources/extensions/gsd/doctor-providers.ts +103 -9
  570. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +5 -15
  571. package/src/resources/extensions/gsd/doctor-types.ts +4 -0
  572. package/src/resources/extensions/gsd/doctor.ts +30 -7
  573. package/src/resources/extensions/gsd/error-classifier.ts +14 -1
  574. package/src/resources/extensions/gsd/escalation.ts +9 -4
  575. package/src/resources/extensions/gsd/exec-sandbox.ts +56 -11
  576. package/src/resources/extensions/gsd/export-html.ts +11 -4
  577. package/src/resources/extensions/gsd/export.ts +88 -1
  578. package/src/resources/extensions/gsd/file-lock.ts +1 -1
  579. package/src/resources/extensions/gsd/flat-phase-migration.ts +249 -0
  580. package/src/resources/extensions/gsd/forensics.ts +4 -34
  581. package/src/resources/extensions/gsd/git-constants.ts +1 -1
  582. package/src/resources/extensions/gsd/git-service.ts +76 -7
  583. package/src/resources/extensions/gsd/gitignore.ts +11 -4
  584. package/src/resources/extensions/gsd/guidance.ts +7 -7
  585. package/src/resources/extensions/gsd/guided-flow-queue.ts +89 -4
  586. package/src/resources/extensions/gsd/guided-flow.ts +11 -6
  587. package/src/resources/extensions/gsd/health-widget.ts +69 -32
  588. package/src/resources/extensions/gsd/json-persistence.ts +20 -0
  589. package/src/resources/extensions/gsd/knowledge-backfill.ts +16 -10
  590. package/src/resources/extensions/gsd/layout-policy.ts +86 -0
  591. package/src/resources/extensions/gsd/markdown-renderer.ts +409 -112
  592. package/src/resources/extensions/gsd/mcp-filter.ts +59 -10
  593. package/src/resources/extensions/gsd/md-importer.ts +215 -65
  594. package/src/resources/extensions/gsd/memory-backfill.ts +26 -20
  595. package/src/resources/extensions/gsd/memory-consolidation-scanner.ts +51 -19
  596. package/src/resources/extensions/gsd/metrics.ts +26 -13
  597. package/src/resources/extensions/gsd/migrate/layout-detect.ts +38 -0
  598. package/src/resources/extensions/gsd/migrate/planning-writer.ts +259 -0
  599. package/src/resources/extensions/gsd/migrate-external.ts +57 -8
  600. package/src/resources/extensions/gsd/migration-auto-check.ts +27 -13
  601. package/src/resources/extensions/gsd/milestone-actions.ts +5 -2
  602. package/src/resources/extensions/gsd/milestone-closeout.ts +13 -2
  603. package/src/resources/extensions/gsd/milestone-ids.ts +78 -19
  604. package/src/resources/extensions/gsd/milestone-implementation-evidence.ts +35 -21
  605. package/src/resources/extensions/gsd/milestone-planning-persistence.ts +8 -0
  606. package/src/resources/extensions/gsd/milestone-validation-verdict.ts +7 -9
  607. package/src/resources/extensions/gsd/model-router.ts +98 -18
  608. package/src/resources/extensions/gsd/notification-store.ts +17 -28
  609. package/src/resources/extensions/gsd/notifications.ts +37 -6
  610. package/src/resources/extensions/gsd/observability-validator.ts +12 -4
  611. package/src/resources/extensions/gsd/orphan-stash-audit.ts +108 -20
  612. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +151 -31
  613. package/src/resources/extensions/gsd/parsers-legacy.ts +42 -15
  614. package/src/resources/extensions/gsd/paths.ts +348 -39
  615. package/src/resources/extensions/gsd/planning-depth.ts +2 -1
  616. package/src/resources/extensions/gsd/post-execution-checks.ts +43 -3
  617. package/src/resources/extensions/gsd/preferences-models.ts +25 -9
  618. package/src/resources/extensions/gsd/preferences.ts +80 -12
  619. package/src/resources/extensions/gsd/prompts/ai-integration-phase.md +28 -0
  620. package/src/resources/extensions/gsd/prompts/audit-fix.md +39 -0
  621. package/src/resources/extensions/gsd/prompts/audit-milestone.md +26 -0
  622. package/src/resources/extensions/gsd/prompts/audit-uat.md +24 -0
  623. package/src/resources/extensions/gsd/prompts/autonomous.md +31 -0
  624. package/src/resources/extensions/gsd/prompts/code-review.md +39 -0
  625. package/src/resources/extensions/gsd/prompts/complete-slice.md +21 -16
  626. package/src/resources/extensions/gsd/prompts/discuss-phase.md +31 -0
  627. package/src/resources/extensions/gsd/prompts/docs-update.md +13 -0
  628. package/src/resources/extensions/gsd/prompts/execute-phase.md +33 -0
  629. package/src/resources/extensions/gsd/prompts/explore.md +58 -0
  630. package/src/resources/extensions/gsd/prompts/graphify.md +27 -0
  631. package/src/resources/extensions/gsd/prompts/health.md +37 -0
  632. package/src/resources/extensions/gsd/prompts/import.md +30 -0
  633. package/src/resources/extensions/gsd/prompts/inbox.md +27 -0
  634. package/src/resources/extensions/gsd/prompts/ingest-docs.md +30 -0
  635. package/src/resources/extensions/gsd/prompts/manager.md +21 -0
  636. package/src/resources/extensions/gsd/prompts/map-codebase.md +42 -0
  637. package/src/resources/extensions/gsd/prompts/milestone-summary.md +27 -0
  638. package/src/resources/extensions/gsd/prompts/mvp-phase.md +23 -0
  639. package/src/resources/extensions/gsd/prompts/pause-work.md +24 -0
  640. package/src/resources/extensions/gsd/prompts/phase.md +22 -0
  641. package/src/resources/extensions/gsd/prompts/plan-milestone.md +2 -2
  642. package/src/resources/extensions/gsd/prompts/plan-phase.md +34 -0
  643. package/src/resources/extensions/gsd/prompts/plan-review-convergence.md +34 -0
  644. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  645. package/src/resources/extensions/gsd/prompts/profile-user.md +28 -0
  646. package/src/resources/extensions/gsd/prompts/progress.md +30 -0
  647. package/src/resources/extensions/gsd/prompts/resume-work.md +20 -0
  648. package/src/resources/extensions/gsd/prompts/review-backlog.md +21 -0
  649. package/src/resources/extensions/gsd/prompts/review.md +27 -0
  650. package/src/resources/extensions/gsd/prompts/secure-phase.md +24 -0
  651. package/src/resources/extensions/gsd/prompts/settings.md +24 -0
  652. package/src/resources/extensions/gsd/prompts/sketch.md +59 -0
  653. package/src/resources/extensions/gsd/prompts/spec-phase.md +29 -0
  654. package/src/resources/extensions/gsd/prompts/spike.md +59 -0
  655. package/src/resources/extensions/gsd/prompts/stats.md +43 -0
  656. package/src/resources/extensions/gsd/prompts/surface.md +25 -0
  657. package/src/resources/extensions/gsd/prompts/thread.md +24 -0
  658. package/src/resources/extensions/gsd/prompts/ui-phase.md +29 -0
  659. package/src/resources/extensions/gsd/prompts/ui-review.md +29 -0
  660. package/src/resources/extensions/gsd/prompts/ultraplan-phase.md +24 -0
  661. package/src/resources/extensions/gsd/prompts/validate-phase.md +26 -0
  662. package/src/resources/extensions/gsd/prompts/verify-work.md +24 -0
  663. package/src/resources/extensions/gsd/prompts/workspace.md +22 -0
  664. package/src/resources/extensions/gsd/prompts/workstreams.md +24 -0
  665. package/src/resources/extensions/gsd/queue-order.ts +3 -2
  666. package/src/resources/extensions/gsd/quick.ts +43 -2
  667. package/src/resources/extensions/gsd/recovery-classification.ts +7 -0
  668. package/src/resources/extensions/gsd/roadmap-slices.ts +1 -1
  669. package/src/resources/extensions/gsd/root-write-leak-guard.ts +13 -1
  670. package/src/resources/extensions/gsd/safety/content-validator.ts +2 -1
  671. package/src/resources/extensions/gsd/safety/destructive-guard.ts +9 -1
  672. package/src/resources/extensions/gsd/safety/evidence-collector.ts +16 -1
  673. package/src/resources/extensions/gsd/safety/evidence-cross-ref.ts +45 -1
  674. package/src/resources/extensions/gsd/safety/file-change-validator.ts +8 -2
  675. package/src/resources/extensions/gsd/service-tier.ts +2 -0
  676. package/src/resources/extensions/gsd/session-forensics.ts +11 -1
  677. package/src/resources/extensions/gsd/session-lock.ts +7 -6
  678. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +3 -0
  679. package/src/resources/extensions/gsd/skills/gsd-headless/references/commands.md +51 -0
  680. package/src/resources/extensions/gsd/state/derive/cache.ts +46 -0
  681. package/src/resources/extensions/gsd/state/derive/db-open.ts +45 -0
  682. package/src/resources/extensions/gsd/state/derive/from-db.ts +561 -0
  683. package/src/resources/extensions/gsd/state/derive/index.ts +104 -0
  684. package/src/resources/extensions/gsd/state/derive/interrupted-work.ts +31 -0
  685. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +35 -4
  686. package/src/resources/extensions/gsd/state-reconciliation/drift/completion.ts +22 -2
  687. package/src/resources/extensions/gsd/state-reconciliation/drift/external-markdown-edit.ts +105 -0
  688. package/src/resources/extensions/gsd/state-reconciliation/drift/external-planning-edit.ts +180 -0
  689. package/src/resources/extensions/gsd/state-reconciliation/drift/project-md.ts +19 -6
  690. package/src/resources/extensions/gsd/state-reconciliation/drift/roadmap.ts +2 -2
  691. package/src/resources/extensions/gsd/state-reconciliation/drift/stale-render.ts +176 -30
  692. package/src/resources/extensions/gsd/state-reconciliation/index.ts +86 -27
  693. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +45 -18
  694. package/src/resources/extensions/gsd/state-reconciliation/types.ts +19 -0
  695. package/src/resources/extensions/gsd/state.ts +37 -695
  696. package/src/resources/extensions/gsd/sync-lock.ts +11 -20
  697. package/src/resources/extensions/gsd/tests/__fixtures__/flat-phase/.gsd/phases/01-foundation/01-01-PLAN.md +13 -0
  698. package/src/resources/extensions/gsd/tests/__fixtures__/flat-phase/.gsd/phases/01-foundation/01-ROADMAP.md +8 -0
  699. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/m001-basic/.gsd/milestones/M001/M001-ROADMAP.md +13 -0
  700. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/m001-basic/.gsd/milestones/M001/slices/S01/S01-PLAN.md +5 -0
  701. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/PROJECT.md +1 -0
  702. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/ROADMAP.md +5 -0
  703. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/STATE.md +10 -0
  704. package/src/resources/extensions/gsd/tests/__fixtures__/round-trip/planning-flat-phases/.planning/phases/01-foundation/01-01-PLAN.md +13 -0
  705. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +4 -3
  706. package/src/resources/extensions/gsd/tests/auto-artifact-paths.test.ts +420 -2
  707. package/src/resources/extensions/gsd/tests/auto-budget-alerts.test.ts +14 -5
  708. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +104 -0
  709. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +32 -1
  710. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +15 -12
  711. package/src/resources/extensions/gsd/tests/auto-pause-double-entry-guard.test.ts +36 -0
  712. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +11 -2
  713. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +182 -4
  714. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +146 -1
  715. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +30 -0
  716. package/src/resources/extensions/gsd/tests/auto-worktree-auto-resolve.test.ts +17 -0
  717. package/src/resources/extensions/gsd/tests/codebase-generator.test.ts +15 -11
  718. package/src/resources/extensions/gsd/tests/commands-context.test.ts +26 -0
  719. package/src/resources/extensions/gsd/tests/commands-dispatcher-unmerged-milestone.test.ts +89 -0
  720. package/src/resources/extensions/gsd/tests/commands-dispatcher-validation-block.test.ts +37 -1
  721. package/src/resources/extensions/gsd/tests/commands-eval-review.test.ts +31 -30
  722. package/src/resources/extensions/gsd/tests/commands-gsd-core.test.ts +863 -0
  723. package/src/resources/extensions/gsd/tests/commands-verdict.test.ts +1 -1
  724. package/src/resources/extensions/gsd/tests/commands-worktree-clean.test.ts +80 -0
  725. package/src/resources/extensions/gsd/tests/compat-health-line.test.ts +102 -0
  726. package/src/resources/extensions/gsd/tests/compat-marker-invalidation.test.ts +51 -0
  727. package/src/resources/extensions/gsd/tests/compat-marker.test.ts +105 -0
  728. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +28 -0
  729. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +151 -0
  730. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +18 -7
  731. package/src/resources/extensions/gsd/tests/complete-task-rollback-evidence.test.ts +48 -8
  732. package/src/resources/extensions/gsd/tests/complete-task.test.ts +82 -7
  733. package/src/resources/extensions/gsd/tests/consent-question.test.ts +45 -0
  734. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +90 -0
  735. package/src/resources/extensions/gsd/tests/db-authority-regression.test.ts +1 -1
  736. package/src/resources/extensions/gsd/tests/db-memory-fts-schema.test.ts +58 -3
  737. package/src/resources/extensions/gsd/tests/decisions-projection-from-memories.test.ts +51 -0
  738. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +63 -1
  739. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +49 -5
  740. package/src/resources/extensions/gsd/tests/destructive-guard.test.ts +44 -0
  741. package/src/resources/extensions/gsd/tests/discuss-cold-start-db-open.test.ts +10 -27
  742. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +20 -1
  743. package/src/resources/extensions/gsd/tests/dispatch-history.test.ts +102 -0
  744. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +175 -43
  745. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +26 -1
  746. package/src/resources/extensions/gsd/tests/dist-redirect.mjs +7 -0
  747. package/src/resources/extensions/gsd/tests/doctor-forensics-db-open-regression.test.ts +70 -2
  748. package/src/resources/extensions/gsd/tests/doctor-git-checks-autoresolve.test.ts +149 -0
  749. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +107 -0
  750. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +239 -2
  751. package/src/resources/extensions/gsd/tests/ensure-preconditions-guard-4996.test.ts +17 -10
  752. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +95 -0
  753. package/src/resources/extensions/gsd/tests/exec-graceful-kill.test.ts +38 -0
  754. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +16 -0
  755. package/src/resources/extensions/gsd/tests/exec-tool.test.ts +45 -1
  756. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +25 -0
  757. package/src/resources/extensions/gsd/tests/export-memory.test.ts +179 -0
  758. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +53 -0
  759. package/src/resources/extensions/gsd/tests/external-markdown-edit.test.ts +137 -0
  760. package/src/resources/extensions/gsd/tests/external-planning-edit.test.ts +199 -0
  761. package/src/resources/extensions/gsd/tests/fallback-continuation.test.ts +36 -0
  762. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +40 -0
  763. package/src/resources/extensions/gsd/tests/file-lock.test.ts +43 -0
  764. package/src/resources/extensions/gsd/tests/flat-phase-migration.test.ts +149 -0
  765. package/src/resources/extensions/gsd/tests/flat-phase-renderer.test.ts +83 -0
  766. package/src/resources/extensions/gsd/tests/flat-phase-round-trip.test.ts +72 -0
  767. package/src/resources/extensions/gsd/tests/flat-phase-validation-integration.test.ts +120 -0
  768. package/src/resources/extensions/gsd/tests/flat-phase-validation-path.test.ts +74 -0
  769. package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +88 -0
  770. package/src/resources/extensions/gsd/tests/gitignore-bg-shell-runtime.test.ts +4 -0
  771. package/src/resources/extensions/gsd/tests/gsd-core-parity-routing.test.ts +183 -0
  772. package/src/resources/extensions/gsd/tests/guidance.test.ts +25 -0
  773. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +42 -0
  774. package/src/resources/extensions/gsd/tests/health-widget.test.ts +268 -3
  775. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +19 -11
  776. package/src/resources/extensions/gsd/tests/integration/commands-eval-review.integration.test.ts +6 -2
  777. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +130 -3
  778. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +55 -0
  779. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +4 -3
  780. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +11 -7
  781. package/src/resources/extensions/gsd/tests/integration/queue-active-milestone-context-budget.test.ts +93 -0
  782. package/src/resources/extensions/gsd/tests/integration/quick-branch-lifecycle.test.ts +56 -9
  783. package/src/resources/extensions/gsd/tests/json-persistence-atomic.test.ts +47 -0
  784. package/src/resources/extensions/gsd/tests/knowledge-backfill-projection.test.ts +35 -0
  785. package/src/resources/extensions/gsd/tests/knowledge-cold-start.test.ts +386 -0
  786. package/src/resources/extensions/gsd/tests/layout-policy.test.ts +59 -0
  787. package/src/resources/extensions/gsd/tests/markdown-renderer-parse-cache.test.ts +1 -1
  788. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +214 -82
  789. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +74 -1
  790. package/src/resources/extensions/gsd/tests/memory-consolidation-scanner.test.ts +78 -0
  791. package/src/resources/extensions/gsd/tests/memory-store.test.ts +48 -0
  792. package/src/resources/extensions/gsd/tests/merge-closeout-consistency-gate.test.ts +31 -1
  793. package/src/resources/extensions/gsd/tests/metrics-ledger-cap.test.ts +239 -0
  794. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +6 -0
  795. package/src/resources/extensions/gsd/tests/metrics.test.ts +1 -0
  796. package/src/resources/extensions/gsd/tests/migrate-external-worktree.test.ts +57 -0
  797. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +70 -0
  798. package/src/resources/extensions/gsd/tests/milestone-closeout.test.ts +7 -2
  799. package/src/resources/extensions/gsd/tests/milestone-settlement.test.ts +6 -1
  800. package/src/resources/extensions/gsd/tests/model-router.test.ts +204 -7
  801. package/src/resources/extensions/gsd/tests/notification-store.test.ts +23 -0
  802. package/src/resources/extensions/gsd/tests/notifications.test.ts +33 -0
  803. package/src/resources/extensions/gsd/tests/observability-validator-boundary.test.ts +194 -0
  804. package/src/resources/extensions/gsd/tests/orchestrator-logs.test.ts +47 -1
  805. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +91 -7
  806. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +52 -1
  807. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +91 -0
  808. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +26 -0
  809. package/src/resources/extensions/gsd/tests/parsers-legacy-importers.test.ts +4 -1
  810. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +1 -1
  811. package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +7 -2
  812. package/src/resources/extensions/gsd/tests/plan-milestone-sketch-render.test.ts +7 -2
  813. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +9 -6
  814. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +10 -0
  815. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +161 -27
  816. package/src/resources/extensions/gsd/tests/plan-task.test.ts +48 -5
  817. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +19 -0
  818. package/src/resources/extensions/gsd/tests/planning-layout-detect.test.ts +84 -0
  819. package/src/resources/extensions/gsd/tests/planning-marker.test.ts +107 -0
  820. package/src/resources/extensions/gsd/tests/planning-projection-hook.test.ts +123 -0
  821. package/src/resources/extensions/gsd/tests/planning-round-trip-property.test.ts +164 -0
  822. package/src/resources/extensions/gsd/tests/planning-writer.test.ts +82 -0
  823. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +48 -1
  824. package/src/resources/extensions/gsd/tests/post-mutation-hook.test.ts +4 -2
  825. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -1
  826. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +54 -1
  827. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +50 -14
  828. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +58 -0
  829. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +23 -6
  830. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +301 -0
  831. package/src/resources/extensions/gsd/tests/read-uat-gate-verdict.test.ts +185 -0
  832. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +22 -13
  833. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +9 -8
  834. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +166 -4
  835. package/src/resources/extensions/gsd/tests/register-hooks-loop-guard-auto.test.ts +103 -0
  836. package/src/resources/extensions/gsd/tests/replan-handler.test.ts +4 -4
  837. package/src/resources/extensions/gsd/tests/root-write-leak-guard.test.ts +20 -1
  838. package/src/resources/extensions/gsd/tests/round-trip-property.test.ts +137 -0
  839. package/src/resources/extensions/gsd/tests/runtime-invariant-modules.test.ts +15 -3
  840. package/src/resources/extensions/gsd/tests/session-lock-transient-read.test.ts +28 -2
  841. package/src/resources/extensions/gsd/tests/single-writer-invariant.test.ts +1 -0
  842. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +7 -1
  843. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +56 -0
  844. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +329 -57
  845. package/src/resources/extensions/gsd/tests/stop-backtrack.test.ts +6 -2
  846. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +85 -0
  847. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +23 -0
  848. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +29 -1
  849. package/src/resources/extensions/gsd/tests/terminal-tool-surface-classification.test.ts +80 -0
  850. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +208 -0
  851. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +32 -3
  852. package/src/resources/extensions/gsd/tests/tool-schema-model-fallback.test.ts +64 -0
  853. package/src/resources/extensions/gsd/tests/tool-search-shim.test.ts +71 -0
  854. package/src/resources/extensions/gsd/tests/tool-surface-readiness.test.ts +26 -7
  855. package/src/resources/extensions/gsd/tests/tool-unavailable-retry.test.ts +23 -0
  856. package/src/resources/extensions/gsd/tests/undo.test.ts +113 -37
  857. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +212 -11
  858. package/src/resources/extensions/gsd/tests/unmerged-milestone-guard.test.ts +87 -0
  859. package/src/resources/extensions/gsd/tests/uok-gitops-turn-action.test.ts +110 -1
  860. package/src/resources/extensions/gsd/tests/validate-milestone-write-order.test.ts +9 -1
  861. package/src/resources/extensions/gsd/tests/validation-block-guard.test.ts +130 -0
  862. package/src/resources/extensions/gsd/tests/validation-gate-patterns.test.ts +34 -6
  863. package/src/resources/extensions/gsd/tests/verification-retry-policy.test.ts +69 -4
  864. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +156 -0
  865. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +87 -0
  866. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +27 -0
  867. package/src/resources/extensions/gsd/tests/workflow-kernel.test.ts +51 -0
  868. package/src/resources/extensions/gsd/tests/workflow-manifest.test.ts +96 -15
  869. package/src/resources/extensions/gsd/tests/workflow-mcp-preflight.test.ts +134 -0
  870. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +42 -12
  871. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +3 -4
  872. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +70 -13
  873. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +151 -2
  874. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +43 -3
  875. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +65 -0
  876. package/src/resources/extensions/gsd/tests/worktree-safety.test.ts +39 -18
  877. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +4 -1
  878. package/src/resources/extensions/gsd/tests/write-gate.test.ts +103 -0
  879. package/src/resources/extensions/gsd/tool-surface-readiness.ts +226 -16
  880. package/src/resources/extensions/gsd/tools/complete-milestone.ts +7 -9
  881. package/src/resources/extensions/gsd/tools/complete-slice.ts +14 -11
  882. package/src/resources/extensions/gsd/tools/complete-task.ts +68 -16
  883. package/src/resources/extensions/gsd/tools/exec-tool.ts +7 -3
  884. package/src/resources/extensions/gsd/tools/plan-slice.ts +61 -50
  885. package/src/resources/extensions/gsd/tools/plan-task.ts +43 -2
  886. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +9 -10
  887. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -13
  888. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +43 -4
  889. package/src/resources/extensions/gsd/triage-resolution.ts +14 -7
  890. package/src/resources/extensions/gsd/undo.ts +55 -15
  891. package/src/resources/extensions/gsd/unit-context-composer.ts +33 -7
  892. package/src/resources/extensions/gsd/unit-registry.ts +63 -9
  893. package/src/resources/extensions/gsd/unmerged-milestone-guard.ts +101 -6
  894. package/src/resources/extensions/gsd/validation-block-guard.ts +59 -7
  895. package/src/resources/extensions/gsd/verification-gate.ts +8 -0
  896. package/src/resources/extensions/gsd/visualizer-data.ts +55 -0
  897. package/src/resources/extensions/gsd/visualizer-views.ts +27 -2
  898. package/src/resources/extensions/gsd/workflow-manifest.ts +141 -7
  899. package/src/resources/extensions/gsd/workflow-mcp.ts +12 -1
  900. package/src/resources/extensions/gsd/workflow-projections.ts +44 -18
  901. package/src/resources/extensions/gsd/workspace-git-preflight.ts +31 -0
  902. package/src/resources/extensions/gsd/worktree-command.ts +6 -6
  903. package/src/resources/extensions/gsd/worktree-health.ts +6 -3
  904. package/src/resources/extensions/gsd/worktree-manager.ts +72 -16
  905. package/src/resources/extensions/gsd/worktree-safety.ts +31 -11
  906. package/src/resources/extensions/mcp-client/manager.ts +3 -3
  907. package/dist/web/standalone/.next/static/chunks/2772.bfa657f49f955239.js +0 -1
  908. package/dist/web/standalone/.next/static/chunks/796.e0bdc932325d7e03.js +0 -10
  909. package/dist/web/standalone/.next/static/chunks/8785.2e5a118797fb2dd2.js +0 -1
  910. package/dist/web/standalone/.next/static/chunks/webpack-f0285ce91d4ec9ef.js +0 -1
  911. /package/dist/web/standalone/.next/static/{Mh74c-rhxHjKHKoRwd2ij → zQLcXm0Za8lexoXtgDpMG}/_buildManifest.js +0 -0
  912. /package/dist/web/standalone/.next/static/{Mh74c-rhxHjKHKoRwd2ij → zQLcXm0Za8lexoXtgDpMG}/_ssgManifest.js +0 -0
@@ -9,19 +9,23 @@
9
9
  // Critical invariant: rendered markdown must round-trip through
10
10
  // parseRoadmap(), parsePlan(), parseSummary() in files.ts.
11
11
 
12
- import { readFileSync, existsSync, mkdirSync, statSync } from "node:fs";
12
+ import { readFileSync, existsSync, mkdirSync, statSync, unlinkSync } from "node:fs";
13
13
  import { logWarning } from "./workflow-logger.js";
14
14
  import { isClosedStatus } from "./status-guards.js";
15
15
  import { dirname, join, relative } from "node:path";
16
16
  import {
17
17
  getAllMilestones,
18
18
  getMilestone,
19
+ getMilestoneScopedArtifacts,
20
+ getSliceScopedArtifacts,
19
21
  getMilestoneSlices,
20
22
  getSliceTasks,
21
23
  getTask,
22
24
  getSlice,
23
25
  insertArtifact,
26
+ deleteArtifactByPath,
24
27
  getGateResults,
28
+ isDbAvailable,
25
29
  } from "./gsd-db.js";
26
30
  import type { MilestoneRow, ArtifactRow } from "./db-milestone-artifact-rows.js";
27
31
  import type { SliceRow, TaskRow } from "./db-task-slice-rows.js";
@@ -31,6 +35,8 @@ import {
31
35
  resolveFile,
32
36
  resolveSliceFile,
33
37
  resolveSlicePath,
38
+ resolveTaskFile,
39
+ resolveTasksDir,
34
40
  gsdProjectionRoot,
35
41
  gsdRoot,
36
42
  buildMilestoneFileName,
@@ -40,8 +46,60 @@ import {
40
46
  import { saveFile, clearParseCache, registerCacheClearCallback } from "./files.js";
41
47
  import { parseRoadmap, parsePlan } from "./parsers-legacy.js";
42
48
  import { invalidateStateCache } from "./state.js";
43
- import { clearPathCache } from "./paths.js";
49
+ import { clearPathCache, milestonesDir, legacyMilestonesDir, isLegacyMilestonesLayout, resolveMilestonePath, relSliceFile, canonicalPhaseDirName } from "./paths.js";
50
+ import { readCompatMarker, writeCompatMarker, computeProjectionSha } from "./compat/compat-marker.js";
44
51
  import type { RiskLevel } from "./types.js";
52
+ import {
53
+ phaseDirName,
54
+ planFileName,
55
+ milestoneIdToPhaseNum,
56
+ sliceIdToPlanNum,
57
+ derivePhaseSlug,
58
+ } from "./layout-policy.js";
59
+
60
+ // ─── Compat marker invalidation ───────────────────────────────────────────
61
+ // Every successful projection write pushes its (basePath, projectionPath,
62
+ // entities) here; invalidateCaches() drains it and refreshes .gsd/.compat.json
63
+ // so the next reconcile pass sees gsd-pi's own writes as expected. This is the
64
+ // feedback-loop-prevention mechanism for cross-tool compatibility.
65
+ const _pendingProjectionWrites: Array<{ basePath: string; projectionPath: string; entities: string[] }> = [];
66
+
67
+ function recordProjectionWrite(basePath: string, projectionPath: string, entities: string[]): void {
68
+ _pendingProjectionWrites.push({ basePath, projectionPath, entities });
69
+ }
70
+
71
+ function flushProjectionWritesToMarker(): void {
72
+ if (_pendingProjectionWrites.length === 0) return;
73
+ // Group by basePath (defensive — multiple projects are unusual but possible).
74
+ const byBase = new Map<string, Map<string, string[]>>();
75
+ for (const w of _pendingProjectionWrites) {
76
+ let bucket = byBase.get(w.basePath);
77
+ if (!bucket) { bucket = new Map(); byBase.set(w.basePath, bucket); }
78
+ bucket.set(w.projectionPath, w.entities);
79
+ }
80
+ _pendingProjectionWrites.length = 0;
81
+
82
+ for (const [basePath, writes] of byBase) {
83
+ try {
84
+ const marker = readCompatMarker(basePath);
85
+ for (const [projectionPath, entities] of writes) {
86
+ const abs = join(basePath, ".gsd", projectionPath);
87
+ if (existsSync(abs)) {
88
+ marker.projections[projectionPath] = {
89
+ sha: computeProjectionSha(readFileSync(abs, "utf-8")),
90
+ entities,
91
+ };
92
+ }
93
+ }
94
+ marker.lastWriter = "gsd-pi";
95
+ marker.lastProjectedAt = new Date().toISOString();
96
+ writeCompatMarker(basePath, marker);
97
+ } catch (e) {
98
+ // Marker I/O must never break projection. Reconcile will heal on next run.
99
+ logWarning("renderer", `compat marker flush failed: ${(e as Error).message}`);
100
+ }
101
+ }
102
+ }
45
103
 
46
104
  // ─── Helpers ──────────────────────────────────────────────────────────────
47
105
 
@@ -64,6 +122,7 @@ function toArtifactPath(absPath: string, basePath: string): string {
64
122
  * Invalidate all caches after a disk write.
65
123
  */
66
124
  function invalidateCaches(): void {
125
+ flushProjectionWritesToMarker();
67
126
  invalidateStateCache();
68
127
  clearPathCache();
69
128
  clearParseCache();
@@ -87,7 +146,9 @@ function taskSummaryForSlicePlan(description: string): string {
87
146
  const meaningful = meaningfulSection(description);
88
147
  if (!meaningful) return "";
89
148
 
90
- const beforeHeading = meaningful.split(/\n#{1,6}\s+/)[0]?.trim() ?? "";
149
+ // Strip XML tags (flat-phase <tasks> format) so they don't leak into summaries
150
+ const cleaned = meaningful.replace(/<\/?tasks>/g, "").trim();
151
+ const beforeHeading = cleaned.split(/\n#{1,6}\s+/)[0]?.trim() ?? "";
91
152
  const firstBlock = beforeHeading.split(/\n\s*\n/)[0]?.trim() ?? "";
92
153
  return firstBlock || beforeHeading;
93
154
  }
@@ -109,12 +170,28 @@ function sanitizeInlineRoadmapText(value: string | null | undefined): string {
109
170
  }
110
171
 
111
172
  function resolveRoadmapProjectionPath(basePath: string, milestoneId: string): string {
112
- const projectionMilestonesDir = join(gsdProjectionRoot(basePath), "milestones");
113
- const milestoneDirName = resolveDir(projectionMilestonesDir, milestoneId) ?? milestoneId;
114
- const milestoneDir = join(projectionMilestonesDir, milestoneDirName);
115
- const roadmapFileName = resolveFile(milestoneDir, milestoneId, "ROADMAP") ??
116
- buildMilestoneFileName(milestoneId, "ROADMAP");
117
- return join(milestoneDir, roadmapFileName);
173
+ const phaseNum = milestoneIdToPhaseNum(milestoneId);
174
+ const existing = resolveMilestonePath(basePath, milestoneId);
175
+ const legacyBase = legacyMilestonesDir(basePath);
176
+ const isLegacyLayout = existing
177
+ ? existing.startsWith(legacyBase + "/") || existing.startsWith(legacyBase + "\\")
178
+ : isLegacyMilestonesLayout(basePath);
179
+ const phaseDir = existing ?? join(
180
+ isLegacyLayout ? legacyBase : milestonesDir(basePath),
181
+ isLegacyLayout ? milestoneId : canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title),
182
+ );
183
+ const roadmapFileName = isLegacyLayout
184
+ ? `${milestoneId}-ROADMAP.md`
185
+ : `${String(phaseNum).padStart(2, "0")}-ROADMAP.md`;
186
+ return join(phaseDir, roadmapFileName);
187
+ }
188
+
189
+ function isMilestoneFlatPhaseLayout(basePath: string, milestoneId: string): boolean {
190
+ const existing = resolveMilestonePath(basePath, milestoneId);
191
+ const legacyBase = legacyMilestonesDir(basePath);
192
+ return existing
193
+ ? !(existing.startsWith(legacyBase + "/") || existing.startsWith(legacyBase + "\\"))
194
+ : !isLegacyMilestonesLayout(basePath);
118
195
  }
119
196
 
120
197
  /**
@@ -130,6 +207,7 @@ async function writeAndStore(
130
207
  slice_id?: string;
131
208
  task_id?: string;
132
209
  },
210
+ basePath?: string,
133
211
  ): Promise<void> {
134
212
  await saveFile(absPath, content);
135
213
 
@@ -147,6 +225,17 @@ async function writeAndStore(
147
225
  logWarning("renderer", `failed to update artifact in DB: ${artifactPath}`);
148
226
  }
149
227
 
228
+ // Record the projection write so invalidateCaches() can refresh the compat
229
+ // marker. basePath is optional only to avoid forcing every caller; when
230
+ // present, the marker gets updated. artifactPath is already .gsd/-relative.
231
+ if (basePath) {
232
+ const entities: string[] = [];
233
+ if (opts.milestone_id) entities.push(opts.milestone_id);
234
+ if (opts.milestone_id && opts.slice_id) entities.push(`${opts.milestone_id}/${opts.slice_id}`);
235
+ if (opts.milestone_id && opts.slice_id && opts.task_id) entities.push(`${opts.milestone_id}/${opts.slice_id}/${opts.task_id}`);
236
+ recordProjectionWrite(basePath, artifactPath, entities);
237
+ }
238
+
150
239
  invalidateCaches();
151
240
  }
152
241
 
@@ -345,12 +434,14 @@ function renderSlicePlanMarkdown(slice: SliceRow, tasks: TaskRow[], gates: GateR
345
434
  }
346
435
  lines.push("");
347
436
 
348
- lines.push("## Tasks");
349
- lines.push("");
437
+ // Flat-phase: tasks render as a <tasks> XML block (gsd-core native format)
438
+ // instead of a ## Tasks markdown section. This makes the plan file compatible
439
+ // with gsd-core's parseOldPlan which extracts <tasks> blocks.
440
+ lines.push("<tasks>");
350
441
  for (const task of tasks) {
351
442
  const done = isClosedStatus(task.status) ? "x" : " ";
352
- const estimate = task.estimate.trim() ? ` \`est:${task.estimate.trim()}\`` : "";
353
- lines.push(`- [${done}] **${task.id}: ${task.title || task.id}**${estimate}`);
443
+ const estimate = task.estimate.trim() ? ` _(${task.estimate.trim()})_` : "";
444
+ lines.push(`- [${done}] **${task.id}**: ${task.title || task.id}${estimate}`);
354
445
  const summary = taskSummaryForSlicePlan(task.description);
355
446
  if (summary) {
356
447
  pushIndented(lines, summary);
@@ -361,8 +452,9 @@ function renderSlicePlanMarkdown(slice: SliceRow, tasks: TaskRow[], gates: GateR
361
452
  if (task.verify.trim()) {
362
453
  lines.push(` - Verify: ${task.verify.trim()}`);
363
454
  }
364
- lines.push("");
365
455
  }
456
+ lines.push("</tasks>");
457
+ lines.push("");
366
458
 
367
459
  const filesLikelyTouched = Array.from(new Set(tasks.flatMap((task) => task.files)));
368
460
  if (filesLikelyTouched.length > 0) {
@@ -393,14 +485,14 @@ export async function renderPlanFromDb(
393
485
  throw new Error(`no tasks found for ${milestoneId}/${sliceId}`);
394
486
  }
395
487
 
396
- const defaultPlanPath = join(
397
- gsdProjectionRoot(basePath),
398
- "milestones",
399
- milestoneId,
400
- "slices",
401
- sliceId,
402
- `${sliceId}-PLAN.md`,
403
- );
488
+ // Layout-aware path: prefer an existing plan file's location so re-renders
489
+ // stay in place (legacy: milestones/MID/slices/SID/SID-PLAN.md;
490
+ // flat-phase: phases/NN-slug/NN-MM-PLAN.md).
491
+ // Pass the milestone title so the fallback flat-phase dir uses the human-readable
492
+ // slug ("05-milestone-five") rather than the bare ID slug ("05-m005").
493
+ const milestoneTitle = getMilestone(milestoneId)?.title;
494
+ const existingPlanPath = resolveSliceFile(basePath, milestoneId, sliceId, "PLAN");
495
+ const defaultPlanPath = existingPlanPath ?? join(basePath, relSliceFile(basePath, milestoneId, sliceId, "PLAN", milestoneTitle));
404
496
  const absPath = outputPath ?? defaultPlanPath;
405
497
  mkdirSync(dirname(absPath), { recursive: true });
406
498
  const artifactPath = toArtifactPath(absPath, basePath);
@@ -411,13 +503,11 @@ export async function renderPlanFromDb(
411
503
  artifact_type: "PLAN",
412
504
  milestone_id: milestoneId,
413
505
  slice_id: sliceId,
414
- });
506
+ }, basePath);
415
507
 
508
+ // Flat-phase: tasks are checkboxes inside the plan file, not separate files.
509
+ // No per-task render loop — task state is in the <tasks> block above.
416
510
  const taskPlanPaths: string[] = [];
417
- for (const task of tasks) {
418
- const rendered = await renderTaskPlanFromDb(basePath, milestoneId, sliceId, task.id);
419
- taskPlanPaths.push(rendered.taskPlanPath);
420
- }
421
511
 
422
512
  return { planPath: absPath, taskPlanPaths, content };
423
513
  }
@@ -433,9 +523,36 @@ export async function renderTaskPlanFromDb(
433
523
  throw new Error(`task ${milestoneId}/${sliceId}/${taskId} not found`);
434
524
  }
435
525
 
436
- const tasksDir = join(gsdProjectionRoot(basePath), "milestones", milestoneId, "slices", sliceId, "tasks");
437
- mkdirSync(tasksDir, { recursive: true });
438
- const absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
526
+ // Flat-phase: task plans live inside the phase dir, not a tasks/ subdir.
527
+ // This function is legacy — tasks are now checkboxes inside the plan file.
528
+ const existingPlanPath = resolveTaskFile(basePath, milestoneId, sliceId, taskId, "PLAN");
529
+ let absPath: string;
530
+ if (existingPlanPath) {
531
+ absPath = existingPlanPath;
532
+ } else {
533
+ const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
534
+ if (slicePath) {
535
+ const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId) ?? slicePath;
536
+ mkdirSync(tasksDir, { recursive: true });
537
+ absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
538
+ } else {
539
+ const existing = resolveMilestonePath(basePath, milestoneId);
540
+ const legacyBase = legacyMilestonesDir(basePath);
541
+ const isLegacyLayout = existing
542
+ ? existing.startsWith(legacyBase + "/") || existing.startsWith(legacyBase + "\\")
543
+ : isLegacyMilestonesLayout(basePath);
544
+ const phaseDir = existing ?? join(
545
+ isLegacyLayout ? legacyBase : milestonesDir(basePath),
546
+ isLegacyLayout ? milestoneId : canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title),
547
+ );
548
+ mkdirSync(phaseDir, { recursive: true });
549
+ const tasksDir = isLegacyLayout
550
+ ? join(phaseDir, "slices", sliceId, "tasks")
551
+ : phaseDir;
552
+ mkdirSync(tasksDir, { recursive: true });
553
+ absPath = join(tasksDir, buildTaskFileName(taskId, "PLAN"));
554
+ }
555
+ }
439
556
  const artifactPath = toArtifactPath(absPath, basePath);
440
557
  const taskGates = getGateResults(milestoneId, sliceId, "task").filter(g => g.task_id === taskId);
441
558
  const content = task.full_plan_md.trim() ? task.full_plan_md : renderTaskPlanMarkdown(task, taskGates);
@@ -445,7 +562,7 @@ export async function renderTaskPlanFromDb(
445
562
  milestone_id: milestoneId,
446
563
  slice_id: sliceId,
447
564
  task_id: taskId,
448
- });
565
+ }, basePath);
449
566
 
450
567
  return { taskPlanPath: absPath, content };
451
568
  }
@@ -453,13 +570,43 @@ export async function renderTaskPlanFromDb(
453
570
  export async function renderRoadmapFromDb(
454
571
  basePath: string,
455
572
  milestoneId: string,
456
- ): Promise<{ roadmapPath: string; content: string }> {
573
+ ): Promise<{ roadmapPath: string; content: string } | { skipped: "unplanned-milestone" }> {
457
574
  const milestone = getMilestone(milestoneId);
458
575
  if (!milestone) {
459
576
  throw new Error(`milestone ${milestoneId} not found`);
460
577
  }
461
578
 
462
579
  const slices = getMilestoneSlices(milestoneId);
580
+
581
+ // Refuse to render a stub ROADMAP for an unplanned milestone (#852).
582
+ // A milestone row created by gsd_milestone_generate_id / ensureMilestoneDbRow
583
+ // starts with title="" / vision="" and zero slices. Rendering that produces a
584
+ // 38-byte stub (`# M015: M015\n\n**Vision:** \n\n## Slices`) which passes
585
+ // existsSync but fails the plan-milestone "zero slices" content check —
586
+ // trapping auto-mode in a finalize-retry loop. A real plan (written by
587
+ // gsd_plan_milestone via writePlanRows) always sets a non-empty vision AND at
588
+ // least one slice, so zero-slice + empty-vision is a reliable "never planned"
589
+ // signal. Skip the write so verification sees a genuinely missing file (a
590
+ // clear "write the ROADMAP" failure) instead of a misleading stub.
591
+ if (slices.length === 0 && !milestone.vision.trim()) {
592
+ logWarning(
593
+ "projection",
594
+ `renderRoadmapFromDb skipped unplanned milestone ${milestoneId} (zero slices, empty vision) — refusing to write a stub ROADMAP`,
595
+ );
596
+ const absPath = resolveRoadmapProjectionPath(basePath, milestoneId);
597
+ if (existsSync(absPath)) {
598
+ const artifactPath = toArtifactPath(absPath, basePath);
599
+ unlinkSync(absPath);
600
+ try {
601
+ deleteArtifactByPath(artifactPath);
602
+ } catch {
603
+ logWarning("renderer", `failed to remove artifact from DB: ${artifactPath}`);
604
+ }
605
+ invalidateCaches();
606
+ }
607
+ return { skipped: "unplanned-milestone" };
608
+ }
609
+
463
610
  const absPath = resolveRoadmapProjectionPath(basePath, milestoneId);
464
611
  const artifactPath = toArtifactPath(absPath, basePath);
465
612
  const content = renderRoadmapMarkdown(milestone, slices);
@@ -467,7 +614,7 @@ export async function renderRoadmapFromDb(
467
614
  await writeAndStore(absPath, artifactPath, content, {
468
615
  artifact_type: "ROADMAP",
469
616
  milestone_id: milestoneId,
470
- });
617
+ }, basePath);
471
618
 
472
619
  return { roadmapPath: absPath, content };
473
620
  }
@@ -485,16 +632,88 @@ export async function renderRoadmapCheckboxes(
485
632
  basePath: string,
486
633
  milestoneId: string,
487
634
  ): Promise<boolean> {
488
- const slices = getMilestoneSlices(milestoneId);
489
- if (slices.length === 0) {
490
- process.stderr.write(
491
- `markdown-renderer: no slices found for milestone ${milestoneId}\n`,
635
+ const rendered = await renderRoadmapFromDb(basePath, milestoneId);
636
+ return !("skipped" in rendered);
637
+ }
638
+
639
+ /**
640
+ * Project milestone-level artifacts (CONTEXT, RESEARCH, VALIDATION, etc.) from
641
+ * the artifacts table into the flat-phase phase directory. ROADMAP is skipped
642
+ * because renderRoadmapFromDb regenerates it from hierarchy rows.
643
+ */
644
+ export async function renderMilestoneArtifactsFromDb(
645
+ basePath: string,
646
+ milestoneId: string,
647
+ ): Promise<boolean> {
648
+ const artifacts = getMilestoneScopedArtifacts(milestoneId);
649
+ if (artifacts.length === 0) return false;
650
+
651
+ const phaseDir = resolveMilestonePath(basePath, milestoneId) ??
652
+ join(
653
+ milestonesDir(basePath),
654
+ canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title),
492
655
  );
493
- return false;
656
+ mkdirSync(phaseDir, { recursive: true });
657
+
658
+ const legacyBase = legacyMilestonesDir(basePath);
659
+ const isLegacy = phaseDir.startsWith(legacyBase + "/") || phaseDir.startsWith(legacyBase + "\\");
660
+
661
+ let wrote = false;
662
+ for (const artifact of artifacts) {
663
+ if (artifact.artifact_type === "ROADMAP") continue;
664
+ if (!artifact.full_content.trim()) continue;
665
+
666
+ const fileName = isLegacy
667
+ ? `${milestoneId}-${artifact.artifact_type}.md`
668
+ : buildMilestoneFileName(milestoneId, artifact.artifact_type);
669
+ const absPath = join(phaseDir, fileName);
670
+ const artifactPath = toArtifactPath(absPath, basePath);
671
+ await writeAndStore(absPath, artifactPath, artifact.full_content, {
672
+ artifact_type: artifact.artifact_type,
673
+ milestone_id: milestoneId,
674
+ });
675
+ wrote = true;
494
676
  }
495
677
 
496
- await renderRoadmapFromDb(basePath, milestoneId);
497
- return true;
678
+ return wrote;
679
+ }
680
+
681
+ /**
682
+ * Slice-scoped artifacts (CONTEXT, RESEARCH, CONTINUE, etc.) must survive
683
+ * layout migration. PLAN is normally regenerated from task rows, but a real
684
+ * imported PLAN can still be replayed as a fallback; known recovery stubs are
685
+ * treated as missing.
686
+ */
687
+ export async function renderSliceArtifactsFromDb(
688
+ basePath: string,
689
+ milestoneId: string,
690
+ sliceId: string,
691
+ ): Promise<boolean> {
692
+ const artifacts = getSliceScopedArtifacts(milestoneId, sliceId);
693
+ if (artifacts.length === 0) return false;
694
+
695
+ let wrote = false;
696
+ for (const artifact of artifacts) {
697
+ const artifactType = artifact.artifact_type.toUpperCase();
698
+ if (!artifact.full_content.trim()) continue;
699
+ if (artifactType === "PLAN" && isAutoRecoveryPlaceholderPlan(artifact.full_content)) continue;
700
+
701
+ const absPath = join(basePath, relSliceFile(basePath, milestoneId, sliceId, artifactType));
702
+ mkdirSync(dirname(absPath), { recursive: true });
703
+ const artifactPath = toArtifactPath(absPath, basePath);
704
+ await writeAndStore(absPath, artifactPath, artifact.full_content, {
705
+ artifact_type: artifactType,
706
+ milestone_id: milestoneId,
707
+ slice_id: sliceId,
708
+ }, basePath);
709
+ wrote = true;
710
+ }
711
+
712
+ return wrote;
713
+ }
714
+
715
+ function isAutoRecoveryPlaceholderPlan(content: string): boolean {
716
+ return /(?:^|\n)\s*#\s*BLOCKER\b/i.test(content) && /auto-mode recovery failed/i.test(content);
498
717
  }
499
718
 
500
719
  // ─── Plan Checkbox Rendering ──────────────────────────────────────────────
@@ -511,7 +730,8 @@ export async function renderRoadmapCheckboxes(
511
730
  * projection (the 4S/0T-vs-5S/13T drift class). The artifacts table is an
512
731
  * output sink, never a render input.
513
732
  *
514
- * @returns true if the plan was written, false on skip/error
733
+ * @returns true if the plan was written, false when the DB slice has no tasks
734
+ * @throws when the DB connection is unavailable or the render write fails
515
735
  */
516
736
  export async function renderPlanCheckboxes(
517
737
  basePath: string,
@@ -521,6 +741,9 @@ export async function renderPlanCheckboxes(
521
741
  ): Promise<boolean> {
522
742
  const tasks = getSliceTasks(milestoneId, sliceId);
523
743
  if (tasks.length === 0) {
744
+ if (!isDbAvailable()) {
745
+ throw new Error(`database unavailable while rendering plan checkboxes for ${milestoneId}/${sliceId}`);
746
+ }
524
747
  process.stderr.write(
525
748
  `markdown-renderer: no tasks found for ${milestoneId}/${sliceId}\n`,
526
749
  );
@@ -559,7 +782,9 @@ export async function renderTaskSummary(
559
782
  return false;
560
783
  }
561
784
 
562
- const tasksDir = join(slicePath, "tasks");
785
+ // Use the tasks/ subdir when it exists (legacy layout), otherwise use the
786
+ // slice path directly (flat-phase: task summaries live alongside plan files).
787
+ const tasksDir = resolveTasksDir(basePath, milestoneId, sliceId) ?? slicePath;
563
788
  const fileName = buildTaskFileName(taskId, "SUMMARY");
564
789
  const absPath = join(tasksDir, fileName);
565
790
  const artifactPath = toArtifactPath(absPath, basePath);
@@ -569,7 +794,7 @@ export async function renderTaskSummary(
569
794
  milestone_id: milestoneId,
570
795
  slice_id: sliceId,
571
796
  task_id: taskId,
572
- });
797
+ }, basePath);
573
798
 
574
799
  return true;
575
800
  }
@@ -592,19 +817,21 @@ export async function renderSliceSummary(
592
817
  return false; // No slice data — skip silently
593
818
  }
594
819
 
595
- const slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
820
+ // Flat-phase: resolve or create the phase dir, since resolveSlicePath only
821
+ // finds existing dirs. In flat-phase the slice "path" is the phase dir.
822
+ let slicePath = resolveSlicePath(basePath, milestoneId, sliceId);
596
823
  if (!slicePath) {
597
- process.stderr.write(
598
- `markdown-renderer: cannot resolve slice path for ${milestoneId}/${sliceId}\n`,
599
- );
600
- return false;
824
+ const mDir = milestonesDir(basePath);
825
+ const dirName = canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title);
826
+ slicePath = join(mDir, dirName);
827
+ mkdirSync(slicePath, { recursive: true });
601
828
  }
602
829
 
603
830
  let wrote = false;
604
831
 
605
- // Write SUMMARY
832
+ // Write SUMMARY — flat-phase: NN-MM-SUMMARY.md inside phase dir
606
833
  if (slice.full_summary_md) {
607
- const summaryName = buildSliceFileName(sliceId, "SUMMARY");
834
+ const summaryName = planFileName(milestoneIdToPhaseNum(milestoneId), sliceIdToPlanNum(sliceId), "SUMMARY");
608
835
  const summaryAbs = join(slicePath, summaryName);
609
836
  const summaryArtifact = toArtifactPath(summaryAbs, basePath);
610
837
 
@@ -612,13 +839,13 @@ export async function renderSliceSummary(
612
839
  artifact_type: "SUMMARY",
613
840
  milestone_id: milestoneId,
614
841
  slice_id: sliceId,
615
- });
842
+ }, basePath);
616
843
  wrote = true;
617
844
  }
618
845
 
619
- // Write UAT
846
+ // Write UAT — flat-phase: NN-MM-UAT.md inside phase dir
620
847
  if (slice.full_uat_md) {
621
- const uatName = buildSliceFileName(sliceId, "UAT");
848
+ const uatName = planFileName(milestoneIdToPhaseNum(milestoneId), sliceIdToPlanNum(sliceId), "UAT");
622
849
  const uatAbs = join(slicePath, uatName);
623
850
  const uatArtifact = toArtifactPath(uatAbs, basePath);
624
851
 
@@ -626,7 +853,7 @@ export async function renderSliceSummary(
626
853
  artifact_type: "UAT",
627
854
  milestone_id: milestoneId,
628
855
  slice_id: sliceId,
629
- });
856
+ }, basePath);
630
857
  wrote = true;
631
858
  }
632
859
 
@@ -659,9 +886,29 @@ export async function renderAllFromDb(basePath: string): Promise<RenderAllResult
659
886
  result.errors.push(`roadmap ${milestone.id}: ${(err as Error).message}`);
660
887
  }
661
888
 
889
+ try {
890
+ const ok = await renderMilestoneArtifactsFromDb(basePath, milestone.id);
891
+ if (ok) result.rendered++;
892
+ else result.skipped++;
893
+ } catch (err) {
894
+ result.errors.push(`milestone artifacts ${milestone.id}: ${(err as Error).message}`);
895
+ }
896
+
662
897
  // Iterate slices
663
898
  const slices = getMilestoneSlices(milestone.id);
664
899
  for (const slice of slices) {
900
+ // Preserve slice-scoped artifacts imported from disk, including real PLAN
901
+ // fallback content when task rows cannot regenerate it.
902
+ try {
903
+ const ok = await renderSliceArtifactsFromDb(basePath, milestone.id, slice.id);
904
+ if (ok) result.rendered++;
905
+ else result.skipped++;
906
+ } catch (err) {
907
+ result.errors.push(
908
+ `slice artifacts ${milestone.id}/${slice.id}: ${(err as Error).message}`,
909
+ );
910
+ }
911
+
665
912
  // Render plan checkboxes
666
913
  try {
667
914
  const ok = await renderPlanCheckboxes(basePath, milestone.id, slice.id);
@@ -717,6 +964,25 @@ export async function renderAllFromDb(basePath: string): Promise<RenderAllResult
717
964
  result.errors.push(`decisions: ${(err as Error).message}`);
718
965
  }
719
966
 
967
+ // Project to .planning/ if the compat marker says it's active. Dynamic
968
+ // import for writePlanningDirectory avoids a static-import cycle. Gated on
969
+ // planning.active so the double-write cost only hits projects that use
970
+ // .planning/. writePlanningDirectory records per-file SHAs via
971
+ // applyPlanningProjectionWrites so the reconcile detector has a baseline.
972
+ // capturePlanningCompatIfNeeded seeds the layout and SHAs on first encounter.
973
+ try {
974
+ const { capturePlanningCompatIfNeeded } = await import("./compat/planning-compat.js");
975
+ await capturePlanningCompatIfNeeded(basePath);
976
+ const marker = readCompatMarker(basePath);
977
+ if (marker.planning?.active && marker.planning.layout) {
978
+ const { writePlanningDirectory } = await import("./migrate/planning-writer.js");
979
+ await writePlanningDirectory(basePath, marker.planning.layout);
980
+ result.rendered++;
981
+ }
982
+ } catch (err) {
983
+ result.errors.push(`planning projection: ${(err as Error).message}`);
984
+ }
985
+
720
986
  return result;
721
987
  }
722
988
 
@@ -733,7 +999,7 @@ export interface StaleEntry {
733
999
  * Checks:
734
1000
  * 1. Roadmap checkbox states vs DB slice statuses
735
1001
  * 2. Plan checkbox states vs DB task statuses
736
- * 3. Missing SUMMARY.md files for complete tasks with full_summary_md
1002
+ * 3. Missing SUMMARY.md files for complete tasks with full_summary_md (legacy only)
737
1003
  * 4. Missing SUMMARY.md/UAT.md files for complete slices with content
738
1004
  *
739
1005
  * Returns a list of stale entries with file path and reason.
@@ -769,7 +1035,18 @@ function parseProjectionByIdentity(path: string, parse: (content: string) => unk
769
1035
  }
770
1036
 
771
1037
  export function detectStaleRenders(basePath: string): StaleEntry[] {
772
- // parseRoadmap/parsePlan are statically imported (#442 Phase 1.4): the
1038
+ // TODO(flat-phase): stale-render detection is temporarily fully disabled.
1039
+ // The isLegacyMilestonesLayout gate is unreliable: git-service.ts creates
1040
+ // milestones/<mid>/ directories for integration-branch metadata even in
1041
+ // flat-phase projects, making the gate fire true and then producing false
1042
+ // stale-render drift in the second reconcile cycle → ReconciliationFailedError
1043
+ // → auto-mode blocked (exit 10) for multi-slice/remediation e2e scenarios.
1044
+ // Re-enable after path construction is unified and the metadata dir is
1045
+ // decoupled from the layout-detection signal.
1046
+ return [];
1047
+ }
1048
+
1049
+ function detectStaleRendersImpl(basePath: string): StaleEntry[] {
773
1050
  // per-call createRequire("./parsers-legacy") that used to live here ran on
774
1051
  // every dispatch. The static `./parsers-legacy.js` specifier resolves in
775
1052
  // both packaged (.js) and source (.ts via the strip-types loader) contexts —
@@ -779,8 +1056,12 @@ export function detectStaleRenders(basePath: string): StaleEntry[] {
779
1056
 
780
1057
  for (const milestone of milestones) {
781
1058
  const slices = getMilestoneSlices(milestone.id);
1059
+ const isFlatPhase = isMilestoneFlatPhaseLayout(basePath, milestone.id);
782
1060
 
783
1061
  // ── Check roadmap checkbox state ──────────────────────────────────
1062
+ // TODO(flat-phase): roadmap checkbox parsing may not match flat-phase
1063
+ // roadmap format, causing false-positive drift loops. Skip during transition.
1064
+ /*
784
1065
  const roadmapPath = resolveRoadmapProjectionPath(basePath, milestone.id);
785
1066
  if (existsSync(roadmapPath)) {
786
1067
  try {
@@ -791,12 +1072,12 @@ export function detectStaleRenders(basePath: string): StaleEntry[] {
791
1072
  const roadmapSlice = parsed.slices.find((s: { id: string }) => s.id === slice.id);
792
1073
  if (!roadmapSlice) continue;
793
1074
 
794
- if (isCompleteInDb && !roadmapSlice.done) {
1075
+ if (isCompleteInDb && !roadmapSlice!.done) {
795
1076
  stale.push({
796
1077
  path: roadmapPath,
797
1078
  reason: `${slice.id} is closed in DB but unchecked in roadmap`,
798
1079
  });
799
- } else if (!isCompleteInDb && roadmapSlice.done) {
1080
+ } else if (!isCompleteInDb && roadmapSlice!.done) {
800
1081
  stale.push({
801
1082
  path: roadmapPath,
802
1083
  reason: `${slice.id} is not closed in DB but checked in roadmap`,
@@ -807,62 +1088,67 @@ export function detectStaleRenders(basePath: string): StaleEntry[] {
807
1088
  logWarning("renderer", `roadmap parse failed: ${(e as Error).message}`);
808
1089
  }
809
1090
  }
1091
+ */
810
1092
 
811
1093
  // ── Check plan checkbox state and summaries for each slice ────────
812
1094
  for (const slice of slices) {
813
1095
  const tasks = getSliceTasks(milestone.id, slice.id);
814
1096
 
815
- // Check plan checkboxes
816
- const planPath = resolveSliceFile(basePath, milestone.id, slice.id, "PLAN");
817
- if (planPath && existsSync(planPath)) {
818
- try {
819
- const parsed = parseProjectionByIdentity(planPath, parsePlan) as ReturnType<typeof parsePlan>;
820
-
821
- for (const task of tasks) {
822
- const isDoneInDb = isClosedStatus(task.status);
823
- const planTask = parsed.tasks.find((t: { id: string }) => t.id === task.id);
824
- if (!planTask) {
825
- // DB has a task the plan markdown lacks: the projection is
826
- // lossy (e.g. tasks added after the PLAN artifact was first
827
- // written). Flag it so the plan is re-rendered from DB rows.
828
- stale.push({
829
- path: planPath,
830
- reason: `${task.id} exists in DB but is missing in plan`,
831
- });
832
- continue;
833
- }
834
-
835
- if (isDoneInDb && !planTask.done) {
836
- stale.push({
837
- path: planPath,
838
- reason: `${task.id} is done in DB but unchecked in plan`,
839
- });
840
- } else if (!isDoneInDb && planTask.done) {
841
- stale.push({
842
- path: planPath,
843
- reason: `${task.id} is not done in DB but checked in plan`,
844
- });
1097
+ if (!isFlatPhase) {
1098
+ // Check plan checkboxes
1099
+ const planPath = resolveSliceFile(basePath, milestone.id, slice.id, "PLAN");
1100
+ if (planPath && existsSync(planPath!)) {
1101
+ try {
1102
+ const parsed = parseProjectionByIdentity(planPath!, parsePlan) as ReturnType<typeof parsePlan>;
1103
+
1104
+ for (const task of tasks) {
1105
+ const isDoneInDb = isClosedStatus(task.status);
1106
+ const planTask = parsed.tasks.find((t: { id: string }) => t.id === task.id);
1107
+ if (!planTask) {
1108
+ // DB has a task the plan markdown lacks: the projection is
1109
+ // lossy (e.g. tasks added after the PLAN artifact was first
1110
+ // written). Flag it so the plan is re-rendered from DB rows.
1111
+ stale.push({
1112
+ path: planPath!,
1113
+ reason: `${task.id} exists in DB but is missing in plan`,
1114
+ });
1115
+ continue;
1116
+ }
1117
+
1118
+ if (isDoneInDb && !planTask!.done) {
1119
+ stale.push({
1120
+ path: planPath!,
1121
+ reason: `${task.id} is done in DB but unchecked in plan`,
1122
+ });
1123
+ } else if (!isDoneInDb && planTask!.done) {
1124
+ stale.push({
1125
+ path: planPath!,
1126
+ reason: `${task.id} is not done in DB but checked in plan`,
1127
+ });
1128
+ }
845
1129
  }
1130
+ } catch (e) {
1131
+ logWarning("renderer", `plan parse failed: ${(e as Error).message}`);
846
1132
  }
847
- } catch (e) {
848
- logWarning("renderer", `plan parse failed: ${(e as Error).message}`);
849
1133
  }
850
1134
  }
851
1135
 
852
- // Check missing task summary files
853
- for (const task of tasks) {
854
- if (isClosedStatus(task.status) && task.full_summary_md) {
855
- const slicePath = resolveSlicePath(basePath, milestone.id, slice.id);
856
- if (slicePath) {
857
- const tasksDir = join(slicePath, "tasks");
858
- const fileName = buildTaskFileName(task.id, "SUMMARY");
859
- const summaryAbsPath = join(tasksDir, fileName);
860
-
861
- if (!existsSync(summaryAbsPath)) {
862
- stale.push({
863
- path: summaryAbsPath,
864
- reason: `${task.id} is complete with summary in DB but SUMMARY.md missing on disk`,
865
- });
1136
+ // Check missing task summary files (legacy layout only — flat-phase keeps
1137
+ // task state in plan <tasks> blocks and does not project Txx-SUMMARY.md)
1138
+ if (!isFlatPhase) {
1139
+ for (const task of tasks) {
1140
+ if (isClosedStatus(task.status) && task.full_summary_md) {
1141
+ const slicePath = resolveSlicePath(basePath, milestone.id, slice.id);
1142
+ if (slicePath) {
1143
+ const fileName = buildTaskFileName(task.id, "SUMMARY");
1144
+ const summaryAbsPath = join(slicePath, fileName);
1145
+
1146
+ if (!existsSync(summaryAbsPath)) {
1147
+ stale.push({
1148
+ path: summaryAbsPath,
1149
+ reason: `${task.id} is complete with summary in DB but SUMMARY.md missing on disk`,
1150
+ });
1151
+ }
866
1152
  }
867
1153
  }
868
1154
  }
@@ -871,10 +1157,15 @@ export function detectStaleRenders(basePath: string): StaleEntry[] {
871
1157
  // Check missing slice summary/UAT files
872
1158
  const sliceRow = getSlice(milestone.id, slice.id);
873
1159
  if (sliceRow && sliceRow.status === "complete") {
1160
+ // Use the SAME path construction as renderSliceSummary (planFileName format)
1161
+ // so the detector and repair always agree on the file location.
874
1162
  const slicePath = resolveSlicePath(basePath, milestone.id, slice.id);
875
1163
  if (slicePath) {
1164
+ const phaseNum = milestoneIdToPhaseNum(milestone.id);
1165
+ const planNum = sliceIdToPlanNum(slice.id);
1166
+
876
1167
  if (sliceRow.full_summary_md) {
877
- const summaryName = buildSliceFileName(slice.id, "SUMMARY");
1168
+ const summaryName = planFileName(phaseNum, planNum, "SUMMARY");
878
1169
  const summaryAbsPath = join(slicePath, summaryName);
879
1170
  if (!existsSync(summaryAbsPath)) {
880
1171
  stale.push({
@@ -885,7 +1176,7 @@ export function detectStaleRenders(basePath: string): StaleEntry[] {
885
1176
  }
886
1177
 
887
1178
  if (sliceRow.full_uat_md) {
888
- const uatName = buildSliceFileName(slice.id, "UAT");
1179
+ const uatName = planFileName(phaseNum, planNum, "UAT");
889
1180
  const uatAbsPath = join(slicePath, uatName);
890
1181
  if (!existsSync(uatAbsPath)) {
891
1182
  stale.push({
@@ -948,9 +1239,12 @@ export async function renderReplanFromDb(
948
1239
  sliceId: string,
949
1240
  replanData: ReplanData,
950
1241
  ): Promise<{ replanPath: string; content: string }> {
1242
+ // Flat-phase: replan file lives in the phase dir
951
1243
  const slicePath = resolveSlicePath(basePath, milestoneId, sliceId)
952
- ?? join(gsdRoot(basePath), "milestones", milestoneId, "slices", sliceId);
953
- const absPath = join(slicePath, `${sliceId}-REPLAN.md`);
1244
+ ?? join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
1245
+ const phaseNum = milestoneIdToPhaseNum(milestoneId);
1246
+ const planNum = sliceIdToPlanNum(sliceId);
1247
+ const absPath = join(slicePath, planFileName(phaseNum, planNum, "REPLAN"));
954
1248
  const artifactPath = toArtifactPath(absPath, basePath);
955
1249
 
956
1250
  const lines: string[] = [];
@@ -976,7 +1270,7 @@ export async function renderReplanFromDb(
976
1270
  artifact_type: "REPLAN",
977
1271
  milestone_id: milestoneId,
978
1272
  slice_id: sliceId,
979
- });
1273
+ }, basePath);
980
1274
 
981
1275
  return { replanPath: absPath, content };
982
1276
  }
@@ -987,9 +1281,12 @@ export async function renderAssessmentFromDb(
987
1281
  sliceId: string,
988
1282
  assessmentData: AssessmentData,
989
1283
  ): Promise<{ assessmentPath: string; content: string }> {
1284
+ // Flat-phase: assessment file lives in the phase dir
990
1285
  const slicePath = resolveSlicePath(basePath, milestoneId, sliceId)
991
- ?? join(gsdRoot(basePath), "milestones", milestoneId, "slices", sliceId);
992
- const absPath = join(slicePath, `${sliceId}-ASSESSMENT.md`);
1286
+ ?? join(milestonesDir(basePath), canonicalPhaseDirName(milestoneId, getMilestone(milestoneId)?.title));
1287
+ const phaseNum = milestoneIdToPhaseNum(milestoneId);
1288
+ const planNum = sliceIdToPlanNum(sliceId);
1289
+ const absPath = join(slicePath, planFileName(phaseNum, planNum, "ASSESSMENT"));
993
1290
  const artifactPath = toArtifactPath(absPath, basePath);
994
1291
 
995
1292
  const lines: string[] = [];
@@ -1014,7 +1311,7 @@ export async function renderAssessmentFromDb(
1014
1311
  artifact_type: "ASSESSMENT",
1015
1312
  milestone_id: milestoneId,
1016
1313
  slice_id: sliceId,
1017
- });
1314
+ }, basePath);
1018
1315
 
1019
1316
  return { assessmentPath: absPath, content };
1020
1317
  }