@mjasnikovs/pi-task 0.38.28 → 0.38.30

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 (370) hide show
  1. package/dist/config/config.d.ts +70 -70
  2. package/dist/config/config.js +26 -35
  3. package/dist/config/extension-list.d.ts +6 -5
  4. package/dist/config/extension-list.js +3 -2
  5. package/dist/config/reasoning-args.d.ts +9 -7
  6. package/dist/config/reasoning-args.js +12 -10
  7. package/dist/config/reasoning.d.ts +44 -105
  8. package/dist/config/reasoning.js +27 -704
  9. package/dist/config/register.d.ts +34 -48
  10. package/dist/config/register.js +41 -51
  11. package/dist/config/tool-list.d.ts +16 -16
  12. package/dist/config/tool-list.js +1 -1
  13. package/dist/remote/bridge.d.ts +19 -10
  14. package/dist/remote/bridge.js +3 -2
  15. package/dist/remote/broadcast.js +3 -1
  16. package/dist/remote/events.js +12 -11
  17. package/dist/remote/history.d.ts +1 -1
  18. package/dist/remote/protocol.d.ts +6 -3
  19. package/dist/remote/protocol.js +2 -1
  20. package/dist/remote/push.d.ts +16 -16
  21. package/dist/remote/push.js +27 -27
  22. package/dist/remote/register.d.ts +3 -3
  23. package/dist/remote/register.js +17 -19
  24. package/dist/remote/server.d.ts +9 -8
  25. package/dist/remote/server.js +15 -14
  26. package/dist/remote/session-state.d.ts +5 -4
  27. package/dist/remote/session-state.js +8 -5
  28. package/dist/remote/sw.d.ts +7 -6
  29. package/dist/remote/sw.js +7 -6
  30. package/dist/remote/tailscale.d.ts +4 -2
  31. package/dist/remote/tailscale.js +4 -2
  32. package/dist/remote/ui-highlight.js +6 -5
  33. package/dist/remote/ui-render.js +4 -4
  34. package/dist/remote/ui-script.js +24 -24
  35. package/dist/remote/ui-styles.d.ts +1 -1
  36. package/dist/remote/ui-styles.js +10 -13
  37. package/dist/remote/ui-tools.js +9 -6
  38. package/dist/shared/child-extensions.d.ts +29 -17
  39. package/dist/shared/child-extensions.js +29 -17
  40. package/dist/shared/child-output.d.ts +30 -24
  41. package/dist/shared/child-output.js +25 -17
  42. package/dist/shared/child-process.d.ts +47 -40
  43. package/dist/shared/child-process.js +50 -59
  44. package/dist/shared/command-watchdog.d.ts +22 -16
  45. package/dist/shared/command-watchdog.js +28 -21
  46. package/dist/shared/fs-text.d.ts +16 -10
  47. package/dist/shared/fs-text.js +16 -10
  48. package/dist/shared/git-runner.d.ts +25 -25
  49. package/dist/shared/git-runner.js +25 -25
  50. package/dist/shared/leaked-tool-call.d.ts +17 -11
  51. package/dist/shared/leaked-tool-call.js +23 -15
  52. package/dist/shared/model-endpoint.d.ts +29 -16
  53. package/dist/shared/model-endpoint.js +33 -21
  54. package/dist/shared/pi-invocation.d.ts +7 -4
  55. package/dist/shared/pi-invocation.js +12 -7
  56. package/dist/shared/pkg-version.d.ts +13 -5
  57. package/dist/shared/pkg-version.js +13 -5
  58. package/dist/shared/reasoning-capability.d.ts +35 -24
  59. package/dist/shared/reasoning-capability.js +35 -24
  60. package/dist/shared/stream-watchdog.d.ts +60 -44
  61. package/dist/shared/stream-watchdog.js +62 -45
  62. package/dist/task/accept-debt.d.ts +41 -43
  63. package/dist/task/accept-debt.js +73 -65
  64. package/dist/task/api-synthesis.d.ts +24 -21
  65. package/dist/task/api-synthesis.js +32 -26
  66. package/dist/task/apis-contract.d.ts +32 -64
  67. package/dist/task/apis-contract.js +32 -64
  68. package/dist/task/artifact-closure.d.ts +27 -13
  69. package/dist/task/artifact-closure.js +95 -67
  70. package/dist/task/auto-commit.d.ts +46 -35
  71. package/dist/task/auto-commit.js +51 -38
  72. package/dist/task/auto-io.d.ts +45 -25
  73. package/dist/task/auto-io.js +57 -29
  74. package/dist/task/auto-orchestrator.d.ts +26 -24
  75. package/dist/task/auto-orchestrator.js +178 -162
  76. package/dist/task/auto-prompts.d.ts +36 -24
  77. package/dist/task/auto-prompts.js +40 -26
  78. package/dist/task/autofix-ledger.d.ts +27 -25
  79. package/dist/task/autofix-ledger.js +29 -26
  80. package/dist/task/batch-test-task.d.ts +20 -12
  81. package/dist/task/batch-test-task.js +67 -60
  82. package/dist/task/boot-probe.d.ts +60 -44
  83. package/dist/task/boot-probe.js +91 -72
  84. package/dist/task/cancel-input.d.ts +30 -16
  85. package/dist/task/cancel-input.js +20 -11
  86. package/dist/task/cancel-points.d.ts +27 -20
  87. package/dist/task/cancel-points.js +30 -22
  88. package/dist/task/child-runner.d.ts +46 -51
  89. package/dist/task/child-runner.js +48 -49
  90. package/dist/task/child-status.d.ts +23 -16
  91. package/dist/task/child-status.js +23 -16
  92. package/dist/task/clamp-output.js +12 -5
  93. package/dist/task/command-run.d.ts +31 -28
  94. package/dist/task/command-run.js +44 -35
  95. package/dist/task/command-shrink.d.ts +25 -18
  96. package/dist/task/command-shrink.js +37 -31
  97. package/dist/task/command-watchdog.d.ts +9 -6
  98. package/dist/task/command-watchdog.js +21 -15
  99. package/dist/task/context-attribution.d.ts +34 -26
  100. package/dist/task/context-attribution.js +34 -26
  101. package/dist/task/context-silence.d.ts +39 -29
  102. package/dist/task/context-silence.js +35 -25
  103. package/dist/task/context-usage.d.ts +25 -7
  104. package/dist/task/context-usage.js +21 -6
  105. package/dist/task/contracts.d.ts +8 -4
  106. package/dist/task/contracts.js +25 -17
  107. package/dist/task/coverage-loop.d.ts +22 -18
  108. package/dist/task/coverage-loop.js +35 -30
  109. package/dist/task/critique-probes.d.ts +13 -14
  110. package/dist/task/critique-probes.js +50 -39
  111. package/dist/task/debug-log.d.ts +13 -5
  112. package/dist/task/debug-log.js +32 -20
  113. package/dist/task/decompose-fidelity.d.ts +11 -9
  114. package/dist/task/decompose-fidelity.js +38 -33
  115. package/dist/task/decompose-granularity.d.ts +41 -38
  116. package/dist/task/decompose-granularity.js +41 -38
  117. package/dist/task/deep-render-check.d.ts +22 -14
  118. package/dist/task/deep-render-check.js +40 -31
  119. package/dist/task/dropped-input.d.ts +12 -7
  120. package/dist/task/dropped-input.js +5 -2
  121. package/dist/task/enforce-attribution.d.ts +38 -47
  122. package/dist/task/enforce-attribution.js +46 -52
  123. package/dist/task/enforce-guidelines.d.ts +31 -20
  124. package/dist/task/enforce-guidelines.js +32 -21
  125. package/dist/task/enrichment.d.ts +7 -2
  126. package/dist/task/enrichment.js +26 -14
  127. package/dist/task/env-notes.d.ts +16 -7
  128. package/dist/task/env-notes.js +48 -31
  129. package/dist/task/env-template-closure.d.ts +4 -4
  130. package/dist/task/env-template-closure.js +42 -34
  131. package/dist/task/external-context.d.ts +28 -21
  132. package/dist/task/external-context.js +17 -12
  133. package/dist/task/failure-classifier.d.ts +4 -5
  134. package/dist/task/failure-classifier.js +6 -7
  135. package/dist/task/file-inventory.d.ts +15 -11
  136. package/dist/task/file-inventory.js +25 -22
  137. package/dist/task/final-gate-fix.d.ts +74 -86
  138. package/dist/task/final-gate-fix.js +97 -116
  139. package/dist/task/final-gate-progress.d.ts +29 -46
  140. package/dist/task/final-gate-progress.js +40 -51
  141. package/dist/task/final-gate.d.ts +64 -97
  142. package/dist/task/final-gate.js +192 -199
  143. package/dist/task/fix-child.d.ts +21 -27
  144. package/dist/task/fix-child.js +21 -27
  145. package/dist/task/foreign-path.d.ts +6 -5
  146. package/dist/task/foreign-path.js +0 -0
  147. package/dist/task/frozen-conflict.d.ts +9 -10
  148. package/dist/task/frozen-conflict.js +61 -64
  149. package/dist/task/frozen-path-guard.d.ts +35 -14
  150. package/dist/task/frozen-path-guard.js +56 -39
  151. package/dist/task/gate-child.d.ts +27 -28
  152. package/dist/task/gate-child.js +37 -35
  153. package/dist/task/gate-deps.d.ts +34 -27
  154. package/dist/task/gate-deps.js +169 -159
  155. package/dist/task/gate-tally.d.ts +77 -80
  156. package/dist/task/gate-tally.js +65 -68
  157. package/dist/task/git-state-guard.d.ts +15 -11
  158. package/dist/task/git-state-guard.js +76 -66
  159. package/dist/task/impl-widget.d.ts +25 -16
  160. package/dist/task/impl-widget.js +27 -17
  161. package/dist/task/implementation-thinking.d.ts +33 -31
  162. package/dist/task/implementation-thinking.js +5 -6
  163. package/dist/task/implementation-turn.d.ts +34 -31
  164. package/dist/task/implementation-turn.js +29 -27
  165. package/dist/task/inline-markdown.d.ts +20 -7
  166. package/dist/task/inline-markdown.js +15 -6
  167. package/dist/task/launch-config-gap.js +25 -39
  168. package/dist/task/launch-contract.d.ts +18 -21
  169. package/dist/task/launch-contract.js +28 -30
  170. package/dist/task/launch-manifest.d.ts +6 -2
  171. package/dist/task/launch-manifest.js +35 -34
  172. package/dist/task/ledger.js +16 -14
  173. package/dist/task/lint-fix.d.ts +6 -8
  174. package/dist/task/lint-fix.js +67 -69
  175. package/dist/task/loop-detector.d.ts +9 -8
  176. package/dist/task/loop-detector.js +16 -12
  177. package/dist/task/mid-run-input.d.ts +17 -15
  178. package/dist/task/mid-run-input.js +17 -15
  179. package/dist/task/orchestrator.d.ts +24 -28
  180. package/dist/task/orchestrator.js +62 -64
  181. package/dist/task/orientation.d.ts +18 -23
  182. package/dist/task/orientation.js +24 -31
  183. package/dist/task/owned-freeze-conflict.d.ts +21 -20
  184. package/dist/task/owned-freeze-conflict.js +52 -85
  185. package/dist/task/owned-freeze-reassign.d.ts +40 -60
  186. package/dist/task/owned-freeze-reassign.js +41 -61
  187. package/dist/task/parsers.d.ts +4 -2
  188. package/dist/task/parsers.js +4 -4
  189. package/dist/task/phases.d.ts +41 -48
  190. package/dist/task/phases.js +180 -248
  191. package/dist/task/plan-io.d.ts +6 -7
  192. package/dist/task/plan-io.js +6 -7
  193. package/dist/task/plan-orchestrator.d.ts +10 -8
  194. package/dist/task/plan-orchestrator.js +14 -10
  195. package/dist/task/plan-prompts.d.ts +6 -5
  196. package/dist/task/plan-prompts.js +6 -5
  197. package/dist/task/plan-readonly.d.ts +4 -5
  198. package/dist/task/plan-readonly.js +4 -5
  199. package/dist/task/plan-rounds.d.ts +17 -29
  200. package/dist/task/plan-rounds.js +21 -34
  201. package/dist/task/plan-session.d.ts +58 -72
  202. package/dist/task/plan-session.js +61 -83
  203. package/dist/task/probe-gaming.d.ts +28 -27
  204. package/dist/task/probe-gaming.js +0 -0
  205. package/dist/task/prohibition-probe.d.ts +14 -16
  206. package/dist/task/prompts.d.ts +3 -4
  207. package/dist/task/prompts.js +17 -26
  208. package/dist/task/qa-transcript.d.ts +15 -22
  209. package/dist/task/qa-transcript.js +15 -21
  210. package/dist/task/question-box.d.ts +17 -13
  211. package/dist/task/question-box.js +19 -15
  212. package/dist/task/question-dedup.d.ts +6 -7
  213. package/dist/task/question-dedup.js +13 -14
  214. package/dist/task/question-dialog.d.ts +22 -32
  215. package/dist/task/question-dialog.js +22 -32
  216. package/dist/task/question-source.d.ts +18 -44
  217. package/dist/task/question-source.js +22 -51
  218. package/dist/task/refuted-constraint.d.ts +11 -31
  219. package/dist/task/refuted-constraint.js +27 -51
  220. package/dist/task/regenerable-artifacts.d.ts +12 -31
  221. package/dist/task/regenerable-artifacts.js +12 -31
  222. package/dist/task/render-check.d.ts +11 -22
  223. package/dist/task/render-check.js +33 -46
  224. package/dist/task/repo-health-check.d.ts +10 -14
  225. package/dist/task/repo-health-check.js +17 -23
  226. package/dist/task/requirements.d.ts +38 -71
  227. package/dist/task/requirements.js +78 -126
  228. package/dist/task/research-fanout-budget.d.ts +51 -88
  229. package/dist/task/research-fanout-budget.js +51 -88
  230. package/dist/task/research-worker.d.ts +33 -36
  231. package/dist/task/research-worker.js +39 -61
  232. package/dist/task/resume-gap.d.ts +14 -15
  233. package/dist/task/root-cause-repair.d.ts +9 -9
  234. package/dist/task/root-cause-repair.js +28 -40
  235. package/dist/task/run-bracket.d.ts +10 -13
  236. package/dist/task/run-end.d.ts +12 -22
  237. package/dist/task/run-end.js +8 -16
  238. package/dist/task/run-final-gate.d.ts +19 -21
  239. package/dist/task/run-final-gate.js +62 -80
  240. package/dist/task/runner-globs.d.ts +12 -13
  241. package/dist/task/runner-globs.js +12 -13
  242. package/dist/task/runner-resolve.d.ts +9 -9
  243. package/dist/task/runner-resolve.js +22 -23
  244. package/dist/task/script-escape.d.ts +10 -12
  245. package/dist/task/script-escape.js +13 -14
  246. package/dist/task/serve-entry.d.ts +1 -1
  247. package/dist/task/serve-entry.js +22 -25
  248. package/dist/task/service-blocks.js +4 -2
  249. package/dist/task/shipped-source.d.ts +11 -29
  250. package/dist/task/shipped-source.js +11 -29
  251. package/dist/task/skip-escape.js +10 -14
  252. package/dist/task/spec-urls.d.ts +26 -65
  253. package/dist/task/spec-urls.js +26 -65
  254. package/dist/task/spec-validation.d.ts +17 -20
  255. package/dist/task/spec-validation.js +17 -20
  256. package/dist/task/stall-detector.d.ts +23 -30
  257. package/dist/task/stall-detector.js +23 -30
  258. package/dist/task/stream-watchdog.d.ts +14 -12
  259. package/dist/task/stream-watchdog.js +14 -12
  260. package/dist/task/substitution-probe.d.ts +17 -20
  261. package/dist/task/substitution-probe.js +17 -20
  262. package/dist/task/task-gates.d.ts +36 -41
  263. package/dist/task/task-gates.js +95 -106
  264. package/dist/task/task-io.d.ts +4 -4
  265. package/dist/task/task-io.js +4 -4
  266. package/dist/task/task-parsers.js +4 -3
  267. package/dist/task/task-provenance.d.ts +2 -2
  268. package/dist/task/task-provenance.js +11 -13
  269. package/dist/task/task-types.d.ts +4 -3
  270. package/dist/task/terminal-outcome.d.ts +14 -16
  271. package/dist/task/terminal-outcome.js +12 -14
  272. package/dist/task/test-assembly.d.ts +13 -20
  273. package/dist/task/test-assembly.js +13 -20
  274. package/dist/task/timings.d.ts +5 -3
  275. package/dist/task/timings.js +5 -3
  276. package/dist/task/title-label.d.ts +9 -4
  277. package/dist/task/title-label.js +9 -4
  278. package/dist/task/type-only-answer.d.ts +44 -52
  279. package/dist/task/type-only-answer.js +44 -52
  280. package/dist/task/unfailable-command.d.ts +18 -24
  281. package/dist/task/unfailable-command.js +21 -27
  282. package/dist/task/unknown-routing.d.ts +10 -4
  283. package/dist/task/unknown-routing.js +10 -4
  284. package/dist/task/user-directives.d.ts +5 -8
  285. package/dist/task/user-directives.js +5 -8
  286. package/dist/task/verify-quality.d.ts +18 -22
  287. package/dist/task/verify-quality.js +45 -46
  288. package/dist/task/verify-reconcile.d.ts +15 -10
  289. package/dist/task/verify-reconcile.js +45 -43
  290. package/dist/task/verify-resolution.d.ts +24 -20
  291. package/dist/task/verify-resolution.js +51 -50
  292. package/dist/task/verify-work.d.ts +59 -66
  293. package/dist/task/verify-work.js +101 -138
  294. package/dist/task/widget.d.ts +15 -14
  295. package/dist/task/widget.js +22 -17
  296. package/dist/task/wiring-claims.d.ts +25 -32
  297. package/dist/task/wiring-claims.js +30 -35
  298. package/dist/task/write-guard.d.ts +39 -39
  299. package/dist/task/write-guard.js +48 -51
  300. package/dist/task/yolo.d.ts +34 -30
  301. package/dist/task/yolo.js +42 -37
  302. package/dist/workers/abstention.d.ts +21 -41
  303. package/dist/workers/abstention.js +27 -48
  304. package/dist/workers/brave-search.d.ts +4 -3
  305. package/dist/workers/brave-search.js +5 -2
  306. package/dist/workers/brave-warning.d.ts +7 -4
  307. package/dist/workers/brave-warning.js +19 -7
  308. package/dist/workers/ddg-search.d.ts +6 -6
  309. package/dist/workers/ddg-search.js +18 -12
  310. package/dist/workers/docs-cache.js +5 -2
  311. package/dist/workers/docs-chunk.d.ts +30 -37
  312. package/dist/workers/docs-chunk.js +37 -41
  313. package/dist/workers/docs-core.d.ts +28 -44
  314. package/dist/workers/docs-core.js +25 -44
  315. package/dist/workers/docs-index.js +4 -3
  316. package/dist/workers/docs-lookup.d.ts +15 -22
  317. package/dist/workers/docs-lookup.js +12 -21
  318. package/dist/workers/docs-project.d.ts +15 -9
  319. package/dist/workers/docs-project.js +17 -10
  320. package/dist/workers/docs-resolve.d.ts +19 -20
  321. package/dist/workers/docs-resolve.js +35 -32
  322. package/dist/workers/docs-retrieve.d.ts +5 -6
  323. package/dist/workers/docs-retrieve.js +18 -15
  324. package/dist/workers/exa-search.d.ts +9 -6
  325. package/dist/workers/exa-search.js +23 -12
  326. package/dist/workers/fetch-core.d.ts +13 -16
  327. package/dist/workers/fetch-core.js +23 -23
  328. package/dist/workers/focused-extractor.d.ts +12 -12
  329. package/dist/workers/focused-extractor.js +16 -19
  330. package/dist/workers/html-clean.js +24 -14
  331. package/dist/workers/http-request.d.ts +28 -20
  332. package/dist/workers/http-request.js +22 -17
  333. package/dist/workers/npm-version.d.ts +28 -11
  334. package/dist/workers/npm-version.js +24 -15
  335. package/dist/workers/phantom-imports.d.ts +15 -12
  336. package/dist/workers/phantom-imports.js +30 -24
  337. package/dist/workers/pi-worker-core.d.ts +86 -54
  338. package/dist/workers/pi-worker-core.js +112 -112
  339. package/dist/workers/pi-worker-docs.d.ts +24 -19
  340. package/dist/workers/pi-worker-docs.js +67 -76
  341. package/dist/workers/pi-worker-fetch.d.ts +7 -3
  342. package/dist/workers/pi-worker-fetch.js +27 -19
  343. package/dist/workers/pi-worker-search.js +12 -8
  344. package/dist/workers/pi-worker.d.ts +9 -4
  345. package/dist/workers/pi-worker.js +23 -10
  346. package/dist/workers/reasoning-warning.d.ts +18 -17
  347. package/dist/workers/reasoning-warning.js +22 -20
  348. package/dist/workers/research-cache.js +50 -78
  349. package/dist/workers/search-core.js +7 -5
  350. package/dist/workers/search-types.d.ts +10 -9
  351. package/dist/workers/search-types.js +9 -8
  352. package/dist/workers/session-hint.d.ts +13 -14
  353. package/dist/workers/session-hint.js +8 -9
  354. package/dist/workers/shared.d.ts +21 -25
  355. package/dist/workers/shared.js +0 -0
  356. package/dist/workers/single-read-extension.d.ts +14 -7
  357. package/dist/workers/single-read-extension.js +14 -7
  358. package/dist/workers/single-read-guard.d.ts +25 -28
  359. package/dist/workers/single-read-guard.js +32 -32
  360. package/dist/workers/typeonly-log.d.ts +12 -9
  361. package/dist/workers/typeonly-log.js +29 -33
  362. package/dist/workers/worker-channels.d.ts +15 -23
  363. package/dist/workers/worker-channels.js +15 -23
  364. package/dist/workers/worker-failure.d.ts +38 -46
  365. package/dist/workers/worker-failure.js +31 -39
  366. package/dist/workers/worker-kill.d.ts +25 -26
  367. package/dist/workers/worker-kill.js +16 -19
  368. package/dist/workers/worker-profiles.d.ts +43 -53
  369. package/dist/workers/worker-profiles.js +30 -38
  370. package/package.json +10 -8
