gsd-pi 2.80.0-dev.e146beb20 → 2.80.0-dev.e51d2c88c

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 (197) hide show
  1. package/README.md +4 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/phases.js +29 -15
  4. package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
  5. package/dist/resources/extensions/gsd/auto/run-unit.js +13 -1
  6. package/dist/resources/extensions/gsd/auto-prompts.js +13 -1
  7. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  8. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  9. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  10. package/dist/resources/extensions/gsd/auto.js +66 -4
  11. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +21 -2
  12. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +27 -20
  13. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +21 -0
  14. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  15. package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
  16. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  17. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  18. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  19. package/dist/resources/extensions/gsd/guided-flow.js +33 -4
  20. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  21. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  22. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  23. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  24. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +14 -13
  25. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  26. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  27. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  28. package/dist/resources/extensions/gsd/quick.js +34 -2
  29. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  30. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  31. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  32. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  33. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  34. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  35. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  36. package/dist/resources/extensions/gsd/unit-runtime.js +11 -0
  37. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  38. package/dist/web/standalone/.next/BUILD_ID +1 -1
  39. package/dist/web/standalone/.next/app-path-routes-manifest.json +18 -18
  40. package/dist/web/standalone/.next/build-manifest.json +2 -2
  41. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  42. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  43. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  44. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  45. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  46. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  47. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  48. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  51. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/index.html +1 -1
  59. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app-paths-manifest.json +18 -18
  66. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  67. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  68. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  69. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  70. package/package.json +3 -3
  71. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  72. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  73. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  74. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  75. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  76. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  77. package/packages/native/tsconfig.tsbuildinfo +1 -1
  78. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  79. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  80. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  81. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
  82. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  83. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
  84. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  85. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  86. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  87. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  88. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  89. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  90. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  91. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  92. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  93. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +1 -0
  94. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  95. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -0
  96. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  97. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +2 -0
  98. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  99. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +7 -0
  100. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  101. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  102. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  103. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  104. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  105. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  106. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  107. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  108. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +3 -0
  109. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  110. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  111. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +13 -5
  112. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  113. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +53 -0
  114. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  115. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  116. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  117. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  118. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  119. package/packages/pi-coding-agent/src/core/agent-session.ts +8 -0
  120. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
  121. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  122. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  123. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +2 -0
  124. package/packages/pi-coding-agent/src/core/extensions/runner.ts +3 -0
  125. package/packages/pi-coding-agent/src/core/extensions/types.ts +7 -0
  126. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  127. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +4 -0
  128. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +56 -0
  129. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +22 -7
  130. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  131. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  132. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  133. package/packages/pi-tui/dist/tui.js +18 -8
  134. package/packages/pi-tui/dist/tui.js.map +1 -1
  135. package/packages/pi-tui/src/tui.ts +20 -8
  136. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  137. package/src/resources/extensions/gsd/auto/phases.ts +35 -20
  138. package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
  139. package/src/resources/extensions/gsd/auto/run-unit.ts +18 -1
  140. package/src/resources/extensions/gsd/auto-prompts.ts +17 -1
  141. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  142. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  143. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  144. package/src/resources/extensions/gsd/auto.ts +78 -3
  145. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +21 -1
  146. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +27 -19
  147. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  148. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  149. package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
  150. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  151. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  152. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  153. package/src/resources/extensions/gsd/guided-flow.ts +49 -4
  154. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  155. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  156. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  157. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  158. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  159. package/src/resources/extensions/gsd/prompts/complete-milestone.md +14 -13
  160. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  161. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  162. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  163. package/src/resources/extensions/gsd/quick.ts +37 -2
  164. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +71 -0
  165. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  166. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  167. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  168. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  169. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  170. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  171. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  172. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +234 -0
  173. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  174. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  175. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  176. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  177. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  178. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  179. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  180. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  181. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  182. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
  183. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  184. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  185. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
  186. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +30 -0
  187. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  188. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  189. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  190. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  191. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  192. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  193. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  194. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  195. package/src/resources/extensions/gsd/unit-runtime.ts +11 -0
  196. /package/dist/web/standalone/.next/static/{y73quA-XdLo9n41nxphjW → 8F5YpnZNBaooIWGF4GBV3}/_buildManifest.js +0 -0
  197. /package/dist/web/standalone/.next/static/{y73quA-XdLo9n41nxphjW → 8F5YpnZNBaooIWGF4GBV3}/_ssgManifest.js +0 -0
