@mjasnikovs/pi-task 0.38.29 → 0.38.31

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 (373) 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/index.js +2 -0
  14. package/dist/remote/bridge.d.ts +19 -10
  15. package/dist/remote/bridge.js +3 -2
  16. package/dist/remote/broadcast.js +3 -1
  17. package/dist/remote/events.js +12 -11
  18. package/dist/remote/history.d.ts +1 -1
  19. package/dist/remote/protocol.d.ts +6 -3
  20. package/dist/remote/protocol.js +2 -1
  21. package/dist/remote/push.d.ts +16 -16
  22. package/dist/remote/push.js +27 -27
  23. package/dist/remote/register.d.ts +3 -3
  24. package/dist/remote/register.js +17 -19
  25. package/dist/remote/server.d.ts +9 -8
  26. package/dist/remote/server.js +15 -14
  27. package/dist/remote/session-state.d.ts +5 -4
  28. package/dist/remote/session-state.js +8 -5
  29. package/dist/remote/sw.d.ts +7 -6
  30. package/dist/remote/sw.js +7 -6
  31. package/dist/remote/tailscale.d.ts +4 -2
  32. package/dist/remote/tailscale.js +4 -2
  33. package/dist/remote/ui-highlight.js +6 -5
  34. package/dist/remote/ui-render.js +4 -4
  35. package/dist/remote/ui-script.js +24 -24
  36. package/dist/remote/ui-styles.d.ts +1 -1
  37. package/dist/remote/ui-styles.js +10 -13
  38. package/dist/remote/ui-tools.js +9 -6
  39. package/dist/shared/child-extensions.d.ts +29 -17
  40. package/dist/shared/child-extensions.js +29 -17
  41. package/dist/shared/child-output.d.ts +30 -24
  42. package/dist/shared/child-output.js +25 -17
  43. package/dist/shared/child-process.d.ts +47 -40
  44. package/dist/shared/child-process.js +50 -59
  45. package/dist/shared/command-watchdog.d.ts +85 -16
  46. package/dist/shared/command-watchdog.js +115 -21
  47. package/dist/shared/fs-text.d.ts +16 -10
  48. package/dist/shared/fs-text.js +16 -10
  49. package/dist/shared/git-runner.d.ts +25 -25
  50. package/dist/shared/git-runner.js +25 -25
  51. package/dist/shared/leaked-tool-call.d.ts +17 -11
  52. package/dist/shared/leaked-tool-call.js +23 -15
  53. package/dist/shared/model-endpoint.d.ts +29 -16
  54. package/dist/shared/model-endpoint.js +33 -21
  55. package/dist/shared/pi-invocation.d.ts +7 -4
  56. package/dist/shared/pi-invocation.js +12 -7
  57. package/dist/shared/pkg-version.d.ts +13 -5
  58. package/dist/shared/pkg-version.js +13 -5
  59. package/dist/shared/reasoning-capability.d.ts +35 -24
  60. package/dist/shared/reasoning-capability.js +35 -24
  61. package/dist/shared/stream-watchdog.d.ts +60 -44
  62. package/dist/shared/stream-watchdog.js +62 -45
  63. package/dist/task/accept-debt.d.ts +41 -43
  64. package/dist/task/accept-debt.js +73 -65
  65. package/dist/task/api-synthesis.d.ts +24 -21
  66. package/dist/task/api-synthesis.js +32 -26
  67. package/dist/task/apis-contract.d.ts +32 -64
  68. package/dist/task/apis-contract.js +32 -64
  69. package/dist/task/artifact-closure.d.ts +27 -13
  70. package/dist/task/artifact-closure.js +95 -67
  71. package/dist/task/auto-commit.d.ts +46 -35
  72. package/dist/task/auto-commit.js +51 -38
  73. package/dist/task/auto-io.d.ts +45 -25
  74. package/dist/task/auto-io.js +57 -29
  75. package/dist/task/auto-orchestrator.d.ts +26 -24
  76. package/dist/task/auto-orchestrator.js +192 -165
  77. package/dist/task/auto-prompts.d.ts +36 -24
  78. package/dist/task/auto-prompts.js +40 -26
  79. package/dist/task/autofix-ledger.d.ts +27 -25
  80. package/dist/task/autofix-ledger.js +29 -26
  81. package/dist/task/batch-test-task.d.ts +20 -12
  82. package/dist/task/batch-test-task.js +67 -60
  83. package/dist/task/boot-probe.d.ts +60 -44
  84. package/dist/task/boot-probe.js +91 -72
  85. package/dist/task/cancel-input.d.ts +30 -16
  86. package/dist/task/cancel-input.js +20 -11
  87. package/dist/task/cancel-points.d.ts +27 -20
  88. package/dist/task/cancel-points.js +30 -22
  89. package/dist/task/child-runner.d.ts +124 -55
  90. package/dist/task/child-runner.js +298 -90
  91. package/dist/task/child-status.d.ts +23 -16
  92. package/dist/task/child-status.js +23 -16
  93. package/dist/task/clamp-output.js +12 -5
  94. package/dist/task/command-run.d.ts +31 -28
  95. package/dist/task/command-run.js +44 -35
  96. package/dist/task/command-shrink.d.ts +25 -18
  97. package/dist/task/command-shrink.js +37 -31
  98. package/dist/task/command-watchdog.d.ts +9 -6
  99. package/dist/task/command-watchdog.js +21 -15
  100. package/dist/task/context-attribution.d.ts +34 -26
  101. package/dist/task/context-attribution.js +34 -26
  102. package/dist/task/context-silence.d.ts +39 -29
  103. package/dist/task/context-silence.js +35 -25
  104. package/dist/task/context-usage.d.ts +16 -9
  105. package/dist/task/context-usage.js +16 -9
  106. package/dist/task/contracts.d.ts +8 -4
  107. package/dist/task/contracts.js +25 -17
  108. package/dist/task/coverage-loop.d.ts +22 -18
  109. package/dist/task/coverage-loop.js +35 -30
  110. package/dist/task/critique-probes.d.ts +13 -14
  111. package/dist/task/critique-probes.js +50 -39
  112. package/dist/task/debug-log.d.ts +13 -5
  113. package/dist/task/debug-log.js +32 -20
  114. package/dist/task/decompose-fidelity.d.ts +11 -9
  115. package/dist/task/decompose-fidelity.js +38 -33
  116. package/dist/task/decompose-granularity.d.ts +41 -38
  117. package/dist/task/decompose-granularity.js +41 -38
  118. package/dist/task/deep-render-check.d.ts +22 -14
  119. package/dist/task/deep-render-check.js +40 -31
  120. package/dist/task/dropped-input.d.ts +12 -7
  121. package/dist/task/dropped-input.js +5 -2
  122. package/dist/task/enforce-attribution.d.ts +38 -47
  123. package/dist/task/enforce-attribution.js +46 -52
  124. package/dist/task/enforce-guidelines.d.ts +31 -20
  125. package/dist/task/enforce-guidelines.js +32 -21
  126. package/dist/task/enrichment.d.ts +7 -2
  127. package/dist/task/enrichment.js +26 -14
  128. package/dist/task/env-notes.d.ts +16 -7
  129. package/dist/task/env-notes.js +48 -31
  130. package/dist/task/env-template-closure.d.ts +4 -4
  131. package/dist/task/env-template-closure.js +42 -34
  132. package/dist/task/external-context.d.ts +28 -21
  133. package/dist/task/external-context.js +17 -12
  134. package/dist/task/failure-classifier.d.ts +4 -5
  135. package/dist/task/failure-classifier.js +30 -8
  136. package/dist/task/file-inventory.d.ts +15 -11
  137. package/dist/task/file-inventory.js +25 -22
  138. package/dist/task/final-gate-fix.d.ts +74 -86
  139. package/dist/task/final-gate-fix.js +97 -116
  140. package/dist/task/final-gate-progress.d.ts +29 -46
  141. package/dist/task/final-gate-progress.js +40 -51
  142. package/dist/task/final-gate.d.ts +64 -97
  143. package/dist/task/final-gate.js +192 -199
  144. package/dist/task/fix-child.d.ts +21 -27
  145. package/dist/task/fix-child.js +21 -27
  146. package/dist/task/foreign-path.d.ts +6 -5
  147. package/dist/task/foreign-path.js +0 -0
  148. package/dist/task/frozen-conflict.d.ts +9 -10
  149. package/dist/task/frozen-conflict.js +61 -64
  150. package/dist/task/frozen-path-guard.d.ts +35 -14
  151. package/dist/task/frozen-path-guard.js +56 -39
  152. package/dist/task/gate-child.d.ts +27 -28
  153. package/dist/task/gate-child.js +36 -35
  154. package/dist/task/gate-deps.d.ts +34 -27
  155. package/dist/task/gate-deps.js +169 -159
  156. package/dist/task/gate-tally.d.ts +77 -80
  157. package/dist/task/gate-tally.js +65 -68
  158. package/dist/task/git-state-guard.d.ts +15 -11
  159. package/dist/task/git-state-guard.js +76 -66
  160. package/dist/task/impl-widget.d.ts +25 -16
  161. package/dist/task/impl-widget.js +27 -17
  162. package/dist/task/implementation-guards.d.ts +26 -0
  163. package/dist/task/implementation-guards.js +177 -0
  164. package/dist/task/implementation-thinking.d.ts +33 -31
  165. package/dist/task/implementation-thinking.js +5 -6
  166. package/dist/task/implementation-turn.d.ts +39 -31
  167. package/dist/task/implementation-turn.js +41 -28
  168. package/dist/task/inline-markdown.d.ts +20 -7
  169. package/dist/task/inline-markdown.js +15 -6
  170. package/dist/task/launch-config-gap.js +25 -39
  171. package/dist/task/launch-contract.d.ts +18 -21
  172. package/dist/task/launch-contract.js +28 -30
  173. package/dist/task/launch-manifest.d.ts +6 -2
  174. package/dist/task/launch-manifest.js +35 -34
  175. package/dist/task/ledger.js +16 -14
  176. package/dist/task/lint-fix.d.ts +6 -8
  177. package/dist/task/lint-fix.js +67 -69
  178. package/dist/task/loop-detector.d.ts +27 -8
  179. package/dist/task/loop-detector.js +38 -14
  180. package/dist/task/mid-run-input.d.ts +17 -15
  181. package/dist/task/mid-run-input.js +17 -15
  182. package/dist/task/orchestrator.d.ts +24 -28
  183. package/dist/task/orchestrator.js +89 -66
  184. package/dist/task/orientation.d.ts +18 -23
  185. package/dist/task/orientation.js +24 -31
  186. package/dist/task/owned-freeze-conflict.d.ts +21 -20
  187. package/dist/task/owned-freeze-conflict.js +52 -85
  188. package/dist/task/owned-freeze-reassign.d.ts +40 -60
  189. package/dist/task/owned-freeze-reassign.js +41 -61
  190. package/dist/task/parsers.d.ts +4 -2
  191. package/dist/task/parsers.js +4 -4
  192. package/dist/task/phases.d.ts +41 -48
  193. package/dist/task/phases.js +196 -252
  194. package/dist/task/plan-io.d.ts +6 -7
  195. package/dist/task/plan-io.js +6 -7
  196. package/dist/task/plan-orchestrator.d.ts +10 -8
  197. package/dist/task/plan-orchestrator.js +14 -10
  198. package/dist/task/plan-prompts.d.ts +6 -5
  199. package/dist/task/plan-prompts.js +6 -5
  200. package/dist/task/plan-readonly.d.ts +4 -5
  201. package/dist/task/plan-readonly.js +4 -5
  202. package/dist/task/plan-rounds.d.ts +17 -29
  203. package/dist/task/plan-rounds.js +21 -34
  204. package/dist/task/plan-session.d.ts +58 -72
  205. package/dist/task/plan-session.js +61 -83
  206. package/dist/task/probe-gaming.d.ts +28 -27
  207. package/dist/task/probe-gaming.js +0 -0
  208. package/dist/task/prohibition-probe.d.ts +14 -16
  209. package/dist/task/prompts.d.ts +3 -4
  210. package/dist/task/prompts.js +17 -26
  211. package/dist/task/qa-transcript.d.ts +15 -22
  212. package/dist/task/qa-transcript.js +15 -21
  213. package/dist/task/question-box.d.ts +17 -13
  214. package/dist/task/question-box.js +19 -15
  215. package/dist/task/question-dedup.d.ts +6 -7
  216. package/dist/task/question-dedup.js +13 -14
  217. package/dist/task/question-dialog.d.ts +22 -32
  218. package/dist/task/question-dialog.js +22 -32
  219. package/dist/task/question-source.d.ts +18 -44
  220. package/dist/task/question-source.js +22 -51
  221. package/dist/task/refuted-constraint.d.ts +11 -31
  222. package/dist/task/refuted-constraint.js +27 -51
  223. package/dist/task/regenerable-artifacts.d.ts +12 -31
  224. package/dist/task/regenerable-artifacts.js +12 -31
  225. package/dist/task/render-check.d.ts +11 -22
  226. package/dist/task/render-check.js +33 -46
  227. package/dist/task/repo-health-check.d.ts +10 -14
  228. package/dist/task/repo-health-check.js +17 -23
  229. package/dist/task/requirements.d.ts +38 -71
  230. package/dist/task/requirements.js +78 -126
  231. package/dist/task/research-fanout-budget.d.ts +51 -88
  232. package/dist/task/research-fanout-budget.js +51 -88
  233. package/dist/task/research-worker.d.ts +29 -39
  234. package/dist/task/research-worker.js +37 -61
  235. package/dist/task/resume-gap.d.ts +14 -15
  236. package/dist/task/root-cause-repair.d.ts +9 -9
  237. package/dist/task/root-cause-repair.js +28 -40
  238. package/dist/task/run-bracket.d.ts +10 -13
  239. package/dist/task/run-end.d.ts +12 -22
  240. package/dist/task/run-end.js +8 -16
  241. package/dist/task/run-final-gate.d.ts +19 -21
  242. package/dist/task/run-final-gate.js +62 -80
  243. package/dist/task/runner-globs.d.ts +12 -13
  244. package/dist/task/runner-globs.js +12 -13
  245. package/dist/task/runner-resolve.d.ts +9 -9
  246. package/dist/task/runner-resolve.js +22 -23
  247. package/dist/task/script-escape.d.ts +10 -12
  248. package/dist/task/script-escape.js +13 -14
  249. package/dist/task/serve-entry.d.ts +1 -1
  250. package/dist/task/serve-entry.js +22 -25
  251. package/dist/task/service-blocks.js +4 -2
  252. package/dist/task/shipped-source.d.ts +11 -29
  253. package/dist/task/shipped-source.js +11 -29
  254. package/dist/task/skip-escape.js +10 -14
  255. package/dist/task/spec-urls.d.ts +26 -65
  256. package/dist/task/spec-urls.js +26 -65
  257. package/dist/task/spec-validation.d.ts +17 -20
  258. package/dist/task/spec-validation.js +17 -20
  259. package/dist/task/stall-detector.d.ts +23 -30
  260. package/dist/task/stall-detector.js +23 -30
  261. package/dist/task/stream-watchdog.d.ts +14 -12
  262. package/dist/task/stream-watchdog.js +14 -12
  263. package/dist/task/substitution-probe.d.ts +17 -20
  264. package/dist/task/substitution-probe.js +17 -20
  265. package/dist/task/task-gates.d.ts +36 -41
  266. package/dist/task/task-gates.js +95 -106
  267. package/dist/task/task-io.d.ts +4 -4
  268. package/dist/task/task-io.js +4 -4
  269. package/dist/task/task-parsers.js +4 -3
  270. package/dist/task/task-provenance.d.ts +2 -2
  271. package/dist/task/task-provenance.js +11 -13
  272. package/dist/task/task-types.d.ts +4 -3
  273. package/dist/task/terminal-outcome.d.ts +14 -16
  274. package/dist/task/terminal-outcome.js +12 -14
  275. package/dist/task/test-assembly.d.ts +13 -20
  276. package/dist/task/test-assembly.js +13 -20
  277. package/dist/task/timings.d.ts +5 -3
  278. package/dist/task/timings.js +5 -3
  279. package/dist/task/title-label.d.ts +9 -4
  280. package/dist/task/title-label.js +9 -4
  281. package/dist/task/type-only-answer.d.ts +44 -52
  282. package/dist/task/type-only-answer.js +44 -52
  283. package/dist/task/unfailable-command.d.ts +18 -24
  284. package/dist/task/unfailable-command.js +21 -27
  285. package/dist/task/unknown-routing.d.ts +10 -4
  286. package/dist/task/unknown-routing.js +10 -4
  287. package/dist/task/user-directives.d.ts +5 -8
  288. package/dist/task/user-directives.js +5 -8
  289. package/dist/task/verify-quality.d.ts +18 -22
  290. package/dist/task/verify-quality.js +45 -46
  291. package/dist/task/verify-reconcile.d.ts +15 -10
  292. package/dist/task/verify-reconcile.js +45 -43
  293. package/dist/task/verify-resolution.d.ts +24 -20
  294. package/dist/task/verify-resolution.js +51 -50
  295. package/dist/task/verify-work.d.ts +59 -66
  296. package/dist/task/verify-work.js +101 -138
  297. package/dist/task/widget.d.ts +15 -14
  298. package/dist/task/widget.js +22 -17
  299. package/dist/task/wiring-claims.d.ts +25 -32
  300. package/dist/task/wiring-claims.js +30 -35
  301. package/dist/task/write-guard.d.ts +39 -39
  302. package/dist/task/write-guard.js +48 -51
  303. package/dist/task/yolo.d.ts +34 -30
  304. package/dist/task/yolo.js +42 -37
  305. package/dist/workers/abstention.d.ts +21 -41
  306. package/dist/workers/abstention.js +27 -48
  307. package/dist/workers/brave-search.d.ts +4 -3
  308. package/dist/workers/brave-search.js +5 -2
  309. package/dist/workers/brave-warning.d.ts +7 -4
  310. package/dist/workers/brave-warning.js +19 -7
  311. package/dist/workers/ddg-search.d.ts +6 -6
  312. package/dist/workers/ddg-search.js +18 -12
  313. package/dist/workers/docs-cache.js +5 -2
  314. package/dist/workers/docs-chunk.d.ts +30 -37
  315. package/dist/workers/docs-chunk.js +37 -41
  316. package/dist/workers/docs-core.d.ts +28 -44
  317. package/dist/workers/docs-core.js +25 -44
  318. package/dist/workers/docs-index.js +4 -3
  319. package/dist/workers/docs-lookup.d.ts +15 -22
  320. package/dist/workers/docs-lookup.js +12 -21
  321. package/dist/workers/docs-project.d.ts +15 -9
  322. package/dist/workers/docs-project.js +17 -10
  323. package/dist/workers/docs-resolve.d.ts +19 -20
  324. package/dist/workers/docs-resolve.js +35 -32
  325. package/dist/workers/docs-retrieve.d.ts +5 -6
  326. package/dist/workers/docs-retrieve.js +18 -15
  327. package/dist/workers/exa-search.d.ts +9 -6
  328. package/dist/workers/exa-search.js +23 -12
  329. package/dist/workers/fetch-core.d.ts +13 -16
  330. package/dist/workers/fetch-core.js +23 -23
  331. package/dist/workers/focused-extractor.d.ts +13 -12
  332. package/dist/workers/focused-extractor.js +27 -19
  333. package/dist/workers/html-clean.js +24 -14
  334. package/dist/workers/http-request.d.ts +28 -20
  335. package/dist/workers/http-request.js +22 -17
  336. package/dist/workers/npm-version.d.ts +28 -11
  337. package/dist/workers/npm-version.js +24 -15
  338. package/dist/workers/phantom-imports.d.ts +15 -12
  339. package/dist/workers/phantom-imports.js +30 -24
  340. package/dist/workers/pi-worker-core.d.ts +65 -96
  341. package/dist/workers/pi-worker-core.js +93 -181
  342. package/dist/workers/pi-worker-docs.d.ts +24 -19
  343. package/dist/workers/pi-worker-docs.js +67 -76
  344. package/dist/workers/pi-worker-fetch.d.ts +7 -3
  345. package/dist/workers/pi-worker-fetch.js +27 -19
  346. package/dist/workers/pi-worker-search.js +12 -8
  347. package/dist/workers/pi-worker.d.ts +9 -4
  348. package/dist/workers/pi-worker.js +21 -14
  349. package/dist/workers/reasoning-warning.d.ts +18 -17
  350. package/dist/workers/reasoning-warning.js +22 -20
  351. package/dist/workers/research-cache.js +50 -78
  352. package/dist/workers/search-core.js +7 -5
  353. package/dist/workers/search-types.d.ts +10 -9
  354. package/dist/workers/search-types.js +9 -8
  355. package/dist/workers/session-hint.d.ts +13 -14
  356. package/dist/workers/session-hint.js +8 -9
  357. package/dist/workers/shared.d.ts +21 -25
  358. package/dist/workers/shared.js +0 -0
  359. package/dist/workers/single-read-extension.d.ts +14 -7
  360. package/dist/workers/single-read-extension.js +14 -7
  361. package/dist/workers/single-read-guard.d.ts +27 -30
  362. package/dist/workers/single-read-guard.js +36 -36
  363. package/dist/workers/typeonly-log.d.ts +12 -9
  364. package/dist/workers/typeonly-log.js +29 -33
  365. package/dist/workers/worker-channels.d.ts +15 -23
  366. package/dist/workers/worker-channels.js +15 -23
  367. package/dist/workers/worker-failure.d.ts +38 -46
  368. package/dist/workers/worker-failure.js +31 -39
  369. package/dist/workers/worker-kill.d.ts +25 -26
  370. package/dist/workers/worker-kill.js +16 -19
  371. package/dist/workers/worker-profiles.d.ts +54 -56
  372. package/dist/workers/worker-profiles.js +63 -39
  373. package/package.json +10 -8
