toolroll 0.9.93 → 0.9.95

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 (436) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/dist/activity-line.d.ts +7 -4
  3. package/dist/activity-line.js +9 -7
  4. package/dist/agent-fence.d.ts +10 -0
  5. package/dist/agent-fence.js +6 -3
  6. package/dist/approval-authority.d.ts +7 -1
  7. package/dist/approval-authority.js +11 -2
  8. package/dist/approval-password.d.ts +31 -0
  9. package/dist/approval-password.js +26 -0
  10. package/dist/assignment-status.d.ts +1 -1
  11. package/dist/assignment-ui.js +3 -1
  12. package/dist/assignment.js +5 -0
  13. package/dist/attest.d.ts +3 -0
  14. package/dist/attest.js +10 -0
  15. package/dist/boot-identity.d.ts +2 -1
  16. package/dist/boot-identity.js +6 -4
  17. package/dist/bounded-spawn.d.ts +57 -0
  18. package/dist/bounded-spawn.js +220 -0
  19. package/dist/browser/terminal.js +42 -42
  20. package/dist/browser/workspace.css +1 -1
  21. package/dist/browser/workspace.js +32 -32
  22. package/dist/browser-crew.js +2 -0
  23. package/dist/browser-shell.d.ts +1 -1
  24. package/dist/browser-shell.js +2 -2
  25. package/dist/browser-workspace.d.ts +50 -2
  26. package/dist/browser-workspace.js +3 -3
  27. package/dist/build-review.js +2 -0
  28. package/dist/builder-restart.d.ts +21 -0
  29. package/dist/builder-restart.js +50 -0
  30. package/dist/builder.d.ts +11 -2
  31. package/dist/builder.js +234 -101
  32. package/dist/card-catalog.d.ts +209 -0
  33. package/dist/card-catalog.js +133 -0
  34. package/dist/card-cli.d.ts +43 -0
  35. package/dist/card-cli.js +44 -0
  36. package/dist/card-render.d.ts +26 -0
  37. package/dist/card-render.js +223 -0
  38. package/dist/card-sources.d.ts +68 -0
  39. package/dist/card-sources.js +234 -0
  40. package/dist/chat-acceptance.js +1 -1
  41. package/dist/chat-actions.d.ts +106 -9
  42. package/dist/chat-actions.js +473 -46
  43. package/dist/chat-approval.d.ts +13 -0
  44. package/dist/chat-approval.js +39 -9
  45. package/dist/chat-card-part.d.ts +11 -0
  46. package/dist/chat-card-part.js +18 -0
  47. package/dist/chat-card.d.ts +46 -0
  48. package/dist/chat-card.js +99 -0
  49. package/dist/chat-channel.d.ts +2 -0
  50. package/dist/chat-channel.js +37 -14
  51. package/dist/chat-controls.d.ts +4 -0
  52. package/dist/chat-controls.js +4 -0
  53. package/dist/chat-decide.d.ts +10 -16
  54. package/dist/chat-decide.js +79 -62
  55. package/dist/chat-delivery.js +13 -4
  56. package/dist/chat-flow.d.ts +0 -27
  57. package/dist/chat-flow.js +31 -2
  58. package/dist/chat-quiet.js +4 -4
  59. package/dist/chat-task-actions.d.ts +3 -2
  60. package/dist/chat-task-actions.js +19 -5
  61. package/dist/chat-terms.d.ts +14 -2
  62. package/dist/chat-terms.js +35 -0
  63. package/dist/chat-voice.d.ts +1 -1
  64. package/dist/chat-voice.js +2 -2
  65. package/dist/check-facts.d.ts +3 -1
  66. package/dist/check-facts.js +57 -11
  67. package/dist/check-failure.d.ts +24 -3
  68. package/dist/check-failure.js +89 -13
  69. package/dist/check-levels-ui.d.ts +4 -0
  70. package/dist/check-levels-ui.js +10 -1
  71. package/dist/check-load.d.ts +85 -0
  72. package/dist/check-load.js +147 -0
  73. package/dist/check-only-standing.d.ts +36 -0
  74. package/dist/check-only-standing.js +39 -0
  75. package/dist/check-only.d.ts +15 -0
  76. package/dist/check-only.js +99 -0
  77. package/dist/check-repair.d.ts +47 -0
  78. package/dist/check-repair.js +240 -0
  79. package/dist/check-report.d.ts +2 -0
  80. package/dist/check-report.js +1 -1
  81. package/dist/check-stamp.d.ts +46 -0
  82. package/dist/check-stamp.js +93 -0
  83. package/dist/checkout-cleanup.d.ts +36 -5
  84. package/dist/checkout-cleanup.js +166 -14
  85. package/dist/claim.d.ts +6 -0
  86. package/dist/claim.js +13 -2
  87. package/dist/cli-help.d.ts +4 -1
  88. package/dist/cli-help.js +49 -30
  89. package/dist/cli.js +15 -1
  90. package/dist/code-extract.d.ts +44 -0
  91. package/dist/code-extract.js +88 -0
  92. package/dist/code-map-acts.d.ts +24 -0
  93. package/dist/code-map-acts.js +53 -0
  94. package/dist/code-map-admission.d.ts +52 -0
  95. package/dist/code-map-admission.js +295 -0
  96. package/dist/code-map-build.d.ts +63 -0
  97. package/dist/code-map-build.js +415 -0
  98. package/dist/code-map-cli.d.ts +153 -0
  99. package/dist/code-map-cli.js +103 -0
  100. package/dist/code-map-main.d.ts +1 -0
  101. package/dist/code-map-main.js +48 -0
  102. package/dist/code-map-read.d.ts +106 -0
  103. package/dist/code-map-read.js +171 -0
  104. package/dist/code-map-report.d.ts +37 -0
  105. package/dist/code-map-report.js +95 -0
  106. package/dist/code-map-shape.d.ts +172 -0
  107. package/dist/code-map-shape.js +327 -0
  108. package/dist/code-map-store.d.ts +136 -0
  109. package/dist/code-map-store.js +233 -0
  110. package/dist/coding-provider.d.ts +3 -1
  111. package/dist/coding-provider.js +12 -7
  112. package/dist/coding-update.js +3 -2
  113. package/dist/coding-workspace.d.ts +1 -1
  114. package/dist/coding-workspace.js +8 -8
  115. package/dist/console-chrome.js +2 -2
  116. package/dist/containment.d.ts +5 -0
  117. package/dist/containment.js +14 -1
  118. package/dist/contracts/chat-actions.d.ts +92 -0
  119. package/dist/contracts/chat-actions.js +20 -0
  120. package/dist/contracts/chat-card.d.ts +91 -0
  121. package/dist/contracts/chat-card.js +54 -0
  122. package/dist/contracts/chat-content.d.ts +191 -0
  123. package/dist/contracts/chat-content.js +4 -0
  124. package/dist/contracts/cli.d.ts +52 -0
  125. package/dist/contracts/cli.js +4 -0
  126. package/dist/contracts/console-api.d.ts +12 -3
  127. package/dist/contracts/console-api.js +12 -3
  128. package/dist/contracts/flow-propose.d.ts +8 -1
  129. package/dist/contracts/flow-propose.js +3 -1
  130. package/dist/contracts/flow-send.d.ts +126 -0
  131. package/dist/contracts/flow-send.js +3 -0
  132. package/dist/contracts/gateway-tools.d.ts +17 -0
  133. package/dist/contracts/gateway-tools.js +3 -1
  134. package/dist/contracts/lead-tools.d.ts +234 -0
  135. package/dist/contracts/lead-tools.js +25 -1
  136. package/dist/contracts/project-knowledge.d.ts +38 -5
  137. package/dist/contracts/project-knowledge.js +11 -5
  138. package/dist/contracts/project-memory.d.ts +3 -1
  139. package/dist/contracts/project-memory.js +3 -2
  140. package/dist/contracts/storage.d.ts +14 -0
  141. package/dist/contracts/storage.js +3 -1
  142. package/dist/contracts/store-json.d.ts +18 -0
  143. package/dist/contracts/youiyoux-request.d.ts +1 -1
  144. package/dist/contracts/youiyoux-request.js +1 -1
  145. package/dist/desktop-access.js +6 -2
  146. package/dist/discord-chat.js +14 -0
  147. package/dist/dispatch.d.ts +1 -1
  148. package/dist/dispatch.js +25 -16
  149. package/dist/dispose.d.ts +19 -0
  150. package/dist/dispose.js +55 -9
  151. package/dist/easy-start.js +2 -3
  152. package/dist/eval-oracle.js +4 -1
  153. package/dist/evals.js +2 -1
  154. package/dist/evidence-pair.d.ts +53 -0
  155. package/dist/evidence-pair.js +128 -0
  156. package/dist/exhaustion.d.ts +17 -4
  157. package/dist/exhaustion.js +44 -4
  158. package/dist/export.js +1 -1
  159. package/dist/failing-first.d.ts +31 -0
  160. package/dist/failing-first.js +44 -0
  161. package/dist/fallback-schema.d.ts +8 -0
  162. package/dist/fallback-schema.js +40 -0
  163. package/dist/fallback.d.ts +138 -0
  164. package/dist/fallback.js +605 -0
  165. package/dist/fast-start.d.ts +136 -0
  166. package/dist/fast-start.js +431 -0
  167. package/dist/fast-terms.d.ts +9 -0
  168. package/dist/fast-terms.js +23 -0
  169. package/dist/fenced-check-coverage.d.ts +62 -0
  170. package/dist/fenced-check-coverage.js +54 -0
  171. package/dist/findings.d.ts +224 -0
  172. package/dist/findings.js +449 -0
  173. package/dist/first-run.js +1 -1
  174. package/dist/flaky-ci.d.ts +31 -0
  175. package/dist/flaky-ci.js +149 -0
  176. package/dist/flaky-cli.d.ts +60 -0
  177. package/dist/flaky-cli.js +60 -0
  178. package/dist/flaky.d.ts +75 -9
  179. package/dist/flaky.js +255 -0
  180. package/dist/fleet-schema.d.ts +17 -0
  181. package/dist/fleet-schema.js +135 -0
  182. package/dist/flow-browser.js +2 -2
  183. package/dist/flow-card-task.js +3 -0
  184. package/dist/flow-code.d.ts +2 -2
  185. package/dist/flow-code.js +9 -5
  186. package/dist/flow-result-card.d.ts +22 -0
  187. package/dist/flow-result-card.js +55 -0
  188. package/dist/flow-send.js +12 -9
  189. package/dist/flow-steps.js +1 -1
  190. package/dist/flow-triggers.d.ts +1 -1
  191. package/dist/flow-triggers.js +2 -2
  192. package/dist/flow-unattended.d.ts +26 -0
  193. package/dist/flow-unattended.js +12 -3
  194. package/dist/flows-ui.js +10 -2
  195. package/dist/follow-through-brief.d.ts +12 -0
  196. package/dist/follow-through-brief.js +31 -0
  197. package/dist/follow-through-cli.d.ts +23 -0
  198. package/dist/follow-through-cli.js +153 -0
  199. package/dist/git-incident.d.ts +16 -0
  200. package/dist/git-incident.js +69 -6
  201. package/dist/github-import.d.ts +62 -0
  202. package/dist/github-import.js +146 -0
  203. package/dist/guides.js +15 -10
  204. package/dist/handover-note.d.ts +33 -0
  205. package/dist/handover-note.js +106 -0
  206. package/dist/invoke.d.ts +25 -2
  207. package/dist/invoke.js +157 -58
  208. package/dist/job-object-helper.ps1 +10 -3
  209. package/dist/keymap.d.ts +41 -0
  210. package/dist/keymap.js +51 -0
  211. package/dist/knowledge-cli.js +1 -1
  212. package/dist/knowledge-ui.d.ts +21 -4
  213. package/dist/knowledge-ui.js +75 -7
  214. package/dist/laptop-background.d.ts +16 -0
  215. package/dist/laptop-background.js +108 -2
  216. package/dist/lead-cli.js +26 -24
  217. package/dist/lead-context.js +1 -1
  218. package/dist/lead-contract.d.ts +1 -1
  219. package/dist/lead-contract.js +3 -2
  220. package/dist/lead-doors.d.ts +4 -0
  221. package/dist/lead-doors.js +2 -2
  222. package/dist/lead-progress.js +5 -0
  223. package/dist/lead-status.d.ts +2 -0
  224. package/dist/lead-status.js +6 -2
  225. package/dist/lead-tools.js +162 -34
  226. package/dist/lead.js +2 -2
  227. package/dist/lesson-notes.d.ts +81 -0
  228. package/dist/lesson-notes.js +336 -0
  229. package/dist/limits-ui.js +1 -1
  230. package/dist/local-owner.d.ts +1 -1
  231. package/dist/local-owner.js +16 -0
  232. package/dist/machine-check.d.ts +16 -0
  233. package/dist/machine-check.js +26 -0
  234. package/dist/machine-identity.d.ts +75 -0
  235. package/dist/machine-identity.js +170 -0
  236. package/dist/mcp-core.js +11 -1
  237. package/dist/memory-cli.d.ts +300 -1
  238. package/dist/memory-cli.js +62 -9
  239. package/dist/memory-pass.d.ts +16 -0
  240. package/dist/memory-pass.js +67 -3
  241. package/dist/memory-tidy.d.ts +181 -0
  242. package/dist/memory-tidy.js +523 -0
  243. package/dist/memory-use.d.ts +35 -0
  244. package/dist/memory-use.js +109 -0
  245. package/dist/merge-checklist.d.ts +55 -0
  246. package/dist/merge-checklist.js +182 -0
  247. package/dist/modes.d.ts +6 -6
  248. package/dist/modes.js +3 -1
  249. package/dist/needs-you.d.ts +31 -9
  250. package/dist/needs-you.js +110 -41
  251. package/dist/nightly-github.d.ts +2 -0
  252. package/dist/nightly-github.js +4 -4
  253. package/dist/operate-remote-arguments.js +7 -1
  254. package/dist/operate-remote.js +3 -1
  255. package/dist/operate.d.ts +6 -1
  256. package/dist/operate.js +565 -64
  257. package/dist/phase-routing.js +2 -2
  258. package/dist/plain-schema.d.ts +23 -0
  259. package/dist/plain-schema.js +94 -0
  260. package/dist/plain-words.d.ts +20 -0
  261. package/dist/plain-words.js +66 -0
  262. package/dist/plan-login.d.ts +14 -0
  263. package/dist/plan-login.js +58 -0
  264. package/dist/planner.d.ts +1 -1
  265. package/dist/planner.js +4 -2
  266. package/dist/process-liveness.d.ts +2 -0
  267. package/dist/process-liveness.js +61 -17
  268. package/dist/project-delete-ui.d.ts +19 -2
  269. package/dist/project-delete-ui.js +29 -1
  270. package/dist/project-delete.js +14 -1
  271. package/dist/project-knowledge.d.ts +18 -11
  272. package/dist/project-knowledge.js +39 -9
  273. package/dist/project-learning.d.ts +2 -1
  274. package/dist/project-learning.js +15 -45
  275. package/dist/project-memory.d.ts +5 -0
  276. package/dist/project-memory.js +22 -2
  277. package/dist/project-tools.d.ts +4 -4
  278. package/dist/project-tools.js +23 -7
  279. package/dist/proof.js +30 -5
  280. package/dist/protected-storage-look.d.ts +1 -0
  281. package/dist/protected-storage-look.js +13 -0
  282. package/dist/protected-storage.d.ts +70 -39
  283. package/dist/protected-storage.js +196 -147
  284. package/dist/provider-auth.js +1 -1
  285. package/dist/provider-capture.d.ts +34 -0
  286. package/dist/provider-capture.js +53 -0
  287. package/dist/publish.js +9 -1
  288. package/dist/pull-request-flow.js +5 -0
  289. package/dist/push.d.ts +18 -2
  290. package/dist/push.js +40 -16
  291. package/dist/release-adapters.d.ts +9 -0
  292. package/dist/release-adapters.js +76 -0
  293. package/dist/release-auto.js +13 -13
  294. package/dist/release-card.d.ts +1 -2
  295. package/dist/release-card.js +11 -0
  296. package/dist/release-carry.d.ts +7 -2
  297. package/dist/release-carry.js +49 -10
  298. package/dist/release-cli.d.ts +4 -0
  299. package/dist/release-cli.js +29 -22
  300. package/dist/release-coverage.js +1 -1
  301. package/dist/release-next.d.ts +48 -0
  302. package/dist/release-next.js +161 -0
  303. package/dist/release.d.ts +20 -1
  304. package/dist/release.js +85 -9
  305. package/dist/remote-destination.d.ts +36 -0
  306. package/dist/remote-destination.js +217 -0
  307. package/dist/remote-main.d.ts +48 -0
  308. package/dist/remote-main.js +84 -5
  309. package/dist/repository-context.d.ts +3 -2
  310. package/dist/repository-context.js +112 -70
  311. package/dist/restart-certification.d.ts +1 -0
  312. package/dist/restart-certification.js +8 -6
  313. package/dist/result-acts.d.ts +27 -19
  314. package/dist/result-acts.js +36 -25
  315. package/dist/result-follow-ups.d.ts +2 -2
  316. package/dist/result-follow-ups.js +18 -4
  317. package/dist/result-review.d.ts +1 -1
  318. package/dist/route-change-check.d.ts +4 -0
  319. package/dist/route-change-check.js +13 -0
  320. package/dist/route-change.d.ts +22 -0
  321. package/dist/route-change.js +89 -0
  322. package/dist/route-hooks.js +3 -2
  323. package/dist/route-results.d.ts +6 -1
  324. package/dist/route-results.js +14 -5
  325. package/dist/run-closeout.d.ts +1 -1
  326. package/dist/run-closeout.js +7 -5
  327. package/dist/runner-process.js +3 -2
  328. package/dist/runner.js +2 -1
  329. package/dist/scope.d.ts +28 -4
  330. package/dist/scope.js +92 -28
  331. package/dist/scout.d.ts +1 -1
  332. package/dist/scout.js +2 -1
  333. package/dist/serve.d.ts +1 -1
  334. package/dist/serve.js +26 -18
  335. package/dist/server/chat.js +16 -14
  336. package/dist/server/chrome.d.ts +1 -1
  337. package/dist/server/chrome.js +26 -35
  338. package/dist/server/console.css +73 -0
  339. package/dist/server/guards.js +3 -0
  340. package/dist/server/home.d.ts +6 -0
  341. package/dist/server/home.js +21 -13
  342. package/dist/server/http.js +1 -1
  343. package/dist/server/kit.js +1 -1
  344. package/dist/server/merge-ready-view.d.ts +10 -0
  345. package/dist/server/merge-ready-view.js +30 -0
  346. package/dist/server/pages-assets.d.ts +1 -0
  347. package/dist/server/pages-assets.js +8 -5
  348. package/dist/server/pages.js +103 -82
  349. package/dist/server/render-chat.js +16 -3
  350. package/dist/server/render-code-map.d.ts +30 -0
  351. package/dist/server/render-code-map.js +137 -0
  352. package/dist/server/render-flaky.d.ts +20 -0
  353. package/dist/server/render-flaky.js +59 -0
  354. package/dist/server/render-follow-through.d.ts +11 -0
  355. package/dist/server/render-follow-through.js +68 -0
  356. package/dist/server/render-history.js +1 -1
  357. package/dist/server/render-new-task.d.ts +26 -1
  358. package/dist/server/render-new-task.js +30 -5
  359. package/dist/server/render-pages.d.ts +1 -175
  360. package/dist/server/render-pages.js +38 -313
  361. package/dist/server/render-projects.d.ts +2 -1
  362. package/dist/server/render-projects.js +9 -7
  363. package/dist/server/render-release.d.ts +2 -0
  364. package/dist/server/render-release.js +3 -3
  365. package/dist/server/render-results.d.ts +2 -0
  366. package/dist/server/render-results.js +68 -68
  367. package/dist/server/render-tasks.d.ts +16 -2
  368. package/dist/server/render-tasks.js +177 -141
  369. package/dist/server/retired-routes.d.ts +17 -0
  370. package/dist/server/retired-routes.js +53 -0
  371. package/dist/server/route-table.d.ts +3 -0
  372. package/dist/server/route-table.js +48 -12
  373. package/dist/server/settings.js +166 -34
  374. package/dist/server/task-views.js +66 -26
  375. package/dist/server/tasks.d.ts +2 -6
  376. package/dist/server/tasks.js +250 -321
  377. package/dist/server/welcome.js +1 -1
  378. package/dist/settings-groups-ui.d.ts +1 -0
  379. package/dist/settings-groups-ui.js +4 -2
  380. package/dist/settings-kit.js +3 -2
  381. package/dist/settings-proofs.js +3 -1
  382. package/dist/slack-chat.js +14 -1
  383. package/dist/steer-mailbox.d.ts +8 -1
  384. package/dist/steer-mailbox.js +164 -6
  385. package/dist/stop-proof.js +6 -4
  386. package/dist/storage-sweep-process.js +1 -1
  387. package/dist/storage-sweep.d.ts +5 -3
  388. package/dist/storage-sweep.js +30 -9
  389. package/dist/storage-ui.js +28 -17
  390. package/dist/storage.d.ts +27 -2
  391. package/dist/storage.js +39 -2
  392. package/dist/store.d.ts +89 -7
  393. package/dist/store.js +386 -114
  394. package/dist/surface.js +67 -6
  395. package/dist/sweep-quarantine.d.ts +1 -0
  396. package/dist/sweep-quarantine.js +6 -4
  397. package/dist/tamper-scan.d.ts +4 -0
  398. package/dist/tamper-scan.js +90 -0
  399. package/dist/task-aliases.d.ts +5 -0
  400. package/dist/task-aliases.js +9 -0
  401. package/dist/task-control.d.ts +2 -1
  402. package/dist/task-control.js +4 -1
  403. package/dist/task-outcome-cli.d.ts +2 -0
  404. package/dist/task-outcome-cli.js +17 -17
  405. package/dist/task-sizing.d.ts +5 -0
  406. package/dist/task-sizing.js +2 -0
  407. package/dist/task-source.d.ts +7 -0
  408. package/dist/task-source.js +14 -0
  409. package/dist/task-status.d.ts +9 -0
  410. package/dist/task-status.js +45 -49
  411. package/dist/teardown-git.d.ts +18 -0
  412. package/dist/teardown-git.js +105 -21
  413. package/dist/telegram-lead.js +23 -6
  414. package/dist/telegram-progress.js +5 -3
  415. package/dist/telegram-status.js +6 -4
  416. package/dist/telegram.js +12 -1
  417. package/dist/test-infra.d.ts +8 -0
  418. package/dist/test-infra.js +18 -0
  419. package/dist/tidy.js +1 -1
  420. package/dist/toolroll-update.js +19 -5
  421. package/dist/tui-contract.d.ts +24 -0
  422. package/dist/tui-source.js +67 -8
  423. package/dist/tui.js +51 -51
  424. package/dist/vanished-retry.d.ts +30 -0
  425. package/dist/vanished-retry.js +174 -0
  426. package/dist/work-index.d.ts +2 -0
  427. package/dist/work-index.js +95 -66
  428. package/dist/work-summary.d.ts +1 -1
  429. package/dist/work-summary.js +7 -2
  430. package/dist/workspace-ui.d.ts +7 -3
  431. package/dist/workspace-ui.js +38 -23
  432. package/dist/worktree.d.ts +12 -3
  433. package/dist/worktree.js +91 -14
  434. package/package.json +2 -1
  435. package/dist/server/render-next.d.ts +0 -63
  436. package/dist/server/render-next.js +0 -109