@@ -111,15 +111,41 @@ function warmCache() {
111
111
  }
112
112
  }
113
113
  let warmCacheScheduled = false;
114
+ let warmCacheRan = false;
115
+ let warmCacheTimer;
116
+ /**
117
+ * Synchronously snapshot the prompt/template tree into the cache.
118
+ *
119
+ * Safe to call immediately after `initResources()` because that function uses
120
+ * synchronous fs APIs — there is no race window that requires deferring the
121
+ * cache warm via setTimeout. Idempotent: subsequent calls are no-ops.
122
+ *
123
+ * Cancels the fallback `scheduleWarmCache` timer if it is still pending.
124
+ */
125
+ export function primeCache() {
126
+ if (warmCacheRan)
127
+ return;
128
+ if (warmCacheTimer) {
129
+ clearTimeout(warmCacheTimer);
130
+ warmCacheTimer = undefined;
131
+ }
132
+ warmCacheScheduled = true;
133
+ warmCacheRan = true;
134
+ warmCache();
135
+ }
114
136
  function scheduleWarmCache() {
115
137
  if (warmCacheScheduled)
116
138
  return;
117
139
  warmCacheScheduled = true;
118
140
  const run = () => {
141
+ warmCacheTimer = undefined;
142
+ if (warmCacheRan)
143
+ return;
144
+ warmCacheRan = true;
119
145
  warmCache();
120
146
  };
121
- const timer = setTimeout(run, 1000);
122
- timer.unref?.();
147
+ warmCacheTimer = setTimeout(run, 1000);
148
+ warmCacheTimer.unref?.();
123
149
  }
124
150
  // Snapshot the full prompt/template tree after import so extension startup only
125
151
  // pays for prompts that are actually needed immediately.
@@ -29,14 +29,15 @@ Subagents report only; they do not write user source. Fold any findings into Dec
29
29
 
30
30
  ## Steps
31
31
 
32
- 1. Use the **Milestone Summary** output template from the inlined context above
33
- 2. {{skillActivation}}
34
- 3. **Verify code changes exist.** Compare milestone work against the integration branch (`main`, `master`, or recorded branch), using merge-base as older revision and `HEAD` as newer. If the diff lists non-`.gsd/` files, pass. If `HEAD` equals the integration branch/merge-base, treat it as a self-diff retry: inspect milestone-scoped commit evidence (`GSD-Unit: {{milestoneId}}` or production `GSD-Task: Sxx/Tyy` trailers touching `.gsd/milestones/{{milestoneId}}/`) and verify those commits touched non-`.gsd/` files. Record **verification failure** only when neither source shows implementation files.
35
- 4. Verify every **success criterion** from `{{roadmapPath}}`. If passing validation is present, summarize the validation evidence instead of re-auditing it; otherwise verify with evidence from summaries, tests, or observable behavior. Record unmet criteria as **verification failure**.
36
- 5. Verify **definition of done**: all slices `[x]`, summaries exist, and integrations work. If passing validation is present, trust its integration/verification verdict unless inconsistent with current artifacts. Record unmet items as **verification failure**.
37
- 6. If the roadmap includes a **Horizontal Checklist**, verify each item and note unchecked items in the summary.
38
- 7. Fill the **Decision Re-evaluation** table: compare each key `.gsd/DECISIONS.md` decision from this milestone with what shipped, and flag decisions to revisit.
39
- 8. Validate **requirement status transitions**. For each changed requirement, confirm evidence supports the new status. Requirements may move between Active, Validated, Deferred, Blocked, or Out of Scope only with proof.
32
+ 1. **Duplicate completion guard:** Call `gsd_milestone_status` for `{{milestoneId}}` before any durable writes. If the returned milestone **status is `complete`**, this is a stale or duplicate closeout turn: do NOT mutate requirements, do NOT refresh the project document, do NOT write LEARNINGS, and do NOT persist milestone completion again. Say: "Milestone {{milestoneId}} is already complete." and stop.
33
+ 2. Use the **Milestone Summary** output template from the inlined context above
34
+ 3. {{skillActivation}}
35
+ 4. **Verify code changes exist.** Compare milestone work against the integration branch (`main`, `master`, or recorded branch), using merge-base as older revision and `HEAD` as newer. If the diff lists non-`.gsd/` files, pass. If `HEAD` equals the integration branch/merge-base, treat it as a self-diff retry: inspect milestone-scoped commit evidence (`GSD-Unit: {{milestoneId}}` or production `GSD-Task: Sxx/Tyy` trailers touching `.gsd/milestones/{{milestoneId}}/`) and verify those commits touched non-`.gsd/` files. Record **verification failure** only when neither source shows implementation files.
36
+ 5. Verify every **success criterion** from `{{roadmapPath}}`. If passing validation is present, summarize the validation evidence instead of re-auditing it; otherwise verify with evidence from summaries, tests, or observable behavior. Record unmet criteria as **verification failure**.
37
+ 6. Verify **definition of done**: all slices `[x]`, summaries exist, and integrations work. If passing validation is present, trust its integration/verification verdict unless inconsistent with current artifacts. Record unmet items as **verification failure**.
38
+ 7. If the roadmap includes a **Horizontal Checklist**, verify each item and note unchecked items in the summary.
39
+ 8. Fill the **Decision Re-evaluation** table: compare each key `.gsd/DECISIONS.md` decision from this milestone with what shipped, and flag decisions to revisit.
40
+ 9. Validate **requirement status transitions**. For each changed requirement, confirm evidence supports the new status. Requirements may move between Active, Validated, Deferred, Blocked, or Out of Scope only with proof.
40
41
 
