toolroll 0.9.92 → 0.9.94

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 (341) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/dist/activity-line.d.ts +7 -4
  3. package/dist/activity-line.js +9 -7
  4. package/dist/agent-fence.d.ts +4 -0
  5. package/dist/agent-fence.js +4 -1
  6. package/dist/approval-authority.d.ts +7 -1
  7. package/dist/approval-authority.js +11 -2
  8. package/dist/approval-password.d.ts +31 -0
  9. package/dist/approval-password.js +26 -0
  10. package/dist/assignment-status.d.ts +1 -1
  11. package/dist/assignment-ui.js +3 -3
  12. package/dist/assignment.js +16 -3
  13. package/dist/boot-identity.d.ts +2 -1
  14. package/dist/boot-identity.js +6 -4
  15. package/dist/bounded-spawn.d.ts +57 -0
  16. package/dist/bounded-spawn.js +220 -0
  17. package/dist/browser/terminal.js +42 -42
  18. package/dist/browser/workspace.css +2 -2
  19. package/dist/browser/workspace.js +26 -26
  20. package/dist/browser-crew.js +2 -2
  21. package/dist/browser-shell.d.ts +1 -1
  22. package/dist/browser-shell.js +2 -2
  23. package/dist/browser-workspace.d.ts +48 -7
  24. package/dist/browser-workspace.js +3 -3
  25. package/dist/builder-restart.d.ts +21 -0
  26. package/dist/builder-restart.js +50 -0
  27. package/dist/builder.d.ts +4 -0
  28. package/dist/builder.js +73 -25
  29. package/dist/chat-acceptance.js +1 -1
  30. package/dist/chat-actions.d.ts +12 -2
  31. package/dist/chat-actions.js +25 -2
  32. package/dist/chat-channel.js +11 -0
  33. package/dist/chat-decide.d.ts +7 -2
  34. package/dist/chat-decide.js +37 -9
  35. package/dist/chat-quiet.js +3 -3
  36. package/dist/chat-voice.d.ts +1 -1
  37. package/dist/chat-voice.js +2 -2
  38. package/dist/check-facts.d.ts +126 -0
  39. package/dist/check-facts.js +318 -0
  40. package/dist/check-failure.d.ts +22 -3
  41. package/dist/check-failure.js +57 -13
  42. package/dist/check-levels-ui.d.ts +4 -0
  43. package/dist/check-levels-ui.js +10 -1
  44. package/dist/check-load.d.ts +85 -0
  45. package/dist/check-load.js +147 -0
  46. package/dist/check-only-standing.d.ts +36 -0
  47. package/dist/check-only-standing.js +39 -0
  48. package/dist/check-only.d.ts +15 -0
  49. package/dist/check-only.js +99 -0
  50. package/dist/check-report.d.ts +7 -0
  51. package/dist/check-report.js +4 -3
  52. package/dist/check-stamp.d.ts +46 -0
  53. package/dist/check-stamp.js +93 -0
  54. package/dist/checkout-cleanup.d.ts +36 -5
  55. package/dist/checkout-cleanup.js +166 -14
  56. package/dist/cli-help.d.ts +4 -1
  57. package/dist/cli-help.js +47 -30
  58. package/dist/cli.js +16 -1
  59. package/dist/code-extract.d.ts +44 -0
  60. package/dist/code-extract.js +88 -0
  61. package/dist/code-map-acts.d.ts +24 -0
  62. package/dist/code-map-acts.js +53 -0
  63. package/dist/code-map-admission.d.ts +52 -0
  64. package/dist/code-map-admission.js +295 -0
  65. package/dist/code-map-build.d.ts +63 -0
  66. package/dist/code-map-build.js +415 -0
  67. package/dist/code-map-cli.d.ts +153 -0
  68. package/dist/code-map-cli.js +103 -0
  69. package/dist/code-map-main.d.ts +1 -0
  70. package/dist/code-map-main.js +48 -0
  71. package/dist/code-map-read.d.ts +106 -0
  72. package/dist/code-map-read.js +171 -0
  73. package/dist/code-map-report.d.ts +37 -0
  74. package/dist/code-map-report.js +95 -0
  75. package/dist/code-map-shape.d.ts +172 -0
  76. package/dist/code-map-shape.js +327 -0
  77. package/dist/code-map-store.d.ts +136 -0
  78. package/dist/code-map-store.js +233 -0
  79. package/dist/coding-provider.d.ts +2 -0
  80. package/dist/coding-provider.js +3 -2
  81. package/dist/coding-update.js +3 -2
  82. package/dist/coding-workspace.js +4 -4
  83. package/dist/console-chrome.js +2 -2
  84. package/dist/containment.d.ts +5 -0
  85. package/dist/containment.js +14 -1
  86. package/dist/contracts/chat-actions.d.ts +9 -0
  87. package/dist/contracts/chat-actions.js +2 -0
  88. package/dist/contracts/cli.d.ts +52 -0
  89. package/dist/contracts/cli.js +4 -0
  90. package/dist/contracts/console-api.d.ts +12 -5
  91. package/dist/contracts/console-api.js +12 -5
  92. package/dist/contracts/gateway-tools.d.ts +17 -0
  93. package/dist/contracts/gateway-tools.js +3 -1
  94. package/dist/contracts/lead-tools.d.ts +61 -0
  95. package/dist/contracts/lead-tools.js +10 -1
  96. package/dist/contracts/project-knowledge.d.ts +38 -5
  97. package/dist/contracts/project-knowledge.js +11 -5
  98. package/dist/contracts/project-memory.d.ts +3 -1
  99. package/dist/contracts/project-memory.js +3 -2
  100. package/dist/contracts/release-check.d.ts +25 -1
  101. package/dist/contracts/release-check.js +19 -0
  102. package/dist/contracts/storage.d.ts +14 -0
  103. package/dist/contracts/storage.js +3 -1
  104. package/dist/contracts/store-json.d.ts +2 -0
  105. package/dist/contracts/youiyoux-request.d.ts +1 -1
  106. package/dist/contracts/youiyoux-request.js +1 -1
  107. package/dist/desktop-access.js +6 -2
  108. package/dist/desktop-update.d.ts +2 -2
  109. package/dist/desktop-update.js +13 -9
  110. package/dist/dispatch.js +18 -15
  111. package/dist/dispose.js +8 -2
  112. package/dist/easy-start.js +2 -3
  113. package/dist/eval-hooks.d.ts +55 -0
  114. package/dist/eval-hooks.js +227 -4
  115. package/dist/evals.js +2 -1
  116. package/dist/fast-start.d.ts +136 -0
  117. package/dist/fast-start.js +431 -0
  118. package/dist/fast-terms.d.ts +9 -0
  119. package/dist/fast-terms.js +23 -0
  120. package/dist/fenced-check-coverage.d.ts +62 -0
  121. package/dist/fenced-check-coverage.js +54 -0
  122. package/dist/first-run.js +1 -1
  123. package/dist/flaky-ci.d.ts +31 -0
  124. package/dist/flaky-ci.js +149 -0
  125. package/dist/flaky-cli.d.ts +60 -0
  126. package/dist/flaky-cli.js +60 -0
  127. package/dist/flaky.d.ts +83 -0
  128. package/dist/flaky.js +264 -0
  129. package/dist/flow-card-task.js +3 -0
  130. package/dist/flow-triggers.d.ts +1 -1
  131. package/dist/flow-triggers.js +1 -1
  132. package/dist/github-import.d.ts +62 -0
  133. package/dist/github-import.js +146 -0
  134. package/dist/guides.js +15 -10
  135. package/dist/invoke.d.ts +5 -1
  136. package/dist/invoke.js +49 -14
  137. package/dist/job-object-helper.ps1 +10 -3
  138. package/dist/keymap.d.ts +41 -0
  139. package/dist/keymap.js +51 -0
  140. package/dist/knowledge-cli.js +1 -1
  141. package/dist/knowledge-ui.d.ts +21 -4
  142. package/dist/knowledge-ui.js +75 -7
  143. package/dist/laptop-background.d.ts +16 -0
  144. package/dist/laptop-background.js +108 -2
  145. package/dist/lead-context.js +1 -1
  146. package/dist/lead-contract.d.ts +1 -1
  147. package/dist/lead-contract.js +2 -2
  148. package/dist/lead-progress.js +3 -0
  149. package/dist/lead-status.d.ts +2 -0
  150. package/dist/lead-status.js +6 -2
  151. package/dist/lead-tools.js +51 -2
  152. package/dist/lead.js +1 -1
  153. package/dist/lesson-notes.d.ts +81 -0
  154. package/dist/lesson-notes.js +336 -0
  155. package/dist/limits-ui.js +1 -1
  156. package/dist/local-owner.d.ts +1 -1
  157. package/dist/local-owner.js +11 -0
  158. package/dist/machine-check.d.ts +16 -0
  159. package/dist/machine-check.js +26 -0
  160. package/dist/machine-identity.d.ts +75 -0
  161. package/dist/machine-identity.js +170 -0
  162. package/dist/mcp-core.js +11 -1
  163. package/dist/memory-cli.d.ts +300 -1
  164. package/dist/memory-cli.js +62 -9
  165. package/dist/memory-pass.d.ts +16 -0
  166. package/dist/memory-pass.js +67 -3
  167. package/dist/memory-tidy.d.ts +181 -0
  168. package/dist/memory-tidy.js +523 -0
  169. package/dist/memory-use.d.ts +35 -0
  170. package/dist/memory-use.js +109 -0
  171. package/dist/merge-checklist.d.ts +55 -0
  172. package/dist/merge-checklist.js +182 -0
  173. package/dist/needs-you.d.ts +32 -13
  174. package/dist/needs-you.js +108 -49
  175. package/dist/nightly-github.d.ts +2 -0
  176. package/dist/nightly-github.js +4 -4
  177. package/dist/operate-remote-arguments.js +6 -1
  178. package/dist/operate-remote.js +3 -1
  179. package/dist/operate.d.ts +6 -1
  180. package/dist/operate.js +540 -70
  181. package/dist/phase-routing.js +2 -2
  182. package/dist/plain-schema.d.ts +23 -0
  183. package/dist/plain-schema.js +94 -0
  184. package/dist/plain-words.d.ts +20 -0
  185. package/dist/plain-words.js +66 -0
  186. package/dist/planner.js +2 -1
  187. package/dist/process-liveness.d.ts +2 -0
  188. package/dist/process-liveness.js +61 -17
  189. package/dist/project-delete-ui.d.ts +7 -2
  190. package/dist/project-delete-ui.js +12 -1
  191. package/dist/project-delete.js +13 -2
  192. package/dist/project-knowledge.d.ts +18 -11
  193. package/dist/project-knowledge.js +39 -9
  194. package/dist/project-learning.d.ts +2 -1
  195. package/dist/project-learning.js +15 -45
  196. package/dist/project-memory.d.ts +5 -0
  197. package/dist/project-memory.js +22 -2
  198. package/dist/proof.js +30 -5
  199. package/dist/provider-auth.js +1 -1
  200. package/dist/publish.js +9 -1
  201. package/dist/pull-request-flow.js +5 -0
  202. package/dist/push.d.ts +26 -3
  203. package/dist/push.js +55 -15
  204. package/dist/release-adapters.d.ts +9 -0
  205. package/dist/release-adapters.js +87 -1
  206. package/dist/release-approval.d.ts +191 -0
  207. package/dist/release-approval.js +382 -0
  208. package/dist/release-auto.js +26 -17
  209. package/dist/release-card.d.ts +74 -6
  210. package/dist/release-card.js +179 -23
  211. package/dist/release-carry.d.ts +7 -2
  212. package/dist/release-carry.js +39 -9
  213. package/dist/release-cli.d.ts +4 -0
  214. package/dist/release-cli.js +38 -23
  215. package/dist/release-coverage.js +1 -1
  216. package/dist/release-next.d.ts +48 -0
  217. package/dist/release-next.js +161 -0
  218. package/dist/release.d.ts +50 -1
  219. package/dist/release.js +118 -11
  220. package/dist/remote-destination.d.ts +36 -0
  221. package/dist/remote-destination.js +217 -0
  222. package/dist/remote-main.d.ts +48 -0
  223. package/dist/remote-main.js +84 -5
  224. package/dist/repository-context.d.ts +3 -2
  225. package/dist/repository-context.js +112 -70
  226. package/dist/restart-certification.d.ts +1 -0
  227. package/dist/restart-certification.js +8 -6
  228. package/dist/result-acts.d.ts +29 -21
  229. package/dist/result-acts.js +36 -25
  230. package/dist/result-follow-ups.d.ts +2 -2
  231. package/dist/result-follow-ups.js +18 -4
  232. package/dist/result-review.d.ts +1 -1
  233. package/dist/route-change-check.d.ts +4 -0
  234. package/dist/route-change-check.js +13 -0
  235. package/dist/route-change.d.ts +22 -0
  236. package/dist/route-change.js +89 -0
  237. package/dist/route-hooks.js +3 -2
  238. package/dist/route-results.d.ts +6 -1
  239. package/dist/route-results.js +14 -5
  240. package/dist/run-closeout.d.ts +1 -1
  241. package/dist/run-closeout.js +7 -5
  242. package/dist/runner-process.js +3 -2
  243. package/dist/runner.js +2 -1
  244. package/dist/scope.d.ts +6 -1
  245. package/dist/scope.js +22 -9
  246. package/dist/serve.d.ts +1 -1
  247. package/dist/serve.js +24 -18
  248. package/dist/server/chat.js +14 -12
  249. package/dist/server/chrome.d.ts +1 -1
  250. package/dist/server/chrome.js +26 -35
  251. package/dist/server/console.css +23 -0
  252. package/dist/server/guards.js +4 -0
  253. package/dist/server/home.d.ts +6 -0
  254. package/dist/server/home.js +21 -13
  255. package/dist/server/http.js +1 -1
  256. package/dist/server/kit.js +1 -1
  257. package/dist/server/merge-ready-view.d.ts +10 -0
  258. package/dist/server/merge-ready-view.js +30 -0
  259. package/dist/server/pages-assets.d.ts +1 -0
  260. package/dist/server/pages-assets.js +8 -5
  261. package/dist/server/pages.js +103 -82
  262. package/dist/server/render-chat.js +2 -2
  263. package/dist/server/render-code-map.d.ts +30 -0
  264. package/dist/server/render-code-map.js +137 -0
  265. package/dist/server/render-flaky.d.ts +20 -0
  266. package/dist/server/render-flaky.js +59 -0
  267. package/dist/server/render-history.js +1 -1
  268. package/dist/server/render-new-task.d.ts +26 -1
  269. package/dist/server/render-new-task.js +30 -5
  270. package/dist/server/render-pages.d.ts +1 -175
  271. package/dist/server/render-pages.js +38 -313
  272. package/dist/server/render-projects.d.ts +2 -1
  273. package/dist/server/render-projects.js +9 -7
  274. package/dist/server/render-release.d.ts +19 -0
  275. package/dist/server/render-release.js +84 -0
  276. package/dist/server/render-results.d.ts +2 -2
  277. package/dist/server/render-results.js +71 -73
  278. package/dist/server/render-tasks.d.ts +13 -2
  279. package/dist/server/render-tasks.js +156 -139
  280. package/dist/server/retired-routes.d.ts +17 -0
  281. package/dist/server/retired-routes.js +53 -0
  282. package/dist/server/route-table.d.ts +4 -1
  283. package/dist/server/route-table.js +52 -13
  284. package/dist/server/settings.js +129 -22
  285. package/dist/server/task-views.js +61 -26
  286. package/dist/server/tasks.d.ts +17 -6
  287. package/dist/server/tasks.js +273 -338
  288. package/dist/server/welcome.js +1 -1
  289. package/dist/settings-groups-ui.js +1 -1
  290. package/dist/setup-guide.d.ts +2 -2
  291. package/dist/stop-proof.d.ts +67 -0
  292. package/dist/stop-proof.js +295 -0
  293. package/dist/storage-sweep-process.js +1 -1
  294. package/dist/storage-sweep.d.ts +5 -3
  295. package/dist/storage-sweep.js +30 -9
  296. package/dist/storage-ui.js +28 -17
  297. package/dist/storage.d.ts +27 -2
  298. package/dist/storage.js +39 -2
  299. package/dist/store.d.ts +148 -34
  300. package/dist/store.js +626 -177
  301. package/dist/surface.js +46 -5
  302. package/dist/sweep-quarantine.d.ts +1 -0
  303. package/dist/sweep-quarantine.js +6 -4
  304. package/dist/tamper-scan.d.ts +4 -0
  305. package/dist/tamper-scan.js +90 -0
  306. package/dist/task-aliases.d.ts +5 -0
  307. package/dist/task-aliases.js +9 -0
  308. package/dist/task-control.js +4 -1
  309. package/dist/task-outcome-cli.d.ts +2 -0
  310. package/dist/task-outcome-cli.js +36 -17
  311. package/dist/task-sizing.d.ts +5 -0
  312. package/dist/task-sizing.js +2 -0
  313. package/dist/task-source.d.ts +7 -0
  314. package/dist/task-source.js +14 -0
  315. package/dist/task-status.d.ts +9 -0
  316. package/dist/task-status.js +40 -49
  317. package/dist/teardown-git.d.ts +16 -0
  318. package/dist/teardown-git.js +63 -5
  319. package/dist/telegram-progress.js +5 -3
  320. package/dist/telegram-status.js +6 -4
  321. package/dist/test-infra.d.ts +8 -0
  322. package/dist/test-infra.js +18 -0
  323. package/dist/tidy.js +1 -1
  324. package/dist/toolroll-update-ui.js +2 -2
  325. package/dist/toolroll-update.js +18 -5
  326. package/dist/tui-contract.d.ts +24 -0
  327. package/dist/tui-source.js +67 -8
  328. package/dist/tui.js +51 -51
  329. package/dist/vanished-retry.d.ts +30 -0
  330. package/dist/vanished-retry.js +174 -0
  331. package/dist/work-index.d.ts +2 -0
  332. package/dist/work-index.js +82 -70
  333. package/dist/work-summary.d.ts +2 -2
  334. package/dist/work-summary.js +2 -0
  335. package/dist/workspace-ui.d.ts +4 -2
  336. package/dist/workspace-ui.js +28 -22
  337. package/dist/worktree.d.ts +12 -3
  338. package/dist/worktree.js +68 -13
  339. package/package.json +1 -1
  340. package/dist/server/render-next.d.ts +0 -63
  341. package/dist/server/render-next.js +0 -109
