gsd-pi 2.43.0 → 2.44.0-dev.0b97ffd

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 (693) hide show
  1. package/README.md +30 -12
  2. package/dist/cli.js +13 -1
  3. package/dist/help-text.js +24 -0
  4. package/dist/resources/extensions/bg-shell/overlay.js +3 -0
  5. package/dist/resources/extensions/github-sync/sync.js +2 -1
  6. package/dist/resources/extensions/gsd/auto/loop.js +0 -2
  7. package/dist/resources/extensions/gsd/auto/phases.js +7 -12
  8. package/dist/resources/extensions/gsd/auto-dashboard.js +19 -18
  9. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +34 -19
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +36 -21
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +128 -14
  12. package/dist/resources/extensions/gsd/auto-prompts.js +202 -92
  13. package/dist/resources/extensions/gsd/auto-recovery.js +83 -135
  14. package/dist/resources/extensions/gsd/auto-start.js +10 -0
  15. package/dist/resources/extensions/gsd/auto-supervisor.js +14 -0
  16. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +4 -7
  17. package/dist/resources/extensions/gsd/auto-verification.js +5 -10
  18. package/dist/resources/extensions/gsd/auto-worktree.js +123 -30
  19. package/dist/resources/extensions/gsd/auto.js +1 -4
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +611 -0
  21. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +28 -3
  22. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -0
  23. package/dist/resources/extensions/gsd/commands/catalog.js +3 -1
  24. package/dist/resources/extensions/gsd/commands/handlers/ops.js +15 -1
  25. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +5 -0
  26. package/dist/resources/extensions/gsd/commands-handlers.js +1 -1
  27. package/dist/resources/extensions/gsd/commands-maintenance.js +78 -3
  28. package/dist/resources/extensions/gsd/dashboard-overlay.js +32 -31
  29. package/dist/resources/extensions/gsd/db-writer.js +95 -4
  30. package/dist/resources/extensions/gsd/dispatch-guard.js +35 -30
  31. package/dist/resources/extensions/gsd/doctor-checks.js +28 -11
  32. package/dist/resources/extensions/gsd/doctor-environment.js +28 -0
  33. package/dist/resources/extensions/gsd/doctor-types.js +0 -15
  34. package/dist/resources/extensions/gsd/doctor.js +46 -282
  35. package/dist/resources/extensions/gsd/file-watcher.js +5 -1
  36. package/dist/resources/extensions/gsd/files.js +14 -198
  37. package/dist/resources/extensions/gsd/git-service.js +4 -0
  38. package/dist/resources/extensions/gsd/gitignore.js +4 -0
  39. package/dist/resources/extensions/gsd/gsd-db.js +819 -197
  40. package/dist/resources/extensions/gsd/guided-flow.js +18 -8
  41. package/dist/resources/extensions/gsd/markdown-renderer.js +862 -0
  42. package/dist/resources/extensions/gsd/md-importer.js +182 -4
  43. package/dist/resources/extensions/gsd/native-git-bridge.js +10 -1
  44. package/dist/resources/extensions/gsd/parallel-eligibility.js +14 -19
  45. package/dist/resources/extensions/gsd/parallel-orchestrator.js +38 -0
  46. package/dist/resources/extensions/gsd/parsers-legacy.js +239 -0
  47. package/dist/resources/extensions/gsd/preferences-types.js +1 -0
  48. package/dist/resources/extensions/gsd/preferences-validation.js +9 -0
  49. package/dist/resources/extensions/gsd/preferences.js +1 -0
  50. package/dist/resources/extensions/gsd/prompts/complete-slice.md +22 -9
  51. package/dist/resources/extensions/gsd/prompts/discuss.md +2 -2
  52. package/dist/resources/extensions/gsd/prompts/execute-task.md +15 -5
  53. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  54. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  55. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  56. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
  57. package/dist/resources/extensions/gsd/prompts/plan-slice.md +4 -7
  58. package/dist/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
  59. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
  60. package/dist/resources/extensions/gsd/prompts/replan-slice.md +6 -6
  61. package/dist/resources/extensions/gsd/reactive-graph.js +33 -3
  62. package/dist/resources/extensions/gsd/skill-health.js +3 -1
  63. package/dist/resources/extensions/gsd/state.js +484 -30
  64. package/dist/resources/extensions/gsd/tools/complete-milestone.js +128 -0
  65. package/dist/resources/extensions/gsd/tools/complete-slice.js +244 -0
  66. package/dist/resources/extensions/gsd/tools/complete-task.js +204 -0
  67. package/dist/resources/extensions/gsd/tools/plan-milestone.js +205 -0
  68. package/dist/resources/extensions/gsd/tools/plan-slice.js +155 -0
  69. package/dist/resources/extensions/gsd/tools/plan-task.js +94 -0
  70. package/dist/resources/extensions/gsd/tools/reassess-roadmap.js +152 -0
  71. package/dist/resources/extensions/gsd/tools/replan-slice.js +146 -0
  72. package/dist/resources/extensions/gsd/triage-resolution.js +17 -1
  73. package/dist/resources/extensions/gsd/undo.js +197 -3
  74. package/dist/resources/extensions/gsd/visualizer-data.js +53 -16
  75. package/dist/resources/extensions/gsd/workspace-index.js +63 -39
  76. package/dist/web/standalone/.next/BUILD_ID +1 -1
  77. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -17
  78. package/dist/web/standalone/.next/build-manifest.json +4 -4
  79. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  80. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  81. package/dist/web/standalone/.next/required-server-files.json +4 -4
  82. package/dist/web/standalone/.next/routes-manifest.json +6 -0
  83. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  84. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  86. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  94. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  96. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -4
  97. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -4
  98. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -4
  100. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  103. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  104. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  106. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  108. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  110. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  120. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  121. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  122. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  123. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  124. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  125. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  132. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  148. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  154. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -0
  166. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -0
  167. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -0
  168. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  171. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  173. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  175. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  184. package/dist/web/standalone/.next/server/app/index.html +1 -1
  185. package/dist/web/standalone/.next/server/app/index.rsc +5 -5
  186. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  187. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +5 -5
  188. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  189. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -4
  190. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  191. package/dist/web/standalone/.next/server/app/page.js +2 -2
  192. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -17
  194. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  195. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  196. package/dist/web/standalone/.next/server/functions-config-manifest.json +1 -0
  197. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  198. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/middleware.js +2 -2
  200. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  202. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  203. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  204. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  205. package/dist/web/standalone/.next/static/alS4hoANx0TK4UVZY27da/_buildManifest.js +1 -0
  206. package/dist/web/standalone/.next/static/chunks/{4024.c195dc1fdd2adbea.js → 4024.0de81b543b28b9fe.js} +2 -2
  207. package/dist/web/standalone/.next/static/chunks/app/_global-error/{page-d07a2c023f1aef1e.js → page-d83ba70a25a85472.js} +1 -1
  208. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  209. package/dist/web/standalone/.next/static/chunks/app/api/boot/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  210. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/input/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  211. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/resize/{route-d07a2c023f1aef1e.js → route-d83ba70a25a85472.js} +1 -1
  212. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d83ba70a25a85472.js +1 -0
  213. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d83ba70a25a85472.js +1 -0
  214. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d83ba70a25a85472.js +1 -0
  215. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d83ba70a25a85472.js +1 -0
  216. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d83ba70a25a85472.js +1 -0
  217. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d83ba70a25a85472.js +1 -0
  218. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d83ba70a25a85472.js +1 -0
  219. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d83ba70a25a85472.js +1 -0
  220. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d83ba70a25a85472.js +1 -0
  221. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d83ba70a25a85472.js +1 -0
  222. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d83ba70a25a85472.js +1 -0
  223. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d83ba70a25a85472.js +1 -0
  224. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d83ba70a25a85472.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d83ba70a25a85472.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d83ba70a25a85472.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d83ba70a25a85472.js +1 -0
  228. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d83ba70a25a85472.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d83ba70a25a85472.js +1 -0
  230. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d83ba70a25a85472.js +1 -0
  231. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d83ba70a25a85472.js +1 -0
  232. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d83ba70a25a85472.js +1 -0
  233. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d83ba70a25a85472.js +1 -0
  234. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d83ba70a25a85472.js +1 -0
  235. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d83ba70a25a85472.js +1 -0
  236. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d83ba70a25a85472.js +1 -0
  237. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d83ba70a25a85472.js +1 -0
  238. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d83ba70a25a85472.js +1 -0
  239. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d83ba70a25a85472.js +1 -0
  240. package/dist/web/standalone/.next/static/chunks/app/api/switch-root/route-d83ba70a25a85472.js +1 -0
  241. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d83ba70a25a85472.js +1 -0
  242. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d83ba70a25a85472.js +1 -0
  243. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d83ba70a25a85472.js +1 -0
  244. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d83ba70a25a85472.js +1 -0
  245. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d83ba70a25a85472.js +1 -0
  246. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d83ba70a25a85472.js +1 -0
  247. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d83ba70a25a85472.js +1 -0
  248. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d83ba70a25a85472.js +1 -0
  249. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  250. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  251. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  252. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d83ba70a25a85472.js +1 -0
  253. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d83ba70a25a85472.js +1 -0
  254. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  255. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d83ba70a25a85472.js +1 -0
  256. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d83ba70a25a85472.js +1 -0
  257. package/dist/web/standalone/.next/static/chunks/{webpack-fa307370fcf9fb2c.js → webpack-9014b5adb127a98a.js} +1 -1
  258. package/dist/web/standalone/.next/static/css/8a727f372cf53002.css +1 -0
  259. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  260. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  261. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  262. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  263. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  264. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  265. package/dist/web/standalone/server.js +1 -1
  266. package/package.json +4 -4
  267. package/packages/pi-ai/dist/models.custom.d.ts +173 -0
  268. package/packages/pi-ai/dist/models.custom.d.ts.map +1 -0
  269. package/packages/pi-ai/dist/models.custom.js +170 -0
  270. package/packages/pi-ai/dist/models.custom.js.map +1 -0
  271. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  272. package/packages/pi-ai/dist/models.js +16 -1
  273. package/packages/pi-ai/dist/models.js.map +1 -1
  274. package/packages/pi-ai/dist/models.test.d.ts +2 -0
  275. package/packages/pi-ai/dist/models.test.d.ts.map +1 -0
  276. package/packages/pi-ai/dist/models.test.js +67 -0
  277. package/packages/pi-ai/dist/models.test.js.map +1 -0
  278. package/packages/pi-ai/src/models.custom.ts +172 -0
  279. package/packages/pi-ai/src/models.test.ts +85 -0
  280. package/packages/pi-ai/src/models.ts +17 -1
  281. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +10 -3
  282. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/agent-session.js +21 -34
  284. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +6 -8
  286. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts +2 -2
  288. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/compaction/branch-summarization.js.map +1 -1
  290. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +2 -2
  291. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  292. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +4 -4
  294. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  296. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +6 -0
  299. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/extensions/loader.js +80 -0
  301. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js +63 -0
  303. package/packages/pi-coding-agent/dist/core/extensions/loader.test.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +24 -26
  305. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  306. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +37 -0
  307. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +2 -3
  311. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +12 -2
  313. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/fs-utils.test.js +29 -48
  315. package/packages/pi-coding-agent/dist/core/fs-utils.test.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts +38 -0
  317. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.d.ts.map +1 -0
  318. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js +192 -0
  319. package/packages/pi-coding-agent/dist/core/lifecycle-hooks.js.map +1 -0
  320. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts +5 -0
  321. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  322. package/packages/pi-coding-agent/dist/core/lsp/client.js +69 -21
  323. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts +2 -0
  325. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.d.ts.map +1 -0
  326. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +255 -0
  327. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -0
  328. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +15 -0
  329. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/model-registry.js +40 -3
  331. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/package-commands.d.ts +25 -0
  333. package/packages/pi-coding-agent/dist/core/package-commands.d.ts.map +1 -0
  334. package/packages/pi-coding-agent/dist/core/package-commands.js +253 -0
  335. package/packages/pi-coding-agent/dist/core/package-commands.js.map +1 -0
  336. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts +2 -0
  337. package/packages/pi-coding-agent/dist/core/package-commands.test.d.ts.map +1 -0
  338. package/packages/pi-coding-agent/dist/core/package-commands.test.js +225 -0
  339. package/packages/pi-coding-agent/dist/core/package-commands.test.js.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js +34 -44
  341. package/packages/pi-coding-agent/dist/core/resolve-config-value.test.js.map +1 -1
  342. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/core/sdk.js +4 -0
  344. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  345. package/packages/pi-coding-agent/dist/core/session-manager.test.js +30 -34
  346. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  347. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js +10 -12
  348. package/packages/pi-coding-agent/dist/core/tools/edit-diff.test.js.map +1 -1
  349. package/packages/pi-coding-agent/dist/index.d.ts +3 -1
  350. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/index.js +1 -0
  352. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  354. package/packages/pi-coding-agent/dist/main.js +11 -199
  355. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  356. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts +6 -0
  357. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  358. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +21 -0
  359. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  360. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  361. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +8 -15
  363. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/modes/print-mode.d.ts.map +1 -1
  365. package/packages/pi-coding-agent/dist/modes/print-mode.js +45 -34
  366. package/packages/pi-coding-agent/dist/modes/print-mode.js.map +1 -1
  367. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts +1 -0
  368. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js +7 -2
  370. package/packages/pi-coding-agent/dist/modes/rpc/rpc-client.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  372. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js +2 -1
  373. package/packages/pi-coding-agent/dist/modes/rpc/rpc-mode.js.map +1 -1
  374. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js +43 -47
  375. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.test.js.map +1 -1
  376. package/packages/pi-coding-agent/package.json +1 -1
  377. package/packages/pi-coding-agent/src/core/agent-session.ts +26 -37
  378. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +7 -7
  379. package/packages/pi-coding-agent/src/core/compaction/branch-summarization.ts +2 -2
  380. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +3 -3
  381. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +4 -4
  382. package/packages/pi-coding-agent/src/core/extensions/index.ts +5 -0
  383. package/packages/pi-coding-agent/src/core/extensions/loader.test.ts +96 -0
  384. package/packages/pi-coding-agent/src/core/extensions/loader.ts +89 -0
  385. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +26 -26
  386. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -0
  387. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +15 -2
  388. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +2 -3
  389. package/packages/pi-coding-agent/src/core/fs-utils.test.ts +31 -43
  390. package/packages/pi-coding-agent/src/core/lifecycle-hooks.ts +274 -0
  391. package/packages/pi-coding-agent/src/core/lsp/client.ts +83 -21
  392. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +288 -0
  393. package/packages/pi-coding-agent/src/core/model-registry.ts +39 -3
  394. package/packages/pi-coding-agent/src/core/package-commands.test.ts +240 -0
  395. package/packages/pi-coding-agent/src/core/package-commands.ts +310 -0
  396. package/packages/pi-coding-agent/src/core/resolve-config-value.test.ts +40 -45
  397. package/packages/pi-coding-agent/src/core/sdk.ts +4 -0
  398. package/packages/pi-coding-agent/src/core/session-manager.test.ts +33 -33
  399. package/packages/pi-coding-agent/src/core/tools/edit-diff.test.ts +17 -17
  400. package/packages/pi-coding-agent/src/index.ts +7 -0
  401. package/packages/pi-coding-agent/src/main.ts +11 -232
  402. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +20 -0
  403. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +9 -16
  404. package/packages/pi-coding-agent/src/modes/print-mode.ts +42 -32
  405. package/packages/pi-coding-agent/src/modes/rpc/rpc-client.ts +8 -2
  406. package/packages/pi-coding-agent/src/modes/rpc/rpc-mode.ts +2 -1
  407. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.test.ts +74 -74
  408. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  409. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  410. package/pkg/dist/modes/interactive/theme/theme.js +8 -15
  411. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  412. package/pkg/package.json +1 -1
  413. package/src/resources/extensions/bg-shell/overlay.ts +4 -0
  414. package/src/resources/extensions/github-sync/sync.ts +2 -1
  415. package/src/resources/extensions/gsd/auto/loop-deps.ts +0 -8
  416. package/src/resources/extensions/gsd/auto/loop.ts +0 -2
  417. package/src/resources/extensions/gsd/auto/phases.ts +7 -20
  418. package/src/resources/extensions/gsd/auto/types.ts +0 -1
  419. package/src/resources/extensions/gsd/auto-dashboard.ts +20 -16
  420. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +34 -19
  421. package/src/resources/extensions/gsd/auto-dispatch.ts +38 -21
  422. package/src/resources/extensions/gsd/auto-post-unit.ts +150 -15
  423. package/src/resources/extensions/gsd/auto-prompts.ts +186 -103
  424. package/src/resources/extensions/gsd/auto-recovery.ts +77 -142
  425. package/src/resources/extensions/gsd/auto-start.ts +14 -0
  426. package/src/resources/extensions/gsd/auto-supervisor.ts +14 -0
  427. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +6 -7
  428. package/src/resources/extensions/gsd/auto-verification.ts +4 -9
  429. package/src/resources/extensions/gsd/auto-worktree.ts +126 -30
  430. package/src/resources/extensions/gsd/auto.ts +0 -9
  431. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +675 -4
  432. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +31 -3
  433. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -0
  434. package/src/resources/extensions/gsd/commands/catalog.ts +3 -1
  435. package/src/resources/extensions/gsd/commands/handlers/ops.ts +15 -1
  436. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +8 -0
  437. package/src/resources/extensions/gsd/commands-handlers.ts +1 -1
  438. package/src/resources/extensions/gsd/commands-maintenance.ts +86 -3
  439. package/src/resources/extensions/gsd/dashboard-overlay.ts +17 -13
  440. package/src/resources/extensions/gsd/db-writer.ts +105 -4
  441. package/src/resources/extensions/gsd/dispatch-guard.ts +32 -30
  442. package/src/resources/extensions/gsd/doctor-checks.ts +25 -11
  443. package/src/resources/extensions/gsd/doctor-environment.ts +31 -0
  444. package/src/resources/extensions/gsd/doctor-types.ts +0 -23
  445. package/src/resources/extensions/gsd/doctor.ts +45 -295
  446. package/src/resources/extensions/gsd/file-watcher.ts +4 -1
  447. package/src/resources/extensions/gsd/files.ts +16 -220
  448. package/src/resources/extensions/gsd/git-service.ts +4 -0
  449. package/src/resources/extensions/gsd/gitignore.ts +4 -0
  450. package/src/resources/extensions/gsd/gsd-db.ts +1157 -370
  451. package/src/resources/extensions/gsd/guided-flow.ts +20 -8
  452. package/src/resources/extensions/gsd/markdown-renderer.ts +1098 -0
  453. package/src/resources/extensions/gsd/md-importer.ts +211 -2
  454. package/src/resources/extensions/gsd/native-git-bridge.ts +12 -1
  455. package/src/resources/extensions/gsd/parallel-eligibility.ts +14 -18
  456. package/src/resources/extensions/gsd/parallel-orchestrator.ts +43 -0
  457. package/src/resources/extensions/gsd/parsers-legacy.ts +271 -0
  458. package/src/resources/extensions/gsd/preferences-types.ts +3 -0
  459. package/src/resources/extensions/gsd/preferences-validation.ts +9 -0
  460. package/src/resources/extensions/gsd/preferences.ts +1 -0
  461. package/src/resources/extensions/gsd/prompts/complete-slice.md +22 -9
  462. package/src/resources/extensions/gsd/prompts/discuss.md +2 -2
  463. package/src/resources/extensions/gsd/prompts/execute-task.md +15 -5
  464. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +1 -1
  466. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +1 -1
  467. package/src/resources/extensions/gsd/prompts/plan-milestone.md +6 -10
  468. package/src/resources/extensions/gsd/prompts/plan-slice.md +4 -7
  469. package/src/resources/extensions/gsd/prompts/reactive-execute.md +3 -3
  470. package/src/resources/extensions/gsd/prompts/reassess-roadmap.md +6 -7
  471. package/src/resources/extensions/gsd/prompts/replan-slice.md +6 -6
  472. package/src/resources/extensions/gsd/reactive-graph.ts +33 -3
  473. package/src/resources/extensions/gsd/skill-health.ts +2 -1
  474. package/src/resources/extensions/gsd/state.ts +547 -29
  475. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +99 -99
  476. package/src/resources/extensions/gsd/tests/atomic-task-closeout.test.ts +8 -120
  477. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +14 -16
  478. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +20 -11
  479. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +43 -57
  480. package/src/resources/extensions/gsd/tests/auto-preflight.test.ts +11 -13
  481. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +600 -513
  482. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +73 -75
  483. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +34 -56
  484. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +121 -0
  485. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +540 -668
  486. package/src/resources/extensions/gsd/tests/auto-worktree.test.ts +165 -143
  487. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +29 -52
  488. package/src/resources/extensions/gsd/tests/captures.test.ts +148 -176
  489. package/src/resources/extensions/gsd/tests/claude-import-tui.test.ts +32 -33
  490. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +141 -143
  491. package/src/resources/extensions/gsd/tests/commands-inspect-open-db.test.ts +25 -25
  492. package/src/resources/extensions/gsd/tests/commands-logs.test.ts +81 -81
  493. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +39 -60
  494. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +375 -0
  495. package/src/resources/extensions/gsd/tests/complete-task.test.ts +387 -0
  496. package/src/resources/extensions/gsd/tests/context-store.test.ts +354 -367
  497. package/src/resources/extensions/gsd/tests/continue-here.test.ts +68 -72
  498. package/src/resources/extensions/gsd/tests/cost-projection.test.ts +92 -106
  499. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +27 -35
  500. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +0 -2
  501. package/src/resources/extensions/gsd/tests/dashboard-budget.test.ts +220 -237
  502. package/src/resources/extensions/gsd/tests/db-writer.test.ts +390 -420
  503. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +76 -92
  504. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +512 -0
  505. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +644 -84
  506. package/src/resources/extensions/gsd/tests/derive-state-deps.test.ts +78 -101
  507. package/src/resources/extensions/gsd/tests/derive-state.test.ts +192 -227
  508. package/src/resources/extensions/gsd/tests/detection.test.ts +232 -278
  509. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +30 -34
  510. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +192 -161
  511. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +43 -49
  512. package/src/resources/extensions/gsd/tests/dispatch-uat-last-completed.test.ts +28 -32
  513. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +30 -90
  514. package/src/resources/extensions/gsd/tests/doctor-delimiter-fix.test.ts +34 -38
  515. package/src/resources/extensions/gsd/tests/doctor-enhancements.test.ts +57 -80
  516. package/src/resources/extensions/gsd/tests/doctor-environment-worktree.test.ts +164 -0
  517. package/src/resources/extensions/gsd/tests/doctor-environment.test.ts +72 -97
  518. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +55 -153
  519. package/src/resources/extensions/gsd/tests/doctor-git.test.ts +104 -145
  520. package/src/resources/extensions/gsd/tests/doctor-proactive.test.ts +84 -106
  521. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +53 -97
  522. package/src/resources/extensions/gsd/tests/doctor-runtime.test.ts +72 -93
  523. package/src/resources/extensions/gsd/tests/doctor.test.ts +109 -149
  524. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +123 -131
  525. package/src/resources/extensions/gsd/tests/exit-command.test.ts +20 -24
  526. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +48 -57
  527. package/src/resources/extensions/gsd/tests/files-loadfile-eisdir.test.ts +5 -7
  528. package/src/resources/extensions/gsd/tests/flag-file-db.test.ts +278 -0
  529. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +232 -0
  530. package/src/resources/extensions/gsd/tests/git-locale.test.ts +13 -27
  531. package/src/resources/extensions/gsd/tests/git-service.test.ts +291 -390
  532. package/src/resources/extensions/gsd/tests/gitignore-tracked-gsd.test.ts +31 -39
  533. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +63 -69
  534. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +255 -264
  535. package/src/resources/extensions/gsd/tests/gsd-inspect.test.ts +108 -119
  536. package/src/resources/extensions/gsd/tests/gsd-recover.test.ts +440 -0
  537. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +229 -262
  538. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +13 -13
  539. package/src/resources/extensions/gsd/tests/health-widget.test.ts +29 -37
  540. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +81 -270
  541. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +16 -18
  542. package/src/resources/extensions/gsd/tests/integration-edge.test.ts +41 -46
  543. package/src/resources/extensions/gsd/tests/integration-lifecycle.test.ts +42 -53
  544. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +75 -91
  545. package/src/resources/extensions/gsd/tests/integration-proof.test.ts +643 -0
  546. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +0 -3
  547. package/src/resources/extensions/gsd/tests/markdown-renderer.test.ts +1161 -0
  548. package/src/resources/extensions/gsd/tests/md-importer.test.ts +101 -125
  549. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +45 -54
  550. package/src/resources/extensions/gsd/tests/memory-store.test.ts +81 -94
  551. package/src/resources/extensions/gsd/tests/migrate-command.test.ts +57 -66
  552. package/src/resources/extensions/gsd/tests/migrate-hierarchy.test.ts +429 -0
  553. package/src/resources/extensions/gsd/tests/migrate-parser.test.ts +161 -170
  554. package/src/resources/extensions/gsd/tests/migrate-transformer.test.ts +125 -141
  555. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +107 -131
  556. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +89 -97
  557. package/src/resources/extensions/gsd/tests/migrate-writer.test.ts +127 -164
  558. package/src/resources/extensions/gsd/tests/must-have-parser.test.ts +81 -94
  559. package/src/resources/extensions/gsd/tests/none-mode-gates.test.ts +35 -36
  560. package/src/resources/extensions/gsd/tests/overrides.test.ts +99 -106
  561. package/src/resources/extensions/gsd/tests/parallel-crash-recovery.test.ts +40 -47
  562. package/src/resources/extensions/gsd/tests/parallel-worker-monitoring.test.ts +25 -28
  563. package/src/resources/extensions/gsd/tests/parallel-workers-multi-milestone-e2e.test.ts +66 -83
  564. package/src/resources/extensions/gsd/tests/park-edge-cases.test.ts +54 -77
  565. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +68 -115
  566. package/src/resources/extensions/gsd/tests/parsers.test.ts +548 -612
  567. package/src/resources/extensions/gsd/tests/paths.test.ts +72 -87
  568. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +176 -113
  569. package/src/resources/extensions/gsd/tests/plan-slice-prompt.test.ts +7 -0
  570. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +179 -0
  571. package/src/resources/extensions/gsd/tests/plan-task.test.ts +145 -0
  572. package/src/resources/extensions/gsd/tests/planning-crossval.test.ts +305 -0
  573. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +77 -117
  574. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +139 -0
  575. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +56 -56
  576. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +93 -119
  577. package/src/resources/extensions/gsd/tests/queue-order.test.ts +70 -82
  578. package/src/resources/extensions/gsd/tests/queue-reorder-e2e.test.ts +42 -55
  579. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +100 -0
  580. package/src/resources/extensions/gsd/tests/quick-branch-lifecycle.test.ts +45 -73
  581. package/src/resources/extensions/gsd/tests/reassess-handler.test.ts +325 -0
  582. package/src/resources/extensions/gsd/tests/reassess-prompt.test.ts +28 -38
  583. package/src/resources/extensions/gsd/tests/replan-handler.test.ts +410 -0
  584. package/src/resources/extensions/gsd/tests/replan-slice.test.ts +73 -80
  585. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +71 -74
  586. package/src/resources/extensions/gsd/tests/requirements.test.ts +70 -75
  587. package/src/resources/extensions/gsd/tests/retry-state-reset.test.ts +44 -66
  588. package/src/resources/extensions/gsd/tests/roadmap-parse-regression.test.ts +114 -181
  589. package/src/resources/extensions/gsd/tests/roadmap-slices.test.ts +1 -1
  590. package/src/resources/extensions/gsd/tests/rogue-file-detection.test.ts +296 -0
  591. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +63 -65
  592. package/src/resources/extensions/gsd/tests/run-uat.test.ts +66 -128
  593. package/src/resources/extensions/gsd/tests/schema-v9-sequence.test.ts +176 -0
  594. package/src/resources/extensions/gsd/tests/session-lock-multipath.test.ts +18 -25
  595. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +37 -44
  596. package/src/resources/extensions/gsd/tests/shared-wal.test.ts +209 -0
  597. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +63 -0
  598. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +6 -8
  599. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +22 -28
  600. package/src/resources/extensions/gsd/tests/token-cost-display.test.ts +118 -0
  601. package/src/resources/extensions/gsd/tests/token-savings.test.ts +54 -56
  602. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +23 -25
  603. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +19 -13
  604. package/src/resources/extensions/gsd/tests/undo.test.ts +321 -1
  605. package/src/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +66 -82
  606. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +46 -47
  607. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +1 -1
  608. package/src/resources/extensions/gsd/tests/verification-evidence.test.ts +0 -142
  609. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -22
  610. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -86
  611. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +41 -43
  612. package/src/resources/extensions/gsd/tests/visualizer-views.test.ts +94 -96
  613. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +11 -13
  614. package/src/resources/extensions/gsd/tests/worker-registry.test.ts +27 -29
  615. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +50 -52
  616. package/src/resources/extensions/gsd/tests/worktree-bugfix.test.ts +10 -13
  617. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +14 -18
  618. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +38 -39
  619. package/src/resources/extensions/gsd/tests/worktree-e2e.test.ts +17 -21
  620. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +12 -5
  621. package/src/resources/extensions/gsd/tests/worktree-health.test.ts +25 -30
  622. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +30 -37
  623. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +15 -22
  624. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +59 -66
  625. package/src/resources/extensions/gsd/tests/worktree.test.ts +44 -50
  626. package/src/resources/extensions/gsd/tools/complete-milestone.ts +176 -0
  627. package/src/resources/extensions/gsd/tools/complete-slice.ts +300 -0
  628. package/src/resources/extensions/gsd/tools/complete-task.ts +245 -0
  629. package/src/resources/extensions/gsd/tools/plan-milestone.ts +249 -0
  630. package/src/resources/extensions/gsd/tools/plan-slice.ts +194 -0
  631. package/src/resources/extensions/gsd/tools/plan-task.ts +116 -0
  632. package/src/resources/extensions/gsd/tools/reassess-roadmap.ts +203 -0
  633. package/src/resources/extensions/gsd/tools/replan-slice.ts +192 -0
  634. package/src/resources/extensions/gsd/triage-resolution.ts +20 -1
  635. package/src/resources/extensions/gsd/types.ts +50 -0
  636. package/src/resources/extensions/gsd/undo.ts +247 -3
  637. package/src/resources/extensions/gsd/visualizer-data.ts +54 -17
  638. package/src/resources/extensions/gsd/workspace-index.ts +64 -46
  639. package/dist/resources/extensions/gsd/auto-observability.js +0 -56
  640. package/dist/resources/extensions/gsd/observability-validator.js +0 -422
  641. package/dist/resources/extensions/gsd/roadmap-mutations.js +0 -110
  642. package/dist/web/standalone/.next/static/VvclDCW6TAWjEyLU-EYL1/_buildManifest.js +0 -1
  643. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  644. package/dist/web/standalone/.next/static/chunks/app/api/bridge-terminal/stream/route-d07a2c023f1aef1e.js +0 -1
  645. package/dist/web/standalone/.next/static/chunks/app/api/browse-directories/route-d07a2c023f1aef1e.js +0 -1
  646. package/dist/web/standalone/.next/static/chunks/app/api/captures/route-d07a2c023f1aef1e.js +0 -1
  647. package/dist/web/standalone/.next/static/chunks/app/api/cleanup/route-d07a2c023f1aef1e.js +0 -1
  648. package/dist/web/standalone/.next/static/chunks/app/api/dev-mode/route-d07a2c023f1aef1e.js +0 -1
  649. package/dist/web/standalone/.next/static/chunks/app/api/doctor/route-d07a2c023f1aef1e.js +0 -1
  650. package/dist/web/standalone/.next/static/chunks/app/api/export-data/route-d07a2c023f1aef1e.js +0 -1
  651. package/dist/web/standalone/.next/static/chunks/app/api/files/route-d07a2c023f1aef1e.js +0 -1
  652. package/dist/web/standalone/.next/static/chunks/app/api/forensics/route-d07a2c023f1aef1e.js +0 -1
  653. package/dist/web/standalone/.next/static/chunks/app/api/git/route-d07a2c023f1aef1e.js +0 -1
  654. package/dist/web/standalone/.next/static/chunks/app/api/history/route-d07a2c023f1aef1e.js +0 -1
  655. package/dist/web/standalone/.next/static/chunks/app/api/hooks/route-d07a2c023f1aef1e.js +0 -1
  656. package/dist/web/standalone/.next/static/chunks/app/api/inspect/route-d07a2c023f1aef1e.js +0 -1
  657. package/dist/web/standalone/.next/static/chunks/app/api/knowledge/route-d07a2c023f1aef1e.js +0 -1
  658. package/dist/web/standalone/.next/static/chunks/app/api/live-state/route-d07a2c023f1aef1e.js +0 -1
  659. package/dist/web/standalone/.next/static/chunks/app/api/onboarding/route-d07a2c023f1aef1e.js +0 -1
  660. package/dist/web/standalone/.next/static/chunks/app/api/preferences/route-d07a2c023f1aef1e.js +0 -1
  661. package/dist/web/standalone/.next/static/chunks/app/api/projects/route-d07a2c023f1aef1e.js +0 -1
  662. package/dist/web/standalone/.next/static/chunks/app/api/recovery/route-d07a2c023f1aef1e.js +0 -1
  663. package/dist/web/standalone/.next/static/chunks/app/api/remote-questions/route-d07a2c023f1aef1e.js +0 -1
  664. package/dist/web/standalone/.next/static/chunks/app/api/session/browser/route-d07a2c023f1aef1e.js +0 -1
  665. package/dist/web/standalone/.next/static/chunks/app/api/session/command/route-d07a2c023f1aef1e.js +0 -1
  666. package/dist/web/standalone/.next/static/chunks/app/api/session/events/route-d07a2c023f1aef1e.js +0 -1
  667. package/dist/web/standalone/.next/static/chunks/app/api/session/manage/route-d07a2c023f1aef1e.js +0 -1
  668. package/dist/web/standalone/.next/static/chunks/app/api/settings-data/route-d07a2c023f1aef1e.js +0 -1
  669. package/dist/web/standalone/.next/static/chunks/app/api/shutdown/route-d07a2c023f1aef1e.js +0 -1
  670. package/dist/web/standalone/.next/static/chunks/app/api/skill-health/route-d07a2c023f1aef1e.js +0 -1
  671. package/dist/web/standalone/.next/static/chunks/app/api/steer/route-d07a2c023f1aef1e.js +0 -1
  672. package/dist/web/standalone/.next/static/chunks/app/api/terminal/input/route-d07a2c023f1aef1e.js +0 -1
  673. package/dist/web/standalone/.next/static/chunks/app/api/terminal/resize/route-d07a2c023f1aef1e.js +0 -1
  674. package/dist/web/standalone/.next/static/chunks/app/api/terminal/sessions/route-d07a2c023f1aef1e.js +0 -1
  675. package/dist/web/standalone/.next/static/chunks/app/api/terminal/stream/route-d07a2c023f1aef1e.js +0 -1
  676. package/dist/web/standalone/.next/static/chunks/app/api/terminal/upload/route-d07a2c023f1aef1e.js +0 -1
  677. package/dist/web/standalone/.next/static/chunks/app/api/undo/route-d07a2c023f1aef1e.js +0 -1
  678. package/dist/web/standalone/.next/static/chunks/app/api/update/route-d07a2c023f1aef1e.js +0 -1
  679. package/dist/web/standalone/.next/static/chunks/app/api/visualizer/route-d07a2c023f1aef1e.js +0 -1
  680. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  681. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  682. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/app-error-d07a2c023f1aef1e.js +0 -1
  683. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/forbidden-d07a2c023f1aef1e.js +0 -1
  684. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  685. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/not-found-d07a2c023f1aef1e.js +0 -1
  686. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/unauthorized-d07a2c023f1aef1e.js +0 -1
  687. package/dist/web/standalone/.next/static/css/123c0bb039697968.css +0 -1
  688. package/src/resources/extensions/gsd/auto-observability.ts +0 -74
  689. package/src/resources/extensions/gsd/observability-validator.ts +0 -456
  690. package/src/resources/extensions/gsd/roadmap-mutations.ts +0 -134
  691. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +0 -174
  692. package/src/resources/extensions/gsd/tests/plan-quality-validator.test.ts +0 -474
  693. /package/dist/web/standalone/.next/static/{VvclDCW6TAWjEyLU-EYL1 → alS4hoANx0TK4UVZY27da}/_ssgManifest.js +0 -0
