gsd-pi 2.80.0-dev.cf9433f56 → 2.80.0-dev.d4fc28e6b

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 (237) hide show
  1. package/dist/cli.js +0 -19
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  4. package/dist/resources/extensions/gsd/auto/loop.js +71 -8
  5. package/dist/resources/extensions/gsd/auto/phases.js +150 -94
  6. package/dist/resources/extensions/gsd/auto/resolve.js +12 -0
  7. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -30
  8. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  9. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  10. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  11. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  12. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +17 -4
  14. package/dist/resources/extensions/gsd/auto-prompts.js +90 -15
  15. package/dist/resources/extensions/gsd/auto-start.js +197 -6
  16. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  17. package/dist/resources/extensions/gsd/auto.js +18 -22
  18. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +86 -19
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  20. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  21. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +9 -3
  22. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  23. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  24. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +298 -54
  26. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  27. package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
  28. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  29. package/dist/resources/extensions/gsd/db/unit-dispatches.js +53 -0
  30. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  31. package/dist/resources/extensions/gsd/guided-flow.js +47 -28
  32. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  33. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  34. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  35. package/dist/resources/extensions/gsd/pre-execution-checks.js +15 -0
  36. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  37. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  38. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  39. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  40. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  41. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  42. package/dist/resources/extensions/gsd/worktree-resolver.js +35 -4
  43. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  44. package/dist/web/standalone/.next/BUILD_ID +1 -1
  45. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  46. package/dist/web/standalone/.next/build-manifest.json +2 -2
  47. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  48. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  49. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  50. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  51. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  57. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/index.html +1 -1
  65. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  72. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  73. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  74. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  75. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  76. package/dist/welcome-screen.d.ts +2 -0
  77. package/dist/welcome-screen.js +9 -7
  78. package/package.json +1 -1
  79. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  80. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  81. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  82. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  83. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  84. package/packages/pi-agent-core/dist/agent.js +2 -0
  85. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  86. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  87. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  88. package/packages/pi-agent-core/dist/index.js +2 -0
  89. package/packages/pi-agent-core/dist/index.js.map +1 -1
  90. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  91. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  92. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  93. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  94. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  95. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  96. package/packages/pi-agent-core/dist/types.js.map +1 -1
  97. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  98. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  99. package/packages/pi-agent-core/src/agent.ts +8 -0
  100. package/packages/pi-agent-core/src/index.ts +2 -0
  101. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  102. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  103. package/packages/pi-agent-core/src/types.ts +14 -0
  104. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  105. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  106. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  107. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  108. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  109. package/packages/pi-coding-agent/dist/core/agent-session.js +36 -7
  110. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  111. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  112. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  113. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  114. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +2 -0
  115. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  116. package/packages/pi-coding-agent/dist/core/extensions/runner.js +3 -6
  117. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  118. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +3 -3
  119. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  120. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +32 -1
  121. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  122. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  123. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  124. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  125. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  126. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  127. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  128. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  129. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  130. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  131. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  132. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  134. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  135. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  136. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  138. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  139. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  140. package/packages/pi-coding-agent/src/core/agent-session.ts +40 -7
  141. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  142. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +3 -3
  143. package/packages/pi-coding-agent/src/core/extensions/runner.ts +5 -5
  144. package/packages/pi-coding-agent/src/core/extensions/types.ts +35 -1
  145. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  146. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  147. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  148. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  149. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  150. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  151. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  152. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  153. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
  154. package/src/resources/extensions/gsd/auto/loop.ts +84 -8
  155. package/src/resources/extensions/gsd/auto/phases.ts +218 -154
  156. package/src/resources/extensions/gsd/auto/resolve.ts +19 -0
  157. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -29
  158. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  159. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  160. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  161. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  162. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
  163. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  164. package/src/resources/extensions/gsd/auto-prompts.ts +95 -14
  165. package/src/resources/extensions/gsd/auto-start.ts +230 -9
  166. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  167. package/src/resources/extensions/gsd/auto.ts +18 -18
  168. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +100 -18
  169. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  170. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  171. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +10 -3
  172. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  173. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  174. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  175. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +347 -54
  176. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  177. package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
  178. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  179. package/src/resources/extensions/gsd/db/unit-dispatches.ts +66 -0
  180. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  181. package/src/resources/extensions/gsd/guided-flow.ts +52 -35
  182. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  183. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  184. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  185. package/src/resources/extensions/gsd/pre-execution-checks.ts +16 -0
  186. package/src/resources/extensions/gsd/prompts/complete-milestone.md +2 -0
  187. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  188. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  189. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  190. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  191. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  192. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +361 -10
  193. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  194. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
  195. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  196. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  197. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  198. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  199. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  200. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  201. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  202. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  203. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +5 -1
  204. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  205. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  206. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  207. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  208. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  209. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  210. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  211. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  212. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  213. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +7 -5
  214. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  215. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  216. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  217. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  218. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  219. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  220. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  221. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  222. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  223. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  224. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +50 -1
  225. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  226. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  227. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  228. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  229. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  230. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  231. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  232. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +104 -3
  233. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  234. package/src/resources/extensions/gsd/worktree-resolver.ts +49 -4
  235. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  236. /package/dist/web/standalone/.next/static/{-5nHJWzSdG-WkPMul_khA → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
  237. /package/dist/web/standalone/.next/static/{-5nHJWzSdG-WkPMul_khA → cWaxzf-sdbSSbbwYu8q7a}/_ssgManifest.js +0 -0
@@ -12,7 +12,7 @@ import { join, dirname } from "node:path";
12
12
  import { fileURLToPath } from "node:url";
13
13
  import { gsdRoot } from "./paths.js";
14
14
  import { createWorktree, worktreePath } from "./worktree-manager.js";
15
- import { autoWorktreeBranch, runWorktreePostCreateHook, syncGsdStateToWorktree } from "./auto-worktree.js";
15
+ import { autoWorktreeBranch, fastForwardReusedMilestoneBranchIfSafe, runWorktreePostCreateHook, syncGsdStateToWorktree } from "./auto-worktree.js";
16
16
  import { nativeBranchExists } from "./native-git-bridge.js";
17
17
  import { readIntegrationBranch } from "./git-service.js";
18
18
  import { resolveParallelConfig } from "./preferences.js";
@@ -368,7 +368,7 @@ export async function startParallel(basePath, milestoneIds, prefs) {
368
368
  // Create the worktree (without chdir — coordinator stays in project root)
369
369
  let wtPath;
370
370
  try {
371
- wtPath = createMilestoneWorktree(basePath, mid);
371
+ wtPath = _createMilestoneWorktree(basePath, mid);
372
372
  }
373
373
  catch (e) {
374
374
  logWarning("parallel", `createMilestoneWorktree fallback for ${mid}: ${e.message}`);
@@ -421,12 +421,22 @@ export async function startParallel(basePath, milestoneIds, prefs) {
421
421
  /**
422
422
  * Create a git worktree for a milestone without changing the coordinator's cwd.
423
423
  * Uses milestone/<MID> branch naming (same as auto-worktree.ts).
424
+ *
425
+ * Exported with the `_` prefix purely for tests — production callers stay on
426
+ * the closure-private name `createMilestoneWorktree` below.
424
427
  */
425
- function createMilestoneWorktree(basePath, milestoneId) {
428
+ export function _createMilestoneWorktree(basePath, milestoneId) {
426
429
  const branch = autoWorktreeBranch(milestoneId);
427
430
  const branchExists = nativeBranchExists(basePath, branch);
428
431
  let info;
429
432
  if (branchExists) {
433
+ // #5549 post-merge audit (R3): match the fast-forward behavior added to
434
+ // `createAutoWorktree` in commit 8996cb68e. When a worker reuses an
435
+ // existing milestone branch, fast-forward it onto the integration branch
436
+ // when safe so per-worker worktrees don't fork from a stale base after a
437
+ // sibling milestone has merged. Same `nativeIsAncestor` + worktree-list
438
+ // safety guards apply.
439
+ fastForwardReusedMilestoneBranchIfSafe(basePath, milestoneId, branch);
430
440
  info = createWorktree(basePath, milestoneId, { branch, reuseExistingBranch: true });
431
441
  }
432
442
  else {
@@ -391,6 +391,15 @@ function getExpectedOutputsUpTo(tasks, taskIndex) {
391
391
  */
392
392
  export function checkFilePathConsistency(tasks, basePath) {
393
393
  const results = [];
394
+ // Build a set of all files created by any task at any position (normalized).
395
+ // Used to suppress consistency errors for files that will be caught with a
396
+ // more precise message by checkTaskOrdering (sequence violation).
397
+ const allTaskOutputs = new Set();
398
+ for (const t of tasks) {
399
+ for (const f of t.expected_output) {
400
+ allTaskOutputs.add(normalizeFilePath(f));
401
+ }
402
+ }
394
403
  for (let i = 0; i < tasks.length; i++) {
395
404
  const task = tasks[i];
396
405
  const priorOutputs = getExpectedOutputsUpTo(tasks, i);
@@ -421,6 +430,12 @@ export function checkFilePathConsistency(tasks, basePath) {
421
430
  anyOutputUnderDirectory(normalizedFile, ownOutputs);
422
431
  }
423
432
  if (!existsOnDisk && !inPriorOutputs && !inOwnOutputs && !directorySatisfied) {
433
+ // If a later task claims to create this file, the ordering check will
434
+ // fire a more precise "sequence violation" error for the same file.
435
+ // Suppress the consistency error here to avoid duplicate noise.
436
+ if (allTaskOutputs.has(normalizedFile) && !ownOutputs.has(normalizedFile)) {
437
+ continue;
438
+ }
424
439
  results.push({
425
440
  category: "file",
426
441
  target: file,
@@ -6,6 +6,8 @@ You are executing GSD auto-mode.
6
6
 
7
7
  Your working directory is `{{workingDirectory}}`. All file reads, writes, and shell commands MUST operate relative to this directory. Do NOT `cd` to any other directory.
8
8
 
9
+ If any inlined plan, summary, verification command, or prior artifact names an absolute path outside `{{workingDirectory}}`, treat that path as stale context. Convert it to the equivalent relative path under `{{workingDirectory}}` before reading, writing, or executing. If no equivalent path exists under `{{workingDirectory}}`, record a verification failure and stop; do not edit or run commands in another checkout.
10
+
9
11
  ## Mission
10
12
 
11
13
  All slices are complete. Verify the integrated work, persist milestone completion, refresh project state, and write the final record future milestones will rely on.
@@ -29,7 +29,7 @@ Use `subagent` only for fresh-context review when useful: reviewer for cross-cut
29
29
  7. If requirement status changed, call `gsd_requirement_update`; do not write `.gsd/REQUIREMENTS.md` directly.
30
30
  8. Prepare `gsd_slice_complete` content with camelCase fields `milestoneId`, `sliceId`, `sliceTitle`, `oneLiner`, `narrative`, `verification`, and `uatContent`.
31
31
  9. Draft concrete UAT with preconditions, numbered steps, expected outcomes, edge cases, UAT Type, and Not Proven By This UAT.
32
- 10. Review task summaries for DECISIONS.md and KNOWLEDGE.md-worthy decisions, patterns, and gotchas. Capture significant items with `capture_thought`; do not append knowledge files directly.
32
+ 10. Review the inlined task-summary excerpts for DECISIONS.md and KNOWLEDGE.md-worthy decisions, patterns, and gotchas. Read full `*-SUMMARY.md` files only when an excerpt is absent, truncated, or lacks the specific evidence needed for the slice narrative. Capture significant items with `capture_thought`; do not append knowledge files directly.
33
33
  11. Call `gsd_slice_complete`. The DB-backed tool is the canonical write path. Do **not** manually write `{{sliceSummaryPath}}`. Do **not** manually write `{{sliceUatPath}}`. Do not edit roadmap checkboxes; the tool renders files and updates projections.
34
34
  12. Do not run git commands.
35
35
  13. Update `.gsd/PROJECT.md` with a full `write` only if the current project state needs refresh.
@@ -33,7 +33,7 @@ You execute. The inlined task plan is authoritative. Verify referenced files and
33
33
  ## Execution Rules
34
34
 
35
35
  1. Tersely narrate transitions, decisions, and verification outcomes between tool-call clusters.
36
- 2. Call `memory_query` with 2-4 keywords from the task title and touched files unless this is purely mechanical.
36
+ 2. Use the injected memory/context blocks first. Call `memory_query` with 2-4 keywords from the task title and touched files only when no injected memory block exists or the inlined memory/context is insufficient for this task.
37
37
  3. {{skillActivation}} Follow activated skills before code edits.
38
38
  4. Execute the task plan. Before any `Write` that creates an artifact or output file, check whether that path already exists. If it does, read it first and decide whether the work is already done, should be extended, or truly needs replacement.
39
39
  5. Build real behavior through the intended surface; stubs/mocks belong in tests only.
@@ -59,11 +59,13 @@ Keep about **{{verificationBudget}}** for verification and summary. If context i
59
59
  - If the plan is fundamentally invalid, set `blocker_discovered: true` in the summary and explain.
60
60
  - For downstream-impacting ambiguity that cannot be resolved from code, plans, or decisions, include an `escalation` object with question, options, recommendation, rationale, and `continueWithDefault`.
61
61
  - Capture meaningful architecture/pattern/observability decisions with `capture_thought`; capture non-obvious gotchas or conventions only when they save future investigation.
62
- - Read the template at `{{taskSummaryTemplatePath}}`.
62
+ - Use the inlined Task Summary template below. Read `{{taskSummaryTemplatePath}}` only if the inlined template is absent or visibly truncated.
63
63
  - Call `gsd_task_complete` with camelCase fields `milestoneId`, `sliceId`, `taskId`, `oneLiner`, `narrative`, `verification`, and `verificationEvidence`.
64
64
  - The DB-backed tool is the canonical write path. Do **not** manually write `{{taskSummaryPath}}` or edit PLAN.md checkboxes; the tool renders the summary and updates state.
65
65
  - Do not run git commands; the system commits from your summary.
66
66
 
67
+ {{inlinedTemplates}}
68
+
67
69
  **Autonomous execution:** no human is available. Do not call `ask_user_questions` or `secure_env_collect`; make reasonable assumptions and document them.
68
70
 
69
71
  **You MUST call `gsd_task_complete` before finishing.**
@@ -39,7 +39,7 @@ If slice research is inlined, trust it. Explore enough code to confirm paths, bo
39
39
  5. Define slice verification before tasks. Non-trivial slices need real tests or executable assertions; boundary contracts need contract-exercising checks. Tests must not read .gitignore/gitignored paths such as `.gsd/`, `.planning/`, or `.audits/`.
40
40
  6. Include Threat Surface (Q3), Requirement Impact (Q4), proof level, observability, integration closure, Failure Modes (Q5), Load Profile (Q6), and Negative Tests (Q7) only where applicable.
41
41
  7. Right-size tasks. Simple slices can be one task; split only when context, ownership, or verification boundaries justify it.
42
- 8. Each task needs a concrete title, Why / Files / Do / Verify / Done when, plus task-plan description, steps, must-haves, verification, inputs, and expected output. Inputs and Expected Output must include concrete backtick-wrapped paths; each task needs at least one output path. Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands.
42
+ 8. Each task needs a concrete title, Why / Files / Do / Verify / Done when, plus task-plan description, steps, must-haves, verification, inputs, and expected output. Inputs and Expected Output must include concrete backtick-wrapped paths. Use paths relative to `{{workingDirectory}}`; do not put absolute paths to the original checkout or any directory outside `{{workingDirectory}}` in `files`, `inputs`, `expectedOutput`, or verification commands. **`expected_output` must only list files the task actually creates or overwrites on disk.** Do NOT include files the task merely reads, verifies, or tests — those belong only in `inputs`. If a task is a pure verification or test task that produces no new files, its `expected_output` may be empty or limited to test-result artifacts (e.g. a log or assertion output). A file that does not yet exist on disk and is needed as an `input` must be produced by an earlier task's `expected_output` — if no prior task creates it, add a task before this one that does.
43
43
  9. Persist with `gsd_plan_slice` using goal, successCriteria, optional proofLevel/integrationClosure/observabilityImpact, and tasks. `gsd_plan_slice` handles task persistence transactionally and renders `{{outputPath}}` plus task plans; do not call `gsd_plan_task`. The DB-backed tool is the canonical write path. Do **not** rely on direct `PLAN.md` writes as the source of truth.
44
44
  10. Self-audit before finishing: goal/demo closure, requirement coverage, locked decisions, concrete paths, dependency order, wiring, scope size, proof truthfulness, feature completeness, and quality gates. Quality gates: non-trivial slices/tasks include specific Q3-Q7 coverage where applicable.
45
45
  11. If planning creates structural decisions, append them to `.gsd/DECISIONS.md`.
@@ -8,7 +8,7 @@ Your working directory is `{{workingDirectory}}`. All file reads, writes, and sh
8
8
 
9
9
  A completed task reported `blocker_discovered: true`, meaning the current slice plan cannot be executed as-is. Your job is to rewrite the remaining tasks in the slice plan to address the blocker while preserving all completed work.
10
10
 
11
- All relevant context has been preloaded below — the roadmap, current slice plan, the blocker task summary, and decisions are inlined. Start working immediately without re-reading these files.
11
+ All relevant context has been preloaded below — the roadmap, current slice plan, blocker task summary excerpt, and decisions are inlined. Start working immediately without re-reading these files.
12
12
 
13
13
  {{inlinedContext}}
14
14
 
@@ -30,7 +30,7 @@ Consider these captures when rewriting the remaining tasks — they represent th
30
30
 
31
31
  ## Instructions
32
32
 
33
- 1. Read the blocker task summary carefully. Understand exactly what was discovered and why it blocks the current plan.
33
+ 1. Use the inlined blocker summary excerpt first. Read the full blocker task summary only if the excerpt is absent, marked truncated, or lacks the specific blocker evidence needed to replan.
34
34
  2. Analyze the remaining `[ ]` tasks in the slice plan. Determine which are still valid, which need modification, and which should be replaced.
35
35
  3. **Persist replan state through `gsd_replan_slice`.** Call it with: `milestoneId`, `sliceId`, `blockerTaskId`, `blockerDescription`, `whatChanged`, `updatedTasks` (array of task objects with taskId, title, description, estimate, files, verify, inputs, expectedOutput), `removedTaskIds` (array of task ID strings). The tool structurally enforces preservation of completed tasks, writes replan history to the DB, re-renders `{{planPath}}`, and renders `{{replanPath}}`. Preserve or update the Threat Surface and Requirement Impact sections if the replan changes the slice's security posture or requirement coverage.
36
36
  4. If any incomplete task had a `T0x-PLAN.md`, remove or rewrite it to match the new task description.
@@ -0,0 +1,131 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Shared capped workflow protocol and doctor-heal prompt payload helpers.
3
+ const DEFAULT_WORKFLOW_PROTOCOL_EXCERPT_CHARS = 4_000;
4
+ const MIN_WORKFLOW_PROTOCOL_EXCERPT_CHARS = 1_000;
5
+ const DEFAULT_DOCTOR_SUMMARY_CHARS = 2_400;
6
+ const DEFAULT_DOCTOR_ISSUE_CHARS = 300;
7
+ const DEFAULT_DOCTOR_MAX_ISSUES = 12;
8
+ const DEFAULT_DOCTOR_ISSUES_CHARS = 4_000;
9
+ export function buildWorkflowProtocolExcerpt(workflow, workflowPath, opts = {}) {
10
+ const limit = opts.maxChars ?? getWorkflowProtocolExcerptLimit();
11
+ const trimmed = workflow.trim();
12
+ const excerpt = buildPrioritizedWorkflowExcerpt(trimmed, limit);
13
+ const truncated = trimmed.length > limit;
14
+ const lines = [
15
+ "## GSD Workflow Protocol Excerpt",
16
+ `Source: \`${workflowPath}\``,
17
+ "",
18
+ excerpt,
19
+ ];
20
+ if (truncated) {
21
+ lines.push("", "[Workflow Protocol Truncated]", "The full workflow protocol remains available at the source path above. Read it only if this excerpt lacks a rule required for the dispatched task.");
22
+ }
23
+ return lines.join("\n");
24
+ }
25
+ export function buildWorkflowDispatchContent(opts) {
26
+ return [
27
+ "Read the following GSD workflow protocol excerpt and execute exactly. Use the source path for a full protocol read only if the excerpt lacks a required rule.",
28
+ "",
29
+ buildWorkflowProtocolExcerpt(opts.workflow, opts.workflowPath, { maxChars: opts.maxProtocolChars }),
30
+ "",
31
+ "## Your Task",
32
+ "",
33
+ opts.task.trim(),
34
+ ].join("\n");
35
+ }
36
+ export function buildDoctorHealSummary(reportText, opts = {}) {
37
+ const limit = opts.maxChars ?? DEFAULT_DOCTOR_SUMMARY_CHARS;
38
+ const lines = reportText.split(/\r?\n/).map((line) => line.trimEnd());
39
+ const summaryLines = lines.filter((line) => line.length > 0 && (/^#/.test(line) ||
40
+ /^(scope|status|summary|checks?|errors?|warnings?|fixes?|issues?)\b/i.test(line) ||
41
+ /doctor/i.test(line)));
42
+ const selected = summaryLines.length > 0 ? summaryLines : lines.filter((line) => line.trim()).slice(0, 24);
43
+ return capText(selected.join("\n"), limit, "Full doctor report is available in the command output; use the structured issue list below for repairs.");
44
+ }
45
+ export function buildDoctorHealIssuePayload(structuredIssues, opts = {}) {
46
+ const maxIssues = opts.maxIssues ?? DEFAULT_DOCTOR_MAX_ISSUES;
47
+ const maxIssueChars = opts.maxIssueChars ?? DEFAULT_DOCTOR_ISSUE_CHARS;
48
+ const maxChars = opts.maxChars ?? DEFAULT_DOCTOR_ISSUES_CHARS;
49
+ const blocks = splitIssueBlocks(structuredIssues);
50
+ const topBlocks = blocks.slice(0, maxIssues).map((block) => capText(block, maxIssueChars, "Issue details truncated; inspect the relevant artifact before editing."));
51
+ if (blocks.length > maxIssues) {
52
+ topBlocks.push(`[${blocks.length - maxIssues} additional actionable issue(s) omitted from prompt. Re-run /gsd doctor heal after this repair pass.]`);
53
+ }
54
+ return capText(topBlocks.join("\n\n"), maxChars, "Structured issue list truncated; repair top actionable issues first and re-run doctor heal.");
55
+ }
56
+ function getWorkflowProtocolExcerptLimit() {
57
+ const raw = process.env.PI_GSD_WORKFLOW_PROTOCOL_MAX_CHARS;
58
+ if (!raw)
59
+ return DEFAULT_WORKFLOW_PROTOCOL_EXCERPT_CHARS;
60
+ const parsed = Number(raw);
61
+ if (!Number.isFinite(parsed) || parsed < MIN_WORKFLOW_PROTOCOL_EXCERPT_CHARS) {
62
+ return DEFAULT_WORKFLOW_PROTOCOL_EXCERPT_CHARS;
63
+ }
64
+ return Math.floor(parsed);
65
+ }
66
+ function buildPrioritizedWorkflowExcerpt(workflow, limit) {
67
+ if (workflow.length <= limit)
68
+ return workflow;
69
+ const sections = splitMarkdownSections(workflow);
70
+ const wanted = [
71
+ /^# /,
72
+ /^## Quick Start\b/i,
73
+ /^## The Hierarchy\b/i,
74
+ /^## The Phases\b/i,
75
+ /^### Phase 4: Execute\b/i,
76
+ /^### Phase 5: Verify\b/i,
77
+ /^### Observable Truths\b/i,
78
+ /^### Artifacts\b/i,
79
+ /^### Key Links\b/i,
80
+ /^### Phase 6: Summarize\b/i,
81
+ /^### Phase 7: Advance\b/i,
82
+ ];
83
+ const selected = [];
84
+ const used = new Set();
85
+ for (const pattern of wanted) {
86
+ const index = sections.findIndex((section, sectionIndex) => !used.has(sectionIndex) && pattern.test(section.heading));
87
+ if (index >= 0) {
88
+ used.add(index);
89
+ selected.push(sections[index].text);
90
+ }
91
+ }
92
+ const body = selected.length > 0 ? selected.join("\n\n") : workflow;
93
+ return capText(body, limit, "Workflow protocol excerpt capped; read the source path for omitted details.");
94
+ }
95
+ function splitMarkdownSections(markdown) {
96
+ const lines = markdown.split(/\r?\n/);
97
+ const sections = [];
98
+ let currentHeading = lines[0]?.startsWith("#") ? lines[0] : "# Preamble";
99
+ let current = [];
100
+ for (const line of lines) {
101
+ if (/^#{1,3}\s+/.test(line) && current.length > 0) {
102
+ sections.push({ heading: currentHeading, text: current.join("\n").trim() });
103
+ currentHeading = line;
104
+ current = [line];
105
+ continue;
106
+ }
107
+ if (/^#{1,3}\s+/.test(line))
108
+ currentHeading = line;
109
+ current.push(line);
110
+ }
111
+ if (current.length > 0) {
112
+ sections.push({ heading: currentHeading, text: current.join("\n").trim() });
113
+ }
114
+ return sections.filter((section) => section.text.length > 0);
115
+ }
116
+ function splitIssueBlocks(structuredIssues) {
117
+ const trimmed = structuredIssues.trim();
118
+ if (!trimmed)
119
+ return ["No structured issue details were provided."];
120
+ const split = trimmed.split(/\n(?=(?:#{2,6}\s+|\d+\.\s+|- \*\*|- \[[ x]\]))/i)
121
+ .map((block) => block.trim())
122
+ .filter(Boolean);
123
+ return split.length > 0 ? split : [trimmed];
124
+ }
125
+ function capText(text, limit, notice) {
126
+ if (text.length <= limit)
127
+ return text;
128
+ const suffix = `\n\n[Truncated]\n${notice}`;
129
+ const headBudget = Math.max(0, limit - suffix.length);
130
+ return `${text.slice(0, headBudget).trimEnd()}${suffix}`;
131
+ }
@@ -35,6 +35,14 @@ import { claimMilestoneLease, refreshMilestoneLease, releaseMilestoneLease } fro
35
35
  function isSamePath(a, b) {
36
36
  return normalizeWorktreePathForCompare(a) === normalizeWorktreePathForCompare(b);
37
37
  }
38
+ class UserNotifiedError extends Error {
39
+ cause;
40
+ constructor(message, cause) {
41
+ super(message);
42
+ this.name = "UserNotifiedError";
43
+ this.cause = cause;
44
+ }
45
+ }
38
46
  // ─── Path Helpers ──────────────────────────────────────────────────────────
39
47
  /**
40
48
  * Resolve the project root from session path state.
@@ -663,16 +671,35 @@ export class WorktreeResolver {
663
671
  const currentBranch = this.deps.getCurrentBranch(this.s.basePath);
664
672
  const milestoneBranch = this.deps.autoWorktreeBranch(milestoneId);
665
673
  if (currentBranch !== milestoneBranch) {
674
+ // #5538-followup: previous behavior was to silently `return false`
675
+ // when HEAD wasn't on the milestone branch — that let the loop
676
+ // advance with the milestone's commits stranded on the branch (the
677
+ // exact failure mode reported in the test12345 repro). Attempt
678
+ // recovery by force-checking-out the milestone branch; if the
679
+ // checkout fails, throw so the caller pauses auto-mode and the user
680
+ // sees the failure instead of a silent merge skip.
666
681
  debugLog("WorktreeResolver", {
667
682
  action: "mergeAndExit",
668
683
  milestoneId,
669
684
  mode: "branch",
670
- skipped: true,
671
- reason: "not-on-milestone-branch",
685
+ recovery: "checkout-milestone-branch",
672
686
  currentBranch,
673
687
  milestoneBranch,
674
688
  });
675
- return false;
689
+ try {
690
+ this.deps.checkoutBranch(this.s.basePath, milestoneBranch);
691
+ }
692
+ catch (checkoutErr) {
693
+ const checkoutMsg = checkoutErr instanceof Error ? checkoutErr.message : String(checkoutErr);
694
+ ctx.notify(`Cannot merge milestone ${milestoneId}: working tree is on ${currentBranch} and checkout to ${milestoneBranch} failed (${checkoutMsg}). Resolve manually and run /gsd auto to resume.`, "error");
695
+ throw new UserNotifiedError(checkoutMsg, checkoutErr);
696
+ }
697
+ const reverify = this.deps.getCurrentBranch(this.s.basePath);
698
+ if (reverify !== milestoneBranch) {
699
+ const reverifyMsg = `branch checkout to ${milestoneBranch} reported success but current branch is ${reverify}`;
700
+ ctx.notify(`Cannot merge milestone ${milestoneId}: ${reverifyMsg}. Resolve manually and run /gsd auto to resume.`, "error");
701
+ throw new UserNotifiedError(reverifyMsg);
702
+ }
676
703
  }
677
704
  const roadmapPath = this.deps.resolveMilestoneFile(this.s.basePath, milestoneId, "ROADMAP");
678
705
  if (!roadmapPath) {
@@ -713,7 +740,9 @@ export class WorktreeResolver {
713
740
  result: "error",
714
741
  error: msg,
715
742
  });
716
- ctx.notify(`Milestone merge failed (branch mode): ${msg}`, "warning");
743
+ if (!(err instanceof UserNotifiedError)) {
744
+ ctx.notify(`Milestone merge failed (branch mode): ${msg}`, "warning");
745
+ }
717
746
  // Re-throw all errors so callers can apply their own recovery logic (#4380).
718
747
  throw err;
719
748
  }
@@ -736,6 +765,8 @@ export class WorktreeResolver {
736
765
  this.mergeAndExit(currentMilestoneId, ctx);
737
766
  }
738
767
  catch (err) {
768
+ if (err instanceof UserNotifiedError)
769
+ throw err;
739
770
  // mergeAndExit emits a warning and restores state when it fails during
740
771
  // merge/cleanup. But if it throws before recovery runs (e.g., in
741
772
  // validateMilestoneId or emitJournalEvent), basePath won't be restored