@@ -12,7 +12,7 @@ import { projectName } from "../project.js";
12
12
  import { coverageStateWords, coverageWords, dispatchStatusToken, GOAL_ASSESSMENT_PENDING, manualReviewCriterionOf, manualReviewOnly, passFraction, personCheckWords, plainReasonWords, reviewConflict, semanticCoverage } from "../proof.js";
13
13
  import {} from "../pull-request-flow.js";
14
14
  import { qualityModeTitle } from "../quality.js";
15
- import { acceptWithChecksOf, resultActsOf } from "../result-acts.js";
15
+ import { acceptWithChecksOf, resultActsOf, SEND_BACK_PUBLISHED, SEND_BACK_UNPUBLISHED } from "../result-acts.js";
16
16
  import { SCREENSHOT_CAPTURE, structuredHandoffView, terminalDiffView } from "../result-evidence-readers.js";
17
17
  import { ADD_TESTS_ACTION, followUpChecksOf } from "../result-follow-ups.js";
18
18
  import { evidenceHealthOf, evidenceProblemDetailsOf, evidenceResultStatusOf, isRevisionFeedback, RESULT_REVIEW_SCRIPT, RESULT_TABS, resultFactsAttributeMap, resultLeadOf, revisionBatchOf, revisionSourceOf } from "../result-review.js";
