@mjasnikovs/pi-task 0.38.29 → 0.38.30

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (370) hide show
  1. package/dist/config/config.d.ts +70 -70
  2. package/dist/config/config.js +26 -35
  3. package/dist/config/extension-list.d.ts +6 -5
  4. package/dist/config/extension-list.js +3 -2
  5. package/dist/config/reasoning-args.d.ts +9 -7
  6. package/dist/config/reasoning-args.js +12 -10
  7. package/dist/config/reasoning.d.ts +44 -105
  8. package/dist/config/reasoning.js +27 -704
  9. package/dist/config/register.d.ts +34 -48
  10. package/dist/config/register.js +41 -51
  11. package/dist/config/tool-list.d.ts +16 -16
  12. package/dist/config/tool-list.js +1 -1
  13. package/dist/remote/bridge.d.ts +19 -10
  14. package/dist/remote/bridge.js +3 -2
  15. package/dist/remote/broadcast.js +3 -1
  16. package/dist/remote/events.js +12 -11
  17. package/dist/remote/history.d.ts +1 -1
  18. package/dist/remote/protocol.d.ts +6 -3
  19. package/dist/remote/protocol.js +2 -1
  20. package/dist/remote/push.d.ts +16 -16
  21. package/dist/remote/push.js +27 -27
  22. package/dist/remote/register.d.ts +3 -3
  23. package/dist/remote/register.js +17 -19
  24. package/dist/remote/server.d.ts +9 -8
  25. package/dist/remote/server.js +15 -14
  26. package/dist/remote/session-state.d.ts +5 -4
  27. package/dist/remote/session-state.js +8 -5
  28. package/dist/remote/sw.d.ts +7 -6
  29. package/dist/remote/sw.js +7 -6
  30. package/dist/remote/tailscale.d.ts +4 -2
  31. package/dist/remote/tailscale.js +4 -2
  32. package/dist/remote/ui-highlight.js +6 -5
  33. package/dist/remote/ui-render.js +4 -4
  34. package/dist/remote/ui-script.js +24 -24
  35. package/dist/remote/ui-styles.d.ts +1 -1
  36. package/dist/remote/ui-styles.js +10 -13
  37. package/dist/remote/ui-tools.js +9 -6
  38. package/dist/shared/child-extensions.d.ts +29 -17
  39. package/dist/shared/child-extensions.js +29 -17
  40. package/dist/shared/child-output.d.ts +30 -24
  41. package/dist/shared/child-output.js +25 -17
  42. package/dist/shared/child-process.d.ts +47 -40
  43. package/dist/shared/child-process.js +50 -59
  44. package/dist/shared/command-watchdog.d.ts +22 -16
  45. package/dist/shared/command-watchdog.js +28 -21
  46. package/dist/shared/fs-text.d.ts +16 -10
  47. package/dist/shared/fs-text.js +16 -10
  48. package/dist/shared/git-runner.d.ts +25 -25
  49. package/dist/shared/git-runner.js +25 -25
  50. package/dist/shared/leaked-tool-call.d.ts +17 -11
  51. package/dist/shared/leaked-tool-call.js +23 -15
  52. package/dist/shared/model-endpoint.d.ts +29 -16
  53. package/dist/shared/model-endpoint.js +33 -21
  54. package/dist/shared/pi-invocation.d.ts +7 -4
  55. package/dist/shared/pi-invocation.js +12 -7
  56. package/dist/shared/pkg-version.d.ts +13 -5
  57. package/dist/shared/pkg-version.js +13 -5
  58. package/dist/shared/reasoning-capability.d.ts +35 -24
  59. package/dist/shared/reasoning-capability.js +35 -24
  60. package/dist/shared/stream-watchdog.d.ts +60 -44
  61. package/dist/shared/stream-watchdog.js +62 -45
  62. package/dist/task/accept-debt.d.ts +41 -43
  63. package/dist/task/accept-debt.js +73 -65
  64. package/dist/task/api-synthesis.d.ts +24 -21
  65. package/dist/task/api-synthesis.js +32 -26
  66. package/dist/task/apis-contract.d.ts +32 -64
  67. package/dist/task/apis-contract.js +32 -64
  68. package/dist/task/artifact-closure.d.ts +27 -13
  69. package/dist/task/artifact-closure.js +95 -67
  70. package/dist/task/auto-commit.d.ts +46 -35
  71. package/dist/task/auto-commit.js +51 -38
  72. package/dist/task/auto-io.d.ts +45 -25
  73. package/dist/task/auto-io.js +57 -29
  74. package/dist/task/auto-orchestrator.d.ts +26 -24
  75. package/dist/task/auto-orchestrator.js +178 -162
  76. package/dist/task/auto-prompts.d.ts +36 -24
  77. package/dist/task/auto-prompts.js +40 -26
  78. package/dist/task/autofix-ledger.d.ts +27 -25
  79. package/dist/task/autofix-ledger.js +29 -26
  80. package/dist/task/batch-test-task.d.ts +20 -12
  81. package/dist/task/batch-test-task.js +67 -60
  82. package/dist/task/boot-probe.d.ts +60 -44
  83. package/dist/task/boot-probe.js +91 -72
  84. package/dist/task/cancel-input.d.ts +30 -16
  85. package/dist/task/cancel-input.js +20 -11
  86. package/dist/task/cancel-points.d.ts +27 -20
  87. package/dist/task/cancel-points.js +30 -22
  88. package/dist/task/child-runner.d.ts +46 -51
  89. package/dist/task/child-runner.js +48 -49
  90. package/dist/task/child-status.d.ts +23 -16
  91. package/dist/task/child-status.js +23 -16
  92. package/dist/task/clamp-output.js +12 -5
  93. package/dist/task/command-run.d.ts +31 -28
  94. package/dist/task/command-run.js +44 -35
  95. package/dist/task/command-shrink.d.ts +25 -18
  96. package/dist/task/command-shrink.js +37 -31
  97. package/dist/task/command-watchdog.d.ts +9 -6
  98. package/dist/task/command-watchdog.js +21 -15
  99. package/dist/task/context-attribution.d.ts +34 -26
  100. package/dist/task/context-attribution.js +34 -26
  101. package/dist/task/context-silence.d.ts +39 -29
  102. package/dist/task/context-silence.js +35 -25
  103. package/dist/task/context-usage.d.ts +16 -9
  104. package/dist/task/context-usage.js +16 -9
  105. package/dist/task/contracts.d.ts +8 -4
  106. package/dist/task/contracts.js +25 -17
  107. package/dist/task/coverage-loop.d.ts +22 -18
  108. package/dist/task/coverage-loop.js +35 -30
  109. package/dist/task/critique-probes.d.ts +13 -14
  110. package/dist/task/critique-probes.js +50 -39
  111. package/dist/task/debug-log.d.ts +13 -5
  112. package/dist/task/debug-log.js +32 -20
  113. package/dist/task/decompose-fidelity.d.ts +11 -9
  114. package/dist/task/decompose-fidelity.js +38 -33
  115. package/dist/task/decompose-granularity.d.ts +41 -38
  116. package/dist/task/decompose-granularity.js +41 -38
  117. package/dist/task/deep-render-check.d.ts +22 -14
  118. package/dist/task/deep-render-check.js +40 -31
  119. package/dist/task/dropped-input.d.ts +12 -7
  120. package/dist/task/dropped-input.js +5 -2
  121. package/dist/task/enforce-attribution.d.ts +38 -47
  122. package/dist/task/enforce-attribution.js +46 -52
  123. package/dist/task/enforce-guidelines.d.ts +31 -20
  124. package/dist/task/enforce-guidelines.js +32 -21
  125. package/dist/task/enrichment.d.ts +7 -2
  126. package/dist/task/enrichment.js +26 -14
  127. package/dist/task/env-notes.d.ts +16 -7
  128. package/dist/task/env-notes.js +48 -31
  129. package/dist/task/env-template-closure.d.ts +4 -4
  130. package/dist/task/env-template-closure.js +42 -34
  131. package/dist/task/external-context.d.ts +28 -21
  132. package/dist/task/external-context.js +17 -12
  133. package/dist/task/failure-classifier.d.ts +4 -5
  134. package/dist/task/failure-classifier.js +6 -7
  135. package/dist/task/file-inventory.d.ts +15 -11
  136. package/dist/task/file-inventory.js +25 -22
  137. package/dist/task/final-gate-fix.d.ts +74 -86
  138. package/dist/task/final-gate-fix.js +97 -116
  139. package/dist/task/final-gate-progress.d.ts +29 -46
  140. package/dist/task/final-gate-progress.js +40 -51
  141. package/dist/task/final-gate.d.ts +64 -97
  142. package/dist/task/final-gate.js +192 -199
  143. package/dist/task/fix-child.d.ts +21 -27
  144. package/dist/task/fix-child.js +21 -27
  145. package/dist/task/foreign-path.d.ts +6 -5
  146. package/dist/task/foreign-path.js +0 -0
  147. package/dist/task/frozen-conflict.d.ts +9 -10
  148. package/dist/task/frozen-conflict.js +61 -64
  149. package/dist/task/frozen-path-guard.d.ts +35 -14
  150. package/dist/task/frozen-path-guard.js +56 -39
  151. package/dist/task/gate-child.d.ts +27 -28
  152. package/dist/task/gate-child.js +36 -35
  153. package/dist/task/gate-deps.d.ts +34 -27
  154. package/dist/task/gate-deps.js +169 -159
  155. package/dist/task/gate-tally.d.ts +77 -80
  156. package/dist/task/gate-tally.js +65 -68
  157. package/dist/task/git-state-guard.d.ts +15 -11
  158. package/dist/task/git-state-guard.js +76 -66
  159. package/dist/task/impl-widget.d.ts +25 -16
  160. package/dist/task/impl-widget.js +27 -17
  161. package/dist/task/implementation-thinking.d.ts +33 -31
  162. package/dist/task/implementation-thinking.js +5 -6
  163. package/dist/task/implementation-turn.d.ts +34 -31
  164. package/dist/task/implementation-turn.js +29 -27
  165. package/dist/task/inline-markdown.d.ts +20 -7
  166. package/dist/task/inline-markdown.js +15 -6
  167. package/dist/task/launch-config-gap.js +25 -39
  168. package/dist/task/launch-contract.d.ts +18 -21
  169. package/dist/task/launch-contract.js +28 -30
  170. package/dist/task/launch-manifest.d.ts +6 -2
  171. package/dist/task/launch-manifest.js +35 -34
  172. package/dist/task/ledger.js +16 -14
  173. package/dist/task/lint-fix.d.ts +6 -8
  174. package/dist/task/lint-fix.js +67 -69
  175. package/dist/task/loop-detector.d.ts +9 -8
  176. package/dist/task/loop-detector.js +16 -12
  177. package/dist/task/mid-run-input.d.ts +17 -15
  178. package/dist/task/mid-run-input.js +17 -15
  179. package/dist/task/orchestrator.d.ts +24 -28
  180. package/dist/task/orchestrator.js +62 -64
  181. package/dist/task/orientation.d.ts +18 -23
  182. package/dist/task/orientation.js +24 -31
  183. package/dist/task/owned-freeze-conflict.d.ts +21 -20
  184. package/dist/task/owned-freeze-conflict.js +52 -85
  185. package/dist/task/owned-freeze-reassign.d.ts +40 -60
  186. package/dist/task/owned-freeze-reassign.js +41 -61
  187. package/dist/task/parsers.d.ts +4 -2
  188. package/dist/task/parsers.js +4 -4
  189. package/dist/task/phases.d.ts +41 -48
  190. package/dist/task/phases.js +179 -248
  191. package/dist/task/plan-io.d.ts +6 -7
  192. package/dist/task/plan-io.js +6 -7
  193. package/dist/task/plan-orchestrator.d.ts +10 -8
  194. package/dist/task/plan-orchestrator.js +14 -10
  195. package/dist/task/plan-prompts.d.ts +6 -5
  196. package/dist/task/plan-prompts.js +6 -5
  197. package/dist/task/plan-readonly.d.ts +4 -5
  198. package/dist/task/plan-readonly.js +4 -5
  199. package/dist/task/plan-rounds.d.ts +17 -29
  200. package/dist/task/plan-rounds.js +21 -34
  201. package/dist/task/plan-session.d.ts +58 -72
  202. package/dist/task/plan-session.js +61 -83
  203. package/dist/task/probe-gaming.d.ts +28 -27
  204. package/dist/task/probe-gaming.js +0 -0
  205. package/dist/task/prohibition-probe.d.ts +14 -16
  206. package/dist/task/prompts.d.ts +3 -4
  207. package/dist/task/prompts.js +17 -26
  208. package/dist/task/qa-transcript.d.ts +15 -22
  209. package/dist/task/qa-transcript.js +15 -21
  210. package/dist/task/question-box.d.ts +17 -13
  211. package/dist/task/question-box.js +19 -15
  212. package/dist/task/question-dedup.d.ts +6 -7
  213. package/dist/task/question-dedup.js +13 -14
  214. package/dist/task/question-dialog.d.ts +22 -32
  215. package/dist/task/question-dialog.js +22 -32
  216. package/dist/task/question-source.d.ts +18 -44
  217. package/dist/task/question-source.js +22 -51
  218. package/dist/task/refuted-constraint.d.ts +11 -31
  219. package/dist/task/refuted-constraint.js +27 -51
  220. package/dist/task/regenerable-artifacts.d.ts +12 -31
  221. package/dist/task/regenerable-artifacts.js +12 -31
  222. package/dist/task/render-check.d.ts +11 -22
  223. package/dist/task/render-check.js +33 -46
  224. package/dist/task/repo-health-check.d.ts +10 -14
  225. package/dist/task/repo-health-check.js +17 -23
  226. package/dist/task/requirements.d.ts +38 -71
  227. package/dist/task/requirements.js +78 -126
  228. package/dist/task/research-fanout-budget.d.ts +51 -88
  229. package/dist/task/research-fanout-budget.js +51 -88
  230. package/dist/task/research-worker.d.ts +29 -39
  231. package/dist/task/research-worker.js +37 -61
  232. package/dist/task/resume-gap.d.ts +14 -15
  233. package/dist/task/root-cause-repair.d.ts +9 -9
  234. package/dist/task/root-cause-repair.js +28 -40
  235. package/dist/task/run-bracket.d.ts +10 -13
  236. package/dist/task/run-end.d.ts +12 -22
  237. package/dist/task/run-end.js +8 -16
  238. package/dist/task/run-final-gate.d.ts +19 -21
  239. package/dist/task/run-final-gate.js +62 -80
  240. package/dist/task/runner-globs.d.ts +12 -13
  241. package/dist/task/runner-globs.js +12 -13
  242. package/dist/task/runner-resolve.d.ts +9 -9
  243. package/dist/task/runner-resolve.js +22 -23
  244. package/dist/task/script-escape.d.ts +10 -12
  245. package/dist/task/script-escape.js +13 -14
  246. package/dist/task/serve-entry.d.ts +1 -1
  247. package/dist/task/serve-entry.js +22 -25
  248. package/dist/task/service-blocks.js +4 -2
  249. package/dist/task/shipped-source.d.ts +11 -29
  250. package/dist/task/shipped-source.js +11 -29
  251. package/dist/task/skip-escape.js +10 -14
  252. package/dist/task/spec-urls.d.ts +26 -65
  253. package/dist/task/spec-urls.js +26 -65
  254. package/dist/task/spec-validation.d.ts +17 -20
  255. package/dist/task/spec-validation.js +17 -20
  256. package/dist/task/stall-detector.d.ts +23 -30
  257. package/dist/task/stall-detector.js +23 -30
  258. package/dist/task/stream-watchdog.d.ts +14 -12
  259. package/dist/task/stream-watchdog.js +14 -12
  260. package/dist/task/substitution-probe.d.ts +17 -20
  261. package/dist/task/substitution-probe.js +17 -20
  262. package/dist/task/task-gates.d.ts +36 -41
  263. package/dist/task/task-gates.js +95 -106
  264. package/dist/task/task-io.d.ts +4 -4
  265. package/dist/task/task-io.js +4 -4
  266. package/dist/task/task-parsers.js +4 -3
  267. package/dist/task/task-provenance.d.ts +2 -2
  268. package/dist/task/task-provenance.js +11 -13
  269. package/dist/task/task-types.d.ts +4 -3
  270. package/dist/task/terminal-outcome.d.ts +14 -16
  271. package/dist/task/terminal-outcome.js +12 -14
  272. package/dist/task/test-assembly.d.ts +13 -20
  273. package/dist/task/test-assembly.js +13 -20
  274. package/dist/task/timings.d.ts +5 -3
  275. package/dist/task/timings.js +5 -3
  276. package/dist/task/title-label.d.ts +9 -4
  277. package/dist/task/title-label.js +9 -4
  278. package/dist/task/type-only-answer.d.ts +44 -52
  279. package/dist/task/type-only-answer.js +44 -52
  280. package/dist/task/unfailable-command.d.ts +18 -24
  281. package/dist/task/unfailable-command.js +21 -27
  282. package/dist/task/unknown-routing.d.ts +10 -4
  283. package/dist/task/unknown-routing.js +10 -4
  284. package/dist/task/user-directives.d.ts +5 -8
  285. package/dist/task/user-directives.js +5 -8
  286. package/dist/task/verify-quality.d.ts +18 -22
  287. package/dist/task/verify-quality.js +45 -46
  288. package/dist/task/verify-reconcile.d.ts +15 -10
  289. package/dist/task/verify-reconcile.js +45 -43
  290. package/dist/task/verify-resolution.d.ts +24 -20
  291. package/dist/task/verify-resolution.js +51 -50
  292. package/dist/task/verify-work.d.ts +59 -66
  293. package/dist/task/verify-work.js +101 -138
  294. package/dist/task/widget.d.ts +15 -14
  295. package/dist/task/widget.js +22 -17
  296. package/dist/task/wiring-claims.d.ts +25 -32
  297. package/dist/task/wiring-claims.js +30 -35
  298. package/dist/task/write-guard.d.ts +39 -39
  299. package/dist/task/write-guard.js +48 -51
  300. package/dist/task/yolo.d.ts +34 -30
  301. package/dist/task/yolo.js +42 -37
  302. package/dist/workers/abstention.d.ts +21 -41
  303. package/dist/workers/abstention.js +27 -48
  304. package/dist/workers/brave-search.d.ts +4 -3
  305. package/dist/workers/brave-search.js +5 -2
  306. package/dist/workers/brave-warning.d.ts +7 -4
  307. package/dist/workers/brave-warning.js +19 -7
  308. package/dist/workers/ddg-search.d.ts +6 -6
  309. package/dist/workers/ddg-search.js +18 -12
  310. package/dist/workers/docs-cache.js +5 -2
  311. package/dist/workers/docs-chunk.d.ts +30 -37
  312. package/dist/workers/docs-chunk.js +37 -41
  313. package/dist/workers/docs-core.d.ts +28 -44
  314. package/dist/workers/docs-core.js +25 -44
  315. package/dist/workers/docs-index.js +4 -3
  316. package/dist/workers/docs-lookup.d.ts +15 -22
  317. package/dist/workers/docs-lookup.js +12 -21
  318. package/dist/workers/docs-project.d.ts +15 -9
  319. package/dist/workers/docs-project.js +17 -10
  320. package/dist/workers/docs-resolve.d.ts +19 -20
  321. package/dist/workers/docs-resolve.js +35 -32
  322. package/dist/workers/docs-retrieve.d.ts +5 -6
  323. package/dist/workers/docs-retrieve.js +18 -15
  324. package/dist/workers/exa-search.d.ts +9 -6
  325. package/dist/workers/exa-search.js +23 -12
  326. package/dist/workers/fetch-core.d.ts +13 -16
  327. package/dist/workers/fetch-core.js +23 -23
  328. package/dist/workers/focused-extractor.d.ts +12 -12
  329. package/dist/workers/focused-extractor.js +16 -19
  330. package/dist/workers/html-clean.js +24 -14
  331. package/dist/workers/http-request.d.ts +28 -20
  332. package/dist/workers/http-request.js +22 -17
  333. package/dist/workers/npm-version.d.ts +28 -11
  334. package/dist/workers/npm-version.js +24 -15
  335. package/dist/workers/phantom-imports.d.ts +15 -12
  336. package/dist/workers/phantom-imports.js +30 -24
  337. package/dist/workers/pi-worker-core.d.ts +69 -71
  338. package/dist/workers/pi-worker-core.js +100 -109
  339. package/dist/workers/pi-worker-docs.d.ts +24 -19
  340. package/dist/workers/pi-worker-docs.js +67 -76
  341. package/dist/workers/pi-worker-fetch.d.ts +7 -3
  342. package/dist/workers/pi-worker-fetch.js +27 -19
  343. package/dist/workers/pi-worker-search.js +12 -8
  344. package/dist/workers/pi-worker.d.ts +9 -4
  345. package/dist/workers/pi-worker.js +21 -14
  346. package/dist/workers/reasoning-warning.d.ts +18 -17
  347. package/dist/workers/reasoning-warning.js +22 -20
  348. package/dist/workers/research-cache.js +50 -78
  349. package/dist/workers/search-core.js +7 -5
  350. package/dist/workers/search-types.d.ts +10 -9
  351. package/dist/workers/search-types.js +9 -8
  352. package/dist/workers/session-hint.d.ts +13 -14
  353. package/dist/workers/session-hint.js +8 -9
  354. package/dist/workers/shared.d.ts +21 -25
  355. package/dist/workers/shared.js +0 -0
  356. package/dist/workers/single-read-extension.d.ts +14 -7
  357. package/dist/workers/single-read-extension.js +14 -7
  358. package/dist/workers/single-read-guard.d.ts +25 -28
  359. package/dist/workers/single-read-guard.js +32 -32
  360. package/dist/workers/typeonly-log.d.ts +12 -9
  361. package/dist/workers/typeonly-log.js +29 -33
  362. package/dist/workers/worker-channels.d.ts +15 -23
  363. package/dist/workers/worker-channels.js +15 -23
  364. package/dist/workers/worker-failure.d.ts +38 -46
  365. package/dist/workers/worker-failure.js +31 -39
  366. package/dist/workers/worker-kill.d.ts +25 -26
  367. package/dist/workers/worker-kill.js +16 -19
  368. package/dist/workers/worker-profiles.d.ts +43 -53
  369. package/dist/workers/worker-profiles.js +30 -38
  370. package/package.json +10 -8
