@mjasnikovs/pi-task 0.38.29 → 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 +16 -9
  104. package/dist/task/context-usage.js +16 -9
  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 +36 -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 +179 -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 +29 -39
  231. package/dist/task/research-worker.js +37 -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 +69 -71
  338. package/dist/workers/pi-worker-core.js +100 -109
  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 +21 -14
  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
@@ -46,13 +46,12 @@ export declare function formatPlanDecisions(entries: readonly PlanEntry[]): stri
46
46
  /**
47
47
  * The line that pins the DELIVERABLE, and it is not optional.
48
48
  *
49
- * The task prompt leads the handoff verbatim, and users reach /task-plan by
50
- * phrasing the request as planning — live (aiz-client TASK_PLAN_0001,
51
- * 2026-08-05): "Lets plan new tab and report @src/app/reports/". /task's refine
52
- * read the verb as the deliverable and produced a task titled "Plan the addition
53
- * of a new sub-tab…", whose ACCEPTANCE was "a planning document exists with
54
- * placeholder sections" and whose VERIFY asserted that no `.ts`/`.tsx` file had
55
- * changed. It passed. Nothing was built.
49
+ * The task prompt leads the handoff VERBATIM (see `buildHandoffPrompt`), and the
50
+ * way a user reaches /task-plan is by phrasing the request as planning — "let's
51
+ * plan X". Handed that verb, /task's refine can read PLANNING as the deliverable:
52
+ * the task becomes "plan X", its ACCEPTANCE becomes "a planning document exists",
53
+ * and its VERIFY asserts that no source file changed. Such a task passes its own
54
+ * gate with nothing built.
56
55
  *
57
56
  * Planning already happened — this prompt IS its output — so the handoff says so
58
57
  * rather than letting the request's own wording re-open it. It rides on every
@@ -76,13 +76,12 @@ export function formatPlanDecisions(entries) {
76
76
  /**
77
77
  * The line that pins the DELIVERABLE, and it is not optional.
78
78
  *
79
- * The task prompt leads the handoff verbatim, and users reach /task-plan by
80
- * phrasing the request as planning — live (aiz-client TASK_PLAN_0001,
81
- * 2026-08-05): "Lets plan new tab and report @src/app/reports/". /task's refine
82
- * read the verb as the deliverable and produced a task titled "Plan the addition
83
- * of a new sub-tab…", whose ACCEPTANCE was "a planning document exists with
84
- * placeholder sections" and whose VERIFY asserted that no `.ts`/`.tsx` file had
85
- * changed. It passed. Nothing was built.
79
+ * The task prompt leads the handoff VERBATIM (see `buildHandoffPrompt`), and the
80
+ * way a user reaches /task-plan is by phrasing the request as planning — "let's
81
+ * plan X". Handed that verb, /task's refine can read PLANNING as the deliverable:
82
+ * the task becomes "plan X", its ACCEPTANCE becomes "a planning document exists",
83
+ * and its VERIFY asserts that no source file changed. Such a task passes its own
84
+ * gate with nothing built.
86
85
  *
87
86
  * Planning already happened — this prompt IS its output — so the handoff says so
88
87
  * rather than letting the request's own wording re-open it. It rides on every
@@ -4,20 +4,22 @@
4
4
  * The command is a thin wiring layer. Everything it does is already in the
5
5
  * codebase and is reused as-is:
6
6
  *
7
- * • the adaptive question loop, the duplicate backstop, the boxed picker and
8
- * the A/B answer mapping → plan-session.ts (which reuses parsers.ts,
9
- * question-dedup.ts, inline-markdown.ts,
10
- * question-box.ts, yolo.ts)
7
+ * • the question loop, the duplicate backstop and the A/B answer mapping
8
+ * → plan-session.ts, via question-source.ts (which
9
+ * uses parsers.ts and question-dedup.ts),
10
+ * question-dialog.ts, inline-markdown.ts, yolo.ts
11
11
  * • the child process, its loop/leak/stall guards and retries → child-runner.ts
12
- * • local TUI + remote browser prompt fan-out remote/bridge.ts
13
- * the status widget widget.ts
12
+ * • local TUI + remote browser prompt fan-out, and the boxed
13
+ * picker the TUI half renders remote/bridge.ts
14
+ * • the status widget → child-status.ts, which drives widget.ts
14
15
  * • the plan file (.pi-tasks/TASK_PLAN_NNNN.md) → task-io.ts
15
16
  * • the handoff itself → orchestrator.ts
16
17
  *
17
18
  * The handoff is deliberately the SAME call /task makes for a typed prompt —
18
19
  * gated when `verify work` / `enforce guidelines` is on, fire-and-forget
19
- * otherwise — so a planned task is not a second kind of task. The only thing
20
- * /task receives that a bare /task would not is the decisions block.
20
+ * otherwise — so a planned task is not a second kind of task. What /task
21
+ * receives beyond a bare /task is HANDOFF_DELIVERABLE_RULE, which rides on every
22
+ * handoff, and the decisions block when anything was settled.
21
23
  */