@@ -89,7 +89,7 @@ export function repairChainHtml(chain) {
89
89
  ? `Stopped after ${chain.attempt} attempt${chain.attempt === 1 ? "" : "s"}`
90
90
  : chain.outcome === "no-progress"
91
91
  ? "Stopped because two attempts made no progress"
92
- : "Stopped because the evidence may conflict with the approved work";
92
+ : "Stopped because what the build reported may not match the approved work";
93
93
  const link = chain.draftTask === null ? "" : html ` <a href="${taskHref(chain.draftTask)}">${chain.draftTask}</a>`;
94
94
  const details = chain.unresolved.length === 0
95
95
  ? ""
@@ -202,9 +202,9 @@ export function criterionMatrixHtml(matrix, options = {}) {
202
202
  html `<p class="requirement-statement">${row.statement}</p>`,
203
203
  review?.judgement === "upholds" && !confirmed ? html `<p class="requirement-review" data-review-judgement="upholds">Reviewer confirmed</p>` : "",
204
204
  warnings,
205
- html `<details class="requirement-evidence"><summary>View evidence</summary><div class="requirement-evidence-body">`,
206
- html `<p class="meta">Required: ${row.requiredEvidence.map(kind => kinds[kind]).join(", ") || "No evidence types specified"}</p>`,
207
- answered.length === 0 ? html `<p class="meta">No evidence was submitted for this requirement.</p>` : groups,
205
+ html `<details class="requirement-evidence"><summary>How it was shown</summary><div class="requirement-evidence-body">`,
206
+ html `<p class="meta">Required: ${row.requiredEvidence.map(kind => kinds[kind]).join(", ") || "Nothing named"}</p>`,
207
+ answered.length === 0 ? html `<p class="meta">Nothing was saved to show this requirement.</p>` : groups,
208
208
  state !== "pass" || detail.length === 0 ? "" : html `<div class="requirement-evidence-group"><strong>Verification notes</strong><ul>${detail.map(line => html `<li>${line}</li>`)}</ul></div>`,
209
209
  reviewDetails,
210
210
  coverage === undefined ? "" : html `<p class="meta"${coverage.state === "gap" ? "" : html ` data-context-coverage="${coverage.state}"`}>Review context: ${coverageStateWords(coverage)}</p>`,
@@ -264,18 +264,18 @@ export function reviewPriorityOf(row) {
264
264
  const manual = ids(one => one.state === "manual-review");
265
265
  const humanReview = manualReviewOnly({ verdict: row.proofVerdict ?? "", reasons: row.proofReasons ?? [], matrix: row.proofMatrix });
266
266
  if (row.proofVerdict === "refuted") {
267
- raise(row.proofAccepted ? 1 : 0, row.proofAccepted ? "conflicting evidence — accepted with exception" : "conflicting evidence");
267
+ raise(row.proofAccepted ? 1 : 0, row.proofAccepted ? "the report doesn't match the changes — accepted with a reason" : "the report doesn't match the changes");
268
268
  }
269
269
  else if (humanReview) {
270
270
  raise(1, row.proofAccepted ? "accepted after human review" : "human review needed");
271
271
  }
272
272
  else if (row.proofVerdict === "short") {
273
- raise(row.proofAccepted ? 1 : 0, row.proofAccepted ? "missing evidence — accepted with exception" : "missing evidence");
273
+ raise(row.proofAccepted ? 1 : 0, row.proofAccepted ? "not all requirements shown — accepted with a reason" : "not all requirements shown");
274
274
  }
275
275
  if (contradicted !== "")
276
276
  raise(row.proofAccepted ? 1 : 0, `reviewer raised a concern with ${contradicted}`);
277
277
  if (broken !== "")
278
- raise(row.proofAccepted ? 1 : 0, `missing or failed evidence for ${broken}`);
278
+ raise(row.proofAccepted ? 1 : 0, `not shown, or shown failing, for ${broken}`);
279
279
  if (row.ciFailing)
280
280
  raise(0, "CI failing on its pull request — observed, not inferred");
281
281
  if (row.publicationState === "failed")
@@ -458,7 +458,7 @@ export function verificationExplanation(verdict, reasons) {
458
458
  return "Automatic recovery ran the approved setup, but Toolroll still couldn't start the project check.";
459
459
  }
460
460
  if (reason === "automatic recovery stopped because this worker no longer owned the build") {
461
- return "Automatic recovery stopped because this worker no longer owned the build. A current worker can retry safely.";
461
+ return "Automatic recovery stopped because this builder no longer had the build. Another builder can retry it safely.";
462
462
  }
463
463
  if (reason === "the approved verification command could not be run") {
464
464
  return "Toolroll couldn't run the project check.";
@@ -488,11 +488,11 @@ export function verificationExplanation(verdict, reasons) {
488
488
  if (verdict === "verified")
489
489
  return "Toolroll independently verified this result.";
490
490
  if (verdict === "attested")
491
- return "The agent supplied evidence, but no independent project check was available.";
491
+ return "The agent reported its own checks, but no project check could run to confirm them.";
492
492
  if (verdict === "short")
493
- return "Some approved requirements still need evidence.";
493
+ return "Some approved requirements aren't shown yet.";
494
494
  if (verdict === "refuted")
495
- return "Recorded evidence conflicts with this result.";
495
+ return "What the build reported doesn't match its changes.";
496
496
  return "No verification result is available for this build.";
497
497
  }
498
498
  export function verificationRecovered(reasons) {
@@ -592,30 +592,30 @@ export function reviewCockpitDetailParts(view, csrf, noted, canRetryReview, tab,
592
592
  const intent = view.intent;
593
593
  let intentView = null;
594
594
  if (intent === null) {
595
- parts.push(html `<section class="card cockpit-section" data-cockpit-section="intent"><h3>Approved scope</h3><p class="meta">No scope was filed for this task, so there is no approved goal or boundary to review.</p></section>`);
595
+ parts.push(html `<section class="card cockpit-section" data-cockpit-section="intent"><h3>Approved plan</h3><p class="meta">No plan was filed for this task, so there is no approved goal or boundary to review.</p></section>`);
596
596
  }
597
597
  else {
598
598
  // The time itself goes to the page as a stamp: the one formatter words it in the viewer's zone.
599
599
  const approvalWords = intent.approval.approved
600
- ? `Approved by ${intent.approvedBy ?? "an operator"}`
600
+ ? `Approved by ${intent.approvedBy ?? "an approver"}`
601
601
  : intent.approval.reason === "changed"
602
- ? "The scope changed after approval. The words below are the current text, not the signed one."
603
- : "Never approved. The result was built without a signed scope.";
602
+ ? "Edited after approval. The words below are the current plan, not the approved one."
603
+ : "Never approved. The result was built without an approved plan.";
604
604
  const approval = intent.approval.approved
605
- ? html `Approved by ${intent.approvedBy ?? "an operator"} · ${whenTime(intent.approval.at)}`
605
+ ? html `Approved by ${intent.approvedBy ?? "an approver"} · ${whenTime(intent.approval.at)}`
606
606
  : approvalWords;
607
607
  const body = joinHtml([
608
608
  html `<p class="recap" style="margin-top:.25rem"><strong>Goal</strong> ${intent.goal}</p>`,
609
609
  intent.outOfScope === null ? html `<p class="meta">No boundary was stated</p>` : html `<p class="recap"><strong>Not this</strong> ${intent.outOfScope}</p>`,
610
610
  intent.touches.length === 0
611
- ? html `<p class="meta">No expected paths were signed — every changed file reads as in bounds</p>`
611
+ ? html `<p class="meta">No files were named in the plan, so every changed file is in bounds</p>`
612
612
  : html `<p class="row"><span class="meta">Expected to touch</span> ${joinHtml(intent.touches.map(one => html `<span class="mono">${one}</span>`), " ")}</p>`,
613
613
  view.plan === null
614
614
  ? ""
615
- : html `<p class="meta">Plan revision ${view.plan.revision} · <span class="mono" title="${view.plan.sha256}">${view.plan.sha256.slice(0, 12)}…</span>${view.plan.approach === null ? "" : ` — ${view.plan.approach}`}</p>`,
615
+ : html `<p class="meta">Plan revision ${view.plan.revision} · <span class="mono">${view.plan.sha256.slice(0, 7)}</span>${view.plan.approach === null ? "" : ` — ${view.plan.approach}`}</p>`,
616
616
  ]);
617
617
  intentView = { approval: approvalWords, approvedAt: intent.approval.approved ? intent.approval.at ?? null : null, html: htmlString(body) };
618
- parts.push(html `<details class="card cockpit-section cockpit-disclosure" data-cockpit-section="intent"><summary><h3>Approved scope<small>What this build was asked to do · ${approval}</small></h3><span class="cockpit-disclosure-action">View</span></summary><div class="cockpit-disclosure-body">${body}</div></details>`);
618
+ parts.push(html `<details class="card cockpit-section cockpit-disclosure" data-cockpit-section="intent"><summary><h3>Approved plan<small>What this build was asked to do · ${approval}</small></h3><span class="cockpit-disclosure-action">View</span></summary><div class="cockpit-disclosure-body">${body}</div></details>`);
619
619
  }
620
620
  const selected = {
621
621
  taskId: view.taskId, title: view.title, project: view.repo === null ? null : projectName(view.repo), build: run === null ? null : run.id,
@@ -631,8 +631,8 @@ export function reviewCockpitDetailParts(view, csrf, noted, canRetryReview, tab,
631
631
  // The raw run record lives under Details now (2026-10-02): /r/<id> for this result redirects here.
632
632
  record: run === null ? null : { build: run.id, href: `/r/${run.id}?record=1`, facts: [
633
633
  { label: "Agent", value: [run.provider, run.model].filter(Boolean).join(" · ") },
634
- { label: "Worker", value: run.runner },
635
- ...(view.checkAccess === undefined || view.checkAccess === "sandboxed" ? [] : [{ label: "Checks", value: view.checkAccess === "unsandboxed" ? "Checks ran without a sandbox" : "Checks ran with model and GitHub sign-ins" }]),
634
+ { label: "Builder", value: run.runner },
635
+ ...(view.checkRan === undefined || view.checkRan === null ? [] : [{ label: "Checks", value: view.checkRan }]),
636
636
  ...(run.branch === null ? [] : [{ label: "Branch", value: run.branch }]),
637
637
  ...(run.finishedAt === null ? [] : [{ label: "Finished", value: when(run.finishedAt) }]),
638
638
  ...(run.ranMinutes === null ? [] : [{ label: "Ran", value: `${run.ranMinutes} min` }]),
@@ -660,7 +660,7 @@ export function reviewCockpitDetailParts(view, csrf, noted, canRetryReview, tab,
660
660
  if (checks !== undefined)
661
661
  parts.push(html `<p class="${checks.status === "failed" || checks.status === "unavailable" ? "problem" : "meta"}" data-actual-checks="${checks.status}">${checks.status === "unavailable" && saved.cause === "command-changed" ? CHECK_COMMAND_CHANGED : html `${checks.status === "unavailable" && saved.status !== "unavailable" ? `${CHECK_UNREADABLE} ` : ""}${checks.detail}`}${checks.logArtifactId === null ? "" : html ` <a href="/r/${run.id}/evidence/${checks.logArtifactId}">Open check output</a>`}</p>`);
662
662
  if (assignment?.completion != null)
663
- parts.push(html `<p class="meta" data-result-completed>Marked complete by ${assignment.completion.actor.replace(/^operator:/, "")}.</p>`);
663
+ parts.push(html `<p class="meta" data-result-completed>Accepted by ${assignment.completion.actor.replace(/^operator:/, "")}.</p>`);
664
664
  const panel = resultPanelParts(view.detail, {
665
665
  place: "review",
666
666
  tab,
@@ -706,7 +706,7 @@ export function reviewCockpitDetailParts(view, csrf, noted, canRetryReview, tab,
706
706
  proof: proof !== null && proof.proof !== null && proof.proofProblem === null,
707
707
  });
708
708
  // Refuted: plain Accept and finish stays as allowed, in outline, and the one line before the acts (acts.line) says why.
709
- const settled = base === null || blocked === null ? base : { ...base, label: "Accept and finish", ready: false };
709
+ const settled = base === null || blocked === null ? base : { ...base, label: "Accept", ready: false };
710
710
  const decision = settled === null ? null : { sentence: RESULT_DECISION_SENTENCE, ...settled, ...acceptWithChecksOf(settled, { unanswered, notRight: [] }),
711
711
  base: { label: settled.label, ready: settled.ready, why: settled.why } };
712
712
  // Run checks: no check ran on this result (or its saved one can't be read), the project has one, and an approver may run it.
@@ -731,7 +731,7 @@ export function reviewCockpitDetailParts(view, csrf, noted, canRetryReview, tab,
731
731
  checksRunning,
732
732
  blocked,
733
733
  canRequest: panel.panel.canRequest && panel.panel.request !== null,
734
- need: need === null || need.accept != null ? null : need.rebuild != null ? "rebuild" : need.confirm !== null ? "confirm-stopped" : null,
734
+ need: need === null || need.accept != null ? null : need.rebuild != null ? "rebuild" : need.confirm !== null ? "recheck-stopped" : null,
735
735
  next: nextKind === "revise" || nextKind === "draft-repair" ? nextKind : null,
736
736
  unanswered: settled === null ? 0 : unanswered.length,
737
737
  notRight: 0,
@@ -812,9 +812,9 @@ export function completionForm(taskId, runId, digest, pullRequestTo = null, acce
812
812
  const options = { attrs: { class: "card result-complete" }, hidden: { receipt: digest, run: runId, accept: accept === null ? null : "1" } };
813
813
  if (pullRequestTo !== null) {
814
814
  // With pull requests set up: the PR is the primary road, a bare finish the quiet one beside it.
815
- return postForm(`${taskHref(taskId)}/complete`, html `${reason}<p class="meta">Finishes the task. A pull request opens on ${pullRequestTo} from this exact commit when you ask for one.</p><div class="result-complete-actions"><button type="submit" name="publish" value="1" style="min-height:44px">Complete and open a pull request</button><button type="submit" class="secondary" style="min-height:44px">Accept and finish</button></div>`, options);
815
+ return postForm(`${taskHref(taskId)}/complete`, html `${reason}<p class="meta">Finishes the task. A pull request opens on ${pullRequestTo} from this exact commit when you ask for one.</p><div class="result-complete-actions"><button type="submit" name="publish" value="1" style="min-height:44px">Accept and open a pull request</button><button type="submit" class="secondary" style="min-height:44px">Accept</button></div>`, options);
816
816
  }
817
- return postForm(`${taskHref(taskId)}/complete`, html `${reason}<p class="meta">Finishes the task. Checks stay unchanged; nothing is published or deployed.</p><button type="submit" style="min-height:44px">Accept and finish</button>`, options);
817
+ return postForm(`${taskHref(taskId)}/complete`, html `${reason}<p class="meta">Finishes the task. Checks stay unchanged; nothing is published or deployed.</p><button type="submit" style="min-height:44px">Accept</button>`, options);
818
818
  }
819
819
  /** The pull request, in one card: its state and link, one line of detail, and the one action it needs — Merge
820
820
  * behind the password when checks passed, or Open a pull request for a result completed without one. */
@@ -854,13 +854,13 @@ function reviewNextActionParts(view, csrf, back) {
854
854
  const detail = view.detail;
855
855
  const card = (kind, title, detailWords, control) => ({ kind, title, detail: detailWords, control });
856
856
  if (run === null || detail === null) {
857
- return card("inspect-task", "No build to review", "This task was marked complete without a build record.", html `<a class="button-link" href="${taskHref(view.taskId)}">Open the task</a>`);
857
+ return card("inspect-task", "No build to review", "This task was accepted without a build record.", html `<a class="button-link" href="${taskHref(view.taskId)}">Open the task</a>`);
858
858
  }
859
859
  if (detail.ciFailing && csrf !== "") {
860
- return card("draft-repair", "CI is failing on its pull request", "Toolroll confirmed the failure. Draft one repair task, then approve it before it runs.", postForm(`/r/${run.id}/draft-repair`, html `<button type="submit">Draft a repair task</button>`));
860
+ return card("draft-repair", "CI is failing on its pull request", `Toolroll confirmed the failure. ${SEND_BACK_PUBLISHED}`, postForm(`/r/${run.id}/draft-repair`, html `<button type="submit">Send back</button>`));
861
861
  }
862
862
  if (detail.comments.length > 0 && csrf !== "") {
863
- return card("revise", `${detail.comments.length} note${detail.comments.length === 1 ? "" : "s"} ready`, "Create one revision from these notes. You approve it before it runs.", postForm(`/r/${run.id}/revise`, html `${revisionSealFields(detail.comments, detail.sourceDigest)}<button type="submit">Revise</button>`, { returnTo: back ?? reviewHref(view.taskId) }));
863
+ return card("revise", `${detail.comments.length} note${detail.comments.length === 1 ? "" : "s"} ready`, SEND_BACK_UNPUBLISHED, postForm(`/r/${run.id}/revise`, html `${revisionSealFields(detail.comments, detail.sourceDigest)}<button type="submit">Send back</button>`, { returnTo: back ?? reviewHref(view.taskId) }));
864
864
  }
865
865
  return null;
866
866
  }
@@ -872,8 +872,8 @@ function reviewNextActionParts(view, csrf, back) {
872
872
  export const PHASE_WORDS = {
873
873
  "agent-running": "agent working",
874
874
  "validating-handoff": "checking the handoff",
875
- "correcting-proof": "correcting evidence",
876
- "capturing-evidence": "capturing evidence",
875
+ "correcting-proof": "correcting its report",
876
+ "capturing-evidence": "saving its files",
877
877
  committing: "committing",
878
878
  };
879
879
  /** An agent's phase on the home card, from the machine's own vocabulary. */
@@ -884,8 +884,8 @@ export function homePhaseWords(run) {
884
884
  return "Reviewing";
885
885
  if (run.role === "scout")
886
886
  return "Investigating";
887
- const words = { "agent-running": "Writing the change", "validating-handoff": "Checking its handoff", "capturing-evidence": "Saving its evidence",
888
- committing: "Committing", "verifying-proof": "Running the checks", "correcting-proof": "Correcting its evidence" };
887
+ const words = { "agent-running": "Writing the change", "validating-handoff": "Checking its handoff", "capturing-evidence": "Saving its files",
888
+ committing: "Committing", "verifying-proof": "Running the checks", "correcting-proof": "Correcting its report" };
889
889
  return run.phase === null ? "Starting" : words[run.phase] ?? "Working";
890
890
  }
891
891
  export function phaseWords(phase) {
@@ -901,7 +901,7 @@ export const INCIDENT_WORDS = {
901
901
  "commit-failure": "the commit failed",
902
902
  "malformed-plan": "the plan was malformed",
903
903
  "plan-attempts-exhausted": "planning failed too many times",
904
- "malformed-report": "the scout's report was malformed",
904
+ "malformed-report": "the research report was malformed",
905
905
  };
906
906
  export function incidentWords(kind) {
907
907
  return INCIDENT_WORDS[kind] ?? "something went wrong — the run records have the detail";
@@ -917,11 +917,11 @@ export const EVIDENCE_WORDS = {
917
917
  handoff: "Agent handoff",
918
918
  "revision-brief": "Revision brief",
919
919
  report: "Report",
920
- proof: "Agent proof",
920
+ proof: "Agent report",
921
921
  "check-log": "Check log",
922
922
  screenshot: "Screenshot",
923
923
  "structured-output": "Agent response",
924
- "plan-contract": "Plan contract",
924
+ "plan-contract": "Your request",
925
925
  "review-context": "Review context",
926
926
  };
927
927
  /** Byte counts as people read them. */
@@ -1012,7 +1012,7 @@ export function sharedResultFactsOf(run, proof, terminal, handoff, report, publi
1012
1012
  runId: run.id,
1013
1013
  base: statOk ? stat.base : run.baseRevision,
1014
1014
  head: statOk ? stat.head : run.headRevision,
1015
- headSource: statOk ? "sealed diff" : run.headRevision === null ? null : "run record",
1015
+ headSource: statOk ? "saved diff" : run.headRevision === null ? null : "build record",
1016
1016
  checks: passed === null ? null : { passed: passed.passed, total: passed.total },
1017
1017
  caveats: proof?.proof?.caveats ?? [],
1018
1018
  evidenceProblems: evidenceProblems.map(one => one.words),
@@ -1285,8 +1285,8 @@ export function reviewDiffHtml(patch, stat, runId, commentable, anchors = new Ma
1285
1285
  return html `<div class="diff-review" data-review-diff>${commentable
1286
1286
  ? html `<div class="diff-review-bar"><span class="meta">${parsed.files.length} changed file${parsed.files.length === 1 ? "" : "s"}</span><div class="diff-modes" role="group" aria-label="diff mode"><button type="button" data-diff-mode="view" aria-pressed="true">View</button><button type="button" data-diff-mode="annotate" aria-pressed="false">Annotate</button></div></div><p class="diff-review-help">Select a line, then describe what should change. Nothing is revised until you create the revision below.</p>`
1287
1287
  : ""}${files}${patch.truncated
1288
- ? html `<p class="diff-cut">The sealed diff was shortened at storage: the rest of the change was never captured, here or in the download.</p>`
1289
- : parsed.linesTruncated ? html `<p class="diff-cut">This visual diff is shortened. Review the sealed patch before approving.</p>` : ""}</div>${storedDownloadLink(runId, patch.artifactId, "diff", patch.truncated)}`;
1288
+ ? html `<p class="diff-cut">The saved diff was shortened when it was stored: the rest of the change was never captured, here or in the download.</p>`
1289
+ : parsed.linesTruncated ? html `<p class="diff-cut">This visual diff is shortened. Review the saved patch before approving.</p>` : ""}</div>${storedDownloadLink(runId, patch.artifactId, "diff", patch.truncated)}`;
1290
1290
  }
1291
1291
  /** The check log as stored (repair 2026-09-14): its output behind a
1292
1292
  * disclosure when the bytes verify — a shortened log says so in the
@@ -1366,7 +1366,7 @@ export function evidenceBundleCard(view, run, publication = null, review = null)
1366
1366
  if (view === null)
1367
1367
  return html ``;
1368
1368
  const runId = run.id;
1369
- const parts = [html `<h2>Verification and evidence</h2>`];
1369
+ const parts = [html `<h2>Checks and saved files</h2>`];
1370
1370
  if (view.verdict !== null) {
1371
1371
  // The same status line every other surface renders for this run
1372
1372
  // (workspace package 1), beside the verdict's own explanation.
@@ -1380,7 +1380,7 @@ export function evidenceBundleCard(view, run, publication = null, review = null)
1380
1380
  parts.push(criterionMatrixHtml(view.matrix, { runId, links: view.matrixLinks, verdict: view.verdict }));
1381
1381
  parts.push(semanticCoverageHtml(view.matrix, view.qualityMode));
1382
1382
  if (reviewConflict(view.matrix, view.machineVerdict, view.verdict)) {
1383
- parts.push(html `<p class="meta">An independent review found conflicting evidence.</p>`);
1383
+ parts.push(html `<p class="meta">An independent review found the report doesn't match the changes.</p>`);
1384
1384
  }
1385
1385
  parts.push(repairChainHtml(view.repairChain));
1386
1386
  if (view.proofProblem !== null) {
@@ -1395,7 +1395,7 @@ export function evidenceBundleCard(view, run, publication = null, review = null)
1395
1395
  parts.push(html `<div class="result-section"><strong>Checks reported by the agent</strong><ul>${view.proof.checks.map(one => html `<li><span class="mono">${one.command}</span> <span class="meta">(exit ${one.exitCode}) — ${one.summary}</span></li>`)}</ul></div>`);
1396
1396
  }
1397
1397
  if (view.proof.caveats.length > 0) {
1398
- parts.push(html `<div class="result-section"><strong>Caveats</strong><ul>${view.proof.caveats.map(one => html `<li>${one}</li>`)}</ul></div>`);
1398
+ parts.push(html `<div class="result-section"><strong>Limitations the agent noted</strong><ul>${view.proof.caveats.map(one => html `<li>${one}</li>`)}</ul></div>`);
1399
1399
  }
1400
1400
  }
1401
1401
  if (view.checkLog !== null)
@@ -1422,7 +1422,7 @@ export function followUpsFor(store, evidenceRoot, run, now) {
1422
1422
  return { repo, checks: followUpChecksOf(store, run.id, now, evidenceRoot), testsTask: tests === undefined ? null : String(tests["outcome"]),
1423
1423
  quick: repo !== null && liveQuickCommand(store, repo) !== null, full: repo !== null && store.liveVerifyCommand(repo) !== null };
1424
1424
  }
1425
- export const FOLLOW_UP_WORDS = { waiting: "waiting for a worker", running: "running", passed: "passed", failed: "failed", "not-run": "didn't run" };
1425
+ export const FOLLOW_UP_WORDS = { waiting: "waiting for a builder", running: "running", passed: "passed", failed: "failed", "not-run": "didn't run" };
1426
1426
  /** Run checks and Add tests, under the result's Checks: what ran since, then the two acts. */
1427
1427
  export function followUpsHtml(followUps, runId, o) {
1428
1428
  // A batch check names every result it ran with and the exact commit it tested (batch-checks.ts).
@@ -1520,9 +1520,9 @@ export function completionReceiptCard(view, taskId, place, standing = receiptSta
1520
1520
  inReview ? html `<details class="receipt-history"><summary>Review history</summary><p class="receipt-review meta" data-receipt-review="${status.token}">${status.detail}</p></details>` : "",
1521
1521
  // The matrix count is the proof's own citation; it reads as verified
1522
1522
  // only when the machine verified the result (workspace package 1).
1523
- html `<div class="receipt-facts"><span><strong>${criteria}</strong><small>${stored.tone === "problem" ? html `the agent's own claim — not checked` : stored.token === "agent-attested" ? html `the agent's own claim, no project check` : "against the approved scope"}</small></span>`,
1524
- html `<span><strong>${diff}</strong><small>${facts.head === null ? "no commit recorded" : `head ${facts.head.slice(0, 12)} · ${facts.headSource ?? ""}`}</small></span>`,
1525
- html `<span><strong>${view.screenshots.length} screenshot${view.screenshots.length === 1 ? "" : "s"}</strong><small>${view.screenshots.length === 0 ? "none required or captured" : unavailable === 0 ? "validated visual proof" : `${unavailable} unavailable — not validated`}</small></span></div>`,
1523
+ html `<div class="receipt-facts"><span><strong>${criteria}</strong><small>${stored.tone === "problem" ? html `the agent's own word — not checked` : stored.token === "agent-attested" ? html `the agent's own word, no project check` : "against the approved plan"}</small></span>`,
1524
+ html `<span><strong>${diff}</strong><small>${facts.head === null ? "no commit recorded" : `head ${facts.head.slice(0, 7)} · ${facts.headSource ?? ""}`}</small></span>`,
1525
+ html `<span><strong>${view.screenshots.length} screenshot${view.screenshots.length === 1 ? "" : "s"}</strong><small>${view.screenshots.length === 0 ? "none required or captured" : unavailable === 0 ? "checked screenshots" : `${unavailable} unavailable — not validated`}</small></span></div>`,
1526
1526
  html `<div class="receipt-actions">`,
1527
1527
  place === "task"
1528
1528
  ? html `<a href="${taskChatHref(taskId)}">Discuss in chat →</a>`
@@ -1684,7 +1684,7 @@ export function resultPanelParts(detail, o) {
1684
1684
  summaryParts.push(html `<p class="result-files-lead">${detail.files.length === 0 ? "" : html `${joinHtml(detail.files.slice(0, 6).map(one => html `<span class="mono">${one.path}</span>`), ", ")}${detail.files.length > 6 ? ` and ${detail.files.length - 6} more` : ""} — `}<a href="${tabHref("changes")}" data-result-goto="changes">see the diff</a></p>`);
1685
1685
  }
1686
1686
  if (lead === "summary" && run.outcome === "no-change")
1687
- summaryParts.push(html `<p class="meta">The agent found that no repository change was needed${statOk && stat.fileCount === 0 ? "; the sealed diff is empty" : ""}.</p>`);
1687
+ summaryParts.push(html `<p class="meta">The agent found that no repository change was needed${statOk && stat.fileCount === 0 ? "; the saved diff is empty" : ""}.</p>`);
1688
1688
  // The agent's own account — its full conclusion (when the outcome line
1689
1689
  // shortened it), what it says it changed, and how it checked — on demand.
1690
1690
  const agentAccount = [
@@ -1702,8 +1702,8 @@ export function resultPanelParts(detail, o) {
1702
1702
  }
1703
1703
  const evidenceSources = [
1704
1704
  ...(report !== null ? [report.ok ? `verified report${report.truncated ? " (shortened)" : ""}` : "report (unverifiable)"] : []),
1705
- ...(patch !== null ? [patchOk ? `sealed diff${patch.truncated ? " (shortened)" : ""}` : "diff (unverifiable)"] : []),
1706
- ...(proof === null ? [] : proof.proofProblem !== null ? ["proof (unreadable)"] : proof.proof !== null ? ["agent proof"] : []),
1705
+ ...(patch !== null ? [patchOk ? `saved diff${patch.truncated ? " (shortened)" : ""}` : "diff (can't be checked)"] : []),
1706
+ ...(proof === null ? [] : proof.proofProblem !== null ? ["agent report (unreadable)"] : proof.proof !== null ? ["agent report"] : []),
1707
1707
  ...(proof?.checkLog !== null && proof?.checkLog !== undefined ? [proof.checkLog.problem !== null ? "check log (unverifiable)" : `check log${proof.checkLog.truncated ? " (shortened)" : ""}`] : []),
1708
1708
  ...(shots.length > 0 ? [`${shown.length} validated screenshot${shown.length === 1 ? "" : "s"}${unavailableShots.length > 0 ? `, ${unavailableShots.length} unavailable` : ""}`] : []),
1709
1709
  ];
@@ -1728,9 +1728,9 @@ export function resultPanelParts(detail, o) {
1728
1728
  html `<div><dt>Build</dt><dd>#${runId} · ${run.runner}${agent === null ? ` · ${run.provider}` : ""}${run.finishedAt === null ? "" : html ` · ${whenTime(run.finishedAt)}`}</dd></div>`,
1729
1729
  agent === null ? "" : html `<div><dt>Agent</dt><dd>${agent}</dd></div>`,
1730
1730
  html `<div><dt>Commits</dt><dd>${facts.head === null
1731
- ? facts.base === null ? "no commit recorded" : html `<span class="mono">${facts.base.slice(0, 12)}</span> <span class="meta">base · no head recorded</span>`
1732
- : html `<span class="mono">${facts.base === null ? "" : `${facts.base.slice(0, 12)} → `}${facts.head.slice(0, 12)}</span> <span class="meta">from the ${facts.headSource ?? "record"}</span>`}</dd></div>`,
1733
- html `<div><dt>Evidence</dt><dd>${evidenceSources.length === 0 ? "nothing was captured" : evidenceSources.join(" · ")}</dd></div>`,
1731
+ ? facts.base === null ? "no commit recorded" : html `<span class="mono">${facts.base.slice(0, 7)}</span> <span class="meta">base · no head recorded</span>`
1732
+ : html `<span class="mono">${facts.base === null ? "" : `${facts.base.slice(0, 7)} → `}${facts.head.slice(0, 7)}</span> <span class="meta">from the ${facts.headSource ?? "record"}</span>`}</dd></div>`,
1733
+ html `<div><dt>Saved files</dt><dd>${evidenceSources.length === 0 ? "nothing was captured" : evidenceSources.join(" · ")}</dd></div>`,
1734
1734
  html `<div><dt>Publication</dt><dd>${publicationHtml}</dd></div>`,
1735
1735
  html `</dl>`,
1736
1736
  html `<p class="result-links meta">${links}</p>`,
@@ -1747,7 +1747,7 @@ export function resultPanelParts(detail, o) {
1747
1747
  else if (!statOk)
1748
1748
  changeParts.push(html `<p class="problem">Change summary unavailable: ${stat.problem}.</p>`);
1749
1749
  else {
1750
- changeParts.push(html `<p class="row result-stat"><span class="mono">${stat.base.slice(0, 12)} → ${stat.head.slice(0, 12)}</span> — ${stat.fileCount === 0
1750
+ changeParts.push(html `<p class="row result-stat"><span class="mono">${stat.base.slice(0, 7)} → ${stat.head.slice(0, 7)}</span> — ${stat.fileCount === 0
1751
1751
  ? "no changes, verified"
1752
1752
  : `${stat.fileCount} file${stat.fileCount === 1 ? "" : "s"} · +${stat.additions} −${stat.deletions}${stat.binaryCount > 0 ? ` · ${stat.binaryCount} binary` : ""}${stat.filesTruncated ? " · file list cut, counts complete" : ""}`}</p>`);
1753
1753
  }
@@ -1784,10 +1784,10 @@ export function resultPanelParts(detail, o) {
1784
1784
  if (proof === null && reviewerNotes.length > 0)
1785
1785
  checkParts.push(html `<div class="result-section" data-cockpit-source="reviewer"><strong>Previous assessment</strong><ul>${reviewerNotes}</ul></div>`);
1786
1786
  if (run.outcome === "no-change" && !directAssessment)
1787
- checkParts.push(html `<p class="meta">The build concluded that no repository change was needed. A no-change conclusion owes no proof — its handoff and machine-captured diff are the record.</p>`);
1787
+ checkParts.push(html `<p class="meta">The build concluded that no repository change was needed. With no change, its handoff and the saved diff are the record.</p>`);
1788
1788
  if (proof === null) {
1789
1789
  if (run.outcome !== "no-change")
1790
- checkParts.push(html `<p class="meta" data-proof-verdict="none">This build has no verification result or captured evidence. Review its recorded changes yourself.</p>`);
1790
+ checkParts.push(html `<p class="meta" data-proof-verdict="none">This build has no check result or saved files. Review its changes yourself.</p>`);
1791
1791
  }
1792
1792
  else {
1793
1793
  if (proof.verdict !== null && !directAssessment) {
@@ -1806,7 +1806,7 @@ export function resultPanelParts(detail, o) {
1806
1806
  if (proof.accepted !== null)
1807
1807
  checkParts.push(html `<p class="meta">${humanReview ? "Accepted after human review" : "Accepted with an exception"} by <span class="mono">${proof.accepted.by}</span> · ${whenTime(proof.accepted.at)}${proof.accepted.note === null ? "" : ` — ${proof.accepted.note}`}</p>`);
1808
1808
  if (proof.matrix.length === 0) {
1809
- checkParts.push(detail.signedCriteria > 0 ? html `<p class="meta">The approved scope has ${detail.signedCriteria} requirement${detail.signedCriteria === 1 ? "" : "s"}, but this build has no requirement-by-requirement verification.</p>` : html `<p class="meta">This scope signed no acceptance checks.</p>`);
1809
+ checkParts.push(detail.signedCriteria > 0 ? html `<p class="meta">The approved plan has ${detail.signedCriteria} requirement${detail.signedCriteria === 1 ? "" : "s"}, but this build wasn't checked requirement by requirement.</p>` : html `<p class="meta">This plan names no requirements to check.</p>`);
1810
1810
  }
1811
1811
  else {
1812
1812
  checkParts.push(criterionMatrixHtml(proof.matrix, { runId, links: proof.matrixLinks, fileAnchors: detail.fileAnchors, verdict: proof.verdict,
@@ -1814,7 +1814,7 @@ export function resultPanelParts(detail, o) {
1814
1814
  }
1815
1815
  checkParts.push(semanticCoverageHtml(proof.matrix, proof.qualityMode));
1816
1816
  if (reviewConflict(proof.matrix, proof.machineVerdict, proof.verdict))
1817
- checkParts.push(html `<p class="meta">An independent review found conflicting evidence.</p>`);
1817
+ checkParts.push(html `<p class="meta">An independent review found the report doesn't match the changes.</p>`);
1818
1818
  checkParts.push(repairChainHtml(proof.repairChain));
1819
1819
  if (detail.reviewerFindings.length > 0) {
1820
1820
  checkParts.push(html `<div class="result-section" data-cockpit-source="reviewer"><strong>Independent review</strong><ul>${reviewerNotes}</ul></div>`);
@@ -1832,8 +1832,8 @@ export function resultPanelParts(detail, o) {
1832
1832
  ? html `<p class="meta" data-cockpit-source="screenshots">${shown.length} validated screenshot${shown.length === 1 ? "" : "s"} shown in Summary${unavailableShots.length > 0 ? `; ${unavailableShots.length} unavailable` : ""}.</p>`
1833
1833
  : html `<details class="cockpit-proof-group" data-cockpit-source="screenshots"><summary>Screenshots · ${shown.length}${unavailableShots.length > 0 ? ` (${unavailableShots.length} unavailable)` : ""}</summary><div class="receipt-visuals" aria-label="validated screenshots">${shown.map(picture)}</div></details>`);
1834
1834
  checkParts.push(receipt.caveats.length === 0
1835
- ? directAssessment ? html `` : html `<p class="meta" data-cockpit-source="caveats">No caveats were reported.</p>`
1836
- : html `<details class="cockpit-proof-group" data-cockpit-source="caveats"><summary>Agent caveats · ${receipt.caveats.length}</summary><ul>${receipt.caveats.map(one => html `<li>${one}</li>`)}</ul></details>`);
1835
+ ? directAssessment ? html `` : html `<p class="meta" data-cockpit-source="caveats">The agent noted no limitations.</p>`
1836
+ : html `<details class="cockpit-proof-group" data-cockpit-source="caveats"><summary>Limitations the agent noted · ${receipt.caveats.length}</summary><ul>${receipt.caveats.map(one => html `<li>${one}</li>`)}</ul></details>`);
1837
1837
  }
1838
1838
  if (followUps !== null && run.role === "builder")
1839
1839
  checkParts.push(followUpsHtml(followUps, runId, o));
@@ -1863,7 +1863,7 @@ export function resultPanelParts(detail, o) {
1863
1863
  if (detail.comments.length > 0) {
1864
1864
  requestParts.push(html `<p class="meta">Saved for later · ${detail.comments.length}</p><div class="diff-comments" data-result-notes="${detail.comments.length}">${detail.comments.map(one => html `<div class="diff-comment">${imageNote(one)}<span class="diff-comment-pin" aria-hidden="true"></span><p>${one.path === null ? "" : pathWords(one.path, one.line)}${one.note}</p><span class="meta">${one.author} · ${whenTime(one.createdAt)}</span></div>`)}</div>`);
1865
1865
  if (o.csrf !== "" && !detail.canAnnotate) {
1866
- requestParts.push(postForm(`/r/${runId}/revise`, html `${revisionSealFields(detail.comments, detail.sourceDigest)}<div><strong>${detail.comments.length} note${detail.comments.length === 1 ? "" : "s"} ready</strong></div><button type="submit">Request changes</button>`, { attrs: { class: "card revision-from-comments" }, returnTo: o.returnTo }));
1866
+ requestParts.push(postForm(`/r/${runId}/revise`, html `${revisionSealFields(detail.comments, detail.sourceDigest)}<div><strong>${detail.comments.length} note${detail.comments.length === 1 ? "" : "s"} ready</strong></div><button type="submit">Send back</button>`, { attrs: { class: "card revision-from-comments" }, returnTo: o.returnTo }));
1867
1867
  }
1868
1868
  }
1869
1869
  if ((detail.pastComments?.length ?? 0) > 0) {
@@ -1875,10 +1875,10 @@ export function resultPanelParts(detail, o) {
1875
1875
  requestParts.push(html `<p class="result-revision" data-result-revision="${revision.id}" data-result-revision-approved="${revision.approved ? "1" : "0"}" data-tone="${revision.tone}"><strong>Revision</strong> <a href="${taskHref(revision.id)}">${revision.title}</a> <span class="meta">· ${revision.standing}</span></p>`);
1876
1876
  }
1877
1877
  if (o.csrf === "") {
1878
- requestParts.push(html `<p class="meta">Sign in with a browser session to request changes.</p>`);
1878
+ requestParts.push(html `<p class="meta">Sign in with a browser session to send it back.</p>`);
1879
1879
  }
1880
1880
  else if (!detail.canAnnotate) {
1881
- requestParts.push(html `<p class="meta" data-result-feedback="unavailable">${terminal === null ? "This result has no sealed diff to attach notes to." : "The sealed diff no longer verifies, so notes cannot attach to it."} <a href="${taskChatHref(detail.rootId ?? detail.taskId)}">Discuss in chat →</a></p>`);
1881
+ requestParts.push(html `<p class="meta" data-result-feedback="unavailable">${terminal === null ? "This result has no saved diff to attach notes to." : "The saved diff no longer checks out, so notes can't attach to it."} <a href="${taskChatHref(detail.rootId ?? detail.taskId)}">Discuss in chat →</a></p>`);
1882
1882
  }
1883
1883
  else {
1884
1884
  requestParts.push(html `<details class="result-request-open result-request-form"${detail.comments.length > 0 ? " open" : ""}><summary>What should change?</summary>${postForm(`/r/${runId}/comment`, joinHtml([
@@ -1890,7 +1890,7 @@ export function resultPanelParts(detail, o) {
1890
1890
  html `<details class="result-pin"><summary>Attach to a file or line</summary>`,
1891
1891
  html `<div class="diff-comment-target"><label>File<input type="text" name="path" placeholder="src/…" aria-label="file" class="mono"></label>`,
1892
1892
  html `<label>Line<input type="text" name="line" placeholder="—" aria-label="line" inputmode="numeric"></label></div></details>`,
1893
- html `<div class="result-feedback-actions"><button type="submit" name="intent" value="revise" data-request-changes>Request changes</button><button type="submit" name="intent" value="note" class="quiet" data-save-feedback>Save for later</button></div>`,
1893
+ html `<div class="result-feedback-actions"><button type="submit" name="intent" value="revise" data-request-changes>Send back</button><button type="submit" name="intent" value="note" class="quiet" data-save-feedback>Save for later</button></div>`,
1894
1894
  ]), { attrs: { class: "diff-comment-form", id: "comment-form" }, returnTo: o.returnTo, hidden: { tab: o.tab, request: o.requestToken } })}</details>`);
1895
1895
  }
1896
1896
  // ---- the panel ---------------------------------------------------------
@@ -2009,12 +2009,10 @@ export function needActionOf(assignment, status, csrf, returnTo, result) {
2009
2009
  if (status.need.key === "review-result" || here)
2010
2010
  return null;
2011
2011
  }
2012
- const confirm = action?.code === "confirm-stopped" && action.target.runId !== null && csrf !== ""
2013
- ? { action: `${taskHref(assignment.rootId)}/confirm-stopped`, run: action.target.runId, returnTo, checked: needsCheck(assignment) } : null;
2012
+ const confirm = action?.code === "recheck-stopped" && action.target.runId !== null && csrf !== ""
2013
+ ? { action: `${taskHref(assignment.rootId)}/recheck-stopped`, run: action.target.runId, returnTo } : null;
2014
2014
  return { label: status.need.action.label, href: assignmentActionHref(assignment) ?? taskHref(assignment.rootId), confirm };
2015
2015
  }
2016
- /** A build Toolroll can't check at all: the approver ticks that they checked before confirming. */
2017
- export const needsCheck = (assignment) => assignment.need != null && "key" in assignment.need && assignment.need.key === "check-stopped";
2018
2016
  /** The server page's form of the same: the need's action first, Request changes as the quiet second. */
2019
2017
  export function resultNeedAction(need, o, canRequest) {
2020
2018
  const control = need.accept != null
@@ -2022,9 +2020,9 @@ export function resultNeedAction(need, o, canRequest) {
2022
2020
  : need.rebuild != null
2023
2021
  ? postForm(need.rebuild.action, html `<button type="submit" data-primary-action data-rebuild style="min-height:44px">${need.label}</button>`, { attrs: { class: "rebuild" } })
2024
2022
  : need.confirm !== null
2025
- ? postForm(need.confirm.action, html `${need.confirm.checked === true ? html `<label><input type="checkbox" name="checked" value="yes" required> Nothing from build #${need.confirm.run} is running</label>` : ""}${reauth(html `<label>Your password<input type="password" name="token" autocomplete="current-password" required></label>`)}<button type="submit" style="min-height:44px">${need.label}</button>`, { attrs: { id: "confirm-stopped", class: "confirm-stopped" }, returnTo: need.confirm.returnTo, hidden: { run: need.confirm.run } })
2023
+ ? postForm(need.confirm.action, html `<button type="submit" data-primary-action style="min-height:44px">${need.label}</button>`, { attrs: { id: "recheck-stopped", class: "recheck-stopped" }, returnTo: need.confirm.returnTo, hidden: { run: need.confirm.run } })
2026
2024
  : html `<a class="button-link" href="${need.href ?? "#"}" data-primary-action>${need.label}</a>`;
2027
- return html `<div class="result-action" data-result-action="need">${control}${canRequest && o.csrf !== "" ? html `<a class="result-feedback-link" href="#request-changes">Request changes</a>` : ""}</div>`;
2025
+ return html `<div class="result-action" data-result-action="need">${control}${canRequest && o.csrf !== "" ? html `<a class="result-feedback-link" href="#request-changes">Send back</a>` : ""}</div>`;
2028
2026
  }
2029
2027
  /** The outcome in one bounded sentence (repair 2026-09-14): the handoff's
2030
2028
  * first sentence, cut at a word when it runs past 180 characters. The
@@ -2043,7 +2041,7 @@ export function conciseOutcomeOf(conclusion) {
2043
2041
  export function resultPrimaryAction(detail, o, prUrl) {
2044
2042
  const wrap = (kind, control) => html `<div class="result-action" data-result-action="${kind}">${control}</div>`;
2045
2043
  if (detail.ciFailing && o.csrf !== "") {
2046
- return wrap("draft-repair", postForm(`/r/${detail.run.id}/draft-repair`, html `<button type="submit">Draft a repair task</button>`));
2044
+ return wrap("draft-repair", postForm(`/r/${detail.run.id}/draft-repair`, html `<p class="meta">${SEND_BACK_PUBLISHED}</p><button type="submit">Send back</button>`));
2047
2045
  }
2048
2046
  if (detail.comments.length > 0 && o.csrf !== "")
2049
2047
  return wrap("revise", html `<a class="result-feedback-link" href="#request-changes">Review saved notes</a>`);
@@ -2052,9 +2050,9 @@ export function resultPrimaryAction(detail, o, prUrl) {
2052
2050
  if (detail.assignment == null && detail.proof?.matrix.some(row => row.assessment !== undefined) && detail.proof.reasons.includes(GOAL_ASSESSMENT_PENDING))
2053
2051
  return wrap("open-result", html `<a class="button-link" href="${reviewHref(detail.taskId)}">Open result</a>`);
2054
2052
  if (detail.assignment == null && detail.proof?.matrix.some(row => row.assessment !== undefined && row.review?.judgement === "cannot-tell"))
2055
- return wrap("review-evidence", html `<a class="button-link" href="${o.hrefFor("checks")}">Review evidence</a>`);
2053
+ return wrap("review-evidence", html `<a class="button-link" href="${o.hrefFor("checks")}">Review the checks</a>`);
2056
2054
  if (detail.canAnnotate && o.csrf !== "")
2057
- return wrap("request-changes", html `<a class="result-feedback-link" href="#request-changes">Request changes</a>`);
2055
+ return wrap("request-changes", html `<a class="result-feedback-link" href="#request-changes">Send back</a>`);
2058
2056
  return html ``;
2059
2057
  }
2060
2058
  /** The run's facts as rows — one renderer for the page and its live
@@ -155,13 +155,18 @@ export declare class PermissionsWouldChange extends Error {
155
155
  }
156
156
  /** Evidence kinds in plain words, for the signed criteria in Details. */
157
157
  export declare const EVIDENCE_PLAIN: Record<string, string>;
158
+ /** The kinds a requirement's "How we'll know" picker offers, in the order it lists them (#19). */
159
+ export declare const HOW_WE_KNOW: readonly ["check", "screenshot", "changed-path", "manual-review"];
160
+ export declare const HOW_WE_KNOW_WORDS: Record<(typeof HOW_WE_KNOW)[number], string>;
158
161
  /** The permission choice a sealed profile carries, as the scope form names it. */
159
162
  export declare function permissionModeOfProfile(profile: Scope["profile"] | null | undefined): UnattendedPermissionMode | null;
160
163
  /** Done when, from the in-place editor: each line keeps its requirement's
161
164
  * id by position, and its evidence and guidance while its words stand; a
162
165
  * rewritten one is yours to check, like an added one; an emptied one is
163
- * dropped. */
164
- export declare function requirementsFromEditor(body: FormView<"requirement" | "requirement-new">, current: readonly AcceptanceCriterion[]): unknown[];
166
+ * dropped. A "How we'll know" choice beside a line (#19) names its one kind
167
+ * instead; "keep", or no choice at all (an older form), changes nothing. The
168
+ * saved plan is a new version either way: it needs approving like any edit. */
169
+ export declare function requirementsFromEditor(body: FormView<"requirement" | "requirement-new" | "requirement-how" | "requirement-new-how">, current: readonly AcceptanceCriterion[]): unknown[];
165
170
  /**
166
171
  * THE CONSENT DOOR (v48): whether a yes can be given on this scope right
167
172
  * now — one answer for the task page, the focused chat, and /next, so no
@@ -563,6 +568,10 @@ export declare function taskBodyParts(data: {
563
568
  steerRecent?: number[];
564
569
  /** Cockpit B2: when this person's remembered password was given, when it may approve these terms. */
565
570
  approvalFresh?: string | null;
571
+ /** A new route waiting for its one Approve (route-change.ts): what changed. */
572
+ routeChange?: string | null;
573
+ /** A fast start's result grew past a small change (fast-start.ts): its sentence, and the one act on. */
574
+ fastGrown?: string | null;
566
575
  /** Easy-start C5: the viewer is a laptop's local owner — whether this plan is one it approves without a password. */
567
576
  approvalLocal?: LocalApprovalView | null;
568
577
  /** Cockpit B2: how the current approval's person was proved (approval proved ledger), when it was a remembered one. */
@@ -748,3 +757,5 @@ export declare function approvedKitOf(scope: Scope, approval: {
748
757
  method: string;
749
758
  at: string;
750
759
  } | null): NonNullable<BrowserTaskView["approved"]> | null;
760
+ /** The plan version, in Details: a short handle a person can compare, never on the approval line itself. */
761
+ export declare function planVersionDetailsHtml(digest: string): Html;