@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
@@ -43,20 +43,18 @@ export interface LintFixDeps {
43
43
  */
44
44
  introducedBy?: (rel: string) => Promise<string | null>;
45
45
  /**
46
- * Debug-log sink. This dep did not exist, so all four of this pass's guard
47
- * trips were invisible in the trail while the twin (`FinalFixDeps.log`) logged
48
- * three of its own — and a guard whose firing leaves no record cannot be
49
- * distinguished from one that never armed.
46
+ * Debug-log sink. Every guard below logs its own trip through it: a guard whose
47
+ * firing leaves no record cannot be distinguished from one that never armed.
50
48
  */
51
49
  log?: (msg: string) => void;
52
50
  }
53
51
  /** The fix child edits and runs the checker; bash exists to RUN the check, not git. */
54
52
  export declare const LINT_FIX_TOOLS = "read,edit,bash";
55
53
  /**
56
- * Build the fix child's prompt. The constraints encode both live findings: smallest
57
- * edits only (the impl re-run's rewrite habit is the defect this pass replaces), and
58
- * an explicit ban on discarding work (both validation runs reached green via
59
- * `git checkout` of the work file until the guard existed).
54
+ * Build the fix child's prompt. Two constraints carry the design: smallest edits
55
+ * only the re-run's rewrite habit is the defect this pass replaces and an
56
+ * explicit ban on discarding work, which is the cheapest route to a green check and
57
+ * exactly what the revert-guard exists to catch.
60
58
  */
61
59
  export declare function buildLintFixPrompt(failReason: string, frozenPaths?: string[]): string;