22
24
  import type { ExtensionAPI, ExtensionCommandContext } from '@earendil-works/pi-coding-agent';
23
25
  import { type PlanSessionDeps, type PlanOutcome } from './plan-session.js';
@@ -4,20 +4,22 @@
4
4
  * The command is a thin wiring layer. Everything it does is already in the
5
5
  * codebase and is reused as-is:
6
6
  *
7
- * • the adaptive question loop, the duplicate backstop, the boxed picker and
8
- * the A/B answer mapping → plan-session.ts (which reuses parsers.ts,
9
- * question-dedup.ts, inline-markdown.ts,
10
- * question-box.ts, yolo.ts)
7
+ * • the question loop, the duplicate backstop and the A/B answer mapping
8
+ * → plan-session.ts, via question-source.ts (which
9
+ * uses parsers.ts and question-dedup.ts),
10
+ * question-dialog.ts, inline-markdown.ts, yolo.ts
11
11
  * • the child process, its loop/leak/stall guards and retries → child-runner.ts
12
- * • local TUI + remote browser prompt fan-out remote/bridge.ts
13
- * the status widget widget.ts
12
+ * • local TUI + remote browser prompt fan-out, and the boxed
13
+ * picker the TUI half renders remote/bridge.ts
14
+ * • the status widget → child-status.ts, which drives widget.ts
14
15
  * • the plan file (.pi-tasks/TASK_PLAN_NNNN.md) → task-io.ts
15
16
  * • the handoff itself → orchestrator.ts
16
17
  *
17
18
  * The handoff is deliberately the SAME call /task makes for a typed prompt —
18
19
  * gated when `verify work` / `enforce guidelines` is on, fire-and-forget
19
- * otherwise — so a planned task is not a second kind of task. The only thing
20
- * /task receives that a bare /task would not is the decisions block.
20
+ * otherwise — so a planned task is not a second kind of task. What /task
21
+ * receives beyond a bare /task is HANDOFF_DELIVERABLE_RULE, which rides on every
22
+ * handoff, and the decisions block when anything was settled.
21
23
  */
22
24
  import * as path from 'node:path';
23
25
  import { prependHint, USER_CANCELLED } from './child-runner.js';
@@ -93,8 +95,10 @@ export function buildPlanDeps(ctx, cwd, planId, task, signal) {
93
95
  });
94
96
  }