@@ -12,8 +12,9 @@
12
12
  * /task-cancel cancel the running task (soft-terminal — still resumable)
13
13
  *
14
14
  * The orchestrator persists after every phase boundary to
15
- * <cwd>/.pi-tasks/TASK_NNNN.md. All user interaction during phases runs through
16
- * ctx.ui dialogs; the main pi chat only receives the final spec.
15
+ * <cwd>/.pi-tasks/TASK_NNNN.md. User interaction during phases runs through the
16
+ * SessionUI bridge — a local ctx.ui dialog raced against a remote browser card
17
+ * never through the main conversation, which only receives the final spec.
17
18
  */
18
19
  import * as fsp from 'node:fs/promises';
19
20
  import * as path from 'node:path';
@@ -61,11 +62,12 @@ let piApi = null;
61
62
  /**
62
63
  * The live session's thinking level, as a {@link ThinkingControl}.
63
64
  *
64
- * Goes through `piApi` rather than the command ctx because
65
- * `ExtensionCommandContext` exposes `thinkingLevel` READ-ONLY; the setter lives
66
- * on the extension API. Before `registerTask(pi)` has run there is nothing to
67
- * control, so this degrades to a no-op pair rather than throwing a task that
68
- * cannot move the level should still run.
65
+ * Goes through `piApi` rather than the command ctx because `ExtensionContext`
66
+ * (which the command ctx extends) carries `thinkingLevel` as a plain optional
67
+ * VALUE with no setter; `setThinkingLevel` lives on `ExtensionAPI`. Before
68
+ * `registerTask(pi)` has run there is nothing to control, so this degrades to a
69
+ * no-op pair rather than throwing — a task that cannot move the level should
70
+ * still run.
69
71
  */