62
60
  /**
@@ -1,17 +1,16 @@
1
1
  /**
2
2
  * lint-fix — the bounded, graduated resolution for a repo-health verify FAIL.
3
3
  *
4
- * The failure this closes (mx5 run 3, TASK_0017): AUTOFIX's only hammer is a FULL
5
- * implementation re-run. For a repo-health FAIL of 10 trivial lint findings the live
6
- * run burned two 36–56-minute impl turns, each REGENERATING a fresh 900-line rewrite
7
- * that failed lint differently the loop cannot converge because the tool is bigger
8
- * than the defect. Validated live on the real TASK_0017 tree: a bounded fix child
9
- * (read,edit,bash) reached lint-clean in 64s and 106s, 2/2.
4
+ * WHY A SEPARATE PASS. AUTOFIX's only hammer is a FULL implementation re-run. For a
5
+ * repo-health FAIL of a few trivial lint findings the re-run REGENERATES the work
6
+ * rather than editing it, and fresh output fails lint differently the loop cannot
7
+ * converge because the tool is bigger than the defect. A bounded fix child
8
+ * (read,edit,bash) edits only the findings.
10
9
  *
11
- * The same validation caught the design's failure mode: BOTH runs cheated, running
12
- * `git checkout -- src/test/request.ts` REVERTING the task's uncommitted work to
13
- * make the findings vanish. So this pass ships with a deterministic REVERT-GUARD,
14
- * outcome-based (command filtering can't catch every path to the same effect):
10
+ * REVERT-GUARD. A fix child can reach lint-clean by DISCARDING the task's
11
+ * uncommitted work: `git checkout -- <the work file>` makes every finding vanish.
12
+ * The prompt forbids it, but the guard is outcome-based, because command filtering
13
+ * cannot catch every path to the same effect:
15
14
  *
16
15
  * - Before the child runs: snapshot the full working state (`git add -A` +
17
16
  * `git write-tree`, then unstage) and record which files differ from HEAD.
@@ -28,34 +27,38 @@
28
27
  * recommend → AUTOFIX/ACCEPT/dismiss picker, so this pass can only make the loop
29
28
  * faster, never change what it can decide.
30
29
  *
31
- * FROZEN-PATH GUARD (mx5 run 12, TASK_0021/0022): the checker's own error text
32
- * can INSTRUCT an edit to a spec-frozen file (typed ESLint: "playwright/index.ts
33
- * was not found by the project … Consider either including it in the
34
- * tsconfig.json") and this child complies — while the task's spec froze
35
- * `tsconfig.json` and verify's rule-4b prohibition probe then fails the TASK for
36
- * the gate child's edit. Two gates, contradictory rules, same file; the loop
37
- * never converges (live: TASK_0021 burned all three unattended AUTOFIX rounds).
38
- * Prompt framing alone is A/B-proven ~0–1/5 on the weak model (see
39
- * frozen-path-guard.ts), so the deny is mechanical: the spec's frozen paths are
30
+ * FROZEN-PATH GUARD. The checker's own error text can INSTRUCT an edit to a
31
+ * spec-frozen file. Typed ESLint, asked to lint a file outside the tsconfig
32
+ * `include`, prints:
33
+ *
34
+ * Parsing error: <file> was not found by the project service. Consider either
35
+ * including it in the tsconfig.json or including it in allowDefaultProject.
36
+ *
37
+ * A child that complies edits `tsconfig.json`. If the task's spec froze that file,
38
+ * verify's prohibition probe raises rule 4b "SPEC PROHIBITIONS ARE PART OF THE
39
+ * BAR — YOU HAVE NO WAIVER AUTHORITY" — and FAILs the TASK for the gate child's
40
+ * edit. Two gates, contradictory rules, same file; the loop never converges.
41
+ *
42
+ * So the deny is mechanical rather than framing: the spec's frozen paths are
40
43
  * threaded in via `frozenPaths`, injected into the prompt as a do-not-touch list
41
- * (belt), and any frozen path the child still changed is deterministically
42
- * reverted post-child and the fix reported not-applied (suspenders). Only paths
43
- * that were CLEAN before the child ran are reverted — a frozen path already
44
- * dirty with (possibly task) work is left alone, in the guard's safe direction:
45
- * cost time, never work.
44
+ * (belt), and any frozen path the child still changed is deterministically reverted
45
+ * post-child and the fix reported not-applied (suspenders). Only paths that were
46
+ * CLEAN before the child ran are reverted — a frozen path already dirty with
47
+ * (possibly task) work is left alone, in the guard's safe direction: cost time,
48
+ * never work.
46
49
  *
47
- * CROSS-TASK DELETION GUARD (mx5 run 12 PROMPT 2, verify-debug.log 17:53:44): the
48
- * revert-guard above is outcome-based but blind to a CLEAN tracked file a
49
- * sibling task's committed deliverable is neither pre-dirty nor pre-untracked, so
50
- * DELETING it slips both checks, and if the lint converges the pass returns ok
51
- * (confirmed live: the child deleted TASK_0020's playwright ct files to green a
52
- * typed-lint it was frozen out of fixing properly). The discriminator is
53
- * PROVENANCE, not deletion per se: a tracked file the CHILD deleted whose
54
- * introducing task (per `introducedBy`, git history) differs from the CURRENT
50
+ * CROSS-TASK DELETION GUARD. The revert-guard above is outcome-based but blind to a
51
+ * CLEAN tracked file. Delete one and `git status --porcelain` reports ` D <path>`
52
+ * while it appears in NEITHER of the guard's two lists: it was not pre-dirty (it
53
+ * matched HEAD) and not pre-untracked (it is tracked). If the lint then converges,
54
+ * the pass returns ok having destroyed a sibling task's committed deliverable. The
55
+ * discriminator is PROVENANCE, not deletion per se: a tracked file the CHILD deleted
56
+ * whose introducing task (per `introducedBy`, git history) differs from the CURRENT
55
57
  * task is restored from HEAD and the fix reported not-applied naming the owner.
56
- * Same-task deletions, unknown provenance, relocations, and any git error all
57
- * step aside the guard may only cost time, never work. Armed only when both
58
- * `currentTaskId` and `introducedBy` are wired.
58
+ * Same-task deletions, unknown provenance, relocations (a deletion whose basename
59
+ * reappears among the added paths) and any git error all step aside the guard may
60
+ * only cost time, never work. Armed only when both `currentTaskId` and
61
+ * `introducedBy` are wired.
59
62
  */