95
97
  finally {
96
- // Outside a git repo `before` is null and there is nothing to compare
97
- // against the same degrade every other tree-reading guard here takes.
98
+ // `before` is null only when the snapshot itself failed, and there
99
+ // is then nothing to compare against. A non-repo cwd does NOT take
100
+ // that path: `git status` exits 128 and collectTreeChanges answers an
101
+ // empty summary, so the comparison runs and finds nothing.
98
102
  if (before) {
99
103
  const after = await collectTreeChanges(cwd, signal).catch(() => null);
100
104
  const touched = after ? newTreeChanges(before, after) : null;
@@ -9,11 +9,12 @@
9
9
  * {@link parseClarifyList} parses this output UNCHANGED, and the boxed picker,
10
10
  * the duplicate backstop and the YOLO picker all work here with no new code.
11
11
  *
12
- * What differs is the JOB. /task-auto's clarify asks what changes how a feature is
13
- * SPLIT INTO TASKS; every question it asks is about plan shape, ordering, and which
14
- * subsystems are in or out. /task-plan is planning a single unit of work that /task
15
- * will implement in one run, so a "how do we split this" question is off-topic here
16
- * and the prompt below rules it out explicitly.
12
+ * What differs is the JOB. /task-auto's clarify asks for what most changes how a
13
+ * feature is SPLIT INTO TASKS scope boundaries, which subsystems are in or out,
14
+ * ordering, the cross-cutting choices that fork the breakdown. /task-plan is
15
+ * planning a single unit of work that /task will implement in one run, so a "how
16
+ * do we split this" question is off-topic here, and the SCOPE RULES below rule it
17
+ * out explicitly.
17
18
  */
18
19
  /**
19
20
  * Ask the SINGLE most important remaining question about ONE task.
@@ -9,11 +9,12 @@
9
9
  * {@link parseClarifyList} parses this output UNCHANGED, and the boxed picker,
10
10
  * the duplicate backstop and the YOLO picker all work here with no new code.
11
11
  *
12
- * What differs is the JOB. /task-auto's clarify asks what changes how a feature is
13
- * SPLIT INTO TASKS; every question it asks is about plan shape, ordering, and which
14
- * subsystems are in or out. /task-plan is planning a single unit of work that /task
15
- * will implement in one run, so a "how do we split this" question is off-topic here
16
- * and the prompt below rules it out explicitly.
12
+ * What differs is the JOB. /task-auto's clarify asks for what most changes how a
13
+ * feature is SPLIT INTO TASKS scope boundaries, which subsystems are in or out,
14
+ * ordering, the cross-cutting choices that fork the breakdown. /task-plan is
15
+ * planning a single unit of work that /task will implement in one run, so a "how
16
+ * do we split this" question is off-topic here, and the SCOPE RULES below rule it
17
+ * out explicitly.
17
18
  */
18
19
  /**
19
20
  * Ask the SINGLE most important remaining question about ONE task.
@@ -11,9 +11,8 @@
11
11
  *
12
12
  * PREVENTION — the planning children run with {@link PLAN_TOOLS}, an allowlist
13
13
  * of exactly one tool. pi applies `--tools` to built-in, extension AND custom
14
- * tools, so a write tool contributed by a whitelisted extension is excluded too
15
- * (proven live — scripts/live-task-plan-readonly.ts). This is what actually
16
- * makes the session read-only.
14
+ * tools, so a write tool contributed by a whitelisted extension is excluded
15
+ * too. This is what actually makes the session read-only.
17
16
  *
18
17
  * VERIFICATION — after every child, the working tree is compared against the
19
18
  * snapshot taken before it. `.pi-tasks/` is excluded (that is where the plan
@@ -29,8 +28,8 @@ import type { TreeChangeSummary } from './write-guard.js';
29
28
  *
30
29
  * Deliberately a named constant with a test pinning it (plan-readonly.test.ts):
31
30
  * widening this string is the single edit that would end the read-only guarantee,
32
- * and it should never happen by accident. The same value grill and clarify use
33
- * for their generation children planning has never needed more.
31
+ * and it should never happen by accident. The same value the grill-gen and
32
+ * auto-clarify children run under.
34
33
  */
35
34
  export declare const PLAN_TOOLS = "read";
36
35
  /**
@@ -11,9 +11,8 @@
11
11
  *
12
12
  * PREVENTION — the planning children run with {@link PLAN_TOOLS}, an allowlist
13
13
  * of exactly one tool. pi applies `--tools` to built-in, extension AND custom
14
- * tools, so a write tool contributed by a whitelisted extension is excluded too
15
- * (proven live — scripts/live-task-plan-readonly.ts). This is what actually
16
- * makes the session read-only.
14
+ * tools, so a write tool contributed by a whitelisted extension is excluded
15
+ * too. This is what actually makes the session read-only.
17
16
  *
18
17
  * VERIFICATION — after every child, the working tree is compared against the
19
18
  * snapshot taken before it. `.pi-tasks/` is excluded (that is where the plan
@@ -28,8 +27,8 @@
28
27
  *
29
28
  * Deliberately a named constant with a test pinning it (plan-readonly.test.ts):
30
29
  * widening this string is the single edit that would end the read-only guarantee,
31
- * and it should never happen by accident. The same value grill and clarify use
32
- * for their generation children planning has never needed more.
30
+ * and it should never happen by accident. The same value the grill-gen and
31
+ * auto-clarify children run under.
33
32
  */
34
33
  export const PLAN_TOOLS = 'read';
35
34
  /**
@@ -1,31 +1,20 @@
1
1
  /**
2
- * What the PLAN-SHAPING loops record, and the decisions that record makes.
2
+ * What the PLAN-SHAPING loop records, and the decisions that record makes.
3
3
  *
4
- * `GateTally`'s and `AutofixLedger`'s twin, one phase earlier. CONTEXT.md records
5
- * that shape twice already: a long loop threading mutable locals by closure, with
6
- * pure helpers extracted for testability while the ORDERING and CARRY-FORWARD
7
- * decisions stayed in the caller. `coverPlan` was the third instance — five locals
8
- * (`planTitles`, `best`, `round`, `roundCap`, `bonusRoundUsed`) plus a
9
- * snapshot-before-overwrite pair (`priorCovered`, `priorMissing`) that existed
10
- * ONLY because the bonus-round decision was made downstream from the evidence it
11
- * needed, so the loop had to save a copy of `best` before replacing it.
4
+ * `GateTally`'s and `AutofixLedger`'s twin, one phase earlier: the ORDERING and
5
+ * CARRY-FORWARD decisions live in the record, not in the caller's locals.
12
6
  *
13
- * The last real bug here says the shape out loud, in the loop's own comment:
14
- * *"This used to be two assignments, and the second one kept the OLD plan's
15
- * accounting whenever the new plan's coverage-map child faulted
16
- * (`cand.accounting ?? accounting`) binding requirements to titles they were
17
- * never mapped against."* `AutofixLedger`'s indictment, verbatim: the decision was
18
- * made downstream from the evidence.
7
+ * `consider` compares, replaces the plan WHOLE (`ScoredPlan` titles and
8
+ * accounting together, because they are one value), and grants the bonus round IN
9
+ * THE SAME CALL that adopts the way `AutofixLedger.judge(outcome, edited)`
10
+ * enters the demoted signature in the call that decides to demote. A caller
11
+ * cannot hold a pre-adoption snapshot that the replacement has already
12
+ * invalidated, because it never takes one.
19
13
  *
20
- * `consider` closes it by construction rather than by comment. It compares, it
21
- * replaces the plan WHOLE (titles and accounting together, because they are one
22
- * value), and it grants the bonus round IN THE SAME CALL that adopts — the way
23
- * `judge(outcome, edited)` enters the demoted signature in the call that demotes.
24
- * There is no window in which the snapshot and the replacement can disagree.
25
- *
26
- * NO I/O. No `logPlanDebug`, no notify, no child — for the same reason `GateTally`
27
- * performs none: a record that performs effects cannot be driven by a test that
28
- * only wants the verdict. The caller trails what the returned decision says.
14
+ * NO I/O. No `logPlanDebug`, no notify, no child the same reason `GateTally`
15
+ * performs none (it imports two types and nothing else): a record that performs
16
+ * effects cannot be driven by a test that only wants the verdict. The caller
17
+ * trails what the returned decision says.
29
18
  */
30
19
  import { type AdoptionDecision, type ScoredPlan } from './coverage-loop.js';
31
20
  /** What `consider` did with a candidate, and why. */
@@ -42,17 +31,16 @@ export interface CoverageLedgerOptions {
42
31
  /**
43
32
  * Are there grounded requirements to judge against?
44
33
  *
45
- * Without them `missing` is pure holistic-judge free text that can change every
46
- * round, so there is no trustworthy "grew"/"new" signalwhich is why the
47
- * bonus round is requirements-path only.
34
+ * Without them `covered` is built by `groundedCoverage` over an EMPTY quote
35
+ * list, so it is empty every round and can never grow the bonus round's own
36
+ * growth guard could not fire anyway. This flag says so up front instead of
37
+ * relying on that, and keeps the grant on the requirements path.
48
38
  */
49
39
  hasRequirements: boolean;
50
40
  }
51
41
  /**
52
42
  * The coverage loop's record: the best plan seen, the rounds spent, and the
53
43
  * one-shot bonus round.
54
- *
55
- * Methods are named for what they MEAN, not for the field they touch.
56
44
  */
57
45
  export declare class CoverageLedger {
58
46
  private _best;
@@ -1,38 +1,25 @@
1
1
  /**
2
- * What the PLAN-SHAPING loops record, and the decisions that record makes.
2
+ * What the PLAN-SHAPING loop records, and the decisions that record makes.
3
3
  *
4
- * `GateTally`'s and `AutofixLedger`'s twin, one phase earlier. CONTEXT.md records
5
- * that shape twice already: a long loop threading mutable locals by closure, with
6
- * pure helpers extracted for testability while the ORDERING and CARRY-FORWARD
7
- * decisions stayed in the caller. `coverPlan` was the third instance — five locals
8
- * (`planTitles`, `best`, `round`, `roundCap`, `bonusRoundUsed`) plus a
9
- * snapshot-before-overwrite pair (`priorCovered`, `priorMissing`) that existed
10
- * ONLY because the bonus-round decision was made downstream from the evidence it
11
- * needed, so the loop had to save a copy of `best` before replacing it.
4
+ * `GateTally`'s and `AutofixLedger`'s twin, one phase earlier: the ORDERING and
5
+ * CARRY-FORWARD decisions live in the record, not in the caller's locals.
12
6
  *
13
- * The last real bug here says the shape out loud, in the loop's own comment:
14
- * *"This used to be two assignments, and the second one kept the OLD plan's
15
- * accounting whenever the new plan's coverage-map child faulted
16
- * (`cand.accounting ?? accounting`) binding requirements to titles they were
17
- * never mapped against."* `AutofixLedger`'s indictment, verbatim: the decision was
18
- * made downstream from the evidence.
7
+ * `consider` compares, replaces the plan WHOLE (`ScoredPlan` titles and
8
+ * accounting together, because they are one value), and grants the bonus round IN
9
+ * THE SAME CALL that adopts the way `AutofixLedger.judge(outcome, edited)`
10
+ * enters the demoted signature in the call that decides to demote. A caller
11
+ * cannot hold a pre-adoption snapshot that the replacement has already
12
+ * invalidated, because it never takes one.
19
13
  *
20
- * `consider` closes it by construction rather than by comment. It compares, it
21
- * replaces the plan WHOLE (titles and accounting together, because they are one
22
- * value), and it grants the bonus round IN THE SAME CALL that adopts — the way
23
- * `judge(outcome, edited)` enters the demoted signature in the call that demotes.
24
- * There is no window in which the snapshot and the replacement can disagree.
25
- *
26
- * NO I/O. No `logPlanDebug`, no notify, no child — for the same reason `GateTally`
27
- * performs none: a record that performs effects cannot be driven by a test that
28
- * only wants the verdict. The caller trails what the returned decision says.
14
+ * NO I/O. No `logPlanDebug`, no notify, no child the same reason `GateTally`
15
+ * performs none (it imports two types and nothing else): a record that performs
16
+ * effects cannot be driven by a test that only wants the verdict. The caller
17
+ * trails what the returned decision says.
29
18
  */
30
19
  import { decideAdoption, normMissingArea } from './coverage-loop.js';
31
20
  /**
32
21
  * The coverage loop's record: the best plan seen, the rounds spent, and the
33
22
  * one-shot bonus round.
34
- *
35
- * Methods are named for what they MEAN, not for the field they touch.
36
23
  */
37
24
  export class CoverageLedger {
38
25
  _best;
@@ -82,8 +69,8 @@ export class CoverageLedger {
82
69
  return { adopted: false, decision, grantedBonusRound: false };
83
70
  const priorCovered = this._best.plan.covered.size;
84
71
  const priorMissing = new Set(this._best.plan.missing.map(normMissingArea));
85
- // WHOLE, titles and accounting together. They are one value; splitting them
86
- // is a bug this codebase has already had.
72
+ // WHOLE, titles and accounting together one assignment, so the two can
73
+ // never come from different rounds.
87
74
  this._best = cand;
88
75
  const grant = !this._bonusUsed
89
76
  && this._round >= this._cap
@@ -97,9 +84,9 @@ export class CoverageLedger {
97
84
  return { adopted: true, decision, grantedBonusRound: grant };
98
85
  }
99
86
  }
100
- // DECOMPOSE's two retry budgets (`emptyAttempts`, `smallRetryUsed`) are NOT here.
101
- // They look like this shape and are not: that loop keys on `isSuspectPlan`, a
102
- // predicate over the SPEC LENGTH rather than a title-count floor, and its two
103
- // counters already sit inside a nine-line comment explaining why a single counter
104
- // was wrong. Wrapping them in a class that does not model `isSuspectPlan` would
105
- // move the code without concentrating the decision.
87
+ // DECOMPOSE's two retry budgets (`emptyAttempts`, `smallRetryUsed` in
88
+ // auto-orchestrator.ts) are NOT here. They look like this shape and are not: that
89
+ // loop keys on `isSuspectPlan`, which combines a title-count ceiling with a
90
+ // minimum SPEC LENGTH, and its two counters carry their own comment on why a
91
+ // single counter was wrong. Wrapping them in a class that does not model
92
+ // `isSuspectPlan` would move the code without concentrating the decision.
@@ -1,31 +1,29 @@
1
1
  /**
2
2
  * The /task-plan interaction loop.
3
3
  *
4
- * Sequential & adaptive, exactly like /task's grill (phases.ts `phaseGrill`) and
5
- * /task-auto's clarify (auto-orchestrator.ts `planAuto`): ask ONE question at a
6
- * time, feed every answer back into the next generation call so later questions
7
- * react to earlier ones, and stop when the model emits NONE. The duplicate
8
- * backstop (`isDuplicateQuestion` + `DUP_REPROMPT_HINT` + `MAX_DUP_STRIKES`), the
9
- * markdown handling, the A/B answer-letter mapping and the YOLO policy are the
10
- * SAME modules those two loops use none of that is new here.
4
+ * Sequential and adaptive: ask ONE question at a time, feed the whole transcript
5
+ * back into the next generation call so later questions react to earlier answers,
6
+ * and stop when the model emits NONE. Generation, the question cap and the
7
+ * duplicate backstop live in question-source.ts; the answer cards and the A/B
8
+ * letter mapping in question-dialog.ts; markdown in inline-markdown.ts; the
9
+ * unattended policy in yolo.ts. /task's grill (phases.ts `phaseGrill`) and
10
+ * /task-auto's clarify (auto-orchestrator.ts `planAuto`) drive the same modules.
11
11
  *
12
- * What IS new is the control surface. In grill and clarify the user's only move is
13
- * to answer the question in front of them. Here three moves are available at every
14
- * single prompt, in that order of appearance:
12
+ * What this loop adds is the control surface. Grill and clarify let the user only
13
+ * answer the question in front of them. Here three moves are on every prompt, in
14
+ * this order of appearance:
15
15
  *
16
16
  * ❓ ask the model a question — the user asks, the model answers (PLAN_ASK)
17
- * ✎ answer in your own words — the free-text card askQuestionBox already
18
- * appends to every boxed picker; it is not new,
19
- * it is simply always present here, and it
20
- * doubles as "state a decision" when the model
21
- * has nothing to ask
17
+ * ✎ answer in your own words — the free-text card askQuestionBox appends to
18
+ * every boxed picker. It doubles as "state a
19
+ * decision" when the model has nothing to ask.
22
20
  * ▶ proceed to execution — stop planning, hand the decisions to /task
23
21
  * (PLAN_PROCEED). Always the LAST card in the
24
22
  * box — it ends the session, so it sits under
25
23
  * every move that continues it, including the
26
24
  * free-text card (see `manualPosition`).
27
25
  *
28
- * The loop is pure with respect to I/O: every side effect (child calls, dialogs,
26
+ * The loop performs no I/O of its own: every side effect (child calls, dialogs,
29
27
  * persistence) arrives through {@link PlanSessionDeps}, so the whole interaction
30
28
  * is unit-testable without a TUI or a model.
31
29
  */
@@ -37,8 +35,8 @@ export { resolveAnswer } from './question-dialog.js';
37
35
  export type { PendingQuestion } from './question-dialog.js';
38
36
  /**
39
37
  * Sentinel values the picker resolves to when the user takes a control action
40
- * instead of answering. Deliberately shaped like the existing `USER_CANCELLED`
41
- * sentinel (child-runner.ts): a value no model answer and no human ever types.
38
+ * instead of answering. Same shape as `USER_CANCELLED` (child-runner.ts): a
39
+ * value no model answer and no human ever types.
42
40
  */
43
41
  export declare const PLAN_ASK = "__plan_ask__";
44
42
  export declare const PLAN_PROCEED = "__plan_proceed__";
@@ -52,99 +50,86 @@ export declare const PLAN_STATE_LABEL = "\u270E Add a decision of your own\u2026
52
50
  export declare const PLAN_NO_QUESTIONS = "No further questions \u2014 the decisions so far settle how this task is built.";
53
51
  /**
54
52
  * Hard ceiling on model-generated questions for one plan. The loop is open-ended
55
- * (it stops when the model emits NONE); this only bounds a model that never
56
- * does. Matches /task-auto's MAX_CLARIFY_QUESTIONS, for the same reason.
53
+ * it stops when the model emits NONE — so this only bounds a model that never
54
+ * does. Same value as /task-auto's MAX_CLARIFY_QUESTIONS.
57
55
  */
58
56
  export declare const MAX_PLAN_QUESTIONS = 8;
59
57
  /**
60
58
  * Corrective re-prompt for a question reply that did not follow the format —
61
- * either nothing parseable at all, or a question with no `SUGGESTED:` line. Same
62
- * shape and same one-shot budget as GRILL_AUTO_FORMAT_HINT (prompts.ts), which
63
- * exists because the local model drops a required tag every so often and a
64
- * silent fallback is worse than one extra call: an unparsed reply reads as "no
65
- * questions left" and a missing SUGGESTED leaves the picker with nothing to
66
- * recommend.
59
+ * either nothing the parser could read, or a question with no `SUGGESTED:` line.
60
+ * Same shape and same one-shot budget as GRILL_AUTO_FORMAT_HINT (prompts.ts).
61
+ *
62
+ * Both failures are silent without it. `makeQuestionSource` answers `exhausted`
63
+ * for a reply it cannot parse, which this loop renders as "no further questions";
64
+ * and a question with no SUGGESTED reaches `buildOptionCards` with nothing to
65
+ * build a card from.
67
66
  */
68
67
  export declare const PLAN_FORMAT_HINT: string;
69
68
  export { isNoneReply, pickQuestion } from './question-source.js';
70
69
  /**
71
70
  * Does the question offer the user a choice between two named alternatives?
72
- * Deliberately shallow an "X or Y?" in the question's own clause.
71
+ * Deliberately shallow: an `or` anywhere before the first question mark.
73
72
  */
74
73
  export declare function looksLikeFork(question: string): boolean;
75
74
  /**
76
75
  * Does the recommended default DEFER the decision instead of making one?
77
76
  *
78
- * The prompt asks for a "concrete, decisive default", and nothing enforced it.
79
- * Live (aiz-client TASK_PLAN_0001, 2026-08-05): the model asked "what specific
80
- * report should this new tab display?" and recommended
81
- * "clarify with the user what the report is meant to show before proceeding".
82
- * The user pressed enter, so it was recorded `(accepted recommendation)` and rode
83
- * into /task's handoff as an AUTHORITATIVE decision — an order not to proceed,
84
- * addressed to a run where no user exists. /task duly built a task whose
85
- * ACCEPTANCE was "a planning document with placeholder sections" and whose VERIFY
86
- * asserted that no source file had changed.
87
- *
88
77
  * A deferral is not an answer, and the one place it can never be one is here: the
89
78
  * user IS present during planning, so "ask the user" is a null move — that IS the
90
- * question. Detection is anchored to the START of the default, which keeps it off
91
- * legitimate product behaviour ("prompt the user to confirm deletion" decides
92
- * something; "ask the user which report" decides nothing).
79
+ * question. An accepted recommendation is a `decision` entry, so it rides into
80
+ * /task's handoff inside the block `buildHandoffPrompt` (plan-io.ts) labels
81
+ * authoritative addressed to a run where no user exists.
82
+ *
83
+ * Every pattern is anchored to the START of the default, which keeps it off
84
+ * legitimate product behaviour: "prompt the user to confirm deletion" decides
85
+ * something and does not match; "ask the user which report" decides nothing and
86
+ * does.
93
87
  */
94
88
  export declare function isDeferralSuggestion(suggested: string): boolean;
95
89
  /**
96
- * Corrective re-prompt for a default that deferred the decision. Same one-shot
97
- * budget and same quote-it-back shape as {@link planForkHint}, because the child
98
- * is stateless and cannot otherwise know what it just recommended.
90
+ * Corrective re-prompt for a default that deferred the decision. Quotes the
91
+ * question and the default back, because the child is a fresh process carrying
92
+ * only its prompt and cannot otherwise know what it just recommended.
99
93
  */
100
94
  export declare function planDecisiveHint(question: string, suggested: string): string;
101
95
  /**
102
96
  * Corrective re-prompt for a fork-shaped question that shipped only ONE option.
97
+ * With no ALT, `buildOptionCards` emits a single card, so the user has to type
98
+ * out the alternative the model itself just named.
103
99
  *
104
- * Measured on the local model (scripts/live-task-plan-step0.ts, 15 reps): the
105
- * SUGGESTED line is always there, but 10/15 questions named two alternatives and
106
- * gave only one of them so the picker showed a single card and the user had to
107
- * type out the option the model itself had just proposed.
108
- *
109
- * The retry quotes the question back because the child is stateless (a fresh
110
- * process per call, prompt only), so it cannot otherwise know what it just wrote.
111
- * Validated before wiring (scripts/live-task-plan-fork-alt.ts): 6/6 fires
112
- * recovered an ALT, and 6/6 re-asked the SAME question rather than changing the
113
- * subject. It costs one extra child call on the questions where it fires.
100
+ * The retry quotes the question back because the child is a fresh process
101
+ * carrying only its prompt, so it cannot otherwise know what it just wrote. It
102
+ * costs one extra child call on the questions where it fires.
114
103
  */
115
104
  export declare function planForkHint(question: string): string;
116
105
  /**
117
106
  * PLAN's quality rules, in order.
118
107
  *
119
- * Each is worth exactly one corrective re-prompt (the child is stateless, so each
120
- * hint quotes the question back), and each DEGRADES rather than discards when the
121
- * defect survives a question with a weak default still beats no question.
108
+ * The corrective-re-prompt budget is per QUESTION and shared across the whole
109
+ * table (question-source.ts): at most one rule fires per draw, and a defect that
110
+ * survives its re-prompt DEGRADES through `repair` rather than discarding the
111
+ * question — a weak default still beats no question. Each hint quotes the
112
+ * question back, because the child is a fresh process carrying only its prompt.
122
113
  *
123
114
  * Only {@link CLARIFY_QUALITY_RULES} is shared with `/task-auto`, and only the
124
- * deferral rule is in it. The other two were MEASURED here (10/15 fork-shaped
125
- * questions shipped one option; the SUGGESTED requirement is in both prompts) but
126
- * each costs one extra child call every time it fires, and clarify is the most
127
- * A/B'd path in the codebase — moving them there is its own experiment, not a
128
- * side effect of sharing a state machine. Recorded rather than done.
115
+ * deferral rule is in it. The other two cost an extra child call every time they
116
+ * fire.
129
117
  */
130
118
  export declare const PLAN_QUALITY_RULES: ReadonlyArray<QuestionRule>;
131
119
  /**
132
120
  * The deferral rule alone — the one clarify shares.
133
121
  *
134
- * It exists because an accepted "clarify with the user before proceeding" rode
135
- * into `/task`'s handoff AS AN AUTHORITATIVE DECISION and produced a task whose
136
- * ACCEPTANCE was "a planning document with placeholder sections" and whose VERIFY
137
- * asserted that no source file had changed. Clarify's answers ride into the
138
- * decompose prompt and the AUTO file with exactly the same authority and had no
139
- * guard at all — the same bug, one command over, waiting.
122
+ * Clarify's answers ride into the decompose prompt and the AUTO file with the
123
+ * same authority /task-plan's decisions ride into the handoff, so an accepted
124
+ * "clarify with the user before proceeding" lands there as an instruction too.
140
125
  *
141
126
  * It is also the only one of the three that costs nothing on the happy path: a
142
127
  * decisive default never triggers it.
143
128
  */
144
129
  export declare const CLARIFY_QUALITY_RULES: ReadonlyArray<QuestionRule>;
145
- /** The ask spec the session hands to the UI: an {@link AskSpec} plus the picker
146
- * entries. Kept structurally identical to what phaseGrill/planAuto build so the
147
- * same SessionUI.ask serves all three. */
130
+ /** The ask spec the session hands to the UI: an {@link AskSpec} whose optional
131
+ * picker fields are all required here. The same SessionUI.ask serves grill,
132
+ * clarify and this loop. */
148
133
  export type PlanAskSpec = AskSpec & {
149
134
  options: {
150
135
  label: string;
@@ -158,7 +143,8 @@ export type PlanAskSpec = AskSpec & {
158
143
  }[];
159
144
  };
160
145
  export interface PlanSessionDeps {
161
- /** Run the question-generation child. `hint` is the duplicate reprompt. */
146
+ /** Run the question-generation child. `hint` is whatever corrective
147
+ * re-prompt question-source.ts chose, or null. */
162
148
  generateQuestion(priorQA: string, hint: string | null): Promise<string>;
163
149
  /** Run the child that answers a question the USER asked. */
164
150
  answerUserQuestion(priorQA: string, question: string): Promise<string>;
@@ -173,7 +159,7 @@ export interface PlanSessionDeps {
173
159
  onEntries?(entries: readonly PlanEntry[]): void | Promise<void>;
174
160
  /** Theme-aware markdown renderer for displayed text; identity when absent. */
175
161
  renderMarkdown?(text: string): string;
176
- /** Status line while a child runs (the widget's `lastLine`). */
162
+ /** Status line while a child runs. */
177
163
  setStatus?(line: string | undefined): void;
178
164
  yolo?: boolean;
179
165
  logDebug?(msg: string): void;