@@ -1,10 +1,12 @@
1
1
  /**
2
2
  * Per-task git commit for /task-auto.
3
3
  *
4
- * After each decomposed task passes, runAutoLoop snapshots the working tree into
5
- * a single commit so the run produces one commit per task. This is best-effort:
6
- * outside a git repo, with nothing staged, or on any git error we report the
7
- * reason and let the loop continue (the task already succeeded).
4
+ * After each decomposed task passes, the loop snapshots the working tree into a
5
+ * single commit, so a run produces one commit per task. Best-effort throughout,
6
+ * and confirmed by calling it: outside a git repo it answers
7
+ * `{committed: false, reason: 'not a git repository'}`, on a clean tree
8
+ * `{committed: false, reason: 'nothing to commit'}`. Nothing throws — the task
9
+ * already succeeded, and a failed snapshot must not undo that.
8
10
  */
9
11
  import * as fsp from 'node:fs/promises';
10
12
  import * as path from 'node:path';
@@ -14,15 +16,21 @@ import { isDeletionExemptArtifact } from './regenerable-artifacts.js';
14
16
  * ledgers. Preserved verbatim across a revert (see gitDropLastCommit). */
15
17
  const TRAIL_DIR = '.pi-tasks';
16
18
  /**
17
- * Does this git stderr describe a missing author identity? Seen live (mx5 run 4):
18
- * the headless docker container has no HOME gitconfig, so EVERY per-task commit
19
- * failed "Author identity unknown" which silently disabled enforce and every
20
- * commit-based differential guard for the whole run.
19
+ * Does this git stderr describe a missing author identity?
20
+ *
21
+ * The failure it catches is total rather than partial: with no usable gitconfig
22
+ * every per-task commit fails, which silently disables enforce and every
23
+ * commit-based differential guard for the rest of the run. Reproduced with real
24
+ * git — committing with `HOME` unset and both config files pointed at
25
+ * `/dev/null` prints "Author identity unknown" plus the `user.email` /
26
+ * `user.name` advice, and this predicate matches that text while rejecting an
27
+ * unrelated `fatal: not a git repository`.
21
28
  */
