@mjasnikovs/pi-task 0.38.28 → 0.38.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/dist/config/config.d.ts +70 -70
  2. package/dist/config/config.js +26 -35
  3. package/dist/config/extension-list.d.ts +6 -5
  4. package/dist/config/extension-list.js +3 -2
  5. package/dist/config/reasoning-args.d.ts +9 -7
  6. package/dist/config/reasoning-args.js +12 -10
  7. package/dist/config/reasoning.d.ts +44 -105
  8. package/dist/config/reasoning.js +27 -704
  9. package/dist/config/register.d.ts +34 -48
  10. package/dist/config/register.js +41 -51
  11. package/dist/config/tool-list.d.ts +16 -16
  12. package/dist/config/tool-list.js +1 -1
  13. package/dist/remote/bridge.d.ts +19 -10
  14. package/dist/remote/bridge.js +3 -2
  15. package/dist/remote/broadcast.js +3 -1
  16. package/dist/remote/events.js +12 -11
  17. package/dist/remote/history.d.ts +1 -1
  18. package/dist/remote/protocol.d.ts +6 -3
  19. package/dist/remote/protocol.js +2 -1
  20. package/dist/remote/push.d.ts +16 -16
  21. package/dist/remote/push.js +27 -27
  22. package/dist/remote/register.d.ts +3 -3
  23. package/dist/remote/register.js +17 -19
  24. package/dist/remote/server.d.ts +9 -8
  25. package/dist/remote/server.js +15 -14
  26. package/dist/remote/session-state.d.ts +5 -4
  27. package/dist/remote/session-state.js +8 -5
  28. package/dist/remote/sw.d.ts +7 -6
  29. package/dist/remote/sw.js +7 -6
  30. package/dist/remote/tailscale.d.ts +4 -2
  31. package/dist/remote/tailscale.js +4 -2
  32. package/dist/remote/ui-highlight.js +6 -5
  33. package/dist/remote/ui-render.js +4 -4
  34. package/dist/remote/ui-script.js +24 -24
  35. package/dist/remote/ui-styles.d.ts +1 -1
  36. package/dist/remote/ui-styles.js +10 -13
  37. package/dist/remote/ui-tools.js +9 -6
  38. package/dist/shared/child-extensions.d.ts +29 -17
  39. package/dist/shared/child-extensions.js +29 -17
  40. package/dist/shared/child-output.d.ts +30 -24
  41. package/dist/shared/child-output.js +25 -17
  42. package/dist/shared/child-process.d.ts +47 -40
  43. package/dist/shared/child-process.js +50 -59
  44. package/dist/shared/command-watchdog.d.ts +22 -16
  45. package/dist/shared/command-watchdog.js +28 -21
  46. package/dist/shared/fs-text.d.ts +16 -10
  47. package/dist/shared/fs-text.js +16 -10
  48. package/dist/shared/git-runner.d.ts +25 -25
  49. package/dist/shared/git-runner.js +25 -25
  50. package/dist/shared/leaked-tool-call.d.ts +17 -11
  51. package/dist/shared/leaked-tool-call.js +23 -15
  52. package/dist/shared/model-endpoint.d.ts +29 -16
  53. package/dist/shared/model-endpoint.js +33 -21
  54. package/dist/shared/pi-invocation.d.ts +7 -4
  55. package/dist/shared/pi-invocation.js +12 -7
  56. package/dist/shared/pkg-version.d.ts +13 -5
  57. package/dist/shared/pkg-version.js +13 -5
  58. package/dist/shared/reasoning-capability.d.ts +35 -24
  59. package/dist/shared/reasoning-capability.js +35 -24
  60. package/dist/shared/stream-watchdog.d.ts +60 -44
  61. package/dist/shared/stream-watchdog.js +62 -45
  62. package/dist/task/accept-debt.d.ts +41 -43
  63. package/dist/task/accept-debt.js +73 -65
  64. package/dist/task/api-synthesis.d.ts +24 -21
  65. package/dist/task/api-synthesis.js +32 -26
  66. package/dist/task/apis-contract.d.ts +32 -64
  67. package/dist/task/apis-contract.js +32 -64
  68. package/dist/task/artifact-closure.d.ts +27 -13
  69. package/dist/task/artifact-closure.js +95 -67
  70. package/dist/task/auto-commit.d.ts +46 -35
  71. package/dist/task/auto-commit.js +51 -38
  72. package/dist/task/auto-io.d.ts +45 -25
  73. package/dist/task/auto-io.js +57 -29
  74. package/dist/task/auto-orchestrator.d.ts +26 -24
  75. package/dist/task/auto-orchestrator.js +178 -162
  76. package/dist/task/auto-prompts.d.ts +36 -24
  77. package/dist/task/auto-prompts.js +40 -26
  78. package/dist/task/autofix-ledger.d.ts +27 -25
  79. package/dist/task/autofix-ledger.js +29 -26
  80. package/dist/task/batch-test-task.d.ts +20 -12
  81. package/dist/task/batch-test-task.js +67 -60
  82. package/dist/task/boot-probe.d.ts +60 -44
  83. package/dist/task/boot-probe.js +91 -72
  84. package/dist/task/cancel-input.d.ts +30 -16
  85. package/dist/task/cancel-input.js +20 -11
  86. package/dist/task/cancel-points.d.ts +27 -20
  87. package/dist/task/cancel-points.js +30 -22
  88. package/dist/task/child-runner.d.ts +46 -51
  89. package/dist/task/child-runner.js +48 -49
  90. package/dist/task/child-status.d.ts +23 -16
  91. package/dist/task/child-status.js +23 -16
  92. package/dist/task/clamp-output.js +12 -5
  93. package/dist/task/command-run.d.ts +31 -28
  94. package/dist/task/command-run.js +44 -35
  95. package/dist/task/command-shrink.d.ts +25 -18
  96. package/dist/task/command-shrink.js +37 -31
  97. package/dist/task/command-watchdog.d.ts +9 -6
  98. package/dist/task/command-watchdog.js +21 -15
  99. package/dist/task/context-attribution.d.ts +34 -26
  100. package/dist/task/context-attribution.js +34 -26
  101. package/dist/task/context-silence.d.ts +39 -29
  102. package/dist/task/context-silence.js +35 -25
  103. package/dist/task/context-usage.d.ts +25 -7
  104. package/dist/task/context-usage.js +21 -6
  105. package/dist/task/contracts.d.ts +8 -4
  106. package/dist/task/contracts.js +25 -17
  107. package/dist/task/coverage-loop.d.ts +22 -18
  108. package/dist/task/coverage-loop.js +35 -30
  109. package/dist/task/critique-probes.d.ts +13 -14
  110. package/dist/task/critique-probes.js +50 -39
  111. package/dist/task/debug-log.d.ts +13 -5
  112. package/dist/task/debug-log.js +32 -20
  113. package/dist/task/decompose-fidelity.d.ts +11 -9
  114. package/dist/task/decompose-fidelity.js +38 -33
  115. package/dist/task/decompose-granularity.d.ts +41 -38
  116. package/dist/task/decompose-granularity.js +41 -38
  117. package/dist/task/deep-render-check.d.ts +22 -14
  118. package/dist/task/deep-render-check.js +40 -31
  119. package/dist/task/dropped-input.d.ts +12 -7
  120. package/dist/task/dropped-input.js +5 -2
  121. package/dist/task/enforce-attribution.d.ts +38 -47
  122. package/dist/task/enforce-attribution.js +46 -52
  123. package/dist/task/enforce-guidelines.d.ts +31 -20
  124. package/dist/task/enforce-guidelines.js +32 -21
  125. package/dist/task/enrichment.d.ts +7 -2
  126. package/dist/task/enrichment.js +26 -14
  127. package/dist/task/env-notes.d.ts +16 -7
  128. package/dist/task/env-notes.js +48 -31
  129. package/dist/task/env-template-closure.d.ts +4 -4
  130. package/dist/task/env-template-closure.js +42 -34
  131. package/dist/task/external-context.d.ts +28 -21
  132. package/dist/task/external-context.js +17 -12
  133. package/dist/task/failure-classifier.d.ts +4 -5
  134. package/dist/task/failure-classifier.js +6 -7
  135. package/dist/task/file-inventory.d.ts +15 -11
  136. package/dist/task/file-inventory.js +25 -22
  137. package/dist/task/final-gate-fix.d.ts +74 -86
  138. package/dist/task/final-gate-fix.js +97 -116
  139. package/dist/task/final-gate-progress.d.ts +29 -46
  140. package/dist/task/final-gate-progress.js +40 -51
  141. package/dist/task/final-gate.d.ts +64 -97
  142. package/dist/task/final-gate.js +192 -199
  143. package/dist/task/fix-child.d.ts +21 -27
  144. package/dist/task/fix-child.js +21 -27
  145. package/dist/task/foreign-path.d.ts +6 -5
  146. package/dist/task/foreign-path.js +0 -0
  147. package/dist/task/frozen-conflict.d.ts +9 -10
  148. package/dist/task/frozen-conflict.js +61 -64
  149. package/dist/task/frozen-path-guard.d.ts +35 -14
  150. package/dist/task/frozen-path-guard.js +56 -39
  151. package/dist/task/gate-child.d.ts +27 -28
  152. package/dist/task/gate-child.js +37 -35
  153. package/dist/task/gate-deps.d.ts +34 -27
  154. package/dist/task/gate-deps.js +169 -159
  155. package/dist/task/gate-tally.d.ts +77 -80
  156. package/dist/task/gate-tally.js +65 -68
  157. package/dist/task/git-state-guard.d.ts +15 -11
  158. package/dist/task/git-state-guard.js +76 -66
  159. package/dist/task/impl-widget.d.ts +25 -16
  160. package/dist/task/impl-widget.js +27 -17
  161. package/dist/task/implementation-thinking.d.ts +33 -31
  162. package/dist/task/implementation-thinking.js +5 -6
  163. package/dist/task/implementation-turn.d.ts +34 -31
  164. package/dist/task/implementation-turn.js +29 -27
  165. package/dist/task/inline-markdown.d.ts +20 -7
  166. package/dist/task/inline-markdown.js +15 -6
  167. package/dist/task/launch-config-gap.js +25 -39
  168. package/dist/task/launch-contract.d.ts +18 -21
  169. package/dist/task/launch-contract.js +28 -30
  170. package/dist/task/launch-manifest.d.ts +6 -2
  171. package/dist/task/launch-manifest.js +35 -34
  172. package/dist/task/ledger.js +16 -14
  173. package/dist/task/lint-fix.d.ts +6 -8
  174. package/dist/task/lint-fix.js +67 -69
  175. package/dist/task/loop-detector.d.ts +9 -8
  176. package/dist/task/loop-detector.js +16 -12
  177. package/dist/task/mid-run-input.d.ts +17 -15
  178. package/dist/task/mid-run-input.js +17 -15
  179. package/dist/task/orchestrator.d.ts +24 -28
  180. package/dist/task/orchestrator.js +62 -64
  181. package/dist/task/orientation.d.ts +18 -23
  182. package/dist/task/orientation.js +24 -31
  183. package/dist/task/owned-freeze-conflict.d.ts +21 -20
  184. package/dist/task/owned-freeze-conflict.js +52 -85
  185. package/dist/task/owned-freeze-reassign.d.ts +40 -60
  186. package/dist/task/owned-freeze-reassign.js +41 -61
  187. package/dist/task/parsers.d.ts +4 -2
  188. package/dist/task/parsers.js +4 -4
  189. package/dist/task/phases.d.ts +41 -48
  190. package/dist/task/phases.js +180 -248
  191. package/dist/task/plan-io.d.ts +6 -7
  192. package/dist/task/plan-io.js +6 -7
  193. package/dist/task/plan-orchestrator.d.ts +10 -8
  194. package/dist/task/plan-orchestrator.js +14 -10
  195. package/dist/task/plan-prompts.d.ts +6 -5
  196. package/dist/task/plan-prompts.js +6 -5
  197. package/dist/task/plan-readonly.d.ts +4 -5
  198. package/dist/task/plan-readonly.js +4 -5
  199. package/dist/task/plan-rounds.d.ts +17 -29
  200. package/dist/task/plan-rounds.js +21 -34
  201. package/dist/task/plan-session.d.ts +58 -72
  202. package/dist/task/plan-session.js +61 -83
  203. package/dist/task/probe-gaming.d.ts +28 -27
  204. package/dist/task/probe-gaming.js +0 -0
  205. package/dist/task/prohibition-probe.d.ts +14 -16
  206. package/dist/task/prompts.d.ts +3 -4
  207. package/dist/task/prompts.js +17 -26
  208. package/dist/task/qa-transcript.d.ts +15 -22
  209. package/dist/task/qa-transcript.js +15 -21
  210. package/dist/task/question-box.d.ts +17 -13
  211. package/dist/task/question-box.js +19 -15
  212. package/dist/task/question-dedup.d.ts +6 -7
  213. package/dist/task/question-dedup.js +13 -14
  214. package/dist/task/question-dialog.d.ts +22 -32
  215. package/dist/task/question-dialog.js +22 -32
  216. package/dist/task/question-source.d.ts +18 -44
  217. package/dist/task/question-source.js +22 -51
  218. package/dist/task/refuted-constraint.d.ts +11 -31
  219. package/dist/task/refuted-constraint.js +27 -51
  220. package/dist/task/regenerable-artifacts.d.ts +12 -31
  221. package/dist/task/regenerable-artifacts.js +12 -31
  222. package/dist/task/render-check.d.ts +11 -22
  223. package/dist/task/render-check.js +33 -46
  224. package/dist/task/repo-health-check.d.ts +10 -14
  225. package/dist/task/repo-health-check.js +17 -23
  226. package/dist/task/requirements.d.ts +38 -71
  227. package/dist/task/requirements.js +78 -126
  228. package/dist/task/research-fanout-budget.d.ts +51 -88
  229. package/dist/task/research-fanout-budget.js +51 -88
  230. package/dist/task/research-worker.d.ts +33 -36
  231. package/dist/task/research-worker.js +39 -61
  232. package/dist/task/resume-gap.d.ts +14 -15
  233. package/dist/task/root-cause-repair.d.ts +9 -9
  234. package/dist/task/root-cause-repair.js +28 -40
  235. package/dist/task/run-bracket.d.ts +10 -13
  236. package/dist/task/run-end.d.ts +12 -22
  237. package/dist/task/run-end.js +8 -16
  238. package/dist/task/run-final-gate.d.ts +19 -21
  239. package/dist/task/run-final-gate.js +62 -80
  240. package/dist/task/runner-globs.d.ts +12 -13
  241. package/dist/task/runner-globs.js +12 -13
  242. package/dist/task/runner-resolve.d.ts +9 -9
  243. package/dist/task/runner-resolve.js +22 -23
  244. package/dist/task/script-escape.d.ts +10 -12
  245. package/dist/task/script-escape.js +13 -14
  246. package/dist/task/serve-entry.d.ts +1 -1
  247. package/dist/task/serve-entry.js +22 -25
  248. package/dist/task/service-blocks.js +4 -2
  249. package/dist/task/shipped-source.d.ts +11 -29
  250. package/dist/task/shipped-source.js +11 -29
  251. package/dist/task/skip-escape.js +10 -14
  252. package/dist/task/spec-urls.d.ts +26 -65
  253. package/dist/task/spec-urls.js +26 -65
  254. package/dist/task/spec-validation.d.ts +17 -20
  255. package/dist/task/spec-validation.js +17 -20
  256. package/dist/task/stall-detector.d.ts +23 -30
  257. package/dist/task/stall-detector.js +23 -30
  258. package/dist/task/stream-watchdog.d.ts +14 -12
  259. package/dist/task/stream-watchdog.js +14 -12
  260. package/dist/task/substitution-probe.d.ts +17 -20
  261. package/dist/task/substitution-probe.js +17 -20
  262. package/dist/task/task-gates.d.ts +36 -41
  263. package/dist/task/task-gates.js +95 -106
  264. package/dist/task/task-io.d.ts +4 -4
  265. package/dist/task/task-io.js +4 -4
  266. package/dist/task/task-parsers.js +4 -3
  267. package/dist/task/task-provenance.d.ts +2 -2
  268. package/dist/task/task-provenance.js +11 -13
  269. package/dist/task/task-types.d.ts +4 -3
  270. package/dist/task/terminal-outcome.d.ts +14 -16
  271. package/dist/task/terminal-outcome.js +12 -14
  272. package/dist/task/test-assembly.d.ts +13 -20
  273. package/dist/task/test-assembly.js +13 -20
  274. package/dist/task/timings.d.ts +5 -3
  275. package/dist/task/timings.js +5 -3
  276. package/dist/task/title-label.d.ts +9 -4
  277. package/dist/task/title-label.js +9 -4
  278. package/dist/task/type-only-answer.d.ts +44 -52
  279. package/dist/task/type-only-answer.js +44 -52
  280. package/dist/task/unfailable-command.d.ts +18 -24
  281. package/dist/task/unfailable-command.js +21 -27
  282. package/dist/task/unknown-routing.d.ts +10 -4
  283. package/dist/task/unknown-routing.js +10 -4
  284. package/dist/task/user-directives.d.ts +5 -8
  285. package/dist/task/user-directives.js +5 -8
  286. package/dist/task/verify-quality.d.ts +18 -22
  287. package/dist/task/verify-quality.js +45 -46
  288. package/dist/task/verify-reconcile.d.ts +15 -10
  289. package/dist/task/verify-reconcile.js +45 -43
  290. package/dist/task/verify-resolution.d.ts +24 -20
  291. package/dist/task/verify-resolution.js +51 -50
  292. package/dist/task/verify-work.d.ts +59 -66
  293. package/dist/task/verify-work.js +101 -138
  294. package/dist/task/widget.d.ts +15 -14
  295. package/dist/task/widget.js +22 -17
  296. package/dist/task/wiring-claims.d.ts +25 -32
  297. package/dist/task/wiring-claims.js +30 -35
  298. package/dist/task/write-guard.d.ts +39 -39
  299. package/dist/task/write-guard.js +48 -51
  300. package/dist/task/yolo.d.ts +34 -30
  301. package/dist/task/yolo.js +42 -37
  302. package/dist/workers/abstention.d.ts +21 -41
  303. package/dist/workers/abstention.js +27 -48
  304. package/dist/workers/brave-search.d.ts +4 -3
  305. package/dist/workers/brave-search.js +5 -2
  306. package/dist/workers/brave-warning.d.ts +7 -4
  307. package/dist/workers/brave-warning.js +19 -7
  308. package/dist/workers/ddg-search.d.ts +6 -6
  309. package/dist/workers/ddg-search.js +18 -12
  310. package/dist/workers/docs-cache.js +5 -2
  311. package/dist/workers/docs-chunk.d.ts +30 -37
  312. package/dist/workers/docs-chunk.js +37 -41
  313. package/dist/workers/docs-core.d.ts +28 -44
  314. package/dist/workers/docs-core.js +25 -44
  315. package/dist/workers/docs-index.js +4 -3
  316. package/dist/workers/docs-lookup.d.ts +15 -22
  317. package/dist/workers/docs-lookup.js +12 -21
  318. package/dist/workers/docs-project.d.ts +15 -9
  319. package/dist/workers/docs-project.js +17 -10
  320. package/dist/workers/docs-resolve.d.ts +19 -20
  321. package/dist/workers/docs-resolve.js +35 -32
  322. package/dist/workers/docs-retrieve.d.ts +5 -6
  323. package/dist/workers/docs-retrieve.js +18 -15
  324. package/dist/workers/exa-search.d.ts +9 -6
  325. package/dist/workers/exa-search.js +23 -12
  326. package/dist/workers/fetch-core.d.ts +13 -16
  327. package/dist/workers/fetch-core.js +23 -23
  328. package/dist/workers/focused-extractor.d.ts +12 -12
  329. package/dist/workers/focused-extractor.js +16 -19
  330. package/dist/workers/html-clean.js +24 -14
  331. package/dist/workers/http-request.d.ts +28 -20
  332. package/dist/workers/http-request.js +22 -17
  333. package/dist/workers/npm-version.d.ts +28 -11
  334. package/dist/workers/npm-version.js +24 -15
  335. package/dist/workers/phantom-imports.d.ts +15 -12
  336. package/dist/workers/phantom-imports.js +30 -24
  337. package/dist/workers/pi-worker-core.d.ts +86 -54
  338. package/dist/workers/pi-worker-core.js +112 -112
  339. package/dist/workers/pi-worker-docs.d.ts +24 -19
  340. package/dist/workers/pi-worker-docs.js +67 -76
  341. package/dist/workers/pi-worker-fetch.d.ts +7 -3
  342. package/dist/workers/pi-worker-fetch.js +27 -19
  343. package/dist/workers/pi-worker-search.js +12 -8
  344. package/dist/workers/pi-worker.d.ts +9 -4
  345. package/dist/workers/pi-worker.js +23 -10
  346. package/dist/workers/reasoning-warning.d.ts +18 -17
  347. package/dist/workers/reasoning-warning.js +22 -20
  348. package/dist/workers/research-cache.js +50 -78
  349. package/dist/workers/search-core.js +7 -5
  350. package/dist/workers/search-types.d.ts +10 -9
  351. package/dist/workers/search-types.js +9 -8
  352. package/dist/workers/session-hint.d.ts +13 -14
  353. package/dist/workers/session-hint.js +8 -9
  354. package/dist/workers/shared.d.ts +21 -25
  355. package/dist/workers/shared.js +0 -0
  356. package/dist/workers/single-read-extension.d.ts +14 -7
  357. package/dist/workers/single-read-extension.js +14 -7
  358. package/dist/workers/single-read-guard.d.ts +25 -28
  359. package/dist/workers/single-read-guard.js +32 -32
  360. package/dist/workers/typeonly-log.d.ts +12 -9
  361. package/dist/workers/typeonly-log.js +29 -33
  362. package/dist/workers/worker-channels.d.ts +15 -23
  363. package/dist/workers/worker-channels.js +15 -23
  364. package/dist/workers/worker-failure.d.ts +38 -46
  365. package/dist/workers/worker-failure.js +31 -39
  366. package/dist/workers/worker-kill.d.ts +25 -26
  367. package/dist/workers/worker-kill.js +16 -19
  368. package/dist/workers/worker-profiles.d.ts +43 -53
  369. package/dist/workers/worker-profiles.js +30 -38
  370. package/package.json +10 -8