@@ -0,0 +1,296 @@
1
+ /**
2
+ * Rogue file detection tests — verifies that detectRogueFileWrites()
3
+ * correctly identifies summary files written directly to disk without
4
+ * a corresponding DB completion record.
5
+ */
6
+
7
+ import test from "node:test";
8
+ import assert from "node:assert/strict";
9
+ import { existsSync, mkdirSync, mkdtempSync, realpathSync, rmSync, writeFileSync } from "node:fs";
10
+ import { join } from "node:path";
11
+ import { tmpdir } from "node:os";
12
+
13
+ import { detectRogueFileWrites } from "../auto-post-unit.ts";
14
+ import { openDatabase, closeDatabase, isDbAvailable, insertMilestone, insertSlice, insertTask, updateSliceStatus, upsertMilestonePlanning } from "../gsd-db.ts";
15
+
16
+ // ── Helpers ──────────────────────────────────────────────────────────────────
17
+
18
+ function createTmpBase(): string {
19
+ return realpathSync(mkdtempSync(join(tmpdir(), "gsd-rogue-test-")));
20
+ }
21
+
22
+ /**
23
+ * Create a minimal .gsd/ directory structure with a task summary file.
24
+ */
25
+ function createTaskSummaryOnDisk(basePath: string, mid: string, sid: string, tid: string): string {
26
+ const tasksDir = join(basePath, ".gsd", "milestones", mid, "slices", sid, "tasks");
27
+ mkdirSync(tasksDir, { recursive: true });
28
+ const summaryFile = join(tasksDir, `${tid}-SUMMARY.md`);
29
+ writeFileSync(summaryFile, `---\nid: ${tid}\nparent: ${sid}\nmilestone: ${mid}\n---\n# ${tid}: Test\n`, "utf-8");
30
+ return summaryFile;
31
+ }
32
+
33
+ /**
34
+ * Create a minimal .gsd/ directory structure with a slice summary file.
35
+ */
36
+ function createSliceSummaryOnDisk(basePath: string, mid: string, sid: string): string {
37
+ const sliceDir = join(basePath, ".gsd", "milestones", mid, "slices", sid);
38
+ mkdirSync(sliceDir, { recursive: true });
39
+ const summaryFile = join(sliceDir, `${sid}-SUMMARY.md`);
40
+ writeFileSync(summaryFile, `---\nid: ${sid}\nmilestone: ${mid}\n---\n# ${sid}: Test Slice\n`, "utf-8");
41
+ return summaryFile;
42
+ }
43
+
44
+ function createRoadmapOnDisk(basePath: string, mid: string): string {
45
+ const milestoneDir = join(basePath, ".gsd", "milestones", mid);
46
+ mkdirSync(milestoneDir, { recursive: true });
47
+ const roadmapFile = join(milestoneDir, `${mid}-ROADMAP.md`);
48
+ writeFileSync(roadmapFile, `# ${mid}: Test Roadmap\n`, "utf-8");
49
+ return roadmapFile;
50
+ }
51
+
52
+ function createSlicePlanOnDisk(basePath: string, mid: string, sid: string): string {
53
+ const sliceDir = join(basePath, ".gsd", "milestones", mid, "slices", sid);
54
+ mkdirSync(sliceDir, { recursive: true });
55
+ const planFile = join(sliceDir, `${sid}-PLAN.md`);
56
+ writeFileSync(planFile, `# ${sid}: Test Plan\n`, "utf-8");
57
+ return planFile;
58
+ }
59
+
60
+
61
+ // ── Tests ────────────────────────────────────────────────────────────────────
62
+
63
+ test("rogue detection: task summary on disk, no DB row → detected as rogue", () => {
64
+ const basePath = createTmpBase();
65
+ const dbPath = join(basePath, ".gsd", "gsd.db");
66
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
67
+
68
+ try {
69
+ openDatabase(dbPath);
70
+ assert.ok(isDbAvailable(), "DB should be available");
71
+
72
+ const summaryPath = createTaskSummaryOnDisk(basePath, "M001", "S01", "T01");
73
+ assert.ok(existsSync(summaryPath), "Summary file should exist on disk");
74
+
75
+ const rogues = detectRogueFileWrites("execute-task", "M001/S01/T01", basePath);
76
+ assert.equal(rogues.length, 1, "Should detect one rogue file");
77
+ assert.equal(rogues[0].path, summaryPath);
78
+ assert.equal(rogues[0].unitType, "execute-task");
79
+ assert.equal(rogues[0].unitId, "M001/S01/T01");
80
+ } finally {
81
+ closeDatabase();
82
+ rmSync(basePath, { recursive: true, force: true });
83
+ }
84
+ });
85
+
86
+ test("rogue detection: task summary on disk, DB row with status 'complete' → NOT rogue", () => {
87
+ const basePath = createTmpBase();
88
+ const dbPath = join(basePath, ".gsd", "gsd.db");
89
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
90
+
91
+ try {
92
+ openDatabase(dbPath);
93
+
94
+ createTaskSummaryOnDisk(basePath, "M001", "S01", "T01");
95
+
96
+ // Insert parent milestone and slice first (foreign key constraints)
97
+ insertMilestone({ id: "M001" });
98
+ insertSlice({ milestoneId: "M001", id: "S01" });
99
+
100
+ // Insert a completed task row into the DB (INSERT OR REPLACE)
101
+ insertTask({
102
+ milestoneId: "M001",
103
+ sliceId: "S01",
104
+ id: "T01",
105
+ title: "Test Task",
106
+ status: "complete",
107
+ oneLiner: "Test",
108
+ });
109
+
110
+ const rogues = detectRogueFileWrites("execute-task", "M001/S01/T01", basePath);
111
+ assert.equal(rogues.length, 0, "Should NOT detect rogue when DB row is complete");
112
+ } finally {
113
+ closeDatabase();
114
+ rmSync(basePath, { recursive: true, force: true });
115
+ }
116
+ });
117
+
118
+ test("rogue detection: no summary file on disk → NOT rogue regardless of DB state", () => {
119
+ const basePath = createTmpBase();
120
+ const dbPath = join(basePath, ".gsd", "gsd.db");
121
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
122
+
123
+ try {
124
+ openDatabase(dbPath);
125
+
126
+ // Don't create any summary file on disk
127
+ const rogues = detectRogueFileWrites("execute-task", "M001/S01/T01", basePath);
128
+ assert.equal(rogues.length, 0, "Should NOT detect rogue when no file on disk");
129
+ } finally {
130
+ closeDatabase();
131
+ rmSync(basePath, { recursive: true, force: true });
132
+ }
133
+ });
134
+
135
+ test("rogue detection: DB not available → returns empty array (graceful degradation)", () => {
136
+ const basePath = createTmpBase();
137
+
138
+ try {
139
+ closeDatabase();
140
+ assert.ok(!isDbAvailable(), "DB should not be available");
141
+
142
+ // Create a file on disk even though DB is closed
143
+ createTaskSummaryOnDisk(basePath, "M001", "S01", "T01");
144
+
145
+ const rogues = detectRogueFileWrites("execute-task", "M001/S01/T01", basePath);
146
+ assert.equal(rogues.length, 0, "Should return empty array when DB unavailable");
147
+ } finally {
148
+ rmSync(basePath, { recursive: true, force: true });
149
+ }
150
+ });
151
+
152
+ test("rogue detection: slice summary on disk, no DB row → detected as rogue", () => {
153
+ const basePath = createTmpBase();
154
+ const dbPath = join(basePath, ".gsd", "gsd.db");
155
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
156
+
157
+ try {
158
+ openDatabase(dbPath);
159
+
160
+ const summaryPath = createSliceSummaryOnDisk(basePath, "M001", "S01");
161
+ assert.ok(existsSync(summaryPath), "Slice summary file should exist on disk");
162
+
163
+ const rogues = detectRogueFileWrites("complete-slice", "M001/S01", basePath);
164
+ assert.equal(rogues.length, 1, "Should detect one rogue slice file");
165
+ assert.equal(rogues[0].path, summaryPath);
166
+ assert.equal(rogues[0].unitType, "complete-slice");
167
+ assert.equal(rogues[0].unitId, "M001/S01");
168
+ } finally {
169
+ closeDatabase();
170
+ rmSync(basePath, { recursive: true, force: true });
171
+ }
172
+ });
173
+
174
+ test("rogue detection: slice summary on disk, DB row with status 'complete' → NOT rogue", () => {
175
+ const basePath = createTmpBase();
176
+ const dbPath = join(basePath, ".gsd", "gsd.db");
177
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
178
+
179
+ try {
180
+ openDatabase(dbPath);
181
+
182
+ createSliceSummaryOnDisk(basePath, "M001", "S01");
183
+
184
+ // Insert parent milestone first (foreign key constraint)
185
+ insertMilestone({ id: "M001" });
186
+
187
+ // Insert a slice row, then update to complete
188
+ insertSlice({
189
+ milestoneId: "M001",
190
+ id: "S01",
191
+ title: "Test Slice",
192
+ status: "complete",
193
+ });
194
+ updateSliceStatus("M001", "S01", "complete", new Date().toISOString());
195
+
196
+ const rogues = detectRogueFileWrites("complete-slice", "M001/S01", basePath);
197
+ assert.equal(rogues.length, 0, "Should NOT detect rogue when slice DB row is complete");
198
+ } finally {
199
+ closeDatabase();
200
+ rmSync(basePath, { recursive: true, force: true });
201
+ }
202
+ });
203
+
204
+ test("rogue detection: plan milestone roadmap on disk, no milestone planning row → detected as rogue", () => {
205
+ const basePath = createTmpBase();
206
+ const dbPath = join(basePath, ".gsd", "gsd.db");
207
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
208
+
209
+ try {
210
+ openDatabase(dbPath);
211
+
212
+ const roadmapPath = createRoadmapOnDisk(basePath, "M001");
213
+ assert.ok(existsSync(roadmapPath), "Roadmap file should exist on disk");
214
+
215
+ const rogues = detectRogueFileWrites("plan-milestone", "M001", basePath);
216
+ assert.equal(rogues.length, 1, "Should detect one rogue roadmap file");
217
+ assert.equal(rogues[0].path, roadmapPath);
218
+ assert.equal(rogues[0].unitType, "plan-milestone");
219
+ assert.equal(rogues[0].unitId, "M001");
220
+ } finally {
221
+ closeDatabase();
222
+ rmSync(basePath, { recursive: true, force: true });
223
+ }
224
+ });
225
+
226
+ test("rogue detection: plan milestone roadmap on disk, DB milestone planning row exists → NOT rogue", () => {
227
+ const basePath = createTmpBase();
228
+ const dbPath = join(basePath, ".gsd", "gsd.db");
229
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
230
+
231
+ try {
232
+ openDatabase(dbPath);
233
+
234
+ createRoadmapOnDisk(basePath, "M001");
235
+ insertMilestone({ id: "M001", title: "Planned Milestone" });
236
+ upsertMilestonePlanning("M001", {
237
+ vision: "Real planning state",
238
+ requirementCoverage: "R001 → S01",
239
+ boundaryMapMarkdown: "- planner → db",
240
+ });
241
+
242
+ const rogues = detectRogueFileWrites("plan-milestone", "M001", basePath);
243
+ assert.equal(rogues.length, 0, "Should NOT detect rogue when milestone planning state exists");
244
+ } finally {
245
+ closeDatabase();
246
+ rmSync(basePath, { recursive: true, force: true });
247
+ }
248
+ });
249
+
250
+ test("rogue detection: slice plan on disk, no slice planning row → detected as rogue", () => {
251
+ const basePath = createTmpBase();
252
+ const dbPath = join(basePath, ".gsd", "gsd.db");
253
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
254
+
255
+ try {
256
+ openDatabase(dbPath);
257
+
258
+ const planPath = createSlicePlanOnDisk(basePath, "M001", "S01");
259
+ assert.ok(existsSync(planPath), "Slice plan file should exist on disk");
260
+
261
+ const rogues = detectRogueFileWrites("plan-slice", "M001/S01", basePath);
262
+ assert.equal(rogues.length, 1, "Should detect one rogue slice plan file");
263
+ assert.equal(rogues[0].path, planPath);
264
+ assert.equal(rogues[0].unitType, "plan-slice");
265
+ assert.equal(rogues[0].unitId, "M001/S01");
266
+ } finally {
267
+ closeDatabase();
268
+ rmSync(basePath, { recursive: true, force: true });
269
+ }
270
+ });
271
+
272
+ test("rogue detection: slice plan on disk, DB slice planning row exists → NOT rogue", () => {
273
+ const basePath = createTmpBase();
274
+ const dbPath = join(basePath, ".gsd", "gsd.db");
275
+ mkdirSync(join(basePath, ".gsd"), { recursive: true });
276
+
277
+ try {
278
+ openDatabase(dbPath);
279
+
280
+ createSlicePlanOnDisk(basePath, "M001", "S01");
281
+ insertMilestone({ id: "M001" });
282
+ insertSlice({
283
+ milestoneId: "M001",
284
+ id: "S01",
285
+ title: "Planned Slice",
286
+ status: "pending",
287
+ demo: "Observable plan",
288
+ });
289
+
290
+ const rogues = detectRogueFileWrites("plan-slice", "M001/S01", basePath);
291
+ assert.equal(rogues.length, 0, "Should NOT detect rogue when slice planning state exists");
292
+ } finally {
293
+ closeDatabase();
294
+ rmSync(basePath, { recursive: true, force: true });
295
+ }
296
+ });
@@ -3,8 +3,8 @@
3
3
  // Tests the RuleRegistry class, UnifiedRule types, singleton accessors,