41
42
  **DB access safety:** Do NOT query `.gsd/gsd.db` directly via `sqlite3` or `node -e require('better-sqlite3')`; the engine owns the WAL connection. Use `gsd_milestone_status`, inlined context, or `gsd_*` tools; never direct SQL.
42
43
 
@@ -53,13 +54,13 @@ Subagents report only; they do not write user source. Fold any findings into Dec
53
54
 
54
55
  **Success path** (all verifications passed):
55
56
 
56
- 9. For each requirement whose status changed in step 8, call `gsd_requirement_update` with the requirement ID and updated `status` and `validation` fields — the tool regenerates `.gsd/REQUIREMENTS.md` automatically. Do this BEFORE completing the milestone so requirement updates are persisted.
57
- 10. Update `.gsd/PROJECT.md`: use the `write` tool with `path: ".gsd/PROJECT.md"` and `content` containing the full updated document reflecting milestone completion and current project state. Do NOT use the `edit` tool for this — PROJECT.md is a full-document refresh.
58
- 11. Extract structured learnings from this milestone and persist them to the GSD memory store. Follow the procedure block immediately below — it writes `{{milestoneId}}-LEARNINGS.md` as the audit trail and persists Patterns, Lessons, and Decisions via `capture_thought` (categories: pattern, gotcha/convention, architecture). The memory store is the single source of truth for cross-session durable knowledge (ADR-013).
57
+ 10. For each requirement whose status changed in step 9, call `gsd_requirement_update` with the requirement ID and updated `status` and `validation` fields — the tool regenerates `.gsd/REQUIREMENTS.md` automatically. Do this BEFORE completing the milestone so requirement updates are persisted.
58
+ 11. Update `.gsd/PROJECT.md`: use the `write` tool with `path: ".gsd/PROJECT.md"` and `content` containing the full updated document reflecting milestone completion and current project state. Do NOT use the `edit` tool for this — PROJECT.md is a full-document refresh.
59
+ 12. Extract structured learnings from this milestone and persist them to the GSD memory store. Follow the procedure block immediately below — it writes `{{milestoneId}}-LEARNINGS.md` as the audit trail and persists Patterns, Lessons, and Decisions via `capture_thought` (categories: pattern, gotcha/convention, architecture). The memory store is the single source of truth for cross-session durable knowledge (ADR-013).
59
60
 