60
63
  import { parseChangedFrozenFiles, pathNamedIn, revertFrozenPaths } from './frozen-path-guard.js';
61
64
  import { runFixChild } from './fix-child.js';
@@ -64,10 +67,10 @@ import { findCrossTaskDeletions } from './task-provenance.js';
64
67
  /** The fix child edits and runs the checker; bash exists to RUN the check, not git. */
65
68
  export const LINT_FIX_TOOLS = 'read,edit,bash';
66
69
  /**
67
- * Build the fix child's prompt. The constraints encode both live findings: smallest
68
- * edits only (the impl re-run's rewrite habit is the defect this pass replaces), and
69
- * an explicit ban on discarding work (both validation runs reached green via
70
- * `git checkout` of the work file until the guard existed).
70
+ * Build the fix child's prompt. Two constraints carry the design: smallest edits
71
+ * only the re-run's rewrite habit is the defect this pass replaces and an
72
+ * explicit ban on discarding work, which is the cheapest route to a green check and
73
+ * exactly what the revert-guard exists to catch.
71
74
  */
72
75
  export function buildLintFixPrompt(failReason, frozenPaths = []) {
73
76
  const frozenBlock = frozenPaths.length === 0 ?
@@ -123,7 +126,7 @@ export function revertGuardViolations(preDirty, stillDirty) {
123
126
  const EXCLUDE_TASKS_DIR = ':(exclude).pi-tasks';
124
127
  /**
125
128
  * Files differing from HEAD, or null when git itself failed. The distinction is
126
- * load-bearing: mx5 run 4 rolled back two GOOD converged fixes because a git
129
+ * load-bearing: without it a run rolls back GOOD converged fixes because a git
127
130
  * failure after the child read as "[] files still dirty" → every pre-existing work
128
131
  * file looked reverted → false "discarded work". A git error is INCONCLUSIVE, not
129
132
  * evidence of destruction.
@@ -205,12 +208,10 @@ export async function runBoundedLintFix(deps) {
205
208
  // guard for this run (inconclusive ≠ evidence).
206
209
  const deletionGuardArmed = Boolean(deps.currentTaskId && deps.introducedBy);
207
210
  const preChanges = deletionGuardArmed ? await treeChanges(deps) : null;
208
- // The four-rung ladder lives in task/fix-child.ts. A cancel still propagates
209
- // (it THROWS, so the caller's USER_CANCELLED path is unchanged); what is new
210
- // here is the BLOCKED rung, which this pass instructed in its prompt and then
211
- // discarded the reply of — so a child that reported BLOCKED still paid the
212
- // whole guard stack and a repo-health re-run (15–69s measured) to be told
213
- // `did not converge`, instead of its own stated reason.
211
+ // The four-rung ladder lives in task/fix-child.ts: a cancel propagates as a
212
+ // THROW (so the caller's USER_CANCELLED path is unchanged), a child that threw
213
+ // for any other reason is `error`, a self-declared BLOCKED is `blocked`, and
214
+ // anything else is `done`.
214
215
  const end = await runFixChild({
215
216
  runChild: deps.runChild,
216
217
  tools: LINT_FIX_TOOLS,
@@ -228,10 +229,10 @@ export async function runBoundedLintFix(deps) {
228
229
  // where the twin consults its own.
229
230
  // REVERT-GUARD: every pre-existing work file must still differ from HEAD, and
230
231
  // every pre-existing untracked file must still exist. Trip → restore snapshot.
231
- // Every comparison requires git to have actually SUCCEEDED: a git error after
232
- // the child is inconclusive (proven live: it flagged the whole untracked file
233
- // list as "discarded" while the child had verifiably edited only lint findings)
234
- // — then the guard steps aside and the converge check below still decides.
232
+ // Every comparison requires git to have actually SUCCEEDED. A git error after
233
+ // the child reads as "nothing is dirty", which would flag every pre-existing
234
+ // work file as discarded inconclusive, not evidence. The guard then steps
235
+ // aside and the converge check below still decides.
235
236
  const stillDirtyList = await dirtyFiles(deps);
236
237
  let guardNote;
237
238
  const violations = [];
@@ -271,10 +272,9 @@ export async function runBoundedLintFix(deps) {
271
272
  }
272
273
  // CROSS-TASK DELETION GUARD: a tracked file the CHILD deleted whose
273
274
  // introducing task differs from the current task is a sibling's committed
274
- // deliverable destroyed to go green (mx5 run 12: the child deleted TASK_0020's
275
- // playwright ct files and the pass returned ok the revert-guard above only
276
- // watches pre-dirty and pre-untracked files, and a clean tracked sibling file
277
- // is neither). Restore JUST those paths from HEAD (they were clean pre-child,
275
+ // deliverable destroyed to go green. The revert-guard above only watches
276
+ // pre-dirty and pre-untracked files, and a clean tracked sibling file is
277
+ // neither. Restore JUST those paths from HEAD (they were clean pre-child,
278
278
  // so nothing of the task's work can be lost) and report not-applied naming the
279
279
  // owner. Inconclusive on any side — git error, unknown provenance, same-task
280
280
  // deletion, relocation — steps aside.
@@ -300,14 +300,13 @@ export async function runBoundedLintFix(deps) {
300
300
  }
301
301
  }
302
302
  }
303
- // FROZEN-PATH GUARD: a frozen path that was clean pre-child and is changed
304
- // now is the child's edit — the exact write verify's rule-4b prohibition
305
- // probe is guaranteed to fail the TASK for (mx5 run 12: ESLint's own error
306
- // text instructed the tsconfig.json edit and the child complied, 5/5 in the
307
- // live A/B). Revert JUST those paths (they were clean, so HEAD == pre-state:
308
- // no work can be lost) and report not-applied so the caller falls through to
309
- // the ordinary recommend → AUTOFIX/ACCEPT picker. Inconclusive git (either
310
- // side) → guard steps aside; the verify probe still catches what survives.
303
+ // FROZEN-PATH GUARD: a frozen path that was clean pre-child and is changed now
304
+ // is the child's edit — the exact write verify's rule-4b prohibition probe
305
+ // fails the TASK for. Revert JUST those paths (they were clean, so HEAD ==
306
+ // pre-state: no work can be lost) and report not-applied so the caller falls
307
+ // through to the ordinary recommend AUTOFIX/ACCEPT picker. Inconclusive git
308
+ // (either side) guard steps aside; the verify probe still catches what
309
+ // survives.
311
310
  if (preFrozenDirty !== null) {
312
311
  const postFrozenDirty = await frozenDirtySet(deps, frozen);
313
312
  if (postFrozenDirty !== null) {
@@ -341,18 +340,17 @@ export async function runBoundedLintFix(deps) {
341
340
  // while the child's edits sit in the working tree.
342
341
  //
343
342
  // So BLOCKED does not decide; it only supplies a better REASON when the check
344
- // agrees nothing converged. That was the durable half of the win. Skipping the
345
- // re-run was the other half, and it is not worth this.
343
+ // agrees nothing converged. Skipping the re-run on the marker alone is not
344
+ // worth that risk.
346
345
  const health = await deps.repoHealth();
347
346
  if (!health.ok) {
348
347
  if (end.kind === 'blocked') {
349
348
  return { ok: false, reason: `fix child blocked: ${end.note}` };
350
349
  }
351
- // FROZEN-PATH TRACE on non-convergence (PROMPT 1 layer B): when the child
352
- // was honest — it did NOT touch the frozen path, so the guard above never
353
- // tripped — but the check is still red and its own output NAMES a frozen
354
- // path (typed ESLint: "playwright/index.ts was not found by the project
355
- // consider including it in the tsconfig.json"), the findings can only be
350
+ // FROZEN-PATH TRACE on non-convergence: when the child was honest it did
351
+ // NOT touch the frozen path, so the guard above never tripped — but the
352
+ // check is still red and its own output NAMES a frozen path (the typed
353
+ // ESLint message quoted in this file's header), the findings can only be
356
354
  // fixed by an edit this task's spec forbids. Report it under the same
357
355
  // `frozen-path:` prefix as the guard trip, so the gate loop can route
358
356
  // straight to the human picker instead of burning unattended AUTOFIX
@@ -47,15 +47,16 @@ export declare class LoopDetector {
47
47
  /**
48
48
  * Count same-path calls in the window that are "revisits" — accesses that end
49
49
  * no further into the file than the furthest line already covered for that
50
- * path. Paging yields zero revisits and never trips; repeated whole-file
51
- * re-reads, backward jumps and path-targeting greps accumulate.
50
+ * path. The FIRST call on a path is therefore never a revisit: it sets the
51
+ * high-water mark. Paging yields zero revisits and never trips; repeated
52
+ * whole-file re-reads, backward jumps, narrower re-reads and repeated
53
+ * path-targeting greps all accumulate.
52
54
  *
53
- * The comparison is on the RANGE, not the offset. Offset alone scored a page
54
- * that re-asks from the same start with a bigger limit `{offset:80,
55
- * limit:400}` after `{offset:80, limit:300}`, real reads from a measured
56
- * decompose run as a revisit, even though it covers 100 lines the child had
57
- * never seen. That is the same mistake SingleReadGuard made by keying on the
58
- * path alone, and it is corrected the same way.
55
+ * The comparison is on the RANGE, not the offset. Keying on offset alone scores
56
+ * `{offset:80, limit:400}` after `{offset:80, limit:300}` as a revisit, even
57
+ * though it covers 100 lines the child has never seen. That is the same mistake
58
+ * SingleReadGuard made by keying on the path alone, and it is corrected the same
59
+ * way.
59
60
  */
60
61
  private countRevisits;
61
62
  }
@@ -52,7 +52,11 @@ function readOffset(args) {
52
52
  const o = args.offset;
53
53
  return typeof o === 'number' && Number.isFinite(o) ? o : 0;
54
54
  }
55
- /** Default `limit` pi's read tool applies when the call names none. */
55
+ /**
56
+ * pi's read tool truncates its output at `DEFAULT_MAX_LINES` lines (its
57
+ * `core/tools/truncate` module). A `limit` at or above that asks for as much as
58
+ * the tool will ever return, so it is treated the same as naming no limit at all.
59
+ */
56
60
  const DEFAULT_READ_LIMIT = 2000;
57
61
  /**
58
62
  * The last line a call reaches, so a page can be told from a re-read. Absent,
@@ -96,9 +100,8 @@ export class LoopDetector {
96
100
  if (exact >= this.threshold)
97
101
  return { call, count: exact, windowSize: this.buf.length };
98
102
  // 2. Path-aware loop: the same file re-targeted without forward progress.
99
- // Caught here precisely because varied offset/limit make the exact key
100
- // miss it (TASK_0017: auth.ts read/grepped ~12× with changing args until
101
- // the wall-clock timeout, never tripping the exact detector).
103
+ // Caught here precisely because varied offset/limit change the exact key on
104
+ // every call, so pattern 1 above can never see it.
102
105
  const path = this.buf[this.buf.length - 1].path;
103
106
  if (path !== null) {
104
107
  const revisits = this.countRevisits(path);
@@ -111,15 +114,16 @@ export class LoopDetector {
111
114
  /**
112
115
  * Count same-path calls in the window that are "revisits" — accesses that end
113
116
  * no further into the file than the furthest line already covered for that
114
- * path. Paging yields zero revisits and never trips; repeated whole-file
115
- * re-reads, backward jumps and path-targeting greps accumulate.
117
+ * path. The FIRST call on a path is therefore never a revisit: it sets the
118
+ * high-water mark. Paging yields zero revisits and never trips; repeated
119
+ * whole-file re-reads, backward jumps, narrower re-reads and repeated
120
+ * path-targeting greps all accumulate.
116
121
  *
117
- * The comparison is on the RANGE, not the offset. Offset alone scored a page
118
- * that re-asks from the same start with a bigger limit `{offset:80,
119
- * limit:400}` after `{offset:80, limit:300}`, real reads from a measured
120
- * decompose run as a revisit, even though it covers 100 lines the child had
121
- * never seen. That is the same mistake SingleReadGuard made by keying on the
122
- * path alone, and it is corrected the same way.
122
+ * The comparison is on the RANGE, not the offset. Keying on offset alone scores
123
+ * `{offset:80, limit:400}` after `{offset:80, limit:300}` as a revisit, even
124
+ * though it covers 100 lines the child has never seen. That is the same mistake
125
+ * SingleReadGuard made by keying on the path alone, and it is corrected the same
126
+ * way.
123
127
  */
124
128
  countRevisits(path) {
125
129
  let maxEnd = -1;
@@ -1,26 +1,28 @@
1
1
  /**
2
2
  * What a typed message DOES while a task run owns the session.
3
3
  *
4
- * Before this module the two surfaces disagreed, and both were wrong whenever the
5
- * host session was idle — which is most of a run, since the spec phases and every
6
- * gate are child `pi` processes, not host turns:
4
+ * Both surfaces the terminal Enter listener and the remote browser need ONE
5
+ * rule, because for most of a run the HOST session is idle: the spec phases and
6
+ * every gate are child `pi` processes, not host turns. Left to itself each surface
7
+ * has its own failure on an idle session:
7
8
  *
8
- * - browser → `sendUserMessage` with no delivery mode, which starts a SECOND
9
- * turn alongside the run. Reproduced live on pi 0.82.1 (issue #8):
10
- * that turn ran the write tool into the project, and when it was
11
- * still streaming as the pipeline delivered its spec the run died
12
- * with "TASK_0001 failed: Agent is already processing."
13
- * - terminal → pi's `pendingUserInputs` queue, drained only by the main loop
14
- * that our own command handler is parked inside so the line sat
15
- * there silently and then fired minutes later against a finished
16
- * run.
9
+ * - browser → `sendUserMessage` with no delivery mode. pi's own API docs call it
10
+ * "Always triggers a turn", so it opens a SECOND turn beside the run,
11
+ * with the write tool in hand. If that turn is still streaming when
12
+ * the pipeline delivers its spec, the spec's own send hits pi's
13
+ * guard: "Agent is already processing. Specify streamingBehavior
14
+ * ('steer' or 'followUp') to queue the message."
15
+ * - terminal pi's `pendingUserInputs` queue, which only `getUserInput()` drains
16
+ * and that is the main loop our own command handler is parked
17
+ * inside. The line sits there silently, then fires against a
18
+ * finished run.
17
19
  *
18
- * The shared rule both surfaces now follow:
20
+ * The shared rule both surfaces follow:
19
21
  *
20
- * agent streaming → steer the live turn (unchanged; this half always worked)
22
+ * agent streaming → steer the live turn
21
23
  * agent idle, run active → HOLD it here, show it as pending, and deliver it as
22
24
  * a steer when the next task turn starts
23
- * no run active → ordinary message, unchanged
25
+ * no run active → ordinary message
24
26
  *
25
27
  * Holding is what makes the two surfaces agree AND keeps the run safe: a held
26
28
  * line never becomes a competing turn, and it is never silently replayed after
@@ -1,26 +1,28 @@
1
1
  /**
2
2
  * What a typed message DOES while a task run owns the session.
3
3
  *
4
- * Before this module the two surfaces disagreed, and both were wrong whenever the
5
- * host session was idle — which is most of a run, since the spec phases and every
6
- * gate are child `pi` processes, not host turns:
4
+ * Both surfaces the terminal Enter listener and the remote browser need ONE
5
+ * rule, because for most of a run the HOST session is idle: the spec phases and
6
+ * every gate are child `pi` processes, not host turns. Left to itself each surface
7
+ * has its own failure on an idle session:
7
8
  *
8
- * - browser → `sendUserMessage` with no delivery mode, which starts a SECOND
9
- * turn alongside the run. Reproduced live on pi 0.82.1 (issue #8):
10
- * that turn ran the write tool into the project, and when it was
11
- * still streaming as the pipeline delivered its spec the run died
12
- * with "TASK_0001 failed: Agent is already processing."
13
- * - terminal → pi's `pendingUserInputs` queue, drained only by the main loop
14
- * that our own command handler is parked inside so the line sat
15
- * there silently and then fired minutes later against a finished
16
- * run.
9
+ * - browser → `sendUserMessage` with no delivery mode. pi's own API docs call it
10
+ * "Always triggers a turn", so it opens a SECOND turn beside the run,
11
+ * with the write tool in hand. If that turn is still streaming when
12
+ * the pipeline delivers its spec, the spec's own send hits pi's
13
+ * guard: "Agent is already processing. Specify streamingBehavior
14
+ * ('steer' or 'followUp') to queue the message."
15
+ * - terminal pi's `pendingUserInputs` queue, which only `getUserInput()` drains
16
+ * and that is the main loop our own command handler is parked
17
+ * inside. The line sits there silently, then fires against a
18
+ * finished run.
17
19
  *
18
- * The shared rule both surfaces now follow:
20
+ * The shared rule both surfaces follow:
19
21
  *
20
- * agent streaming → steer the live turn (unchanged; this half always worked)
22
+ * agent streaming → steer the live turn
21
23
  * agent idle, run active → HOLD it here, show it as pending, and deliver it as
22
24
  * a steer when the next task turn starts
23
- * no run active → ordinary message, unchanged
25
+ * no run active → ordinary message
24
26
  *
25
27
  * Holding is what makes the two surfaces agree AND keeps the run safe: a held
26
28
  * line never becomes a competing turn, and it is never silently replayed after
@@ -12,8 +12,9 @@
12
12
  * /task-cancel cancel the running task (soft-terminal — still resumable)
13
13
  *
14
14
  * The orchestrator persists after every phase boundary to
15
- * <cwd>/.pi-tasks/TASK_NNNN.md. All user interaction during phases runs through
16
- * ctx.ui dialogs; the main pi chat only receives the final spec.
15
+ * <cwd>/.pi-tasks/TASK_NNNN.md. User interaction during phases runs through the
16
+ * SessionUI bridge — a local ctx.ui dialog raced against a remote browser card
17
+ * never through the main conversation, which only receives the final spec.
17
18
  */
18
19
  import type { ExtensionAPI, ExtensionCommandContext } from '@earendil-works/pi-coding-agent';
19
20
  import { type WidgetState } from './widget.js';
@@ -43,12 +44,13 @@ export interface TaskRunnerOptions {
43
44
  * `spawn` drives the Error-triage ladder or a real process. `runChild(name,
44
45
  * tools, prompt)` answers every phase child BY NAME, with none of the
45
46
  * ladder's guards — use it when the child is a premise of the test, not its
46
- * subject. `runWorker(label, input)` answers every research worker by name,
47
- * so the three Research retry gates are reachable without matching a marker
48
- * sentence inside a prompt. The EXTERNAL CONTEXT lookups and the file
47
+ * subject. `runWorker(label, input)` answers every research worker by name, so
48
+ * the research phase's retry gates (`zeroRetrievalRetry`, `retryIfSilent`, the
49
+ * restart ladder) are reachable without matching a marker sentence inside a
50
+ * prompt. The EXTERNAL CONTEXT lookups and the file
49
51
  * inventory each default to the real implementation when absent. `timeoutMs`,
50
- * `sleepFor`, `childExtensions` and `logDebug` are seams too, and were
51
- * unreachable from here until this became one field.
52
+ * `sleepFor`, `childExtensions` and `logDebug` are seams too, and travel in the
53
+ * same field.
52
54
  */
53
55
  seams?: PhaseSeams;
54
56
  /** Called with the resolved task id once its file exists, before any phase
@@ -96,9 +98,9 @@ export declare class TaskRunner {
96
98
  private readonly _deps;
97
99
  private readonly _pc;
98
100
  /**
99
- * Per-phase wall-clock durations collected during the run. Written to the
100
- * `## phase timings` section on successful completion so we can spot
101
- * regressions and target future speed work. Each top-level entry is a
101
+ * Per-phase wall-clock durations collected during the run, written to the
102
+ * `## phase timings` section on completion, and again from the catch so a
103
+ * failed run still records what it got through. Each top-level entry is a
102
104
  * phase (refine/research/grill/compose/critique); children are optional
103
105
  * sub-step splits the phase chose to record via deps.recordSubStep.
104
106
  */
@@ -111,16 +113,15 @@ export declare class TaskRunner {
111
113
  status(): WidgetState | null;
112
114
  /** Cancel the running task by aborting the signal. */
113
115
  cancel(): void;
114
- /** Execute the full task lifecycle. Mid-run input holds instead of starting
115
- * a competing turn for the whole of it, and the terminal interception is
116
- * armed for the same window (`withRun`); nested inside `runGatedTask` or
117
- * the `/task-auto` loop the bracket refcounts, so this changes nothing there
118
- * and covers the fire-and-forget `runSingleTask` path on its own. */
119
116
  /**
120
- * Run the task and NAME how it ended.
117
+ * Run the task and NAME how it ended (`RunEnd`), so no caller has to re-read
118
+ * the task file to find out.
121
119
  *
122
- * This returned `void`, so the caller re-read the task file to learn what had
123
- * just happened here see run-end.ts for the report that got wrong.
120
+ * Mid-run input holds instead of starting a competing turn for the whole of
121
+ * it, and the terminal interception is armed for the same window (`withRun`);
122
+ * nested inside `runGatedTask` or the `/task-auto` loop the bracket refcounts,
123
+ * so this changes nothing there and covers the fire-and-forget
124
+ * `runSingleTask` path on its own.
124
125
  */
125
126
  run(): Promise<RunEnd>;
126
127
  private _run;
@@ -163,8 +164,8 @@ export interface RunSingleTaskOptions extends Pick<TaskRunnerOptions, 'resumeId'
163
164
  notifyFinish?: boolean;
164
165
  /**
165
166
  * How the implementation turn's thinking level is read and written. Defaults
166
- * to the live pi session; injected by tests, which must be able to assert
167
- * the restore without a real session to restore.
167
+ * to the live pi session; injectable so the hold-and-restore is assertable
168
+ * with no real session to restore.
168
169
  */
169
170
  thinkingControl?: ThinkingControl;
170
171
  }
@@ -172,11 +173,7 @@ export interface RunSingleTaskResult {
172
173
  taskId: string;
173
174
  /**
174
175
  * How the run ended, named by the runner rather than re-derived from disk.
175
- *
176
- * This was `ok: boolean` plus `sessionCancelled`, `interrupted` and `reason`
177
- * — four fields for one fact, three of them smuggled out of the `withSession`
178
- * closure through mutable captures. `/task-cancel` fell into the `!ok` arm
179
- * and was reported as a failure; see run-end.ts.
176
+ * One value for one fact: see run-end.ts for the endings and their policy.
180
177
  */
181
178
  end: RunEnd;
182
179
  /**
@@ -194,9 +191,8 @@ export interface RunSingleTaskResult {
194
191
  * deliver its spec. With waitForImplementation, block until the agent finishes
195
192
  * implementing the delivered spec.
196
193
  *
197
- * The ending comes from `TaskRunner.run`. It used to be read back off the task
198
- * file's front matter — a disk round-trip this process made to learn what it had
199
- * just done, and one that could not tell a cancel from a failure.
194
+ * The ending in the result comes from `TaskRunner.run` itself, not from re-reading
195
+ * the task file's front matter — which cannot tell a cancel from a failure.
200
196
  */
201
197
  export declare function runSingleTask(ctx: ExtensionCommandContext, cwd: string, rawPrompt: string, opts?: RunSingleTaskOptions): Promise<RunSingleTaskResult>;
202
198
  /**