gsd-pi 2.47.0 → 2.48.0-dev.ced2eca

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 (200) hide show
  1. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -2
  2. package/dist/resources/extensions/gsd/auto-post-unit.js +17 -3
  3. package/dist/resources/extensions/gsd/auto-start.js +8 -1
  4. package/dist/resources/extensions/gsd/auto-worktree.js +5 -2
  5. package/dist/resources/extensions/gsd/commands/handlers/auto.js +43 -3
  6. package/dist/resources/extensions/gsd/forensics.js +292 -1
  7. package/dist/resources/extensions/gsd/git-service.js +11 -10
  8. package/dist/resources/extensions/gsd/guided-flow.js +85 -3
  9. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +223 -56
  10. package/dist/resources/extensions/gsd/prompts/forensics.md +37 -5
  11. package/dist/resources/extensions/gsd/prompts/run-uat.md +4 -4
  12. package/dist/resources/extensions/gsd/session-forensics.js +10 -1
  13. package/dist/resources/extensions/gsd/worktree-command.js +1 -1
  14. package/dist/web/standalone/.next/BUILD_ID +1 -1
  15. package/dist/web/standalone/.next/app-path-routes-manifest.json +13 -13
  16. package/dist/web/standalone/.next/build-manifest.json +3 -3
  17. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  18. package/dist/web/standalone/.next/required-server-files.json +3 -3
  19. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  20. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  21. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  22. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  23. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  24. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  25. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  26. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  27. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  28. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  29. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  30. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  31. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  32. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  33. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  34. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  35. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  36. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  37. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  38. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  39. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  40. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  41. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  42. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  43. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  44. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  45. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  46. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  47. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  48. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  49. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  50. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  51. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  52. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  53. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  54. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  55. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  56. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  57. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  58. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  59. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  60. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  61. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  62. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  63. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  64. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  65. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  66. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  68. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  69. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  70. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  71. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  72. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  74. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  76. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  78. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  79. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  80. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  81. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  82. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  83. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  84. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  85. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  86. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  87. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  88. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  89. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  90. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  91. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  92. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  93. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  94. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  95. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  96. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  98. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  99. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  100. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  101. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  102. package/dist/web/standalone/.next/server/app/api/switch-root/route_client-reference-manifest.js +1 -1
  103. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +2 -2
  104. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  106. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  108. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  110. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  111. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  112. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  114. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  115. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  116. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  118. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/app/index.html +1 -1
  120. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  121. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  122. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  123. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  125. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/page.js +2 -2
  127. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  128. package/dist/web/standalone/.next/server/app-paths-manifest.json +13 -13
  129. package/dist/web/standalone/.next/server/chunks/229.js +1 -1
  130. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  131. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/middleware.js +2 -2
  133. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  134. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  135. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  136. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  137. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  138. package/dist/web/standalone/.next/static/chunks/app/_not-found/{page-2f24283c162b6ab3.js → page-f2a7482d42a5614b.js} +1 -1
  139. package/dist/web/standalone/.next/static/chunks/app/{layout-9ecfd95f343793f0.js → layout-a16c7a7ecdf0c2cf.js} +1 -1
  140. package/dist/web/standalone/.next/static/chunks/app/page-6654a8cca61a3d1c.js +1 -0
  141. package/dist/web/standalone/.next/static/chunks/main-app-fdab67f7802d7832.js +1 -0
  142. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  143. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  144. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  145. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  146. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  147. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  148. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  149. package/dist/web/standalone/server.js +1 -1
  150. package/dist/worktree-cli.js +1 -1
  151. package/package.json +1 -1
  152. package/packages/pi-agent-core/dist/agent-loop.js +3 -2
  153. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  154. package/packages/pi-agent-core/src/agent-loop.ts +3 -2
  155. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +43 -0
  156. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  157. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/model-registry.js +26 -3
  159. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  160. package/packages/pi-coding-agent/package.json +1 -1
  161. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +70 -0
  162. package/packages/pi-coding-agent/src/core/model-registry.ts +29 -2
  163. package/packages/pi-tui/dist/components/box.d.ts +1 -0
  164. package/packages/pi-tui/dist/components/box.d.ts.map +1 -1
  165. package/packages/pi-tui/dist/components/box.js +10 -0
  166. package/packages/pi-tui/dist/components/box.js.map +1 -1
  167. package/packages/pi-tui/src/components/box.ts +10 -0
  168. package/pkg/package.json +1 -1
  169. package/src/resources/extensions/github-sync/tests/commit-linking.test.ts +8 -4
  170. package/src/resources/extensions/gsd/auto-dispatch.ts +18 -1
  171. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -3
  172. package/src/resources/extensions/gsd/auto-start.ts +7 -1
  173. package/src/resources/extensions/gsd/auto-worktree.ts +4 -2
  174. package/src/resources/extensions/gsd/commands/handlers/auto.ts +46 -3
  175. package/src/resources/extensions/gsd/forensics.ts +329 -2
  176. package/src/resources/extensions/gsd/git-service.ts +12 -11
  177. package/src/resources/extensions/gsd/guided-flow.ts +105 -3
  178. package/src/resources/extensions/gsd/prompts/discuss-headless.md +223 -56
  179. package/src/resources/extensions/gsd/prompts/forensics.md +37 -5
  180. package/src/resources/extensions/gsd/prompts/run-uat.md +4 -4
  181. package/src/resources/extensions/gsd/session-forensics.ts +11 -1
  182. package/src/resources/extensions/gsd/tests/all-milestones-complete-merge.test.ts +2 -2
  183. package/src/resources/extensions/gsd/tests/auto-stash-merge.test.ts +1 -1
  184. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +14 -12
  185. package/src/resources/extensions/gsd/tests/discuss-queued-milestones.test.ts +241 -0
  186. package/src/resources/extensions/gsd/tests/feature-branch-lifecycle-integration.test.ts +1 -1
  187. package/src/resources/extensions/gsd/tests/forensics-error-filter.test.ts +121 -0
  188. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +162 -0
  189. package/src/resources/extensions/gsd/tests/git-service.test.ts +19 -9
  190. package/src/resources/extensions/gsd/tests/milestone-transition-worktree.test.ts +2 -2
  191. package/src/resources/extensions/gsd/tests/parallel-merge.test.ts +6 -6
  192. package/src/resources/extensions/gsd/tests/preflight-context-draft-filter.test.ts +115 -0
  193. package/src/resources/extensions/gsd/tests/run-uat.test.ts +68 -0
  194. package/src/resources/extensions/gsd/tests/stale-milestone-id-reservation.test.ts +79 -0
  195. package/src/resources/extensions/gsd/worktree-command.ts +1 -1
  196. package/dist/web/standalone/.next/static/chunks/app/page-12dd5ece0df4badc.js +0 -1
  197. package/dist/web/standalone/.next/static/chunks/main-app-d3d4c336195465f9.js +0 -1
  198. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-ab5a8926e07ec673.js +0 -1
  199. /package/dist/web/standalone/.next/static/{VPcLnRF4BL8VoJEilBwlB → PTL5V00OW8q4-092tUQKx}/_buildManifest.js +0 -0
  200. /package/dist/web/standalone/.next/static/{VPcLnRF4BL8VoJEilBwlB → PTL5V00OW8q4-092tUQKx}/_ssgManifest.js +0 -0