@@ -3,24 +3,30 @@
3
3
  *
4
4
  * A cancel is a *request*, never a kill. It is honoured only where the on-disk
5
5
  * state is durable and /task-auto-resume provably continues from it. Killing a
6
- * child mid-phase would also stop the run (the abort signal already reaches
7
- * every child's process group) but throws away that phase's work and can leave
8
- * a half-written tree so the flag is polled at boundaries instead.
6
+ * child mid-phase would also stop the run the abort signal reaches every
7
+ * child's process group but it throws away that phase's work and can leave a
8
+ * half-written tree, so the flag is polled at boundaries instead.
9
9
  *
10
- * The checkpoint set, and why each one is safe:
10
+ * The checkpoint set is exactly these four, one call site each:
11
11
  *
12
- * loop-top the previous task is checked off + committed and the next one
13
- * has not started. The original (and until now the ONLY) point.
14
- * pre-task after the pre-task checkpoint commit, before the runner is
15
- * constructed: tree committed, no inner id stamped yet, so the
16
- * entry is simply still unchecked and a resume restarts it.
17
- * phase:<name> inside the runner's phase loop, after setTaskSection +
18
- * postCommitPhase have persisted the phase output and
19
- * front-matter `phase` names the NEXT phase. This is exactly
20
- * the state /task-resume already resumes from (PHASE_INDEX
21
- * skip-forward), so a cancel here costs nothing.
22
- * pre-final-gate every task is checked off and committed; the whole-repo gate
23
- * has not started. A resume re-enters the same branch.
12
+ * loop-top (auto-orchestrator) the previous task is checked off and
13
+ * committed and the next one has not started.
14
+ * pre-task (auto-orchestrator) after the pre-task checkpoint commit,
15
+ * before the runner is constructed: tree committed, no inner id
16
+ * stamped yet, so the entry is simply still unchecked and a
17
+ * resume restarts it.
18
+ * phase:<name> (orchestrator, inside the phase loop) after setTaskSection and
19
+ * postCommitPhase have persisted this phase's output. Front-matter
20
+ * `phase` still names the phase that JUST FINISHED, not the next
21
+ * one: `advance()` writes it at the TOP of each iteration and
22
+ * nothing moves it afterwards postCommitPhase writes only
23
+ * `title` and `label`. Since the resume skip rule is
24
+ * `idx < resumeIdx`, a resume therefore RE-ENTERS this phase and
25
+ * runs it again. Nothing is lost, because its section is already
26
+ * on disk; the cost is repeating one phase, not zero.
27
+ * pre-final-gate (run-final-gate) every task is checked off and committed; the
28
+ * whole-repo gate has not started. A resume re-enters the same
29
+ * branch.
24
30
  *
25
31
  * DELIBERATELY NOT checkpoints — stopping here is not safe:
26
32
  * - mid implementation turn: uncommitted, half-applied edits. The user's ESC
@@ -31,7 +37,8 @@
31
37
  */
32
38
  let requested = false;
33
39
  /** Checkpoints actually reached since the last reset, in order. Instrumentation
34
- * for the A/B harness and the unit tests never read by the loop itself. */
40
+ * only: `checkpointsCrossed` and `resetCheckpointTrail` have no caller anywhere
41
+ * in src/ — every consumer is a test. */
35
42
  const crossed = [];
36
43
  export function requestCancel() {
37
44
  requested = true;
@@ -51,7 +58,7 @@ export function isCancelRequested() {
51
58
  export function resetCancel() {
52
59
  requested = false;
53
60
  }
54
- /** Drop the recorded checkpoint trail (A/B + tests). */
61
+ /** Drop the recorded checkpoint trail. */
55
62
  export function resetCheckpointTrail() {
56
63
  crossed.length = 0;
57
64
  }
@@ -64,14 +71,15 @@ export function resetCheckpointTrail() {
64
71
  */
65
72
  export function cancelCheckpoint(where) {
66
73
  crossed.push(where);
67
- // A/B ONLY (scripts/cancel-latency-ab.ts): reproduce the pre-checkpoint
68
- // behaviour the flag was observed at the loop top and nowhere else so the
69
- // two arms differ in exactly the thing under test and share every other path.
74
+ // CANCEL_AB_ARM=baseline collapses the checkpoint set back to loop-top alone,
75
+ // so the two arms differ in exactly one thing. Nothing in src/ ever sets it;
76
+ // the only writer in the tree is cancel-points.test.ts, which uses it to pin
77
+ // that the extra checkpoints — and only they — are what the flag gates.
70
78
  if (process.env.CANCEL_AB_ARM === 'baseline' && where !== 'loop-top')
71
79
  return false;
72
80
  return requested;
73
81
  }
74
- /** Checkpoints crossed since the last reset (A/B + tests). */
82
+ /** Checkpoints crossed since the last reset. */
75
83
  export function checkpointsCrossed() {
76
84
  return crossed;
77
85
  }
@@ -6,34 +6,30 @@
6
6
  * for phase-level child pi invocations.
7
7
  */
8
8
  import { type SpawnFn, type ContextSnapshot, type ToolCall, type LoopHit } from '../shared/child-process.js';
9
+ import { type CommandKill } from '../shared/command-watchdog.js';
10
+ import { type WorkerGuardPolicy } from '../workers/worker-profiles.js';
9
11
  import type { DebugLine } from './debug-log.js';
10
12
  import type { RunWorkerInput, RunWorkerResult } from '../workers/pi-worker-core.js';
11
13
  import type { docsRaw, docsFocused } from '../workers/docs-core.js';
12
14
  import type { fetchRaw, fetchFocused } from '../workers/fetch-core.js';
13
15
  import type { npmVersionLookup } from '../workers/npm-version.js';
14
16
  import type { SearchCoreInput, SearchCoreResult } from '../workers/search-core.js';
15
- export declare const LOOP_WINDOW = 20;
16
- export declare const LOOP_THRESHOLD = 5;
17
- export declare const MAX_LOOP_RESTARTS = 2;
18
17
  /**
19
18
  * Optional wall-clock bound on ONE spawn of a phase child. DEFAULT: OFF.
20
19
  *
21
- * It used to default to 600_000, sized against measured HEALTHY planning
22
- * children on one local 27B backend (decompose 89s, whole plan phase 321s) on
23
- * the reasoning that ten minutes was a 3-6x margin over honest work.
20
+ * WHY OFF, AND NOT A NUMBER. A wall clock on a model child measures the
21
+ * MODEL'S SPEED, not its health. The same planning child that answers well in
22
+ * seconds on one backend takes many minutes on another, or on the same backend
23
+ * with thinking turned on — so any cap generous enough to be safe is too loose
24
+ * to catch anything, and any cap tight enough to catch a runaway kills healthy
25
+ * work. Assume a model that emits one token per second and the number has no
26
+ * defensible value at all.
24
27
  *
25
- * That premise was measured and is false. Replaying ONE captured auto-decompose
26
- * request against the same backend with reasoning ON, n=10, everything else
27
- * byte-identical (2026-08-17): all ten answered correctly with 26-42 titles, and
28
- * every one took 610-927s. The cap would have killed 10 out of 10 GOOD runs and
29
- * then failed the phase with PhaseTimeoutError. The number was not measuring the
30
- * pathology, it was measuring one model's speed on one day.
31
- *
32
- * The runaway it was there to catch — a decompose child that ran 16m23s at
33
- * 117,370 of a 120,064-token window, forward-paging past the loop detector — is
34
- * now caught by StallDetector (stall-detector.ts), which bounds NON-PROGRESS and
35
- * CONTEXT CHURN instead of elapsed seconds. Both of those are properties of the
36
- * pathology, so neither has to be re-tuned for a slower model or a bigger repo.
28
+ * The runaway it was there to catch a child forward-paging through its whole
29
+ * context window, past the loop detector, never going to return is caught by
30
+ * StallDetector (stall-detector.ts) instead. That bounds NON-PROGRESS and
31
+ * CONTEXT CHURN, both properties of the pathology itself, so neither has to be
32
+ * re-tuned for a slower model or a bigger repo.
37
33
  *
38
34
  * The value and the plumbing stay for a caller that genuinely wants a hard stop
39
35
  * (tests inject a short one), but nothing sets it in production. Pass
@@ -53,6 +49,54 @@ export declare class PhaseTimeoutError extends Error {
53
49
  readonly attempts: number;
54
50
  constructor(childName: string, budgetMs: number, attempts: number);
55
51
  }
52
+ /**
53
+ * The terminal error for a guard kill, or null when the child was not killed.
54
+ *
55
+ * Both spawn paths must ask. A kill reports `exitCode: 0` (child-process.ts uses
56
+ * `code ?? 0`, and a signal gives null), so a path that tests the exit code
57
+ * instead returns the truncated text as the phase's answer.
58
+ */
59
+ export declare function guardKillError(name: string, r: PhaseRunResult, opts?: {
60
+ finalAttempt?: boolean;
61
+ }): Error | null;
62
+ /**
63
+ * The dead-backend probe killed a phase child on its LAST attempt.
64
+ *
65
+ * Reaching this means every attempt found no endpoint answering, not one. The
66
+ * single-probe verdict is not trusted on its own: `discoverModelEndpoints` reads
67
+ * every provider in models.json rather than the one this child's model uses, so a
68
+ * stopped local server can condemn a run against a healthy cloud backend. Three
69
+ * failed probes cost ~15s; one wrong verdict costs the run.
70
+ */
71
+ export declare class BackendDownError extends Error {
72
+ readonly childName: string;
73
+ constructor(childName: string);
74
+ }
75
+ /**
76
+ * A phase child spent every attempt on a command that never returned. Its own
77
+ * class because the fix is in the SPEC, not the model's exploration: a VERIFY
78
+ * block naming an unbounded `dev` command re-hangs every attempt.
79
+ */
80
+ export declare class CommandTimeoutError extends Error {
81
+ readonly childName: string;
82
+ readonly kill: CommandKill;
83
+ constructor(childName: string, kill: CommandKill);
84
+ }
85
+ /**
86
+ * Causes a best-effort `catch` must NOT absorb.
87
+ *
88
+ * A phase child that merely answered badly should degrade — that is what those
89
+ * catches are for. These two are different in kind: the run is over either way,
90
+ * and swallowing them ships a half-built spec while every later phase dies
91
+ * against the same dead backend, or turns a user's ESC into silent progress.
92
+ * `failure-classifier.ts` has a verdict for both; a catch that eats them makes it
93
+ * unreachable.
94
+ */
95
+ export declare function isFatalChildCause(e: unknown): boolean;
96
+ /**
97
+ * Retry budget is three attempts at 500ms/1s/2s — three requests over 3.5s, which
98
+ * is not a storm even against a throttle. pi's own ladder is three at 2s/4s/8s.
99
+ */
56
100
  export declare function isConnectionError(cause: string): boolean;
57
101
  /** Exponential backoff before a connection-error retry: 500ms, 1s, 2s, …, so a
58
102
  * brief saturation window can drain before we re-issue the request. */
@@ -66,6 +110,18 @@ export interface PhaseRunResult {
66
110
  leakedToolCall?: string;
67
111
  /** Set when the child's final turn failed with stopReason "error" (model/provider failure). */
68
112
  modelError?: string;
113
+ /**
114
+ * Set when the per-command watchdog killed the child: one tool call outran
115
+ * `requestTimeoutMs`. RESTARTABLE (worker-kill.ts) — a hung command is a
116
+ * mistake the next attempt can be told not to repeat.
117
+ */
118
+ commandKill?: CommandKill;
119
+ /**
120
+ * Set when the dead-backend probe killed the child: no output for the stall
121
+ * window AND the model endpoint unreachable. NOT restartable (worker-kill.ts):
122
+ * re-spawning against a backend that is down buys nothing.
123
+ */
124
+ stalled?: boolean;
69
125
  }
70
126
  export declare function childArgs(tools: string, extensions?: readonly string[],
71
127
  /**
@@ -84,13 +140,13 @@ export declare const USER_CANCELLED = "__user_cancelled__";
84
140
  /**
85
141
  * One child-pi invocation, as a value.
86
142
  *
87
- * WHY A RECORD. This was thirteen ordered positionals, and the thirteenth
88
- * carried its own DEBT note saying so. Two production callers reached it, and
89
- * they had already drifted: the degrade attempt wrote three bare `undefined`s to
90
- * reach the later slots and passed the RAW signal, so it escaped the wall clock
91
- * its own strike siblings run under the same defect class this file already
92
- * recorded for `runAutoInstall` and for the deleted `runPhaseWithLoopGuard`.
93
- * Adjacent optionals of the same type can no longer swap without a type error.
143
+ * WHY A RECORD RATHER THAN POSITIONALS. With this many optional parameters of
144
+ * the same type, a caller reaching a late one must write bare `undefined`s to get
145
+ * there, and one that miscounts silently lands the wrong value in the wrong slot.
146
+ * The failure that shape produces here is a child spawned with the RAW signal
147
+ * instead of the wall-clocked one, escaping a guard its siblings run under, with
148
+ * nothing to catch it. Named fields make adjacent optionals of the same type
149
+ * impossible to swap without a type error.
94
150
  */
95
151
  export interface ChildRun {
96
152
  cwd: string;
@@ -111,9 +167,11 @@ export interface ChildRun {
111
167
  */
112
168
  onToolResult?: (text: string, isError: boolean) => void;
113
169
  /**
114
- * The child's context window in tokens. Nothing in pi's event stream reports
115
- * one (issue #16), so the parent hands its own down children carry no `-m`
116
- * and resolve the same default model. 0 / omitted = unknown, as before.
170
+ * The child's context window in tokens. Nothing in pi's `--mode json` stream
171
+ * reports one a real capture carries token counts and a model id, but no key
172
+ * naming a window — so the parent hands its own down. Children carry no `-m`
173
+ * (CHILD_BASE_ARGS) and resolve the same default model, which is what makes
174
+ * the parent's window the honest value. 0 or omitted = unknown.
117
175
  */
118
176
  contextWindow?: number;
119
177
  /**
@@ -121,8 +179,23 @@ export interface ChildRun {
121
179
  * group, or `[]`/omitted to inherit the session default as before.
122
180
  */
123
181
  thinking?: readonly string[];
182
+ /**
183
+ * This attempt's per-command ceiling, already halved for prior hangs by the
184
+ * caller's strike loop. Omitted -> the `phase` row's full configured ceiling,
185
+ * which is the right value for a single-attempt caller.
186
+ */
187
+ commandCeilingMs?: number;
124
188
  }
125
- export declare function runChild({ cwd, tools, prompt, signal, onLine, onContextUsage, onToolCall, spawn: spawnFn, extensions, onToolResult, contextWindow, thinking }: ChildRun): Promise<PhaseRunResult>;
189
+ /**
190
+ * The `phase` row of WORKER_PROFILES, resolved with this machine's config.
191
+ *
192
+ * Read here rather than at module load so a /task-config change reaches the next
193
+ * child, the same contract childBaseArgs already keeps. Both spawn paths in this
194
+ * file go through it, so the degraded final attempt cannot drift from the ordinary
195
+ * one — the mislabel class runDegradedFinalAttempt's own comment warns about.
196
+ */
197
+ export declare function phasePolicy(): WorkerGuardPolicy;
198
+ export declare function runChild({ cwd, tools, prompt, signal, onLine, onContextUsage, onToolCall, spawn: spawnFn, extensions, onToolResult, contextWindow, thinking, commandCeilingMs }: ChildRun): Promise<PhaseRunResult>;
126
199
  export interface PhaseDeps {
127
200
  cwd: string;
128
201
  taskId: string;
@@ -132,12 +205,12 @@ export interface PhaseDeps {
132
205
  /**
133
206
  * The parent session's context window in tokens, handed down to every child.
134
207
  *
135
- * pi's `--mode json` stream reports token counts but no window (issue #16),
136
- * so without this the gauge shows a bare number and — worse — the
137
- * StallDetector's CONTEXT CHURN rule, which is gated on a positive window,
138
- * can never fire. Children are spawned without `-m` (CHILD_BASE_ARGS) and so
139
- * run the parent's own default model; its window is the honest value.
140
- * Absent = unknown, and both consumers degrade exactly as they did before.
208
+ * pi's `--mode json` stream reports token counts but no window, so without
209
+ * this the gauge shows a bare number and — worse — the StallDetector's CONTEXT
210
+ * CHURN rule can never fire: it opens with `if (this.contextWindow <= 0)
211
+ * return false`. Children are spawned without `-m` (CHILD_BASE_ARGS) and so
212
+ * run the parent's own default model, which is what makes its window the
213
+ * honest value. Absent = unknown, and both consumers degrade.
141
214
  */
142
215
  contextWindow?: number;
143
216
  /**
@@ -185,11 +258,10 @@ export interface PhaseDeps {
185
258
  * the substitute answers directly and NONE of those guards run.
186
259
  *
187
260
  * The child's NAME is the first parameter because the name is what a caller
188
- * branches on and what a test wants to assert. It used to be discarded before
189
- * reaching the only injectable boundary (`spawn`), so a phase test had to
190
- * reconstruct it by matching prompt PROSE against prompts.ts — which made
191
- * prompt copy load-bearing test infrastructure in a codebase whose practice is
192
- * rewording prompts and A/B-ing them.
261
+ * branches on and what a test wants to assert. Discarded before it reaches
262
+ * the only injectable boundary (`spawn`), a phase test has to reconstruct it
263
+ * by matching prompt PROSE against prompts.ts — which makes prompt copy
264
+ * load-bearing test infrastructure in a codebase that rewords prompts.
193
265
  *
194
266
  * `spawn` stays: the ladder's OWN tests must drive a real process to exercise
195
267
  * the rungs. This seam is for callers to whom the child is a premise.
@@ -232,13 +304,10 @@ export interface PhaseDeps {
232
304
  * The subset of `PhaseDeps` a CALLER may supply — every injectable seam, derived
233
305
  * by naming what the runner owns instead of by listing what it does not.
234
306
  *
235
- * `TaskRunnerOptions` used to declare `spawnFn`, `runChild`, `runWorker` and a
236
- * seven-name `Pick` called `lookups` separately; `RunSingleTaskOptions` re-picked
237
- * all four, `runSingleTask` re-forwarded each by name, and the constructor spread
238
- * them back together. Four coordinated edits, none of which failed to compile if
239
- * you skipped one — the exact indictment this codebase already recorded against
240
- * `ConfigItem`. Four seams (`timeoutMs`, `sleepFor`, `childExtensions`,
241
- * `logDebug`) had in fact been left behind, so a runner-driven test of the
307
+ * Declaring the seams separately on `TaskRunnerOptions`, re-picking them on
308
+ * `RunSingleTaskOptions`, re-forwarding each by name and spreading them back
309
+ * together is four coordinated edits, none of which fails to compile if you skip
310
+ * one. Seams get left behind that way, and a runner-driven test of the
242
311
  * connection-error rung really slept and the debug trail could not be asserted at
243
312
  * all. Derived by `Omit`, a NEW seam field joins this with no second edit.
244
313
  */
@@ -254,16 +323,16 @@ export type PhaseSeams = Omit<PhaseDeps, 'cwd' | 'taskId' | 'signal' | 'onChildO
254
323
  *
255
324
  * THREE RUNAWAY GUARDS ride the same budget, because this is the runner every
256
325
  * /task-auto planning child goes through (clarify, decompose, coverage,
257
- * contract-extract) and until mx5-n 2026-08-14 it had none:
326
+ * contract-extract), and an unguarded planning child can burn a whole run:
258
327
  * • a LoopDetector, so an identical repeated tool call is killed and
259
328
  * re-prompted instead of being allowed to fill the context window;
260
329
  * • a StallDetector, the backstop for the varied-args thrash the loop
261
- * detector's short window cannot see — the shape that actually cost us a
262
- * 16-minute decompose child that was never going to return. It bounds
330
+ * detector's short window cannot see — a child that keeps calling tools with
331
+ * different arguments, learns nothing, and is never going to return. It bounds
263
332
  * consecutive no-new-ground calls and total context churn, NOT elapsed time;
264
- * • PHASE_CHILD_TIMEOUT_MS, a hard wall clock, OFF by default because the
265
- * measured healthy range (610-927s for a reasoning-on decompose) overlaps
266
- * any value that would catch the pathology. See its comment.
333
+ * • PHASE_CHILD_TIMEOUT_MS, a hard wall clock, OFF by default: a healthy
334
+ * reasoning-on planning child and a runaway one occupy the same range of
335
+ * elapsed times, so no threshold separates them. See its comment.
267
336
  * All three are checked BEFORE the triage ladder: we killed the child, so its
268
337
  * exit status describes our SIGTERM and says nothing about its verdict.
269
338
  */
@@ -292,8 +361,8 @@ export declare function prependHint(hint: string | null, prompt: string): string
292
361
  /**
293
362
  * The two things a phase child can disagree about. Everything else — the loop
294
363
  * and stall detectors, the wall clock, the loop trail, the triage ladder and its
295
- * budget — is the one loop's, because the two wrappers that used to differ
296
- * disagreed on nothing else that was ever observable.
364
+ * budget — is the one loop's. These two are the only differences observable from
365
+ * outside it.
297
366
  */
298
367
  export interface PhaseChildOptions {
299
368
  /**