70
72
  function piThinkingControl() {
71
73
  const api = piApi;
@@ -93,9 +95,9 @@ export class TaskRunner {
93
95
  _deps;
94
96
  _pc;
95
97
  /**
96
- * Per-phase wall-clock durations collected during the run. Written to the
97
- * `## phase timings` section on successful completion so we can spot
98
- * regressions and target future speed work. Each top-level entry is a
98
+ * Per-phase wall-clock durations collected during the run, written to the
99
+ * `## phase timings` section on completion, and again from the catch so a
100
+ * failed run still records what it got through. Each top-level entry is a
99
101
  * phase (refine/research/grill/compose/critique); children are optional
100
102
  * sub-step splits the phase chose to record via deps.recordSubStep.
101
103
  */
@@ -113,8 +115,8 @@ export class TaskRunner {
113
115
  this._fixInstruction = opts.fixInstruction;
114
116
  this._implAwaited = opts.implAwaited ?? false;
115
117
  this._startedAt = Date.now();
116
- // We'll populate id/title/phase lazily in run().
117
- // Placeholder real values set in run().
118
+ // Placeholder: id/title/phase are only known once run() has allocated or
119
+ // read the task file.
118
120
  this._widgetState = {
119
121
  taskId: '',
120
122
  title: '',
@@ -137,7 +139,7 @@ export class TaskRunner {
137
139
  },
138
140
  // Handed DOWN so the child's own snapshot carries a window and the
139
141
  // StallDetector's churn rule can arm; resolveContextUsage below stays
140
- // as the fallback for a child that still reports none (issue #16).
142
+ // as the fallback for a child that still reports none.
141
143
  contextWindow: parentContextWindow,
142
144
  onContextUsage: snapshot => {
143
145
  this._widgetState.contextUsage = resolveContextUsage(snapshot, this._widgetState.contextUsage, parentContextWindow);
@@ -175,16 +177,15 @@ export class TaskRunner {
175
177
  cancel() {
176
178
  this._abort.abort();
177
179
  }
178
- /** Execute the full task lifecycle. Mid-run input holds instead of starting
179
- * a competing turn for the whole of it, and the terminal interception is
180
- * armed for the same window (`withRun`); nested inside `runGatedTask` or
181
- * the `/task-auto` loop the bracket refcounts, so this changes nothing there
182
- * and covers the fire-and-forget `runSingleTask` path on its own. */
183
180
  /**
184
- * Run the task and NAME how it ended.
181
+ * Run the task and NAME how it ended (`RunEnd`), so no caller has to re-read
182
+ * the task file to find out.
185
183
  *
186
- * This returned `void`, so the caller re-read the task file to learn what had
187
- * just happened here see run-end.ts for the report that got wrong.
184
+ * Mid-run input holds instead of starting a competing turn for the whole of
185
+ * it, and the terminal interception is armed for the same window (`withRun`);
186
+ * nested inside `runGatedTask` or the `/task-auto` loop the bracket refcounts,
187
+ * so this changes nothing there and covers the fire-and-forget
188
+ * `runSingleTask` path on its own.
188
189
  */
189
190
  async run() {
190
191
  return withRun(this._ctx, {}, () => this._run());
@@ -226,11 +227,12 @@ export class TaskRunner {
226
227
  await this._onStart(id);
227
228
  // Wire up per-task debug log (<cwd>/.pi-tasks/TASK_XXXX-debug.log).
228
229
  const debugLogPath = path.join(tasksDir(cwd), `${id}-debug.log`);
229
- // Left UNSET at level `off`, so the ~39 `logDebug?.(…)` sites downstream
230
- // short-circuit before they format a string and the file is never created.
231
- // A caller-supplied `logDebug` seam WINS: it is the only way to observe
232
- // the ~39 trail decisions from a runner-driven test, and production never
233
- // sets one, so the file writer is unaffected.
230
+ // `gateDebugWriter` returns undefined at level `off`, so every
231
+ // `logDebug?.(…)` site downstream short-circuits before it formats a string
232
+ // and the file is never created. A caller-supplied `logDebug` seam WINS
233
+ // (`??=`): it is the only way to observe the trail decisions from a
234
+ // runner-driven test, and production never sets one, so the file writer is
235
+ // unaffected.
234
236
  this._deps.logDebug ??= gateDebugWriter((msg) => {
235
237
  const line = `${new Date().toISOString()} ${msg}\n`;
236
238
  fsp.appendFile(debugLogPath, line).catch(() => {
@@ -295,9 +297,9 @@ export class TaskRunner {
295
297
  await postCommitPhase(phase, this._deps, this._pc, out);
296
298
  // SAFE CHECKPOINT (phase boundary): this phase's output is on disk
297
299
  // and the next `advance()` has not moved front-matter forward, so a
298
- // resume re-enters at exactly this phase. Without this the whole
299
- // spec pipeline (refine→critique, ~4.5 min on the mx5 run, research
300
- // alone ~3 min) runs to completion after a cancel is requested.
300
+ // resume re-enters at exactly this phase. Without a checkpoint here
301
+ // the whole refine→critique pipeline runs to completion after a
302
+ // cancel is requested.
301
303
  // Throwing USER_CANCELLED reuses the existing cancellation path:
302
304
  // handleFailure leaves the task resumable and /task-auto's catch
303
305
  // announces the resume hint.
@@ -375,10 +377,11 @@ export class TaskRunner {
375
377
  throw new Error('extension not initialised (no ExtensionAPI captured)');
376
378
  }
377
379
  armImplWidget(meta, { oneShot: true });
378
- // Always name a delivery mode. pi ignores it when the session is idle and
379
- // uses it when something else is streaming so this one call is correct
380
- // in both cases, where an isIdle() check is a check-then-act race that
381
- // loses to any turn starting in between (issue #8).
380
+ // Always name a delivery mode. pi's `prompt()` consults `streamingBehavior`
381
+ // only inside `if (this.isStreaming)`, so naming one is inert on an idle
382
+ // session and queues on a busy one correct in both cases, where an
383
+ // isIdle() check is a check-then-act race that loses to any turn starting
384
+ // in between.
382
385
  piApi.sendUserMessage(spec, { deliverAs: 'followUp' });
383
386
  }
384
387
  /**
@@ -418,9 +421,8 @@ export class TaskRunner {
418
421
  * deliver its spec. With waitForImplementation, block until the agent finishes
419
422
  * implementing the delivered spec.
420
423
  *
421
- * The ending comes from `TaskRunner.run`. It used to be read back off the task
422
- * file's front matter — a disk round-trip this process made to learn what it had
423
- * just done, and one that could not tell a cancel from a failure.
424
+ * The ending in the result comes from `TaskRunner.run` itself, not from re-reading
425
+ * the task file's front matter — which cannot tell a cancel from a failure.
424
426
  */
425
427
  export async function runSingleTask(ctx, cwd, rawPrompt, opts = {}) {
426
428
  let taskId = '';
@@ -441,10 +443,12 @@ export async function runSingleTask(ctx, cwd, rawPrompt, opts = {}) {
441
443
  withSession: async (newCtx) => {
442
444
  freshCtx = newCtx;
443
445
  getBridge().currentCtx = newCtx; // keep remote dispatch ctx fresh across session replacement
444
- // Same reason, for the terminal: pi clears every extension terminal
445
- // input listener when the old session is invalidated, and that
446
- // happens at the START of each task — precisely the window a typed
447
- // /task-auto-cancel has to survive. No-op unless a run armed one.
446
+ // Same reason, for the terminal: pi wires
447
+ // `setBeforeSessionInvalidate(() => this.resetExtensionUI())`, and
448
+ // `resetExtensionUI` calls `clearExtensionTerminalInputListeners()`.
449
+ // Every extension listener dies at the START of each task — precisely
450
+ // the window a typed /task-auto-cancel has to survive. No-op unless a
451
+ // run armed one.
448
452
  rearmCancelListener(newCtx);
449
453
  const runner = new TaskRunner({
450
454
  ctx: newCtx,
@@ -460,7 +464,8 @@ export async function runSingleTask(ctx, cwd, rawPrompt, opts = {}) {
460
464
  // here rather than at either call site.
461
465
  const release = holdImplementationThinking(opts.thinkingControl ?? piThinkingControl());
462
466
  try {
463
- // Queue-or-run: never throws, whatever else is on the session (issue #8).
467
+ // Queue-or-run: naming a delivery mode means pi's
468
+ // "Agent is already processing" throw is unreachable here.
464
469
  await newCtx.sendUserMessage(spec, { deliverAs: 'followUp' });
465
470
  if (opts.waitForImplementation) {
466
471
  await newCtx.waitForIdle();
@@ -502,12 +507,9 @@ export async function runSingleTask(ctx, cwd, rawPrompt, opts = {}) {
502
507
  // delivered and the task file already reads `completed`:
503
508
  //
504
509
  // • the user interrupted and declined to steer — a pause, not a fault;
505
- // • the implementation turn died with stopReason "error" (a context-overflow
506
- // 400, say), which must stop /task-auto here rather than let it commit and
507
- // advance on a file that says `completed`.
508
- //
509
- // Both used to reach the caller as extra fields beside a boolean, and both are
510
- // endings.
510
+ // • the implementation turn died with stopReason "error", which must stop
511
+ // /task-auto here rather than let it commit and advance on a file that
512
+ // says `completed`.
511
513
  let end = runEnd;
512
514
  if (end.kind === 'completed' && interrupted)
513
515
  end = { kind: 'interrupted' };
@@ -536,9 +538,9 @@ export const gateRunTask = (c, cwd, t, opts) => runSingleTask(c, cwd, t, {
536
538
  // NO `seams` here, deliberately. Threading them would need a field on
537
539
  // `GateParams` and another on `GateDeps`, and nothing — production or
538
540
  // test — would set either: the gate is reached through two orchestrators
539
- // that build their params from a task file. An unused field on a seam
540
- // roster is the `WorkerOutcome.reason` shape (written twelve times, read
541
- // by nothing), so this stays unplumbed until a test actually needs it.
541
+ // that build their params from a task file. `WorkerOutcome.reason` is what
542
+ // that costs: written at every `workerUnavailable` call site and read
543
+ // nowhere. So this stays unplumbed until a test actually needs it.
542
544
  });
543
545
  /**
544
546
  * Demote a task file to a resumable state after a gate (or its implementation)
@@ -567,15 +569,13 @@ export async function markResumable(cwd, taskId) {
567
569
  export async function runGatedTask(ctx, cwd, raw, opts = {}) {
568
570
  // The GATES are part of the run, and they are child processes with the host
569
571
  // session idle — the same hold window as the spec phases. Bracketing only
570
- // TaskRunner would leave verify/enforce looking like "no run", which a live
571
- // run on pi 0.82.1 showed as runActive=false while the widget still read
572
- // "verifying work" (issue #8). The body has many early returns, so the
573
- // bracket lives in this wrapper rather than in a dozen places. The same
574
- // bracket arms the raw-stdin interception for the WHOLE run: without it a
575
- // plain /task had no terminal path at all — only /task-auto armed one so a
576
- // line typed during it went into pi's queue and fired after the run (seen
577
- // live). No onCancel: a typed /task-auto-cancel goes through the generic
578
- // bridge dispatch here.
572
+ // TaskRunner would leave verify/enforce reading as "no run" while the widget
573
+ // still says "verifying work". The body has many early returns, so the bracket
574
+ // lives in this wrapper rather than in a dozen places. The same bracket arms
575
+ // the raw-stdin interception for the WHOLE run: without it a line typed during
576
+ // a plain /task lands in pi's `pendingUserInputs` and fires after the run. No
577
+ // onCancel: a typed /task-auto-cancel goes through the generic bridge dispatch
578
+ // here.
579
579
  await withRun(ctx, {}, () => runGatedTaskInner(ctx, cwd, raw, opts));
580
580
  }
581
581
  async function runGatedTaskInner(ctx, cwd, raw, opts = {}) {
@@ -595,10 +595,8 @@ async function runGatedTaskInner(ctx, cwd, raw, opts = {}) {
595
595
  const res = await deps.runTask(active, cwd, raw, { resumeId: opts.resumeId });
596
596
  active = res.ctx ?? active;
597
597
  const tag = res.taskId || 'Task';
598
- // One dispatch over the named ending. The four-branch ladder this replaces put
599
- // a CANCELLED run into the `!ok` arm, so `/task-cancel` overwrote the file's
600
- // `cancelled` with `failed` and told the user their task had stopped and needed
601
- // fixing. Resumability comes from RUN_END_POLICY; the wording stays here,
598
+ // One dispatch over the named ending, so a cancel can never be reported as a
599
+ // failure. Resumability comes from RUN_END_POLICY; the wording stays here,
602
600
  // because `/task-auto` says `/task-auto-resume` where this says `/task-resume`.
603
601
  if (!runSucceeded(res.end)) {
604
602
  const policy = RUN_END_POLICY[res.end.kind];
@@ -656,7 +654,7 @@ async function handleTask(args, ctx) {
656
654
  // When a gate is enabled, /task awaits the implementation and runs the same
657
655
  // verify + enforce gates a /task-auto sub-task does. With both gates off
658
656
  // (the default), /task stays fire-and-forget: hand the spec to the main
659
- // conversation and return immediately, exactly as before.
657
+ // conversation and return immediately.
660
658
  const cfg = getConfig();
661
659
  if (cfg.verifyWork || cfg.enforceGuidelines) {
662
660
  await runGatedTask(ctx, cwd, raw);
@@ -1,17 +1,16 @@
1
1
  /**
2
- * Project orientation core — a bounded snapshot of the few files every research
3
- * worker re-reads cold to learn "what is this project" (manifest, config, domain
4
- * types, schema, entrypoints, API surface). The four workers run as separate
5
- * child processes with no shared memory, so today each one independently
6
- * `read()`s the same hot files: across the recorded mx5 run package.json was
7
- * read 87×, src/types/index.ts 82×, and 55% of all worker reads were repeats of
8
- * a file another worker in the same task had already read.
2
+ * Project orientation core — a bounded snapshot of the few files a research worker
3
+ * re-reads cold to learn "what is this project" (manifest, config, domain types,
4
+ * schema, entrypoints, API surface). The four research workers are separate child
5
+ * processes with no shared memory, so without this each one reads the same hot
6
+ * files for itself.
9
7
  *
10
- * This module picks that orientation core from the file inventory (repo-agnostic,
11
- * by path convention), reads it ONCE in the parent, and the caller folds it into
12
- * the shared prompt header so every worker already has those files and skips
13
- * the cold read. It is purely additive: nothing is blocked, so a worker can still
14
- * read anything it wants; orientation only removes the need to.
8
+ * This module picks that core from the file inventory (repo-agnostic, by path
9
+ * convention) and reads it ONCE in the parent. The caller folds the block into a
10
+ * prompt: refine gets a tier-0/1 subset, and phases.ts prepends the full block to
11
+ * the two READ-HEAVY research workers (`worker:files`, `worker:apis`) not to all
12
+ * four. It is purely additive: nothing is blocked, so a worker can still read
13
+ * anything it wants; orientation only removes the need to.
15
14
  *
16
15
  * Bounded by design — the snapshot can never overflow the prompt regardless of
17
16
  * repo size: a hard total byte budget, a per-file cap (one huge file can't eat
@@ -20,23 +19,19 @@
20
19
  * core; reading takes an injectable reader so it can be exercised without a repo.
21
20
  */
22
21
  /**
23
- * Total bytes of file content the orientation block may contain (~10k tokens).
24
- * This is the real overflow guard: it bounds the block regardless of repo size,
25
- * and because the snapshot is prepended to each read-heavy worker it also caps
26
- * the prefill those workers pay. Selection stops as soon as adding a file would
27
- * exceed it.
22
+ * Total bytes the emitted orientation block may occupy. This is the real overflow
23
+ * guard: it bounds the block regardless of repo size, and because the snapshot is
24
+ * prepended to each read-heavy worker it also caps the prefill those workers pay.
25
+ * Selection stops as soon as adding a file would exceed it.
28
26
  */
29
27
  export declare const ORIENTATION_BYTE_BUDGET: number;
30
28
  /** A single file larger than this is skipped (read by the worker as before). */
31
29
  export declare const ORIENTATION_PER_FILE_MAX: number;
32
30
  /**
33
31
  * Backstop file-count cap — a guard against a pathological repo with hundreds of
34
- * tiny core files packing the byte budget into noise, NOT a normal-case limit.
35
- * It is deliberately set high enough that the byte budget binds first on real
36
- * repos (verified: mx5/aiz-server hit the budget at ~16 files; a 5000-file repo
37
- * yields only ~6 orientation candidates because leaf source is filtered out). An
38
- * earlier cap of 16 wrongly bound before the budget — e.g. it dropped 5 core
39
- * files on a 165-file repo while leaving 17KB of budget unused.
32
+ * tiny core files packing the byte budget into noise, NOT a normal-case limit. Set
33
+ * high enough that the byte budget binds first: whenever this cap is what stops
34
+ * selection, budget is left unspent and core files are dropped for no reason.
40
35
  */
41
36
  export declare const ORIENTATION_MAX_FILES = 40;
42
37
  /**
@@ -1,17 +1,16 @@
1
1
  /**
2
- * Project orientation core — a bounded snapshot of the few files every research
3
- * worker re-reads cold to learn "what is this project" (manifest, config, domain
4
- * types, schema, entrypoints, API surface). The four workers run as separate
5
- * child processes with no shared memory, so today each one independently
6
- * `read()`s the same hot files: across the recorded mx5 run package.json was
7
- * read 87×, src/types/index.ts 82×, and 55% of all worker reads were repeats of
8
- * a file another worker in the same task had already read.
2
+ * Project orientation core — a bounded snapshot of the few files a research worker
3
+ * re-reads cold to learn "what is this project" (manifest, config, domain types,
4
+ * schema, entrypoints, API surface). The four research workers are separate child
5
+ * processes with no shared memory, so without this each one reads the same hot
6
+ * files for itself.
9
7
  *
10
- * This module picks that orientation core from the file inventory (repo-agnostic,
11
- * by path convention), reads it ONCE in the parent, and the caller folds it into
12
- * the shared prompt header so every worker already has those files and skips
13
- * the cold read. It is purely additive: nothing is blocked, so a worker can still
14
- * read anything it wants; orientation only removes the need to.
8
+ * This module picks that core from the file inventory (repo-agnostic, by path
9
+ * convention) and reads it ONCE in the parent. The caller folds the block into a
10
+ * prompt: refine gets a tier-0/1 subset, and phases.ts prepends the full block to
11
+ * the two READ-HEAVY research workers (`worker:files`, `worker:apis`) not to all
12
+ * four. It is purely additive: nothing is blocked, so a worker can still read
13
+ * anything it wants; orientation only removes the need to.
15
14
  *
16
15
  * Bounded by design — the snapshot can never overflow the prompt regardless of
17
16
  * repo size: a hard total byte budget, a per-file cap (one huge file can't eat
@@ -20,23 +19,19 @@
20
19
  * core; reading takes an injectable reader so it can be exercised without a repo.
21
20
  */
22
21
  /**
23
- * Total bytes of file content the orientation block may contain (~10k tokens).
24
- * This is the real overflow guard: it bounds the block regardless of repo size,
25
- * and because the snapshot is prepended to each read-heavy worker it also caps
26
- * the prefill those workers pay. Selection stops as soon as adding a file would
27
- * exceed it.
22
+ * Total bytes the emitted orientation block may occupy. This is the real overflow
23
+ * guard: it bounds the block regardless of repo size, and because the snapshot is
24
+ * prepended to each read-heavy worker it also caps the prefill those workers pay.
25
+ * Selection stops as soon as adding a file would exceed it.
28
26
  */
29
27
  export const ORIENTATION_BYTE_BUDGET = 40 * 1024;
30
28
  /** A single file larger than this is skipped (read by the worker as before). */
31
29
  export const ORIENTATION_PER_FILE_MAX = 12 * 1024;
32
30
  /**
33
31
  * Backstop file-count cap — a guard against a pathological repo with hundreds of
34
- * tiny core files packing the byte budget into noise, NOT a normal-case limit.
35
- * It is deliberately set high enough that the byte budget binds first on real
36
- * repos (verified: mx5/aiz-server hit the budget at ~16 files; a 5000-file repo
37
- * yields only ~6 orientation candidates because leaf source is filtered out). An
38
- * earlier cap of 16 wrongly bound before the budget — e.g. it dropped 5 core
39
- * files on a 165-file repo while leaving 17KB of budget unused.
32
+ * tiny core files packing the byte budget into noise, NOT a normal-case limit. Set
33
+ * high enough that the byte budget binds first: whenever this cap is what stops
34
+ * selection, budget is left unspent and core files are dropped for no reason.
40
35
  */
41
36
  export const ORIENTATION_MAX_FILES = 40;
42
37
  /** Code/config/doc extensions worth pre-reading; everything else is ignored. */
@@ -100,10 +95,9 @@ function depth(p) {
100
95
  */
101
96
  export function orientationTier(path) {
102
97
  const lower = path.toLowerCase();
103
- // Never orient on vendored/build output or tests: a dependency's manifest or
104
- // a big *.test.ts would otherwise outrank the project's own files and eat the
105
- // budget (validated against the mx5 traces node_modules/hono/package.json
106
- // and zod-schemas.test.ts both crowded out genuinely hot project files). A
98
+ // Never orient on vendored/build output or tests: a dependency's package.json
99
+ // is tier 0 by basename and a `*.test.ts` under `src/types/` is tier 2, so
100
+ // either would outrank the project's own files and eat the budget. A
107
101
  // git-ls-files inventory won't list these anyway; this is belt-and-braces.
108
102
  if (/(^|\/)(node_modules|dist|build|out|vendor|\.git|coverage)\//.test(lower))
109
103
  return null;
@@ -167,10 +161,9 @@ export async function buildOrientation(inventoryPaths, readFile, opts = {}) {
167
161
  const supplied = new Set();
168
162
  const parts = [];
169
163
  // Budget the *emitted* block, not just the raw content: the per-file fence
170
- // (`--- path ---\n` + the `\n\n` join) and the fixed wrapper add up across
171
- // many files and would otherwise let the block overrun the budget (a 27-file
172
- // repo overran a content-only budget by >1KB). Seed `used` with the wrapper
173
- // so the final block is guaranteed ≤ byteBudget.
164
+ // (`--- path ---\n` + the `\n\n` join) and the fixed wrapper add up across many
165
+ // files, so a content-only budget lets the block overrun. Seeding `used` with
166
+ // the wrapper makes `Buffer.byteLength(block) <= byteBudget` an invariant.
174
167
  const HEADER = `PROJECT ORIENTATION (full contents of the project's core files — `
175
168
  + `already provided, do not re-read these)\n`;
176
169
  const TRAILER = '\n\n';
@@ -9,13 +9,11 @@ export interface CategoryFreeze {
9
9
  /**
10
10
  * One unsatisfiable pair, keyed by the REQUIREMENT rather than by the path.
11
11
  *
12
- * Grouping matters for the resolution's size. mx5 run 18's TASK_0023 carries
13
- * two owned build-contract clauses that between them name three frozen paths;
14
- * per-path findings would demand three separate ownership grants (and the same
15
- * pair twice over, because that spec states its freeze in CONSTRAINTS and again
16
- * in ACCEPTANCE). Per requirement, the rewrite is told which files that one
17
- * obligation names and grants only what it needs — which is what keeps
18
- * `inv-no-spec-inflation` satisfiable at all.
12
+ * Grouping this way bounds the resolution. A requirement naming several frozen
13
+ * files would otherwise yield one finding per file, and a spec that states its
14
+ * freeze in CONSTRAINTS and again in ACCEPTANCE would yield each of those twice.
15
+ * Per requirement, the resolution is told which files that ONE obligation names
16
+ * and grants only what it needs.
19
17
  */
20
18
  export interface OwnedFreezeConflict {
21
19
  /** The owned requirement line, verbatim. */
@@ -55,14 +53,13 @@ export interface OwnedFreezeOptions {
55
53
  /**
56
54
  * Is this repo-relative token an existing SOURCE file of the tree the spec
57
55
  * will run against? Supplied by the caller (compose knows its cwd; the
58
- * measured implementation is "tracked by git" — see `trackedSourceOracle`).
56
+ * usual implementation is "tracked by git" — see `trackedSourceOracle`).
59
57
  *
60
- * Two false-positive classes die here, both observed at STEP 0 on the real
61
- * TASK_0023 spec: route literals and build outputs (`/api`, `dist/`,
62
- * `dist/app.css` named by the very clause that is the true positive, but
63
- * not files anyone can edit), and files a task is about to CREATE, which a
64
- * freeze on the existing tree does not block. Omitted → every path-shaped
65
- * token counts (the broad reading, reported alongside at STEP 0).
58
+ * Two false-positive classes die here: build outputs (`dist/app.css` named
59
+ * by the same clause that names the real file, but not something anyone
60
+ * edits), and files a task is about to CREATE, which a freeze on the existing
61
+ * tree does not block. Omitted every path-shaped token counts, which is the
62
+ * broad reading.
66
63
  */
67
64
  isSource?: (p: string) => boolean;
68
65
  }
@@ -75,7 +72,7 @@ export interface OwnedFreezeOptions {
75
72
  */
76
73
  export declare function findOwnedFreezeConflicts(spec: string | null | undefined, opts?: OwnedFreezeOptions): OwnedFreezeConflict[];
77
74
  /**
78
- * The measured `isSource` oracle: a token counts only when git tracks it in
75
+ * The production `isSource` oracle: a token counts only when git tracks it in
79
76
  * `cwd`. Tracked ⇒ it exists, it is not a build output, and it is not ignored —
80
77
  * exactly the "source file" the category freezes talk about. `git` missing or
81
78
  * the tree not a repo ⇒ every token counts (the broad reading), so the detector
@@ -86,10 +83,14 @@ export declare function trackedSourceOracle(lsFiles: (p: string) => {
86
83
  exitCode: number;
87
84
  }): (p: string) => boolean;
88
85
  /**
89
- * The forced critique-rewrite defect text, in the shape the existing four
90
- * families use: MANDATORY, self-contained, naming the exact resolutions. Prose
91
- * surrender and silently dropping the requirement are called out as
92
- * non-resolutions because narrowing the clause is precisely what run 16 did and
93
- * freezing its file is precisely what run 18 did.
86
+ * A forced-rewrite defect block in the shape the CRITIQUE_PROBES entries use:
87
+ * MANDATORY, self-contained, naming the exact resolutions. Prose surrender and
88
+ * silently dropping the requirement are called out as non-resolutions — narrowing
89
+ * the clause and freezing its file are both ways a rewrite makes the
90
+ * contradiction disappear without satisfying the requirement.
91
+ *
92
+ * UNWIRED. Nothing in src/ or test/ calls this. The shipped resolution is the
93
+ * DETACH in `owned-freeze-reassign.ts`, which needs no model rewrite; this text
94
+ * is what a rewrite-based resolution would say if one were ever added.
94
95
  */
95
96
  export declare function ownedFreezeConflictProbeText(conflicts: OwnedFreezeConflict[]): string;