@@ -1,15 +1,12 @@
1
1
  /**
2
- * requirements — requirement-level coverage accounting for /task-auto planning
3
- * (mx5 run 11, goal A).
2
+ * requirements — requirement-level coverage accounting for /task-auto planning.
4
3
  *
5
- * The failure this closes: the design's §10 Testing section REQUIRES test-first
6
- * cadence, Playwright CT with screenshot baselines, a `test:ct` script, a
7
- * separate test DB, and a `test/` dir and got ZERO tasks and ZERO per-task
8
- * injection. The coverage gate asked one holistic question ("do these tasks
9
- * cover the whole feature?"), and a task list that mirrors the spec's own
10
- * milestone list is structurally parity-complete, so the judge said COMPLETE in
11
- * round 1. Milestone-parity coverage is structurally blind to sections that
12
- * aren't milestones.
4
+ * The failure this closes: a single holistic coverage question ("do these tasks
5
+ * cover the whole feature?") is answerable YES by any task list that mirrors the
6
+ * spec's own milestone headings. Such a list is structurally parity-complete, so
7
+ * the sections that are NOT milestones a Testing section demanding a test
8
+ * script, a test database, a test directory can produce zero tasks and zero
9
+ * per-task injection while the judge still says COMPLETE.
13
10
  *
14
11
  * Mechanism (spec-shape-agnostic, contracts.ts pattern):
15
12
  * 1. EXTRACT requirement units as VERBATIM quotes from whatever structure the
@@ -25,10 +22,10 @@
25
22
  * pattern: content travels, not a pointer); requirements still unmapped
26
23
  * after the retry rounds are recorded user-visibly, never silently dropped.
27
24
  *
28
- * Goal C rides the same channel: when the spec mandates a verification
29
- * methodology ("a test lands in the same change as each new route"), that quote
30
- * is exactly what gets injected, and compose's VERIFY rules fold it into every
31
- * applicable task's runnable verification.
25
+ * A mandated verification methodology rides the same channel: when the spec says
26
+ * "a test lands in the same change as each new route", that quote is exactly what
27
+ * gets injected, and compose's VERIFY rules fold it into every applicable task's
28
+ * runnable verification.
32
29
  */