60
61
  {{extractLearningsSteps}}
61
62
 
62
- 12. **Persist completion through `gsd_complete_milestone`.** Call it with the parameters below. This must be the final persistent write in the unit. The tool updates the milestone status in the DB, renders `{{milestoneSummaryPath}}`, and validates all slices are complete.
63
+ 13. **Persist completion through `gsd_complete_milestone`.** Call it with the parameters below. This must be the final persistent write in the unit. The tool updates the milestone status in the DB, renders `{{milestoneSummaryPath}}`, and validates all slices are complete.
63
64
 
64
65
  **Required parameters:**
65
66
  - `milestoneId` (string) — Milestone ID (e.g. M001)
@@ -78,7 +79,7 @@ Subagents report only; they do not write user source. Fold any findings into Dec
78
79
  - `followUps` (string) — Follow-up items for future milestones
79
80
  - `deviations` (string) — Deviations from the original plan
80
81
 
81
- 13. Do not commit manually — the system auto-commits your changes after this unit completes.
82
+ 14. Do not commit manually — the system auto-commits your changes after this unit completes.
82
83
  - Say: "Milestone {{milestoneId}} complete."
83
84
 
84
85
  **Important:** Do NOT skip code-change, success-criteria, or definition-of-done verification (steps 3-5). The summary must reflect verified outcomes. Verification failures block completion; there is no override. If a verification tool fails, errors, or returns unexpected output, treat it as failure.
@@ -16,7 +16,7 @@ Dispatch ALL slices simultaneously using the `subagent` tool in **parallel mode*
16
16
 
17
17
  1. Call `subagent` with `tasks: [...]` containing one entry per slice below
18
18
  2. Wait for ALL subagents to complete
19
- 3. Verify each slice's RESEARCH file was written (check the `.gsd/{{mid}}/` directory)
19
+ 3. Verify each slice's RESEARCH file was written (check `.gsd/milestones/{{mid}}/slices/<slice-id>/`)
20
20
  4. If a subagent failed to write its RESEARCH file, retry it **once** individually
21
21
  5. If it fails a second time, write a partial RESEARCH file for that slice with a `## BLOCKER` section explaining the failure — do NOT retry again
22
22
  6. Report which slices completed research and which (if any) needed a blocker note
@@ -17,11 +17,7 @@ You are executing a GSD quick task — a lightweight, focused unit of work outsi
17
17
  5. Verify your work:
18
18
  - Run tests if applicable.
19
19
  - Verify both happy path and failure modes for non-trivial changes.
20
- 6. Commit your changes atomically:
21
- - Use conventional commit messages (feat:, fix:, refactor:, etc.)
22
- - Stage only relevant files — never commit secrets or runtime files.
23
- - Commit logical units separately if the task involves distinct changes.
24
- - Quick tasks run outside the auto-mode lifecycle — there is no system auto-commit, so commit directly here.
20
+ 6. {{commitInstruction}}
25
21
  7. Write a brief summary to `{{summaryPath}}`:
26
22
  - Quick tasks operate outside the milestone/slice/task DB structure, so `gsd_summary_save` (which requires a `milestone_id`) cannot be used here. Write the file directly.
27
23
 
@@ -27,13 +27,13 @@ Roadmap, slice summaries, assessments, requirements, decisions, and project cont
27
27
  Call `subagent` with `tasks: [...]` containing ALL THREE reviewers simultaneously:
28
28
 
29
29
  **Reviewer A - Requirements Coverage**
30
- Prompt: "Review milestone {{milestoneId}} requirements coverage. Working directory: {{workingDirectory}}. Read `.gsd/{{milestoneId}}/REQUIREMENTS.md` or equivalent. For each requirement, check slice SUMMARY files in `.gsd/{{milestoneId}}/` and mark COVERED, PARTIAL, or MISSING. Output table: Requirement | Status | Evidence. End with one-line verdict: PASS if all covered, NEEDS-ATTENTION if partials exist, FAIL if any missing."
30
+ Prompt: "Review milestone {{milestoneId}} requirements coverage. Working directory: {{workingDirectory}}. Read `.gsd/REQUIREMENTS.md` or use the inlined requirements context. For each requirement, check slice SUMMARY files under `.gsd/milestones/{{milestoneId}}/slices/` and mark COVERED, PARTIAL, or MISSING. Output table: Requirement | Status | Evidence. End with one-line verdict: PASS if all covered, NEEDS-ATTENTION if partials exist, FAIL if any missing."
31
31
 