22
29
  export function isIdentityFailure(stderr) {
23
30
  return /identity unknown|unable to auto-detect email|user\.(name|email)/i.test(stderr);
24
31
  }
25
- /** Fallback identity for environments with no git config (headless containers). */
32
+ /** Fallback identity for environments with no git config. Confirmed against real
33
+ * git: the same commit that fails with no identity succeeds with these args. */
26
34
  export const FALLBACK_IDENTITY_ARGS = [
27
35
  '-c',
28
36
  'user.name=pi-task',
@@ -42,21 +50,22 @@ export async function git(cwd, args, signal, spawnFn) {
42
50
  * `test-results/`, `playwright-report/`, `coverage/`, `.nyc_output/`,
43
51
  * `.last-run.json`, `*.tsbuildinfo`.
44
52
  *
45
- * This is the other half of mx5 run 20. TASK_0027's snapshot ran a bare
46
- * `git add -A` over a tree the test run had just littered with three Playwright
47
- * FAILURE screenshots (`*-actual.png` written only when a screenshot assertion
48
- * fails), committed them, and thereby made them tracked deliverables. Two whole
49
- * final-gate fix attempts were then rejected for deleting them. The deletion guard
50
- * fix (write-guard.ts) stops the rejection; this stops the tracking.
53
+ * The failure this closes: a bare `git add -A` sweeps up whatever the test run
54
+ * just littered the tree with a failure screenshot, a coverage dir and commits
55
+ * it, making regenerable output a TRACKED deliverable. A later task that cleans it
56
+ * up then reads as deleting someone's work.
51
57
  *
52
58
  * ONLY UNTRACKED PATHS ARE EXCLUDED, and that is load-bearing rather than tidy.
53
- * `git ls-files --others` lists untracked, non-ignored files and nothing else, so a
54
- * path git ALREADY tracks can never appear here — meaning a project that
55
- * deliberately commits, say, a `coverage/` badge keeps having its edits to it
56
- * committed. Excluding by directory pathspec instead (`:(exclude)coverage/`) would
57
- * silently stop committing those.
59
+ * Both halves measured with real git in a repo with a gitignored `coverage/` and
60
+ * an untracked `test-results/`:
61
+ * `ls-files --others --exclude-standard` returned the untracked file alone;
62
+ * dropping the flag brought the gitignored one back too.
63
+ * a TRACKED file never appears, even while modified.
64
+ * So a project that deliberately commits, say, a `coverage/` badge keeps having
65
+ * its edits to it committed. Excluding by directory pathspec instead
66
+ * (`:(exclude)coverage/`) would silently stop committing those.
58
67
  *
59
- * Best-effort: any git failure yields an empty list, i.e. today's `git add -A`.
68
+ * Best-effort: any git failure yields an empty list, i.e. a plain `git add -A`.
60
69
  */
61
70
  export async function untrackedArtifacts(cwd, signal, spawnFn) {
62
71
  const r = await git(cwd, ['ls-files', '--others', '--exclude-standard', '-z'], signal, spawnFn);
@@ -69,7 +78,7 @@ export async function untrackedArtifacts(cwd, signal, spawnFn) {
69
78
  .sort();
70
79
  }
71
80
  /** `:(exclude)` pathspecs for `git add -A`; empty when nothing is excluded, so the
72
- * common case is byte-identical to the previous bare `git add -A`. */
81
+ * common case adds no arguments at all and stays a bare `git add -A`. */
73
82
  export function stagePathspec(excluded) {
74
83
  if (excluded.length === 0)
75
84
  return [];
@@ -80,10 +89,12 @@ export function stagePathspec(excluded) {
80
89
  * Empty outside a git repo or on any git error — this is a GUARD input, and a
81
90
  * guard that cannot conclude must not block.
82
91
  *
83
- * Why it exists (mx5 run 6): a stale `git stash pop` mid-task left two paths UU;
84
- * every later commit was doomed, three verify passes ran against a conflicted
85
- * tree, and worse a blind `git add -A` on that index would have silently
86
- * "resolved" the conflict with whatever happened to be on disk.
92
+ * Why it exists: with an unmerged index every later commit is doomed, verify runs
93
+ * against a conflicted tree, and worst a blind `git add -A` SILENTLY resolves
94
+ * the conflict with whatever is on disk. Reproduced on a real conflict: `git
95
+ * status` showed `UU c.txt`, then a bare `git add -A` turned it into `M c.txt`
96
+ * and left `ls-files -u` empty. The conflict markers become staged content and
97
+ * nothing says so.
87
98
  */
88
99
  export async function gitUnmergedPaths(cwd, signal, spawnFn) {
89
100
  const r = await git(cwd, ['ls-files', '-u'], signal, spawnFn);
@@ -103,7 +114,7 @@ export async function gitUnmergedPaths(cwd, signal, spawnFn) {
103
114
  }
104
115
  /** Sha of `refs/stash`, or null when there is no stash (or not a git repo). Used
105
116
  * to detect a stash created (or consumed) during a task and left behind — the
106
- * exact landmine that detonated mx5 run 6 two days after it was pushed. */
117
+ * exact landmine that detonates days after it is pushed. */
107
118
  export async function gitStashRef(cwd, signal, spawnFn) {
108
119
  const r = await git(cwd, ['rev-parse', '-q', '--verify', 'refs/stash'], signal, spawnFn);
109
120
  return r.exitCode === 0 ? r.stdout.trim() : null;
@@ -187,18 +198,20 @@ export async function gitCommitAll(cwd, message, signal, spawnFn) {
187
198
  * verified task commit underneath it.
188
199
  *
189
200
  * `reset --hard` targets the enforce pass's in-place SOURCE edits. But it must NOT
190
- * rewind the forensic gate trail: `.pi-tasks/` is frequently TRACKED (the per-task
191
- * snapshots stage it via `git add -A`), so a bare reset restores TASK_00NN.md to the
192
- * snapshot commit and ERASES every trail line written after it the "commit: task
193
- * snapshot committed", "enforce(edit): …", and resolution lines (mx5 run 9:
194
- * TASK_0007/0008/0012 each lost their whole post-snapshot trail on this exact path,
195
- * so a passing-then-reverted task looked like it had never been committed). So the
196
- * trail is snapshotted before the reset and restored after the revert undoes code,
197
- * the audit log survives.
201
+ * rewind the forensic gate trail. `.pi-tasks/` is frequently TRACKED here — unlike
202
+ * the accept-debt ledger's writers, the per-task snapshot stages it with a plain
203
+ * `git add -A` and no exclusion so a bare reset rewinds the task file along with
204
+ * the source and ERASES every trail line written after the snapshot.
205
+ *
206
+ * Both halves were run on a real repo. A bare `reset --hard HEAD~1` restored the
207
+ * source AND dropped the trail line added after the snapshot; calling this
208
+ * function on the identical setup restored the source and kept that line. The
209
+ * revert undoes code, the audit log survives.
198
210
  *
199
- * Best-effort and never throws: a git failure is swallowed (the caller has
200
- * already decided to keep the verified work; a failed reset only leaves the
201
- * enforce commit in place, which is surfaced as a warning).
211
+ * Best-effort and never throws: a git failure is swallowed, since the caller has
212
+ * already decided to keep the verified work and a failed reset only leaves the
213
+ * enforce commit in place, which is surfaced as a warning. Called on a directory
214
+ * that is not a repo at all, it returns without throwing.
202
215
  */
203
216
  export async function gitDropLastCommit(cwd, signal, spawnFn) {
204
217
  const trail = await snapshotTrail(cwd);
@@ -10,12 +10,16 @@ export declare function allocateAutoId(cwd: string): Promise<string>;
10
10
  /**
11
11
  * Parse a decompose-phase model output into a clean list of titles.
12
12
  *
13
- * No cap: every title the model emits is kept. An arbitrary ceiling (was 30)
14
- * silently dropped the tail of a large plan AND re-clipped every coverage retry,
15
- * so a design that genuinely needed >N tasks could never escape the ceiling —
16
- * it burned its coverage rounds and shipped a knowingly-gapped plan. The real
17
- * bound on task count is the design's own grounded-requirement scope, enforced
18
- * downstream by the coverage loop; this parser must not pre-empt it.
13
+ * No cap: every title the model emits is kept 100 lines in, 100 titles out.
14
+ * A ceiling here would be invisible and self-defeating, because it would clip the
15
+ * tail of a large plan AND re-clip every coverage retry, so a design that
16
+ * genuinely needs more tasks than the ceiling could never grow past it — it would
17
+ * burn its coverage rounds and ship a knowingly-gapped plan. The real bound is
18
+ * the design's own grounded-requirement scope, enforced downstream by the
19
+ * coverage loop; this parser must not pre-empt it.
20
+ *
21
+ * Accepts checkbox, bare-dash and numbered forms (`1.` and `2)`), indented or
22
+ * not, and skips prose lines and empty bullets.
19
23
  */
20
24
  export declare function parseDecomposeList(raw: string): string[];
21
25
  /** Parsed DECOMPOSE_COVERAGE_PROMPT verdict. */
@@ -24,16 +28,21 @@ export interface CoverageVerdict {
24
28
  missing: string[];
25
29
  }
26
30
  /**
27
- * Parse the coverage-triage child's verdict. Returns null when no COVERAGE tag
28
- * is present (the model wrote prose) the caller treats that as "accept the
29
- * list as-is", so a malformed judgment can never block planning.
31
+ * Parse the coverage-triage child's verdict. Returns null when no COVERAGE tag is
32
+ * present (the model wrote prose), and the caller reads a null verdict as an
33
+ * empty missing-list, so a malformed judgment can never block planning.
34
+ *
35
+ * `COVERAGE: INCOMPLETE` with no MISSING lines also returns null, deliberately:
36
+ * it names nothing to reprompt with, so treating it as a verdict would loop
37
+ * blind. Confirmed by running both shapes.
30
38
  */
31
39
  export declare function parseCoverageVerdict(raw: string): CoverageVerdict | null;
32
40
  /** Parse the "## tasks" checkbox list. */
33
41
  export declare function parseTaskList(body: string): TaskEntry[];
34
42
  /** Build the initial AUTO-file body. `coverage` is the requirement-level
35
- * accounting summary (goal A(c) — a durable, user-visible record of what was
36
- * carried cross-cutting and what stayed unowned); '' omits the section. */
43
+ * accounting summary — a durable, user-visible record of what was carried
44
+ * cross-cutting and what stayed unowned. An empty string omits the section
45
+ * entirely rather than emitting a blank heading. */
37
46
  export declare function buildAutoBody(feature: string, clarifications: string, titles: string[], coverage?: string): string;
38
47
  /** Check off the Nth checkbox line, stamping the produced TASK_NNNN id. */
39
48
  export declare function checkOffTask(cwd: string, id: string, index: number, producedId: string, title: string): Promise<void>;
@@ -46,18 +55,24 @@ export declare function checkOffTask(cwd: string, id: string, index: number, pro
46
55
  export declare function stampTaskInProgress(cwd: string, id: string, index: number, producedId: string, title: string): Promise<void>;
47
56
  /**
48
57
  * Insert a NEW unchecked entry directly after the `afterIndex`th checkbox — the
49
- * mid-run plan mutation the root-cause repair channel needs (mx5 run 14 item 5:
50
- * a repair task must land BEFORE the next dependent task, not at the end of the
51
- * plan, or the defect keeps failing everything in between).
58
+ * mid-run plan mutation the root-cause repair channel needs: a repair task must
59
+ * land BEFORE the next dependent task, not at the end of the plan, or the defect
60
+ * keeps failing everything in between.
52
61
  *
53
- * MONOTONIC by construction (the run-12 replacement lesson): this only ever
54
- * SPLICES a line in. No existing entry is rewritten, reordered, or dropped, and
55
- * an already-present title is a no-op — so a plan can grow mid-run but never
56
- * shrink, and a retried insert cannot duplicate. Returns whether a line was added.
62
+ * MONOTONIC by construction: this only ever SPLICES a line in. No existing entry
63
+ * is rewritten, reordered or dropped, and an already-present title is a no-op —
64
+ * so a plan can grow mid-run but never shrink, and a retried insert cannot
65
+ * duplicate. Returns whether a line was added.
66
+ *
67
+ * Run against a real plan: inserting a new title after entry 0 returns true and
68
+ * lands it directly after that entry; the same title again returns false; a title
69
+ * that is already present AND CHECKED also returns false; an empty title returns
70
+ * false. Everything else keeps its order.
57
71
  *
58
72
  * Later entries shift down by one, which is safe because the /task-auto loop
59
73
  * re-reads and re-parses the plan at the top of every iteration and locates its
60
- * next step by "first unchecked" rather than by a cached index.
74
+ * next step with `entries.find(e => !e.done)` — first unchecked rather than a
75
+ * cached index.
61
76
  */
62
77
  export declare function insertTaskAfter(cwd: string, id: string, afterIndex: number, title: string): Promise<boolean>;
63
78
  /**
@@ -65,12 +80,17 @@ export declare function insertTaskAfter(cwd: string, id: string, afterIndex: num
65
80
  * last-write time the resume banner reports (see resume-gap.ts). Null when there
66
81
  * is nothing resumable.
67
82
  *
68
- * `states` narrows which states count as resumable, and the UNATTENDED path passes
69
- * UNATTENDED_STATES so the search answers the question that path actually asks
70
- * "is there an IN-FLIGHT run to pick up?". Selecting the newest human-resumable run
71
- * and only then refusing it on state let one failed run shadow an in-flight one
72
- * behind it: the boot hook refused every restart and the in-flight run stayed in
73
- * exactly the dead air this feature exists to end.
83
+ * `states` narrows which states count as resumable BEFORE the newest-wins sort,
84
+ * and that ordering is the whole point. The UNATTENDED path passes
85
+ * UNATTENDED_STATES so the search answers the question it actually asks "is
86
+ * there an IN-FLIGHT run to pick up?"
87
+ *
88
+ * Filtering after the sort instead would let one failed run shadow an in-flight
89
+ * one behind it. Demonstrated on two files, the newer `failed` and the older
90
+ * `in_progress`: the default states pick the newer failed one, while
91
+ * UNATTENDED_STATES picks the older in-progress one. Had the newest been chosen
92
+ * first and only then refused on state, the restart would find nothing and the
93
+ * in-flight run would sit in exactly the dead air this exists to end.
74
94
  */
75
95
  export declare function findResumableAutoDetailed(cwd: string, states?: readonly TaskState[]): Promise<AutoResumeCandidate | null>;
76
96
  /** Id-only form of {@link findResumableAutoDetailed}. */
@@ -2,8 +2,11 @@
2
2
  * AUTO-file I/O & parsing for /task-auto.
3
3
  *
4
4
  * Thin layer over task-io/task-parsers: a TASK_AUTO_NNNN.md is a normal task
5
- * file (same front matter) whose body holds feature prompt, clarifications, and
6
- * a markdown checkbox list of task titles. The checkboxes are the resume cursor.
5
+ * file — the same front matter, parsed by the same `parseFrontMatter` whose
6
+ * body holds `## feature prompt`, `## clarifications`, `## tasks` and optionally
7
+ * `## coverage`. The checkbox list under `## tasks` is the resume cursor, and the
8
+ * loop finds its next step with `entries.find(e => !e.done)` rather than a
9
+ * remembered position.
7
10
  */
8
11
  import * as fsp from 'node:fs/promises';
9
12
  import * as path from 'node:path';
@@ -29,12 +32,16 @@ export async function allocateAutoId(cwd) {
29
32
  /**
30
33
  * Parse a decompose-phase model output into a clean list of titles.
31
34
  *
32
- * No cap: every title the model emits is kept. An arbitrary ceiling (was 30)
33
- * silently dropped the tail of a large plan AND re-clipped every coverage retry,
34
- * so a design that genuinely needed >N tasks could never escape the ceiling —
35
- * it burned its coverage rounds and shipped a knowingly-gapped plan. The real
36
- * bound on task count is the design's own grounded-requirement scope, enforced
37
- * downstream by the coverage loop; this parser must not pre-empt it.
35
+ * No cap: every title the model emits is kept 100 lines in, 100 titles out.
36
+ * A ceiling here would be invisible and self-defeating, because it would clip the
37
+ * tail of a large plan AND re-clip every coverage retry, so a design that
38
+ * genuinely needs more tasks than the ceiling could never grow past it — it would
39
+ * burn its coverage rounds and ship a knowingly-gapped plan. The real bound is
40
+ * the design's own grounded-requirement scope, enforced downstream by the
41
+ * coverage loop; this parser must not pre-empt it.
42
+ *
43
+ * Accepts checkbox, bare-dash and numbered forms (`1.` and `2)`), indented or
44
+ * not, and skips prose lines and empty bullets.
38
45
  */
39
46
  export function parseDecomposeList(raw) {
40
47
  const out = [];
@@ -46,9 +53,13 @@ export function parseDecomposeList(raw) {
46
53
  return out;
47
54
  }
48
55
  /**
49
- * Parse the coverage-triage child's verdict. Returns null when no COVERAGE tag
50
- * is present (the model wrote prose) the caller treats that as "accept the
51
- * list as-is", so a malformed judgment can never block planning.
56
+ * Parse the coverage-triage child's verdict. Returns null when no COVERAGE tag is
57
+ * present (the model wrote prose), and the caller reads a null verdict as an
58
+ * empty missing-list, so a malformed judgment can never block planning.
59
+ *
60
+ * `COVERAGE: INCOMPLETE` with no MISSING lines also returns null, deliberately:
61
+ * it names nothing to reprompt with, so treating it as a verdict would loop
62
+ * blind. Confirmed by running both shapes.
52
63
  */
53
64
  export function parseCoverageVerdict(raw) {
54
65
  const tag = /^\s*COVERAGE:\s*(COMPLETE|INCOMPLETE)\s*$/im.exec(raw);
@@ -98,8 +109,9 @@ export function parseTaskList(body) {
98
109
  return entries;
99
110
  }
100
111
  /** Build the initial AUTO-file body. `coverage` is the requirement-level
101
- * accounting summary (goal A(c) — a durable, user-visible record of what was
102
- * carried cross-cutting and what stayed unowned); '' omits the section. */
112
+ * accounting summary — a durable, user-visible record of what was carried
113
+ * cross-cutting and what stayed unowned. An empty string omits the section
114
+ * entirely rather than emitting a blank heading. */
103
115
  export function buildAutoBody(feature, clarifications, titles, coverage = '') {
104
116
  const tasks = titles.map(t => `- [ ] ${t}`).join('\n');
105
117
  return (`\n## feature prompt\n\n${feature.trim() || '(none)'}\n\n`
@@ -151,18 +163,24 @@ function entryTitle(line) {
151
163
  }
152
164
  /**
153
165
  * Insert a NEW unchecked entry directly after the `afterIndex`th checkbox — the
154
- * mid-run plan mutation the root-cause repair channel needs (mx5 run 14 item 5:
155
- * a repair task must land BEFORE the next dependent task, not at the end of the
156
- * plan, or the defect keeps failing everything in between).
166
+ * mid-run plan mutation the root-cause repair channel needs: a repair task must
167
+ * land BEFORE the next dependent task, not at the end of the plan, or the defect
168
+ * keeps failing everything in between.
157
169
  *
158
- * MONOTONIC by construction (the run-12 replacement lesson): this only ever
159
- * SPLICES a line in. No existing entry is rewritten, reordered, or dropped, and
160
- * an already-present title is a no-op — so a plan can grow mid-run but never
161
- * shrink, and a retried insert cannot duplicate. Returns whether a line was added.
170
+ * MONOTONIC by construction: this only ever SPLICES a line in. No existing entry
171
+ * is rewritten, reordered or dropped, and an already-present title is a no-op —
172
+ * so a plan can grow mid-run but never shrink, and a retried insert cannot
173
+ * duplicate. Returns whether a line was added.
174
+ *
175
+ * Run against a real plan: inserting a new title after entry 0 returns true and
176
+ * lands it directly after that entry; the same title again returns false; a title
177
+ * that is already present AND CHECKED also returns false; an empty title returns
178
+ * false. Everything else keeps its order.
162
179
  *
163
180
  * Later entries shift down by one, which is safe because the /task-auto loop
164
181
  * re-reads and re-parses the plan at the top of every iteration and locates its
165
- * next step by "first unchecked" rather than by a cached index.
182
+ * next step with `entries.find(e => !e.done)` — first unchecked rather than a
183
+ * cached index.
166
184
  */
167
185
  export async function insertTaskAfter(cwd, id, afterIndex, title) {
168
186
  const clean = title.trim();
@@ -186,8 +204,13 @@ export async function insertTaskAfter(cwd, id, afterIndex, title) {
186
204
  if (seen === afterIndex)
187
205
  break;
188
206
  }
189
- // An out-of-range index appends after the LAST checkbox rather than throwing:
190
- // a plan that grew underneath the caller must still receive the entry.
207
+ // An out-of-range afterIndex is not an error: the loop above leaves `insertAt`
208
+ // just past the LAST checkbox, so the entry is appended rather than lost — a
209
+ // plan that grew underneath the caller must still receive it. Confirmed with
210
+ // afterIndex 99 on a five-entry plan.
211
+ //
212
+ // The guard below is the different case: a `## tasks` section with NO checkbox
213
+ // lines at all, where there is no position to splice into.
191
214
  if (insertAt === -1)
192
215
  return false;
193
216
  lines.splice(insertAt, 0, `- [ ] ${clean}`);
@@ -199,12 +222,17 @@ export async function insertTaskAfter(cwd, id, afterIndex, title) {
199
222
  * last-write time the resume banner reports (see resume-gap.ts). Null when there
200
223
  * is nothing resumable.
201
224
  *
202
- * `states` narrows which states count as resumable, and the UNATTENDED path passes
203
- * UNATTENDED_STATES so the search answers the question that path actually asks
204
- * "is there an IN-FLIGHT run to pick up?". Selecting the newest human-resumable run
205
- * and only then refusing it on state let one failed run shadow an in-flight one
206
- * behind it: the boot hook refused every restart and the in-flight run stayed in
207
- * exactly the dead air this feature exists to end.
225
+ * `states` narrows which states count as resumable BEFORE the newest-wins sort,
226
+ * and that ordering is the whole point. The UNATTENDED path passes
227
+ * UNATTENDED_STATES so the search answers the question it actually asks "is
228
+ * there an IN-FLIGHT run to pick up?"
229
+ *
230
+ * Filtering after the sort instead would let one failed run shadow an in-flight
231
+ * one behind it. Demonstrated on two files, the newer `failed` and the older
232
+ * `in_progress`: the default states pick the newer failed one, while
233
+ * UNATTENDED_STATES picks the older in-progress one. Had the newest been chosen
234
+ * first and only then refused on state, the restart would find nothing and the
235
+ * in-flight run would sit in exactly the dead air this exists to end.
208
236
  */
209
237
  export async function findResumableAutoDetailed(cwd, states = RESUMABLE_STATES) {
210
238
  await ensureTasksDir(cwd);
@@ -16,15 +16,15 @@ export interface AutoDeps extends GateDeps, FinalGateStageDeps {
16
16
  runChild: (name: string, tools: string, prompt: string) => Promise<string>;
17
17
  /**
18
18
  * Paths with unmerged index entries (an in-progress merge conflict). The loop
19
- * refuses to START a task on a conflicted tree — mx5 run 6 ran a full impl turn
20
- * plus three verifies against one, with every commit doomed from the outset.
19
+ * refuses to START a task on a conflicted tree: a full implementation turn
20
+ * and its verifies run against one with every commit doomed from the outset.
21
21
  * Absent (tests) → treated as clean.
22
22
  */
23
23
  unmergedPaths?: (cwd: string) => Promise<string[]>;
24
24
  /**
25
25
  * Sha of refs/stash or null. Compared around each task so a stash pushed (or
26
26
  * consumed) during the task and left behind is called out — an orphan stash is
27
- * exactly the landmine that detonated as an unresolvable conflict in run 6.
27
+ * exactly the landmine that detonates as an unresolvable conflict later.
28
28
  * Absent (tests) → the check is skipped.
29
29
  */
30
30
  stashRef?: (cwd: string) => Promise<string | null>;
@@ -50,34 +50,35 @@ export declare function expandFeatureMentions(cwd: string, feature: string): Pro
50
50
  export declare function readableMentions(cwd: string, feature: string): Promise<string[]>;
51
51
  /**
52
52
  * Thread the feature's spec references AND any per-task decisions into every
53
- * decomposed task title. A title is ALL a per-task pipeline ever sees, so both
54
- * the design doc the feature pointed at and the user's clarification choices have
55
- * to ride along or they're invisible downstream — this is how an "Implement
56
- * @design.md" run built a generic `posts` table the spec never mentioned, and how
57
- * a "do not use vite" clarification got silently overridden by the doc's own
58
- * vite.config.ts.
53
+ * decomposed task title. A title is ALL a per-task pipeline ever sees, so both the
54
+ * design doc the feature pointed at and the user's clarification choices have to
55
+ * ride along or they are invisible downstream — a task that cannot see the doc
56
+ * invents its own schema, and one that cannot see "do not use vite" is overridden
57
+ * by whatever the doc's own config says.
59
58
  *
60
- * Precedence is the crux: a clarification is a CORRECTION to a (possibly stale)
61
- * spec doc, so the decisions clause is marked as overriding the doc, while the doc
62
- * stays authoritative for everything the decisions don't touch. Decompose scopes
63
- * each decision to the task(s) it governs, so most titles carry none. No readable
64
- * refs and no decisions → title unchanged, so a doc-less /task-auto behaves
65
- * exactly as before.
59
+ * Precedence is the crux: a clarification is a CORRECTION to a possibly stale spec
60
+ * doc, so the decisions clause is marked as overriding the doc while the doc stays
61
+ * authoritative for everything the decisions do not touch. The emitted order puts
62
+ * decisions first, then the spec ref. Decompose scopes each decision to the tasks
63
+ * it governs, so most titles carry none.
64
+ *
65
+ * Run: with no refs and no decisions the title comes back unchanged, and
66
+ * re-threading an already-threaded list is a no-op.
66
67
  */
67
68
  export declare function attachSpecRefs(titles: string[], refs: string[]): string[];
68
69
  /**
69
70
  * Build the refine scope fence for step `currentIndex` of an N-step /task-auto
70
71
  * plan. Every per-step pipeline only ever sees its own title, so without this the
71
72
  * refine phase — told "the task title is only a pointer into that spec; follow the
72
- * spec" — re-expands the whole referenced design into one task (a real run
73
- * implemented all 24 steps under step 1). The fence lists the sibling steps by
74
- * number and forbids touching anything they own, so refine bounds this step's
75
- * slice. Validated on the local model: with the fence, refine's CONSTRAINTS gained
76
- * an explicit per-step deferral list and tool calls dropped 27→11.
73
+ * spec" — re-expands the whole referenced design into a single task, implementing
74
+ * the entire plan under step one. The fence lists the sibling steps by number and
75
+ * forbids touching anything they own, so refine bounds this step's slice.
77
76
  *
78
77
  * The plan listing strips the threaded "| decisions … | spec …" tail from each
79
- * title (keeps the human-readable head) so the model reads clean step names. The
80
- * authoritative spec ref still rides on THIS step's own title via attachSpecRefs.
78
+ * title and keeps the human-readable head, so the model reads clean step names,
79
+ * and it marks the current one "(THIS STEP)" both confirmed by building a fence
80
+ * over threaded titles. The authoritative spec ref still rides on THIS step's own
81
+ * title via attachSpecRefs.
81
82
  */
82
83
  export declare function buildScopeFence(titles: string[], currentIndex: number): string;
83
84
  /**
@@ -117,8 +118,9 @@ export declare function orientFeature(cwd: string, feature: string, deps: AutoDe
117
118
  * settles is auto-resolved and never shown — only genuine open forks reach the user.
118
119
  * The model emits NONE when nothing remains.
119
120
  *
120
- * The ONLY stage that talks to the user, and so the only one that can be dismissed:
121
- * `null` means the user cancelled and the cancellation has already been announced.
121
+ * The ONLY stage that ASKS the user anything, and so the only one that can be
122
+ * dismissed the others only notify, which cannot be. `null` means the user
123
+ * cancelled and the cancellation has already been announced.
122
124
  * Every other outcome is a transcript, possibly empty.
123
125
  */
124
126
  export declare function elicitClarifications(ctx: ExtensionCommandContext, cwd: string, deps: AutoDeps, oriented: OrientedFeature): Promise<string | null>;