33
30
  import { normalise } from './contracts.js';
34
31
  import { makeLedger } from './ledger.js';
@@ -92,16 +89,12 @@ export function keepGroundedRequirements(entries, sourceDoc) {
92
89
  return kept;
93
90
  }
94
91
  /**
95
- * Bound the list WITHOUT doc-order truncation. Two measured failure shapes drive
96
- * the rule:
97
- * - an eager model extracts 40+ items top-down (every §1 decision row), so a
98
- * plain first-N cap systematically drops the TAIL sections exactly where
99
- * mx5 keeps its testing obligations;
100
- * - "given order" as the tie-break re-creates the same tail bias one level up
101
- * (mx5 run 16, measured live: the model emitted 185 requirements, 178
102
- * grounded — INCLUDING §9's "serves `/api` + static `dist/`", the clause
103
- * whose loss shipped a permanently blank app — and the cap's doc-order fill
104
- * cut all 138 past the cap, every one from the design's tail).
92
+ * Bound the list WITHOUT doc-order truncation. An extractor that works top-down
93
+ * yields more entries than the cap from the doc's early sections alone, so a
94
+ * plain first-N cap drops the TAIL sections wholesale and a spec keeps its
95
+ * testing and deployment obligations at the end. "Given order" as the tie-break
96
+ * re-creates the same bias one level up.
97
+ *
105
98
  * Rule (deterministic priority, not a knob): entries quoting an obligation-
106
99
  * marked passage survive first; the remaining budget is filled ROUND-ROBIN
107
100
  * across the source doc's sections (each section's entries in doc order), so
@@ -111,9 +104,9 @@ export function keepGroundedRequirements(entries, sourceDoc) {
111
104
  * cannot be located) the fill degrades to the old given-order behavior.
112
105
  */