32
32
  **Reviewer B - Cross-Slice Integration**
33
33
  Prompt: "Review milestone {{milestoneId}} cross-slice integration. Working directory: {{workingDirectory}}. Read `{{roadmapPath}}` and find the boundary map (produces/consumes contracts). For each boundary, confirm producer SUMMARY produced the artifact and consumer SUMMARY consumed it. Output table: Boundary | Producer Summary | Consumer Summary | Status. End with one-line verdict: PASS if all boundaries honored, NEEDS-ATTENTION if any gaps."
34
34
 
35
35
  **Reviewer C - Assessment & Acceptance Criteria**
36
- Prompt: "Review milestone {{milestoneId}} assessment evidence and acceptance criteria. Working directory: {{workingDirectory}}. Read `.gsd/{{milestoneId}}/CONTEXT.md` for criteria. Check slice ASSESSMENT files. Verify each criterion maps to a passing assessment or clear SUMMARY evidence. Then review inlined milestone verification classes. For each non-empty planned class, output table: Class | Planned Check | Evidence | Verdict. Use the exact class names `Contract`, `Integration`, `Operational`, and `UAT` whenever those classes are present. If no verification classes were planned, say that explicitly. Output sections `Acceptance Criteria` with checklist `[ ] Criterion | Evidence`, and `Verification Classes` with the table. End with one-line verdict: PASS if all criteria and classes are covered, NEEDS-ATTENTION if gaps exist."
36
+ Prompt: "Review milestone {{milestoneId}} assessment evidence and acceptance criteria. Working directory: {{workingDirectory}}. Read `.gsd/milestones/{{milestoneId}}/{{milestoneId}}-CONTEXT.md` for criteria. Check slice SUMMARY/UAT files under `.gsd/milestones/{{milestoneId}}/slices/`. Verify each criterion maps to passing evidence. Then review inlined milestone verification classes. For each non-empty planned class, output table: Class | Planned Check | Evidence | Verdict. Use the exact class names `Contract`, `Integration`, `Operational`, and `UAT` whenever those classes are present. If no verification classes were planned, say that explicitly. Output sections `Acceptance Criteria` with checklist `[ ] Criterion | Evidence`, and `Verification Classes` with the table. End with one-line verdict: PASS if all criteria and classes are covered, NEEDS-ATTENTION if gaps exist."
37
37
 
38
38
  ### Step 2 - Synthesize Findings
39
39
 
@@ -8,8 +8,8 @@
8
8
  * Quick tasks live in `.gsd/quick/` and are tracked in STATE.md's
9
9
  * "Quick Tasks Completed" table.
10
10
  */
11
- import { existsSync, mkdirSync, readFileSync, readdirSync, rmSync, writeFileSync } from "node:fs";
12
- import { join } from "node:path";
11
+ import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, rmSync, writeFileSync } from "node:fs";
12
+ import { isAbsolute, join, relative } from "node:path";
13
13
  import { loadPrompt } from "./prompt-loader.js";
14
14
  import { gsdRoot } from "./paths.js";
15
15
  import { GitServiceImpl, runGit } from "./git-service.js";
@@ -64,6 +64,37 @@ function ensureQuickDir(basePath, taskNum, slug) {
64
64
  mkdirSync(taskDir, { recursive: true });
65
65
  return taskDir;
66
66
  }
