toolroll 0.9.103 → 0.9.105

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 (1518) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/README.md +27 -27
  3. package/dist/accent-colors.js +0 -29
  4. package/dist/acp-agents.js +0 -3
  5. package/dist/acp-attest.js +0 -30
  6. package/dist/acp-check.js +3 -70
  7. package/dist/acp-client.js +3 -94
  8. package/dist/acp-inspect.js +1 -20
  9. package/dist/action-ledger.js +0 -8
  10. package/dist/activity-line.js +0 -14
  11. package/dist/actor.js +0 -15
  12. package/dist/advanced-schema.js +12 -0
  13. package/dist/advanced-view.js +26 -0
  14. package/dist/advanced.js +61 -0
  15. package/dist/agent-board.js +0 -117
  16. package/dist/agent-fence.js +11 -367
  17. package/dist/agent-onboard.js +12 -50
  18. package/dist/agent-pulse.js +5 -38
  19. package/dist/agent-state-words.js +0 -8
  20. package/dist/agent-state.js +1 -45
  21. package/dist/agent-turns.js +3 -17
  22. package/dist/agentconfig.js +1 -99
  23. package/dist/agents-board.js +0 -60
  24. package/dist/agents-live.js +1 -8
  25. package/dist/api-tokens.js +0 -27
  26. package/dist/approval-authority.js +0 -59
  27. package/dist/approval-password.js +0 -10
  28. package/dist/approval-policy.js +0 -29
  29. package/dist/approval-rules-ui.js +0 -9
  30. package/dist/assignment-adapters.js +0 -14
  31. package/dist/assignment-brief.js +1 -17
  32. package/dist/assignment-delivery.js +0 -22
  33. package/dist/assignment-presentation.js +0 -14
  34. package/dist/assignment-status.js +1 -30
  35. package/dist/assignment-ui.js +0 -12
  36. package/dist/assignment.js +117 -103
  37. package/dist/attest.js +0 -38
  38. package/dist/audit-cli.js +0 -9
  39. package/dist/backend.js +0 -59
  40. package/dist/backup-ui.js +0 -12
  41. package/dist/backup.js +8 -61
  42. package/dist/batch-checks.js +0 -20
  43. package/dist/batch-policy.js +0 -4
  44. package/dist/beads.js +0 -48
  45. package/dist/bin.js +0 -8
  46. package/dist/board.js +1 -36
  47. package/dist/boot-identity.js +0 -42
  48. package/dist/bounded-spawn.js +4 -28
  49. package/dist/brand-mark.js +0 -21
  50. package/dist/brief-fence.js +0 -16
  51. package/dist/browser/terminal.css +1 -1
  52. package/dist/browser/terminal.js +16 -16
  53. package/dist/browser/workspace.css +2 -2
  54. package/dist/browser/workspace.js +26 -26
  55. package/dist/browser-crew.js +0 -8
  56. package/dist/browser-shell.js +2 -15
  57. package/dist/browser-workspace.js +6 -30
  58. package/dist/budget-alerts.js +1 -4
  59. package/dist/build-review.js +2 -50
  60. package/dist/builder-restart.js +0 -13
  61. package/dist/builder.js +21 -1035
  62. package/dist/canonical-json.js +0 -12
  63. package/dist/capscan.js +1 -32
  64. package/dist/card-catalog.js +0 -12
  65. package/dist/card-cli.js +0 -1
  66. package/dist/card-render.js +0 -25
  67. package/dist/card-sources.js +0 -10
  68. package/dist/chat-acceptance.js +0 -7
  69. package/dist/chat-actions.js +5 -190
  70. package/dist/chat-admission.js +0 -7
  71. package/dist/chat-approval.js +0 -25
  72. package/dist/chat-ask.js +0 -17
  73. package/dist/chat-card-part.js +0 -3
  74. package/dist/chat-card.js +0 -6
  75. package/dist/chat-channel.js +2 -83
  76. package/dist/chat-continuity.js +0 -31
  77. package/dist/chat-controls.js +0 -7
  78. package/dist/chat-core.js +0 -55
  79. package/dist/chat-decide.js +2 -153
  80. package/dist/chat-delivery-state.js +0 -49
  81. package/dist/chat-delivery.js +2 -143
  82. package/dist/chat-display.js +0 -2
  83. package/dist/chat-evidence.js +0 -65
  84. package/dist/chat-flow.js +0 -72
  85. package/dist/chat-follow.js +0 -13
  86. package/dist/chat-inbox.js +0 -34
  87. package/dist/chat-live-schema.js +0 -14
  88. package/dist/chat-live.js +2 -87
  89. package/dist/chat-message-states.js +13 -40
  90. package/dist/chat-messages.js +0 -153
  91. package/dist/chat-migration.js +0 -57
  92. package/dist/chat-polish.js +0 -7
  93. package/dist/chat-quiet.js +0 -37
  94. package/dist/chat-review.js +0 -4
  95. package/dist/chat-rooms.js +0 -22
  96. package/dist/chat-settings-page.js +0 -4
  97. package/dist/chat-task-actions.js +0 -7
  98. package/dist/chat-terms.js +0 -21
  99. package/dist/chat-voice.js +0 -38
  100. package/dist/chat-warmth.js +1 -3
  101. package/dist/check-access.js +0 -30
  102. package/dist/check-facts.js +2 -62
  103. package/dist/check-failure.js +0 -98
  104. package/dist/check-levels-ui.js +4 -10
  105. package/dist/check-levels.js +3 -35
  106. package/dist/check-load.js +1 -49
  107. package/dist/check-only-standing.js +0 -6
  108. package/dist/check-only.js +0 -22
  109. package/dist/check-progress.js +0 -32
  110. package/dist/check-repair.js +2 -35
  111. package/dist/check-report.js +1 -108
  112. package/dist/check-stamp.js +0 -20
  113. package/dist/checkout-cleanup.js +0 -84
  114. package/dist/checkout-proof.js +1 -13
  115. package/dist/child-database.js +0 -3
  116. package/dist/claim.js +4 -508
  117. package/dist/claude-print.js +0 -10
  118. package/dist/cli-fast.js +0 -8
  119. package/dist/cli-help.js +90 -78
  120. package/dist/cli-http.js +0 -10
  121. package/dist/cli.js +26 -241
  122. package/dist/code-extract.js +0 -6
  123. package/dist/code-map-acts.js +0 -7
  124. package/dist/code-map-admission.js +2 -26
  125. package/dist/code-map-build.js +3 -24
  126. package/dist/code-map-cli.js +0 -4
  127. package/dist/code-map-main.js +0 -6
  128. package/dist/code-map-read.js +0 -12
  129. package/dist/code-map-report.js +0 -9
  130. package/dist/code-map-shape.js +0 -19
  131. package/dist/code-map-store.js +0 -26
  132. package/dist/codex-limits.js +1 -17
  133. package/dist/coding-context.js +0 -10
  134. package/dist/coding-handoff.js +0 -14
  135. package/dist/coding-provider.js +0 -39
  136. package/dist/coding-shipping-ui.js +0 -1
  137. package/dist/coding-ui.js +0 -1
  138. package/dist/coding-update.js +1 -18
  139. package/dist/coding-workspace.js +0 -27
  140. package/dist/commit-extract.js +0 -83
  141. package/dist/connect-cli.js +0 -19
  142. package/dist/console-chrome.js +1 -34
  143. package/dist/console-instance.js +2 -91
  144. package/dist/container-state.js +0 -4
  145. package/dist/containment.js +2 -105
  146. package/dist/contract-changes.js +0 -6
  147. package/dist/contracts/acceptance-terms.js +0 -7
  148. package/dist/contracts/chat-actions.js +0 -46
  149. package/dist/contracts/chat-callback-rows.js +0 -8
  150. package/dist/contracts/chat-card.js +0 -14
  151. package/dist/contracts/chat-content.js +0 -55
  152. package/dist/contracts/chat-tables.js +0 -7
  153. package/dist/contracts/cli.js +0 -59
  154. package/dist/contracts/coding-activity.js +0 -15
  155. package/dist/contracts/coding-context.js +0 -15
  156. package/dist/contracts/coding-handoff.js +0 -11
  157. package/dist/contracts/coding-workspace.js +0 -14
  158. package/dist/contracts/console-api.js +3 -54
  159. package/dist/contracts/contract-test.js +0 -14
  160. package/dist/contracts/contract.js +0 -48
  161. package/dist/contracts/decision.js +0 -20
  162. package/dist/contracts/diff-stat.js +0 -16
  163. package/dist/contracts/discord-callback.js +0 -9
  164. package/dist/contracts/flow-card.js +0 -18
  165. package/dist/contracts/flow-propose.js +0 -8
  166. package/dist/contracts/flow-send.js +0 -31
  167. package/dist/contracts/flow.js +0 -112
  168. package/dist/contracts/gateway-tools.js +0 -22
  169. package/dist/contracts/handoff.js +0 -22
  170. package/dist/contracts/integration-metadata.js +0 -39
  171. package/dist/contracts/lead-context.js +0 -14
  172. package/dist/contracts/lead-tools.js +0 -49
  173. package/dist/contracts/mcp-oauth.js +0 -12
  174. package/dist/contracts/memory-pass.js +0 -21
  175. package/dist/contracts/model-catalog.js +0 -9
  176. package/dist/contracts/observation-request.js +0 -11
  177. package/dist/contracts/plan.js +0 -16
  178. package/dist/contracts/project-knowledge.js +0 -26
  179. package/dist/contracts/project-memory.js +0 -16
  180. package/dist/contracts/project-skills.js +0 -31
  181. package/dist/contracts/proof.js +0 -23
  182. package/dist/contracts/provider.js +0 -9
  183. package/dist/contracts/recipes.js +0 -16
  184. package/dist/contracts/release-check.js +0 -61
  185. package/dist/contracts/release-terms.js +0 -27
  186. package/dist/contracts/retention.js +0 -12
  187. package/dist/contracts/review-findings.js +0 -13
  188. package/dist/contracts/route-results.js +0 -15
  189. package/dist/contracts/route.js +0 -33
  190. package/dist/contracts/scope.js +0 -29
  191. package/dist/contracts/scout-report.js +0 -34
  192. package/dist/contracts/slack-callback.js +0 -11
  193. package/dist/contracts/sort-answer.js +0 -24
  194. package/dist/contracts/stage-output.js +0 -46
  195. package/dist/contracts/storage.js +0 -8
  196. package/dist/contracts/store-json.js +0 -41
  197. package/dist/contracts/subagent-turn.js +0 -23
  198. package/dist/contracts/task-sizing.js +0 -10
  199. package/dist/contracts/teams-callback.js +0 -7
  200. package/dist/contracts/telegram-callback.js +0 -27
  201. package/dist/contracts/trigger-payloads.js +0 -41
  202. package/dist/contracts/update-journal.js +0 -47
  203. package/dist/contracts/verification-receipt.js +0 -36
  204. package/dist/contracts/verification-view.js +0 -15
  205. package/dist/contracts/youiyoux-request.js +0 -26
  206. package/dist/control-setup.js +0 -7
  207. package/dist/control-ui.js +0 -3
  208. package/dist/controller-service.js +0 -4
  209. package/dist/controller-supervisor.js +0 -15
  210. package/dist/converse.js +3 -129
  211. package/dist/coordinator-proposals.js +1 -6
  212. package/dist/coordinator.js +0 -65
  213. package/dist/credentials-ui.js +0 -6
  214. package/dist/daemon.js +0 -137
  215. package/dist/database-reclaim.js +0 -3
  216. package/dist/decision.js +0 -78
  217. package/dist/demo-chat.js +4 -15
  218. package/dist/demo-sign-in.js +77 -0
  219. package/dist/demo.js +5 -194
  220. package/dist/deploy-gate.js +0 -20
  221. package/dist/deploy-lock.js +0 -4
  222. package/dist/deploy-phase.js +0 -22
  223. package/dist/deploy-rescue.js +0 -21
  224. package/dist/deprecations.js +0 -12
  225. package/dist/design/kit.css +9 -6
  226. package/dist/design/kit.js +2 -33
  227. package/dist/desktop-access.js +0 -9
  228. package/dist/desktop-bundle.js +1 -3
  229. package/dist/desktop-host.js +0 -34
  230. package/dist/desktop-update-gate.js +0 -8
  231. package/dist/desktop-update-recovery.js +1 -18
  232. package/dist/desktop-update.js +2 -48
  233. package/dist/digest-times.js +0 -2
  234. package/dist/disclosure.js +0 -5
  235. package/dist/discord-api.js +0 -6
  236. package/dist/discord-chat.js +0 -31
  237. package/dist/discord.js +0 -7
  238. package/dist/discover.js +0 -50
  239. package/dist/dispatch.js +61 -60
  240. package/dist/dispose.js +0 -208
  241. package/dist/doctor.js +0 -48
  242. package/dist/easy-start-args.js +7 -7
  243. package/dist/easy-start.js +32 -45
  244. package/dist/egress.js +1 -63
  245. package/dist/email-settings.js +0 -8
  246. package/dist/envelope.js +50 -86
  247. package/dist/eval-gate.js +1 -37
  248. package/dist/eval-hooks.js +0 -120
  249. package/dist/eval-oracle-main.js +0 -7
  250. package/dist/eval-oracle.js +3 -42
  251. package/dist/eval-world.js +1 -23
  252. package/dist/evals.js +6 -134
  253. package/dist/evidence-pack.js +0 -29
  254. package/dist/evidence-pair.js +0 -17
  255. package/dist/evidence.js +4 -280
  256. package/dist/exec.js +19 -404
  257. package/dist/exhaustion.js +0 -30
  258. package/dist/export-ui.js +0 -7
  259. package/dist/export.js +1 -38
  260. package/dist/failing-first.js +0 -6
  261. package/dist/fallback-schema.js +0 -5
  262. package/dist/fallback.js +0 -81
  263. package/dist/fast-start.js +0 -97
  264. package/dist/fast-terms.js +0 -3
  265. package/dist/fenced-check-coverage.js +0 -11
  266. package/dist/findings.js +1 -63
  267. package/dist/first-run.js +4 -57
  268. package/dist/first-tasks-child.js +0 -5
  269. package/dist/flaky-ci.js +1 -24
  270. package/dist/flaky-cli.js +0 -4
  271. package/dist/flaky.js +0 -43
  272. package/dist/fleet-schema.js +0 -11
  273. package/dist/flow-actions.js +0 -31
  274. package/dist/flow-browser.js +0 -42
  275. package/dist/flow-cadence.js +1 -24
  276. package/dist/flow-card-task.js +0 -11
  277. package/dist/flow-changed.js +0 -16
  278. package/dist/flow-code.js +1 -45
  279. package/dist/flow-draft.js +0 -17
  280. package/dist/flow-engine.js +2 -76
  281. package/dist/flow-gallery-ui.js +0 -28
  282. package/dist/flow-gallery.js +0 -54
  283. package/dist/flow-insights.js +0 -12
  284. package/dist/flow-items.js +0 -27
  285. package/dist/flow-live.js +0 -31
  286. package/dist/flow-people.js +0 -14
  287. package/dist/flow-pull-request.js +0 -32
  288. package/dist/flow-replies.js +0 -9
  289. package/dist/flow-result-card.js +0 -8
  290. package/dist/flow-schedule.js +0 -74
  291. package/dist/flow-scripts.js +0 -13
  292. package/dist/flow-secrets.js +0 -10
  293. package/dist/flow-send.js +0 -45
  294. package/dist/flow-share.js +0 -60
  295. package/dist/flow-sort.js +1 -24
  296. package/dist/flow-starters-ui.js +0 -2
  297. package/dist/flow-starters.js +0 -13
  298. package/dist/flow-steps.js +0 -80
  299. package/dist/flow-triggers.js +2 -256
  300. package/dist/flow-unattended-words.js +0 -13
  301. package/dist/flow-unattended.js +2 -115
  302. package/dist/flows-cli.js +2 -36
  303. package/dist/flows-ui.js +0 -51
  304. package/dist/flows.js +0 -158
  305. package/dist/folder-gate.js +0 -21
  306. package/dist/folder-look.js +0 -42
  307. package/dist/follow-through-brief.js +0 -6
  308. package/dist/follow-through-cli.js +0 -5
  309. package/dist/fonts.js +0 -13
  310. package/dist/gaps.js +0 -20
  311. package/dist/gate-failure.js +0 -7
  312. package/dist/git-floor.js +0 -12
  313. package/dist/git-incident.js +2 -38
  314. package/dist/git-views.js +0 -24
  315. package/dist/git.js +0 -31
  316. package/dist/github-import.js +0 -22
  317. package/dist/github-jobs.js +0 -12
  318. package/dist/google-mail.js +2 -27
  319. package/dist/grant.js +0 -110
  320. package/dist/graph.js +0 -108
  321. package/dist/guides.js +4 -15
  322. package/dist/handover-note.js +0 -12
  323. package/dist/health-cli.js +0 -2
  324. package/dist/home-groups.js +0 -15
  325. package/dist/html.js +0 -54
  326. package/dist/install-method.js +0 -12
  327. package/dist/integrations-ui.js +0 -15
  328. package/dist/integrations.js +7 -50
  329. package/dist/invoke.js +1 -381
  330. package/dist/is-record.js +0 -1
  331. package/dist/issues.js +0 -48
  332. package/dist/jsonl-discriminants.js +0 -6
  333. package/dist/keymap.js +2 -16
  334. package/dist/keys.js +0 -56
  335. package/dist/kits-ui.js +0 -3
  336. package/dist/kits.js +1 -24
  337. package/dist/knowledge-cli.js +0 -4
  338. package/dist/knowledge-ui.js +0 -8
  339. package/dist/landed-cleanup.js +0 -119
  340. package/dist/laptop-background.js +0 -85
  341. package/dist/laptop-service.js +0 -67
  342. package/dist/latency-timeline.js +2 -23
  343. package/dist/lead-about.js +0 -7
  344. package/dist/lead-answer-eval.js +0 -39
  345. package/dist/lead-capabilities.js +0 -19
  346. package/dist/lead-cli-live.js +0 -22
  347. package/dist/lead-cli.js +0 -27
  348. package/dist/lead-commitments.js +1 -27
  349. package/dist/lead-context.js +2 -42
  350. package/dist/lead-contract.js +0 -8
  351. package/dist/lead-doors.js +0 -105
  352. package/dist/lead-follow.js +0 -41
  353. package/dist/lead-identity.js +1 -4
  354. package/dist/lead-latency-schema.js +0 -13
  355. package/dist/lead-people.js +3 -18
  356. package/dist/lead-progress.js +0 -12
  357. package/dist/lead-queue-runtime.js +0 -26
  358. package/dist/lead-queue.js +0 -35
  359. package/dist/lead-route.js +0 -33
  360. package/dist/lead-status.js +0 -37
  361. package/dist/lead-sweep.js +0 -18
  362. package/dist/lead-tools.js +0 -160
  363. package/dist/lead-voice.js +0 -54
  364. package/dist/lead.js +2 -105
  365. package/dist/learning-child.js +0 -6
  366. package/dist/learning-look.js +0 -14
  367. package/dist/ledger-chain.js +0 -34
  368. package/dist/ledger-csv.js +0 -2
  369. package/dist/ledger-view.js +0 -3
  370. package/dist/lesson-notes.js +0 -56
  371. package/dist/limits-ui.js +0 -14
  372. package/dist/link.js +0 -79
  373. package/dist/live-backup.js +3 -33
  374. package/dist/live-bus.js +7 -81
  375. package/dist/live-children-read.js +4 -47
  376. package/dist/live-children.js +4 -44
  377. package/dist/live-detail.js +0 -17
  378. package/dist/live-input.js +5 -68
  379. package/dist/live-main-read.js +1 -14
  380. package/dist/live-notes.js +0 -12
  381. package/dist/live-open.js +1 -23
  382. package/dist/live-records.js +4 -151
  383. package/dist/live-reply.js +1 -51
  384. package/dist/live-terminal.js +12 -111
  385. package/dist/live.js +4 -130
  386. package/dist/local-owner-acts.js +168 -0
  387. package/dist/local-owner.js +15 -80
  388. package/dist/log.js +0 -8
  389. package/dist/login-secrets.js +2 -38
  390. package/dist/machine-check.js +0 -2
  391. package/dist/machine-identity.js +1 -46
  392. package/dist/mailbox.js +0 -30
  393. package/dist/maintenance.js +1 -3
  394. package/dist/mcp-connect.js +0 -88
  395. package/dist/mcp-core.js +0 -45
  396. package/dist/mcp-http.js +0 -13
  397. package/dist/mcp-oauth.js +0 -37
  398. package/dist/mcp-person.js +0 -11
  399. package/dist/mcp.js +3 -73
  400. package/dist/memory-cli.js +0 -3
  401. package/dist/memory-pass.js +0 -53
  402. package/dist/memory-tidy.js +0 -55
  403. package/dist/memory-use.js +2 -24
  404. package/dist/merge-checklist.js +21 -29
  405. package/dist/metrics.js +0 -10
  406. package/dist/mobile-viewport.js +0 -6
  407. package/dist/model-catalog.js +1 -33
  408. package/dist/model-choices.js +9 -84
  409. package/dist/model-names.js +0 -9
  410. package/dist/models-cli.js +0 -13
  411. package/dist/models-ui.js +0 -17
  412. package/dist/modes.js +0 -35
  413. package/dist/monitoring-settings.js +2 -27
  414. package/dist/monitoring-ui.js +2 -14
  415. package/dist/monitoring.js +2 -38
  416. package/dist/names.js +0 -39
  417. package/dist/needs-you.js +7 -70
  418. package/dist/never-index.js +0 -9
  419. package/dist/nightly-check.js +0 -74
  420. package/dist/nightly-github.js +0 -168
  421. package/dist/notification-delivery.js +0 -3
  422. package/dist/notification-rows.js +0 -17
  423. package/dist/oauth-run-token.js +1 -37
  424. package/dist/observations.js +0 -16
  425. package/dist/oidc.js +1 -20
  426. package/dist/onboard.js +4 -57
  427. package/dist/one-step-chat-schema.js +0 -15
  428. package/dist/openrouter-models.js +0 -6
  429. package/dist/operate-remote-arguments.js +2 -17
  430. package/dist/operate-remote.js +0 -33
  431. package/dist/operate.js +280 -2304
  432. package/dist/orphan-sweep.js +3 -37
  433. package/dist/page-work-contract.js +0 -3
  434. package/dist/password-bearer.js +1 -11
  435. package/dist/passwordless.js +0 -3
  436. package/dist/peek-cli.js +0 -46
  437. package/dist/peek.js +2 -61
  438. package/dist/people-audit-ui.js +0 -6
  439. package/dist/person-proof.js +0 -6
  440. package/dist/phase-routing.js +8 -183
  441. package/dist/plain-schema.js +0 -14
  442. package/dist/plain-words.js +18 -12
  443. package/dist/plan-auto.js +3 -18
  444. package/dist/plan-login.js +0 -16
  445. package/dist/plan.js +0 -68
  446. package/dist/plane-review.js +0 -56
  447. package/dist/planner-source.js +0 -96
  448. package/dist/planner.js +0 -117
  449. package/dist/policy-ui.js +0 -8
  450. package/dist/policy.js +0 -47
  451. package/dist/prepared-evidence.js +0 -5
  452. package/dist/principal.js +0 -29
  453. package/dist/probe.js +0 -30
  454. package/dist/process-custody.js +0 -15
  455. package/dist/process-liveness.js +0 -32
  456. package/dist/process-tree.js +3 -29
  457. package/dist/project-access.js +0 -10
  458. package/dist/project-admission.js +1 -41
  459. package/dist/project-cli.js +0 -6
  460. package/dist/project-concurrency.js +0 -35
  461. package/dist/project-delete-ui.js +4 -29
  462. package/dist/project-delete.js +1 -73
  463. package/dist/project-demo.js +0 -13
  464. package/dist/project-file.js +0 -2
  465. package/dist/project-identity.js +0 -41
  466. package/dist/project-knowledge.js +0 -39
  467. package/dist/project-learning.js +3 -55
  468. package/dist/project-memory.js +2 -45
  469. package/dist/project-outcomes.js +0 -6
  470. package/dist/project-sandbox.js +0 -23
  471. package/dist/project-skills.js +0 -12
  472. package/dist/project-tools.js +6 -184
  473. package/dist/project.js +0 -48
  474. package/dist/prompt.js +0 -31
  475. package/dist/proof.js +0 -220
  476. package/dist/proposal.js +0 -50
  477. package/dist/protected-storage-look.js +0 -6
  478. package/dist/protected-storage.js +1 -84
  479. package/dist/provider-auth.js +3 -69
  480. package/dist/provider-capture.js +1 -15
  481. package/dist/provider-connection.js +0 -8
  482. package/dist/provider-home.js +0 -25
  483. package/dist/provider-limits.js +0 -14
  484. package/dist/provider.js +0 -324
  485. package/dist/public-access.js +11 -30
  486. package/dist/public-check.js +0 -16
  487. package/dist/publish.js +1 -150
  488. package/dist/pull-request-flow.js +6 -74
  489. package/dist/pull-request-schema.js +0 -4
  490. package/dist/pull-request-ui.js +0 -5
  491. package/dist/pulls.js +0 -80
  492. package/dist/push.js +5 -89
  493. package/dist/quick-start.js +1 -23
  494. package/dist/read-executor-worker.js +0 -1
  495. package/dist/read-executor.js +0 -10
  496. package/dist/read-only-request.js +0 -7
  497. package/dist/recipe-ui.js +0 -6
  498. package/dist/recipes.js +0 -13
  499. package/dist/release-adapters.js +6 -214
  500. package/dist/release-approval.js +0 -74
  501. package/dist/release-authority.js +0 -42
  502. package/dist/release-auto.js +0 -142
  503. package/dist/release-card.js +26 -103
  504. package/dist/release-carry.js +0 -132
  505. package/dist/release-ci-hold.js +0 -20
  506. package/dist/release-cli.js +0 -46
  507. package/dist/release-coverage.js +0 -16
  508. package/dist/release-gate.js +0 -30
  509. package/dist/release-git.js +0 -24
  510. package/dist/release-links.js +0 -17
  511. package/dist/release-net.js +0 -42
  512. package/dist/release-next.js +0 -25
  513. package/dist/release-recheck.js +0 -89
  514. package/dist/release-refusal.js +0 -18
  515. package/dist/release-view.js +0 -5
  516. package/dist/release.js +7 -341
  517. package/dist/releases.js +0 -49
  518. package/dist/remote-audit.js +0 -25
  519. package/dist/remote-command.js +0 -16
  520. package/dist/remote-destination.js +5 -26
  521. package/dist/remote-exec.js +1 -27
  522. package/dist/remote-main.js +1 -53
  523. package/dist/remote-run.js +0 -5
  524. package/dist/remote.js +0 -49
  525. package/dist/render.js +0 -133
  526. package/dist/reply-shape.js +0 -85
  527. package/dist/reply-voice.js +0 -7
  528. package/dist/report-summary.js +0 -5
  529. package/dist/reported-usage.js +0 -30
  530. package/dist/repos.js +9 -62
  531. package/dist/repository-context.js +1 -24
  532. package/dist/request-budget-ui.js +0 -4
  533. package/dist/request-budget.js +0 -23
  534. package/dist/restart-certification.js +0 -37
  535. package/dist/result-actions.js +0 -62
  536. package/dist/result-acts.js +0 -34
  537. package/dist/result-completion.js +9 -28
  538. package/dist/result-evidence-readers.js +0 -3
  539. package/dist/result-follow-ups.js +1 -39
  540. package/dist/result-review.js +0 -86
  541. package/dist/result-shots.js +0 -39
  542. package/dist/retention-ui.js +0 -7
  543. package/dist/retention.js +2 -46
  544. package/dist/review-context.js +0 -129
  545. package/dist/review-evidence.js +0 -4
  546. package/dist/review-switch.js +1 -7
  547. package/dist/reviewer.js +0 -35
  548. package/dist/route-change-check.js +0 -2
  549. package/dist/route-change.js +0 -16
  550. package/dist/route-hooks.js +0 -27
  551. package/dist/route-results.js +2 -58
  552. package/dist/route-rules.js +1 -106
  553. package/dist/route-savings.js +0 -36
  554. package/dist/route-store.js +1 -133
  555. package/dist/run-closeout.js +2 -50
  556. package/dist/run-efficiency.js +2 -44
  557. package/dist/run-ending.js +0 -13
  558. package/dist/runner-process.js +0 -33
  559. package/dist/runner.js +17 -189
  560. package/dist/sample-project.js +2 -27
  561. package/dist/sandbox-launch.js +4 -25
  562. package/dist/sandbox-runtime.js +1 -88
  563. package/dist/scan.js +0 -27
  564. package/dist/scope.js +88 -566
  565. package/dist/scout-browser-lock.js +0 -6
  566. package/dist/scout-browser.js +2 -68
  567. package/dist/scout-net.js +1 -32
  568. package/dist/scout-report.js +0 -22
  569. package/dist/scout.js +1 -116
  570. package/dist/secret-mint.js +0 -6
  571. package/dist/serve.js +29 -564
  572. package/dist/server/agents-computers.js +0 -10
  573. package/dist/server/agents-live-filed.js +0 -13
  574. package/dist/server/agents-live-lead.js +0 -19
  575. package/dist/server/agents-live-room.js +0 -19
  576. package/dist/server/chat.js +2 -194
  577. package/dist/server/chrome.js +17 -263
  578. package/dist/server/console.css +4 -4
  579. package/dist/server/edge-refusal.js +0 -3
  580. package/dist/server/flows.js +5 -74
  581. package/dist/server/guards.js +9 -86
  582. package/dist/server/handler-registry.js +0 -2
  583. package/dist/server/home-asks.js +1 -22
  584. package/dist/server/home.js +1 -30
  585. package/dist/server/http.js +0 -82
  586. package/dist/server/in-place.js +0 -15
  587. package/dist/server/kit-standalone.js +0 -20
  588. package/dist/server/kit.js +2 -114
  589. package/dist/server/last-checks.js +0 -2
  590. package/dist/server/live.js +1 -36
  591. package/dist/server/merge-ready-view.js +0 -6
  592. package/dist/server/mutation-key.js +3 -40
  593. package/dist/server/pages-assets.js +0 -16
  594. package/dist/server/pages.js +7 -195
  595. package/dist/server/people-tokens.js +3 -101
  596. package/dist/server/remote-hooks.js +0 -13
  597. package/dist/server/remote.js +0 -28
  598. package/dist/server/render-chat.js +8 -144
  599. package/dist/server/render-code-map.js +0 -5
  600. package/dist/server/render-flaky.js +0 -8
  601. package/dist/server/render-follow-through.js +2 -5
  602. package/dist/server/render-history.js +2 -34
  603. package/dist/server/render-new-task.js +2 -29
  604. package/dist/server/render-pages.js +1 -111
  605. package/dist/server/render-people.js +2 -46
  606. package/dist/server/render-projects.js +15 -32
  607. package/dist/server/render-release.js +1 -14
  608. package/dist/server/render-results.js +4 -355
  609. package/dist/server/render-settings.js +0 -15
  610. package/dist/server/render-tasks.js +17 -497
  611. package/dist/server/request-context.js +2 -9
  612. package/dist/server/retired-routes.js +0 -11
  613. package/dist/server/route-policy.js +0 -3
  614. package/dist/server/route-table.js +8 -133
  615. package/dist/server/runtime.js +0 -1
  616. package/dist/server/session.js +0 -28
  617. package/dist/server/settings.js +40 -246
  618. package/dist/server/signup-gate.js +0 -11
  619. package/dist/server/sweeps.js +0 -6
  620. package/dist/server/task-views.js +12 -227
  621. package/dist/server/tasks.js +37 -531
  622. package/dist/server/terminals.js +2 -46
  623. package/dist/server/welcome.js +2 -22
  624. package/dist/server-telemetry.js +0 -9
  625. package/dist/settings-groups-ui.js +50 -63
  626. package/dist/settings-kit-script.js +0 -19
  627. package/dist/settings-kit.js +0 -63
  628. package/dist/settings-proofs.js +0 -23
  629. package/dist/setup-guide.js +1 -9
  630. package/dist/shared-deps.js +9 -84
  631. package/dist/sign-in-guard.js +0 -27
  632. package/dist/skills-ui.js +0 -2
  633. package/dist/skills.js +2 -54
  634. package/dist/slack-api.js +0 -3
  635. package/dist/slack-chat.js +0 -25
  636. package/dist/slack-settings.js +0 -1
  637. package/dist/slack-socket.js +0 -5
  638. package/dist/slack.js +0 -4
  639. package/dist/sleep.js +0 -1
  640. package/dist/source-key.js +0 -10
  641. package/dist/spend-report.js +0 -29
  642. package/dist/spend-ui.js +0 -26
  643. package/dist/spend.js +0 -40
  644. package/dist/sqlite-runtime.js +0 -2
  645. package/dist/sqlite-telemetry.js +0 -9
  646. package/dist/sso-settings.js +0 -13
  647. package/dist/sso-ui.js +0 -2
  648. package/dist/staged-runtimes.js +5 -39
  649. package/dist/steer-capabilities.js +1 -7
  650. package/dist/steer-controls.js +0 -10
  651. package/dist/steer-live.js +0 -31
  652. package/dist/steer-mailbox.js +4 -65
  653. package/dist/steer-status.js +0 -7
  654. package/dist/stop-proof.js +5 -62
  655. package/dist/storage-sweep-child.js +1 -5
  656. package/dist/storage-sweep-process.js +2 -20
  657. package/dist/storage-sweep-schedule.js +0 -32
  658. package/dist/storage-sweep.js +2 -51
  659. package/dist/storage-ui.js +0 -18
  660. package/dist/storage.js +0 -31
  661. package/dist/store-baseline.js +0 -14
  662. package/dist/store.js +109 -4763
  663. package/dist/stream-scope.js +0 -16
  664. package/dist/structured-output.js +0 -39
  665. package/dist/style-asset.js +0 -2
  666. package/dist/subagent-admin.js +0 -9
  667. package/dist/subagent-desk.js +0 -29
  668. package/dist/subagent-memory.js +0 -38
  669. package/dist/subagent-question.js +0 -29
  670. package/dist/subagent-tools.js +1 -60
  671. package/dist/subagent-week.js +0 -28
  672. package/dist/subagent-work.js +1 -39
  673. package/dist/subagents-ui.js +1 -13
  674. package/dist/subagents.js +0 -40
  675. package/dist/subscription-chat.js +1 -42
  676. package/dist/summary.js +0 -19
  677. package/dist/surface.js +8 -73
  678. package/dist/sweep-gate.js +0 -2
  679. package/dist/sweep-quarantine.js +2 -13
  680. package/dist/sync.js +0 -47
  681. package/dist/tailnet.js +0 -9
  682. package/dist/tamper-scan.js +0 -15
  683. package/dist/task-activity.js +1 -16
  684. package/dist/task-aliases.js +0 -3
  685. package/dist/task-archive.js +0 -7
  686. package/dist/task-base.js +0 -18
  687. package/dist/task-composer.js +0 -2
  688. package/dist/task-control.js +0 -74
  689. package/dist/task-live.js +0 -23
  690. package/dist/task-moves.js +0 -28
  691. package/dist/task-outcome-cli.js +66 -19
  692. package/dist/task-review-brief.js +0 -7
  693. package/dist/task-sizing.js +0 -47
  694. package/dist/task-source.js +0 -23
  695. package/dist/task-status.js +0 -106
  696. package/dist/task-text.js +0 -12
  697. package/dist/team-chat-authorization.js +0 -3
  698. package/dist/team-contract.js +0 -2
  699. package/dist/team-http.js +0 -4
  700. package/dist/team-leads.js +1 -16
  701. package/dist/team-runtime.js +0 -13
  702. package/dist/team-ui.js +0 -1
  703. package/dist/team-updates.js +0 -4
  704. package/dist/teams-api.js +0 -12
  705. package/dist/teams-chat.js +0 -28
  706. package/dist/teams.js +0 -12
  707. package/dist/teardown-git.js +6 -294
  708. package/dist/telegram-flow.js +0 -51
  709. package/dist/telegram-lead.js +2 -203
  710. package/dist/telegram-live.js +1 -42
  711. package/dist/telegram-progress.js +0 -18
  712. package/dist/telegram-settings.js +0 -7
  713. package/dist/telegram-status.js +0 -46
  714. package/dist/telegram-team.js +1 -33
  715. package/dist/telegram.js +6 -454
  716. package/dist/templates.js +0 -24
  717. package/dist/terminal-catalog.js +2 -20
  718. package/dist/terminal-text.js +0 -12
  719. package/dist/test-infra.js +0 -50
  720. package/dist/test-temp.js +3 -26
  721. package/dist/text-limits.js +0 -92
  722. package/dist/tidy.js +0 -76
  723. package/dist/tier-report.js +0 -2
  724. package/dist/token-notices.js +1 -9
  725. package/dist/tokens-cli.js +0 -13
  726. package/dist/tool-broker.js +2 -53
  727. package/dist/tool-launcher.js +0 -14
  728. package/dist/tool-secret-store.js +3 -125
  729. package/dist/toolroll-update-cli.js +0 -9
  730. package/dist/toolroll-update-ui.js +0 -14
  731. package/dist/toolroll-update.js +13 -252
  732. package/dist/tools-ui.js +0 -17
  733. package/dist/transitions-recipes.js +0 -2
  734. package/dist/tree-proof.js +0 -23
  735. package/dist/tui-contract.js +0 -8
  736. package/dist/tui-source.js +91 -40
  737. package/dist/tui.js +54 -54
  738. package/dist/typed-start.js +0 -27
  739. package/dist/unfenced-test-support.js +0 -5
  740. package/dist/up-processes.js +1 -40
  741. package/dist/up-role-child.js +1 -13
  742. package/dist/update-notice.js +0 -1
  743. package/dist/vanished-retry.js +0 -40
  744. package/dist/verification-evidence.js +0 -39
  745. package/dist/version.js +0 -1
  746. package/dist/wake-hub.js +0 -28
  747. package/dist/webhook-limits.js +0 -7
  748. package/dist/webhook-readers.js +0 -30
  749. package/dist/webhook-signing.js +0 -14
  750. package/dist/webhooks.js +0 -54
  751. package/dist/welcome-facts.js +2 -14
  752. package/dist/when-html.js +0 -27
  753. package/dist/work-index.js +26 -98
  754. package/dist/work-summary.js +2 -17
  755. package/dist/workspace-motion.js +0 -2
  756. package/dist/workspace-revision.js +1 -21
  757. package/dist/workspace-ui.js +15 -135
  758. package/dist/worktree-notices.js +0 -3
  759. package/dist/worktree.js +0 -308
  760. package/dist/writes-mode.js +0 -1
  761. package/dist/youiyoux-intake.js +4 -159
  762. package/package.json +5 -4
  763. package/dist/accent-colors.d.ts +0 -51
  764. package/dist/acp-agents.d.ts +0 -43
  765. package/dist/acp-attest.d.ts +0 -44
  766. package/dist/acp-check.d.ts +0 -37
  767. package/dist/acp-client.d.ts +0 -163
  768. package/dist/acp-inspect.d.ts +0 -23
  769. package/dist/action-ledger.d.ts +0 -27
  770. package/dist/activity-line.d.ts +0 -29
  771. package/dist/actor.d.ts +0 -11
  772. package/dist/agent-board.d.ts +0 -229
  773. package/dist/agent-fence.d.ts +0 -479
  774. package/dist/agent-onboard.d.ts +0 -158
  775. package/dist/agent-pulse.d.ts +0 -43
  776. package/dist/agent-state-words.d.ts +0 -19
  777. package/dist/agent-state.d.ts +0 -65
  778. package/dist/agent-turns.d.ts +0 -52
  779. package/dist/agentconfig.d.ts +0 -191
  780. package/dist/agents-board.d.ts +0 -145
  781. package/dist/agents-live.d.ts +0 -31
  782. package/dist/api-tokens.d.ts +0 -80
  783. package/dist/approval-authority.d.ts +0 -51
  784. package/dist/approval-password.d.ts +0 -31
  785. package/dist/approval-policy.d.ts +0 -69
  786. package/dist/approval-rules-ui.d.ts +0 -40
  787. package/dist/assignment-adapters.d.ts +0 -152
  788. package/dist/assignment-brief.d.ts +0 -83
  789. package/dist/assignment-delivery.d.ts +0 -86
  790. package/dist/assignment-presentation.d.ts +0 -37
  791. package/dist/assignment-status.d.ts +0 -71
  792. package/dist/assignment-ui.d.ts +0 -68
  793. package/dist/assignment.d.ts +0 -318
  794. package/dist/attest.d.ts +0 -59
  795. package/dist/audit-cli.d.ts +0 -17
  796. package/dist/backend.d.ts +0 -97
  797. package/dist/backup-ui.d.ts +0 -32
  798. package/dist/backup.d.ts +0 -92
  799. package/dist/batch-checks.d.ts +0 -15
  800. package/dist/batch-policy.d.ts +0 -23
  801. package/dist/beads.d.ts +0 -34
  802. package/dist/bin.d.ts +0 -2
  803. package/dist/board.d.ts +0 -134
  804. package/dist/boot-identity.d.ts +0 -64
  805. package/dist/bounded-spawn.d.ts +0 -57
  806. package/dist/brand-icons.d.ts +0 -168
  807. package/dist/brand-mark.d.ts +0 -28
  808. package/dist/brief-fence.d.ts +0 -9
  809. package/dist/browser-crew.d.ts +0 -12
  810. package/dist/browser-shell.d.ts +0 -9
  811. package/dist/browser-workspace.d.ts +0 -1972
  812. package/dist/budget-alerts.d.ts +0 -19
  813. package/dist/build-review.d.ts +0 -38
  814. package/dist/builder-restart.d.ts +0 -21
  815. package/dist/builder.d.ts +0 -409
  816. package/dist/canonical-json.d.ts +0 -14
  817. package/dist/capscan.d.ts +0 -35
  818. package/dist/card-catalog.d.ts +0 -209
  819. package/dist/card-cli.d.ts +0 -43
  820. package/dist/card-render.d.ts +0 -43
  821. package/dist/card-sources.d.ts +0 -68
  822. package/dist/chat-acceptance.d.ts +0 -74
  823. package/dist/chat-actions.d.ts +0 -460
  824. package/dist/chat-admission.d.ts +0 -19
  825. package/dist/chat-approval.d.ts +0 -58
  826. package/dist/chat-ask.d.ts +0 -32
  827. package/dist/chat-card-part.d.ts +0 -11
  828. package/dist/chat-card.d.ts +0 -46
  829. package/dist/chat-channel.d.ts +0 -126
  830. package/dist/chat-continuity.d.ts +0 -32
  831. package/dist/chat-controls.d.ts +0 -117
  832. package/dist/chat-core.d.ts +0 -177
  833. package/dist/chat-decide.d.ts +0 -269
  834. package/dist/chat-delivery-state.d.ts +0 -132
  835. package/dist/chat-delivery.d.ts +0 -71
  836. package/dist/chat-display.d.ts +0 -1
  837. package/dist/chat-evidence.d.ts +0 -123
  838. package/dist/chat-flow.d.ts +0 -70
  839. package/dist/chat-follow.d.ts +0 -20
  840. package/dist/chat-inbox.d.ts +0 -57
  841. package/dist/chat-live-schema.d.ts +0 -17
  842. package/dist/chat-live.d.ts +0 -161
  843. package/dist/chat-message-states.d.ts +0 -75
  844. package/dist/chat-messages.d.ts +0 -338
  845. package/dist/chat-migration.d.ts +0 -30
  846. package/dist/chat-polish.d.ts +0 -17
  847. package/dist/chat-quiet.d.ts +0 -40
  848. package/dist/chat-review.d.ts +0 -51
  849. package/dist/chat-rooms.d.ts +0 -123
  850. package/dist/chat-settings-page.d.ts +0 -43
  851. package/dist/chat-task-actions.d.ts +0 -59
  852. package/dist/chat-terms.d.ts +0 -29
  853. package/dist/chat-voice.d.ts +0 -69
  854. package/dist/chat-warmth.d.ts +0 -21
  855. package/dist/check-access.d.ts +0 -54
  856. package/dist/check-facts.d.ts +0 -126
  857. package/dist/check-failure.d.ts +0 -113
  858. package/dist/check-levels-ui.d.ts +0 -36
  859. package/dist/check-levels.d.ts +0 -70
  860. package/dist/check-load.d.ts +0 -85
  861. package/dist/check-only-standing.d.ts +0 -36
  862. package/dist/check-only.d.ts +0 -15
  863. package/dist/check-progress.d.ts +0 -78
  864. package/dist/check-repair.d.ts +0 -47
  865. package/dist/check-report.d.ts +0 -177
  866. package/dist/check-stamp.d.ts +0 -46
  867. package/dist/checkout-cleanup.d.ts +0 -157
  868. package/dist/checkout-proof.d.ts +0 -28
  869. package/dist/child-database.d.ts +0 -12
  870. package/dist/claim.d.ts +0 -627
  871. package/dist/claude-print.d.ts +0 -12
  872. package/dist/cli-fast.d.ts +0 -8
  873. package/dist/cli-help.d.ts +0 -8
  874. package/dist/cli-http.d.ts +0 -58
  875. package/dist/cli.d.ts +0 -149
  876. package/dist/code-extract.d.ts +0 -44
  877. package/dist/code-map-acts.d.ts +0 -24
  878. package/dist/code-map-admission.d.ts +0 -52
  879. package/dist/code-map-build.d.ts +0 -63
  880. package/dist/code-map-cli.d.ts +0 -153
  881. package/dist/code-map-main.d.ts +0 -1
  882. package/dist/code-map-read.d.ts +0 -106
  883. package/dist/code-map-report.d.ts +0 -37
  884. package/dist/code-map-shape.d.ts +0 -172
  885. package/dist/code-map-store.d.ts +0 -136
  886. package/dist/codex-limits.d.ts +0 -15
  887. package/dist/coding-context.d.ts +0 -18
  888. package/dist/coding-handoff.d.ts +0 -39
  889. package/dist/coding-provider.d.ts +0 -88
  890. package/dist/coding-shipping-ui.d.ts +0 -5
  891. package/dist/coding-types.d.ts +0 -16
  892. package/dist/coding-ui.d.ts +0 -19
  893. package/dist/coding-update.d.ts +0 -28
  894. package/dist/coding-workspace.d.ts +0 -141
  895. package/dist/commit-extract.d.ts +0 -135
  896. package/dist/connect-cli.d.ts +0 -34
  897. package/dist/console-chrome.d.ts +0 -41
  898. package/dist/console-instance.d.ts +0 -157
  899. package/dist/container-state.d.ts +0 -5
  900. package/dist/containment.d.ts +0 -205
  901. package/dist/contract-changes.d.ts +0 -52
  902. package/dist/contracts/acceptance-terms.d.ts +0 -14
  903. package/dist/contracts/chat-actions.d.ts +0 -465
  904. package/dist/contracts/chat-callback-rows.d.ts +0 -59
  905. package/dist/contracts/chat-card.d.ts +0 -91
  906. package/dist/contracts/chat-content.d.ts +0 -551
  907. package/dist/contracts/chat-tables.d.ts +0 -12
  908. package/dist/contracts/cli.d.ts +0 -987
  909. package/dist/contracts/coding-activity.d.ts +0 -64
  910. package/dist/contracts/coding-context.d.ts +0 -97
  911. package/dist/contracts/coding-handoff.d.ts +0 -44
  912. package/dist/contracts/coding-workspace.d.ts +0 -165
  913. package/dist/contracts/console-api.d.ts +0 -539
  914. package/dist/contracts/contract-test.d.ts +0 -45
  915. package/dist/contracts/contract.d.ts +0 -92
  916. package/dist/contracts/decision.d.ts +0 -45
  917. package/dist/contracts/diff-stat.d.ts +0 -58
  918. package/dist/contracts/discord-callback.d.ts +0 -45
  919. package/dist/contracts/flow-card.d.ts +0 -53
  920. package/dist/contracts/flow-propose.d.ts +0 -334
  921. package/dist/contracts/flow-send.d.ts +0 -245
  922. package/dist/contracts/flow.d.ts +0 -19565
  923. package/dist/contracts/gateway-tools.d.ts +0 -472
  924. package/dist/contracts/handoff.d.ts +0 -91
  925. package/dist/contracts/health.d.ts +0 -82
  926. package/dist/contracts/integration-metadata.d.ts +0 -100
  927. package/dist/contracts/lead-context.d.ts +0 -165
  928. package/dist/contracts/lead-tools.d.ts +0 -2312
  929. package/dist/contracts/mcp-oauth.d.ts +0 -53
  930. package/dist/contracts/memory-pass.d.ts +0 -157
  931. package/dist/contracts/model-catalog.d.ts +0 -21
  932. package/dist/contracts/observation-request.d.ts +0 -37
  933. package/dist/contracts/plan.d.ts +0 -58
  934. package/dist/contracts/project-knowledge.d.ts +0 -159
  935. package/dist/contracts/project-memory.d.ts +0 -119
  936. package/dist/contracts/project-skills.d.ts +0 -120
  937. package/dist/contracts/proof.d.ts +0 -136
  938. package/dist/contracts/provider.d.ts +0 -40
  939. package/dist/contracts/recipes.d.ts +0 -166
  940. package/dist/contracts/release-check.d.ts +0 -371
  941. package/dist/contracts/release-terms.d.ts +0 -107
  942. package/dist/contracts/retention.d.ts +0 -42
  943. package/dist/contracts/review-findings.d.ts +0 -46
  944. package/dist/contracts/route-results.d.ts +0 -121
  945. package/dist/contracts/route.d.ts +0 -897
  946. package/dist/contracts/scope.d.ts +0 -105
  947. package/dist/contracts/scout-report.d.ts +0 -234
  948. package/dist/contracts/slack-callback.d.ts +0 -43
  949. package/dist/contracts/sort-answer.d.ts +0 -83
  950. package/dist/contracts/stage-output.d.ts +0 -127
  951. package/dist/contracts/storage.d.ts +0 -37
  952. package/dist/contracts/store-json.d.ts +0 -313
  953. package/dist/contracts/subagent-turn.d.ts +0 -43
  954. package/dist/contracts/task-sizing.d.ts +0 -24
  955. package/dist/contracts/teams-callback.d.ts +0 -13
  956. package/dist/contracts/telegram-callback.d.ts +0 -120
  957. package/dist/contracts/trigger-payloads.d.ts +0 -389
  958. package/dist/contracts/update-journal.d.ts +0 -254
  959. package/dist/contracts/verification-receipt.d.ts +0 -200
  960. package/dist/contracts/verification-view.d.ts +0 -102
  961. package/dist/contracts/youiyoux-request.d.ts +0 -248
  962. package/dist/control-setup.d.ts +0 -44
  963. package/dist/control-ui.d.ts +0 -37
  964. package/dist/controller-service.d.ts +0 -1
  965. package/dist/controller-supervisor.d.ts +0 -38
  966. package/dist/converse.d.ts +0 -316
  967. package/dist/coordinator-proposals.d.ts +0 -29
  968. package/dist/coordinator.d.ts +0 -186
  969. package/dist/credentials-ui.d.ts +0 -33
  970. package/dist/daemon.d.ts +0 -226
  971. package/dist/database-reclaim.d.ts +0 -4
  972. package/dist/decision.d.ts +0 -119
  973. package/dist/demo-chat.d.ts +0 -32
  974. package/dist/demo.d.ts +0 -153
  975. package/dist/deploy-gate.d.ts +0 -20
  976. package/dist/deploy-lock.d.ts +0 -8
  977. package/dist/deploy-phase.d.ts +0 -37
  978. package/dist/deploy-rescue.d.ts +0 -42
  979. package/dist/deprecations.d.ts +0 -20
  980. package/dist/design/kit.d.ts +0 -216
  981. package/dist/desktop-access.d.ts +0 -28
  982. package/dist/desktop-bundle.d.ts +0 -16
  983. package/dist/desktop-host.d.ts +0 -54
  984. package/dist/desktop-update-gate.d.ts +0 -12
  985. package/dist/desktop-update-recovery.d.ts +0 -14
  986. package/dist/desktop-update.d.ts +0 -147
  987. package/dist/digest-times.d.ts +0 -3
  988. package/dist/disclosure.d.ts +0 -6
  989. package/dist/discord-api.d.ts +0 -24
  990. package/dist/discord-chat.d.ts +0 -27
  991. package/dist/discord-settings.d.ts +0 -4
  992. package/dist/discord.d.ts +0 -10
  993. package/dist/discover.d.ts +0 -75
  994. package/dist/dispatch.d.ts +0 -123
  995. package/dist/dispose.d.ts +0 -194
  996. package/dist/doctor.d.ts +0 -67
  997. package/dist/easy-start-args.d.ts +0 -13
  998. package/dist/easy-start.d.ts +0 -77
  999. package/dist/egress.d.ts +0 -121
  1000. package/dist/email-settings.d.ts +0 -34
  1001. package/dist/envelope.d.ts +0 -47
  1002. package/dist/eval-gate.d.ts +0 -51
  1003. package/dist/eval-hooks.d.ts +0 -94
  1004. package/dist/eval-oracle-main.d.ts +0 -1
  1005. package/dist/eval-oracle.d.ts +0 -60
  1006. package/dist/eval-world.d.ts +0 -17
  1007. package/dist/evals.d.ts +0 -299
  1008. package/dist/evidence-pack.d.ts +0 -186
  1009. package/dist/evidence-pair.d.ts +0 -53
  1010. package/dist/evidence.d.ts +0 -371
  1011. package/dist/exec.d.ts +0 -355
  1012. package/dist/exhaustion.d.ts +0 -58
  1013. package/dist/export-ui.d.ts +0 -11
  1014. package/dist/export.d.ts +0 -48
  1015. package/dist/failing-first.d.ts +0 -31
  1016. package/dist/fallback-schema.d.ts +0 -8
  1017. package/dist/fallback.d.ts +0 -138
  1018. package/dist/fast-start.d.ts +0 -213
  1019. package/dist/fast-terms.d.ts +0 -9
  1020. package/dist/fenced-check-coverage.d.ts +0 -62
  1021. package/dist/findings.d.ts +0 -224
  1022. package/dist/first-run.d.ts +0 -197
  1023. package/dist/first-tasks-child.d.ts +0 -1
  1024. package/dist/flaky-ci.d.ts +0 -31
  1025. package/dist/flaky-cli.d.ts +0 -60
  1026. package/dist/flaky.d.ts +0 -83
  1027. package/dist/fleet-schema.d.ts +0 -17
  1028. package/dist/flow-actions.d.ts +0 -79
  1029. package/dist/flow-browser.d.ts +0 -103
  1030. package/dist/flow-cadence.d.ts +0 -48
  1031. package/dist/flow-card-task.d.ts +0 -11
  1032. package/dist/flow-changed.d.ts +0 -14
  1033. package/dist/flow-code.d.ts +0 -84
  1034. package/dist/flow-draft.d.ts +0 -42
  1035. package/dist/flow-engine.d.ts +0 -82
  1036. package/dist/flow-gallery-ui.d.ts +0 -73
  1037. package/dist/flow-gallery.d.ts +0 -147
  1038. package/dist/flow-insights.d.ts +0 -104
  1039. package/dist/flow-items.d.ts +0 -37
  1040. package/dist/flow-live.d.ts +0 -16
  1041. package/dist/flow-people.d.ts +0 -23
  1042. package/dist/flow-pull-request.d.ts +0 -14
  1043. package/dist/flow-replies.d.ts +0 -48
  1044. package/dist/flow-result-card.d.ts +0 -22
  1045. package/dist/flow-schedule.d.ts +0 -154
  1046. package/dist/flow-scripts.d.ts +0 -31
  1047. package/dist/flow-secrets.d.ts +0 -13
  1048. package/dist/flow-send.d.ts +0 -54
  1049. package/dist/flow-share.d.ts +0 -78
  1050. package/dist/flow-sort.d.ts +0 -63
  1051. package/dist/flow-starters-ui.d.ts +0 -15
  1052. package/dist/flow-starters.d.ts +0 -63
  1053. package/dist/flow-steps.d.ts +0 -52
  1054. package/dist/flow-triggers.d.ts +0 -303
  1055. package/dist/flow-unattended-words.d.ts +0 -48
  1056. package/dist/flow-unattended.d.ts +0 -259
  1057. package/dist/flows-cli.d.ts +0 -358
  1058. package/dist/flows-ui.d.ts +0 -70
  1059. package/dist/flows.d.ts +0 -136
  1060. package/dist/folder-gate.d.ts +0 -32
  1061. package/dist/folder-look.d.ts +0 -110
  1062. package/dist/follow-through-brief.d.ts +0 -12
  1063. package/dist/follow-through-cli.d.ts +0 -23
  1064. package/dist/fonts.d.ts +0 -19
  1065. package/dist/gaps.d.ts +0 -35
  1066. package/dist/gate-failure.d.ts +0 -40
  1067. package/dist/git-floor.d.ts +0 -16
  1068. package/dist/git-incident.d.ts +0 -65
  1069. package/dist/git-views.d.ts +0 -20
  1070. package/dist/git.d.ts +0 -54
  1071. package/dist/github-import.d.ts +0 -62
  1072. package/dist/github-jobs.d.ts +0 -25
  1073. package/dist/google-mail.d.ts +0 -59
  1074. package/dist/grant.d.ts +0 -136
  1075. package/dist/graph.d.ts +0 -164
  1076. package/dist/guides.d.ts +0 -22
  1077. package/dist/handover-note.d.ts +0 -33
  1078. package/dist/health-cli.d.ts +0 -3
  1079. package/dist/home-groups.d.ts +0 -39
  1080. package/dist/html.d.ts +0 -85
  1081. package/dist/install-method.d.ts +0 -17
  1082. package/dist/integrations-ui.d.ts +0 -17
  1083. package/dist/integrations.d.ts +0 -138
  1084. package/dist/invoke.d.ts +0 -228
  1085. package/dist/is-record.d.ts +0 -2
  1086. package/dist/issues.d.ts +0 -41
  1087. package/dist/jsonl-discriminants.d.ts +0 -11
  1088. package/dist/keymap.d.ts +0 -41
  1089. package/dist/keys.d.ts +0 -108
  1090. package/dist/kits-ui.d.ts +0 -16
  1091. package/dist/kits.d.ts +0 -88
  1092. package/dist/knowledge-cli.d.ts +0 -132
  1093. package/dist/knowledge-ui.d.ts +0 -45
  1094. package/dist/landed-cleanup.d.ts +0 -175
  1095. package/dist/laptop-background.d.ts +0 -187
  1096. package/dist/laptop-service.d.ts +0 -111
  1097. package/dist/latency-timeline.d.ts +0 -46
  1098. package/dist/lead-about.d.ts +0 -35
  1099. package/dist/lead-answer-eval.d.ts +0 -93
  1100. package/dist/lead-capabilities.d.ts +0 -57
  1101. package/dist/lead-cli-live.d.ts +0 -56
  1102. package/dist/lead-cli.d.ts +0 -58
  1103. package/dist/lead-commitments.d.ts +0 -84
  1104. package/dist/lead-context.d.ts +0 -45
  1105. package/dist/lead-contract.d.ts +0 -10
  1106. package/dist/lead-doors.d.ts +0 -122
  1107. package/dist/lead-follow.d.ts +0 -26
  1108. package/dist/lead-identity.d.ts +0 -23
  1109. package/dist/lead-latency-schema.d.ts +0 -24
  1110. package/dist/lead-people.d.ts +0 -55
  1111. package/dist/lead-progress.d.ts +0 -67
  1112. package/dist/lead-queue-runtime.d.ts +0 -46
  1113. package/dist/lead-queue.d.ts +0 -104
  1114. package/dist/lead-route.d.ts +0 -56
  1115. package/dist/lead-status.d.ts +0 -116
  1116. package/dist/lead-sweep.d.ts +0 -67
  1117. package/dist/lead-tools.d.ts +0 -167
  1118. package/dist/lead-voice.d.ts +0 -85
  1119. package/dist/lead.d.ts +0 -142
  1120. package/dist/learning-child.d.ts +0 -1
  1121. package/dist/learning-look.d.ts +0 -25
  1122. package/dist/ledger-chain.d.ts +0 -46
  1123. package/dist/ledger-csv.d.ts +0 -4
  1124. package/dist/ledger-view.d.ts +0 -27
  1125. package/dist/lesson-notes.d.ts +0 -81
  1126. package/dist/limits-ui.d.ts +0 -34
  1127. package/dist/link.d.ts +0 -72
  1128. package/dist/live-backup.d.ts +0 -39
  1129. package/dist/live-bus.d.ts +0 -141
  1130. package/dist/live-children-read.d.ts +0 -52
  1131. package/dist/live-children.d.ts +0 -73
  1132. package/dist/live-detail.d.ts +0 -27
  1133. package/dist/live-input.d.ts +0 -68
  1134. package/dist/live-main-read.d.ts +0 -19
  1135. package/dist/live-notes.d.ts +0 -20
  1136. package/dist/live-open.d.ts +0 -28
  1137. package/dist/live-records.d.ts +0 -149
  1138. package/dist/live-reply.d.ts +0 -83
  1139. package/dist/live-terminal.d.ts +0 -273
  1140. package/dist/live.d.ts +0 -152
  1141. package/dist/local-owner.d.ts +0 -124
  1142. package/dist/log.d.ts +0 -7
  1143. package/dist/login-secrets.d.ts +0 -60
  1144. package/dist/machine-check.d.ts +0 -16
  1145. package/dist/machine-identity.d.ts +0 -75
  1146. package/dist/mailbox.d.ts +0 -57
  1147. package/dist/maintenance.d.ts +0 -13
  1148. package/dist/mcp-connect.d.ts +0 -181
  1149. package/dist/mcp-core.d.ts +0 -110
  1150. package/dist/mcp-http.d.ts +0 -32
  1151. package/dist/mcp-oauth.d.ts +0 -92
  1152. package/dist/mcp-person.d.ts +0 -22
  1153. package/dist/mcp.d.ts +0 -20
  1154. package/dist/memory-cli.d.ts +0 -768
  1155. package/dist/memory-pass.d.ts +0 -151
  1156. package/dist/memory-tidy.d.ts +0 -181
  1157. package/dist/memory-use.d.ts +0 -35
  1158. package/dist/merge-checklist.d.ts +0 -55
  1159. package/dist/metrics.d.ts +0 -6
  1160. package/dist/mobile-viewport.d.ts +0 -7
  1161. package/dist/model-catalog.d.ts +0 -123
  1162. package/dist/model-choices.d.ts +0 -235
  1163. package/dist/model-names.d.ts +0 -6
  1164. package/dist/models-cli.d.ts +0 -307
  1165. package/dist/models-ui.d.ts +0 -161
  1166. package/dist/modes.d.ts +0 -99
  1167. package/dist/monitoring-settings.d.ts +0 -44
  1168. package/dist/monitoring-ui.d.ts +0 -23
  1169. package/dist/monitoring.d.ts +0 -34
  1170. package/dist/names.d.ts +0 -67
  1171. package/dist/needs-you.d.ts +0 -164
  1172. package/dist/never-index.d.ts +0 -3
  1173. package/dist/nightly-check.d.ts +0 -107
  1174. package/dist/nightly-github.d.ts +0 -318
  1175. package/dist/notification-delivery.d.ts +0 -19
  1176. package/dist/notification-rows.d.ts +0 -30
  1177. package/dist/oauth-run-token.d.ts +0 -51
  1178. package/dist/observations.d.ts +0 -36
  1179. package/dist/oidc.d.ts +0 -71
  1180. package/dist/onboard.d.ts +0 -108
  1181. package/dist/one-step-chat-schema.d.ts +0 -22
  1182. package/dist/openrouter-models.d.ts +0 -34
  1183. package/dist/operate-remote-arguments.d.ts +0 -36
  1184. package/dist/operate-remote.d.ts +0 -98
  1185. package/dist/operate.d.ts +0 -401
  1186. package/dist/orphan-sweep.d.ts +0 -65
  1187. package/dist/page-work-contract.d.ts +0 -21
  1188. package/dist/password-bearer.d.ts +0 -25
  1189. package/dist/passwordless.d.ts +0 -23
  1190. package/dist/peek-cli.d.ts +0 -112
  1191. package/dist/peek.d.ts +0 -110
  1192. package/dist/people-audit-ui.d.ts +0 -16
  1193. package/dist/person-proof.d.ts +0 -2
  1194. package/dist/phase-routing.d.ts +0 -401
  1195. package/dist/plain-schema.d.ts +0 -23
  1196. package/dist/plain-words.d.ts +0 -20
  1197. package/dist/plan-auto.d.ts +0 -25
  1198. package/dist/plan-login.d.ts +0 -14
  1199. package/dist/plan.d.ts +0 -188
  1200. package/dist/plane-review.d.ts +0 -54
  1201. package/dist/planner-source.d.ts +0 -225
  1202. package/dist/planner.d.ts +0 -76
  1203. package/dist/policy-ui.d.ts +0 -22
  1204. package/dist/policy.d.ts +0 -92
  1205. package/dist/prepared-evidence.d.ts +0 -17
  1206. package/dist/principal.d.ts +0 -42
  1207. package/dist/probe.d.ts +0 -46
  1208. package/dist/process-custody.d.ts +0 -17
  1209. package/dist/process-liveness.d.ts +0 -13
  1210. package/dist/process-tree.d.ts +0 -39
  1211. package/dist/project-access.d.ts +0 -17
  1212. package/dist/project-activity.d.ts +0 -20
  1213. package/dist/project-admission.d.ts +0 -105
  1214. package/dist/project-cli.d.ts +0 -19
  1215. package/dist/project-concurrency.d.ts +0 -62
  1216. package/dist/project-delete-ui.d.ts +0 -96
  1217. package/dist/project-delete.d.ts +0 -59
  1218. package/dist/project-demo.d.ts +0 -12
  1219. package/dist/project-file.d.ts +0 -3
  1220. package/dist/project-identity.d.ts +0 -52
  1221. package/dist/project-knowledge.d.ts +0 -124
  1222. package/dist/project-learning.d.ts +0 -120
  1223. package/dist/project-memory.d.ts +0 -70
  1224. package/dist/project-outcomes.d.ts +0 -119
  1225. package/dist/project-sandbox.d.ts +0 -59
  1226. package/dist/project-skills.d.ts +0 -139
  1227. package/dist/project-tools.d.ts +0 -318
  1228. package/dist/project.d.ts +0 -65
  1229. package/dist/prompt.d.ts +0 -33
  1230. package/dist/proof.d.ts +0 -457
  1231. package/dist/proposal.d.ts +0 -70
  1232. package/dist/protected-storage-look.d.ts +0 -1
  1233. package/dist/protected-storage.d.ts +0 -98
  1234. package/dist/provider-auth.d.ts +0 -143
  1235. package/dist/provider-capture.d.ts +0 -34
  1236. package/dist/provider-connection.d.ts +0 -23
  1237. package/dist/provider-home.d.ts +0 -22
  1238. package/dist/provider-limits.d.ts +0 -37
  1239. package/dist/provider.d.ts +0 -369
  1240. package/dist/public-access.d.ts +0 -52
  1241. package/dist/public-check.d.ts +0 -37
  1242. package/dist/publish.d.ts +0 -146
  1243. package/dist/pull-request-flow.d.ts +0 -189
  1244. package/dist/pull-request-schema.d.ts +0 -5
  1245. package/dist/pull-request-ui.d.ts +0 -25
  1246. package/dist/pulls.d.ts +0 -121
  1247. package/dist/push.d.ts +0 -120
  1248. package/dist/quality.d.ts +0 -8
  1249. package/dist/quick-start.d.ts +0 -26
  1250. package/dist/read-executor-worker.d.ts +0 -1
  1251. package/dist/read-executor.d.ts +0 -66
  1252. package/dist/read-only-request.d.ts +0 -4
  1253. package/dist/recipe-ui.d.ts +0 -21
  1254. package/dist/recipes.d.ts +0 -56
  1255. package/dist/release-adapters.d.ts +0 -205
  1256. package/dist/release-approval.d.ts +0 -180
  1257. package/dist/release-authority.d.ts +0 -173
  1258. package/dist/release-auto.d.ts +0 -184
  1259. package/dist/release-card.d.ts +0 -156
  1260. package/dist/release-carry.d.ts +0 -261
  1261. package/dist/release-ci-hold.d.ts +0 -41
  1262. package/dist/release-cli.d.ts +0 -34
  1263. package/dist/release-coverage.d.ts +0 -16
  1264. package/dist/release-gate.d.ts +0 -84
  1265. package/dist/release-git.d.ts +0 -43
  1266. package/dist/release-links.d.ts +0 -29
  1267. package/dist/release-net.d.ts +0 -90
  1268. package/dist/release-next.d.ts +0 -48
  1269. package/dist/release-recheck.d.ts +0 -146
  1270. package/dist/release-refusal.d.ts +0 -32
  1271. package/dist/release-view.d.ts +0 -37
  1272. package/dist/release.d.ts +0 -806
  1273. package/dist/releases.d.ts +0 -94
  1274. package/dist/remote-audit.d.ts +0 -79
  1275. package/dist/remote-command.d.ts +0 -45
  1276. package/dist/remote-destination.d.ts +0 -36
  1277. package/dist/remote-exec.d.ts +0 -38
  1278. package/dist/remote-main.d.ts +0 -111
  1279. package/dist/remote-run.d.ts +0 -20
  1280. package/dist/remote.d.ts +0 -67
  1281. package/dist/render.d.ts +0 -64
  1282. package/dist/reply-shape.d.ts +0 -106
  1283. package/dist/reply-voice.d.ts +0 -23
  1284. package/dist/report-summary.d.ts +0 -22
  1285. package/dist/reported-usage.d.ts +0 -69
  1286. package/dist/repos.d.ts +0 -67
  1287. package/dist/repository-context-ui.d.ts +0 -3
  1288. package/dist/repository-context.d.ts +0 -66
  1289. package/dist/request-budget-ui.d.ts +0 -14
  1290. package/dist/request-budget.d.ts +0 -127
  1291. package/dist/restart-certification.d.ts +0 -133
  1292. package/dist/result-actions.d.ts +0 -36
  1293. package/dist/result-acts.d.ts +0 -112
  1294. package/dist/result-completion.d.ts +0 -35
  1295. package/dist/result-evidence-readers.d.ts +0 -42
  1296. package/dist/result-follow-ups.d.ts +0 -118
  1297. package/dist/result-review.d.ts +0 -220
  1298. package/dist/result-shots.d.ts +0 -59
  1299. package/dist/retention-ui.d.ts +0 -21
  1300. package/dist/retention.d.ts +0 -77
  1301. package/dist/review-context.d.ts +0 -245
  1302. package/dist/review-evidence.d.ts +0 -33
  1303. package/dist/review-switch.d.ts +0 -36
  1304. package/dist/reviewer.d.ts +0 -99
  1305. package/dist/route-change-check.d.ts +0 -4
  1306. package/dist/route-change.d.ts +0 -22
  1307. package/dist/route-hooks.d.ts +0 -54
  1308. package/dist/route-results.d.ts +0 -75
  1309. package/dist/route-rules.d.ts +0 -324
  1310. package/dist/route-savings.d.ts +0 -136
  1311. package/dist/route-store.d.ts +0 -300
  1312. package/dist/run-closeout.d.ts +0 -89
  1313. package/dist/run-efficiency.d.ts +0 -74
  1314. package/dist/run-ending.d.ts +0 -21
  1315. package/dist/runner-process.d.ts +0 -76
  1316. package/dist/runner.d.ts +0 -324
  1317. package/dist/sample-project.d.ts +0 -31
  1318. package/dist/sandbox-launch.d.ts +0 -1
  1319. package/dist/sandbox-runtime.d.ts +0 -128
  1320. package/dist/scan.d.ts +0 -32
  1321. package/dist/scope.d.ts +0 -1067
  1322. package/dist/scout-browser-lock.d.ts +0 -69
  1323. package/dist/scout-browser.d.ts +0 -107
  1324. package/dist/scout-net.d.ts +0 -25
  1325. package/dist/scout-report.d.ts +0 -23
  1326. package/dist/scout.d.ts +0 -142
  1327. package/dist/secret-mint.d.ts +0 -1
  1328. package/dist/serve.d.ts +0 -11
  1329. package/dist/server/agents-computers.d.ts +0 -9
  1330. package/dist/server/agents-live-filed.d.ts +0 -17
  1331. package/dist/server/agents-live-lead.d.ts +0 -47
  1332. package/dist/server/agents-live-room.d.ts +0 -23
  1333. package/dist/server/chat.d.ts +0 -39
  1334. package/dist/server/chrome.d.ts +0 -328
  1335. package/dist/server/edge-refusal.d.ts +0 -7
  1336. package/dist/server/flows.d.ts +0 -8
  1337. package/dist/server/guards.d.ts +0 -80
  1338. package/dist/server/handler-context.d.ts +0 -22
  1339. package/dist/server/handler-registry.d.ts +0 -23
  1340. package/dist/server/home-asks.d.ts +0 -45
  1341. package/dist/server/home.d.ts +0 -65
  1342. package/dist/server/http.d.ts +0 -337
  1343. package/dist/server/in-place.d.ts +0 -15
  1344. package/dist/server/kit-standalone.d.ts +0 -22
  1345. package/dist/server/kit.d.ts +0 -452
  1346. package/dist/server/last-checks.d.ts +0 -17
  1347. package/dist/server/live.d.ts +0 -74
  1348. package/dist/server/merge-ready-view.d.ts +0 -10
  1349. package/dist/server/mutation-key.d.ts +0 -70
  1350. package/dist/server/pages-assets.d.ts +0 -11
  1351. package/dist/server/pages.d.ts +0 -8
  1352. package/dist/server/people-tokens.d.ts +0 -18
  1353. package/dist/server/remote-hooks.d.ts +0 -29
  1354. package/dist/server/remote.d.ts +0 -59
  1355. package/dist/server/render-chat.d.ts +0 -439
  1356. package/dist/server/render-code-map.d.ts +0 -30
  1357. package/dist/server/render-flaky.d.ts +0 -20
  1358. package/dist/server/render-follow-through.d.ts +0 -11
  1359. package/dist/server/render-history.d.ts +0 -51
  1360. package/dist/server/render-new-task.d.ts +0 -54
  1361. package/dist/server/render-pages.d.ts +0 -236
  1362. package/dist/server/render-people.d.ts +0 -102
  1363. package/dist/server/render-projects.d.ts +0 -104
  1364. package/dist/server/render-release.d.ts +0 -19
  1365. package/dist/server/render-results.d.ts +0 -754
  1366. package/dist/server/render-settings.d.ts +0 -93
  1367. package/dist/server/render-tasks.d.ts +0 -774
  1368. package/dist/server/request-context.d.ts +0 -78
  1369. package/dist/server/retired-routes.d.ts +0 -17
  1370. package/dist/server/route-policy.d.ts +0 -18
  1371. package/dist/server/route-table.d.ts +0 -114
  1372. package/dist/server/runtime.d.ts +0 -342
  1373. package/dist/server/session.d.ts +0 -192
  1374. package/dist/server/settings.d.ts +0 -76
  1375. package/dist/server/signup-gate.d.ts +0 -9
  1376. package/dist/server/sweeps.d.ts +0 -4
  1377. package/dist/server/task-views.d.ts +0 -98
  1378. package/dist/server/tasks.d.ts +0 -83
  1379. package/dist/server/terminals.d.ts +0 -31
  1380. package/dist/server/welcome.d.ts +0 -28
  1381. package/dist/server-telemetry.d.ts +0 -87
  1382. package/dist/settings-groups-ui.d.ts +0 -286
  1383. package/dist/settings-kit-script.d.ts +0 -21
  1384. package/dist/settings-kit.d.ts +0 -173
  1385. package/dist/settings-proofs.d.ts +0 -64
  1386. package/dist/setup-guide.d.ts +0 -39
  1387. package/dist/shared-deps.d.ts +0 -115
  1388. package/dist/sign-in-guard.d.ts +0 -70
  1389. package/dist/skills-ui.d.ts +0 -12
  1390. package/dist/skills.d.ts +0 -99
  1391. package/dist/slack-api.d.ts +0 -59
  1392. package/dist/slack-chat.d.ts +0 -37
  1393. package/dist/slack-settings.d.ts +0 -4
  1394. package/dist/slack-socket.d.ts +0 -12
  1395. package/dist/slack.d.ts +0 -6
  1396. package/dist/sleep.d.ts +0 -2
  1397. package/dist/source-key.d.ts +0 -2
  1398. package/dist/spend-report.d.ts +0 -87
  1399. package/dist/spend-ui.d.ts +0 -80
  1400. package/dist/spend.d.ts +0 -142
  1401. package/dist/sqlite-runtime.d.ts +0 -3
  1402. package/dist/sqlite-telemetry.d.ts +0 -9
  1403. package/dist/sso-settings.d.ts +0 -33
  1404. package/dist/sso-ui.d.ts +0 -26
  1405. package/dist/staged-runtimes.d.ts +0 -54
  1406. package/dist/steer-capabilities.d.ts +0 -32
  1407. package/dist/steer-controls.d.ts +0 -14
  1408. package/dist/steer-live.d.ts +0 -19
  1409. package/dist/steer-mailbox.d.ts +0 -46
  1410. package/dist/steer-status.d.ts +0 -25
  1411. package/dist/stop-proof.d.ts +0 -67
  1412. package/dist/storage-sweep-child.d.ts +0 -1
  1413. package/dist/storage-sweep-process.d.ts +0 -55
  1414. package/dist/storage-sweep-schedule.d.ts +0 -30
  1415. package/dist/storage-sweep.d.ts +0 -77
  1416. package/dist/storage-ui.d.ts +0 -23
  1417. package/dist/storage.d.ts +0 -68
  1418. package/dist/store-baseline.d.ts +0 -19
  1419. package/dist/store.d.ts +0 -8613
  1420. package/dist/stream-scope.d.ts +0 -18
  1421. package/dist/structured-output.d.ts +0 -57
  1422. package/dist/style-asset.d.ts +0 -7
  1423. package/dist/subagent-admin.d.ts +0 -53
  1424. package/dist/subagent-desk.d.ts +0 -59
  1425. package/dist/subagent-memory.d.ts +0 -65
  1426. package/dist/subagent-question.d.ts +0 -59
  1427. package/dist/subagent-tools.d.ts +0 -125
  1428. package/dist/subagent-week.d.ts +0 -68
  1429. package/dist/subagent-work.d.ts +0 -76
  1430. package/dist/subagents-ui.d.ts +0 -22
  1431. package/dist/subagents.d.ts +0 -146
  1432. package/dist/subscription-chat.d.ts +0 -54
  1433. package/dist/summary.d.ts +0 -33
  1434. package/dist/surface.d.ts +0 -49
  1435. package/dist/sweep-gate.d.ts +0 -10
  1436. package/dist/sweep-quarantine.d.ts +0 -29
  1437. package/dist/sync.d.ts +0 -94
  1438. package/dist/tailnet.d.ts +0 -11
  1439. package/dist/tamper-scan.d.ts +0 -4
  1440. package/dist/task-activity.d.ts +0 -27
  1441. package/dist/task-aliases.d.ts +0 -5
  1442. package/dist/task-archive.d.ts +0 -13
  1443. package/dist/task-base.d.ts +0 -39
  1444. package/dist/task-composer.d.ts +0 -14
  1445. package/dist/task-control.d.ts +0 -159
  1446. package/dist/task-live.d.ts +0 -8
  1447. package/dist/task-moves.d.ts +0 -90
  1448. package/dist/task-outcome-cli.d.ts +0 -30
  1449. package/dist/task-review-brief.d.ts +0 -69
  1450. package/dist/task-sizing.d.ts +0 -58
  1451. package/dist/task-source.d.ts +0 -77
  1452. package/dist/task-status.d.ts +0 -324
  1453. package/dist/task-text.d.ts +0 -31
  1454. package/dist/team-chat-authorization.d.ts +0 -11
  1455. package/dist/team-contract.d.ts +0 -103
  1456. package/dist/team-http.d.ts +0 -25
  1457. package/dist/team-leads.d.ts +0 -85
  1458. package/dist/team-runtime.d.ts +0 -25
  1459. package/dist/team-ui.d.ts +0 -4
  1460. package/dist/team-updates.d.ts +0 -8
  1461. package/dist/teams-api.d.ts +0 -33
  1462. package/dist/teams-chat.d.ts +0 -36
  1463. package/dist/teams-settings.d.ts +0 -14
  1464. package/dist/teams.d.ts +0 -24
  1465. package/dist/teardown-git.d.ts +0 -164
  1466. package/dist/telegram-flow.d.ts +0 -112
  1467. package/dist/telegram-lead.d.ts +0 -151
  1468. package/dist/telegram-live.d.ts +0 -116
  1469. package/dist/telegram-progress.d.ts +0 -20
  1470. package/dist/telegram-settings.d.ts +0 -9
  1471. package/dist/telegram-status.d.ts +0 -83
  1472. package/dist/telegram-team.d.ts +0 -68
  1473. package/dist/telegram.d.ts +0 -271
  1474. package/dist/templates.d.ts +0 -69
  1475. package/dist/terminal-catalog.d.ts +0 -11
  1476. package/dist/terminal-text.d.ts +0 -11
  1477. package/dist/test-infra.d.ts +0 -34
  1478. package/dist/test-temp.d.ts +0 -40
  1479. package/dist/text-limits.d.ts +0 -297
  1480. package/dist/tidy.d.ts +0 -130
  1481. package/dist/tier-report.d.ts +0 -44
  1482. package/dist/token-notices.d.ts +0 -11
  1483. package/dist/tokens-cli.d.ts +0 -21
  1484. package/dist/tool-broker.d.ts +0 -52
  1485. package/dist/tool-launcher.d.ts +0 -1
  1486. package/dist/tool-secret-store.d.ts +0 -167
  1487. package/dist/toolroll-update-cli.d.ts +0 -15
  1488. package/dist/toolroll-update-ui.d.ts +0 -47
  1489. package/dist/toolroll-update.d.ts +0 -265
  1490. package/dist/tools-ui.d.ts +0 -51
  1491. package/dist/transitions-recipes.d.ts +0 -1
  1492. package/dist/tree-proof.d.ts +0 -34
  1493. package/dist/tui-contract.d.ts +0 -144
  1494. package/dist/tui-source.d.ts +0 -14
  1495. package/dist/typed-start.d.ts +0 -51
  1496. package/dist/unfenced-test-support.d.ts +0 -2
  1497. package/dist/up-processes.d.ts +0 -162
  1498. package/dist/up-role-child.d.ts +0 -1
  1499. package/dist/update-notice.d.ts +0 -5
  1500. package/dist/vanished-retry.d.ts +0 -30
  1501. package/dist/verification-evidence.d.ts +0 -68
  1502. package/dist/version.d.ts +0 -2
  1503. package/dist/wake-hub.d.ts +0 -72
  1504. package/dist/webhook-limits.d.ts +0 -23
  1505. package/dist/webhook-readers.d.ts +0 -56
  1506. package/dist/webhook-signing.d.ts +0 -27
  1507. package/dist/webhooks.d.ts +0 -84
  1508. package/dist/welcome-facts.d.ts +0 -18
  1509. package/dist/when-html.d.ts +0 -40
  1510. package/dist/work-index.d.ts +0 -175
  1511. package/dist/work-summary.d.ts +0 -61
  1512. package/dist/workspace-motion.d.ts +0 -4
  1513. package/dist/workspace-revision.d.ts +0 -48
  1514. package/dist/workspace-ui.d.ts +0 -385
  1515. package/dist/worktree-notices.d.ts +0 -13
  1516. package/dist/worktree.d.ts +0 -365
  1517. package/dist/writes-mode.d.ts +0 -9
  1518. package/dist/youiyoux-intake.d.ts +0 -234