113
106
  export function capRequirements(entries, passages, sourceDoc,
114
- /** A/B seam: `false` reproduces the pre-budget rule, so an offline harness can
115
- * score the shipped rule against the one it replaced without transcribing
116
- * sectionFairFill and letting the copy drift. Production never passes it. */
107
+ /** `false` skips the low-value deprioritisation, so a caller can compare the
108
+ * two fills without transcribing sectionFairFill. Production never passes it
109
+ * auto-orchestrator.ts calls this with three arguments. */
117
110
  deprioritiseLowValue = true) {
118
111
  if (entries.length <= MAX_REQUIREMENTS)
119
112
  return entries;
@@ -131,22 +124,20 @@ deprioritiseLowValue = true) {
131
124
  // "MUST log every request" is 22 characters and every length-based rule reads
132
125
  // it as a fragment. Filtering ahead of the marked/rest split deleted it.
133
126
  //
134
- // INSURANCE, not a measured win on mx5: across both 30-run pools exactly one
135
- // distinct quote per pool is low-value AND marked, and it is a genuinely
136
- // truncated one. The layering matters for specs whose obligations are SHORT,
137
- // which mx5's are not. Do not cite it as the reason tail coverage holds —
138
- // tail coverage is identical with the filter applied before the split.
127
+ // The ordering only matters for specs whose obligations are SHORT; it is not
128
+ // what makes tail coverage hold. That is sectionFairFill below.
139
129
  const pool = deprioritiseLowValue ? budgetedByObligation(rest, budget, sourceDoc) : rest;
140
130
  return [...marked.slice(0, MAX_REQUIREMENTS), ...sectionFairFill(pool, budget, sourceDoc)];
141
131
  }