67
+ function isPathInside(parent, child) {
68
+ const rel = relative(parent, child);
69
+ return rel === "" || (!!rel && !rel.startsWith("..") && !isAbsolute(rel));
70
+ }
71
+ function isExternalGsdRoot(basePath, root) {
72
+ try {
73
+ return !isPathInside(realpathSync(basePath), realpathSync(root));
74
+ }
75
+ catch {
76
+ return !isPathInside(basePath, root);
77
+ }
78
+ }
79
+ export function buildQuickCommitInstruction(basePath, root) {
80
+ const externalState = isExternalGsdRoot(basePath, root);
81
+ if (externalState) {
82
+ return [
83
+ "Commit repo changes atomically, but do not stage or commit `.gsd/quick/...`:",
84
+ " - `.gsd/` resolves outside this git repository, so Git cannot stage quick-task summary files from the project repo.",
85
+ " - Write the quick summary file directly at the requested path; that file is persisted by GSD external state.",
86
+ " - Stage and commit only implementation/test/docs files that live inside the repository.",
87
+ " - If the task only writes quick-task research/summary files and no repository files changed, do not run `git commit`; report that there was nothing in the project repo to commit.",
88
+ ].join("\n");
89
+ }
90
+ return [
91
+ "Commit your changes atomically:",
92
+ " - Use conventional commit messages (feat:, fix:, refactor:, etc.)",
93
+ " - Stage only relevant files — never commit secrets or runtime files.",
94
+ " - Commit logical units separately if the task involves distinct changes.",
95
+ " - Quick tasks run outside the auto-mode lifecycle — there is no system auto-commit, so commit directly here.",
96
+ ].join("\n");
97
+ }
67
98
  function quickReturnStatePath(basePath) {
68
99
  return join(gsdRoot(basePath), "runtime", "quick-return.json");
69
100
  }