4
4
  // and evaluation methods using mock rules.
5
5
 
6
+ import assert from 'node:assert/strict';
6
7
  import { test, describe, beforeEach } from "node:test";
7
- import { createTestContext } from "./test-helpers.ts";
8
8
  import {
9
9
  RuleRegistry,
10
10
  getRegistry,
@@ -64,9 +64,7 @@ function makeContext(phase: string): DispatchContext {
64
64
  // ─── Tests ────────────────────────────────────────────────────────────────
65
65
 
66
66
  describe("RuleRegistry", () => {
67
- const { assertEq, assertTrue } = createTestContext();
68
-
69
- beforeEach(() => {
67
+ beforeEach(() => {
70
68
  resetRegistry();
71
69
  });
72
70
 
@@ -81,10 +79,10 @@ describe("RuleRegistry", () => {
81
79
 
82
80
  // At minimum, dispatch rules are returned (hook rules depend on prefs)
83
81
  const dispatchRules = listed.filter(r => r.when === "dispatch");
84
- assertEq(dispatchRules.length, 3, "listRules returns 3 dispatch rules");
85
- assertEq(dispatchRules[0].name, "rule-a", "first rule name is rule-a");
86
- assertEq(dispatchRules[1].name, "rule-b", "second rule name is rule-b");
87
- assertEq(dispatchRules[2].name, "rule-c", "third rule name is rule-c");
82
+ assert.deepStrictEqual(dispatchRules.length, 3, "listRules returns 3 dispatch rules");
83
+ assert.deepStrictEqual(dispatchRules[0].name, "rule-a", "first rule name is rule-a");
84
+ assert.deepStrictEqual(dispatchRules[1].name, "rule-b", "second rule name is rule-b");
85
+ assert.deepStrictEqual(dispatchRules[2].name, "rule-c", "third rule name is rule-c");
88
86
  });
89
87
 
90
88
  test("listRules returns correct fields on each rule", () => {
@@ -95,12 +93,12 @@ describe("RuleRegistry", () => {
95
93
  const listed = registry.listRules();
96
94
  const rule = listed.find(r => r.name === "check-fields")!;
97
95
 
98
- assertTrue(rule !== undefined, "rule found by name");
99
- assertEq(rule.when, "dispatch", "when field is dispatch");
100
- assertEq(rule.evaluation, "first-match", "evaluation is first-match");
101
- assertTrue(typeof rule.where === "function", "where is a function");
102
- assertTrue(typeof rule.then === "function", "then is a function");
103
- assertEq(rule.description, "Mock rule for planning", "description is set");
96
+ assert.ok(rule !== undefined, "rule found by name");
97
+ assert.deepStrictEqual(rule.when, "dispatch", "when field is dispatch");
98
+ assert.deepStrictEqual(rule.evaluation, "first-match", "evaluation is first-match");
99
+ assert.ok(typeof rule.where === "function", "where is a function");
100
+ assert.ok(typeof rule.then === "function", "then is a function");
101
+ assert.deepStrictEqual(rule.description, "Mock rule for planning", "description is set");
104
102
  });
105
103
 
106
104
  test("evaluateDispatch returns first matching rule", async () => {
@@ -113,10 +111,10 @@ describe("RuleRegistry", () => {
113
111
  const ctx = makeContext("executing");
114
112
  const result = await registry.evaluateDispatch(ctx);
115
113
 
116
- assertEq(result.action, "dispatch", "result is a dispatch action");
114
+ assert.deepStrictEqual(result.action, "dispatch", "result is a dispatch action");
117
115
  if (result.action === "dispatch") {
118
- assertEq(result.unitType, "test-executing", "matched the executing rule");
119
- assertEq(result.prompt, "Prompt for executing", "prompt from matched rule");
116
+ assert.deepStrictEqual(result.unitType, "test-executing", "matched the executing rule");
117
+ assert.deepStrictEqual(result.prompt, "Prompt for executing", "prompt from matched rule");
120
118
  }
121
119
  });
122
120
 
@@ -128,9 +126,9 @@ describe("RuleRegistry", () => {
128
126
  const ctx = makeContext("blocked");
129
127
  const result = await registry.evaluateDispatch(ctx);
130
128
 
131
- assertEq(result.action, "stop", "result is a stop action");
129
+ assert.deepStrictEqual(result.action, "stop", "result is a stop action");
132
130
  if (result.action === "stop") {
133
- assertTrue(result.reason.includes("blocked"), "stop reason mentions phase");
131
+ assert.ok(result.reason.includes("blocked"), "stop reason mentions phase");
134
132
  }
135
133
  });
136
134
 
@@ -159,9 +157,9 @@ describe("RuleRegistry", () => {
159
157
  const ctx = makeContext("planning");
160
158
  const result = await registry.evaluateDispatch(ctx);
161
159
 
162
- assertEq(result.action, "dispatch", "async dispatch resolved");
160
+ assert.deepStrictEqual(result.action, "dispatch", "async dispatch resolved");
163
161
  if (result.action === "dispatch") {
164
- assertEq(result.unitType, "async-test", "async rule matched");
162
+ assert.deepStrictEqual(result.unitType, "async-test", "async rule matched");
165
163
  }
166
164
  });
167
165
 
@@ -188,11 +186,11 @@ describe("RuleRegistry", () => {
188
186
  // Reset
189
187
  registry.resetState();
190
188
 
191
- assertEq(registry.getActiveHook(), null, "activeHook cleared");
192
- assertEq(registry.hookQueue.length, 0, "hookQueue cleared");
193
- assertEq(registry.cycleCounts.size, 0, "cycleCounts cleared");
194
- assertEq(registry.isRetryPending(), false, "retryPending cleared");
195
- assertEq(registry.consumeRetryTrigger(), null, "retryTrigger cleared");
189
+ assert.deepStrictEqual(registry.getActiveHook(), null, "activeHook cleared");
190
+ assert.deepStrictEqual(registry.hookQueue.length, 0, "hookQueue cleared");
191
+ assert.deepStrictEqual(registry.cycleCounts.size, 0, "cycleCounts cleared");
192
+ assert.deepStrictEqual(registry.isRetryPending(), false, "retryPending cleared");
193
+ assert.deepStrictEqual(registry.consumeRetryTrigger(), null, "retryTrigger cleared");
196
194
  });
197
195
 
198
196
  test("singleton getRegistry throws when not initialized", () => {
@@ -201,9 +199,9 @@ describe("RuleRegistry", () => {
201
199
  getRegistry();
202
200
  } catch (e: any) {
203
201
  threw = true;
204
- assertTrue(e.message.includes("not initialized"), "error mentions not initialized");
202
+ assert.ok(e.message.includes("not initialized"), "error mentions not initialized");
205
203
  }
206
- assertTrue(threw, "getRegistry threw");
204
+ assert.ok(threw, "getRegistry threw");
207
205
  });
208
206
 
209
207
  test("setRegistry / getRegistry round-trips", () => {
@@ -211,20 +209,20 @@ describe("RuleRegistry", () => {
211
209
  setRegistry(registry);
212
210
 
213
211
  const retrieved = getRegistry();
214
- assertEq(retrieved, registry, "getRegistry returns the same instance");
212
+ assert.deepStrictEqual(retrieved, registry, "getRegistry returns the same instance");
215
213
 
216
214
  const listed = retrieved.listRules().filter(r => r.when === "dispatch");
217
- assertEq(listed.length, 1, "singleton has 1 dispatch rule");
218
- assertEq(listed[0].name, "singleton-test", "rule name matches");
215
+ assert.deepStrictEqual(listed.length, 1, "singleton has 1 dispatch rule");
216
+ assert.deepStrictEqual(listed[0].name, "singleton-test", "rule name matches");
219
217
  });
220
218
 
221
219
  test("initRegistry creates and sets singleton", () => {
222
220
  const rules = [mockDispatchRule("init-test", "executing")];
223
221
  const registry = initRegistry(rules);
224
222
 
225
- assertEq(getRegistry(), registry, "initRegistry sets the singleton");
223
+ assert.deepStrictEqual(getRegistry(), registry, "initRegistry sets the singleton");
226
224
  const listed = getRegistry().listRules().filter(r => r.when === "dispatch");
227
- assertEq(listed.length, 1, "singleton has the rule");
225
+ assert.deepStrictEqual(listed.length, 1, "singleton has the rule");
228
226
  });
229
227
 
230
228
  test("evaluateDispatch respects rule order (first match wins)", async () => {
@@ -258,9 +256,9 @@ describe("RuleRegistry", () => {
258
256
  const ctx = makeContext("planning");
259
257
  const result = await registry.evaluateDispatch(ctx);
260
258
 
261
- assertEq(result.action, "dispatch", "dispatch action returned");
259
+ assert.deepStrictEqual(result.action, "dispatch", "dispatch action returned");
262
260
  if (result.action === "dispatch") {
263
- assertEq(result.unitType, "first-wins", "first rule won over second");
261
+ assert.deepStrictEqual(result.unitType, "first-wins", "first rule won over second");
264
262
  }
265
263
  });
266
264
 
@@ -268,18 +266,18 @@ describe("RuleRegistry", () => {
268
266
 
269
267
  test("convertDispatchRules produces correct count of UnifiedRule objects", () => {
270
268
  const converted = convertDispatchRules(DISPATCH_RULES);
271
- assertEq(converted.length, DISPATCH_RULES.length, `convertDispatchRules produces ${DISPATCH_RULES.length} rules`);
269
+ assert.deepStrictEqual(converted.length, DISPATCH_RULES.length, `convertDispatchRules produces ${DISPATCH_RULES.length} rules`);
272
270
  });
273
271
 
274
272
  test("each converted rule has correct when, evaluation, and original name", () => {
275
273
  const converted = convertDispatchRules(DISPATCH_RULES);
276
274
  for (let i = 0; i < converted.length; i++) {
277
275
  const rule = converted[i];
278
- assertEq(rule.when, "dispatch", `rule ${i} has when:"dispatch"`);
279
- assertEq(rule.evaluation, "first-match", `rule ${i} has evaluation:"first-match"`);
280
- assertEq(rule.name, DISPATCH_RULES[i].name, `rule ${i} preserves name "${DISPATCH_RULES[i].name}"`);
281
- assertTrue(typeof rule.where === "function", `rule ${i} has a where function`);
282
- assertTrue(typeof rule.then === "function", `rule ${i} has a then function`);
276
+ assert.deepStrictEqual(rule.when, "dispatch", `rule ${i} has when:"dispatch"`);
277
+ assert.deepStrictEqual(rule.evaluation, "first-match", `rule ${i} has evaluation:"first-match"`);
278
+ assert.deepStrictEqual(rule.name, DISPATCH_RULES[i].name, `rule ${i} preserves name "${DISPATCH_RULES[i].name}"`);
279
+ assert.ok(typeof rule.where === "function", `rule ${i} has a where function`);
280
+ assert.ok(typeof rule.then === "function", `rule ${i} has a then function`);
283
281
  }
284
282
  });
285
283
 
@@ -287,7 +285,7 @@ describe("RuleRegistry", () => {
287
285
  const converted = convertDispatchRules(DISPATCH_RULES);
288
286
  const registry = new RuleRegistry(converted);
289
287
  const listed = registry.listRules().filter(r => r.when === "dispatch");
290
- assertEq(listed.length, DISPATCH_RULES.length, `listRules returns ${DISPATCH_RULES.length} dispatch rules`);
288
+ assert.deepStrictEqual(listed.length, DISPATCH_RULES.length, `listRules returns ${DISPATCH_RULES.length} dispatch rules`);
291
289
  });
292
290
 
293
291
  test("rule names from listRules match getDispatchRuleNames in exact order", () => {
@@ -298,9 +296,9 @@ describe("RuleRegistry", () => {
298
296
  .map(r => r.name);
299
297
  const originalNames = getDispatchRuleNames();
300
298
 
301
- assertEq(listedNames.length, originalNames.length, "same number of names");
299
+ assert.deepStrictEqual(listedNames.length, originalNames.length, "same number of names");
302
300
  for (let i = 0; i < originalNames.length; i++) {
303
- assertEq(listedNames[i], originalNames[i], `name at index ${i} matches: "${originalNames[i]}"`);
301
+ assert.deepStrictEqual(listedNames[i], originalNames[i], `name at index ${i} matches: "${originalNames[i]}"`);
304
302
  }
305
303
  });
306
304
 
@@ -309,18 +307,18 @@ describe("RuleRegistry", () => {
309
307
  test("getOrCreateRegistry lazily creates a registry with empty dispatch rules", () => {
310
308
  // After resetRegistry(), getRegistry() would throw. getOrCreateRegistry() should not.
311
309
  const registry = getOrCreateRegistry();
312
- assertTrue(registry instanceof RuleRegistry, "returns a RuleRegistry instance");
310
+ assert.ok(registry instanceof RuleRegistry, "returns a RuleRegistry instance");
313
311
  const dispatchRules = registry.listRules().filter(r => r.when === "dispatch");
314
- assertEq(dispatchRules.length, 0, "lazily-created registry has 0 dispatch rules");
312
+ assert.deepStrictEqual(dispatchRules.length, 0, "lazily-created registry has 0 dispatch rules");
315
313
  });
316
314
 
317
315
  test("getOrCreateRegistry returns existing registry when initialized", () => {
318
316
  const rules = [mockDispatchRule("explicit-init", "planning")];
319
317
  const explicit = initRegistry(rules);
320
318
  const lazy = getOrCreateRegistry();
321
- assertEq(lazy, explicit, "getOrCreateRegistry returns the same singleton as initRegistry");
319
+ assert.deepStrictEqual(lazy, explicit, "getOrCreateRegistry returns the same singleton as initRegistry");
322
320
  const dispatchRules = lazy.listRules().filter(r => r.when === "dispatch");
323
- assertEq(dispatchRules.length, 1, "singleton has the explicitly initialized dispatch rule");
321
+ assert.deepStrictEqual(dispatchRules.length, 1, "singleton has the explicitly initialized dispatch rule");
324
322
  });
325
323
 
326
324
  // ── Hook-derived rules in listRules ────────────────────────────────
@@ -333,9 +331,9 @@ describe("RuleRegistry", () => {
333
331
  const preDispatchRules = allRules.filter(r => r.when === "pre-dispatch");
334
332
 
335
333
  // No preferences file = no hooks
336
- assertEq(postUnitRules.length, 0, "no post-unit rules when no hooks configured");
337
- assertEq(preDispatchRules.length, 0, "no pre-dispatch rules when no hooks configured");
338
- assertEq(allRules.length, DISPATCH_RULES.length, "total rules equals dispatch rules only");
334
+ assert.deepStrictEqual(postUnitRules.length, 0, "no post-unit rules when no hooks configured");
335
+ assert.deepStrictEqual(preDispatchRules.length, 0, "no pre-dispatch rules when no hooks configured");
336
+ assert.deepStrictEqual(allRules.length, DISPATCH_RULES.length, "total rules equals dispatch rules only");
339
337
  });
340
338
 
341
339
  test("listRules dispatch rules appear first, hooks after", () => {
@@ -345,8 +343,8 @@ describe("RuleRegistry", () => {
345
343
 
346
344
  // Verify dispatch rules come first (indices 0..N-1)
347
345
  for (let i = 0; i < converted.length; i++) {
348
- assertEq(allRules[i].when, "dispatch", `rule at index ${i} is a dispatch rule`);
349
- assertEq(allRules[i].name, converted[i].name, `dispatch rule at index ${i} has correct name`);
346
+ assert.deepStrictEqual(allRules[i].when, "dispatch", `rule at index ${i} is a dispatch rule`);
347
+ assert.deepStrictEqual(allRules[i].name, converted[i].name, `dispatch rule at index ${i} has correct name`);
350
348
  }
351
349
  });
352
350
 
@@ -355,34 +353,34 @@ describe("RuleRegistry", () => {
355
353
  test("evaluatePostUnit returns null for hook-on-hook prevention", () => {
356
354
  const registry = new RuleRegistry([]);
357
355
  const result = registry.evaluatePostUnit("hook/code-review", "M001/S01/T01", "/tmp/test");
358
- assertEq(result, null, "hook units don't trigger other hooks");
356
+ assert.deepStrictEqual(result, null, "hook units don't trigger other hooks");
359
357
  });
360
358
 
361
359
  test("evaluatePostUnit returns null for triage-captures", () => {
362
360
  const registry = new RuleRegistry([]);
363
361
  const result = registry.evaluatePostUnit("triage-captures", "M001/S01/T01", "/tmp/test");
364
- assertEq(result, null, "triage-captures skipped");
362
+ assert.deepStrictEqual(result, null, "triage-captures skipped");
365
363
  });
366
364
 
367
365
  test("evaluatePostUnit returns null for quick-task", () => {
368
366
  const registry = new RuleRegistry([]);
369
367
  const result = registry.evaluatePostUnit("quick-task", "M001/S01/T01", "/tmp/test");
370
- assertEq(result, null, "quick-task skipped");
368
+ assert.deepStrictEqual(result, null, "quick-task skipped");
371
369
  });
372
370
 
373
371
  test("evaluatePreDispatch bypasses hook units", () => {
374
372
  const registry = new RuleRegistry([]);
375
373
  const result = registry.evaluatePreDispatch("hook/review", "M001/S01/T01", "prompt", "/tmp/test");
376
- assertEq(result.action, "proceed", "hook units always proceed");
377
- assertEq(result.prompt, "prompt", "prompt unchanged");
378
- assertEq(result.firedHooks.length, 0, "no hooks fired");
374
+ assert.deepStrictEqual(result.action, "proceed", "hook units always proceed");
375
+ assert.deepStrictEqual(result.prompt, "prompt", "prompt unchanged");
376
+ assert.deepStrictEqual(result.firedHooks.length, 0, "no hooks fired");
379
377
  });
380
378
 
381
379
  test("evaluatePreDispatch proceeds with empty hooks", () => {
382
380
  const registry = new RuleRegistry([]);
383
381
  const result = registry.evaluatePreDispatch("execute-task", "M001/S01/T01", "original prompt", "/tmp/test");
384
- assertEq(result.action, "proceed", "proceeds when no hooks");
385
- assertEq(result.prompt, "original prompt", "prompt unchanged");
382
+ assert.deepStrictEqual(result.action, "proceed", "proceeds when no hooks");
383
+ assert.deepStrictEqual(result.prompt, "original prompt", "prompt unchanged");
386
384
  });
387
385
 
388
386
  // ── matchedRule provenance (S02 journal support) ───────────────────
@@ -395,8 +393,8 @@ describe("RuleRegistry", () => {
395
393
  const ctx = makeContext("planning");
396
394
  const result = await registry.evaluateDispatch(ctx);
397
395
 
398
- assertEq(result.action, "dispatch", "result is a dispatch action");
399
- assertEq(result.matchedRule, "my-planning-rule", "matchedRule is the rule name");
396
+ assert.deepStrictEqual(result.action, "dispatch", "result is a dispatch action");
397
+ assert.deepStrictEqual(result.matchedRule, "my-planning-rule", "matchedRule is the rule name");
400
398
  });
401
399
 
402
400
  test("evaluateDispatch result includes matchedRule '<no-match>' on fallback stop", async () => {
@@ -407,7 +405,7 @@ describe("RuleRegistry", () => {
407
405
  const ctx = makeContext("some-unknown-phase");
408
406
  const result = await registry.evaluateDispatch(ctx);
409
407
 
410
- assertEq(result.action, "stop", "result is a stop action");
411
- assertEq(result.matchedRule, "<no-match>", "matchedRule is '<no-match>' on fallback");
408
+ assert.deepStrictEqual(result.action, "stop", "result is a stop action");
409
+ assert.deepStrictEqual(result.matchedRule, "<no-match>", "matchedRule is '<no-match>' on fallback");
412
410
  });
413
411
  });