@@ -1,3 +1,4 @@
1
+ import { advancedShownNow } from "../advanced-view.js";
1
2
  import { titleWithin } from "../task-text.js";
2
3
  import { parseFeedbackImage, sameFeedbackImage } from "../result-review.js";
3
4
  import { archiveTaskFamily, dropFeedbackImage, releaseAuthorityOfTask, restoreTaskFamily, revokeRelease, runCheckStamp, runLiveCommands } from "../store.js";
@@ -5,7 +6,6 @@ import { ranWords } from "../check-stamp.js";
5
6
  import { applyTidy, approverStandsNow, familyRepoOf, releaseFactsOf, tidyDays, tidyDigest, tidyPreview, TIDY_DEFAULT_DAYS } from "../tidy.js";
6
7
  import { steerCapabilityOf } from "../steer-capabilities.js";
7
8
  import { canReveal, localCheckoutOf, revealInFinder } from "../checkout-proof.js";
8
- /** A form's way back to a flow card ("flow:<flow>:<card>"), read strictly: numbers only, never a path. */
9
9
  function returnedFlow(value) {
10
10
  const match = /^flow:([1-9][0-9]{0,9}):([1-9][0-9]{0,9})$/.exec(value ?? "");
11
11
  return match === null ? null : { flow: Number(match[1]), card: Number(match[2]) };
@@ -15,7 +15,6 @@ import { ACP_AGENTS, isAcpProvider } from "../acp-agents.js";
15
15
  import { handlersOf } from './handler-registry.js';
16
16
  import { closedQuestionWords, LIMITS } from "../decision.js";
17
17
  import { DEPRECATED_PAGE } from "../deprecations.js";
18
- /** tasks handlers, moved without changing their route bodies. */
19
18
  import { html, htmlString, joinHtml, postForm, textHtml } from "../html.js";
20
19
  import { createHash, randomBytes, randomUUID } from "node:crypto";
21
20
  import { existsSync, lstatSync, realpathSync } from "node:fs";
@@ -30,6 +29,7 @@ import { codingShippingHtml } from '../coding-shipping-ui.js';
30
29
  import { codingWorkspaceHtml, codingWorkspaceScript } from '../coding-ui.js';
31
30
  import { CodingActionError } from '../coding-workspace.js';
32
31
  import { checkResponse, CONSOLE_FORMS, readForm } from "../contracts/console-api.js";
32
+ import { LOCAL_TASK_CHANGED, requestPlanAsLocalOwner, retryAsLocalOwner, retryPinsOf } from "../local-owner-acts.js";
33
33
  import { hasForbiddenControls, validateNote } from "../decision.js";
34
34
  import { builderReadyFor, diagnoseTaskDispatch, firstRunBuilderRepo } from "../dispatch.js";
35
35
  import { firstTaskSuggestions, withBuilderStep } from "../first-run.js";
@@ -93,12 +93,9 @@ import { approvalFactsNow } from "./kit.js";
93
93
  import { localOwnerRefusal } from "../local-owner.js";
94
94
  export function createTasksHandlers(runtime) {
95
95
  const { identities, store, peekSay, peekCache, PEEK_CACHE_TTL_MS, peekInFlight, PEEK_GLOBAL_INFLIGHT, peekBySession, PEEK_SESSION_INFLIGHT, clock, peekName, PEEK_FRAGMENT_BYTES, peekEvict, evidenceRoot, sendScreen, chromeFor, visible, consumeApprovalNonce, authenticateApprover, options, mintApprovalNonce, taskScreen, unscopedMode, admissionList, planViewOf, revisionViewOf, runIsTaskResult, leadPrincipal, familyOf, armTaskResume, runIsLive, revisionLedgerOf, resultDetailOf, reviewFactsFor, taskRepoOf, runVisible, restricted, codingActorAllowed, codingProjectAllowed, managedRepos, routeViewOf, workAccess, firstRunStepsNow, revisionDocOf, failureOf, dockedConversation, planContractViewOf, familiesInView, explainAttempt, taskChatFocus, familyTasksInView, liveCeiling, projectOf, ceiling, bustBadge, revisionDestination } = runtime;
96
- /** A row admitted the address but its path parameter does not parse: the console's unknown page. */
97
96
  function noPage(who, response) {
98
97
  return refuse(response, who, 404, "There's no page at this address.", "/chat");
99
98
  }
100
- // `posted`: the session page's own POST (form token). A GET of changes or the shipping preview runs no git in the
101
- // agent's checkout: changes go back to the session page, the preview asks for one click.
102
99
  const showCode = (part, posted = false) => async (ctx) => {
103
100
  const { url, who, response, project } = ctx;
104
101
  if (who.via !== 'cookie' || !codingActorAllowed({ name: who.name, generation: who.session.generation }))
@@ -154,14 +151,7 @@ export function createTasksHandlers(runtime) {
154
151
  };
155
152
  async function showWork(ctx) {
156
153
  const { url, who, response, now, project } = ctx;
157
- // The Work destination (workspace package 1): every task in view as
158
- // one row wearing the shared status projection, with All, Needs you,
159
- // Running, and Completed as shortcuts over the same rows — never a
160
- // persisted state. With no project open in scoped mode this rolls
161
- // up like the inbox: admission binds the query and every row's repo
162
- // is re-proved here.
163
154
  const view = parseWorkView(url.searchParams.get("view"));
164
- // The stored-state filter the old task list had (`?state=`): an unknown state is refused, as it was there.
165
155
  const wantedState = url.searchParams.get("state");
166
156
  if (wantedState !== null && !TASK_STATES.includes(wantedState))
167
157
  return refuse(response, who, 400, "no such state", "/tasks");
@@ -171,10 +161,7 @@ export function createTasksHandlers(runtime) {
171
161
  try {
172
162
  work = workIndexPage(store, now, workAccess(), { view, limit: 40, cursor: url.searchParams.get('cursor'), project, root: evidenceRoot, ...(state === null ? {} : { state }) });
173
163
  const facts = requestContext.getStore();
174
- // A filtered page never stands in for the counts or the Crew: those read the unfiltered work.
175
164
  if (facts !== undefined && state === null) {
176
- // These counts cover the exact admitted project lens, including
177
- // unplaced tasks where permitted. Crew excludes unplaced rows.
178
165
  if (project === null)
179
166
  facts.workCounts = work.projects;
180
167
  const admitted = workAccess().repos;
@@ -188,10 +175,6 @@ export function createTasksHandlers(runtime) {
188
175
  return refuse(response, who, 400, 'This task page has expired. Open the first page.', '/tasks');
189
176
  throw error;
190
177
  }
191
- // A failed row says what its latest attempt missed, as its task page does (a stop reason already reads so), from
192
- // the database alone: a row reads no check log. A live build's row says which step it is on, or the step it is
193
- // stuck on, from that live attempt's own progress only, never a stopped attempt's; the step's words come from its
194
- // current plan (one saved file, for live rows only), and without it the row names the step by number.
195
178
  const enrich = (page) => ({ ...page, items: page.items.map((item) => {
196
179
  if (item.liveRunId !== null) {
197
180
  const ref = store.lookupRef(item.activeTaskId);
@@ -213,7 +196,6 @@ export function createTasksHandlers(runtime) {
213
196
  return failure.kind === "reason" ? item : { ...item, status: { ...item.status, detail: failure.line } };
214
197
  }) });
215
198
  work = enrich(work);
216
- // The Board view: the same index as four columns (needs you, queued, running, finished), never a second classifier.
217
199
  const board = url.searchParams.get("layout") !== "board" ? null : (() => {
218
200
  const column = (view) => enrich(workIndexPage(store, now, workAccess(), { view, limit: BOARD_COLUMN_LIMIT, project, root: evidenceRoot, ...(state === null ? {} : { state }) }));
219
201
  return { needs: column("needs-you"), queued: column("queued"), running: column("running"), finished: column("completed") };
@@ -230,69 +212,50 @@ export function createTasksHandlers(runtime) {
230
212
  now,
231
213
  state,
232
214
  canPutAway: who.via === "cookie" && who.role === "approver",
233
- // v105: subscription windows and monthly budgets, for whoever runs the installation.
234
- limits: store.isInstanceOperator(who.name)
215
+ limits: store.isInstanceOperator(who.name) && advancedShownNow()
235
216
  ? limitsView(store.providerLimits(), store.budgets().length === 0 ? [] : store.monthSpendCached(now).budgets, { project: projectName, subagent: id => subagentNamesOf(store.handle).get(id) ?? `Subagent ${id}` }, now)
236
217
  : null,
237
218
  });
238
- // One project's Tasks dock that project's own conversation (v77).
239
219
  const projectThread = url.searchParams.has('project') && project !== null && managedRepos().includes(project) ? project : null;
240
220
  const docked = projectThread === null ? null : dockedConversation(who, null, projectThread, now, `/tasks?project=${encodeURIComponent(projectThread)}`);
241
221
  if (docked !== null)
242
222
  page.workspace = { ...page.workspace, conversation: docked, pageHtml: page.body };
243
- // Without a docked chat the list reads itself: 10 s while any of its tasks is building, else 30 s.
244
223
  page.refreshSeconds = work.totals.running > 0 ? 10 : 30;
245
224
  return sendScreen(response, 200, page);
246
225
  }
247
- /** A completed (or attempted) row as the review list ranks it: its proof reasons, CI standing, and the assignment
248
- * when that assignment's receipt is this very row. */
249
226
  function reviewRowOf(row, now) {
250
227
  const assignment = assignmentOf(store, row.taskId, now, workAccess(), evidenceRoot);
251
228
  return { ...row, proofReasons: row.runId === null ? [] : store.proofVerdictFor(row.runId)?.reasons ?? [], ciFailing: ciFailingFor(row.runId, row.prNumber),
252
229
  assignment: assignment?.activeTaskId === row.taskId && (assignment.receipt?.runId ?? null) === row.runId ? assignment : null };
253
230
  }
254
- /** The result a link names (the task's own result, or the exact run `namedRun` of it): its completed row when the
255
- * task is done (`inQueue` when the review list already holds it), else that attempt's own result (a failed or stopped
256
- * build has a result page too), with what went wrong and Retry / Accept anyway as the review page offers them.
257
- * Shared by /review and the task page's Result tab (docs/plans/one-page-task-and-agent.md). */
258
231
  function selectResultFor(wantedId, namedRun, project, who, now, inQueue = null) {
259
232
  const csrf = who.via === "cookie" ? who.session.csrf : "";
260
233
  const beyond = inQueue !== null ? null : completedRowFor(wantedId, project);
261
234
  const beyondRow = beyond === null ? null : reviewRowOf(beyond, now);
262
235
  const completedChoice = inQueue ?? (beyondRow === null ? null : { ...beyondRow, priority: reviewPriorityOf(beyondRow) });
263
- // A build that failed (or stopped) has its own result page too: the run named, or a failed task's latest attempt.
264
236
  const attempt = (completedChoice !== null && (namedRun === null || completedChoice.runId === namedRun)) ? null : attemptRowFor(wantedId, namedRun, project);
265
237
  const attemptRow = attempt === null ? null : reviewRowOf(attempt, now);
266
238
  const chosen = attemptRow !== null ? { ...attemptRow, priority: reviewPriorityOf(attemptRow) } : completedChoice;
267
239
  const selected = chosen === null ? null : reviewCockpitViewOf(chosen, who, now);
268
- // A build that delivered nothing reads Failed here, and so does a failed task's delivered result: what went wrong
269
- // is the card and Retry the ink act. That result may still be accepted, but only in outline, as Accept anyway, with
270
- // a reason.
271
240
  const delivered = selected?.run?.outcome === "built" || selected?.run?.outcome === "no-change";
272
241
  const failedTask = selected === null ? null : store.getTask(selected.taskId);
273
242
  if (selected !== null && attemptRow !== null && selected.run !== null && (!delivered || failedTask?.state === "failed")) {
274
243
  const attemptRun = store.getRun(selected.run.id);
275
244
  const runs = attemptRun === null ? [] : store.runsFor(attemptRun.taskRef);
276
245
  const latest = latestFinishedAttempt(runs);
277
- // Retry from here only when the task failed, nothing holds it, and this is its latest attempt or a result it delivered.
278
246
  const retry = failedTask?.state === "failed" && (latest?.id === selected.run.id || delivered) && csrf !== "" && who.role === "approver" && store.currentLiveLease(attemptRun.taskRef, now) === null
279
- ? { action: `${taskHref(selected.taskId)}/requeue` } : null;
280
- // Accept anyway: the same acceptance this task's latest result takes, never for an older one or one already accepted.
247
+ ? { action: `${taskHref(selected.taskId)}/requeue`, pins: retryPinsOf(store, selected.taskId) } : null;
281
248
  const family = delivered ? familyOf(selected.taskId) : null;
282
249
  const acceptAnyway = delivered && csrf !== "" && who.role === "approver" && family?.current.id === selected.taskId && family.problem === null &&
283
250
  runs.find(runIsTaskResult)?.id === selected.run.id && store.proofAcceptance(selected.run.id) === null
284
251
  ? { action: `${taskHref(selected.taskId)}/accept-proof`, run: selected.run.id } : null;
285
252
  if (attemptRun !== null) {
286
- // A delivered result didn't fail itself: the task's failure is its latest attempt's.
287
253
  const failure = delivered ? failureOf(runs, null) : explainAttempt(attemptRun, null);
288
254
  selected.failure = { ...failure, retry: retry === null ? null : { ...retry, note: retryNoteOf(failure.suggestion) }, ...(acceptAnyway === null ? {} : { acceptAnyway }) };
289
255
  }
290
256
  }
291
257
  return { chosen, attemptRow, beyond, selected };
292
258
  }
293
- /** Whether `run` is a result selectResultFor shows for version `taskId`: a finished attempt that didn't deliver (failed,
294
- * stopped, refused…), or the delivered one that is the version's own result — its completed row's, or, for a failed
295
- * version, its latest finished attempt. An older delivered build is not (its version's result is the newer one). */
296
259
  function resultRunAdmissible(taskId, run, project) {
297
260
  if ((run.role !== "builder" && run.role !== "scout") || (run.finishedAt === null && run.outcome === null) || runIsLive(run))
298
261
  return false;
@@ -303,21 +266,12 @@ export function createTasksHandlers(runtime) {
303
266
  return latestFinishedAttempt(store.runsFor(run.taskRef).filter(one => (one.role === "builder" || one.role === "scout") && (one.finishedAt !== null || one.outcome !== null)))?.id === run.id;
304
267
  return completedRowFor(taskId, project)?.runId === run.id;
305
268
  }
306
- /** A run's own task and its family's root: the task pages a result form may return to. */
307
269
  function runTasks(taskRef) {
308
270
  const task = store.externalIdFor(taskRef);
309
271
  return task === null ? [] : [task, familyOf(task)?.root.id ?? task];
310
272
  }
311
273
  async function showReview(ctx) {
312
274
  const { url, who, response, now, project, chosenProject } = ctx;
313
- // The review cockpit (Priority 5): every visible COMPLETED task,
314
- // ranked by review priority, with one selected result projected
315
- // from the records the task, run, and done pages already read —
316
- // scope, plan, run, artifacts, verdict, publication. The
317
- // ranking is a labeled presentation aid: it never rewrites the
318
- // stored verdict, and the sealed patch downloads exactly as stored.
319
- // Admission binds BEFORE the SQL limit (the done page's own rule),
320
- // and every row is re-proved against the ceiling before ranking.
321
275
  const resultRow = (row) => reviewRowOf(row, now);
322
276
  const rows = familiesInView(project, { states: ["done"], limit: REVIEW_QUEUE_CAP }).flatMap(family => {
323
277
  const row = completedRowFor(family.current.id, project);
@@ -327,34 +281,23 @@ export function createTasksHandlers(runtime) {
327
281
  const wanted = url.searchParams.get("result");
328
282
  const wantedId = wanted === null || wanted.length === 0 || wanted.length > 64 || hasForbiddenControls(wanted) ? null : wanted;
329
283
  const inQueue = wantedId === null ? null : ranked.find(one => one.taskId === wantedId) ?? null;
330
- // A stable deep link outlives the queue window (v2 review, comment
331
- // 1): a completion older than the newest REVIEW_QUEUE_CAP resolves
332
- // directly — re-proved as done, in this project, and inside the
333
- // ceiling — so an old receipt never reads as unfinished or foreign.
334
- // The ranked queue itself stays bounded and says so.
335
284
  const expectedRun = url.searchParams.get("run");
336
285
  const namedRun = expectedRun !== null && /^[1-9]\d*$/.test(expectedRun) ? Number(expectedRun) : null;
337
286
  const csrf = who.via === "cookie" ? who.session.csrf : "";
338
287
  const picked = wantedId === null ? null : selectResultFor(wantedId, namedRun, project, who, now, inQueue);
339
288
  const chosen = picked?.chosen ?? null, attemptRow = picked?.attemptRow ?? null, beyond = picked?.beyond ?? null;
340
289
  const selectedRow = wantedId === null ? ranked[0] ?? null : chosen;
341
- // An exact link to a result this person can't see (or that never existed) reads the same either way.
342
290
  if (expectedRun !== null && wantedId !== null && chosen === null)
343
291
  return refuse(response, who, 404, "No such result in your projects.", "/tasks");
344
292
  if (expectedRun !== null && (!/^[1-9]\d*$/.test(expectedRun) || selectedRow?.runId !== Number(expectedRun))) {
345
293
  return sendScreen(response, 409, screen("Result changed", html `<h1>Result changed</h1><p>This acceptance link no longer matches the current result. Review the current task before accepting.</p><p class="refusal-back"><a class="button-link" href="/tasks?view=ready">Review results</a></p>`, { chrome: chromeFor(project, "runs") }));
346
294
  }
347
295
  const selected = picked !== null ? picked.selected : selectedRow === null ? null : reviewCockpitViewOf(selectedRow, who, now);
348
- // Opening a run's own result page is viewing it: the shell says so with a keyed POST /agents/seen (easy-start N1:
349
- // a page load never writes), which leaves this person's unread Done once the run has finished.
350
296
  const reviewPage = reviewCockpitPage(chromeFor(wantedId === null ? project : chosenProject, "runs"), {
351
297
  queue: ranked,
352
298
  queueCap: REVIEW_QUEUE_CAP,
353
299
  selected,
354
300
  beyondQueue: beyond !== null && attemptRow === null,
355
- // A deep link to a result this console cannot show — not done,
356
- // not admitted, or never existed — says so in one sentence and
357
- // shows the top of the queue; the three cases read identically.
358
301
  missing: wantedId !== null && chosen === null ? wantedId : null,
359
302
  csrf,
360
303
  canRetryReview: who.via === "cookie" && who.role === "approver",
@@ -364,8 +307,6 @@ export function createTasksHandlers(runtime) {
364
307
  user: who.name,
365
308
  now,
366
309
  });
367
- // The result's task conversation, docked beside it (v77); messages
368
- // sent here carry the result being viewed.
369
310
  const reviewFocus = selected === null ? null : taskChatFocus(selected.taskId, now, who, { mintNonce: false });
370
311
  const reviewDocked = reviewFocus === null || selected === null ? null
371
312
  : dockedConversation(who, reviewFocus, null, now, reviewHref(selected.taskId), selected.run !== null && reviewFocus.family.versions.some(one => one.refId === store.getRun(selected.run.id)?.taskRef) ? selected.run.id : null);
@@ -373,11 +314,6 @@ export function createTasksHandlers(runtime) {
373
314
  reviewPage.workspace = { ...reviewPage.workspace, conversation: reviewDocked, pageHtml: reviewPage.body };
374
315
  return sendScreen(response, 200, reviewPage);
375
316
  }
376
- /** The old task list, retired into /work (docs/plans/reui-polish.md slice 7): its address keeps answering, as a
377
- * redirect, so links and bookmarks still land. `state` carries over (an unknown one is still refused); `template`
378
- * goes to the add page, which now pre-fills it. Anything else is dropped. */
379
- /** Tasks (docs/plans/plain-toolroll.md P1.4): the one list, with List, Board, Ready, Archived and an every-project
380
- * scope (`scope=all`). `view=board` is the Board, `view=order` the queue's order, `view=done` Finished. */
381
317
  async function showTasks(ctx) {
382
318
  const { url } = ctx;
383
319
  const template = url.searchParams.get("template");
@@ -386,7 +322,6 @@ export function createTasksHandlers(runtime) {
386
322
  const view = url.searchParams.get("view");
387
323
  if (view === "order")
388
324
  return showOrder(ctx);
389
- // The list reads its own keys: Board is its layout, every project its roll-up, Finished its completed view.
390
325
  const read = new URL(url.href);
391
326
  if (view === "board") {
392
327
  read.searchParams.delete("view");
@@ -400,7 +335,6 @@ export function createTasksHandlers(runtime) {
400
335
  }
401
336
  return showWork({ ...ctx, url: read });
402
337
  }
403
- /** The queue's order view, under Tasks: dispatch order with drag handles (scheduling, never authority). */
404
338
  async function showOrder(ctx) {
405
339
  const { url, who, response, project } = ctx;
406
340
  const csrf = who.via === "cookie" ? who.session.csrf : "";
@@ -415,8 +349,6 @@ export function createTasksHandlers(runtime) {
415
349
  html `<p class="meta" id="queue-region-stamp"></p>`,
416
350
  ], "\n"), { chrome: chromeFor(project, "work"), functional: { script: queueScript(), fetches: true } }));
417
351
  }
418
- /** /n/<number>: a push's task link, by the task's stored number, never its title. It opens the task's page only
419
- * inside the viewer's own projects; anything else is the same not-found as an unknown number. */
420
352
  async function showNumberedTask(ctx) {
421
353
  const { url, who, response } = ctx;
422
354
  const number = Number(url.pathname.slice("/n/".length));
@@ -432,7 +364,6 @@ export function createTasksHandlers(runtime) {
432
364
  const prefill = picked !== null && picked.kind === "task"
433
365
  ? { title: picked.title, goal: picked.goal, not: picked.outOfScope ?? "", touches: picked.touches.join(", "), acceptance: acceptanceToLines(picked.acceptance).join("\n") }
434
366
  : null;
435
- // An idea's link (or any ?text=) puts words in the box: bounded to what the box takes, nothing filed.
436
367
  const text = ctx.url.searchParams.get("text");
437
368
  return newTaskScreen(ctx, 200, null, prefill, text === null ? null : text.slice(0, 200));
438
369
  }
@@ -447,24 +378,17 @@ export function createTasksHandlers(runtime) {
447
378
  const version = url.searchParams.get("version");
448
379
  if (version !== null && !family.versions.some(one => one.id === version))
449
380
  return refuse(response, who, 404, "That version is not available for this task.", taskHref(family.root.id));
450
- // A version's own address lands on its family's page, still asking for the plan editor when it did (Chat's Edit plan).
451
381
  if (task.taskId !== family.root.id) {
452
- // Everything else the address asked for (its tab, result run and view, a form's feedback) rides along.
453
382
  const kept = new URLSearchParams(url.searchParams);
454
383
  kept.delete("version");
455
384
  return redirect(response, `${taskHref(family.root.id)}?version=${encodeURIComponent(task.taskId)}${kept.size === 0 ? "" : `&${kept.toString()}`}`);
456
385
  }
457
- // One page per task (docs/plans/one-page-task-and-agent.md): the tab named, and the Result tab's result — the shown
458
- // version's own, or the exact run `run=` names, which must be a result of that very version.
459
386
  const tabWord = url.searchParams.get("tab");
460
- // The first tab (Plan, or Result once there is one) unless the address names Activity or Attempts.
461
387
  const tab = tabWord === "result" || tabWord === "activity" || tabWord === "attempts" ? tabWord : "plan";
462
388
  const runWord = url.searchParams.get("run");
463
389
  const named = runWord === null ? null : /^[1-9][0-9]{0,14}$/.test(runWord) ? Number(runWord) : -1;
464
390
  if (named === -1)
465
391
  return refuse(response, who, 404, "No such result for this task.", taskHref(family.root.id));
466
- // A run named without a version is shown with the version it belongs to: a saved link to a result outlives a newer
467
- // revision becoming current. A run of no version of this family is no result of it.
468
392
  const owner = named === null || version !== null ? null : (() => { const ref = store.getRun(named)?.taskRef; const id = ref === undefined ? null : store.externalIdFor(ref); return id !== null && family.versions.some(one => one.id === id) ? id : null; })();
469
393
  const shown = version ?? owner ?? family.current.id;
470
394
  const picked = selectResultFor(shown, named, ctx.project, who, ctx.now);
@@ -474,19 +398,15 @@ export function createTasksHandlers(runtime) {
474
398
  const csrf = who.via === "cookie" ? who.session.csrf : "";
475
399
  const result = picked.selected === null ? null : (() => {
476
400
  const parts = reviewCockpitDetailParts(picked.selected, csrf, url.searchParams.get("noted") !== null, who.via === "cookie" && who.role === "approver", parseResultTab(url.searchParams.get("section")), who.name, { kind: "task", base });
477
- // Current: the result the task itself would show (its latest), however the address named it — the header then
478
- // owns its status and ceremonies, so no form is ever on the page twice.
479
401
  const latest = named === null ? picked.chosen?.runId ?? null : selectResultFor(shown, null, ctx.project, who, ctx.now).chosen?.runId ?? null;
480
402
  return { html: parts.html, selected: parts.selected, current: shown === family.current.id && latest !== null && latest === picked.chosen?.runId };
481
403
  })();
482
- // The attempts the picker offers: exactly the runs this page would show for their version (the same rule as above).
483
404
  const admissible = new Set(family.versions.flatMap(one => {
484
405
  const ref = store.lookupRef(one.id);
485
406
  return ref === null ? [] : store.runsFor(ref.id).filter(run => resultRunAdmissible(one.id, run, ctx.project)).map(run => run.id);
486
407
  }));
487
408
  return taskScreen(response, who, shown, null, 200, undefined, undefined, url.searchParams.get("edit") === "plan", { tab, result, admissible });
488
409
  }
489
- // v103: a task's evidence pack, as a printable page or JSON (the whole family, sealed ledger entries included).
490
410
  async function showTaskEvidence(ctx) {
491
411
  const { url, who, response, now } = ctx;
492
412
  const evidence = matchTaskPath(url.pathname, "/evidence$");
@@ -508,8 +428,6 @@ export function createTasksHandlers(runtime) {
508
428
  }
509
429
  return sendScreen(response, 200, evidenceRecordPage(chromeFor(family.root.repo, "tasks"), pack));
510
430
  }
511
- /** Build history lives on Agents now ("Finished in the last …"), and each task keeps its own attempts: the old address
512
- * keeps answering, as a GET alias. */
513
431
  async function showRuns(ctx) {
514
432
  return redirectGet(ctx.response, "/agents");
515
433
  }
@@ -529,14 +447,9 @@ export function createTasksHandlers(runtime) {
529
447
  return respond(response, 200, "text/html; charset=utf-8", checkProgressHtml(store.checkProgress(found.id)));
530
448
  }
531
449
  if (url.searchParams.get("fragment") === "facts") {
532
- // The facts region alone — same auth and ceiling as the page; a
533
- // finished or no-longer-live run says so rather than growing forms
534
- // (finding 5; round-4 finding 15).
535
450
  return respond(response, 200, "text/html; charset=utf-8", runFactsFragment(found, taskId, running, store.runRoute(found.id)));
536
451
  }
537
452
  if (url.searchParams.get("fragment") === "peek") {
538
- // The live peek: cookie sessions only (v2 §3), never stored, never
539
- // cached by anything downstream.
540
453
  if (who.via !== "cookie")
541
454
  return respond(response, 403, "text/plain; charset=utf-8", "the live peek is a browser session's view");
542
455
  const peeked = await peekFragment(found.id, who.session.csrf, options.editorLinks !== undefined && found.runner === options.localRunner && who.session.editorLinks === true);
@@ -546,18 +459,10 @@ export function createTasksHandlers(runtime) {
546
459
  return respond(response, peeked.status, "text/html; charset=utf-8", peeked.body);
547
460
  }
548
461
  if (url.searchParams.get("fragment") === "transcript") {
549
- // The live conversation's window (arc 1; live-conversation.md §3–4):
550
- // JSON over sanitized text or records — the sinks are textContent and
551
- // React text, never innerHTML. Guards, enumerated: cookie session; run
552
- // visible (proved above); this machine's runner asserted AND owning
553
- // the run; byte offsets validated; the file read through its own
554
- // descriptor with the exact numeric-id name, and its generation
555
- // matched. Display state, not evidence — and never cached.
556
462
  response.setHeader("cache-control", "no-store");
557
463
  if (who.via !== "cookie")
558
464
  return respond(response, 403, "application/json", JSON.stringify({ error: "session" }));
559
465
  const records = url.searchParams.get("shape") === "records";
560
- // Notes come from the store, not the file: they show even where the transcript cannot be read.
561
466
  const notesOf = () => (records ? runNotes(store, found, who.name, now) : {});
562
467
  if (options.localRunner === undefined || found.runner !== options.localRunner) {
563
468
  return respond(response, 200, "application/json", JSON.stringify({ error: "off", ...notesOf() }));
@@ -569,27 +474,19 @@ export function createTasksHandlers(runtime) {
569
474
  }
570
475
  const sawGen = url.searchParams.get("gen");
571
476
  const live = runIsLive(found);
572
- // The final drain: a finished run's tail — including a torn last
573
- // line — may be read until the sweep removes the file.
574
477
  const window = readLiveWindow(evidenceRoot, found.id, from, !live);
575
478
  if (!window.ok) {
576
479
  if (window.reason === "replaced") {
577
480
  return respond(response, 409, "application/json", JSON.stringify({ error: "replaced" }));
578
481
  }
579
- // Missing or unreadable: nothing to show. Final only when the
580
- // run can never write again.
581
- // Nothing was read, so the key state the cursor carried is handed straight back.
582
482
  const inKey = url.searchParams.get("inkey") === "1";
583
483
  const keyTail = validKeyTail(url.searchParams.get("ktail") ?? "") ? url.searchParams.get("ktail") ?? "" : "";
584
484
  const empty = records ? { records: [], nextOffset: from, gen: sawGen, inKey, keyTail, final: !live } : { text: "", nextOffset: from, inKey, keyTail, final: !live };
585
485
  return respond(response, 200, "application/json", JSON.stringify({ ...empty, ...notesOf() }));
586
486
  }
587
- // An offset belongs to the file it was read from: another file starts over, visibly.
588
487
  if (sawGen !== null && sawGen !== "" && sawGen !== window.gen) {
589
488
  return respond(response, 409, "application/json", JSON.stringify({ error: "replaced" }));
590
489
  }
591
- // Re-proof after the read (peek discipline): the run row still says
592
- // what admission said — visible, and still this machine's — or nothing is shown.
593
490
  const again = store.getRun(found.id);
594
491
  if (again === null || !runVisible(again) || again.runner !== options.localRunner) {
595
492
  const inKey = url.searchParams.get("inkey") === "1";
@@ -597,35 +494,25 @@ export function createTasksHandlers(runtime) {
597
494
  return respond(response, 200, "application/json", JSON.stringify(records ? { records: [], nextOffset: from, gen: window.gen, inKey, keyTail, final: true } : { text: "", nextOffset: from, inKey, keyTail, final: true }));
598
495
  }
599
496
  const final = !live && window.eof;
600
- // A key block split across reads stays hidden: the cursor carries whether the last read ended inside one.
601
497
  const tailRaw = url.searchParams.get("ktail") ?? "";
602
498
  const keys = { inKey: url.searchParams.get("inkey") === "1", tail: validKeyTail(tailRaw) ? tailRaw : "" };
603
499
  if (records) {
604
- // Command text and output only under this run's own captured answer, never the file's `open` record (v136).
605
500
  const commands = runLiveCommands(store, found.id);
606
501
  const shown = liveWindowRecords(window, commands, keys);
607
502
  return respond(response, 200, "application/json", JSON.stringify({ records: shown, nextOffset: window.nextOffset, gen: window.gen, inKey: keys.inKey, keyTail: keys.tail ?? "", final, ...notesOf() }));
608
503
  }
609
- // The plain words, whatever the file's format; the offset moves by the bytes read even when nothing shows.
610
504
  const lines = liveWindowLines(window, runLiveCommands(store, found.id), keys);
611
505
  return respond(response, 200, "application/json", JSON.stringify({ text: lines.length === 0 ? "" : `${lines.join("\n")}\n`, nextOffset: window.nextOffset, gen: window.gen, inKey: keys.inKey, keyTail: keys.tail ?? "", final }));
612
506
  }
613
- // One result page (2026-10-02): a builder's finished result opens on
614
- // its task's result page, titled with the task. The raw run record
615
- // waits there under Details, and here with ?record=1.
616
507
  if (url.searchParams.get("record") === null && !running && found.role === "builder" && (found.outcome === "built" || found.outcome === "no-change") &&
617
508
  completedRowFor(taskId, null)?.runId === found.id) {
618
509
  const tab = parseResultTab(url.searchParams.get("tab"));
619
510
  return redirect(response, `${reviewHref(taskId, found.id)}${tab === "summary" ? "" : `&tab=${tab}`}`);
620
511
  }
621
- // A build that failed or stopped opens on its own result page too: its changes, its checks and what went wrong.
622
512
  if (url.searchParams.get("record") === null && !running && (found.role === "builder" || found.role === "scout") && attemptRowFor(taskId, found.id, null) !== null) {
623
513
  const tab = parseResultTab(url.searchParams.get("tab"));
624
514
  return redirect(response, `${reviewHref(taskId, found.id)}${tab === "summary" ? "" : `&tab=${tab}`}`);
625
515
  }
626
- // Pollers exist only for a LIVE run — an orphaned null-outcome run
627
- // would otherwise be refetched forever (finding 15). The nonce is
628
- // sendScreen's business now.
629
516
  const artifacts = store.artifactsFor(found.id);
630
517
  return sendScreen(response, 200, runPage(chromeFor(project, "runs", runListPane(project, found.id)), found, taskId, artifacts, terminalDiffView(artifacts, evidenceRoot), store.notesForRun(found.id), who.via === "cookie" ? who.session.csrf : "", store.liveDiffComments(found.id).filter(isRevisionFeedback), (() => {
631
518
  const publication = store.publicationForRun(found.id);
@@ -636,18 +523,12 @@ export function createTasksHandlers(runtime) {
636
523
  ? undefined
637
524
  : regionScript("run-facts", "facts") +
638
525
  (options.localRunner === undefined ? "" : regionScript("run-peek", "peek")) +
639
- (options.localRunner === undefined ? "" : transcriptScript()), options.localRunner !== undefined, running,
640
- // Editor links (arc 6): three statements align or nothing renders —
641
- // the deployment capability, THIS machine's runner owning the run,
642
- // and the session's own device-side yes.
643
- options.editorLinks !== undefined &&
526
+ (options.localRunner === undefined ? "" : transcriptScript()), options.localRunner !== undefined, running, options.editorLinks !== undefined &&
644
527
  options.localRunner !== undefined &&
645
528
  found.runner === options.localRunner &&
646
529
  who.via === "cookie" &&
647
530
  who.session.editorLinks === true &&
648
- // A reviewer run (v29) never had a checkout — no files to open.
649
531
  found.worktree !== null &&
650
- // Idle cleanup removes the folder and a later run makes it again: no link to a folder that isn't there.
651
532
  existsSync(found.worktree)
652
533
  ? { worktree: found.worktree }
653
534
  : null, options.editorLinks !== undefined &&
@@ -655,9 +536,7 @@ export function createTasksHandlers(runtime) {
655
536
  found.runner === options.localRunner &&
656
537
  who.via === "cookie"
657
538
  ? { on: who.session.editorLinks === true }
658
- : null, url.searchParams.get("noted") !== null, structuredHandoffView(artifacts, evidenceRoot), proofBundleView(store, found, artifacts, evidenceRoot), store.runRoute(found.id), store.publicationForRun(found.id), reviewFactsFor(found.id),
659
- // The shared result presentation (package 3) for a finished result.
660
- !running && (found.outcome === "built" || found.outcome === "no-change")
539
+ : null, url.searchParams.get("noted") !== null, structuredHandoffView(artifacts, evidenceRoot), proofBundleView(store, found, artifacts, evidenceRoot), store.runRoute(found.id), store.publicationForRun(found.id), reviewFactsFor(found.id), !running && (found.outcome === "built" || found.outcome === "no-change")
661
540
  ? { detail: resultDetailOf(found, who, now), tab: parseResultTab(url.searchParams.get("tab")), user: who.name, requestToken: randomBytes(16).toString("hex") }
662
541
  : null, store.getScope(taskId)?.digest ?? null));
663
542
  }
@@ -668,7 +547,6 @@ export function createTasksHandlers(runtime) {
668
547
  return noPage(who, response);
669
548
  return runEvidence(response, Number(runArtifact[1]), Number(runArtifact[2]));
670
549
  }
671
- // v115: routines became scheduled flows; an old link to the list or to one routine lands on the flows page.
672
550
  async function showRoutines(ctx) {
673
551
  return redirect(ctx.response, "/flows");
674
552
  }
@@ -707,8 +585,6 @@ export function createTasksHandlers(runtime) {
707
585
  const permitted = (repo) => visible(repo) && codingProjectAllowed(repo);
708
586
  const starting = verb === 'start';
709
587
  const sessionId = starting || verb === 'unknown' ? null : /^\/code\/([a-f0-9]{32})/.exec(url.pathname)[1];
710
- // Sprint 8: a coding session is Codex taking turns: the organisation policy decides whether it may (provider,
711
- // model, and a ceiling Codex can't run under), when it starts and on every action that makes it take another turn.
712
588
  const turnAction = ['send', 'resume', 'recover', 'continue', 'answer'].includes(verb);
713
589
  if (starting || turnAction) {
714
590
  const stopped = store.sessionPolicyRefusal('codex', starting ? body.get('model')?.trim() || null : null, 'coding sessions');
@@ -761,7 +637,6 @@ export function createTasksHandlers(runtime) {
761
637
  runtime.coding.answer(id, actor, token, decision, answers);
762
638
  }
763
639
  }
764
- // Authorization is checked again after asynchronous startup/transport work.
765
640
  if (!codingActorAllowed(actor))
766
641
  return fail(403, 'Your access changed. Sign in again.', 'unknown', id);
767
642
  return wantsJson ? respond(response, 200, 'application/json', JSON.stringify({ ok: true, id })) : redirect(response, `/code/${id}`);
@@ -787,8 +662,6 @@ export function createTasksHandlers(runtime) {
787
662
  if (project === undefined) {
788
663
  return refuse(response, who, 403, "that project is outside what this server was configured to show");
789
664
  }
790
- // Stale-tab guard: a form rendered under one open project must not
791
- // create into a different one switched-to since (finding 6).
792
665
  if (who.via === "cookie") {
793
666
  const seen = body.get("projectRevision");
794
667
  if (seen !== null && seen !== String(who.session.projectRevision)) {
@@ -796,38 +669,21 @@ export function createTasksHandlers(runtime) {
796
669
  }
797
670
  }
798
671
  const id = (body.get("id") ?? "").trim();
799
- // The New task box stops at a title's length (render-new-task.ts): the title is all the planner reads of a no-goal
800
- // filing. A direct POST longer than that is cut at a whole word, with an ellipsis (task-text.ts titleWithin), as a
801
- // belt; a refusal keeps the person's own words (the draft below).
802
672
  const typed = body.get("title") ?? "";
803
673
  const title = titleWithin(typed);
804
- // The EFFECTIVE placement (repo onboarding, findings 15/35): the
805
- // trimmed, nonempty posted repo, else the open project — an empty
806
- // input falls through correctly. In root mode the effective path is
807
- // proved by authorizedProject EXACTLY as typed-then-canonicalized,
808
- // and [canonical] is the admitted list — a fresh clone under a root
809
- // must be able to receive its first task without waiting to appear
810
- // in any table.
811
674
  const repoGiven = (body.get("repo") ?? "").trim();
812
675
  const effective = repoGiven !== "" ? repoGiven : (project ?? "");
813
676
  if (restricted() && !visible(effective === "" ? null : effective))
814
677
  return refuse(response, who, 403, "That project is outside your access.", "/projects");
815
- // A scoped console refuses an EMPTY placement server-side (verification
816
- // finding 1): the form's `required` is a courtesy, not the guard — a
817
- // direct POST with no project open must not mint an unplaced task
818
- // under a ceiling. Unscoped mode keeps its historic unplaced filings.
819
- // A refusal from here on is the add page again with the person's own words (the old task list kept them too).
820
678
  const draft = { title: typed, goal: body.get("goal") ?? "", not: body.get("not") ?? "", touches: body.get("touches") ?? "", acceptance: body.get("acceptance") ?? "", values: body.sent };
821
679
  if (!unscopedMode && effective === "") {
822
680
  return newTaskScreen(ctx, 400, "name a repository — no project is open, so the task must say where it belongs", draft);
823
681
  }
824
682
  let repo = effective;
825
683
  let admitted = unscopedMode ? null : admissionList() ?? [];
826
- // What this filing is decided on: re-checked inside the write below, after every await (project-identity.ts).
827
684
  const decidedOn = identities.generation();
828
685
  const rootMode = !unscopedMode && ceiling.roots.length > 0;
829
686
  if (rootMode && effective !== "") {
830
- // Resolved off the console's thread (project-identity.ts), then proved against the ceiling as that identity.
831
687
  const resolved = await identities.resolveNow(effective);
832
688
  if (resolved === "no-answer")
833
689
  return newTaskScreen(ctx, 503, `${effective} didn't answer — its folder may be on a drive that's disconnected, or waiting on macOS; try again in a moment`, draft);
@@ -853,9 +709,7 @@ export function createTasksHandlers(runtime) {
853
709
  if (qualityMode !== null && !isQualityMode(qualityMode)) {
854
710
  return refuse(response, who, 400, "quality must be Default or Strict / release", "/tasks/new");
855
711
  }
856
- // One filing door for every surface (Codex adoption review, finding 7).
857
712
  const after = (body.get("after") ?? "").trim();
858
- // From an issue or pull request (github-import.ts): read and quoted first; filing is the second press, on what was read.
859
713
  const fromLink = (body.get("from") ?? "").trim();
860
714
  if (fromLink !== "") {
861
715
  if (who.via !== "cookie" || repo === "")
@@ -871,8 +725,6 @@ export function createTasksHandlers(runtime) {
871
725
  return newTaskScreen(ctx, filed.reason === "head-moved" ? 409 : 400, filed.message, draft);
872
726
  return redirect(response, taskHref(filed.taskId));
873
727
  }
874
- // Small work a person starts themselves: their words become the exact terms, and Build is their yes (fast-start.ts).
875
- // Anything else, or any doubt, is the ordinary filing below. `plain` is "Plan it first" from that form.
876
728
  if (who.via === "cookie" && body.get("plain") !== "1" && repo !== "" && goal === "" && notThis === "" && touchesGiven.length === 0 && !scout && id === "" && after === ""
877
729
  && (qualityMode === null || qualityMode === "default") && (permissionMode === null || permissionMode === "auto")) {
878
730
  const fast = await prepareFastStart(store, { actor: who.name, repo, title: typed.trim(), via: "console", ...(permissionMode === null ? {} : { permissionMode }), password: fastPasswordFacts(who) }, now);
@@ -881,8 +733,6 @@ export function createTasksHandlers(runtime) {
881
733
  }
882
734
  let chainProblem = null;
883
735
  const made = store.transact(() => {
884
- // A project folder's identity changed while this request waited (a root or link now leads elsewhere): what was
885
- // proved above may no longer hold, so nothing is filed on it.
886
736
  if (identities.generation() !== decidedOn || (rootMode && repo !== "" && !visible(repo)))
887
737
  return null;
888
738
  const filed = fileTaskProposal(store, {
@@ -910,8 +760,6 @@ export function createTasksHandlers(runtime) {
910
760
  if (!chained.ok)
911
761
  chainProblem = chained.reason;
912
762
  }
913
- // Missing dependencies leave a reviewable, inert task. They must
914
- // never be silently dropped before automatic approval starts work.
915
763
  if (filed.ok && chainProblem === null && who.via === "cookie")
916
764
  applyModeToNewFiling(store, filed.id, who.name, now);
917
765
  return filed;
@@ -924,8 +772,6 @@ export function createTasksHandlers(runtime) {
924
772
  const actionContext = requestContext.getStore();
925
773
  if (actionContext !== undefined)
926
774
  actionContext.createdTask = made.id;
927
- // A proved root-mode placement joins the project table (finding 15):
928
- // the new task's home is openable and admissible from now on.
929
775
  if (rootMode && repo !== "")
930
776
  store.upsertProject(repo, projectName(repo), now);
931
777
  if (chainProblem !== null)
@@ -939,9 +785,6 @@ export function createTasksHandlers(runtime) {
939
785
  if (project === undefined) {
940
786
  return refuse(response, who, 403, "that project is outside what this server was configured to show");
941
787
  }
942
- // The note is a global runner label, not project-scoped work: the
943
- // fleet screen (project-less) posts it too, so the null-project gate
944
- // applies only to moves, which their task-level check re-proves.
945
788
  const worker = (body.get("runner") ?? "").trim();
946
789
  const note = (body.get("note") ?? "").trim();
947
790
  if (note.length > 200 || hasForbiddenControls(note)) {
@@ -965,8 +808,6 @@ export function createTasksHandlers(runtime) {
965
808
  return refuse(response, who, 409, "the open project changed since this form was rendered — reload and try again", QUEUE_VIEW);
966
809
  }
967
810
  }
968
- // A drag posts in place (fetch) when it can; the page re-renders its
969
- // own fragment on success. A plain form still works with no script.
970
811
  const inPlace = body.get("respond") === "fragment";
971
812
  const fromFleet = who.via === "cookie" && body.get("projectRevision") === null;
972
813
  const respondMove = (status, message) => {
@@ -988,8 +829,6 @@ export function createTasksHandlers(runtime) {
988
829
  const toRunner = columnGiven === "" || columnGiven === "anyone" ? null : columnGiven;
989
830
  const beforeGiven = (body.get("before") ?? "").trim();
990
831
  const revisionGiven = Number(body.get("queueRevision") ?? "");
991
- // The queue's own screen enforces the open project; the fleet screen
992
- // is cross-project, so the ceiling is the only wall it needs.
993
832
  const belongs = (id) => {
994
833
  const ref = store.lookupRef(id);
995
834
  return ref !== null && visible(ref.repo) && (fromFleet || project === null || ref.repo === null || ref.repo === project);
@@ -997,12 +836,6 @@ export function createTasksHandlers(runtime) {
997
836
  if (!belongs(taskId) || (beforeGiven !== "" && beforeGiven !== QUEUE_FRONT && !belongs(beforeGiven))) {
998
837
  return respondMove(404, "that task is not in this queue");
999
838
  }
1000
- // The no-script "move to the front" button cannot name the front: the
1001
- // front of a task's partition is decided by the store's exact repo AND
1002
- // assignment, and the page's snapshot is bounded — so the sentinel is
1003
- // resolved HERE, against a fresh snapshot, into a real task id (slice
1004
- // 1b, fix 1). It is honored only within the task's own column; a
1005
- // cross-column front is not provable from a bounded snapshot.
1006
839
  let beforeTaskId = beforeGiven === "" ? null : beforeGiven;
1007
840
  if (beforeGiven === QUEUE_FRONT) {
1008
841
  const ref = store.lookupRef(taskId);
@@ -1014,11 +847,6 @@ export function createTasksHandlers(runtime) {
1014
847
  const now = clock();
1015
848
  const snapshot = store.queueScoped(ref.repo, now);
1016
849
  const self = snapshot.find(one => one.id === taskId);
1017
- // A claim can land after the form rendered WITHOUT
1018
- // bumping queueRevision, so the snapshot — not the form — decides
1019
- // whether the card is still free. A taken or vanished card is the
1020
- // typed refusal, never a silent no-op that would skip moveTask()'s
1021
- // own claimed recheck.
1022
850
  if (self === undefined)
1023
851
  return respondMove(409, moveReason("unknown-task"));
1024
852
  if (self.taken)
@@ -1028,9 +856,6 @@ export function createTasksHandlers(runtime) {
1028
856
  if (front === undefined)
1029
857
  return respondMove(409, moveReason("unknown-task"));
1030
858
  if (front.id === taskId) {
1031
- // Already the front: a no-op, but only against the revision the
1032
- // form was rendered with — this branch never reaches moveTask()'s
1033
- // CAS, so the check is made here.
1034
859
  if (!Number.isSafeInteger(revisionGiven) || revisionGiven !== store.queueRevision()) {
1035
860
  return respondMove(409, moveReason("stale"));
1036
861
  }
@@ -1071,10 +896,6 @@ export function createTasksHandlers(runtime) {
1071
896
  }
1072
897
  const choice = body.get("choice") ?? "";
1073
898
  const chosen = decision.options.find(option => option.id === choice);
1074
- // Irreversible options never ride one accidental tap: the form arms
1075
- // them behind an explicit confirmation field, and the server checks —
1076
- // the client rendering is convenience, this is the rule.
1077
- // The question page's own form hears a refusal in its box, with nothing changed; /next keeps its refusal page.
1078
899
  const inPlace = requestedReturn !== "next";
1079
900
  const pageBack = requestedReturn === null ? null : decisionBack;
1080
901
  if (chosen !== undefined && !chosen.reversible && body.get("confirm") !== "yes") {
@@ -1107,8 +928,6 @@ export function createTasksHandlers(runtime) {
1107
928
  if (act === null)
1108
929
  return noPage(who, response);
1109
930
  const body = readForm(posted, CONSOLE_FORMS.recheckStopped);
1110
- // Check again: Toolroll looks at this computer's processes for the build once more (stop-proof.ts) and settles it
1111
- // when none of them is the build's. Nobody vouches that a build stopped, so there is nothing to confirm here.
1112
931
  const back = taskHref(act.taskId);
1113
932
  const ref = store.lookupRef(act.taskId);
1114
933
  if (ref === null || !visible(ref.repo))
@@ -1141,8 +960,6 @@ export function createTasksHandlers(runtime) {
1141
960
  if (act === null)
1142
961
  return noPage(who, response);
1143
962
  const body = readForm(posted, CONSOLE_FORMS.merge);
1144
- // Merging is a person's act behind their password, typed again: a browser session, an approver, the exact
1145
- // result's pull request. The flow re-reads GitHub before merging and records who merged in the ledger.
1146
963
  if (store.isDemo())
1147
964
  return taskScreen(response, who, act.taskId, "The demo merges nothing.", 403);
1148
965
  const ref = store.lookupRef(act.taskId);
@@ -1159,7 +976,6 @@ export function createTasksHandlers(runtime) {
1159
976
  return taskScreen(response, who, act.taskId, merged.message, merged.reason === "password" ? 403 : 409);
1160
977
  return redirect(response, `${taskHref(act.taskId)}#merge`);
1161
978
  }
1162
- /** A task act bound to its verb: taskMutation owns each verb's checks. */
1163
979
  const taskAct = (verb) => async (ctx) => {
1164
980
  const { url, who, response, now, posted } = ctx;
1165
981
  const act = matchTaskPath(url.pathname, `/${verb}$`);
@@ -1167,8 +983,6 @@ export function createTasksHandlers(runtime) {
1167
983
  return noPage(who, response);
1168
984
  return taskMutation(response, who, act.taskId, verb, posted, now, ctx.request);
1169
985
  };
1170
- // Cockpit E: Show in Finder — the checkout proved again right now (live, this machine's runner, inside the pool),
1171
- // then Finder asked to reveal it with a fixed argv. Nothing runs in it; a Mac only.
1172
986
  async function runReveal(ctx) {
1173
987
  const { url, who, response, now, posted } = ctx;
1174
988
  const asked = /^\/r\/([0-9]{1,15})\/reveal$/.exec(url.pathname);
@@ -1195,10 +1009,6 @@ export function createTasksHandlers(runtime) {
1195
1009
  if (noted === null)
1196
1010
  return noPage(who, response);
1197
1011
  const body = readForm(posted, CONSOLE_FORMS.runNote);
1198
- // An operator's verdict beside the machine's record (M6): immutable,
1199
- // bounded by the same validator as decision notes, ceiling-checked
1200
- // like every run resource. Ordinary authenticated mutation — no
1201
- // nonce, because nothing here approves anything.
1202
1012
  const id = Number(noted[1]);
1203
1013
  const found = store.getRun(id);
1204
1014
  if (found === null || !visible(taskRepoOf(found.taskRef))) {
@@ -1216,31 +1026,17 @@ export function createTasksHandlers(runtime) {
1216
1026
  if (diffComment === null)
1217
1027
  return noPage(who, response);
1218
1028
  const body = readForm(posted, CONSOLE_FORMS.diffComment);
1219
- // A review comment on the IMMUTABLE terminal diff (M6.8): bound to
1220
- // the exact artifact and its hash. Ordinary authenticated mutation —
1221
- // the nonce belongs to the approval screen that later restates the
1222
- // batch, never to the comment box.
1223
1029
  const id = Number(diffComment[1]);
1224
1030
  const found = store.getRun(id);
1225
1031
  if (found === null || !visible(taskRepoOf(found.taskRef))) {
1226
1032
  return refuse(response, who, 404, "no such run");
1227
1033
  }
1228
- // Where the reader came from (package 3): the cockpit's deep link,
1229
- // the chat's result view, or the run page — validated to those exact
1230
- // shapes. A refusal sends them back THERE, where the browser has kept
1231
- // their draft, so a failed submission is recoverable in place.
1232
1034
  const returnTo = resultReturnTarget(body.get("return"), id, runTasks(found.taskRef));
1233
1035
  const selectedTab = parseResultTab(body.get("tab"));
1234
- // A task page's Result tab keeps the result's own view in `section=` (its `tab` is the task's).
1235
1036
  const viewParam = returnTo.startsWith("/t/") ? "section" : "tab";
1236
1037
  const back = selectedTab === "summary" ? returnTo
1237
1038
  : `${returnTo.replace(/&section=(?:summary|changes|checks)$/, "")}${returnTo.includes("?") ? "&" : "?"}${viewParam}=${selectedTab}`;
1238
1039
  if (body.get("intent") === "drop-image") {
1239
- // A saved note whose screenshot is gone or changed would block every revision that seals it. Its words stay:
1240
- // the note is superseded by an exact imageless copy, and the original remains in history.
1241
- // Who: a signed-in browser approver admitted to this run's project (checked above) — the same authority that
1242
- // seals any saved note into a revision. What: only a screenshot that is unusable right now, re-proved inside
1243
- // dropFeedbackImage's transaction, and recorded in the ledger under this person.
1244
1040
  if (who.via !== "cookie" || who.role !== "approver")
1245
1041
  return refuse(response, who, 403, "Only a signed-in approver can change saved feedback.", back);
1246
1042
  const comment = Number(body.get("comment") ?? "");
@@ -1261,14 +1057,11 @@ export function createTasksHandlers(runtime) {
1261
1057
  const result = requestResultChanges(store, evidenceRoot, {
1262
1058
  run: id, batch: body.get("batch"), source: body.get("source"), actor: who.name,
1263
1059
  repos: admissionList(), includeUnplaced: visible(null), allowMode: who.via === "cookie",
1264
- // A browser session is a person's proof; a bearer credential is a machine's.
1265
1060
  origin: who.via === "cookie" ? "person" : "machine",
1266
1061
  note: body.get("note") ?? "", path: body.get("path") ?? "", line: body.get("line") ?? "", request: body.get("request"), image,
1267
1062
  }, now);
1268
1063
  if (!result.ok) {
1269
1064
  const request = body.get("request") ?? "";
1270
- // The queue's link can stop resolving when a newer attempt finishes. The exact
1271
- // run record still hosts this account/run's recoverable feedback draft.
1272
1065
  const retryBase = image === null ? back : `/r/${id}?record=1`;
1273
1066
  const retryBack = /^[a-f0-9]{32}$/.test(request) ? `${retryBase}${retryBase.includes("?") ? "&" : "?"}conflict=${request}#request-changes` : retryBase;
1274
1067
  return refuse(response, who, result.status, result.message, retryBack);
@@ -1279,9 +1072,6 @@ export function createTasksHandlers(runtime) {
1279
1072
  if (terminal === undefined) {
1280
1073
  return refuse(response, who, 400, "this run has no terminal diff to comment on", back);
1281
1074
  }
1282
- // The bytes must VERIFY before words attach to them (audit IV-10):
1283
- // "a comment on the exact reviewed bytes" is a lie if the bytes are
1284
- // gone or no longer hash to their record.
1285
1075
  const proven = readVerifiedArtifact(evidenceRoot, terminal);
1286
1076
  if (!proven.ok) {
1287
1077
  return refuse(response, who, 409, `the terminal diff no longer verifies (${proven.problem}) — nothing to comment on`, back);
@@ -1298,15 +1088,9 @@ export function createTasksHandlers(runtime) {
1298
1088
  if (line !== null && (!Number.isInteger(line) || line < 1 || line > 1_000_000)) {
1299
1089
  return refuse(response, who, 400, "Enter a whole line number from 1 to 1,000,000, or leave it blank.", back);
1300
1090
  }
1301
- // The form's own request token (package 3) is the dedupe key: a
1302
- // replayed or double submission finds its note already recorded and
1303
- // lands on the same receipt instead of a second note. The token is
1304
- // bound to the account, so nobody else's replay can consume it.
1305
1091
  const request = body.get("request");
1306
1092
  const sourceKey = commentSourceKey(who.name, request);
1307
1093
  const path = rawPath === "" ? null : rawPath;
1308
- // Freshness, custody and the insert in one write transaction: a newer attempt finishing in between can't leave a
1309
- // stale screenshot attached (check and write together).
1310
1094
  const saved = store.transact(() => {
1311
1095
  const imageProblem = feedbackImageProblem(store, evidenceRoot, id, image);
1312
1096
  if (imageProblem !== null)
@@ -1317,13 +1101,6 @@ export function createTasksHandlers(runtime) {
1317
1101
  return refuse(response, who, 409, saved.problem, `/r/${id}?record=1#request-changes`);
1318
1102
  const inserted = saved.inserted;
1319
1103
  if (inserted === null && sourceKey !== undefined) {
1320
- // The token was used before (repair 2026-09-14, finding 1). A
1321
- // request identity is IMMUTABLE: it names exactly one note on
1322
- // exactly one result. The unchanged retry — same run, same file,
1323
- // line and words — lands on its original receipt; any other reuse
1324
- // is refused, and the refusal's way back carries `conflict=<token>`
1325
- // so the browser mints a fresh identity for the words it still
1326
- // holds. Nothing typed is lost either way.
1327
1104
  const earlier = store.diffCommentBySourceKey(sourceKey);
1328
1105
  const conflictBack = `${back}${back.includes("?") ? "&" : "?"}conflict=${request}#request-changes`;
1329
1106
  if (earlier === null || earlier.run !== id) {
@@ -1333,21 +1110,12 @@ export function createTasksHandlers(runtime) {
1333
1110
  return refuse(response, who, 409, `this request identity already recorded a different note on this result (${earlier.path === null ? "no file" : `${earlier.path}${earlier.line === null ? "" : `:${earlier.line}`}`}: "${oneLineOf(earlier.note, 80)}") — go back; your edited words are kept as a new note, and the form will carry a new identity`, conflictBack);
1334
1111
  }
1335
1112
  }
1336
- // Land back AT the request-changes form with the note field ready —
1337
- // writing five notes in a row must cost five keystrokes of
1338
- // navigation, not five scrolls (arc 6, finding 5/6). The receipt
1339
- // names the request token, so the browser clears exactly the draft
1340
- // that landed and no other.
1341
1113
  const receipt = sourceKey === undefined ? "1" : request;
1342
1114
  return redirect(response, `${back}${back.includes("?") ? "&" : "?"}noted=${receipt}#request-changes`);
1343
1115
  }
1344
1116
  async function sessionEditorLinks(ctx) {
1345
1117
  const { who, response, posted } = ctx;
1346
1118
  const body = readForm(posted, CONSOLE_FORMS.editorLinks);
1347
- // The session half of the editor-link activation (arc 6, finding 1):
1348
- // only the person at the browser can say "this device holds the
1349
- // worktrees". Per-session, dies with the session, grants nothing —
1350
- // it only lets already-authorized pages RENDER vscode links.
1351
1119
  if (who.via !== "cookie")
1352
1120
  return refuse(response, who, 403, "editor links are a browser session's choice");
1353
1121
  if (options.editorLinks === undefined)
@@ -1362,10 +1130,6 @@ export function createTasksHandlers(runtime) {
1362
1130
  if (revise === null)
1363
1131
  return noPage(who, response);
1364
1132
  const body = readForm(posted, CONSOLE_FORMS.revise);
1365
- // Seal the live comment batch into ONE unapproved revision task with
1366
- // an immutable brief (M6.8). Deterministic — no model reads anything
1367
- // here — and every revision takes its own approval: comments can
1368
- // semantically widen work, and no path check can prove they did not.
1369
1133
  const id = Number(revise[1]);
1370
1134
  const found = store.getRun(id);
1371
1135
  if (found === null || !visible(taskRepoOf(found.taskRef))) {
@@ -1381,8 +1145,6 @@ export function createTasksHandlers(runtime) {
1381
1145
  return refuse(response, who, result.status, result.message, back);
1382
1146
  return redirect(response, revisionDestination(result.id, back));
1383
1147
  }
1384
- // Follow-ups on a result: Run checks on its exact commit (a worker runs the
1385
- // approved command once and seals the log), or file a task to add tests.
1386
1148
  const runFollowUp = (op) => async (ctx) => {
1387
1149
  const { url, who, response, now, posted } = ctx;
1388
1150
  const followUp = /^\/r\/([0-9]{1,15})\//.exec(url.pathname);
@@ -1393,7 +1155,6 @@ export function createTasksHandlers(runtime) {
1393
1155
  const found = store.getRun(id);
1394
1156
  if (found === null || !visible(taskRepoOf(found.taskRef)))
1395
1157
  return refuse(response, who, 404, "no such run");
1396
- // The task page that offered Run checks in place is a return target too: this run's own task, or its family's root.
1397
1158
  const back = resultReturnTarget(body.get("return"), id, runTasks(found.taskRef));
1398
1159
  if (who.via !== "cookie")
1399
1160
  return refuse(response, who, 403, "Sign in with a browser session to do this.", back);
@@ -1406,7 +1167,6 @@ export function createTasksHandlers(runtime) {
1406
1167
  const asked = requestFollowUpChecks(store, { runId: id, level, actor: who.name }, now);
1407
1168
  if (!asked.ok)
1408
1169
  return refuse(response, who, 409, asked.message, back);
1409
- // Back where it was asked: the task page's status row says the checks are running; a result page shows them under #follow-ups.
1410
1170
  return redirect(response, back.startsWith("/t/") ? back : `${back.split("#")[0]}#follow-ups`);
1411
1171
  }
1412
1172
  const filed = fileAddTestsTask(store, evidenceRoot, { runId: id, actor: who.name, filedVia: "console", ...(admissionList() === null ? {} : { admittedRepos: admissionList() }) }, now);
@@ -1419,10 +1179,6 @@ export function createTasksHandlers(runtime) {
1419
1179
  const draftRepair = /^\/r\/([0-9]{1,15})\/draft-repair$/.exec(url.pathname);
1420
1180
  if (draftRepair === null)
1421
1181
  return noPage(who, response);
1422
- // CI repair, suggestion-first (M8.18): a red episode never spawns an
1423
- // agent by itself — it EARNS a button, and the button creates one
1424
- // unapproved task through the same revision machinery as review
1425
- // comments. One draft per task/PR, ever: the merge blocker records it.
1426
1182
  const id = Number(draftRepair[1]);
1427
1183
  const found = store.getRun(id);
1428
1184
  if (found === null || !visible(taskRepoOf(found.taskRef))) {
@@ -1437,9 +1193,6 @@ export function createTasksHandlers(runtime) {
1437
1193
  }
1438
1194
  const sourceTaskId = store.externalIdFor(found.taskRef) ?? "?";
1439
1195
  const sourceScope = store.getScope(sourceTaskId);
1440
- // The observed episode, not the click: the brief binds the head the
1441
- // failure was SEEN on and when (audit C-2) — a PR that advanced since
1442
- // is a different failure, and the click time is not an observation.
1443
1196
  const episode = store.latestOpenCiEpisode(publication.githubRepo, publication.prNumber);
1444
1197
  const brief = {
1445
1198
  schema: 1,
@@ -1457,11 +1210,6 @@ export function createTasksHandlers(runtime) {
1457
1210
  const briefBytes = Buffer.from(JSON.stringify(brief, null, 2), "utf8");
1458
1211
  const briefName = `ci-repair-brief-${randomBytes(6).toString("hex")}.json`;
1459
1212
  const key = writeEvidenceFile(evidenceRoot, id, briefName, briefBytes);
1460
- // The SAME revision boundary the annotation road and the criterion
1461
- // repair use (contract handoff task 2): the inherited terms come from
1462
- // the source rows inside the seal; the scope read above only names
1463
- // the digest this draft was composed against.
1464
- // One draft per task/PR, ever: the PR's merge blocker names it, lifted or not, and is written in the seal's transaction.
1465
1213
  const sealed = store.transact(() => {
1466
1214
  const prior = store.raw().prepare("SELECT task_id FROM merge_blocker WHERE publication = ? AND task_id IS NOT NULL ORDER BY rowid LIMIT 1").get(publication.id);
1467
1215
  if (prior !== undefined)
@@ -1477,9 +1225,6 @@ export function createTasksHandlers(runtime) {
1477
1225
  commentIds: null,
1478
1226
  requestedBy: who.name,
1479
1227
  }, now);
1480
- // The merge blocker rides the SAME breath as the draft (merge grant,
1481
- // findings 3/12/13): while this repair exists, the source PR merges
1482
- // NOTHING — sticky until the operator's unblock act or the PR closes.
1483
1228
  if (result.ok)
1484
1229
  store.createMergeBlocker(publication.id, result.id, now);
1485
1230
  return result;
@@ -1496,11 +1241,6 @@ export function createTasksHandlers(runtime) {
1496
1241
  return noPage(who, response);
1497
1242
  const body = readForm(posted, CONSOLE_FORMS.resolveIncident);
1498
1243
  const id = Number(resolve[1]);
1499
- // The ceiling applies to incident mutation exactly as to every other
1500
- // resource (v3 review, finding 3): resolve incident → run → task, and
1501
- // an incident outside this server's scope does not exist here. The
1502
- // task id is captured BEFORE resolving — afterwards the incident is
1503
- // no longer open and could not be found again.
1504
1244
  const openRow = store.openIncidents().find(one => one.id === id);
1505
1245
  const incidentRun = openRow === undefined ? null : store.getRun(openRow.run);
1506
1246
  if (openRow !== undefined && incidentRun !== null && !visible(taskRepoOf(incidentRun.taskRef))) {
@@ -1512,7 +1252,6 @@ export function createTasksHandlers(runtime) {
1512
1252
  const back = body.get("return") === "inbox" ? "/" : openRow === undefined ? "/" : taskHref(openRow.taskId);
1513
1253
  return redirect(response, back);
1514
1254
  }
1515
- /** The compact recent-runs list for the master pane. */
1516
1255
  function runListPane(project, currentId) {
1517
1256
  const rows = store.listRunsBefore(null, 50, project);
1518
1257
  const live = liveRunIds(rows);
@@ -1521,15 +1260,11 @@ export function createTasksHandlers(runtime) {
1521
1260
  return html `<h2>Builds</h2>\n${rows.length === 0 ? html `<p class="meta">None yet</p>` : items}`;
1522
1261
  }
1523
1262
  async function peekFragment(runId, sessionKey, editorMode = false) {
1524
- // The cache and the in-flight coalescer hold the fragment's bytes (runtime's types); they are markup this made.
1525
1263
  const said = (message, final) => peekSay(message, final);
1526
1264
  const guarded = peekGuards(runId);
1527
1265
  if (!guarded.ok)
1528
1266
  return { status: 200, body: said(guarded.message, guarded.final === true) };
1529
1267
  const { run, worktree, epoch, entries } = guarded.admit;
1530
- // The cache and the in-flight coalescer both vary by LINK MODE (arc 6,
1531
- // finding 3): a linked fragment rendered for one session must never be
1532
- // served to a session that has not activated links on its device.
1533
1268
  const key = `${runId}:${run.baseRevision}:${epoch}:${editorMode ? "links" : "plain"}`;
1534
1269
  const cached = peekCache.get(key);
1535
1270
  if (cached !== undefined && Date.now() - cached.at <= PEEK_CACHE_TTL_MS) {
@@ -1539,7 +1274,6 @@ export function createTasksHandlers(runtime) {
1539
1274
  peekCache.delete(key);
1540
1275
  runtime.peekCacheBytes -= cached.bytes;
1541
1276
  }
1542
- // Coalesce per run; bound per session and globally (finding 10).
1543
1277
  const flightKey = `${runId}:${editorMode ? "links" : "plain"}`;
1544
1278
  const inFlight = peekInFlight.get(flightKey);
1545
1279
  if (inFlight !== undefined)
@@ -1552,9 +1286,6 @@ export function createTasksHandlers(runtime) {
1552
1286
  peekBySession.set(sessionKey, (peekBySession.get(sessionKey) ?? 0) + 1);
1553
1287
  const work = (async () => {
1554
1288
  const seen = await observeWorktree(worktree, entries.entries, PEEK_LIMITS);
1555
- // The fence, proved AGAIN after the walk (findings 16/28): the same
1556
- // run still open, the same claim, the SAME epoch — or the whole
1557
- // observation is discarded, never rendered, never cached.
1558
1289
  const after = peekGuards(runId);
1559
1290
  if (!after.ok || after.admit.epoch !== epoch) {
1560
1291
  return peekSay("the checkout changed hands mid-look — nothing is shown");
@@ -1572,9 +1303,6 @@ export function createTasksHandlers(runtime) {
1572
1303
  if (changed.length === 0 && deleted.length === 0 && fresh.total === 0) {
1573
1304
  parts.push(html `<p class="row">nothing has changed against the starting point yet</p>`);
1574
1305
  }
1575
- // A name is linked ONLY when sanitize provably changed nothing (arc 6,
1576
- // finding 3): a masked or normalized label must never carry an href
1577
- // that discloses what the mask hid. Collapsed labels never link.
1578
1306
  const shownName = (path) => peekName(path);
1579
1307
  const linkedName = (path) => {
1580
1308
  const shown = shownName(path);
@@ -1608,8 +1336,6 @@ export function createTasksHandlers(runtime) {
1608
1336
  parts.push(html `<p class="meta">${seen.partial}</p>`);
1609
1337
  let fragment = joinHtml(parts, "\n");
1610
1338
  if (Buffer.byteLength(htmlString(fragment)) > PEEK_FRAGMENT_BYTES) {
1611
- // The byte cap is enforced AFTER escaping (finding 32): an oversize
1612
- // rendering is replaced whole by its exact counts.
1613
1339
  fragment = html `<p class="meta">Best-effort look at ${stamp} UTC</p><p class="row">${changed.length} changed · ${deleted.length} deleted · ${fresh.total} new · ${unchecked.length} unverified — too much to render live; the final diff will hold the detail</p>`;
1614
1340
  }
1615
1341
  const bytes = Buffer.byteLength(htmlString(fragment));
@@ -1631,10 +1357,7 @@ export function createTasksHandlers(runtime) {
1631
1357
  peekBySession.set(sessionKey, left);
1632
1358
  }
1633
1359
  }
1634
- // ---- mutations -----------------------------------------------------------
1635
- function taskMutation(response, who, taskId, verb, posted, now,
1636
- /** Read only to shape an answer in place (answersInPlace), after the act's proofs. */
1637
- request = null) {
1360
+ function taskMutation(response, who, taskId, verb, posted, now, request = null) {
1638
1361
  const ref = store.lookupRef(taskId);
1639
1362
  if (ref === null || store.getTask(taskId) === null) {
1640
1363
  return refuse(response, who, 404, "no such task", "/tasks");
@@ -1645,21 +1368,13 @@ export function createTasksHandlers(runtime) {
1645
1368
  switch (verb) {
1646
1369
  case "steer": {
1647
1370
  const body = readForm(posted, CONSOLE_FORMS.taskSteer);
1648
- // Steering is a browser session's act, explicitly (arc 1 v2 §3):
1649
- // identify() accepts bearer credentials generically, and those are
1650
- // for machines — a person watching steers, cookie + CSRF only.
1651
1371
  if (who.via !== "cookie") {
1652
1372
  return refuse(response, who, 403, "steering is a browser session's act");
1653
1373
  }
1654
- // The same gates as a pause or a stop (the route's act scope already refuses a viewer; this says why).
1655
1374
  if (who.role !== "approver")
1656
1375
  return taskScreen(response, who, taskId, "your login can watch — sending an agent a note is an approver's act", 403);
1657
1376
  if (store.isDemo())
1658
1377
  return taskScreen(response, who, taskId, "the demo authorizes nothing", 403);
1659
- // From the Agents view, the note is for the exact run on screen (live-conversation.md §6): filed only while that
1660
- // run is still the task's live build, once per draft key. Nothing is filed on a refusal; the view keeps the draft.
1661
- // An unsent note from an attempt that ended, sent on to the task's next attempt from that agent's page: filed
1662
- // task-level, back to the same agent with its draft key so only a confirmed send clears the draft.
1663
1378
  if (body.has("after")) {
1664
1379
  const afterRaw = body.get("after") ?? "";
1665
1380
  const keyRaw = body.get("key") ?? "";
@@ -1669,9 +1384,7 @@ export function createTasksHandlers(runtime) {
1669
1384
  if (ended === null || ended.taskRef !== ref.id || !/^[A-Za-z0-9-]{8,64}$/.test(keyRaw) || body.has("run") || (afterBack !== null && afterBack !== "task" && afterFlow === null)) {
1670
1385
  return taskScreen(response, who, taskId, "that note did not say which agent it came from, so nothing was sent", 400);
1671
1386
  }
1672
- // The same receipt as a send to that run: a draft already filed while it ran comes back as sent, not twice.
1673
1387
  const filed = store.fileSteerNoteForRun(taskId, verifiedAuthor(who.name), body.get("note") ?? "", now, { run: ended.id, key: keyRaw, onward: true });
1674
- // From the task page or a flow card: back there with the draft's key (only that draft clears), or the refusal in words.
1675
1388
  if (afterBack !== null) {
1676
1389
  if (filed.ok)
1677
1390
  return redirect(response, afterFlow !== null ? `/flows/${afterFlow.flow}?card=${afterFlow.card}&sent=${keyRaw}` : `${taskHref(taskId)}?sent=${keyRaw}#steering`);
@@ -1681,7 +1394,6 @@ export function createTasksHandlers(runtime) {
1681
1394
  return redirect(response, `/agents?run=${ended.id}&said=steered-next&sent=${keyRaw}`);
1682
1395
  return redirect(response, `/agents?run=${ended.id}&said=${filed.reason === "task-finished" ? "steer-next-finished" : filed.reason === "key-reused" ? "steer-stale" : "steer-invalid"}`);
1683
1396
  }
1684
- // A form that asks for a run but names none properly is refused — never quietly filed unbound.
1685
1397
  if (body.get("return") === "agents" || body.get("return") === "task" || returnedFlow(body.get("return")) !== null || body.has("run") || body.has("key")) {
1686
1398
  const runRaw = body.get("run") ?? "";
1687
1399
  const keyRaw = body.get("key") ?? "";
@@ -1693,22 +1405,17 @@ export function createTasksHandlers(runtime) {
1693
1405
  const shown = store.getRun(Number(runRaw));
1694
1406
  if (shown === null || shown.taskRef !== ref.id)
1695
1407
  return taskScreen(response, who, taskId, "that run is not part of this task", 404);
1696
- // An attempt that takes no notes (a planner, a scout, a reviewer, one repairing its handoff) is never filed one:
1697
- // it would never read it (cockpit §4).
1698
1408
  const capability = steerCapabilityOf(store, shown.id, now);
1699
1409
  if (capability !== null && capability.send === null) {
1700
1410
  return from === "agents" ? redirect(response, `/agents?run=${shown.id}&said=steer-no-notes`) : taskScreen(response, who, taskId, capability.words, 409);
1701
1411
  }
1702
1412
  const bound = store.fileSteerNoteForRun(taskId, verifiedAuthor(who.name), body.get("note") ?? "", now, { run: shown.id, key: keyRaw });
1703
- // From the task page: back to its steering card, or the refusal in words (the page keeps nothing to restore).
1704
1413
  if (from === "task") {
1705
- // Back where it was written (the task page, or a flow card's task), with its draft's key: only that draft clears.
1706
1414
  if (bound.ok)
1707
1415
  return redirect(response, flowBack !== null ? `/flows/${flowBack.flow}?card=${flowBack.card}&sent=${keyRaw}` : `${taskHref(taskId)}?sent=${keyRaw}#steering`);
1708
1416
  return taskScreen(response, who, taskId, bound.reason === "attempt-ended" || bound.reason === "task-finished" ? "that attempt ended before your note, so nothing was sent — reload and send it to the current one"
1709
1417
  : bound.reason === "invalid-note" ? "that note will not store" : "that form was already used — reload and send it again", 409);
1710
1418
  }
1711
- // The draft's own key comes back: only that draft is cleared from the box.
1712
1419
  if (bound.ok)
1713
1420
  return redirect(response, `/agents?run=${shown.id}&said=steered&sent=${keyRaw}`);
1714
1421
  if (bound.reason === "attempt-ended" || bound.reason === "task-finished")
@@ -1717,7 +1424,6 @@ export function createTasksHandlers(runtime) {
1717
1424
  return redirect(response, `/agents?run=${shown.id}&said=steer-invalid`);
1718
1425
  return redirect(response, `/agents?run=${shown.id}&said=steer-stale`);
1719
1426
  }
1720
- // The session IS the verified principal here — cookie + CSRF proved it.
1721
1427
  const filed = store.fileSteerNote(taskId, verifiedAuthor(who.name), body.get("note") ?? "", now);
1722
1428
  if (!filed.ok) {
1723
1429
  const said = filed.reason === "task-finished"
@@ -1731,10 +1437,8 @@ export function createTasksHandlers(runtime) {
1731
1437
  }
1732
1438
  case "reply": {
1733
1439
  const body = readForm(posted, CONSOLE_FORMS.taskReply);
1734
- // A reply is steering, so it is a browser session's act too.
1735
1440
  if (who.via !== "cookie")
1736
1441
  return refuse(response, who, 403, "replying to an agent is a browser session's act");
1737
- // The same gates as a pause: the route's act scope already refuses a viewer; these say why, and the demo answers nothing.
1738
1442
  if (who.role !== "approver")
1739
1443
  return taskScreen(response, who, taskId, "your login can watch — replying to an agent is an approver's act", 403);
1740
1444
  if (store.isDemo())
@@ -1754,19 +1458,11 @@ export function createTasksHandlers(runtime) {
1754
1458
  if (reason.length > 200 || hasForbiddenControls(reason)) {
1755
1459
  return taskScreen(response, who, taskId, "that reason will not render, so it will not store", 400);
1756
1460
  }
1757
- // Operator-owned only, always: the form supplies a reason, never an
1758
- // owner. Decision, incident, and backoff holds are not reachable
1759
- // from here, whatever a request claims.
1760
1461
  store.hold(ref.id, reason, null, now);
1761
1462
  return redirect(response, taskHref(taskId));
1762
1463
  }
1763
1464
  case "block": {
1764
1465
  const body = readForm(posted, CONSOLE_FORMS.taskBlock);
1765
- // Chains are scheduling, not authority (chains-and-next review,
1766
- // finding 2): the edge decides WHEN the ready set admits the task;
1767
- // approval still decides WHAT may build. Both ends are re-proved
1768
- // here — existence and ceiling — and the
1769
- // cycle refusal comes from the store's own closure check.
1770
1466
  const on = (body.get("on") ?? "").trim();
1771
1467
  const blocker = on === "" ? null : store.getTask(on);
1772
1468
  const blockerRef = on === "" ? null : store.lookupRef(on);
@@ -1850,8 +1546,6 @@ export function createTasksHandlers(runtime) {
1850
1546
  }
1851
1547
  case "reopen": {
1852
1548
  const body = readForm(posted, CONSOLE_FORMS.taskReopen);
1853
- // Authenticated like every approving act: the session alone may
1854
- // read; resuming external work takes the password, typed again.
1855
1549
  const token = (body.get("token") ?? "").trim();
1856
1550
  const authenticated = token !== "" ? authenticateApprover(who, token) : null;
1857
1551
  if (authenticated === null || !authenticated.ok) {
@@ -1878,7 +1572,6 @@ export function createTasksHandlers(runtime) {
1878
1572
  return redirect(response, taskHref(taskId));
1879
1573
  }
1880
1574
  case "stop-carrying": {
1881
- // One click, any active approver (release-once.md): later commits of this release ask again. Only ever stricter.
1882
1575
  const found = releaseAuthorityOfTask(store, taskId);
1883
1576
  if (found === null)
1884
1577
  return taskScreen(response, who, taskId, "This task isn't part of a release.", 409);
@@ -1889,29 +1582,33 @@ export function createTasksHandlers(runtime) {
1889
1582
  }
1890
1583
  case "requeue": {
1891
1584
  const body = readForm(posted, CONSOLE_FORMS.taskRequeue);
1892
- // Retry may carry a note for the next attempt: the same steering note, checked before anything changes.
1893
1585
  const note = (body.get("note") ?? "").trim();
1894
1586
  if (note !== "" && who.via !== "cookie")
1895
1587
  return refuse(response, who, 403, "steering is a browser session's act");
1896
1588
  if (note !== "" && !validateNote(note).ok)
1897
1589
  return taskScreen(response, who, taskId, "that note will not store, so nothing was retried", 400);
1898
- const requeued = store.requeueTask(taskId, who.name, now);
1899
- if (!requeued.ok) {
1900
- return taskScreen(response, who, taskId, `not requeued: ${requeued.reason}`, 409);
1590
+ let replayed = false;
1591
+ if (who.via === "cookie" && who.authority === "local-owner") {
1592
+ const retried = localOwnerRetry(store, taskId, body.get("run"), body.get("digest"), now);
1593
+ if (!retried.ok)
1594
+ return taskScreen(response, who, taskId, retried.message, retried.status);
1595
+ replayed = retried.replayed;
1596
+ }
1597
+ else {
1598
+ const requeued = store.requeueTask(taskId, who.name, now);
1599
+ if (!requeued.ok) {
1600
+ return taskScreen(response, who, taskId, `not requeued: ${requeued.reason}`, 409);
1601
+ }
1901
1602
  }
1902
- if (note !== "") {
1603
+ if (note !== "" && !replayed) {
1903
1604
  const filed = store.fileSteerNote(taskId, verifiedAuthor(who.name), note, now);
1904
1605
  if (!filed.ok)
1905
1606
  return taskScreen(response, who, taskId, "Retried. The note wasn't saved; add it under Steering.", 409);
1906
1607
  }
1907
- // Allow-listed return only — never an arbitrary URL from the form.
1908
1608
  return redirect(response, body.get("return") === "inbox" || body.get("return") === "next" ? "/" : taskHref(taskId));
1909
1609
  }
1910
1610
  case "follow-up": {
1911
1611
  const body = readForm(posted, CONSOLE_FORMS.taskFollowUp);
1912
- // A scout's proposed follow-up, filed by the operator's tap (mate
1913
- // arc §10): the ONE filing door, this task's repository, the scope
1914
- // text stamped as the scout's — mode coverage never seals it.
1915
1612
  const indexRaw = body.get("index") ?? "";
1916
1613
  if (!/^[0-9]{1,2}$/.test(indexRaw))
1917
1614
  return taskScreen(response, who, taskId, "which follow-up?", 400);
@@ -1925,10 +1622,6 @@ export function createTasksHandlers(runtime) {
1925
1622
  return taskScreen(response, who, taskId, "this task has no repository — file the follow-up by hand", 409);
1926
1623
  if (!visible(ref.repo))
1927
1624
  return taskScreen(response, who, taskId, "that repository is outside what this server shows", 403);
1928
- // Idempotent by construction (v4 review, finding 10): the filing's
1929
- // id is derived from the source task, the report's run, and the
1930
- // follow-up's place — a retried POST lands on the task the first
1931
- // one filed instead of minting a twin.
1932
1625
  const followUpId = `${taskId.slice(0, 40)}-r${view.run}-f${Number(indexRaw) + 1}`;
1933
1626
  if (store.getTask(followUpId) !== null)
1934
1627
  return redirect(response, taskHref(followUpId));
@@ -1937,10 +1630,6 @@ export function createTasksHandlers(runtime) {
1937
1630
  title: followUp.title,
1938
1631
  repo: ref.repo,
1939
1632
  goal: followUp.goal,
1940
- // v39: the scout's report format does not yet draft a rubric
1941
- // per follow-up — a placeholder names the operator's own
1942
- // review as the outstanding work, the same posture a
1943
- // coordinator's bare intent takes.
1944
1633
  acceptance: PLACEHOLDER_RUBRIC,
1945
1634
  filedVia: "console", filedBy: { name: who.name, kind: "person" },
1946
1635
  proposedVia: "scout",
@@ -1954,14 +1643,15 @@ export function createTasksHandlers(runtime) {
1954
1643
  return redirect(response, taskHref(filed.id));
1955
1644
  }
1956
1645
  case "plan": {
1957
- // The operator's explicit ask, refused transactionally when the
1958
- // moment has passed — approved scope, live claim, or a plan
1959
- // already under way (Codex planning review's requestPlan guard).
1646
+ if (who.via === "cookie" && who.authority === "local-owner") {
1647
+ const asked = localOwnerPlan(store, taskId, readForm(posted, CONSOLE_FORMS.taskPlan).get("source"), now);
1648
+ return asked.ok ? redirect(response, taskHref(taskId)) : taskScreen(response, who, taskId, asked.message, asked.status);
1649
+ }
1960
1650
  const asked = store.requestPlan(ref.id, now);
1961
1651
  if (!asked.ok) {
1962
1652
  return taskScreen(response, who, taskId, `not planned: ${asked.reason}`, 409);
1963
1653
  }
1964
- if (who.via === "cookie")
1654
+ if (who.via === "cookie" && who.authority === "full")
1965
1655
  authorizePlanUnderMode(store, taskId, who.name, now);
1966
1656
  return redirect(response, taskHref(taskId));
1967
1657
  }
@@ -2025,10 +1715,6 @@ export function createTasksHandlers(runtime) {
2025
1715
  case "accept-revision":
2026
1716
  case "reject-revision": {
2027
1717
  const body = readForm(posted, CONSOLE_FORMS.taskRevision);
2028
- // Adaptive execution plans (v44): resolving a revision the builder
2029
- // filed while its authority snapshot no longer matched the run it
2030
- // started under — the ONLY road a 'blocked' plan_revision reaches,
2031
- // since a plan-only proposal auto-applies without ever pausing here.
2032
1718
  if (who.via !== "cookie") {
2033
1719
  return refuse(response, who, 403, "resolving a plan revision is a browser session's act");
2034
1720
  }
@@ -2039,9 +1725,6 @@ export function createTasksHandlers(runtime) {
2039
1725
  }
2040
1726
  const outcome = verb === "accept-revision" ? "applied" : "rejected";
2041
1727
  if (outcome === "applied") {
2042
- // Accepting a revision that changed signed scope or publication
2043
- // authority takes the password ceremony again — the same act
2044
- // that would be required to approve that authority from scratch.
2045
1728
  const token = (body.get("token") ?? "").trim();
2046
1729
  if (!authenticateApprover(who, token).ok) {
2047
1730
  return taskScreen(response, who, taskId, "accepting this revision takes your password, typed again", 403);
@@ -2070,23 +1753,10 @@ export function createTasksHandlers(runtime) {
2070
1753
  }
2071
1754
  case "route": {
2072
1755
  const body = readForm(posted, CONSOLE_FORMS.taskRoute);
2073
- // THE AGENTS EDIT (v47): an approver's session sets the size,
2074
- // overrides one role to an exact agent, or clears an override — ONE
2075
- // authenticated transaction in the store that CAS-checks the scope
2076
- // digest the form rendered (empty = "I saw no scope"), records the
2077
- // change under this name, reconciles the planner pin, re-files the
2078
- // scope so a sealed route goes visibly stale, and re-requests a
2079
- // drafted plan when the planner changed. The viewer gate above
2080
- // already refused a watcher; a live claim refuses
2081
- // inside the transaction.
2082
1756
  const sizeGiven = body.get("size");
2083
1757
  const riskyGiven = body.getAll("risky");
2084
1758
  const phaseGiven = body.get("phase");
2085
1759
  const clearGiven = body.get("clear-phase");
2086
- // The agent arrives as the form's `provider|model` choice (v48) or,
2087
- // for older clients, as separate fields — either way it must be one
2088
- // of the CONFIGURED, role-valid choices right now: the form offers
2089
- // nothing else, and the server believes nothing else.
2090
1760
  const agentGiven = (body.get("agent") ?? "").trim();
2091
1761
  const providerGiven = agentGiven === "" ? body.get("provider") : agentGiven.slice(0, agentGiven.indexOf("|") === -1 ? agentGiven.length : agentGiven.indexOf("|"));
2092
1762
  const modelGiven = agentGiven === "" ? (body.get("model") ?? "").trim() : agentGiven.indexOf("|") === -1 ? "" : agentGiven.slice(agentGiven.indexOf("|") + 1).trim();
@@ -2098,7 +1768,6 @@ export function createTasksHandlers(runtime) {
2098
1768
  return taskScreen(response, who, taskId, "size is small, medium, or large", 400);
2099
1769
  if (riskyGiven.some(one => one !== "yes" && one !== "no"))
2100
1770
  return taskScreen(response, who, taskId, "risky is yes or no", 400);
2101
- // A size keeps the task's risky flag unless the form says otherwise; marking risky keeps the size.
2102
1771
  const sizeEdit = sizeGiven === null && riskyGiven.length === 0 ? undefined : {
2103
1772
  size: sizeGiven !== null && isTaskSize(sizeGiven) ? sizeGiven : ref.sizing?.size ?? "medium",
2104
1773
  risky: riskyGiven.includes("yes") ? true : riskyGiven.includes("no") ? false : ref.sizing?.risky ?? false,
@@ -2118,17 +1787,12 @@ export function createTasksHandlers(runtime) {
2118
1787
  if ((phaseGiven === "plan" || phaseGiven === "review") && isAcpProvider(providerGiven))
2119
1788
  return taskScreen(response, who, taskId, `${ACP_AGENTS[providerGiven].name} builds and repairs only — choose another agent to ${phaseGiven}`, 400);
2120
1789
  }
2121
- // The configured-choice proof lives INSIDE the edit transaction
2122
- // (`configured`): the pair is held to the role's choices under the
2123
- // configuration standing at that instant, and a stale choice
2124
- // mutates nothing.
2125
1790
  const edited = store.editTaskRoute(ref.id, {
2126
1791
  by: who.name,
2127
1792
  authenticate: () => {
2128
1793
  const account = store.accountOf(who.name);
2129
1794
  return account !== null && account.revokedAt === null && account.role === "approver" ? { ok: true } : { ok: false, reason: "your login is no longer an approver" };
2130
1795
  },
2131
- // A person's size replaces the classifier's; the risky flag rides with it.
2132
1796
  ...(sizeEdit === undefined ? {} : { size: sizeEdit }),
2133
1797
  ...(phase === null
2134
1798
  ? {}
@@ -2139,7 +1803,6 @@ export function createTasksHandlers(runtime) {
2139
1803
  if (!edited.ok) {
2140
1804
  return taskScreen(response, who, taskId, edited.reason === "not-configured" ? `agents not changed: ${edited.detail}` : edited.detail, edited.reason === "unauthenticated" ? 403 : edited.reason === "nothing" || edited.reason === "not-configured" ? 400 : 409);
2141
1805
  }
2142
- // v102: changing how a task runs is authoring it — the requester rule then refuses this person too.
2143
1806
  const routed = store.getScope(taskId);
2144
1807
  if (routed !== null)
2145
1808
  store.recordScopeAuthor(taskId, routed.digest, who.name, now);
@@ -2173,14 +1836,11 @@ export function createTasksHandlers(runtime) {
2173
1836
  : qualityGiven === "default"
2174
1837
  ? "default"
2175
1838
  : ref.qualityMode ?? store.qualityDefault().mode;
2176
- // The optional per-attempt dollar cap (v15) rides the same form.
2177
1839
  const budgetGiven = (body.get("budget-usd") ?? "").trim();
2178
1840
  const budgetUsd = budgetGiven === "" ? null : Number(budgetGiven);
2179
1841
  if (budgetUsd !== null && (!Number.isFinite(budgetUsd) || budgetUsd <= 0)) {
2180
1842
  return taskScreen(response, who, taskId, "the dollar cap is a positive amount", 400);
2181
1843
  }
2182
- // The approval sheet's in-place editor carries the cap it was shown
2183
- // exactly, in millionths, and "none" for no limit (never a default).
2184
1844
  const exactBudgetGiven = body.get("budget-microusd");
2185
1845
  const exactBudget = exactBudgetGiven === null ? undefined : exactBudgetGiven === "none" ? null : /^[1-9][0-9]{0,14}$/.test(exactBudgetGiven) ? Number(exactBudgetGiven) : NaN;
2186
1846
  if (Number.isNaN(exactBudget))
@@ -2189,13 +1849,6 @@ export function createTasksHandlers(runtime) {
2189
1849
  let saved;
2190
1850
  try {
2191
1851
  saved = store.transact(() => {
2192
- // C1/M3: the signer's own credentialed filing auto-approves —
2193
- // coverage is asked INSIDE this transaction, the escalated
2194
- // default and budget ride the filing, and the seal commits
2195
- // atomically with it.
2196
- // COOKIE ONLY (C1's channel table; surfaces round 1, finding 1):
2197
- // bearer credentials are for machines, and a machine road must
2198
- // never spend the signer's mode.
2199
1852
  const coverage = who.via === "cookie"
2200
1853
  ? modeFilingCoverage(store, ref.repo, who.name, now)
2201
1854
  : null;
@@ -2205,7 +1858,6 @@ export function createTasksHandlers(runtime) {
2205
1858
  goal: body.has("goal-brief") ? `${(body.get("goal") ?? "").trim()}${body.get("goal-brief")}` : body.get("goal") ?? "",
2206
1859
  outOfScope: body.get("not") ?? null,
2207
1860
  touches: (body.get("touches") ?? "").split(/[\n,]/),
2208
- // The approval sheet's in-place editor sends Done when line by line.
2209
1861
  acceptance: inPlace
2210
1862
  ? requirementsFromEditor(body, before?.acceptance ?? [])
2211
1863
  : acceptanceLinesToInput((body.get("acceptance") ?? "").split("\n")),
@@ -2230,9 +1882,6 @@ export function createTasksHandlers(runtime) {
2230
1882
  message: proposed.message ?? (proposed.reason === "acceptance-required" ? "Not saved: add at least one requirement under Done when." : `scope not saved: ${proposed.reason}`),
2231
1883
  };
2232
1884
  }
2233
- // Editing the plan in place never changes what the agent may do:
2234
- // a save that would (a legacy setting, a newer policy or mode)
2235
- // rolls back whole.
2236
1885
  if (inPlace && before?.profile != null && proposed.scope.profile != null && levelOfProfile(before.profile) !== levelOfProfile(proposed.scope.profile)) {
2237
1886
  throw new PermissionsWouldChange();
2238
1887
  }
@@ -2243,7 +1892,6 @@ export function createTasksHandlers(runtime) {
2243
1892
  const filedScope = store.getScope(taskId);
2244
1893
  if (filedScope?.profileState === "resolved") {
2245
1894
  const sealedUnderMode = store.sealScopeApproval(taskId, who.name, now, {}, { kind: "mode", modeDigest: coverage.digest });
2246
- // The quarantine speaks at the caller (review finding 7).
2247
1895
  if (!sealedUnderMode) {
2248
1896
  return { ok: false, status: 200, message: "scope saved — coordinator-filed: mode coverage cannot admit it; sign the scope" };
2249
1897
  }
@@ -2258,8 +1906,6 @@ export function createTasksHandlers(runtime) {
2258
1906
  saved = { ok: false, status: 409, message: "Not saved: this would change what the agent may do. Change permissions in Details, under edit the scope." };
2259
1907
  }
2260
1908
  if (!saved.ok) {
2261
- // Refused because the plan moved on: the draft comes back with the version now on file, so saving it
2262
- // again (having read the reason) can succeed instead of being refused the same way.
2263
1909
  const draft = new URLSearchParams(body.sent);
2264
1910
  if (saved.status === 409)
2265
1911
  draft.set("sawDigest", store.getScope(taskId)?.digest ?? "");
@@ -2277,13 +1923,10 @@ export function createTasksHandlers(runtime) {
2277
1923
  : requestedReturn === null
2278
1924
  ? taskHref(taskId)
2279
1925
  : safeChatReturn(requestedReturn);
2280
- // The release sheet's Approve release (trusted-release-reports.md A7): the same door, its own page for words.
2281
1926
  const sheet = body.get("sheet") === "release";
2282
- // Each caller names its outcome (live-pages-and-home.md B2.3); none is inferred from the status.
2283
1927
  const approvalProblem = (outcome, message, status) => {
2284
1928
  if (sheet)
2285
1929
  return releaseSheet.sheetScreen({ who, response, project: null }, taskId, message, status);
2286
- // Asked in place: the same proofs ran, only the answer's shape differs.
2287
1930
  if (answersInPlace(request))
2288
1931
  return answerApprovalInPlace(response, outcome, message, status);
2289
1932
  if (requestedReturn !== null && requestedReturn !== "next") {
@@ -2295,23 +1938,16 @@ export function createTasksHandlers(runtime) {
2295
1938
  if (approvingRef?.plan === "requested") {
2296
1939
  return approvalProblem("refused", "approval is blocked while planning is in progress — review the drafted plan first", 409);
2297
1940
  }
2298
- // Step-up: the session got you here; only the token agrees. The
2299
- // digest names what was seen; the nonce proves this exact form was
2300
- // rendered to this approver and is spent either way.
2301
1941
  const digest = body.get("digest") ?? "";
2302
1942
  const token = body.get("token") ?? "";
2303
1943
  const nonce = body.get("nonce") ?? "";
2304
1944
  if (!consumeApprovalNonce(nonce, who.name, taskId, digest)) {
2305
1945
  return approvalProblem("refused", "that approval form is stale — read it again", 409);
2306
1946
  }
2307
- // An empty password stands for an explicit identity-provider re-check not yet spent, or (cockpit B2) a password
2308
- // remembered on this session; approve() decides whether these terms may stand on a remembered one.
2309
- // Easy-start C5: a laptop's local owner approves eligible work with no password (approve() proves it again).
2310
1947
  if (token === "" && !passwordlessSessionFor(store, who.name) && !ssoNowAvailable(who.name) && withFreshness("approve-standard", () => freshnessFor(who.name)) === null
2311
1948
  && !(who.authority === "local-owner" && localApprovalEligible(store, who.name, taskId).ok)) {
2312
1949
  return approvalProblem("refused", "approval requires your password, typed again", 400);
2313
1950
  }
2314
- // The sheet binds the release card's digest (the nonce was minted for it): the shared card wrapper decides.
2315
1951
  if (sheet)
2316
1952
  return releaseSheet.approveFromSheet({ who, response, project: null }, taskId, digest, token);
2317
1953
  const scopeRow = store.getScope(taskId);
@@ -2322,21 +1958,14 @@ export function createTasksHandlers(runtime) {
2322
1958
  if (digest !== expectedDigest) {
2323
1959
  return approvalProblem("refused", "the scope or plan changed while this form was open — read the latest version and approve again", 409);
2324
1960
  }
2325
- // A revision approves ONLY against a brief that still verifies
2326
- // (Codex M5-M8 audit, IV-3): the batch the screen restated must be
2327
- // provably the batch on disk at the moment of the yes — a brief
2328
- // deleted or corrupted between render and click blocks the
2329
- // approval instead of silently approving comment-free work.
2330
1961
  if (approvingRef !== null && approvingRef.revisionBriefArtifact !== null) {
2331
1962
  const view = revisionViewOf(approvingRef);
2332
1963
  if (view !== null && "problem" in view) {
2333
1964
  return approvalProblem("refused", `approval is blocked: ${view.problem}`, 409);
2334
1965
  }
2335
1966
  }
2336
- // A re-check is spent only if this yes is kept (sealed, or a protected-work vote recorded).
2337
1967
  const approved = spendingOnlyOnSuccess(() => withFreshness("approve-standard", () => approveScope(store, taskId, who.name, now, scopeRow.digest, token)), result => !result.ok && !(result.reason === "second-approver" && !result.already));
2338
1968
  if (!approved.ok) {
2339
- // v102: a first yes on protected work is recorded, not refused — the page says who else is needed.
2340
1969
  if (approved.reason === "second-approver")
2341
1970
  return approvalProblem("vote", gateWords({ verdict: "vote", have: approved.have, need: 2, already: approved.already }), 200);
2342
1971
  if (approved.reason === "policy")
@@ -2344,13 +1973,9 @@ export function createTasksHandlers(runtime) {
2344
1973
  const status = approved.reason === "changed" || approved.reason === "unrouted" ? 409 : 403;
2345
1974
  return approvalProblem("refused", approveRefusalWords(approved.reason), status);
2346
1975
  }
2347
- // Approve & build again (the plan was rewritten after a build): the same yes requeues, only for the build the
2348
- // sheet named, and only while it is still the task's latest result, made to an earlier plan than this one.
2349
1976
  const rebuildRaw = body.get("rebuild") ?? "";
2350
1977
  if (rebuildRaw !== "") {
2351
1978
  const named = /^[0-9]{1,15}$/.test(rebuildRaw) ? store.getRun(Number(rebuildRaw)) : null;
2352
- // Built to an earlier plan than the one just approved (the scope this approval sealed, scopeRow.digest);
2353
- // requeueTask re-proves, in its own transaction, that it is still the latest result and that scope approved.
2354
1979
  const offered = named != null && named.taskRef === ref.id && named.role === "builder" && !!named.scopeDigest && named.scopeDigest !== scopeRow.digest;
2355
1980
  const requeued = offered ? store.requeueTask(taskId, who.name, now, { run: named.id, scopeDigest: scopeRow.digest }) : null;
2356
1981
  if (requeued === null || (!requeued.ok && requeued.reason === "moved"))
@@ -2364,13 +1989,9 @@ export function createTasksHandlers(runtime) {
2364
1989
  }
2365
1990
  case "accept-proof": {
2366
1991
  const body = readForm(posted, CONSOLE_FORMS.taskAcceptProof);
2367
- // Accepting is a person's act, like approving a scope (Priority
2368
- // 2): a cookie session only, never a bearer credential.
2369
1992
  if (who.via !== "cookie") {
2370
1993
  return refuse(response, who, 403, "accepting a proof is a browser session's act");
2371
1994
  }
2372
- // v40 fix: a reviewer run is never the attempt whose proof is
2373
- // being accepted.
2374
1995
  const latest = store.runsFor(ref.id).find(runIsTaskResult);
2375
1996
  if (latest === undefined) {
2376
1997
  return taskScreen(response, who, taskId, "this task has no finished attempt to accept", 404);
@@ -2388,9 +2009,7 @@ export function createTasksHandlers(runtime) {
2388
2009
  }
2389
2010
  note = validated.note;
2390
2011
  }
2391
- // A failed task's result is accepted only anyway, on purpose: with a reason.
2392
2012
  if (note === null && store.getTask(taskId)?.state === "failed") {
2393
- // Posted from the result page: back there, where the reason field is, with the refusal said on it.
2394
2013
  const back = body.get("return") === null ? null : safeReturn(body.get("return"));
2395
2014
  if (back !== null && back.startsWith("/review?"))
2396
2015
  return redirect(response, withRefusal(back, "reason"));
@@ -2401,7 +2020,6 @@ export function createTasksHandlers(runtime) {
2401
2020
  }
2402
2021
  case "complete": {
2403
2022
  const body = readForm(posted, CONSOLE_FORMS.taskComplete);
2404
- // The row admits only an approver's browser session; the principal re-proves that session's standing.
2405
2023
  const principal = who.via === "cookie" ? leadPrincipal(who) : null;
2406
2024
  if (principal === null)
2407
2025
  return refuse(response, who, 403, "Your access changed. Sign in again.");
@@ -2412,8 +2030,6 @@ export function createTasksHandlers(runtime) {
2412
2030
  return taskScreen(response, who, taskId, "This result changed. Open the current result before marking it complete.", 409);
2413
2031
  }
2414
2032
  if (body.get("accept") === "1") {
2415
- // Accept and finish: the person's acceptance and the completion of what it accepted, in one request
2416
- // and one transaction. The receipt named is the one read, before accepting.
2417
2033
  const rawNote = (body.get("note") ?? "").trim();
2418
2034
  let note = null;
2419
2035
  if (rawNote !== "") {
@@ -2429,8 +2045,6 @@ export function createTasksHandlers(runtime) {
2429
2045
  return redirect(response, publish ? `${taskHref(familyOf(taskId)?.root.id ?? taskId)}#merge` : body.get("return") === null ? reviewHref(taskId, Number(namedRun)) : safeReturn(body.get("return")));
2430
2046
  }
2431
2047
  if (body.get("publish") === "1") {
2432
- // "Complete and open a pull request": the same exact-receipt completion, plus the owed PR for this
2433
- // exact commit in one transaction. The watch process pushes and opens it; the task shows its progress.
2434
2048
  const opened = completeAndOpenPullRequest(store, { taskId, digest, runId: Number(namedRun), who: principal, root: evidenceRoot }, now);
2435
2049
  if (!opened.ok)
2436
2050
  return taskScreen(response, who, taskId, opened.message, 409);
@@ -2439,7 +2053,6 @@ export function createTasksHandlers(runtime) {
2439
2053
  const completed = checkAssignmentAsOperator(store, taskId, digest, principal, now, evidenceRoot);
2440
2054
  if (!completed.ok)
2441
2055
  return taskScreen(response, who, taskId, completed.message, 409);
2442
- // Back where it was completed (the task page's Result tab, or the result page), as Accept and finish does.
2443
2056
  return redirect(response, body.get("return") === null ? reviewHref(taskId, Number(namedRun)) : safeReturn(body.get("return")));
2444
2057
  }
2445
2058
  case "retry-review": {
@@ -2447,12 +2060,6 @@ export function createTasksHandlers(runtime) {
2447
2060
  }
2448
2061
  case "stop": {
2449
2062
  const body = readForm(posted, CONSOLE_FORMS.taskStop);
2450
- // The exact-run stop (v52): a browser session's act, an approver's
2451
- // act, naming ONE run. The store's transaction proves the run is
2452
- // this task's current live attempt and records who asked before
2453
- // any process is signalled; the answer is "stopping", never
2454
- // "stopped". A repeated post is the same request; a stale one (a
2455
- // finished run, a successor) is refused in words.
2456
2063
  if (who.via !== "cookie")
2457
2064
  return refuse(response, who, 403, "stopping a task is a browser session's act");
2458
2065
  if (who.role !== "approver")
@@ -2474,7 +2081,6 @@ export function createTasksHandlers(runtime) {
2474
2081
  return taskScreen(response, who, taskId, words[asked.reason] ?? asked.detail, 409);
2475
2082
  }
2476
2083
  const back = body.get("return") ?? "";
2477
- // From the Agents board: back to the same agent, saying what happens now.
2478
2084
  if (back === "agents")
2479
2085
  return redirect(response, `/agents?run=${Number(named)}&said=stopping`);
2480
2086
  const stopFlow = returnedFlow(back);
@@ -2484,10 +2090,6 @@ export function createTasksHandlers(runtime) {
2484
2090
  }
2485
2091
  case "pause": {
2486
2092
  const body = readForm(posted, CONSOLE_FORMS.taskPause);
2487
- // Pause, and Pause and steer (live steering): a browser session's act, an approver's act, naming the ONE run
2488
- // the page showed under the page's own request id. It stops the running Claude build's turn and keeps the
2489
- // build; a note that rides along is filed in the same transaction and sent right after. mode=resume continues a
2490
- // paused build with no note. Never a stop.
2491
2093
  if (who.via !== "cookie")
2492
2094
  return refuse(response, who, 403, "pausing a build is a browser session's act");
2493
2095
  if (who.role !== "approver")
@@ -2498,7 +2100,6 @@ export function createTasksHandlers(runtime) {
2498
2100
  if (!/^[0-9]{1,15}$/.test(named))
2499
2101
  return taskScreen(response, who, taskId, "which build? a pause names one exact run", 400);
2500
2102
  const note = (body.get("note") ?? "").trim();
2501
- // Resume: the paused build goes on where it stopped; no note is filed.
2502
2103
  const asked = body.get("mode") === "resume"
2503
2104
  ? store.requestResume({ taskId, runId: Number(named), by: verifiedAuthor(who.name), via: "web", requestId: body.get("request") ?? "" }, now)
2504
2105
  : store.requestPause({ taskId, runId: Number(named), by: verifiedAuthor(who.name), via: "web", requestId: body.get("request") ?? "", ...(note === "" ? {} : { note }) }, now);
@@ -2514,14 +2115,10 @@ export function createTasksHandlers(runtime) {
2514
2115
  return taskScreen(response, who, taskId, words[asked.reason] ?? asked.detail, asked.reason === "invalid-note" ? 400 : 409);
2515
2116
  }
2516
2117
  const back = body.get("return") ?? "";
2517
- // A note that rode along came from a composer's draft: its key comes back, so only that draft clears.
2518
2118
  const keyRaw = body.get("key") ?? "";
2519
- // Only a note this request actually stored clears its draft: a repeated request answers with the note it stored
2520
- // the first time, and a draft edited since is not that note.
2521
2119
  const storedId = "note" in asked && typeof asked.note === "number" ? asked.note : null;
2522
2120
  const stored = storedId === null ? null : store.handle.prepare("SELECT note FROM task_steer WHERE id = ?").get(storedId)?.["note"];
2523
2121
  const sent = note !== "" && /^[A-Za-z0-9-]{8,64}$/.test(keyRaw) && typeof stored === "string" && stored.trim() === note ? keyRaw : null;
2524
- // A note that rode along but is not the one this request stored (a reused form): said plainly, the draft kept.
2525
2122
  if (note !== "" && (typeof stored !== "string" || stored.trim() !== note)) {
2526
2123
  if (back === "agents")
2527
2124
  return redirect(response, `/agents?run=${Number(named)}&said=pause-note-stale`);
@@ -2542,11 +2139,6 @@ export function createTasksHandlers(runtime) {
2542
2139
  }
2543
2140
  case "resume": {
2544
2141
  const body = readForm(posted, CONSOLE_FORMS.taskResume);
2545
- // The resume itself (v52): password typed again + the durable nonce
2546
- // consumed INSIDE the store's resume transaction against the digest
2547
- // re-derived from live state. A replay finds the nonce spent; a
2548
- // changed approval finds the digest moved; a successor attempt finds
2549
- // the run superseded — each refuses without starting work; a submitted nonce remains one-shot.
2550
2142
  if (who.via !== "cookie")
2551
2143
  return refuse(response, who, 403, "resuming a task is a browser session's act");
2552
2144
  if (who.role !== "approver")
@@ -2594,10 +2186,6 @@ export function createTasksHandlers(runtime) {
2594
2186
  return refuse(response, who, 404, "That action isn't available here.", taskHref(taskId));
2595
2187
  }
2596
2188
  }
2597
- /** The queue as a region: dispatch order per column, drag handles and
2598
- * all — the /queue page's body, and the board's "order" view (the one
2599
- * place dragging exists, because reordering and reserving are scheduling,
2600
- * never authority). */
2601
2189
  function queueRegionFor(project, csrf, revision, now) {
2602
2190
  const tasks = store.queueScoped(project, now).map(one => ({
2603
2191
  ...one,
@@ -2620,23 +2208,12 @@ export function createTasksHandlers(runtime) {
2620
2208
  }));
2621
2209
  return queueBody(tasks, workers, revision, store.queueRevision());
2622
2210
  }
2623
- /** An OBSERVED CI failure on a completed row's PR — the open episode the
2624
- * watcher recorded for exactly that repository and number; never a guess
2625
- * from quiet. One indexed publication read per row that has a PR. */
2626
2211
  function ciFailingFor(runId, prNumber) {
2627
2212
  if (runId === null || prNumber === null)
2628
2213
  return false;
2629
2214
  const publication = store.publicationForRun(runId);
2630
2215
  return publication !== null && publication.prNumber === prNumber && store.hasOpenCiEpisode(publication.githubRepo, prNumber);
2631
2216
  }
2632
- /**
2633
- * One completed row by task id, for a `?result=` deep link the bounded
2634
- * queue could not show — the done list's own predicate, re-proved per
2635
- * read: the task is done, sits in this project (or in none), and its
2636
- * repository passes the ceiling; the result run is the newest finished
2637
- * built/no-change builder or scout attempt. Anything else is
2638
- * null, and null reads exactly like a task that never existed.
2639
- */
2640
2217
  function completedRowFor(taskId, project) {
2641
2218
  const family = familyOf(taskId);
2642
2219
  if (family === null)
@@ -2652,15 +2229,6 @@ export function createTasksHandlers(runtime) {
2652
2229
  (one.role === "builder" || one.role === "scout")) ?? null;
2653
2230
  return resultRowOf(task, ref.repo, family.problem, run);
2654
2231
  }
2655
- /**
2656
- * A build attempt that didn't deliver a result (failed, refused, stopped,
2657
- * never finished) still has a result page: its changes, its checks and what
2658
- * went wrong. The row for one: the run named by `runId` when it is an ended
2659
- * builder or scout attempt of this task that isn't a delivered result, or a
2660
- * failed task's latest attempt; with no run named, that latest attempt. The
2661
- * same admission as a completed row: in this project (or none) and inside
2662
- * the ceiling. Null otherwise, which reads like a task that never existed.
2663
- */
2664
2232
  function attemptRowFor(taskId, runId, project) {
2665
2233
  const family = familyOf(taskId);
2666
2234
  const task = store.getTask(taskId);
@@ -2672,7 +2240,6 @@ export function createTasksHandlers(runtime) {
2672
2240
  const attempts = store.runsFor(ref.id).filter(one => (one.role === "builder" || one.role === "scout") && (one.finishedAt !== null || one.outcome !== null));
2673
2241
  const latest = task.state === "failed" ? latestFinishedAttempt(attempts) : null;
2674
2242
  const run = runId !== null ? attempts.find(one => one.id === runId) ?? null : latest;
2675
- // A delivered result has its completed row; a failed task's latest attempt is what failed, whatever it ended as.
2676
2243
  if (run === null || runIsLive(run) || ((run.outcome === "built" || run.outcome === "no-change") && run.id !== latest?.id))
2677
2244
  return null;
2678
2245
  return resultRowOf(task, ref.repo, family.problem, run);
@@ -2708,8 +2275,6 @@ export function createTasksHandlers(runtime) {
2708
2275
  function reviewCockpitViewOf(row, who, now) {
2709
2276
  const ref = store.lookupRef(row.taskId);
2710
2277
  const scope = store.getScope(row.taskId);
2711
- // The result run, read once: the shared result detail below hangs off
2712
- // this one record.
2713
2278
  const run = row.runId === null ? null : store.getRun(row.runId);
2714
2279
  const intent = scope === null
2715
2280
  ? null
@@ -2767,39 +2332,27 @@ export function createTasksHandlers(runtime) {
2767
2332
  summary: detail.handoff?.conclusion ?? run.handoff,
2768
2333
  },
2769
2334
  detail,
2770
- // How it ran: derived from the run's own records once it has finished, display only. A read ahead of the page's
2771
- // link (x-toolroll-read: prefetch) derives it and saves nothing.
2772
2335
  efficiency: (() => { try {
2773
2336
  return runEfficiencyOf(store, evidenceRoot, run.id, now, requestContext.getStore()?.readPurpose !== "prefetch");
2774
2337
  }
2775
2338
  catch {
2776
2339
  return null;
2777
2340
  } })(),
2778
- // What its network was and what its proxy saw (egress.ts), display only.
2779
2341
  network: store.runNetwork(run.id),
2780
- // Where the time went: its release check's parts and the task's deploys (latency-timeline.ts), display only.
2781
2342
  timing: timingFor(store, run.id, row.taskId),
2782
- // How far its checks reached (check-access.ts), display only.
2783
2343
  checkAccess: store.runCheckAccess(run.id),
2784
- // How its checks actually ran, by what was stamped at launch: said only for a result whose checks ran.
2785
2344
  checkRan: store.artifactsFor(run.id).some(one => one.kind === "check-log") ? ranWords(runCheckStamp(store, run.id)) : null,
2786
2345
  reviewRetry: store.reviewRetryStateOf(run.id),
2787
2346
  review: reviewFactsFor(run.id),
2788
2347
  notes: store.notesForRun(run.id),
2789
2348
  };
2790
2349
  }
2791
- // ---- evidence ------------------------------------------------------------
2792
2350
  function decisionEvidence(response, decisionId, artifactId) {
2793
- // The ceiling applies to decision evidence exactly as to run evidence
2794
- // (v2 review, finding 2): a decision whose task belongs to a repo this
2795
- // server may not serve does not exist here, and neither do its bytes.
2796
2351
  const decision = store.getDecision(decisionId);
2797
2352
  const decisionRun = decision === null ? null : store.getRun(decision.run);
2798
2353
  if (decisionRun !== null && !visible(taskRepoOf(decisionRun.taskRef))) {
2799
2354
  return respond(response, 404, "text/plain; charset=utf-8", "no such evidence");
2800
2355
  }
2801
- // Only through the decision's own relation — an artifact id from another
2802
- // run simply is not in this list, whatever the URL claims.
2803
2356
  const linked = store.evidenceFor(decisionId).find(one => one.id === artifactId);
2804
2357
  if (linked === undefined) {
2805
2358
  return respond(response, 404, "text/plain; charset=utf-8", "no such evidence");
@@ -2811,8 +2364,6 @@ export function createTasksHandlers(runtime) {
2811
2364
  if (run === null || !runVisible(run)) {
2812
2365
  return respond(response, 404, "text/plain; charset=utf-8", "no such run");
2813
2366
  }
2814
- // Membership is the lookup's own predicate — there is no way to check
2815
- // the run and fetch the artifact as two separate acts here.
2816
2367
  const linked = store.artifactForRun(runId, artifactId);
2817
2368
  if (linked === null) {
2818
2369
  return respond(response, 404, "text/plain; charset=utf-8", "no such evidence");
@@ -2824,9 +2375,6 @@ export function createTasksHandlers(runtime) {
2824
2375
  if (!read.ok) {
2825
2376
  return respond(response, 410, "text/plain; charset=utf-8", "the evidence no longer matches its record");
2826
2377
  }
2827
- // A validated screenshot is the one evidence kind meant to render
2828
- // inline (thumbnails, full-image links) — every other kind stays a
2829
- // downloaded text record, exactly as before.
2830
2378
  if (linked.kind === "screenshot") {
2831
2379
  const imageType = linked.key.endsWith(".png") ? "image/png" : linked.key.endsWith(".jpg") ? "image/jpeg" : null;
2832
2380
  if (imageType !== null) {
@@ -2842,7 +2390,6 @@ export function createTasksHandlers(runtime) {
2842
2390
  });
2843
2391
  response.end(read.content);
2844
2392
  }
2845
- /** The full guard list (v3 §4) — run on every request, hit or miss. */
2846
2393
  function peekGuards(runId) {
2847
2394
  if (options.localRunner === undefined || options.poolRoot === undefined) {
2848
2395
  return { ok: false, message: "live peek is off — start serve with --runner <name> naming this machine's runner", final: true };
@@ -2852,17 +2399,11 @@ export function createTasksHandlers(runtime) {
2852
2399
  return { ok: false, message: "no such build", final: true };
2853
2400
  if (run.outcome !== null)
2854
2401
  return { ok: false, message: "this build has finished — the final diff below is the record", final: true };
2855
- // The reviewer role (v29): artifact-only, honestly — there is no
2856
- // checkout anywhere to watch, and there never was.
2857
2402
  if (run.worktree === null) {
2858
2403
  return { ok: false, message: "this run reviewed the sealed diff — no workspace existed to watch", final: true };
2859
2404
  }
2860
2405
  if (run.baseRevision === null)
2861
2406
  return { ok: false, message: "the build has not settled its starting point yet" };
2862
- // The run's lease must be the task's CURRENT live lease — max generation,
2863
- // unreleased, strictly unexpired. liveClaimByLease proves only that the
2864
- // lease exists; a superseded lease would still pass it (round-4
2865
- // finding 15), and superseded is forever, so the poller may stop.
2866
2407
  if (store.currentLiveLease(run.taskRef, clock()) !== run.leaseId) {
2867
2408
  return { ok: false, message: "the build is not actively running right now", final: true };
2868
2409
  }
@@ -2872,8 +2413,6 @@ export function createTasksHandlers(runtime) {
2872
2413
  if (row.runner !== options.localRunner) {
2873
2414
  return { ok: false, message: "this build runs on another machine — open the console there to watch it", final: true };
2874
2415
  }
2875
- // Adoption-path rows can carry no epoch (round-3 finding 37): no fence,
2876
- // no peek — never a guess.
2877
2416
  if (row.leaseEpoch === null || row.leaseEpoch === undefined) {
2878
2417
  return { ok: false, message: "this checkout was set up before live watching existed — the next fresh build can be watched", final: true };
2879
2418
  }
@@ -2887,8 +2426,6 @@ export function createTasksHandlers(runtime) {
2887
2426
  catch {
2888
2427
  return { ok: false, message: "the checkout could not be found on this machine" };
2889
2428
  }
2890
- // The snapshot: exactly one successful, untruncated base-tree artifact
2891
- // whose envelope binds THIS run and THIS base (round-3 finding 42).
2892
2429
  const artifact = store.artifactsFor(runId).find(one => one.kind === "base-tree");
2893
2430
  if (artifact === undefined)
2894
2431
  return { ok: false, message: "no base snapshot was captured for this build" };
@@ -2904,7 +2441,6 @@ export function createTasksHandlers(runtime) {
2904
2441
  }
2905
2442
  return { ok: true, admit: { run, worktree: run.worktree, epoch: row.leaseEpoch, entries: snapshot } };
2906
2443
  }
2907
- /** The live subset of a bounded run page \u2014 one indexed lookup per row. */
2908
2444
  function liveRunIds(rows) {
2909
2445
  const live = new Set();
2910
2446
  for (const run of rows)
@@ -2914,7 +2450,6 @@ export function createTasksHandlers(runtime) {
2914
2450
  }
2915
2451
  const tidyHandlers = createTidyHandlers(runtime);
2916
2452
  const releaseSheet = createReleaseSheetHandlers(runtime);
2917
- /** The question page, with a refusal in its box when an answer was refused (the box keeps the choice to make). */
2918
2453
  function decisionScreen(ctx, id, back, refusal, code, now, draft) {
2919
2454
  const { who, response, project } = ctx;
2920
2455
  const decision = store.getDecision(id);
@@ -2941,13 +2476,10 @@ export function createTasksHandlers(runtime) {
2941
2476
  "code.changes-read": showCode("changes", true),
2942
2477
  "code.ship-preview": showCode("ship", true),
2943
2478
  "code.other": showCode("unknown"),
2944
- // Retired into Tasks and the task page (src/design/KIT.md): each old address still answers, as a redirect.
2945
- // Retired pages (docs/plans/plain-toolroll.md P1.4): permanent redirects, no page handler of their own.
2946
2479
  "inbox": async (ctx) => retiredRedirect("inbox", ctx.url, ctx.response),
2947
2480
  "work": async (ctx) => retiredRedirect("work", ctx.url, ctx.response),
2948
2481
  "next": async (ctx) => retiredRedirect("next", ctx.url, ctx.response),
2949
2482
  "board": async (ctx) => retiredRedirect("board", ctx.url, ctx.response),
2950
- // A result keeps its own page; the bare list moved to Tasks' Ready view.
2951
2483
  "review": async (ctx) => ctx.url.searchParams.has("result") ? showReview(ctx) : retiredRedirect("review", ctx.url, ctx.response),
2952
2484
  "done": async (ctx) => retiredRedirect("done", ctx.url, ctx.response),
2953
2485
  "tasks": showTasks,
@@ -3018,33 +2550,26 @@ export function createTasksHandlers(runtime) {
3018
2550
  "session.editor-links": sessionEditorLinks,
3019
2551
  "incident.resolve": resolveIncident,
3020
2552
  });
3021
- /** The add page, once more: blank, from a shipped template (`?template=`, as the old task list did), or with a refused
3022
- * filing's own words and status (the draft keeps the project revision it was written against). */
3023
2553
  function newTaskScreen(ctx, status, problem, draft, text = null) {
3024
2554
  const { who, response, project } = ctx;
3025
2555
  const chainable = store
3026
2556
  .listTasksScoped(project, undefined, 100, null)
3027
2557
  .filter(one => one.state !== "done" && one.state !== "cancelled" && visible(one.repo))
3028
2558
  .map(one => ({ id: one.id, title: one.title }));
3029
- // A refused draft keeps the task it was to start after, even if the refreshed list no longer carries it.
3030
2559
  const after = draft?.values?.get("after") ?? "";
3031
2560
  if (after !== "" && !chainable.some(one => one.id === after))
3032
2561
  chainable.unshift({ id: after, title: "(as submitted)" });
3033
2562
  const chrome = chromeFor(project, "tasks");
3034
2563
  const revision = draft?.values !== undefined ? undefined : who.via === "cookie" ? who.session.projectRevision : 0;
3035
- // Ideas for the project the box starts on: what the first run found there (issues, TODOs), else the safe generic
3036
- // ones while the first run is open; none once someone has filed work and nothing was found.
3037
2564
  const startsOn = draft?.values?.get("repo") ?? project ?? chrome.projects?.[0]?.path ?? null;
3038
2565
  const found = startsOn === null ? null : runtime.firstTasks.get(startsOn)?.found ?? null;
3039
2566
  const ideas = found ?? (runtime.firstRunStepsNow(ctx.now) !== null && !store.hasAnyWork() ? firstTaskSuggestions({ issues: [], todos: [] }) : []);
3040
2567
  return sendScreen(response, status, newTaskPage(chrome, project, revision, problem, chainable, store.permissionDefault().mode, store.qualityDefault().mode, chrome.projects ?? [], draft, text, ideas, ctx.url.searchParams.get("from")?.slice(0, 300) ?? null));
3041
2568
  }
3042
- /** What the password rule reads for this request (approval-password.ts), the same facts the approve forms read. */
3043
2569
  function fastPasswordFacts(who) {
3044
2570
  return { passwordless: passwordlessSessionFor(store, who.name), localOwner: who.via === "cookie" && who.authority === "local-owner",
3045
2571
  freshAt: withFreshness("approve-standard", () => freshnessFor(who.name, Date.now(), true))?.at ?? null, returnTo: "/tasks/new" };
3046
2572
  }
3047
- /** Build: the fast start's one write. Every check is made again inside fastStartBuild's transaction. */
3048
2573
  async function buildNow(ctx) {
3049
2574
  const { who, response, now, posted } = ctx;
3050
2575
  const body = readForm(posted, CONSOLE_FORMS.tasksFast);
@@ -3064,7 +2589,6 @@ export function createTasksHandlers(runtime) {
3064
2589
  actionContext.createdTask = built.taskId;
3065
2590
  return redirect(response, taskHref(built.taskId));
3066
2591
  }
3067
- /** "Approve it to keep it": a fast start that grew gets a plan for its exact commit, on the ordinary approval. It seals nothing. */
3068
2592
  async function keepGrown(ctx) {
3069
2593
  const { url, who, response, now, posted } = ctx;
3070
2594
  readForm(posted, CONSOLE_FORMS.keepGrown);
@@ -3076,8 +2600,6 @@ export function createTasksHandlers(runtime) {
3076
2600
  return taskScreen(response, who, act.taskId, kept.message, 409);
3077
2601
  return redirect(response, taskHref(act.taskId));
3078
2602
  }
3079
- /** Findings, a failed check's repair and evidence (render-follow-through.ts). Nothing here is an approval: a repair is a
3080
- * draft, and its task page asks for the plan's approval as any other. */
3081
2603
  async function followThroughAct(ctx) {
3082
2604
  const { url, who, response, now, posted } = ctx;
3083
2605
  const body = readForm(posted, CONSOLE_FORMS.followThrough);
@@ -3085,13 +2607,11 @@ export function createTasksHandlers(runtime) {
3085
2607
  if (act === null)
3086
2608
  return noPage(who, response);
3087
2609
  const { taskId } = act;
3088
- // Chat's gate, here too (findings.ts familyInReach): every project in this task's family, not only this page's.
3089
2610
  if (familyInWebReach(store, who, taskId, visible) === null)
3090
2611
  return refuse(response, who, 403, "That task is outside your access.", "/tasks");
3091
2612
  const number = (name) => Number(body.get(name) ?? "");
3092
2613
  const back = () => redirect(response, `${taskHref(taskId)}#findings`);
3093
2614
  const refused = (message) => taskScreen(response, who, taskId, message, 409);
3094
- /** A finding or a run named by a form must belong to this task's family: this page's project was the one admitted. */
3095
2615
  const ownFinding = () => { const found = getFinding(store, number("finding")); return found !== null && found.familyRoot === familyRootOf(store, taskId) ? found : null; };
3096
2616
  const ownRun = () => runOnTask(store, number("run"), taskId);
3097
2617
  switch (body.get("act")) {
@@ -3149,9 +2669,6 @@ export function createTasksHandlers(runtime) {
3149
2669
  }
3150
2670
  return { registrations, runListPane, peekFragment, taskMutation, queueRegionFor, ciFailingFor, completedRowFor, attemptRowFor, resultRowOf, reviewCockpitViewOf, decisionEvidence, runEvidence, sendArtifact, peekGuards, liveRunIds };
3151
2671
  }
3152
- /** Put away and Restore one task, and Put away old tasks (docs/plans/task-tidy.md): the preview reads only (GET-quiet);
3153
- * putting away many is an approver's step-up bound to the digest of exactly what the preview showed. Each write
3154
- * re-proves the person's standing inside its own transaction. */
3155
2672
  export function createTidyHandlers(runtime) {
3156
2673
  const { store, sendScreen, chromeFor, authenticateApprover, workAccess, bustBadge } = runtime;
3157
2674
  async function showPutAway(ctx) {
@@ -3198,19 +2715,11 @@ export function createTidyHandlers(runtime) {
3198
2715
  return { "tasks.archive": showPutAway, "work.put-away": async (ctx) => retiredRedirect("work.put-away", ctx.url, ctx.response),
3199
2716
  "work.put-away.apply": applyPutAway, "task.act.archive": oneTask("archive"), "task.act.restore": oneTask("restore") };
3200
2717
  }
3201
- /** A retired page's GET alias: a plain 302 (the shared 303 helper belongs to POST landings), as pages.ts morningAlias. */
3202
2718
  function redirectGet(response, to) {
3203
2719
  response.writeHead(302, { ...SAFETY, Location: to });
3204
2720
  response.end();
3205
2721
  }
3206
- /** How many cards a Board column shows; the column's count covers them all and its "View all" opens the list. */
3207
2722
  export const BOARD_COLUMN_LIMIT = 40;
3208
- /**
3209
- * Easy-start C1 (N1): the two writes a page load used to make, as keyed POSTs the shell sends (wave 1c wires the
3210
- * browser). `agents.seen`: a finished result this person opened leaves their unread Done. `agents.watch`: hold (on each
3211
- * keep-alive) or release (on unload) the short lease that quiets chat pings while this person's page shows the agent.
3212
- * Each re-proves the run is in the person's projects; a reply carries nothing else.
3213
- */
3214
2723
  export function createAgentSignalHandlers(runtime) {
3215
2724
  const { store, runVisible } = runtime;
3216
2725
  const answer = (response, status, ok) => respond(response, status, "application/json", JSON.stringify({ ok }));
@@ -3225,7 +2734,6 @@ export function createAgentSignalHandlers(runtime) {
3225
2734
  const run = visibleRun(who, readForm(posted, CONSOLE_FORMS.agentSeen).get("run"));
3226
2735
  if (run === null)
3227
2736
  return answer(response, 404, false);
3228
- // Only once it finished: a page shown while it ran saw no finished version (cockpit §3).
3229
2737
  if (run.finishedAt === null)
3230
2738
  return answer(response, 409, false);
3231
2739
  markAgentSeen(store, who.name, run.id, now);
@@ -3249,17 +2757,9 @@ export function createAgentSignalHandlers(runtime) {
3249
2757
  }
3250
2758
  return { "agents.seen": agentSeen, "agents.watch": agentWatch };
3251
2759
  }
3252
- /**
3253
- * One-tap release approval (docs/plans/trusted-release-reports.md, slice A): the sheet (`/t/<id>/release`), the push's
3254
- * opaque locator (`/approve/<task ref>`, a GET that only redirects to the sheet) and the sheet's approval, which the
3255
- * task approval POST hands here once its shared checks (cookie session, CSRF and the browser key at admission, the
3256
- * single-use nonce, a password or a standing proof) passed. The approval itself is the shared card wrapper around the
3257
- * unchanged approve() (release-approval.ts approveReleaseCard).
3258
- */
3259
2760
  export function createReleaseSheetHandlers(runtime) {
3260
2761
  const { store, sendScreen, chromeFor, visible, mintApprovalNonce, clock, authenticateApprover } = runtime;
3261
2762
  const missing = (who, response) => refuse(response, who, 404, "There's no release waiting for approval at this address.", "/work");
3262
- /** The sheet, with a problem said where it happened. */
3263
2763
  function sheetScreen(ctx, taskId, problem, status) {
3264
2764
  const { who, response, project } = ctx;
3265
2765
  const ref = store.lookupRef(taskId);
@@ -3270,7 +2770,6 @@ export function createReleaseSheetHandlers(runtime) {
3270
2770
  return missing(who, response);
3271
2771
  const card = built.card;
3272
2772
  const open = card.approved === null && card.refusal === null;
3273
- // This computer's local owner can't approve a release: the full sign-in comes first (scope.ts localApprovalEligible).
3274
2773
  const local = who.via === "cookie" && who.authority === "local-owner" ? localOwnerRefusal(store.accountOf(who.name)?.passwordSet === true, releaseSheetHref(taskId)) : null;
3275
2774
  const nonce = open && local === null && who.via === "cookie" && who.role === "approver" ? mintApprovalNonce(who.name, taskId, card.digest) : "";
3276
2775
  const remembered = (() => {
@@ -3290,7 +2789,6 @@ export function createReleaseSheetHandlers(runtime) {
3290
2789
  return missing(ctx.who, ctx.response);
3291
2790
  return sheetScreen(ctx, task.taskId, null, 200);
3292
2791
  }
3293
- /** The push's locator: proved a release in the person's projects from the plane's own state, then only redirected. */
3294
2792
  async function locate(ctx) {
3295
2793
  const { who, response, url } = ctx;
3296
2794
  const raw = /^\/approve\/([1-9][0-9]{0,14})$/.exec(url.pathname)?.[1];
@@ -3299,7 +2797,6 @@ export function createReleaseSheetHandlers(runtime) {
3299
2797
  return missing(who, response);
3300
2798
  return redirect(response, releaseSheetHref(ref.externalId));
3301
2799
  }
3302
- /** The sheet's Approve release, after the approval POST's shared checks. */
3303
2800
  function approveFromSheet(ctx, taskId, cardDigest, token) {
3304
2801
  const { who, response } = ctx;
3305
2802
  const now = clock();
@@ -3315,7 +2812,6 @@ export function createReleaseSheetHandlers(runtime) {
3315
2812
  return sheetScreen(ctx, taskId, refused.message, 403);
3316
2813
  return sheetScreen(ctx, taskId, approveRefusalWords(refused.reason), refused.reason === "changed" || refused.reason === "unrouted" ? 409 : 403);
3317
2814
  }
3318
- /** A held automatic release goes on: a person only, proved now. The watch then resumes it (release-next.ts). */
3319
2815
  async function goOn(ctx) {
3320
2816
  const { who, url, posted, now, response } = ctx;
3321
2817
  const body = readForm(posted, CONSOLE_FORMS.releaseGoOn);
@@ -3334,8 +2830,18 @@ export function createReleaseSheetHandlers(runtime) {
3334
2830
  }
3335
2831
  return { routes: { "task.release": showSheet, "task.release.go-on": goOn, "release.locate": locate }, sheetScreen, approveFromSheet };
3336
2832
  }
3337
- /** The answer to an approval asked in place: its named outcome and the same words the page would show, as JSON. Written
3338
- * only after the approve route's proofs, by the caller that knows the outcome. */
3339
2833
  export function answerApprovalInPlace(response, outcome, words, status) {
3340
2834
  respond(response, status, "application/json; charset=utf-8", JSON.stringify({ outcome, words }));
3341
2835
  }
2836
+ export function localOwnerPlan(store, taskId, source, now) {
2837
+ if (typeof source !== "string" || !/^[a-f0-9]{64}$/.test(source))
2838
+ return { ok: false, status: 409, message: LOCAL_TASK_CHANGED };
2839
+ const done = requestPlanAsLocalOwner(store, taskId, source, now);
2840
+ return done.ok ? { ok: true } : { ok: false, status: done.reason === "local-owner" || done.reason === "refused" ? 403 : 409, message: done.message };
2841
+ }
2842
+ export function localOwnerRetry(store, taskId, run, digest, now) {
2843
+ if (typeof run !== "string" || !/^[1-9][0-9]{0,14}$/.test(run) || typeof digest !== "string" || !/^[a-f0-9]{32}$/.test(digest))
2844
+ return { ok: false, status: 409, message: LOCAL_TASK_CHANGED };
2845
+ const done = retryAsLocalOwner(store, taskId, { run: Number(run), digest }, now);
2846
+ return done.ok ? { ok: true, replayed: done.replayed } : { ok: false, status: done.reason === "local-owner" || done.reason === "refused" || done.reason === "limit" ? 403 : 409, message: done.message };
2847
+ }