@@ -198,6 +229,7 @@ export async function handleQuick(args, ctx, pi) {
198
229
  taskDir: taskDirRel,
199
230
  branch: actualBranch,
200
231
  summaryPath,
232
+ commitInstruction: buildQuickCommitInstruction(basePath, root),
201
233
  date,
202
234
  taskNum: String(taskNum),
203
235
  slug,
@@ -0,0 +1,15 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Shared Context Mode tool result helpers.
3
+ export function contextModeDisabledResult(operation) {
4
+ return {
5
+ content: [
6
+ {
7
+ type: "text",
8
+ text: `${operation} is disabled by \`context_mode.enabled: false\` in preferences. ` +
9
+ "Remove that override or set it to true to re-enable Context Mode tools.",
10
+ },
11
+ ],
12
+ details: { operation, error: "context_mode_disabled" },
13
+ isError: true,
14
+ };
15
+ }
@@ -3,7 +3,12 @@
3
3
  // Scans .gsd/exec/*.meta.json and returns a ranked summary so agents can
4
4
  // re-discover past runs without re-executing. Read-only; no DB writes.
5
5
  import { searchExecHistory } from "../exec-history.js";
6
+ import { isContextModeEnabled } from "../preferences-types.js";
7
+ import { contextModeDisabledResult } from "./context-mode-tool-result.js";
6
8
  export function executeExecSearch(params, opts) {
9
+ if (!isContextModeEnabled(opts.preferences)) {
10
+ return contextModeDisabledResult("gsd_exec_search");
11
+ }
7
12
  const searchOpts = {
8
13
  query: typeof params.query === "string" ? params.query : undefined,
9
14
  runtime: params.runtime,
@@ -5,6 +5,7 @@
5
5
  // for MCP return.
6
6
  import { EXEC_DEFAULTS, runExecSandbox, } from "../exec-sandbox.js";
7
7
  import { isContextModeEnabled } from "../preferences-types.js";
8
+ import { contextModeDisabledResult } from "./context-mode-tool-result.js";
8
9
  export function buildExecOptions(baseDir, cfg, extras) {
9
10
  const allowlist = Array.isArray(cfg?.exec_env_allowlist) ? cfg.exec_env_allowlist : EXEC_DEFAULTS.envAllowlist;
10
11
  const stdoutCap = clampNumber(cfg?.exec_stdout_cap_bytes, EXEC_DEFAULTS.stdoutCapBytes, 4_096, 16_777_216);
@@ -33,19 +34,6 @@ function clampNumber(value, fallback, min, max) {
33
34
  function isEnabled(prefs) {
34
35
  return isContextModeEnabled(prefs);
35
36
  }
36
- function disabledResult() {
37
- return {
38
- content: [
39
- {
40
- type: "text",
41
- text: "gsd_exec is disabled by `context_mode.enabled: false` in preferences. Remove that " +
42
- "override (or set it to true) to re-enable sandboxed tool-output execution.",
43
- },
44
- ],
45
- details: { operation: "gsd_exec", error: "context_mode_disabled" },
46
- isError: true,
47
- };
48
- }
49
37
  function paramError(message) {
50
38
  return {
51
39
  content: [{ type: "text", text: `Error: ${message}` }],
@@ -55,7 +43,7 @@ function paramError(message) {
55
43
  }
56
44
  export async function executeGsdExec(params, deps) {
57
45
  if (!isEnabled(deps.preferences))
58
- return disabledResult();
46
+ return contextModeDisabledResult("gsd_exec");
59
47
  const runtime = params.runtime;
60
48
  if (runtime !== "bash" && runtime !== "node" && runtime !== "python") {
61
49
  return paramError(`invalid runtime "${String(runtime)}" — must be bash | node | python`);
@@ -67,7 +55,7 @@ export async function executeGsdExec(params, deps) {
67
55
  if (Buffer.byteLength(script, "utf8") > 200_000) {
68
56
  return paramError("script exceeds the 200 KB length limit");
69
57
  }
70
- const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { now: deps.now, generateId: deps.generateId });
58
+ const opts = buildExecOptions(deps.baseDir, deps.preferences?.context_mode, { env: deps.env, now: deps.now, generateId: deps.generateId });
71
59
  const run = deps.run ?? runExecSandbox;
72
60
  try {
73
61
  const result = await run({
@@ -256,6 +256,7 @@ function includeSupersededMemories(rankedActive) {
256
256
  scope: row["scope"] ?? "project",
257
257
  tags,
258
258
  structured_fields: structuredFields,
259
+ last_hit_at: row["last_hit_at"] ?? null,
259
260
  };
260
261
  });
261
262
  }
@@ -2,7 +2,12 @@
2
2
  // agents can re-orient after compaction or session resume without
3
3
  // re-deriving project memory state.
4
4
  import { readCompactionSnapshot } from "../compaction-snapshot.js";
5
+ import { isContextModeEnabled } from "../preferences-types.js";
6
+ import { contextModeDisabledResult } from "./context-mode-tool-result.js";
5
7
  export function executeResume(_params, opts) {
8
+ if (!isContextModeEnabled(opts.preferences)) {
9
+ return contextModeDisabledResult("gsd_resume");
10
+ }
6
11
  const snapshot = readCompactionSnapshot(opts.baseDir);
7
12
  if (snapshot == null) {
8
13
  return {
@@ -680,7 +680,7 @@ export async function executeMilestoneStatus(params, basePath = process.cwd()) {
680
680
  };
681
681
  return {
682
682
  content: [{ type: "text", text: JSON.stringify(result, null, 2) }],
683
- details: { operation: "milestone_status", milestoneId: milestone.id, sliceCount: slices.length },
683
+ details: { operation: "milestone_status", ...result },
684
684
  };
685
685
  });
686
686
  }
@@ -80,7 +80,15 @@ const CONTEXT_MODE_LANE_LABELS = {
80
80
  orchestration: "orchestration",
81
81
  docs: "documentation",
82
82
  };
83
- const CONTEXT_MODE_GUIDANCE = "Use `gsd_exec` for noisy commands, `gsd_exec_search` before reruns, and `gsd_resume` after compaction or resume.";
83
+ const CONTEXT_MODE_GUIDANCE_BY_LANE = {
84
+ interview: "Use `gsd_resume` to restore prior discussion, `gsd_exec` for noisy discovery, and `gsd_exec_search` before repeating scans.",
85
+ research: "Use `gsd_exec` for noisy research scans, `gsd_exec_search` before reruns, and `gsd_resume` to restore prior findings.",
86
+ planning: "Use `gsd_resume` for planning continuity, `gsd_exec` for noisy checks, and `gsd_exec_search` before rerunning diagnostics.",
87
+ execution: "Use `gsd_exec` for builds, tests, and diagnostics, `gsd_exec_search` before reruns, and `gsd_resume` after compaction or resume.",
88
+ verification: "Use `gsd_exec` for verification commands, `gsd_exec_search` to reuse prior evidence, and `gsd_resume` after compaction or resume.",
89
+ orchestration: "Use `gsd_resume` before resuming orchestration, `gsd_exec_search` to reuse prior runs, and `gsd_exec` for noisy coordination checks.",
90
+ docs: "Use `gsd_resume` for prior context, `gsd_exec_search` for saved evidence, and `gsd_exec` for noisy doc validation commands.",
91
+ };
84
92
  /**
85
93
  * Render the Context Mode instruction lane for a unit type. Unknown unit
86
94
  * types, disabled config, and explicit `contextMode: "none"` all omit the
@@ -93,14 +101,15 @@ export function composeContextModeInstructions(unitType, opts) {
93
101
  if (!manifest || manifest.contextMode === "none")
94
102
  return "";
95
103
  const lane = CONTEXT_MODE_LANE_LABELS[manifest.contextMode];
104
+ const guidance = CONTEXT_MODE_GUIDANCE_BY_LANE[manifest.contextMode];
96
105
  if (opts.renderMode === "nested") {
97
- return `Context Mode (${lane} lane): ${CONTEXT_MODE_GUIDANCE}`;
106
+ return `Context Mode (${lane} lane): ${guidance}`;
98
107
  }
99
108
  return [
100
109
  "## Context Mode",
101
110
  "",
102
111
  `Lane: **${lane} lane**.`,
103
- CONTEXT_MODE_GUIDANCE,
112
+ guidance,
104
113
  ].join("\n");
105
114
  }
106
115
  const SECTION_SEPARATOR = "\n\n---\n\n";
@@ -4,6 +4,8 @@ import { atomicWriteSync } from "./atomic-write.js";
4
4
  import { gsdRoot, relSliceFile, relTaskFile, resolveSliceFile, resolveTaskFile, } from "./paths.js";
5
5
  import { loadFile, parseTaskPlanMustHaves, countMustHavesMentionedInSummary } from "./files.js";
6
6
  import { parseUnitId } from "./unit-id.js";
7
+ import { getTask, isDbAvailable, refreshOpenDatabaseFromDisk } from "./gsd-db.js";
8
+ import { isClosedStatus } from "./status-guards.js";
7
9
  // Per-record advisory lock — prevents read-modify-write races between
8
10
  // concurrent writers updating disjoint fields of the same runtime record.
9
11
  // Within a single Node process this is moot (writeUnitRuntimeRecord is sync),
@@ -165,6 +167,12 @@ export async function inspectExecuteTaskDurability(basePath, unitId) {
165
167
  const escapedTid = tid.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
166
168
  const taskChecked = !!planContent && new RegExp(`^- \\[[xX]\\] \\*\\*${escapedTid}:`, "m").test(planContent);
167
169
  const nextActionAdvanced = !new RegExp(`Execute ${tid}\\b`).test(stateContent);
170
+ let dbComplete = false;
171
+ if (isDbAvailable()) {
172
+ refreshOpenDatabaseFromDisk();
173
+ const task = getTask(mid, sid, tid);
174
+ dbComplete = !!task && isClosedStatus(task.status);
175
+ }
168
176
  // Must-have coverage: load task plan and count mentions in summary
169
177
  let mustHaveCount = 0;
170
178
  let mustHavesMentionedInSummary = 0;
@@ -188,11 +196,14 @@ export async function inspectExecuteTaskDurability(basePath, unitId) {
188
196
  summaryExists,
189
197
  taskChecked,
190
198
  nextActionAdvanced,
199
+ dbComplete,
191
200
  mustHaveCount,
192
201
  mustHavesMentionedInSummary,
193
202
  };
194
203
  }
195
204
  export function formatExecuteTaskRecoveryStatus(status) {
205
+ if (status.dbComplete)
206
+ return "DB task status is closed";
196
207
  const missing = [];
197
208
  if (!status.summaryExists)
198
209
  missing.push(`summary missing (${status.summaryPath})`);