@@ -29,7 +29,7 @@ import { showProjectInit, offerMigration } from "./init-wizard.js";
29
29
  import { validateDirectory } from "./validate-directory.js";
30
30
  import { showConfirm } from "../shared/tui.js";
31
31
  import { debugLog } from "./debug-logger.js";
32
- import { findMilestoneIds, nextMilestoneId, reserveMilestoneId, getReservedMilestoneIds } from "./milestone-ids.js";
32
+ import { findMilestoneIds, nextMilestoneId, reserveMilestoneId, getReservedMilestoneIds, clearReservedMilestoneIds } from "./milestone-ids.js";
33
33
  import { parkMilestone, discardMilestone } from "./milestone-actions.js";
34
34
  import { resolveModelWithFallbacksForUnit } from "./preferences-models.js";
35
35
  // ─── Re-exports (preserve public API for existing importers) ────────────────
@@ -296,6 +296,8 @@ function bootstrapGsdProject(basePath) {
296
296
  * and dispatches the headless discuss prompt (no Q&A rounds).
297
297
  */
298
298
  export async function showHeadlessMilestoneCreation(ctx, pi, basePath, seedContext) {
299
+ // Clear stale reservations from previous cancelled sessions (#2488)
300
+ clearReservedMilestoneIds();
299
301
  // Ensure .gsd/ is bootstrapped
300
302
  bootstrapGsdProject(basePath);
301
303
  // Generate next milestone ID
@@ -403,9 +405,14 @@ export async function showDiscuss(ctx, pi, basePath) {
403
405
  // Invalidate caches to pick up artifacts written by a just-completed discuss/plan
404
406
  invalidateAllCaches();
405
407
  const state = await deriveState(basePath);
406
- // Guard: no active milestone
408
+ // No active milestone — check for pending milestones to discuss instead
407
409
  if (!state.activeMilestone) {
408
- ctx.ui.notify("No active milestone. Run /gsd to create one first.", "warning");
410
+ const pendingMilestones = state.registry.filter(m => m.status === "pending");
411
+ if (pendingMilestones.length === 0) {
412
+ ctx.ui.notify("No active milestone. Run /gsd to create one first.", "warning");
413
+ return;
414
+ }
415
+ await showDiscussQueuedMilestone(ctx, pi, basePath, pendingMilestones);
409
416
  return;
410
417
  }
411
418
  const mid = state.activeMilestone.id;
@@ -526,6 +533,16 @@ export async function showDiscuss(ctx, pi, basePath) {
526
533
  recommended: s.id === firstUndiscussedId,
527
534
  };
528
535
  });
536
+ // Offer access to queued milestones when any exist
537
+ const pendingMilestones = state.registry.filter(m => m.status === "pending");
538
+ if (pendingMilestones.length > 0) {
539
+ actions.push({
540
+ id: "discuss_queued_milestone",
541
+ label: "Discuss a queued milestone",
542
+ description: `Refine context for ${pendingMilestones.length} queued milestone(s). Does not affect current execution.`,
543
+ recommended: false,
544
+ });
545
+ }
529
546
  const choice = await showNextAction(ctx, {
530
547
  title: "GSD — Discuss a slice",
531
548
  summary: [
@@ -537,6 +554,10 @@ export async function showDiscuss(ctx, pi, basePath) {
537
554
  });
538
555
  if (choice === "not_yet")
539
556
  return;
557
+ if (choice === "discuss_queued_milestone") {
558
+ await showDiscussQueuedMilestone(ctx, pi, basePath, pendingMilestones);
559
+ return;
560
+ }
540
561
  const chosen = pendingSlices.find(s => s.id === choice);
541
562
  if (!chosen)
542
563
  return;
@@ -564,6 +585,63 @@ export async function showDiscuss(ctx, pi, basePath) {
564
585
  invalidateAllCaches();
565
586
  }
566
587
  }
588
+ // ─── Queued Milestone Discussion ─────────────────────────────────────────────
589
+ /**
590
+ * Show a picker of queued (pending) milestones and dispatch a discuss flow for
591
+ * the chosen one. Discussing a queued milestone does NOT activate it — it only
592
+ * refines the CONTEXT.md artifact so it is better prepared when auto-mode
593
+ * eventually reaches it.
594
+ */
595
+ async function showDiscussQueuedMilestone(ctx, pi, basePath, pendingMilestones) {
596
+ const actions = pendingMilestones.map((m, i) => {
597
+ const hasContext = !!resolveMilestoneFile(basePath, m.id, "CONTEXT");
598
+ const hasDraft = !hasContext && !!resolveMilestoneFile(basePath, m.id, "CONTEXT-DRAFT");
599
+ const contextStatus = hasContext ? "context ✓" : hasDraft ? "draft context" : "no context yet";
600
+ return {
601
+ id: m.id,
602
+ label: `${m.id}: ${m.title}`,
603
+ description: `[queued] · ${contextStatus}`,
604
+ recommended: i === 0,
605
+ };
606
+ });
607
+ const choice = await showNextAction(ctx, {
608
+ title: "GSD — Discuss a queued milestone",
609
+ summary: [
610
+ "Select a queued milestone to discuss.",
611
+ "Discussing will update its context file. It will not be activated.",
612
+ ],
613
+ actions,
614
+ notYetMessage: "Run /gsd discuss when ready.",
615
+ });
616
+ if (choice === "not_yet")
617
+ return;
618
+ const chosen = pendingMilestones.find(m => m.id === choice);
619
+ if (!chosen)
620
+ return;
621
+ await dispatchDiscussForMilestone(ctx, pi, basePath, chosen.id, chosen.title);
622
+ }
623
+ /**
624
+ * Dispatch the guided-discuss-milestone prompt for a milestone without
625
+ * setting pendingAutoStart — so discussing a queued milestone does not
626
+ * implicitly activate it when the session ends.
627
+ */
628
+ async function dispatchDiscussForMilestone(ctx, pi, basePath, mid, milestoneTitle) {
629
+ const draftFile = resolveMilestoneFile(basePath, mid, "CONTEXT-DRAFT");
630
+ const draftContent = draftFile ? await loadFile(draftFile) : null;
631
+ const discussMilestoneTemplates = inlineTemplate("context", "Context");
632
+ const structuredQuestionsAvailable = pi.getActiveTools().includes("ask_user_questions") ? "true" : "false";
633
+ const basePrompt = loadPrompt("guided-discuss-milestone", {
634
+ milestoneId: mid,
635
+ milestoneTitle,
636
+ inlinedTemplates: discussMilestoneTemplates,
637
+ structuredQuestionsAvailable,
638
+ commitInstruction: buildDocsCommitInstruction(`docs(${mid}): milestone context from discuss`),
639
+ });
640
+ const prompt = draftContent
641
+ ? `${basePrompt}\n\n## Prior Discussion (Draft Seed)\n\n${draftContent}`
642
+ : basePrompt;
643
+ await dispatchWorkflow(pi, prompt, "gsd-discuss", ctx, "plan-milestone");
644
+ }
567
645
  // ─── Smart Entry Point ────────────────────────────────────────────────────────
568
646
  /**
569
647
  * The one wizard. Reads state, shows contextual options, dispatches into the workflow doc.
@@ -693,6 +771,10 @@ async function handleMilestoneActions(ctx, pi, basePath, milestoneId, milestoneT
693
771
  }
694
772
  export async function showSmartEntry(ctx, pi, basePath, options) {
695
773
  const stepMode = options?.step;
774
+ // ── Clear stale milestone ID reservations from previous cancelled sessions ──
775
+ // Reservations only need to survive within a single /gsd interaction.
776
+ // Without this, each cancelled session permanently bumps the next ID. (#2488)
777
+ clearReservedMilestoneIds();
696
778
  // ── Directory safety check — refuse to operate in system/home dirs ───
697
779
  const dirCheck = validateDirectory(basePath);
698
780
  if (dirCheck.severity === "blocked") {
@@ -1,86 +1,253 @@
1
1
  # Headless Milestone Creation
2
2
 
3
- You are creating a GSD milestone from a provided specification document. This is a **headless** (non-interactive) flow — do NOT ask the user any questions. Work entirely from the provided specification.
3
+ You are creating a GSD milestone from a provided specification document. This is a **headless** (non-interactive) flow — do NOT ask the user any questions. Wherever the interactive flow would ask the user, make your best-judgment call and document it as an assumption.
4
4
 
5
5
  ## Provided Specification
6
6
 
7
7
  {{seedContext}}
8
8
 
9
- ## Your Task
9
+ ## Reflection Step
10
10
 
11
- ### Step 1: Reflect
11
+ Summarize your understanding of the specification concretely — not abstractly:
12
12
 
13
- Summarize your understanding of the specification concretely:
14
- - What is being built
15
- - Major capabilities/features
16
- - Scope estimate (how many milestones × slices)
17
- - Any ambiguities or gaps you notice
13
+ 1. Summarize what is being built in your own words.
14
+ 2. Give an honest size read: roughly how many milestones, roughly how many slices in the first one. Base this on the actual work involved, not a classification label.
15
+ 3. Include scope honesty — a bullet list of the major capabilities: "Here's what I'm reading from the spec: [bullet list of major capabilities]."
16
+ 4. Note any ambiguities, gaps, or areas where the spec is vague.
18
17
 
19
- ### Step 2: Investigate (brief)
18
+ Print this reflection in chat. Do not skip this step.
20
19
 
21
- Quickly scout the codebase to understand what already exists — spend no more than 5-6 tool calls here:
22
- - `ls` the project root and key directories
23
- - Search for relevant existing code, patterns, dependencies
24
- - Check library docs if needed (`resolve_library` / `get_library_docs`)
20
+ ## Vision Mapping
25
21
 
26
- Then move on to writing artifacts. Do not explore exhaustively — the research phase will do deeper investigation later.
22
+ Decide the approach based on the actual scope:
27
23
 
28
- ### Step 3: Make Decisions
24
+ **If the work spans multiple milestones:** Map the full landscape:
25
+ 1. Propose a milestone sequence — names, one-line intents, rough dependencies
26
+ 2. Print this in chat as the working milestone sequence
29
27
 
30
- For any ambiguities or gaps in the specification:
31
- - Make your best-guess decision based on the spec's intent, codebase patterns, and domain conventions
32
- - Document each assumption clearly in the Context file
28
+ **If the work fits in a single milestone:** Proceed directly to investigation.
33
29
 
34
- ### Step 4: Assess Scope
30
+ **Anti-reduction rule:** If the spec describes a big vision, plan the big vision. Do not reduce scope. Phase complex/risky work into later milestones — do not cut it. The spec's ambition is the target, and your job is to sequence it intelligently, not shrink it.
35
31
 
36
- Based on reflection + investigation:
37
- - Is this a single milestone or multiple milestones?
38
- - If multi-milestone: plan the full sequence with dependencies
32
+ ## Mandatory Investigation
39
33
 
40
- ### Step 5: Write Artifacts
34
+ Do a mandatory investigation pass before making any decisions. This is not optional.
41
35
 
42
- **Milestone ID**: {{milestoneId}}
36
+ 1. **Scout the codebase** — `ls`, `find`, `rg`, or `scout` for broad unfamiliar areas. Understand what already exists, what patterns are established, what constraints current code imposes.
37
+ 2. **Check library docs** — `resolve_library` / `get_library_docs` for any tech mentioned in the spec. Get current facts about capabilities, constraints, API shapes, version-specific behavior.
38
+ 3. **Web search** — `search-the-web` if the domain is unfamiliar, if you need current best practices, or if the spec references external services/APIs you need facts about. Use `fetch_page` for full content when snippets aren't enough.
43
39
 
44
- Use these templates exactly:
40
+ **Web search budget:** Budget carefully across investigation + focused research:
41
+ - Prefer `resolve_library` / `get_library_docs` over `web_search` for library documentation.
42
+ - Prefer `search_and_read` for one-shot topic research.
43
+ - Target 2-3 web searches in this investigation pass. Save remaining budget for focused research.
44
+ - Do NOT repeat the same or similar queries.
45
45
 
46
- {{inlinedTemplates}}
46
+ The goal: your decisions should reflect what's actually true in the codebase and ecosystem, not what you assume.
47
+
48
+ ## Autonomous Decision-Making
49
+
50
+ For every area where the spec is ambiguous, vague, or silent:
51
+
52
+ - Apply the depth checklist (below) to identify what needs resolution
53
+ - Make your best-judgment call based on: the spec's intent, codebase patterns, domain conventions, and investigation findings
54
+ - **Document every assumption** in the Context file under an "Assumptions" section
55
+ - For each assumption, note: what the spec said (or didn't say), what you decided, and why
56
+
57
+ ### Depth Checklist
58
+
59
+ Ensure ALL of these are resolved before writing artifacts — from the spec + investigation, not by asking:
60
+
61
+ - [ ] **What is being built** — concrete enough that you could explain it to a stranger
62
+ - [ ] **Why it needs to exist** — the problem it solves or the desire it fulfills
63
+ - [ ] **Who it's for** — even if just the spec author
64
+ - [ ] **What "done" looks like** — observable outcomes, not abstract goals
65
+ - [ ] **The biggest technical unknowns / risks** — what could fail, what hasn't been proven
66
+ - [ ] **What external systems/services this touches** — APIs, databases, third-party services, hardware
67
+
68
+ If the spec leaves any of these unresolved, make your best-judgment call and document it.
69
+
70
+ ## Depth Verification
71
+
72
+ Print a structured depth summary in chat covering:
73
+ - What you understood the spec to describe
74
+ - Key technical findings from investigation
75
+ - Assumptions you made and why
76
+ - Areas where you're least confident
77
+
78
+ This is your audit trail. Print it — do not skip it.
79
+
80
+ ## Focused Research
81
+
82
+ Do a focused research pass before roadmap creation.
83
+
84
+ Research is advisory, not auto-binding. Use the spec + investigation to identify:
85
+ - table stakes the product space usually expects
86
+ - domain-standard behaviors that may be implied but not stated
87
+ - likely omissions that would make the product feel incomplete
88
+ - plausible anti-features or scope traps
89
+ - differentiators worth preserving
90
+
91
+ For multi-milestone visions, research should cover the full landscape, not just the first milestone. Research findings may affect milestone sequencing, not just slice ordering within M001.
92
+
93
+ **Key difference from interactive flow:** Where the interactive flow would present research-surfaced candidate requirements for the user to confirm/defer/reject, you instead apply your best judgment. If a research finding clearly aligns with the spec's intent, include it. If it's tangential or would expand scope beyond what the spec describes, defer it or mark it out of scope. Document the reasoning.
94
+
95
+ ## Capability Contract
96
+
97
+ Before writing a roadmap, produce `.gsd/REQUIREMENTS.md`.
98
+
99
+ Use it as the project's explicit capability contract.
100
+
101
+ Requirements must be organized into:
102
+ - Active
103
+ - Validated
104
+ - Deferred
105
+ - Out of Scope
106
+ - Traceability
107
+
108
+ Each requirement should include:
109
+ - stable ID (`R###`)
110
+ - title
111
+ - class
112
+ - status
113
+ - description
114
+ - why it matters
115
+ - source (`spec`, `inferred`, `research`, or `execution`)
116
+ - primary owning slice
117
+ - supporting slices
118
+ - validation status
119
+ - notes
120
+
121
+ Rules:
122
+ - Keep requirements capability-oriented, not a giant feature inventory
123
+ - Every Active requirement must either be mapped to a roadmap owner, explicitly deferred, blocked with reason, or moved out of scope
124
+ - Product-facing work should capture launchability, primary user loop, continuity, and failure visibility when relevant
125
+ - Later milestones may have provisional ownership, but the first planned milestone should map requirements to concrete slices wherever possible
126
+
127
+ For multi-milestone projects, requirements should span the full vision. Requirements owned by later milestones get provisional ownership. The full requirement set captures the spec's complete vision — milestones are the sequencing strategy, not the scope boundary.
128
+
129
+ **Print the requirements in chat before writing the roadmap.** Print a markdown table with columns: ID, Title, Status, Owner, Source. Group by status (Active, Deferred, Out of Scope).
130
+
131
+ ## Scope Assessment
132
+
133
+ Confirm the size estimate from your reflection still holds. Investigation and research often reveal hidden complexity or simplify things. If the scope grew or shrank significantly, adjust the milestone and slice counts accordingly.
134
+
135
+ ## Output Phase
136
+
137
+ ### Roadmap Preview
138
+
139
+ Before writing any files, **print the planned roadmap in chat**. Print a markdown table with columns: Slice, Title, Risk, Depends, Demo. One row per slice. Below the table, print the milestone definition of done as a bullet list.
140
+
141
+ This is the user's audit trail in the TUI scrollback — do not skip it.
142
+
143
+ ### Naming Convention
47
144
 
48
- **For single milestone**, write in this order:
145
+ Directories use bare IDs. Files use ID-SUFFIX format. Titles live inside file content, not in names.
146
+ - Milestone dir: `.gsd/milestones/{{milestoneId}}/`
147
+ - Milestone files: `{{milestoneId}}-CONTEXT.md`, `{{milestoneId}}-ROADMAP.md`
148
+ - Slice dirs: `S01/`, `S02/`, etc.
149
+
150
+ ### Single Milestone
151
+
152
+ In a single pass:
49
153
  1. `mkdir -p .gsd/milestones/{{milestoneId}}/slices`
50
- 2. Write `.gsd/PROJECT.md` (using Project template)
51
- 3. Write `.gsd/REQUIREMENTS.md` (using Requirements template)
52
- 4. Write `{{contextPath}}` (using Context template) — preserve the specification's exact terminology, emphasis, and specific framing. Do not paraphrase domain-specific language into generics. Document assumptions under an "Assumptions" section.
53
- 5. Write `{{roadmapPath}}` (using Roadmap template) — decompose into demoable vertical slices with checkboxes, risk, depends, demo sentences, proof strategy, verification classes, milestone definition of done, requirement coverage, and a boundary map. If the milestone crosses multiple runtime boundaries, include an explicit final integration slice.
54
- 6. Seed `.gsd/DECISIONS.md` (using Decisions template)
154
+ 2. Write or update `.gsd/PROJECT.md` use the **Project** output template below. Describe what the project is, its current state, and list the milestone sequence.
155
+ 3. Write or update `.gsd/REQUIREMENTS.md` use the **Requirements** output template below. Confirm requirement states, ownership, and traceability before roadmap creation.
156
+
157
+ **Depth-Preservation Guidance for context.md:**
158
+ Preserve the specification's exact terminology, emphasis, and specific framing. Do not paraphrase domain-specific language into generics. If the spec said "craft feel," write "craft feel" — not "high-quality user experience." The context file is downstream agents' only window into this conversation — flattening specifics into generics loses the signal that shaped every decision.
159
+
160
+ 4. Write `{{contextPath}}` — use the **Context** output template below. Preserve key risks, unknowns, existing codebase constraints, integration points, and relevant requirements surfaced during research. Include an "Assumptions" section documenting every judgment call.
161
+ 5. Call `gsd_plan_milestone` to create the roadmap. Decompose into demoable vertical slices with risk, depends, demo sentences, proof strategy, verification classes, milestone definition of done, requirement coverage, and a boundary map. If the milestone crosses multiple runtime boundaries, include an explicit final integration slice that proves the assembled system works end-to-end in a real environment. Use the **Roadmap** output template below to structure the tool call parameters.
162
+ 6. For each architectural or pattern decision, call `gsd_decision_save` — the tool auto-assigns IDs and regenerates `.gsd/DECISIONS.md` automatically.
55
163
  7. {{commitInstruction}}
56
- 9. Say exactly: "Milestone {{milestoneId}} ready."
57
164
 
58
- **For multi-milestone**, write in this order:
165
+ After writing the files, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
166
+
167
+ ### Multi-Milestone
168
+
169
+ #### Phase 1: Shared artifacts
170
+
59
171
  1. For each milestone, call `gsd_milestone_generate_id` to get its ID — never invent milestone IDs manually. Then `mkdir -p .gsd/milestones/<ID>/slices` for each.
60
- 2. Write `.gsd/PROJECT.md` — full vision across ALL milestones (using Project template)
61
- 3. Write `.gsd/REQUIREMENTS.md` — full capability contract (using Requirements template)
62
- 4. Seed `.gsd/DECISIONS.md` (using Decisions template)
63
- 5. Write PRIMARY `{{contextPath}}` — full context with all assumptions documented
64
- 6. Write PRIMARY `{{roadmapPath}}` — detailed slices for the first milestone only
65
- 7. For each remaining milestone, write full CONTEXT.md with `depends_on` frontmatter:
66
- ```yaml
67
- ---
68
- depends_on: [M001, M002]
69
- ---
70
-
71
- # M003: Title
72
- ```
73
- Each context file should be rich enough that a future agent — with no memory of this conversation — can understand the intent, constraints, dependencies, what the milestone unlocks, and what "done" looks like.
74
- 8. {{multiMilestoneCommitInstruction}}
75
- 10. Say exactly: "Milestone {{milestoneId}} ready."
172
+ 2. Write `.gsd/PROJECT.md` — use the **Project** output template below.
173
+ 3. Write `.gsd/REQUIREMENTS.md` — use the **Requirements** output template below. Capture Active, Deferred, Out of Scope, and any already Validated requirements. Later milestones may have provisional ownership where slice plans do not exist yet.
174
+ 4. For any architectural or pattern decisions, call `gsd_decision_save` — the tool auto-assigns IDs and regenerates `.gsd/DECISIONS.md` automatically.
175
+
176
+ #### Phase 2: Primary milestone
177
+
178
+ 5. Write a full `CONTEXT.md` for the primary milestone (the first in sequence). Include an "Assumptions" section.
179
+ 6. Call `gsd_plan_milestone` for **only the primary milestone** — detail-planning later milestones now is waste because the codebase will change. Include requirement coverage and a milestone definition of done.
180
+
181
+ #### MANDATORY: depends_on Frontmatter in CONTEXT.md
182
+
183
+ Every CONTEXT.md for a milestone that depends on other milestones MUST have YAML frontmatter with `depends_on`. The auto-mode state machine reads this field to determine execution order — without it, milestones may execute out of order or in parallel when they shouldn't.
184
+
185
+ ```yaml
186
+ ---
187
+ depends_on: [M001, M002]
188
+ ---
189
+
190
+ # M003: Title
191
+ ```
192
+
193
+ If a milestone has no dependencies, omit the frontmatter. Do NOT rely on QUEUE.md or PROJECT.md for dependency tracking — the state machine only reads CONTEXT.md frontmatter.
194
+
195
+ #### Phase 3: Remaining milestones
196
+
197
+ For each remaining milestone, in dependency order, autonomously decide the best readiness mode:
198
+
199
+ - **Write full context** — if the spec provides enough detail for this milestone and investigation confirms feasibility. Write a full `CONTEXT.md` with technical assumptions verified against the actual codebase.
200
+ - **Write draft for later** — if the spec has seed material but the milestone needs its own investigation/research in a future session. Write a `CONTEXT-DRAFT.md` capturing seed material, key ideas, provisional scope, and open questions. **Downstream:** Auto-mode pauses at this milestone and prompts the user to discuss.
201
+ - **Just queue it** — if the milestone is identified but the spec provides no actionable detail. No context file written. **Downstream:** Auto-mode pauses and starts a full discussion from scratch.
202
+
203
+ **Default to writing full context** when the spec is detailed enough. Default to draft when the spec mentions the milestone but is vague. Default to queue when the milestone is implied by the vision but not described.
204
+
205
+ **Technical Assumption Verification is still MANDATORY** for full-context milestones:
206
+ 1. Read the actual code for every file or module you reference. Confirm APIs exist, check what functions actually do.
207
+ 2. Check for stale assumptions — verify referenced modules still work as described.
208
+ 3. Print findings in chat before writing each milestone's CONTEXT.md.
209
+
210
+ Each context file (full or draft) should be rich enough that a future agent encountering it fresh — with no memory of this conversation — can understand the intent, constraints, dependencies, what this milestone unlocks, and what "done" looks like.
211
+
212
+ #### Milestone Gate Tracking (MANDATORY for multi-milestone)
213
+
214
+ After deciding each milestone's readiness, immediately write or update `.gsd/DISCUSSION-MANIFEST.json`:
215
+
216
+ ```json
217
+ {
218
+ "primary": "M001",
219
+ "milestones": {
220
+ "M001": { "gate": "discussed", "context": "full" },
221
+ "M002": { "gate": "discussed", "context": "full" },
222
+ "M003": { "gate": "queued", "context": "none" }
223
+ },
224
+ "total": 3,
225
+ "gates_completed": 3
226
+ }
227
+ ```
228
+
229
+ Write this file AFTER each gate decision, not just at the end. Update `gates_completed` incrementally. The system reads this file and BLOCKS auto-start if `gates_completed < total`.
230
+
231
+ For single-milestone projects, do NOT write this file.
232
+
233
+ #### Phase 4: Finalize
234
+
235
+ 7. {{multiMilestoneCommitInstruction}}
236
+
237
+ After writing the files, say exactly: "Milestone {{milestoneId}} ready." — nothing else. Auto-mode will start automatically.
76
238
 
77
239
  ## Critical Rules
78
240
 
79
- - **DO NOT ask the user any questions** — this is headless mode
241
+ - **DO NOT ask the user any questions** — this is headless mode. Make judgment calls and document them.
80
242
  - **Preserve the specification's terminology** — don't paraphrase domain-specific language
81
- - **Document assumptions** — when you make a judgment call, note it in CONTEXT.md under "Assumptions"
82
- - **Investigate before writing** — always scout the codebase first
83
- - **Use depends_on frontmatter** for multi-milestone sequences (the state machine reads this field to determine execution order)
84
- - **Anti-reduction rule** — if the spec describes a big vision, plan the big vision. Do not ask "what's the minimum viable version?" or reduce scope. Phase complex/risky work into later milestones — do not cut it.
85
- - **Naming convention** — always use `gsd_milestone_generate_id` to get milestone IDs. Directories use bare IDs (e.g. `M001/` or `M001-r5jzab/`), files use ID-SUFFIX format (e.g. `M001-CONTEXT.md` or `M001-r5jzab-CONTEXT.md`). Never invent milestone IDs manually.
243
+ - **Document assumptions** — every judgment call gets noted in CONTEXT.md under "Assumptions" with reasoning
244
+ - **Investigate thoroughly** — scout codebase, check library docs, web search. Same rigor as interactive mode.
245
+ - **Do focused research** identify table stakes, domain standards, omissions, scope traps. Same rigor as interactive mode.
246
+ - **Use proper tools** — `gsd_plan_milestone` for roadmaps, `gsd_decision_save` for decisions, `gsd_milestone_generate_id` for IDs
247
+ - **Print artifacts in chat** — requirements table, roadmap preview, depth summary. The TUI scrollback is the user's audit trail.
248
+ - **Use depends_on frontmatter** for multi-milestone sequences
249
+ - **Anti-reduction rule** — if the spec describes a big vision, plan the big vision. Phase complexity — don't cut it.
250
+ - **Naming convention** — always use `gsd_milestone_generate_id` for IDs. Directories use bare IDs, files use ID-SUFFIX format.
86
251
  - **End with "Milestone {{milestoneId}} ready."** — this triggers auto-start detection
252
+
253
+ {{inlinedTemplates}}
@@ -36,6 +36,8 @@ GSD extension source code is at: `{{gsdSourceDir}}`
36
36
  ├── doctor-history.jsonl — doctor check history
37
37
  ├── activity/ — session activity logs (JSONL per unit)
38
38
  │ └── {seq}-{unitType}-{unitId}.jsonl
39
+ ├── journal/ — structured event journal (JSONL per day)
40
+ │ └── YYYY-MM-DD.jsonl
39
41
  ├── runtime/
40
42
  │ ├── paused-session.json — serialized session when auto pauses
41
43
  │ └── headless-context.md — headless resume context
@@ -60,6 +62,32 @@ GSD extension source code is at: `{{gsdSourceDir}}`
60
62
  - `usage` field on assistant messages: `input`, `output`, `cacheRead`, `cacheWrite`, `totalTokens`, `cost`
61
63
  - **To trace a failure**: find the last activity log, search for `isError: true` tool results, then read the agent's reasoning text preceding that error
62
64
 
65
+ ### Journal Format (`.gsd/journal/`)
66
+
67
+ The journal is a structured event log for auto-mode iterations. Each daily file contains JSONL entries:
68
+
69
+ ```
70
+ { ts: "ISO-8601", flowId: "UUID", seq: 0, eventType: "iteration-start", rule?: "rule-name", causedBy?: { flowId, seq }, data?: { unitId, status, ... } }
71
+ ```
72
+
73
+ **Key event types:**
74
+ - `iteration-start` / `iteration-end` — marks loop iteration boundaries
75
+ - `dispatch-match` / `dispatch-stop` — what the auto-mode decided to do (or not do)
76
+ - `unit-start` / `unit-end` — lifecycle of individual work units
77
+ - `terminal` — auto-mode reached a terminal state (all done, budget exceeded, etc.)
78
+ - `guard-block` — dispatch was blocked by a guard condition (e.g. needs user input)
79
+ - `stuck-detected` — the loop detected it was stuck (same unit repeatedly dispatched)
80
+ - `milestone-transition` — a milestone was promoted or completed
81
+ - `worktree-enter` / `worktree-create-failed` / `worktree-merge-start` / `worktree-merge-failed` — worktree operations
82
+
83
+ **Key concepts:**
84
+ - **flowId**: UUID grouping all events in one iteration. Use to reconstruct what happened in a single loop pass.
85
+ - **causedBy**: Cross-reference to a prior event (same or different flow). Enables causal chain tracing.
86
+ - **seq**: Monotonically increasing within a flow. Reconstruct event order within an iteration.
87
+
88
+ **To trace a stuck loop**: filter for `stuck-detected` events, then follow `flowId` to see the surrounding dispatch and unit events.
89
+ **To trace a guard block**: filter for `guard-block` events, check `data.reason` for why dispatch was blocked.
90
+
63
91
  ### Crash Lock Format (`auto.lock`)
64
92
 
65
93
  JSON with fields: `pid`, `startedAt`, `unitType`, `unitId`, `unitStartedAt`, `completedUnits`, `sessionFile`
@@ -78,20 +106,24 @@ A unit dispatched more than once (`type/id` appears multiple times) indicates a
78
106
 
79
107
  1. **Start with the pre-parsed forensic report** above. The anomaly section contains automated findings — treat these as leads, not conclusions.
80
108
 
81
- 2. **Form hypotheses** about which module and code path is responsible. Use the source map to identify candidate files.
109
+ 2. **Check the journal timeline** if present. The journal events show the auto-mode's decision sequence (dispatches, guards, stuck detection, worktree operations). Use flow IDs to group related events and trace causal chains.
110
+
111
+ 3. **Cross-reference activity logs and journal**. Activity logs show *what the LLM did* (tool calls, reasoning, errors). Journal events show *what auto-mode decided* (dispatch rules, iteration boundaries, state transitions). Together they reveal the full picture.
112
+
113
+ 4. **Form hypotheses** about which module and code path is responsible. Use the source map to identify candidate files.
82
114
 
83
- 3. **Read the actual GSD source code** at `{{gsdSourceDir}}` to confirm or deny each hypothesis. Do not guess what code does — read it.
115
+ 5. **Read the actual GSD source code** at `{{gsdSourceDir}}` to confirm or deny each hypothesis. Do not guess what code does — read it.
84
116
 
85
- 4. **Trace the code path** from the entry point (usually `auto-loop.ts` dispatch or `auto-dispatch.ts`) through to the failure point. Follow function calls across files.
117
+ 6. **Trace the code path** from the entry point (usually `auto-loop.ts` dispatch or `auto-dispatch.ts`) through to the failure point. Follow function calls across files.
86
118
 
87
- 5. **Identify the specific file and line** where the bug lives. Determine what kind of defect it is:
119
+ 7. **Identify the specific file and line** where the bug lives. Determine what kind of defect it is:
88
120
  - Missing edge case / unhandled condition
89
121
  - Wrong boolean logic or comparison
90
122
  - Race condition or ordering issue
91
123
  - State corruption (e.g. completed-units.json out of sync with artifacts)
92
124
  - Timeout / recovery logic not triggering correctly
93
125
 
94
- 6. **Clarify if needed.** Use ask_user_questions (max 2 questions) only if the report is genuinely insufficient. Do not ask questions you can answer from the data or source code.
126
+ 8. **Clarify if needed.** Use ask_user_questions (max 2 questions) only if the report is genuinely insufficient. Do not ask questions you can answer from the data or source code.
95
127
 
96
128
  ## Output
97
129
 
@@ -29,7 +29,7 @@ You are the UAT runner. Execute every check defined in `{{uatPath}}` as deeply a
29
29
  - `runtime-executable` — execute the specified command or script. Capture stdout/stderr as evidence. Record pass/fail based on exit code and output.
30
30
  - `live-runtime` — exercise the real runtime path. Start or connect to the app/service if needed, use browser/runtime/network checks, and verify observable behavior.
31
31
  - `mixed` — run all automatable artifact-driven and live-runtime checks. Separate any remaining human-only checks explicitly.
32
- - `human-experience` — automate setup, preconditions, screenshots, logs, and objective checks, but do **not** invent subjective PASS results. Mark taste-based, experiential, or purely human-judgment checks as `NEEDS-HUMAN` and use an overall verdict of `PARTIAL` unless every required check was objective and passed.
32
+ - `human-experience` — automate setup, preconditions, screenshots, logs, and objective checks, but do **not** invent subjective PASS results. Mark taste-based, experiential, or purely human-judgment checks as `NEEDS-HUMAN`. Use an overall verdict of `PASS` when all automatable checks succeed (even if human-only checks remain as `NEEDS-HUMAN`). Use `PARTIAL` only when automatable checks themselves were inconclusive.
33
33
 
34
34
  ### Evidence tools
35
35
 
@@ -51,9 +51,9 @@ For each check, record:
51
51
  - `PASS`, `FAIL`, or `NEEDS-HUMAN`
52
52
 
53
53
  After running all checks, compute the **overall verdict**:
54
- - `PASS` — all required checks passed and no human-only checks remain
55
- - `FAIL` — one or more checks failed
56
- - `PARTIAL` — some checks passed, but one or more checks were skipped, inconclusive, or still require human judgment
54
+ - `PASS` — all automatable checks passed. Any remaining checks that honestly require human judgment are marked `NEEDS-HUMAN` with clear instructions for the human reviewer. (This is the correct verdict for mixed/human-experience/live-runtime modes when all automatable checks succeed.)
55
+ - `FAIL` — one or more automatable checks failed
56
+ - `PARTIAL` — one or more automatable checks were skipped or returned inconclusive results (not the same as `NEEDS-HUMAN` — use PARTIAL only when the agent itself could not determine pass/fail for a check it was supposed to automate)
57
57
 
58
58
  Call `gsd_summary_save` with `milestone_id: {{milestoneId}}`, `slice_id: {{sliceId}}`, `artifact_type: "ASSESSMENT"`, and the full UAT result markdown as `content` — the tool computes the file path and persists to both DB and disk. The content should follow this format:
59
59
 
@@ -126,7 +126,16 @@ export function extractTrace(entries) {
126
126
  }
127
127
  }
128
128
  if (isError && resultText) {
129
- errors.push(resultText.slice(0, 300));
129
+ // Filter out benign "errors" that are normal during code exploration:
130
+ // - grep/rg/find returning exit code 1 (no matches) is expected POSIX behavior
131
+ // - User interrupts (Escape/skip) are intentional, not failures
132
+ const trimmed = resultText.trim();
133
+ const isBenignNoMatch = pending?.name === "bash" &&
134
+ /^\(no output\)\s*\n\s*Command exited with code 1$/m.test(trimmed);
135
+ const isUserSkip = /^Skipped due to queued user message/i.test(trimmed);
136
+ if (!isBenignNoMatch && !isUserSkip) {
137
+ errors.push(resultText.slice(0, 300));
138
+ }
130
139
  }
131
140
  }
132
141
  }
@@ -548,7 +548,7 @@ async function handleMerge(basePath, name, ctx, pi, targetBranch) {
548
548
  // --- Deterministic merge path (preferred) ---
549
549
  // Try a direct squash-merge first. Only fall back to LLM on conflict.
550
550
  const commitType = inferCommitType(name);
551
- const commitMessage = `${commitType}(${name}): merge worktree ${name}`;
551
+ const commitMessage = `${commitType}: merge worktree ${name}\n\nGSD-Worktree: ${name}`;
552
552
  // Reconcile worktree DB into main DB before squash merge
553
553
  const wtDbPath = join(worktreePath(basePath, name), ".gsd", "gsd.db");
554
554
  const mainDbPath = join(basePath, ".gsd", "gsd.db");
@@ -1 +1 @@
1
- VPcLnRF4BL8VoJEilBwlB
1
+ PTL5V00OW8q4-092tUQKx