142
132
  /** Longest a dependency-pin row can be before it is presumed to carry an
143
- * obligation after the pin. Real pins in the measured corpus run 32..48 chars;
144
- * the pin-prefixed lines that DO obligate ("TypeScript `6.0.3` — one strict
145
- * `tsconfig.json`: `strict`, `noUncheckedIndexedAccess`, …") run 130..260. */
133
+ * obligation after the pin. A bare pin is short; a pin-prefixed line that DOES
134
+ * obligate ("TypeScript `6.0.3` — one strict `tsconfig.json`: `strict`,
135
+ * `noUncheckedIndexedAccess`, …") is several times longer. */
146
136
  const MAX_PIN_LENGTH = 80;
147
137
  /** Cut mid-expression: an unbalanced fence or bracket, or a trailing separator.
148
138
  * NOT `;` — a complete clause legitimately ends with one, and dropping on `;`
149
- * discarded a runnable `lint` = `prettier … && eslint … && tsc --noEmit` line. */
139
+ * would discard a runnable line like `lint` = `prettier … && eslint … && tsc
140
+ * --noEmit`. */
150
141
  function isTruncatedQuote(q) {
151
142
  if ((q.match(/`/g) ?? []).length % 2 === 1)
152
143
  return true;
@@ -194,27 +185,20 @@ export function isLowValueQuote(quote) {
194
185
  /**
195
186
  * Deprioritise obligation-free quotes, but only as far as the BUDGET requires.
196
187
  *
197
- * Measured (mx5, 20402-char spec, two independent 30-run extraction pools): the
198
- * extractor's single-pass yield swings 20..160 for byte-identical input, and the
199
- * padding crowds real obligations out of the 40 that ship — high-yield runs land
200
- * FEWER critical obligations than low-yield ones. Critical obligations reaching
201
- * the shipped list go 8.50 → 9.37 of 16 on the design pool (10 runs better, 0
202
- * worse, p=0.0020) and 7.70 → 8.43 on the confirmation pool (12 / 0, p=0.0005).
188
+ * The extractor's single-pass yield swings wildly for byte-identical input, and
189
+ * the padding crowds real obligations out of the fixed number that ship — a
190
+ * high-yield run lands FEWER critical obligations than a low-yield one.
191
+ * Deprioritising the obligation-free quotes reverses that.
203
192
  *
204
193
  * BUDGETED, not absolute. Below the cap no slot is contested, so dropping there
205
- * destroys information and buys nothing; a run that filtered 55 quotes down to 20
206
- * lost its only carrier of the Argon2id obligation a DDL row that was correctly
207
- * classified as one — while 20 slots sat empty. So the low-value entries come back
208
- * in source-doc order until the list reaches the cap.
209
- *
210
- * Absolute filtering scored marginally higher on raw count (24 gains vs 22 across
211
- * both pools) and was rejected anyway: its extra gains are one more obligation in
212
- * an already-populated list, while its one loss is an obligation vanishing from a
213
- * run outright. Those are not the same size of mistake.
194
+ * destroys information and buys nothing a filter that runs unconditionally can
195
+ * leave slots empty while discarding the only carrier of a real obligation the
196
+ * lexical rules misread. So the low-value entries come back in source-doc order
197
+ * until the list reaches the cap.
214
198
  *
215
199
  * Doc order for the restore is the neutral choice: which entries return only
216
200
  * matters when more were dropped than there are free slots, and ordering by
217
- * anything fitted to an observed loss would be tuning the rule to one pool.
201
+ * anything else would fit the rule to one spec.
218
202
  */
219
203
  function budgetedByObligation(entries, budget, sourceDoc) {
220
204
  const keep = entries.filter(e => !isLowValueQuote(e.quote));
@@ -256,7 +240,7 @@ function normalisedSections(doc) {
256
240
  * whose normalised text contains its quote (the same containment rule that
257
241
  * grounded it), take each bucket's entries in in-section order, one per bucket
258
242
  * per round. Entries that cannot be located (or no doc) go to a trailing
259
- * bucket in given order — the pre-run-16 behavior, never worse. */
243
+ * bucket in given order — the pre-behavior, never worse. */
260
244
  function sectionFairFill(entries, budget, sourceDoc) {
261
245
  if (budget <= 0)
262
246
  return [];
@@ -302,11 +286,11 @@ function sectionFairFill(entries, budget, sourceDoc) {
302
286
  /**
303
287
  * DETERMINISTIC RECALL FLOOR (same medicine as the launch-contract checklist):
304
288
  * paragraphs carrying an obligation marker (word-bounded "required"/"must").
305
- * Extraction recall over a 20KB doc is the weak model's, and it is variance-
306
- * prone measured live, 1 of 5 runs kept 16 quotes with ZERO §10 items. The
307
- * host enumerates the marked passages; the prompt lists their head lines as a
308
- * checklist, and uncoveredPassages() below turns "a marked passage produced no
309
- * quote" into hard evidence for one forced re-extraction.
289
+ * Extraction recall over a long doc is the model's, and it varies run to run, so
290
+ * an entire section can come back with no quotes at all. The host enumerates the
291
+ * marked passages; the prompt lists their head lines as a checklist, and
292
+ * uncoveredPassages() below turns "a marked passage produced no quote" into hard
293
+ * evidence for one forced re-extraction.
310
294
  */
311
295
  export function enumerateObligationPassages(doc) {
312
296
  const out = [];
@@ -392,11 +376,10 @@ export const REQUIREMENT_EXTRACT_PROMPT = (feature, passages = []) => [
392
376
  * NOT exist or happen — there is no task that "delivers" an absence) or a GLOBAL
393
377
  * POLICY (a product-wide rule every slice obeys, not one slice's deliverable). The
394
378
  * per-task coverage map maps both to NONE forever, so left in the `unmapped` set
395
- * they kept the decompose loop's verdict INCOMPLETE and forced it to regenerate
396
- * the whole plan endlessly (mx5 run 12: 3 un-ownable NEGATIVE requirements drove a
397
- * complete full-stack plan to be overwritten by a backend-only one). These belong
398
- * in the CROSS-CUTTING carry — injected verbatim into every task — never fed back
399
- * as a missing area.
379
+ * they hold the decompose loop's verdict at INCOMPLETE and make it regenerate the
380
+ * whole plan every round which can replace a good plan with a worse one. These
381
+ * belong in the CROSS-CUTTING carry, injected verbatim into every task, never fed
382
+ * back as a missing area.
400
383
  *
401
384
  * Deterministic and precision-biased: it only reclassifies clear prohibitions and
402
385
  * clearly product-global policies. It does NOT need to catch every un-ownable line
@@ -485,7 +468,7 @@ export function accountCoverage(requirements, mappings) {
485
468
  acc.crossCutting.push(requirements[i]);
486
469
  // NONE — but a prohibition/global-policy requirement can never be OWNED by
487
470
  // a task (it states an absence or a product-wide rule); the model maps it
488
- // NONE every round, which used to force endless whole-plan regeneration.
471
+ // NONE every round, which forces endless whole-plan regeneration.
489
472
  // Carry it cross-cutting instead, so it stops driving the coverage loop.
490
473
  else if (isCrossCuttingRequirement(requirements[i].quote))
491
474
  acc.crossCutting.push(requirements[i]);
@@ -511,14 +494,13 @@ function formatEntry(e, marker) {
511
494
  * • `unresolved` — grounded requirements still unmapped after the retry rounds.
512
495
  * • `judgeFlagged` — free-text areas the holistic coverage judge flagged as
513
496
  * uncovered that requirement-extraction never captured as a tracked entry, so
514
- * the grounded channels above are structurally blind to them (mx5 2026-07-16:
515
- * §10's test-infra setup was seen ONLY by the judge and, having no carrier,
516
- * was warned-about then dropped). These are plain strings, not quotes of the
517
- * source; marked distinctly so a task can tell an inferred area from a verbatim
518
- * obligation.
497
+ * the grounded channels above are structurally blind to them: without this
498
+ * channel such an area is warned about once and then dropped. These are plain
499
+ * strings, not quotes of the source; marked distinctly so a task can tell an
500
+ * inferred area from a verbatim obligation.
519
501
  * • `danglingArtifacts` — runtime files the spec references but nothing
520
- * produces (mx5 run 13: the served `index.html` no task, tree entry, or
521
- * build output ever created), still unclaimed by any title at coverage
502
+ * produces (an `index.html` the server serves that no task, tree entry or
503
+ * build output ever creates), still unclaimed by any title at coverage
522
504
  * exhaustion. Deterministically extracted (artifact-closure.ts), so like
523
505
  * judge areas they are host-authored strings, not source quotes.
524
506
  */
@@ -543,8 +525,10 @@ export async function appendCarriedRequirements(cwd, crossCutting, unresolved =
543
525
  }
544
526
  /**
545
527
  * The read-only block refine/compose receive when carried requirements exist.
546
- * Verbatim content travels with every task (the directive pattern that works),
547
- * and the VERIFY mandate is explicitgoal C rides here.
528
+ * Verbatim content travels with every task the REFINE_PRESERVE_DIRECTIVE
529
+ * pattern in phases.ts, content rather than a pointer and the VERIFY mandate is
530
+ * spelled out, so a mandated verification methodology reaches every applicable
531
+ * task's runnable checks.
548
532
  */
549
533
  export function buildRequirementsBlock(requirements) {
550
534
  if (requirements.trim().length === 0)
@@ -566,17 +550,15 @@ export function buildRequirementsBlock(requirements) {
566
550
  ''
567
551
  ].join('\n');
568
552
  }
569
- // ─── Owned (task-mapped) requirements — the run-16 channel gap ──────────────
553
+ // ─── Owned (task-mapped) requirements ────────────────────────────────
570
554
  //
571
- // Of run 16's 40 kept requirements only the 6 CROSS-CUTTING ones were persisted
572
- // and injected; the 33 TASK-MAPPED ones rode the decompose ledger (shaping the
573
- // title list) and then vanished — nothing ever showed a task its OWN mapped
574
- // obligations. TASK_0008's refine read §9's "serves `/api` + static `dist/`",
575
- // quoted it in a grill question, and still narrowed the composed spec to
576
- // "SPA fallback serves index.html"; the shipped server never served the client
577
- // bundle and the app was permanently blank. An obligation the coverage map
578
- // assigned to a task must travel INTO that task as verbatim authoritative text,
579
- // exactly like the cross-cutting channel that measurably works.
555
+ // The CROSS-CUTTING requirements are persisted and injected into every task. The
556
+ // TASK-MAPPED ones only ride the decompose ledger, which shapes the title list —
557
+ // so without this channel nothing ever shows a task its OWN mapped obligations,
558
+ // and a refine that merely READ the clause can still narrow it away in the
559
+ // composed spec. An obligation the coverage map assigned to a task travels INTO
560
+ // that task here, as verbatim authoritative text, on the same channel the
561
+ // cross-cutting requirements use.
580
562
  const OWNED_REQUIREMENTS_FILE = 'requirements-owned.md';
581
563
  /**
582
564
  * Uncapped and never appended to — the mapping is recomputed whole per plan
@@ -650,48 +632,17 @@ export function buildOwnedRequirementsBlock(owned) {
650
632
  ].join('\n');
651
633
  }
652
634
  /**
653
- * BRACES for the owned channel (the PROMPT-1 pattern): deterministically append
654
- * each owned obligation the composed spec does not already carry as a
655
- * CONSTRAINTS bullet. Measured need (scripts/live-owned-requirement-compose-ab
656
- * .ts, 8 reps/arm on two real run-16 losses): with the belt block alone compose
657
- * folded the clause into CONSTRAINTS/ACCEPTANCE in only 2/8 reps per fixture
658
- * (baseline 0/8) an instruction the model mostly ignores, the PROMPT-4 shape.
659
- * A host-side append cannot be ignored. "Already carries" = the normalised
660
- * quote appears anywhere in the spec — belt-obeying reps aren't double-stated.
661
- * No CONSTRAINTS section (shape-invalid spec) → returned unchanged; this runs
662
- * only on specs the shape gate already accepted.
663
- *
664
- * NOT EXTENDED TO CONSUMER TASKS — REFUTED AT STEP 0, 2026-07-27. The proposal
665
- * was to classify owned requirements INVARIANT (prohibition-shaped) vs
666
- * DELIVERABLE and propagate the INVARIANTs from here to every task whose spec
667
- * names the same symbol/file, because mx5 run 17 gave all three Hono-RPC
668
- * obligations to TASK_0021 (which complied perfectly) while the four CONSUMER
669
- * tasks that never saw them — 0027/0031/0033/0034 — hand-wrote casts and shipped
670
- * 7 dead client call sites. It was not built, for two measured reasons
671
- * (scripts/owned-consumer-generality-step0.ts, re-runnable):
672
- *
673
- * 1. IT DOES NOT GENERALIZE. The task's own kill condition was <20% of a second
674
- * stack's OWNED requirements being prohibition-shaped. IAR1, 8 live
675
- * regenerations of the real plan-time pipeline over its real 10-task list:
676
- * 2/42 pooled = 4.8% (narrow four-phrase reading 1/42 = 2.4%). mx5 itself is
677
- * 7/33 = 21.2% only under the BROAD rule above; under "never/don't/must
678
- * not/do not" it is 2/33 = 6.1%. The structural reason is in accountCoverage
679
- * right here: a prohibition the map leaves NONE is already carried
680
- * cross-cutting to every task, so in the five reps that logged the split 18
681
- * of IAR1's 19 prohibition-shaped requirements were never owner-only in the
682
- * first place. mx5's 7 leaked because the model mapped them to a TASK.
683
- * 2. THE TARGETING RULE MISSES ITS OWN MOTIVATING CASE. Symbol/file relevance
684
- * would not have reached the four violators for the clause they actually
685
- * broke ("If a call isn't fully typed end-to-end via `hc`, fix the route
686
- * chaining/export, don't paper over it…"): its only extractable symbol is
687
- * `chaining/export`, which no consumer spec contains — 0 consumers. Its
688
- * siblings would have reached all four, attaching to 13/41 tasks each; across
689
- * mx5's 33 owned requirements the mean attach rate is 21% of all tasks and
690
- * 5/33 would attach to more than half of them (the task's own I1 trigger).
635
+ * The host-side belt for the owned channel: deterministically append each owned
636
+ * obligation the composed spec does not already carry as a CONSTRAINTS bullet.
637
+ * The injected block alone is an instruction compose can ignore; an append
638
+ * cannot be. "Already carries" = the normalised quote appears anywhere in the
639
+ * spec, so a spec that DID fold the clause in is not double-stated. No
640
+ * CONSTRAINTS section returned unchanged; this runs only on specs the shape
641
+ * gate already accepted.
691
642
  *
692
- * Do not re-open on mx5 evidence alone. A future attempt needs a second stack
693
- * where prohibition-shaped requirements actually land OWNED, and a targeting rule
694
- * that survives a clause whose symbols are prose.
643
+ * Scoped to the OWNING task only. A prohibition the coverage map leaves unowned is
644
+ * already carried cross-cutting to every task by `accountCoverage` above, so the
645
+ * owned channel is not the place to reach a requirement's other readers.
695
646
  */
696
647
  export function appendOwnedConstraints(spec, owned) {
697
648
  if (owned.length === 0)
@@ -709,8 +660,9 @@ export function appendOwnedConstraints(spec, owned) {
709
660
  .join('\n');
710
661
  return `${spec.slice(0, insertAt)}\n${bullets}${spec.slice(insertAt)}`;
711
662
  }
712
- /** The decompose-prompt ledger block (goal E's belt): the grounded requirement
713
- * list rides into decompose so structure-mirroring can't discharge it. */
663
+ /** The decompose-prompt ledger block: the grounded requirement list rides into
664
+ * decompose so a title list that mirrors the spec's own headings cannot
665
+ * discharge it. */
714
666
  export function buildRequirementsLedger(requirements) {
715
667
  if (requirements.length === 0)
716
668
  return '';
@@ -1,74 +1,48 @@
1
1
  /**
2
- * nexttask 5B — the two candidate bounds on worker:apis's project-source fan-out.
3
- *
4
- * ⚠ ONE of the levers in this file is wired: the RESCUE progress deadline
5
- * (`workerProgressCeilingMs`) SHIPPED ON in nexttask 9, on a PASS measured over 42
6
- * trials per arm against an instrument whose own false-break rate is on record at
7
- * 1.5%. CAP, SCALE and RESCUE-CARRY remain OFF unless their env var is set CAP
8
- * and SCALE were rejected on argument (see below), carry-forward was measured
9
- * HARMFUL on its own.
10
- *
11
- * The OFF levers exist so `scripts/live-research-fanout-budget-ab.ts` can run them
12
- * against the shipped baseline in the SAME build — the alternative (dist surgery)
13
- * measures a patched copy of the code and not the code. Nothing may read them
14
- * outside that harness until it reports PASS; a lever wired on argument rather
15
- * than measurement is the failure mode nexttasks exists to prevent.
16
- *
17
- * THE FAULT THEY TARGET (mx5 run 18, measured — scripts/research-restart-baserate.ts):
18
- * `worker:apis` fans out `pi-worker-docs(module: ".")` project-source lookups, each
19
- * of which spawns its own summarising child, and the per-worker wall-clock cap is
20
- * 240s. Pearson r(project lookups, worker wall clock) = 0.909 over 24 tasks. 0-4
21
- * lookups never timed out; every worker at >=46 lookups burned the FULL restart
22
- * budget — 3 attempts, 720s, two of them discarded whole. The 240s ceiling and a
23
- * 46-call fan-out are jointly unsatisfiable, so the timeout is not a backstop
24
- * there, it is the guaranteed outcome.
25
- *
26
- * TWO WAYS TO MAKE THEM SATISFIABLE, and the A/B — not this comment — decides:
2
+ * research-fanout-budget — the levers bounding worker:apis's project-source
3
+ * fan-out, and which of them is on.
4
+ *
5
+ * `workerProgressCeilingMs` is ON by default; its env var is the OFF switch. CAP
6
+ * (`projectDocsBudget`), SCALE (`fanoutTimeoutPolicy`) and RESCUE-CARRY
7
+ * (`workerCarryForward`) are OFF unless their env var is set. They stay in the
8
+ * shipped build so a harness can run them against the shipped baseline in the SAME
9
+ * build patching a copy of the code measures the copy, not the code. Nothing may
10
+ * read them outside such a harness.
11
+ *
12
+ * THE FAULT THEY TARGET. `worker:apis` fans out `pi-worker-docs(module: ".")`
13
+ * project-source lookups, and each one spawns its own summarising child. Under a
14
+ * fixed wall-clock cap, a large enough fan-out cannot finish inside it so the
15
+ * timeout is not a backstop there, it is the guaranteed outcome.
27
16
  *
28
17
  * CAP bound the fan-out to fit the ceiling. Told to the worker upfront
29
18
  * (projectDocsBudgetNotice) and enforced in the tool
30
- * (projectDocsBudgetExhausted), because run 18 shows the prompt alone
31
- * does not bind: the same worker is ALREADY told "be decisive" by
32
- * WORKER_TIMEOUT_HINT on every restart.
33
- * SCALE bound the ceiling to fit the fan-out: each project-source lookup
34
- * pushes the deadline out, up to a hard ceiling, so a worker that is
35
- * making progress is not killed for making progress.
36
- *
37
- * The risk each carries, and why the A/B's quality invariant is load-bearing: CAP
38
- * can produce a faster worker that ships a THINNER APIS section, which is a
39
- * regression wearing a win's clothes (memory/apis-contract-stage2-failed.md: a
40
- * lever moved behaviour 20/20 while fabricating 15% of it). SCALE can simply
41
- * spend the extra time and still time out, buying nothing.
42
- *
43
- * ─────────────────────────────────────────────────────────────────────────────
44
- * BOTH OF THE ABOVE ANSWER THE WRONG QUESTION. Kept for the record and for the
45
- * A/B's other arms, but they are not the fix.
46
- *
47
- * They argue about how long a worker may run. The actual defect is what happens
48
- * when it runs out: the attempt is killed and everything it produced is THROWN
49
- * AWAY, and the re-spawn is given a hint but no findings — so it re-reads the
50
- * same files against the same clock and dies in the same place. That is why
51
- * every worker at >=46 lookups burned the FULL budget rather than converging.
52
- * The r=0.909 correlation measures the amnesia, not an over-long task.
19
+ * (projectDocsBudgetExhausted). The prompt alone does not bind: the same
20
+ * worker is ALREADY told "be decisive" by WORKER_TIMEOUT_HINT
21
+ * (pi-worker-core.ts) on every restart.
22
+ * SCALE bound the ceiling to fit the fan-out: each project-source lookup pushes
23
+ * the deadline out, up to a hard ceiling, so a worker that is making
24
+ * progress is not killed for making progress.
25
+ *
26
+ * BOTH ANSWER THE WRONG QUESTION. They argue about how long a worker may run. The
27
+ * defect is what happens when it runs out: the attempt is killed, everything it
28
+ * produced is THROWN AWAY, and the re-spawn gets a hint but no findings — so it
29
+ * re-reads the same files against the same clock and dies in the same place.
53
30
  *
54
31
  * Judged against "the worker must return its work", CAP makes the worker read
55
- * LESS lowering the requirement so the metric goes green and SCALE is a
56
- * per-file constant that dies on one big file, and, being wall-clock, makes
57
- * answer quality a function of the user's hardware: the same task on a slower
58
- * local model loses its work and degrades. No constant fixes that.
59
- *
60
- * RESCUE (pi-worker-core.ts) carry the killed attempt's findings into the
61
- * next one and never return less than the best attempt produced, so a
62
- * restart CONVERGES instead of repeating; and deadline on lack of
63
- * PROGRESS rather than elapsed time, so "slow" and "stuck" stop being
64
- * the same verdict. Being stuck is already detected separately and
65
- * correctly by the output-stall probe (STALL_AFTER_MS), which resets
66
- * on progress and only kills when the model endpoint is unreachable.
67
- *
68
- * Its risk is its own, and the same quality invariant catches it: a half-written
69
- * entry replayed under "work already done" is exactly how a fabrication gets
70
- * laundered into a final answer. Hence the carry is framed as unverified, and
71
- * ungrounded-symbol and anti-synthesis counts gate the arm.
32
+ * LESS, lowering the requirement so the metric goes green; and SCALE is a per-file
33
+ * constant that dies on one big file and, being wall-clock, makes answer quality a
34
+ * function of the user's hardware the same task on a slower model loses its work.
35
+ *
36
+ * RESCUE (pi-worker-core.ts) carry the killed attempt's findings into the next
37
+ * one and never return less than the best attempt produced, so a restart
38
+ * CONVERGES instead of repeating; and deadline on lack of PROGRESS rather
39
+ * than elapsed time, so "slow" and "stuck" stop being the same verdict.
40
+ * Being stuck is already detected separately by the output-stall probe
41
+ * (STALL_AFTER_MS, worker-profiles.ts), which resets on progress.
42
+ *
43
+ * The carry has a risk of its own: a half-written entry replayed under "work
44
+ * already done" is how a fabrication gets laundered into a final answer. That is
45
+ * why the carry is framed to the worker as unverified.
72
46
  */
73
47
  /** Max project-source (`module: "."`) docs lookups per worker ATTEMPT. Unset = no cap. */
74
48
  export declare const PROJECT_DOCS_BUDGET_ENV = "PI_TASK_PROJECT_DOCS_BUDGET";
@@ -93,12 +67,10 @@ export declare const RESEARCH_LEVER_ENVS: readonly string[];
93
67
  * The levers, read ONCE, as a reader the profile table can be handed.
94
68
  *
95
69
  * WHY A SNAPSHOT AND NOT `process.env`. Every worker in one research phase must
96
- * see the same arm. The three lever values used to be resolved once in
97
- * `phases.ts` and threaded down as three separate `ResearchWorkerRun` fields for
98
- * exactly that reason; moving the resolution into the `research` profile would
99
- * have moved the READ down to each worker with it, and a harness that flips a
100
- * var mid-phase would then half-apply its own arm. Freezing the reader keeps the
101
- * read-once property while letting the profile own what the values MEAN.
70
+ * see the same lever values. A profile that read `process.env` itself would move
71
+ * the read down to each worker, and a var flipped mid-phase would then apply to
72
+ * some workers and not others. Freezing the reader keeps the read-once property
73
+ * while letting the profile own what the values MEAN.
102
74
  */
103
75
  export declare function snapshotLeverEnv(env?: Env): Env;
104
76
  /**
@@ -129,14 +101,10 @@ export declare function workerCarryForward(env?: Env): boolean;
129
101
  /**
130
102
  * The absolute backstop for the progress-based deadline.
131
103
  *
132
- * WHY THIS NUMBER. It is not a budget and it does not decide how long a worker
133
- * may take — the no-progress deadline does that, and it resets on every tool call.
134
- * This is the last-resort bound on a worker that never stops moving (an infinite
135
- * tool-call loop the loop detector somehow misses), so its only requirement is to
136
- * sit clear of the real workload. Measured on 42 progress-arm trials
137
- * (`~/tmp/research-fanout-ab-v3`): median 275s, p90 523s, **max 730s**. 20 minutes
138
- * is 1.6x the observed worst case, and 1.7x the 720s the SHIPPED path already
139
- * spends on a worker that burns all three attempts and returns nothing.
104
+ * It is not a budget and it does not decide how long a worker may take — the
105
+ * no-progress deadline does that, and it resets on every tool call. This is the
106
+ * last-resort bound on a worker that never stops moving (a tool-call loop the loop
107
+ * detector misses), so its only requirement is to sit clear of the real workload.
140
108
  *
141
109
  * A ceiling that never fires in production is the correct behaviour for a
142
110
  * backstop, not evidence it is untested: it fires under test
@@ -148,12 +116,7 @@ export declare const DEFAULT_WORKER_PROGRESS_CEILING_MS = 1200000;
148
116
  /**
149
117
  * The progress-based deadline's ceiling, or null when the lever is OFF.
150
118
  *
151
- * SHIPPED ON as of nexttask 9 — the env var is now the OFF switch, not the on
152
- * switch. Measured baseline vs progress over 42 trials/arm on a calibrated
153
- * instrument (A/A false-break 1.5%): worker-timeout restarts 22/24 → 0/24,
154
- * degrades 8/24 → 0/24, entries up on all four high-fan-out fixtures (TASK_0021
155
- * 11.0 → 25.5), quality invariants HOLD, every treatment-arm ungrounded flag
156
- * hand-verified as an instrument artifact rather than a fabrication.
119
+ * ON by default, so the env var is the OFF switch, not the on switch:
157
120
  *
158
121
  * unset ON at DEFAULT_WORKER_PROGRESS_CEILING_MS
159
122
  * "0" | "off" OFF — the fixed elapsed-time cap, exactly as before
@@ -167,9 +130,9 @@ export declare function workerProgressCeilingMs(env?: Env): number | null;
167
130
  * The upfront half of the CAP arm, appended to the APIS worker's prompt.
168
131
  *
169
132
  * Upfront and NUMERIC on purpose. The worker cannot ration a budget it learns
170
- * about only when it is spent, and "be decisive" — which it already receives on
171
- * every timeout restart — is exactly the unquantified version that run 18 shows
172
- * it ignoring until the third attempt.
133
+ * about only when it is spent, and "be decisive" — WORKER_TIMEOUT_HINT, which it
134
+ * already receives on every timeout restart — is the unquantified version of the
135
+ * same ask.
173
136
  */
174
137
  export declare function projectDocsBudgetNotice(budget: number): string;
175
138
  /** The enforcement half: what the tool returns once the budget is spent. */