@@ -68,10 +68,12 @@ export declare const knowledgeOmissionSchema: z.ZodObject<{
68
68
  title: z.ZodString;
69
69
  reason: z.ZodString;
70
70
  }, z.core.$strict>;
71
- export declare const KNOWLEDGE_SELECTION_VERSION = 1;
71
+ /** Version 2 (docs/plans/learning-loops.md, "Versioned snapshots"): a selection says when it was frozen, and its decision
72
+ * lines their revision. Version 1 stays readable exactly as it was frozen, its fields as they are. */
73
+ export declare const KNOWLEDGE_SELECTION_VERSION = 2;
72
74
  /** The selection a run is given, as it is frozen. The keys are in the order a selection has always been written. */
73
75
  export declare const knowledgeSelectionSchema: z.ZodObject<{
74
- version: z.ZodLiteral<1>;
76
+ version: z.ZodLiteral<2>;
75
77
  revision: z.ZodInt;
76
78
  instructions: z.ZodString;
77
79
  references: z.ZodArray<z.ZodObject<{
@@ -91,11 +93,39 @@ export declare const knowledgeSelectionSchema: z.ZodObject<{
91
93
  id: z.ZodInt;
92
94
  claim: z.ZodString;
93
95
  decidedAt: z.ZodString;
96
+ revision: z.ZodOptional<z.ZodInt>;
94
97
  }, z.core.$strict>>>;
95
98
  repository: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
99
+ capturedAt: z.ZodString;
96
100
  }, z.core.$strict>;
97
- /** A frozen selection as it is read back. */
101
+ /** A frozen selection as it is read back: the version it was frozen under. */
98
102
  export declare const savedKnowledgeSelectionSchema: z.ZodObject<{
103
+ version: z.ZodLiteral<2>;
104
+ revision: z.ZodInt;
105
+ instructions: z.ZodString;
106
+ references: z.ZodArray<z.ZodObject<{
107
+ id: z.ZodString;
108
+ title: z.ZodString;
109
+ content: z.ZodString;
110
+ path: z.ZodNullable<z.ZodString>;
111
+ sourceSha: z.ZodNullable<z.ZodString>;
112
+ sourceRevision: z.ZodNullable<z.ZodString>;
113
+ }, z.core.$strict>>;
114
+ omitted: z.ZodArray<z.ZodObject<{
115
+ title: z.ZodString;
116
+ reason: z.ZodString;
117
+ }, z.core.$strict>>;
118
+ inheritedFrom: z.ZodNullable<z.ZodInt>;
119
+ decisions: z.ZodOptional<z.ZodArray<z.ZodObject<{
120
+ id: z.ZodInt;
121
+ claim: z.ZodString;
122
+ decidedAt: z.ZodString;
123
+ revision: z.ZodOptional<z.ZodInt>;
124
+ }, z.core.$strict>>>;
125
+ repository: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
126
+ capturedAt: z.ZodString;
127
+ }, z.core.$strict>;
128
+ export declare const savedKnowledgeSelectionV1Schema: z.ZodObject<{
99
129
  version: z.ZodLiteral<1>;
100
130
  revision: z.ZodInt;
101
131
  instructions: z.ZodString;
@@ -116,11 +146,14 @@ export declare const savedKnowledgeSelectionSchema: z.ZodObject<{
116
146
  id: z.ZodInt;
117
147
  claim: z.ZodString;
118
148
  decidedAt: z.ZodString;
149
+ revision: z.ZodOptional<z.ZodInt>;
119
150
  }, z.core.$strict>>>;
120
151
  repository: z.ZodOptional<z.ZodObject<{}, z.core.$loose>>;
121
152
  }, z.core.$strict>;
122
- export type KnowledgeSelection = Omit<z.infer<typeof knowledgeSelectionSchema>, "repository"> & {
153
+ export type KnowledgeSelection = Omit<z.infer<typeof knowledgeSelectionSchema>, "repository" | "version" | "capturedAt"> & {
154
+ version: 1 | 2;
155
+ capturedAt?: string;
123
156
  repository?: RepositoryContext;
124
157
  };
125
- /** Read a frozen selection: version 1 (every selection ever frozen) as itself, a newer one refused plainly. */
158
+ /** Read a frozen selection: version 1 and 2 each as themselves, a newer one refused plainly. */
126
159
  export declare function readKnowledgeSelection(input: unknown): ContractResult<KnowledgeSelection>;
@@ -82,12 +82,18 @@ const selectionShape = (text) => ({
82
82
  /** Source excerpts from the crew's checkout (repository-context.ts owns their shape); absent when not captured. */
83
83
  repository: z.looseObject({}).optional(),
84
84
  });
85
- export const KNOWLEDGE_SELECTION_VERSION = 1;
85
+ /** Version 2 (docs/plans/learning-loops.md, "Versioned snapshots"): a selection says when it was frozen, and its decision
86
+ * lines their revision. Version 1 stays readable exactly as it was frozen, its fields as they are. */
87
+ export const KNOWLEDGE_SELECTION_VERSION = 2;
86
88
  /** The selection a run is given, as it is frozen. The keys are in the order a selection has always been written. */
87
- export const knowledgeSelectionSchema = versioned(KNOWLEDGE_SELECTION_VERSION, selectionShape(written));
88
- /** A frozen selection as it is read back. */
89
- export const savedKnowledgeSelectionSchema = versioned(KNOWLEDGE_SELECTION_VERSION, selectionShape(saved));
90
- /** Read a frozen selection: version 1 (every selection ever frozen) as itself, a newer one refused plainly. */
89
+ export const knowledgeSelectionSchema = versioned(KNOWLEDGE_SELECTION_VERSION, { ...selectionShape(written), capturedAt: z.string() });
90
+ /** A frozen selection as it is read back: the version it was frozen under. */
91
+ export const savedKnowledgeSelectionSchema = versioned(KNOWLEDGE_SELECTION_VERSION, { ...selectionShape(saved), capturedAt: z.string() });
92
+ export const savedKnowledgeSelectionV1Schema = versioned(1, selectionShape(saved));
93
+ /** Read a frozen selection: version 1 and 2 each as themselves, a newer one refused plainly. */
91
94
  export function readKnowledgeSelection(input) {
95
+ const version = input !== null && typeof input === "object" ? input.version : undefined;
96
+ if (version === 1)
97
+ return readVersioned(savedKnowledgeSelectionV1Schema, input);
92
98
  return readVersioned(savedKnowledgeSelectionSchema, input);
93
99
  }
@@ -75,11 +75,13 @@ export declare const decisionDraftSchema: z.ZodObject<{
75
75
  supersedes: z.ZodOptional<z.ZodNullable<z.ZodInt>>;
76
76
  }, z.core.$strict>;
77
77
  export type DecisionDraft = z.infer<typeof decisionDraftSchema>;
78
- /** One decision in a brief: its id, the choice and when; the why loads on demand by id. */
78
+ /** One decision in a brief: its id, the choice and when (the revision on snapshots from version 2 on); the why loads on
79
+ * demand by id. */
79
80
  export declare const decisionLineSchema: z.ZodObject<{
80
81
  id: z.ZodInt;
81
82
  claim: z.ZodString;
82
83
  decidedAt: z.ZodString;
84
+ revision: z.ZodOptional<z.ZodInt>;
83
85
  }, z.core.$strict>;
84
86
  export type DecisionLine = z.infer<typeof decisionLineSchema>;
85
87
  export declare const DECISION_CHANGE_VERSION = 1;
@@ -38,8 +38,9 @@ export const decisionDraftSchema = z.strictObject({
38
38
  sourceRef: z.string().nullable().optional(),
39
39
  supersedes: z.int().nullable().optional(),
40
40
  });
41
- /** One decision in a brief: its id, the choice and when; the why loads on demand by id. */
42
- export const decisionLineSchema = z.strictObject({ id: z.int(), claim: z.string(), decidedAt: z.string() });
41
+ /** One decision in a brief: its id, the choice and when (the revision on snapshots from version 2 on); the why loads on
42
+ * demand by id. */
43
+ export const decisionLineSchema = z.strictObject({ id: z.int(), claim: z.string(), decidedAt: z.string(), revision: z.int().min(1).optional() });
43
44
  export const DECISION_CHANGE_VERSION = 1;
44
45
  /**
45
46
  * One entry of a decision's history (`decision_change.payload`): the record when it was made, or the reason its status
@@ -11,6 +11,13 @@ export declare const checkoutCleanupSchema: z.ZodEnum<{
11
11
  finished: "finished";
12
12
  never: "never";
13
13
  }>;
14
+ /** How long a task stays idle before its clean folder goes (v151, checkout-cleanup.ts). A saved row's NULL is the default. */
15
+ export declare const checkoutIdleSchema: z.ZodEnum<{
16
+ "14d": "14d";
17
+ "30d": "30d";
18
+ "7d": "7d";
19
+ never: "never";
20
+ }>;
14
21
  /** A saved `checkout_cleanup_setting` row (at most one; none means the default), unknown columns ignored. */
15
22
  export declare const checkoutCleanupRowSchema: z.ZodObject<{
16
23
  cleanup: z.ZodEnum<{
@@ -19,5 +26,12 @@ export declare const checkoutCleanupRowSchema: z.ZodObject<{
19
26
  finished: "finished";
20
27
  never: "never";
21
28
  }>;
29
+ idle: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
30
+ "14d": "14d";
31
+ "30d": "30d";
32
+ "7d": "7d";
33
+ never: "never";
34
+ }>>>;
22
35
  }, z.core.$strip>;
23
36
  export type CheckoutCleanup = z.infer<typeof checkoutCleanupSchema>;
37
+ export type CheckoutIdle = z.infer<typeof checkoutIdleSchema>;
@@ -6,5 +6,7 @@
6
6
  */
7
7
  import { z } from "zod";
8
8
  export const checkoutCleanupSchema = z.enum(["finished", "2d", "7d", "never"]);
9
+ /** How long a task stays idle before its clean folder goes (v151, checkout-cleanup.ts). A saved row's NULL is the default. */
10
+ export const checkoutIdleSchema = z.enum(["7d", "14d", "30d", "never"]);
9
11
  /** A saved `checkout_cleanup_setting` row (at most one; none means the default), unknown columns ignored. */
10
- export const checkoutCleanupRowSchema = z.object({ cleanup: checkoutCleanupSchema });
12
+ export const checkoutCleanupRowSchema = z.object({ cleanup: checkoutCleanupSchema, idle: checkoutIdleSchema.nullable().optional() });
@@ -166,8 +166,13 @@ declare const STORE_COLUMN_VALUES: {
166
166
  readonly "lead_proposal.payload_json": z.ZodUnion<readonly [z.ZodObject<{
167
167
  version: z.ZodLiteral<1>;
168
168
  operation: z.ZodEnum<{
169
+ code_map_holdout_end: "code_map_holdout_end";
170
+ code_map_switch: "code_map_switch";
169
171
  decision_record: "decision_record";
170
172
  decision_retire: "decision_retire";
173
+ finding_resend: "finding_resend";
174
+ finding_send: "finding_send";
175
+ flow_archive: "flow_archive";
171
176
  flow_browser: "flow_browser";
172
177
  flow_browser_off: "flow_browser_off";
173
178
  flow_card_add: "flow_card_add";
@@ -187,13 +192,22 @@ declare const STORE_COLUMN_VALUES: {
187
192
  flow_trigger_pause: "flow_trigger_pause";
188
193
  flow_trigger_remove: "flow_trigger_remove";
189
194
  flow_trigger_resume: "flow_trigger_resume";
195
+ flow_unattended: "flow_unattended";
196
+ flow_unattended_off: "flow_unattended_off";
197
+ incident_resolve: "incident_resolve";
190
198
  kit_setup: "kit_setup";
191
199
  knowledge_instructions: "knowledge_instructions";
192
200
  knowledge_remove: "knowledge_remove";
193
201
  knowledge_restore: "knowledge_restore";
194
202
  knowledge_save: "knowledge_save";
195
203
  lead_about_you: "lead_about_you";
204
+ lead_identity: "lead_identity";
205
+ memory_decide: "memory_decide";
206
+ mode_revoke: "mode_revoke";
207
+ provider_resume: "provider_resume";
196
208
  result_accept: "result_accept";
209
+ revision_accept: "revision_accept";
210
+ revision_reject: "revision_reject";
197
211
  scope_approve: "scope_approve";
198
212
  skill_disable: "skill_disable";
199
213
  skill_enable: "skill_enable";
@@ -213,11 +227,15 @@ declare const STORE_COLUMN_VALUES: {
213
227
  suggestion_not_now: "suggestion_not_now";
214
228
  sweep_cancel_rest: "sweep_cancel_rest";
215
229
  sweep_file: "sweep_file";
230
+ task_archive: "task_archive";
216
231
  task_cancel: "task_cancel";
232
+ task_reopen: "task_reopen";
233
+ task_restore: "task_restore";
217
234
  task_resume: "task_resume";
218
235
  tool_add: "tool_add";
219
236
  tool_remove: "tool_remove";
220
237
  trial_stop: "trial_stop";
238
+ worker_note: "worker_note";
221
239
  }>;
222
240
  request: z.ZodObject<{}, z.core.$catchall<z.ZodUnknown>>;
223
241
  repo: z.ZodString;
@@ -15,7 +15,7 @@ export declare const YOUIYOUX_FILED_VIA = "youiyoux";
15
15
  * Approve all and each one's own Approve and Open. */
16
16
  export declare const YOUIYOUX_CARD_KIND = "youiyoux-requests";
17
17
  /** Where a person sees and approves everything waiting on them in the console (flow-triggers.ts NEEDS_YOU_HREF). */
18
- export declare const YOUIYOUX_HOME_PATH = "/work?view=needs-you";
18
+ export declare const YOUIYOUX_HOME_PATH = "/tasks?view=needs-you";
19
19
  export declare const YOUIYOUX_EVIDENCE: readonly ["screenshot", "check", "changed-path", "manual-review"];
20
20
  /** What an options request offers its agent: the one file to write (`.youi/proposals/<proposal>.json`), the props an
21
21
  * option may set (enum values from `values`), and whether it may give the component new text. */
@@ -15,7 +15,7 @@ export const YOUIYOUX_FILED_VIA = "youiyoux";
15
15
  * Approve all and each one's own Approve and Open. */
16
16
  export const YOUIYOUX_CARD_KIND = "youiyoux-requests";
17
17
  /** Where a person sees and approves everything waiting on them in the console (flow-triggers.ts NEEDS_YOU_HREF). */
18
- export const YOUIYOUX_HOME_PATH = "/work?view=needs-you";
18
+ export const YOUIYOUX_HOME_PATH = "/tasks?view=needs-you";
19
19
  const text = (max) => z.string().min(1).max(max);
20
20
  const who = z.object({ kind: z.enum(["person", "agent"]), name: text(100) });
21
21
  // The published schema's date-time: an ISO timestamp with a zone.
@@ -2,8 +2,8 @@
2
2
  import { mkdtempSync, readFileSync, writeFileSync, unlinkSync, rmdirSync, opendirSync, realpathSync } from "node:fs";
3
3
  import { join, resolve } from "node:path";
4
4
  import { fileURLToPath } from "node:url";
5
- import { execFileSync } from "node:child_process";
6
5
  import { run } from "./exec.js";
6
+ import { checkoutGitSync, checkoutTop } from "./teardown-git.js";
7
7
  export function accessFailure(repo, code) {
8
8
  if (code === "EROFS")
9
9
  return { repo, state: "permission-needed", message: "This project is on a read-only drive. Choose a writable copy; Privacy Settings cannot make a read-only drive writable." };
@@ -23,7 +23,11 @@ export function probeDesktopProject(repo) {
23
23
  const directory = opendirSync(repo);
24
24
  directory.readSync();
25
25
  directory.closeSync();
26
- const common = execFileSync("git", ["-C", repo, "rev-parse", "--path-format=absolute", "--git-common-dir"], { encoding: "utf8", timeout: 4000, stdio: ["ignore", "pipe", "pipe"] }).trim();
26
+ // The project's own repository, read through a frozen view: a build's include naming a FIFO can't hang the probe.
27
+ const top = checkoutTop(repo, 4000);
28
+ if (top === null)
29
+ throw Error("Not a readable Git checkout");
30
+ const common = checkoutGitSync(top, ["rev-parse", "--path-format=absolute", "--git-common-dir"], { timeoutMs: 4000, binding: { repo: top } }).trim();
27
31
  scratch = mkdtempSync(join(realpathSync(common), "standing-orders-access-"));
28
32
  const file = join(scratch, "check");
29
33
  writeFileSync(file, "Toolroll access check\n", { flag: "wx", mode: 0o600 });
@@ -1,6 +1,9 @@
1
1
  /** Discord messages and buttons transport the shared assistant's saved actions. */
2
2
  import { chatQuestionButtons } from "./subagent-question.js";
3
3
  import { chatAskButtons } from "./chat-ask.js";
4
+ import { discordCardEmbed } from "./card-render.js";
5
+ import { withoutCard } from "./chat-card-part.js";
6
+ import { cardWithin } from "./chat-card.js";
4
7
  import { chatFlowButtons } from "./chat-flow.js";
5
8
  import { refuseResultShots, resultShotsPruned, shotWaitsUntil } from "./result-shots.js";
6
9
  import { admitChatEvent } from "./chat-admission.js";
@@ -197,6 +200,10 @@ export async function deliverDiscordPart(options) {
197
200
  if (content.task &&
198
201
  !repos.includes(store.lookupRef(content.task)?.repo ?? ""))
199
202
  throw new DiscordError("Connected projects changed");
203
+ if (content.rich && !cardWithin(content.rich, repos)) {
204
+ state.dropPart(row.id, "Connected projects changed");
205
+ return true;
206
+ }
200
207
  let text = content.text, buttons = [], file;
201
208
  if (content.image && content.shot && resultShotsPruned(options.evidenceRoot, content.image.run)) {
202
209
  state.dropPart(row.id, "Removed by retention");
@@ -354,6 +361,8 @@ export async function deliverDiscordPart(options) {
354
361
  file.bytes = fresh.bytes;
355
362
  }
356
363
  const args = discordCard(text, buttons, content.voice === true && !content.proposal && !content.image);
364
+ if (content.rich)
365
+ args.embeds = [discordCardEmbed(content.rich, discordPlain)];
357
366
  if (file)
358
367
  args.attachments = [
359
368
  { id: 0, filename: file.name, description: text.slice(0, 1024) },
@@ -392,6 +401,11 @@ export async function deliverDiscordPart(options) {
392
401
  }
393
402
  // No permission to attach files here: one plain line instead of the result's screenshots.
394
403
  const saved = readChatPart(row.payload), content = saved.ok ? saved.value : null;
404
+ // Discord refused the card's embed: the part's own plain text goes instead, so the message is never lost.
405
+ if (content?.rich && error instanceof DiscordError && error.code === "Discord could not complete the request" && error.retryMs === 60_000) {
406
+ state.repaint(row.id, withoutCard(content));
407
+ return true;
408
+ }
395
409
  if (content !== null && content.image && content.shot && error instanceof DiscordError && error.code === DISCORD_REFUSED) {
396
410
  refuseResultShots(state, store, row, content, "Discord", options.clock?.() ?? new Date());
397
411
  return true;
@@ -39,7 +39,7 @@ export type DispatchAction = "open-result" | "retry-task" | "place-task" | "writ
39
39
  | "resume-run";
40
40
  export type DispatchDiagnosisCode = "updating" | "complete" | "needs-verification" | "proof-refuted" | "review-pending" | "reviewing" | "review-failed"
41
41
  /** v50: every root review attempt ended without a review; nothing retries. */
42
- | "review-exhausted" | "cancelled" | "failed" | "running" | "vanished-run" | "retry-scheduled" | "waiting-decision" | "waiting-incident" | "held"
42
+ | "review-exhausted" | "cancelled" | "failed" | "running" | "vanished-run" | "retry-scheduled" | "waiting-decision" | "waiting-incident" | "held" | "storage-blocked"
43
43
  /** v52: an operator stopped one exact attempt; only resuming it lifts the pause. */
44
44
  | "stopped" | "waiting-dependency" | "terminal-dependency" | "needs-project" | "needs-scope" | "needs-agent-profile" | "needs-approval" | "missing-requirement" | "no-worker-registered" | "no-worker-online" | "worker-at-capacity" | "provider-quota"
45
45
  /** The provider's sign-in stopped working; its dispatch is paused. */
package/dist/dispatch.js CHANGED
@@ -6,6 +6,7 @@
6
6
  * fleet observations on top for people and agents reading the queue. A
7
7
  * diagnosis can go stale; it can never grant a lease.
8
8
  */
9
+ import { STORAGE_HOLD_PREFIX } from "./needs-you.js";
9
10
  import { authorityStandsSql } from "./approval-authority.js";
10
11
  import { isAlive } from "./runner.js";
11
12
  import { updateAdmissionPaused, UPDATE_PAUSED } from "./desktop-update-gate.js";
@@ -16,6 +17,8 @@ import { REVIEW_TOKENS, resultStatusOf, reviewFactsOf } from "./workspace-ui.js"
16
17
  import { replacedWords } from "./task-status.js";
17
18
  import { failedAttemptSentence, latestFinishedAttempt } from "./needs-you.js";
18
19
  import { buildReviewOf } from "./review-switch.js";
20
+ import { vanishedStopOf, vanishedStopSentence } from "./vanished-retry.js";
21
+ import { routeChangeOf } from "./route-change.js";
19
22
  import { BUILT_IN, refArchived, parseCapabilityKey } from "./store.js";
20
23
  import { shortWhen } from "./when-html.js";
21
24
  export const DEFAULT_MAX_OPEN_DECISIONS = 5;
@@ -81,7 +84,7 @@ export function scopeApprovedForDispatch(store, taskRef, now) {
81
84
  JOIN task_ref ON task_ref.id = ? AND task_scope.task_id = task_ref.external_id
82
85
  WHERE task_scope.approved_digest = task_scope.digest AND task_scope.approved_at IS NOT NULL
83
86
  AND ${authorityStandsSql("task_scope", "task_ref.repo", "?")}`)
84
- .get(taskRef, now.toISOString(), now.toISOString(), now.toISOString());
87
+ .get(taskRef, now.toISOString(), now.toISOString(), now.toISOString(), now.toISOString());
85
88
  return row !== undefined;
86
89
  }
87
90
  /** The phase the ordinary dispatch loop would choose before it resolves an
@@ -159,7 +162,7 @@ function reviewViewOf(sourceRun, retry) {
159
162
  };
160
163
  }
161
164
  function approvedProfile(scope) {
162
- if (scope === null || scope.approvalKind === "chain")
165
+ if (scope === null)
163
166
  return null;
164
167
  return scope.approvedProfile ?? scope.profile ?? null;
165
168
  }
@@ -229,9 +232,9 @@ export function diagnoseTaskDispatch(store, taskId, now, readableRepos = null) {
229
232
  return answer(code, code === "reviewing" ? "running" : "waiting", status.label, status.detail, { action: retry.state === "retryable" ? "retry-review" : "open-result", review });
230
233
  }
231
234
  if (!accepted && proof?.verdict === "refuted")
232
- return answer("proof-refuted", "waiting", status.label, `${status.detail} Review the evidence to correct it, or record an explicit acceptance.`, { action: "open-result", review });
235
+ return answer("proof-refuted", "waiting", status.label, `${status.detail} Open the result to send it back, or accept it with a reason.`, { action: "open-result", review });
233
236
  if (!accepted && proof?.verdict === "short")
234
- return answer("needs-verification", "waiting", status.label, `${status.detail} Open the result for the exact criteria still needing verification.`, { action: "open-result", review });
237
+ return answer("needs-verification", "waiting", status.label, `${status.detail} Open the result to see which requirements still need checking.`, { action: "open-result", review });
235
238
  if (!accepted && proof === null && noChangeRecord !== true)
236
239
  return answer("needs-verification", "waiting", status.label, status.detail, { action: "open-result", review });
237
240
  return answer("complete", "terminal", status.label, review?.state === "succeeded" && review.attempt !== null && review.attempt > 1
@@ -248,16 +251,22 @@ export function diagnoseTaskDispatch(store, taskId, now, readableRepos = null) {
248
251
  // The family's latest finished attempt's own recorded reason, or that none was recorded: never "review its incident".
249
252
  const family = store.taskFamilyOf(taskId, ref.repo === null ? [] : [ref.repo], ref.repo === null);
250
253
  const runs = family === null || family.problem !== null ? store.runsFor(ref.id) : family.versions.flatMap(version => store.runsFor(version.refId));
251
- return answer("failed", "terminal", "Needs a retry", failedAttemptSentence(latestFinishedAttempt(runs)?.reason), { action: "retry-task" });
254
+ const stopped = vanishedStopOf(store, ref.id);
255
+ return answer("failed", "terminal", "Needs a retry", stopped === null ? failedAttemptSentence(latestFinishedAttempt(runs)?.reason) : vanishedStopSentence(stopped), { action: "retry-task" });
252
256
  }
253
257
  if (store.hasLiveClaim(ref.id, now))
254
- return answer("running", "running", "Running now", "A worker owns the current live claim.");
258
+ return answer("running", "running", "Running now", "A builder is working on it now.");
255
259
  if (task.state === "running")
256
- return answer("vanished-run", "waiting", "Build vanished", "The task says running, but no current claim owns it; reconcile it before retrying.", { action: "retry-task" });
260
+ return answer("vanished-run", "waiting", "Build vanished", "The build stopped unexpectedly. Retry it.", { action: "retry-task" });
257
261
  if (updateAdmissionPaused(store.raw()))
258
262
  return answer("updating", "waiting", "Waiting for app update", UPDATE_PAUSED);
259
263
  const local = taskReadinessBlocker(store, ref.id, now);
260
264
  if (local?.code === "hold") {
265
+ // The storage check couldn't finish (dispose.ts holdForStorage): its own words, and Try again.
266
+ if (local.ownerKind === "backoff" && local.message.startsWith(`held: ${STORAGE_HOLD_PREFIX}`)) {
267
+ const when = local.until === null ? "" : ` It tries again on its own ${retryWhenWords(local.until, now)}.`;
268
+ return answer("storage-blocked", "waiting", "Needs macOS permission", `${local.message.slice(`held: ${STORAGE_HOLD_PREFIX}`.length)}${when}`, { action: "unhold", nextAt: local.until });
269
+ }
261
270
  if (local.ownerKind === "backoff") {
262
271
  // Run 2085: an attempt that stopped before its handoff says so plainly.
263
272
  const last = store.runsFor(ref.id).find(one => one.role === "builder" && one.finishedAt !== null);
@@ -270,7 +279,7 @@ export function diagnoseTaskDispatch(store, taskId, now, readableRepos = null) {
270
279
  if (local.ownerKind === "decision")
271
280
  return answer("waiting-decision", "waiting", "Waiting on your answer", "An agent parked a question; answering it resumes the task.", { action: "answer-decision" });
272
281
  if (local.ownerKind === "incident")
273
- return answer("waiting-incident", "waiting", "Needs a retry", "An unresolved incident holds the next attempt.", { action: "retry-task" });
282
+ return answer("waiting-incident", "waiting", "Needs a retry", "The last attempts failed the same way. Retry, or change the plan.", { action: "retry-task" });
274
283
  if (local.ownerKind === "stop")
275
284
  return answer("stopped", "waiting", "Paused", `${local.message.replace(/^held:\s*/, "")}. The attempt's work is preserved; resuming that exact attempt lifts this pause.`, { action: "resume-run" });
276
285
  return answer("held", "waiting", "On hold", local.message.replace(/^held:\s*/, ""), { action: local.ownerKind === "operator" ? "unhold" : "inspect-hold" });
@@ -288,14 +297,14 @@ export function diagnoseTaskDispatch(store, taskId, now, readableRepos = null) {
288
297
  const role = dispatchRoleFor(store, ref.id, now);
289
298
  const scope = store.getScope(taskId);
290
299
  if (ref.repo === null)
291
- return answer("needs-project", "waiting", "Needs a project", "Place this task in a repository before a worker can claim it.", { action: "place-task", role });
300
+ return answer("needs-project", "waiting", "Needs a project", "Choose a project for this task so a builder can start it.", { action: "place-task", role });
292
301
  if (role !== "planner") {
293
302
  if (scope === null)
294
- return answer("needs-scope", "waiting", "Needs a scope", "Write the success contract or ask the planner to draft it.", { action: "write-scope", role });
303
+ return answer("needs-scope", "waiting", "Needs a plan", "Write the plan, or ask the planner to draft it.", { action: "write-scope", role });
295
304
  if (scope.profileState === "unresolved")
296
305
  return answer("needs-agent-profile", "waiting", "Needs an agent profile", scope.unresolvedReason ?? "Choose an available provider and model.", { action: "select-agent", role });
297
306
  if (!scopeApprovedForDispatch(store, ref.id, now) || !approvalOf(scope).approved) {
298
- return answer("needs-approval", "waiting", "Needs your approval", "Review and sign the current scope before a worker can claim it.", { action: "approve-scope", role });
307
+ return answer("needs-approval", "waiting", "Needs your approval", routeChangeOf(store, taskId) ?? "Review the plan and approve it so a builder can start.", { action: "approve-scope", role });
299
308
  }
300
309
  }
301
310
  const gap = missingCapability(store, ref.id, ref.repo, now);
@@ -315,14 +324,14 @@ export function diagnoseTaskDispatch(store, taskId, now, readableRepos = null) {
315
324
  }
316
325
  const available = alive.filter(one => store.liveClaimCount(one.name, now) < one.capacity);
317
326
  if (available.length === 0)
318
- return answer("worker-at-capacity", "retrying", "Waiting for worker capacity", "Every eligible worker is busy; this task starts when a slot is released.", { role });
327
+ return answer("worker-at-capacity", "retrying", "Waiting its turn", "Builders are busy; it starts when one is free.", { role });
319
328
  const profile = approvedProfile(scope);
320
329
  if (profile !== null) {
321
330
  const exhausted = available.map(one => store.readQuotaState(one.name, profile.provider, profile.model, now)).filter(one => one?.state === "exhausted");
322
331
  if (exhausted.length === available.length) {
323
332
  const resets = exhausted.map(one => one?.resetAt ?? null).filter((one) => one !== null).sort();
324
333
  const nextAt = resets[0] ?? null;
325
- return answer("provider-quota", "retrying", "Provider quota exhausted", nextAt === null ? "The provider has not supplied a reset time; this needs operator attention." : `The next recorded reset is ${nextAt}.`, { action: nextAt === null ? "select-agent" : null, nextAt, role });
334
+ return answer("provider-quota", "retrying", "Provider quota exhausted", nextAt === null ? "The provider gave no reset time. Choose another agent, or wait for the limit to reset." : `The next recorded reset is ${nextAt}.`, { action: nextAt === null ? "select-agent" : null, nextAt, role });
326
335
  }
327
336
  }
328
337
  // The sign-in pause: the task's provider stopped working; nothing it would
@@ -343,11 +352,11 @@ export function diagnoseTaskDispatch(store, taskId, now, readableRepos = null) {
343
352
  const sourceProblem = plannerSourceProblemOf(store, taskId);
344
353
  if (sourceProblem !== null)
345
354
  return answer("planner-source", "waiting", sourceProblem.title, sourceProblem.detail, { action: "write-scope", role });
346
- return answer("planning-ready", "retrying", "Planner ready", "An eligible worker can draft the scope on the next pass.", { role });
355
+ return answer("planning-ready", "retrying", "Waiting to plan", "A builder can draft the plan next.", { role });
347
356
  }
348
357
  if (role === "scout")
349
- return answer("scouting-ready", "retrying", "Scout ready", "An eligible worker can produce the report on the next pass.", { role });
350
- return answer("ready", "retrying", "Ready to run", "An eligible worker has capacity and every dispatch gate currently passes.", { role });
358
+ return answer("scouting-ready", "retrying", "Waiting to research", "A builder can write the report next.", { role });
359
+ return answer("ready", "retrying", "Ready to run", "A builder is free and nothing is in the way.", { role });
351
360
  }
352
361
  export function diagnosisIsDispatchable(diagnosis) {
353
362
  return diagnosis?.code === "ready" || diagnosis?.code === "planning-ready" || diagnosis?.code === "scouting-ready";
package/dist/dispose.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { STORAGE_HOLD_PREFIX } from "./needs-you.js";
1
2
  import { type FailureClass } from "./claim.js";
2
3
  import type { BuildResult } from "./builder.js";
3
4
  import type { Store } from "./store.js";
@@ -89,6 +90,20 @@ export type Disposition = {
89
90
  * results and failed checks go straight to the person, as before. */
90
91
  export declare function maybeRequestAutoReview(store: Store, repo: string, runId: number, committed: boolean, noChange: boolean, now: Date, root?: string): void;
91
92
  export declare function disposeBuildOutcome(context: DisposeContext, result: BuildResult): Disposition;
93
+ /** How long a task waits after the storage check couldn't finish before it tries again on its own. */
94
+ export declare const STORAGE_RETRY_MS: number;
95
+ export { STORAGE_HOLD_PREFIX };
96
+ /**
97
+ * The storage HOLD: the check couldn't finish, so no launch can be fenced
98
+ * now. The task waits STORAGE_RETRY_MS and tries again on its own (a person
99
+ * who allowed access in Privacy & Security needn't do more), and "Try again"
100
+ * (unhold) lifts it at once. One message per task an hour, with the words.
101
+ */
102
+ export declare function holdForStorage(store: Store, args: {
103
+ taskRef: number;
104
+ taskId: string;
105
+ message: string;
106
+ }, now: Date): void;
92
107
  /**
93
108
  * The stale-approval HOLD, shared by the post-build disposition above and
94
109
  * the tick's pre-admission refusal (v48 integrity): a pre-routing row
@@ -152,6 +167,10 @@ export type RepairTrigger = {
152
167
  } | {
153
168
  kind: "stopped";
154
169
  reason: RepairStopReason;
170
+ }
171
+ /** The check runs once more on the same commit, with no agent: the failure looked unrelated to the change. */
172
+ | {
173
+ kind: "rerun";
155
174
  } | {
156
175
  kind: "none";
157
176
  };