toolroll 0.5.0

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 (626) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1113 -0
  3. package/THIRD_PARTY_NOTICES.md +449 -0
  4. package/dist/accent-colors.d.ts +48 -0
  5. package/dist/accent-colors.js +122 -0
  6. package/dist/action-ledger.d.ts +26 -0
  7. package/dist/action-ledger.js +75 -0
  8. package/dist/agent-fence.d.ts +42 -0
  9. package/dist/agent-fence.js +183 -0
  10. package/dist/agentconfig.d.ts +216 -0
  11. package/dist/agentconfig.js +454 -0
  12. package/dist/api-tokens.d.ts +16 -0
  13. package/dist/api-tokens.js +27 -0
  14. package/dist/approval-policy.d.ts +69 -0
  15. package/dist/approval-policy.js +137 -0
  16. package/dist/approval-rules-ui.d.ts +25 -0
  17. package/dist/approval-rules-ui.js +39 -0
  18. package/dist/assignment-adapters.d.ts +180 -0
  19. package/dist/assignment-adapters.js +239 -0
  20. package/dist/assignment-brief.d.ts +71 -0
  21. package/dist/assignment-brief.js +129 -0
  22. package/dist/assignment-delivery.d.ts +56 -0
  23. package/dist/assignment-delivery.js +160 -0
  24. package/dist/assignment-presentation.d.ts +26 -0
  25. package/dist/assignment-presentation.js +80 -0
  26. package/dist/assignment-status.d.ts +62 -0
  27. package/dist/assignment-status.js +152 -0
  28. package/dist/assignment-ui.d.ts +71 -0
  29. package/dist/assignment-ui.js +103 -0
  30. package/dist/assignment.d.ts +222 -0
  31. package/dist/assignment.js +399 -0
  32. package/dist/attest.d.ts +56 -0
  33. package/dist/attest.js +153 -0
  34. package/dist/backend.d.ts +97 -0
  35. package/dist/backend.js +166 -0
  36. package/dist/backup-ui.d.ts +22 -0
  37. package/dist/backup-ui.js +59 -0
  38. package/dist/backup.d.ts +84 -0
  39. package/dist/backup.js +421 -0
  40. package/dist/beads.d.ts +34 -0
  41. package/dist/beads.js +135 -0
  42. package/dist/bin.d.ts +2 -0
  43. package/dist/bin.js +22 -0
  44. package/dist/board.d.ts +150 -0
  45. package/dist/board.js +210 -0
  46. package/dist/boot-identity.d.ts +63 -0
  47. package/dist/boot-identity.js +99 -0
  48. package/dist/browser/THIRD_PARTY_NOTICES.txt +2295 -0
  49. package/dist/browser/workspace.css +4 -0
  50. package/dist/browser/workspace.js +225 -0
  51. package/dist/browser-crew.d.ts +11 -0
  52. package/dist/browser-crew.js +50 -0
  53. package/dist/browser-shell.d.ts +8 -0
  54. package/dist/browser-shell.js +60 -0
  55. package/dist/browser-workspace.d.ts +780 -0
  56. package/dist/browser-workspace.js +47 -0
  57. package/dist/budget-alerts.d.ts +19 -0
  58. package/dist/budget-alerts.js +46 -0
  59. package/dist/builder.d.ts +370 -0
  60. package/dist/builder.js +3262 -0
  61. package/dist/capscan.d.ts +35 -0
  62. package/dist/capscan.js +113 -0
  63. package/dist/chat-acceptance.d.ts +71 -0
  64. package/dist/chat-acceptance.js +120 -0
  65. package/dist/chat-actions.d.ts +265 -0
  66. package/dist/chat-actions.js +1273 -0
  67. package/dist/chat-channel.d.ts +109 -0
  68. package/dist/chat-channel.js +652 -0
  69. package/dist/chat-continuity.d.ts +32 -0
  70. package/dist/chat-continuity.js +317 -0
  71. package/dist/chat-controls.d.ts +113 -0
  72. package/dist/chat-controls.js +53 -0
  73. package/dist/chat-delivery-state.d.ts +159 -0
  74. package/dist/chat-delivery-state.js +309 -0
  75. package/dist/chat-delivery.d.ts +38 -0
  76. package/dist/chat-delivery.js +693 -0
  77. package/dist/chat-display.d.ts +1 -0
  78. package/dist/chat-display.js +18 -0
  79. package/dist/chat-evidence.d.ts +123 -0
  80. package/dist/chat-evidence.js +207 -0
  81. package/dist/chat-flow.d.ts +44 -0
  82. package/dist/chat-flow.js +215 -0
  83. package/dist/chat-inbox.d.ts +57 -0
  84. package/dist/chat-inbox.js +123 -0
  85. package/dist/chat-polish.d.ts +16 -0
  86. package/dist/chat-polish.js +135 -0
  87. package/dist/chat-review.d.ts +46 -0
  88. package/dist/chat-review.js +98 -0
  89. package/dist/chat-rooms.d.ts +123 -0
  90. package/dist/chat-rooms.js +216 -0
  91. package/dist/chat-task-actions.d.ts +44 -0
  92. package/dist/chat-task-actions.js +79 -0
  93. package/dist/check-progress.d.ts +51 -0
  94. package/dist/check-progress.js +290 -0
  95. package/dist/child-database.d.ts +12 -0
  96. package/dist/child-database.js +30 -0
  97. package/dist/claim.d.ts +688 -0
  98. package/dist/claim.js +1740 -0
  99. package/dist/cli.d.ts +137 -0
  100. package/dist/cli.js +1461 -0
  101. package/dist/codex-limits.d.ts +15 -0
  102. package/dist/codex-limits.js +145 -0
  103. package/dist/coding-context.d.ts +55 -0
  104. package/dist/coding-context.js +92 -0
  105. package/dist/coding-handoff.d.ts +57 -0
  106. package/dist/coding-handoff.js +277 -0
  107. package/dist/coding-provider.d.ts +72 -0
  108. package/dist/coding-provider.js +424 -0
  109. package/dist/coding-shipping-ui.d.ts +4 -0
  110. package/dist/coding-shipping-ui.js +12 -0
  111. package/dist/coding-types.d.ts +62 -0
  112. package/dist/coding-types.js +1 -0
  113. package/dist/coding-ui.d.ts +17 -0
  114. package/dist/coding-ui.js +364 -0
  115. package/dist/coding-update.d.ts +15 -0
  116. package/dist/coding-update.js +149 -0
  117. package/dist/coding-workspace.d.ts +124 -0
  118. package/dist/coding-workspace.js +768 -0
  119. package/dist/container-state.d.ts +5 -0
  120. package/dist/container-state.js +62 -0
  121. package/dist/containment.d.ts +197 -0
  122. package/dist/containment.js +559 -0
  123. package/dist/contest.d.ts +318 -0
  124. package/dist/contest.js +753 -0
  125. package/dist/control-setup.d.ts +35 -0
  126. package/dist/control-setup.js +40 -0
  127. package/dist/control-ui.d.ts +29 -0
  128. package/dist/control-ui.js +53 -0
  129. package/dist/controller-service.d.ts +1 -0
  130. package/dist/controller-service.js +19 -0
  131. package/dist/controller-supervisor.d.ts +30 -0
  132. package/dist/controller-supervisor.js +104 -0
  133. package/dist/converse.d.ts +304 -0
  134. package/dist/converse.js +849 -0
  135. package/dist/coordinator-proposals.d.ts +29 -0
  136. package/dist/coordinator-proposals.js +137 -0
  137. package/dist/coordinator.d.ts +186 -0
  138. package/dist/coordinator.js +447 -0
  139. package/dist/credentials-ui.d.ts +25 -0
  140. package/dist/credentials-ui.js +48 -0
  141. package/dist/daemon.d.ts +209 -0
  142. package/dist/daemon.js +604 -0
  143. package/dist/decision.d.ts +120 -0
  144. package/dist/decision.js +388 -0
  145. package/dist/demo.d.ts +55 -0
  146. package/dist/demo.js +992 -0
  147. package/dist/desktop-access.d.ts +28 -0
  148. package/dist/desktop-access.js +88 -0
  149. package/dist/desktop-bundle.d.ts +16 -0
  150. package/dist/desktop-bundle.js +74 -0
  151. package/dist/desktop-host.d.ts +54 -0
  152. package/dist/desktop-host.js +508 -0
  153. package/dist/desktop-update-gate.d.ts +12 -0
  154. package/dist/desktop-update-gate.js +91 -0
  155. package/dist/desktop-update-recovery.d.ts +14 -0
  156. package/dist/desktop-update-recovery.js +243 -0
  157. package/dist/desktop-update.d.ts +110 -0
  158. package/dist/desktop-update.js +740 -0
  159. package/dist/discord-api.d.ts +20 -0
  160. package/dist/discord-api.js +138 -0
  161. package/dist/discord-chat.d.ts +16 -0
  162. package/dist/discord-chat.js +381 -0
  163. package/dist/discord-settings.d.ts +7 -0
  164. package/dist/discord-settings.js +75 -0
  165. package/dist/discord.d.ts +10 -0
  166. package/dist/discord.js +169 -0
  167. package/dist/discover.d.ts +75 -0
  168. package/dist/discover.js +150 -0
  169. package/dist/dispatch.d.ts +100 -0
  170. package/dist/dispatch.js +311 -0
  171. package/dist/dispose.d.ts +161 -0
  172. package/dist/dispose.js +803 -0
  173. package/dist/email-settings.d.ts +34 -0
  174. package/dist/email-settings.js +50 -0
  175. package/dist/envelope.d.ts +47 -0
  176. package/dist/envelope.js +105 -0
  177. package/dist/evidence-pack.d.ts +185 -0
  178. package/dist/evidence-pack.js +258 -0
  179. package/dist/evidence.d.ts +345 -0
  180. package/dist/evidence.js +782 -0
  181. package/dist/exec.d.ts +285 -0
  182. package/dist/exec.js +1841 -0
  183. package/dist/exhaustion.d.ts +85 -0
  184. package/dist/exhaustion.js +141 -0
  185. package/dist/export-ui.d.ts +4 -0
  186. package/dist/export-ui.js +17 -0
  187. package/dist/export.d.ts +48 -0
  188. package/dist/export.js +305 -0
  189. package/dist/flow-actions.d.ts +77 -0
  190. package/dist/flow-actions.js +203 -0
  191. package/dist/flow-code.d.ts +50 -0
  192. package/dist/flow-code.js +159 -0
  193. package/dist/flow-draft.d.ts +38 -0
  194. package/dist/flow-draft.js +80 -0
  195. package/dist/flow-engine.d.ts +66 -0
  196. package/dist/flow-engine.js +416 -0
  197. package/dist/flow-insights.d.ts +95 -0
  198. package/dist/flow-insights.js +149 -0
  199. package/dist/flow-live.d.ts +24 -0
  200. package/dist/flow-live.js +150 -0
  201. package/dist/flow-people.d.ts +24 -0
  202. package/dist/flow-people.js +91 -0
  203. package/dist/flow-replies.d.ts +48 -0
  204. package/dist/flow-replies.js +113 -0
  205. package/dist/flow-scripts.d.ts +38 -0
  206. package/dist/flow-scripts.js +73 -0
  207. package/dist/flow-secrets.d.ts +13 -0
  208. package/dist/flow-secrets.js +45 -0
  209. package/dist/flow-sort.d.ts +82 -0
  210. package/dist/flow-sort.js +153 -0
  211. package/dist/flow-steps.d.ts +40 -0
  212. package/dist/flow-steps.js +408 -0
  213. package/dist/flow-triggers.d.ts +244 -0
  214. package/dist/flow-triggers.js +959 -0
  215. package/dist/flows-ui.d.ts +20 -0
  216. package/dist/flows-ui.js +175 -0
  217. package/dist/flows.d.ts +229 -0
  218. package/dist/flows.js +968 -0
  219. package/dist/fonts.d.ts +19 -0
  220. package/dist/fonts.js +19 -0
  221. package/dist/gaps.d.ts +35 -0
  222. package/dist/gaps.js +101 -0
  223. package/dist/gate-failure.d.ts +40 -0
  224. package/dist/gate-failure.js +66 -0
  225. package/dist/git.d.ts +54 -0
  226. package/dist/git.js +94 -0
  227. package/dist/google-mail.d.ts +58 -0
  228. package/dist/google-mail.js +151 -0
  229. package/dist/grant.d.ts +136 -0
  230. package/dist/grant.js +238 -0
  231. package/dist/graph.d.ts +164 -0
  232. package/dist/graph.js +383 -0
  233. package/dist/guides.d.ts +22 -0
  234. package/dist/guides.js +363 -0
  235. package/dist/held.d.ts +150 -0
  236. package/dist/held.js +799 -0
  237. package/dist/invoke.d.ts +112 -0
  238. package/dist/invoke.js +780 -0
  239. package/dist/issues.d.ts +41 -0
  240. package/dist/issues.js +131 -0
  241. package/dist/job-object-helper.ps1 +252 -0
  242. package/dist/jsonl-discriminants.d.ts +11 -0
  243. package/dist/jsonl-discriminants.js +93 -0
  244. package/dist/keys.d.ts +104 -0
  245. package/dist/keys.js +229 -0
  246. package/dist/kits-ui.d.ts +17 -0
  247. package/dist/kits-ui.js +46 -0
  248. package/dist/kits.d.ts +86 -0
  249. package/dist/kits.js +215 -0
  250. package/dist/knowledge-cli.d.ts +101 -0
  251. package/dist/knowledge-cli.js +92 -0
  252. package/dist/knowledge-ui.d.ts +24 -0
  253. package/dist/knowledge-ui.js +40 -0
  254. package/dist/lead-context.d.ts +8 -0
  255. package/dist/lead-context.js +56 -0
  256. package/dist/lead-follow.d.ts +22 -0
  257. package/dist/lead-follow.js +167 -0
  258. package/dist/lead-status.d.ts +75 -0
  259. package/dist/lead-status.js +285 -0
  260. package/dist/ledger-chain.d.ts +46 -0
  261. package/dist/ledger-chain.js +187 -0
  262. package/dist/ledger-csv.d.ts +4 -0
  263. package/dist/ledger-csv.js +11 -0
  264. package/dist/ledger-view.d.ts +24 -0
  265. package/dist/ledger-view.js +58 -0
  266. package/dist/limits-ui.d.ts +26 -0
  267. package/dist/limits-ui.js +67 -0
  268. package/dist/link.d.ts +72 -0
  269. package/dist/link.js +217 -0
  270. package/dist/live.d.ts +96 -0
  271. package/dist/live.js +366 -0
  272. package/dist/liveness.d.ts +30 -0
  273. package/dist/liveness.js +42 -0
  274. package/dist/log.d.ts +7 -0
  275. package/dist/log.js +25 -0
  276. package/dist/mailbox.d.ts +57 -0
  277. package/dist/mailbox.js +150 -0
  278. package/dist/maintenance.d.ts +11 -0
  279. package/dist/maintenance.js +35 -0
  280. package/dist/mate-cli.d.ts +52 -0
  281. package/dist/mate-cli.js +345 -0
  282. package/dist/mate-contract.d.ts +10 -0
  283. package/dist/mate-contract.js +30 -0
  284. package/dist/mate-doors.d.ts +69 -0
  285. package/dist/mate-doors.js +548 -0
  286. package/dist/mate-progress.d.ts +29 -0
  287. package/dist/mate-progress.js +121 -0
  288. package/dist/mate-tools.d.ts +94 -0
  289. package/dist/mate-tools.js +1878 -0
  290. package/dist/mate.d.ts +92 -0
  291. package/dist/mate.js +435 -0
  292. package/dist/mcp-connect.d.ts +103 -0
  293. package/dist/mcp-connect.js +252 -0
  294. package/dist/mcp.d.ts +27 -0
  295. package/dist/mcp.js +651 -0
  296. package/dist/memory-cli.d.ts +466 -0
  297. package/dist/memory-cli.js +111 -0
  298. package/dist/memory-pass.d.ts +160 -0
  299. package/dist/memory-pass.js +409 -0
  300. package/dist/metrics.d.ts +3 -0
  301. package/dist/metrics.js +56 -0
  302. package/dist/mobile-viewport.d.ts +3 -0
  303. package/dist/mobile-viewport.js +37 -0
  304. package/dist/model-catalog.d.ts +118 -0
  305. package/dist/model-catalog.js +376 -0
  306. package/dist/models-cli.d.ts +102 -0
  307. package/dist/models-cli.js +66 -0
  308. package/dist/models-ui.d.ts +34 -0
  309. package/dist/models-ui.js +68 -0
  310. package/dist/modes.d.ts +80 -0
  311. package/dist/modes.js +182 -0
  312. package/dist/monitoring-settings.d.ts +44 -0
  313. package/dist/monitoring-settings.js +173 -0
  314. package/dist/monitoring-ui.d.ts +20 -0
  315. package/dist/monitoring-ui.js +51 -0
  316. package/dist/monitoring.d.ts +34 -0
  317. package/dist/monitoring.js +221 -0
  318. package/dist/names.d.ts +67 -0
  319. package/dist/names.js +102 -0
  320. package/dist/observations.d.ts +40 -0
  321. package/dist/observations.js +211 -0
  322. package/dist/oidc.d.ts +71 -0
  323. package/dist/oidc.js +182 -0
  324. package/dist/onboard.d.ts +108 -0
  325. package/dist/onboard.js +325 -0
  326. package/dist/openrouter-models.d.ts +30 -0
  327. package/dist/openrouter-models.js +120 -0
  328. package/dist/operate.d.ts +118 -0
  329. package/dist/operate.js +11321 -0
  330. package/dist/peek-cli.d.ts +97 -0
  331. package/dist/peek-cli.js +215 -0
  332. package/dist/peek.d.ts +134 -0
  333. package/dist/peek.js +578 -0
  334. package/dist/phase-routing.d.ts +307 -0
  335. package/dist/phase-routing.js +658 -0
  336. package/dist/plan-auto.d.ts +14 -0
  337. package/dist/plan-auto.js +92 -0
  338. package/dist/plan.d.ts +186 -0
  339. package/dist/plan.js +401 -0
  340. package/dist/planner-source.d.ts +251 -0
  341. package/dist/planner-source.js +460 -0
  342. package/dist/planner.d.ts +75 -0
  343. package/dist/planner.js +992 -0
  344. package/dist/policy-ui.d.ts +20 -0
  345. package/dist/policy-ui.js +41 -0
  346. package/dist/policy.d.ts +111 -0
  347. package/dist/policy.js +231 -0
  348. package/dist/prepared-evidence.d.ts +16 -0
  349. package/dist/prepared-evidence.js +96 -0
  350. package/dist/pricing.d.ts +45 -0
  351. package/dist/pricing.js +77 -0
  352. package/dist/principal.d.ts +42 -0
  353. package/dist/principal.js +82 -0
  354. package/dist/probe.d.ts +46 -0
  355. package/dist/probe.js +79 -0
  356. package/dist/process-custody.d.ts +17 -0
  357. package/dist/process-custody.js +91 -0
  358. package/dist/process-liveness.d.ts +10 -0
  359. package/dist/process-liveness.js +81 -0
  360. package/dist/process-recovery-anchor.d.ts +75 -0
  361. package/dist/process-recovery-anchor.js +188 -0
  362. package/dist/process-recovery-coalition.d.ts +25 -0
  363. package/dist/process-recovery-coalition.js +105 -0
  364. package/dist/process-recovery-eligibility.d.ts +178 -0
  365. package/dist/process-recovery-eligibility.js +170 -0
  366. package/dist/process-recovery-native.d.ts +172 -0
  367. package/dist/process-recovery-native.js +592 -0
  368. package/dist/process-recovery-provenance.d.ts +163 -0
  369. package/dist/process-recovery-provenance.js +292 -0
  370. package/dist/process-recovery-services.d.ts +56 -0
  371. package/dist/process-recovery-services.js +191 -0
  372. package/dist/process-recovery-settlement.d.ts +32 -0
  373. package/dist/process-recovery-settlement.js +132 -0
  374. package/dist/process-recovery.d.ts +41 -0
  375. package/dist/process-recovery.js +91 -0
  376. package/dist/process-tree.d.ts +41 -0
  377. package/dist/process-tree.js +264 -0
  378. package/dist/project-access.d.ts +14 -0
  379. package/dist/project-access.js +34 -0
  380. package/dist/project-cli.d.ts +18 -0
  381. package/dist/project-cli.js +104 -0
  382. package/dist/project-delete-ui.d.ts +22 -0
  383. package/dist/project-delete-ui.js +48 -0
  384. package/dist/project-delete.d.ts +55 -0
  385. package/dist/project-delete.js +413 -0
  386. package/dist/project-knowledge.d.ts +111 -0
  387. package/dist/project-knowledge.js +241 -0
  388. package/dist/project-learning.d.ts +100 -0
  389. package/dist/project-learning.js +438 -0
  390. package/dist/project-memory.d.ts +81 -0
  391. package/dist/project-memory.js +264 -0
  392. package/dist/project-skills.d.ts +152 -0
  393. package/dist/project-skills.js +660 -0
  394. package/dist/project-tools.d.ts +219 -0
  395. package/dist/project-tools.js +796 -0
  396. package/dist/project.d.ts +61 -0
  397. package/dist/project.js +125 -0
  398. package/dist/prompt.d.ts +22 -0
  399. package/dist/prompt.js +72 -0
  400. package/dist/proof.d.ts +513 -0
  401. package/dist/proof.js +1140 -0
  402. package/dist/proposal.d.ts +82 -0
  403. package/dist/proposal.js +210 -0
  404. package/dist/provider-connection.d.ts +22 -0
  405. package/dist/provider-connection.js +98 -0
  406. package/dist/provider-limits.d.ts +35 -0
  407. package/dist/provider-limits.js +95 -0
  408. package/dist/provider.d.ts +279 -0
  409. package/dist/provider.js +935 -0
  410. package/dist/publish.d.ts +107 -0
  411. package/dist/publish.js +650 -0
  412. package/dist/pulls.d.ts +118 -0
  413. package/dist/pulls.js +240 -0
  414. package/dist/push.d.ts +95 -0
  415. package/dist/push.js +353 -0
  416. package/dist/quality.d.ts +8 -0
  417. package/dist/quality.js +6 -0
  418. package/dist/recipe-ui.d.ts +18 -0
  419. package/dist/recipe-ui.js +152 -0
  420. package/dist/recipes.d.ts +81 -0
  421. package/dist/recipes.js +332 -0
  422. package/dist/remote.d.ts +67 -0
  423. package/dist/remote.js +122 -0
  424. package/dist/render.d.ts +64 -0
  425. package/dist/render.js +587 -0
  426. package/dist/report-summary.d.ts +13 -0
  427. package/dist/report-summary.js +15 -0
  428. package/dist/repos.d.ts +65 -0
  429. package/dist/repos.js +277 -0
  430. package/dist/repository-context-ui.d.ts +2 -0
  431. package/dist/repository-context-ui.js +10 -0
  432. package/dist/repository-context.d.ts +67 -0
  433. package/dist/repository-context.js +376 -0
  434. package/dist/restart-certification.d.ts +134 -0
  435. package/dist/restart-certification.js +226 -0
  436. package/dist/result-actions.d.ts +28 -0
  437. package/dist/result-actions.js +270 -0
  438. package/dist/result-completion.d.ts +18 -0
  439. package/dist/result-completion.js +66 -0
  440. package/dist/result-review.d.ts +213 -0
  441. package/dist/result-review.js +430 -0
  442. package/dist/retention-ui.d.ts +12 -0
  443. package/dist/retention-ui.js +39 -0
  444. package/dist/retention.d.ts +72 -0
  445. package/dist/retention.js +288 -0
  446. package/dist/review-context.d.ts +243 -0
  447. package/dist/review-context.js +1043 -0
  448. package/dist/review-evidence.d.ts +33 -0
  449. package/dist/review-evidence.js +56 -0
  450. package/dist/reviewer.d.ts +97 -0
  451. package/dist/reviewer.js +202 -0
  452. package/dist/routine.d.ts +228 -0
  453. package/dist/routine.js +764 -0
  454. package/dist/runner.d.ts +266 -0
  455. package/dist/runner.js +399 -0
  456. package/dist/scan.d.ts +32 -0
  457. package/dist/scan.js +92 -0
  458. package/dist/scope.d.ts +695 -0
  459. package/dist/scope.js +1176 -0
  460. package/dist/scout-report.d.ts +42 -0
  461. package/dist/scout-report.js +108 -0
  462. package/dist/scout.d.ts +69 -0
  463. package/dist/scout.js +351 -0
  464. package/dist/serve.d.ts +313 -0
  465. package/dist/serve.js +21776 -0
  466. package/dist/session-brief.d.ts +8 -0
  467. package/dist/session-brief.js +24 -0
  468. package/dist/session-cli.d.ts +13 -0
  469. package/dist/session-cli.js +284 -0
  470. package/dist/session-contract.d.ts +183 -0
  471. package/dist/session-contract.js +122 -0
  472. package/dist/session-http.d.ts +19 -0
  473. package/dist/session-http.js +154 -0
  474. package/dist/session-server.d.ts +12 -0
  475. package/dist/session-server.js +37 -0
  476. package/dist/session-service.d.ts +22 -0
  477. package/dist/session-service.js +157 -0
  478. package/dist/setup-guide.d.ts +39 -0
  479. package/dist/setup-guide.js +93 -0
  480. package/dist/sign-in-guard.d.ts +45 -0
  481. package/dist/sign-in-guard.js +74 -0
  482. package/dist/skills-ui.d.ts +11 -0
  483. package/dist/skills-ui.js +58 -0
  484. package/dist/skills.d.ts +97 -0
  485. package/dist/skills.js +276 -0
  486. package/dist/slack-api.d.ts +55 -0
  487. package/dist/slack-api.js +229 -0
  488. package/dist/slack-chat.d.ts +28 -0
  489. package/dist/slack-chat.js +413 -0
  490. package/dist/slack-settings.d.ts +7 -0
  491. package/dist/slack-settings.js +75 -0
  492. package/dist/slack-state.d.ts +13 -0
  493. package/dist/slack-state.js +9 -0
  494. package/dist/slack.d.ts +13 -0
  495. package/dist/slack.js +167 -0
  496. package/dist/spend-ui.d.ts +28 -0
  497. package/dist/spend-ui.js +95 -0
  498. package/dist/spend.d.ts +142 -0
  499. package/dist/spend.js +313 -0
  500. package/dist/sqlite-runtime.d.ts +3 -0
  501. package/dist/sqlite-runtime.js +6 -0
  502. package/dist/sso-settings.d.ts +33 -0
  503. package/dist/sso-settings.js +103 -0
  504. package/dist/sso-ui.d.ts +22 -0
  505. package/dist/sso-ui.js +39 -0
  506. package/dist/storage.d.ts +15 -0
  507. package/dist/storage.js +84 -0
  508. package/dist/store.d.ts +7754 -0
  509. package/dist/store.js +23279 -0
  510. package/dist/structured-output.d.ts +58 -0
  511. package/dist/structured-output.js +103 -0
  512. package/dist/style-asset.d.ts +7 -0
  513. package/dist/style-asset.js +41 -0
  514. package/dist/subscription-chat.d.ts +46 -0
  515. package/dist/subscription-chat.js +275 -0
  516. package/dist/summary.d.ts +33 -0
  517. package/dist/summary.js +71 -0
  518. package/dist/supervisor.mjs +297 -0
  519. package/dist/surface.d.ts +63 -0
  520. package/dist/surface.js +352 -0
  521. package/dist/sync.d.ts +94 -0
  522. package/dist/sync.js +279 -0
  523. package/dist/task-composer.d.ts +13 -0
  524. package/dist/task-composer.js +52 -0
  525. package/dist/task-control.d.ts +165 -0
  526. package/dist/task-control.js +214 -0
  527. package/dist/task-outcome-cli.d.ts +10 -0
  528. package/dist/task-outcome-cli.js +92 -0
  529. package/dist/task-text.d.ts +30 -0
  530. package/dist/task-text.js +41 -0
  531. package/dist/team-cli.d.ts +15 -0
  532. package/dist/team-cli.js +618 -0
  533. package/dist/team-contract.d.ts +92 -0
  534. package/dist/team-contract.js +1 -0
  535. package/dist/team-http.d.ts +17 -0
  536. package/dist/team-http.js +144 -0
  537. package/dist/team-leads.d.ts +81 -0
  538. package/dist/team-leads.js +565 -0
  539. package/dist/team-runtime.d.ts +27 -0
  540. package/dist/team-runtime.js +264 -0
  541. package/dist/team-ui.d.ts +3 -0
  542. package/dist/team-ui.js +9 -0
  543. package/dist/team-updates.d.ts +8 -0
  544. package/dist/team-updates.js +57 -0
  545. package/dist/teammate-admin.d.ts +53 -0
  546. package/dist/teammate-admin.js +111 -0
  547. package/dist/teammate-desk.d.ts +60 -0
  548. package/dist/teammate-desk.js +154 -0
  549. package/dist/teammate-memory.d.ts +64 -0
  550. package/dist/teammate-memory.js +196 -0
  551. package/dist/teammate-question.d.ts +59 -0
  552. package/dist/teammate-question.js +175 -0
  553. package/dist/teammate-tools.d.ts +108 -0
  554. package/dist/teammate-tools.js +271 -0
  555. package/dist/teammate-week.d.ts +68 -0
  556. package/dist/teammate-week.js +132 -0
  557. package/dist/teammate-work.d.ts +76 -0
  558. package/dist/teammate-work.js +280 -0
  559. package/dist/teammates-ui.d.ts +20 -0
  560. package/dist/teammates-ui.js +166 -0
  561. package/dist/teammates.d.ts +180 -0
  562. package/dist/teammates.js +253 -0
  563. package/dist/teams-api.d.ts +33 -0
  564. package/dist/teams-api.js +204 -0
  565. package/dist/teams-chat.d.ts +26 -0
  566. package/dist/teams-chat.js +215 -0
  567. package/dist/teams-settings.d.ts +12 -0
  568. package/dist/teams-settings.js +57 -0
  569. package/dist/teams.d.ts +21 -0
  570. package/dist/teams.js +124 -0
  571. package/dist/telegram-flow.d.ts +49 -0
  572. package/dist/telegram-flow.js +110 -0
  573. package/dist/telegram-mate.d.ts +137 -0
  574. package/dist/telegram-mate.js +707 -0
  575. package/dist/telegram-progress.d.ts +14 -0
  576. package/dist/telegram-progress.js +129 -0
  577. package/dist/telegram-settings.d.ts +9 -0
  578. package/dist/telegram-settings.js +36 -0
  579. package/dist/telegram-status.d.ts +75 -0
  580. package/dist/telegram-status.js +265 -0
  581. package/dist/telegram-team.d.ts +85 -0
  582. package/dist/telegram-team.js +359 -0
  583. package/dist/telegram.d.ts +230 -0
  584. package/dist/telegram.js +1931 -0
  585. package/dist/templates.d.ts +65 -0
  586. package/dist/templates.js +118 -0
  587. package/dist/tool-launcher.d.ts +1 -0
  588. package/dist/tool-launcher.js +101 -0
  589. package/dist/tools-ui.d.ts +30 -0
  590. package/dist/tools-ui.js +40 -0
  591. package/dist/transitions-recipes.d.ts +1 -0
  592. package/dist/transitions-recipes.js +203 -0
  593. package/dist/tree-proof.d.ts +34 -0
  594. package/dist/tree-proof.js +58 -0
  595. package/dist/verification-evidence.d.ts +44 -0
  596. package/dist/verification-evidence.js +238 -0
  597. package/dist/version.d.ts +2 -0
  598. package/dist/version.js +10 -0
  599. package/dist/webhooks.d.ts +91 -0
  600. package/dist/webhooks.js +283 -0
  601. package/dist/work-index.d.ts +68 -0
  602. package/dist/work-index.js +384 -0
  603. package/dist/work-summary.d.ts +57 -0
  604. package/dist/work-summary.js +116 -0
  605. package/dist/workspace-motion.d.ts +4 -0
  606. package/dist/workspace-motion.js +133 -0
  607. package/dist/workspace-revision.d.ts +19 -0
  608. package/dist/workspace-revision.js +92 -0
  609. package/dist/workspace-ui.d.ts +204 -0
  610. package/dist/workspace-ui.js +411 -0
  611. package/dist/worktree-notices.d.ts +13 -0
  612. package/dist/worktree-notices.js +17 -0
  613. package/dist/worktree.d.ts +249 -0
  614. package/dist/worktree.js +720 -0
  615. package/package.json +122 -0
  616. package/scripts/canary-assertions.mjs +42 -0
  617. package/scripts/crash-canary.mjs +253 -0
  618. package/scripts/fixtures/crash-process.mjs +74 -0
  619. package/scripts/fixtures/pilot-scenarios.mjs +85 -0
  620. package/scripts/fixtures/restart-service.mjs +27 -0
  621. package/scripts/launchd-certification.mjs +143 -0
  622. package/scripts/pilot.mjs +121 -0
  623. package/scripts/proof-preflight.mjs +140 -0
  624. package/scripts/provider-canary.mjs +379 -0
  625. package/scripts/recovery-canary.mjs +135 -0
  626. package/scripts/restart-certification.mjs +98 -0
@@ -0,0 +1,399 @@
1
+ /** One assignment follows the existing task family. It owns no execution,
2
+ * approval or proof state. Lead ownership and exact receipt acknowledgments
3
+ * are append-only actions; handoffs use the existing durable outbox. */
4
+ import { createHash } from "node:crypto";
5
+ import { COMPLETION_ACTION, familyChangedFiles } from "./result-completion.js";
6
+ import { homedir } from "node:os";
7
+ import { readSchemaVersion } from "./store.js";
8
+ import { approvalOf } from "./scope.js";
9
+ import { openWorkDecisionOf, taskWorkSummaryOf, workDecisionAction } from "./work-summary.js";
10
+ import { evidenceRoot, readVerifiedArtifact, readVerifiedReport } from "./evidence.js";
11
+ import { verificationEvidence } from "./verification-evidence.js";
12
+ import { reproveApprover } from "./principal.js";
13
+ import { noteAssignmentStatus } from "./assignment-status.js";
14
+ import { historicalAssessmentReason } from "./assignment-presentation.js";
15
+ /** Status-first handoff for routine reads. Fetch get_assignment only when
16
+ * inspecting its exact evidence; do not repeat a full proof in every poll. */
17
+ export function assignmentBrief(assignment) {
18
+ if (assignment === null)
19
+ return null;
20
+ const receipt = assignment.receipt;
21
+ return { version: assignment.version, rootId: assignment.rootId, activeTaskId: assignment.activeTaskId,
22
+ state: assignment.state, detail: assignment.detail, owner: assignment.owner, primaryAction: assignment.primaryAction,
23
+ attention: assignment.attention, attempts: assignment.attempts.length, handoff: assignment.handoff, completion: assignment.completion,
24
+ result: receipt === null ? null : { digest: receipt.digest, taskId: receipt.taskId, runId: receipt.runId,
25
+ base: receipt.base, head: receipt.head, completionKind: receipt.completionKind,
26
+ checks: receipt.checks, proofAcceptance: receipt.proofAcceptance, verdict: receipt.proof?.verdict ?? null,
27
+ criteria: { passed: receipt.proof?.matrix.filter(row => row.state === "pass").length ?? 0, total: receipt.proof?.matrix.length ?? 0 }, evidence: receipt.evidence },
28
+ publication: assignment.publication, deployment: assignment.deployment };
29
+ }
30
+ const digest = (value) => createHash("sha256").update(JSON.stringify(value)).digest("hex");
31
+ const OWNER_ACTION = "assignment claimed";
32
+ const CHECK_ACTION = COMPLETION_ACTION;
33
+ const actorOf = (owner) => `${owner.kind}:${owner.id}`;
34
+ function ownerOf(store, rootId, repo) {
35
+ // The release verifier reads the new projection against the still-running
36
+ // v70 Store before migrating a backup. That read cannot invent team tables.
37
+ const hasTeam = store.handle.prepare("SELECT 1 FROM sqlite_master WHERE type='table' AND name='team_task_owner'").get() !== undefined;
38
+ if (!hasTeam) {
39
+ const version = readSchemaVersion(store.handle);
40
+ if (!version.ok || version.version !== 70)
41
+ throw new Error("Team ownership history is missing; refusing to recreate it.");
42
+ }
43
+ const team = hasTeam ? store.handle.prepare("SELECT l.id,l.name,l.status FROM team_task_owner o JOIN team_lead l ON l.id=o.lead JOIN task_ref r ON r.id=o.task_ref WHERE r.backend='built-in' AND r.external_id=? AND r.repo IS ?").get(rootId, repo) : undefined;
44
+ if (team)
45
+ return { kind: "lead", id: String(team["id"]), label: String(team["name"]), active: team["status"] === "active" };
46
+ const claim = store.handle.prepare("SELECT actor FROM action_ledger WHERE task_id = ? AND action = ? AND source = 'work' ORDER BY id DESC LIMIT 1").get(rootId, OWNER_ACTION);
47
+ const origin = store.lookupRef(rootId)?.coordinatorCid;
48
+ const id = claim === undefined ? origin : String(claim["actor"]).replace(/^coordinator:/, "");
49
+ if (!id)
50
+ return null;
51
+ const credential = store.handle.prepare("SELECT name,repos,revoked_at FROM coordinator_credential WHERE cid = ?").get(id);
52
+ let repos = [];
53
+ try {
54
+ repos = JSON.parse(String(credential?.["repos"] ?? "[]"));
55
+ }
56
+ catch { /* unavailable owner stays inactive */ }
57
+ return { kind: "coordinator", id, label: String(credential?.["name"] ?? "Former lead"),
58
+ active: credential !== undefined && credential["revoked_at"] === null && repo !== null && Array.isArray(repos) && repos.includes(repo) };
59
+ }
60
+ // Report the recorded check outcome, never turn a model verdict into a check.
61
+ function nativeChecks(store, root, runId) {
62
+ const unavailable = (detail) => ({ status: "unavailable", exitCode: null, command: null, logArtifactId: null, detail });
63
+ if (root === undefined)
64
+ return unavailable("Saved checks are unavailable.");
65
+ try {
66
+ const gate = verificationEvidence(store, root, runId);
67
+ if (!gate.ok)
68
+ return unavailable(gate.problem);
69
+ const receipt = gate.bytes === null ? null : JSON.parse(gate.bytes);
70
+ if (receipt === null)
71
+ return { ...unavailable("No machine check is recorded."), status: "not-run" };
72
+ const ran = receipt.result.ran === true, exitCode = ran ? receipt.result.exitCode : null;
73
+ return { status: ran ? exitCode === 0 ? "passed" : "failed" : "not-run", exitCode,
74
+ command: receipt.command.command, logArtifactId: receipt.log.artifactId,
75
+ detail: ran ? exitCode === 0 ? "Checks passed." : `Checks failed (exit ${exitCode}).` : "Checks did not finish." };
76
+ }
77
+ catch {
78
+ return unavailable("Saved checks could not be read.");
79
+ }
80
+ }
81
+ export function assignmentOf(store, taskId, now, access, root) {
82
+ const family = store.taskFamilyOf(taskId, access.repos, access.principal === "operator" && access.includeUnplaced === true);
83
+ if (family === null)
84
+ return null;
85
+ const current = family.current;
86
+ const work = taskWorkSummaryOf(store, current.id, now, access);
87
+ if (work === null)
88
+ return null;
89
+ const result = work.resultRunId === null ? null : store.getRun(work.resultRunId);
90
+ const proof = result === null ? null : store.proofVerdictFor(result.id);
91
+ const acceptance = result === null ? null : store.proofAcceptance(result.id);
92
+ const scope = store.getScope(current.id);
93
+ const owner = ownerOf(store, family.root.id, current.repo);
94
+ const attention = family.problem === null ? [] : [family.problem];
95
+ // Family admission above precedes question bodies. The newest result
96
+ // does not settle an unanswered question on any earlier version.
97
+ const questions = [current, ...family.versions.filter(version => version.id !== current.id)].flatMap(version => {
98
+ const decision = openWorkDecisionOf(store, version.refId, now);
99
+ return decision === null ? [] : [{ taskId: version.id, decision }];
100
+ });
101
+ // A finished task label cannot hide a lease or an unfinished process record.
102
+ const earlierActive = family.versions.filter(version => version.id !== current.id &&
103
+ (version.state === "queued" || version.state === "running" || store.currentLiveLease(version.refId, now) !== null ||
104
+ store.runsFor(version.refId).some(run => run.outcome === null || store.stopQuiescenceProblem(run.id) !== null)));
105
+ const unfinished = store.runsFor(current.refId).find(run => run.outcome === null) ?? null;
106
+ const attempts = family.versions.map(version => {
107
+ const summary = version.id === current.id ? work : taskWorkSummaryOf(store, version.id, now, access);
108
+ return { taskId: version.id, runId: summary?.liveRunId ?? summary?.resultRunId ?? null,
109
+ label: summary?.status.label ?? version.state, detail: summary?.status.detail ?? "Status is unavailable." };
110
+ });
111
+ const artifacts = result === null ? [] : store.artifactsFor(result.id);
112
+ const reports = artifacts.filter(a => a.kind === "report");
113
+ const unavailable = family.versions.flatMap(version => store.runsFor(version.refId).flatMap(run => store.artifactsFor(run.id).filter(artifact => root === undefined || !readVerifiedArtifact(root, artifact).ok)
114
+ .map(artifact => `Saved ${artifact.kind} #${artifact.id} (run ${run.id}) is unavailable or changed.`)));
115
+ const checks = result === null ? null : nativeChecks(store, root, result.id);
116
+ const finishedBuild = result?.role === "builder" && (result.outcome === "built" || result.outcome === "no-change") &&
117
+ result.finishedAt !== null && /^[a-f0-9]{40}$/.test(result.headRevision ?? "");
118
+ // Finished work returns to its lead or user. Strict terms and previous model
119
+ // judgments stay recorded; neither is a second execution stage for handoff.
120
+ const completionKind = result?.role === "scout" && result.outcome === "built" && result.finishedAt !== null ? "research-report"
121
+ : finishedBuild && acceptance !== null ? "accepted-exception"
122
+ : finishedBuild ? checks?.status === "passed" ? "checked-build" : "finished-build" : null;
123
+ const receiptBody = result === null ? null : {
124
+ rootId: family.root.id, taskId: current.id, runId: result.id, base: result.baseRevision,
125
+ head: result.headRevision, scopeDigest: result.scopeDigest ?? null, proof, completionKind, proofAcceptance: acceptance, checks: checks,
126
+ artifacts: artifacts.map(a => ({ id: a.id, kind: a.kind, sha256: a.sha256, bytes: a.bytesStored,
127
+ complete: !a.truncated && a.captureStatus !== "failed" })),
128
+ // Stored verdict limitations are separate from the agent's outcome.
129
+ // Full agent caveats remain in the referenced proof artifact.
130
+ caveats: [...(proof?.reasons ?? []), ...unavailable,
131
+ ...(completionKind === "research-report" && reports.length !== 1 ? ["The report artifact is missing or ambiguous."] : []), ...(completionKind === "accepted-exception" && !artifacts.some(a => a.kind === "proof") ? ["No builder proof artifact is recorded."] : []),
132
+ ...(artifacts.some(a => a.kind === "check-log" && a.truncated) ? ["The check log was shortened when stored; only the retained output is available."] : []),
133
+ ...artifacts.filter(a => a.kind !== "check-log" && (a.truncated || a.captureStatus === "failed")).map(a => `Saved ${a.kind} #${a.id} is ${a.captureStatus === "failed" ? "a failed capture" : "incomplete"}.`)],
134
+ agentReport: result.handoff, evidence: "recorded",
135
+ };
136
+ const receipt = receiptBody === null ? null : { ...receiptBody, digest: digest({ receipt: receiptBody,
137
+ scope: scope === null ? null : { digest: scope.digest, approved: approvalOf(scope).approved, termsProblem: scope.termsProblem ?? null },
138
+ versions: family.versions.map(v => ({ id: v.id, state: v.state })) }) };
139
+ let completion = null;
140
+ let state = "working";
141
+ let detail = work.status.detail;
142
+ let primaryAction = work.primaryAction;
143
+ const live = work.liveRunId !== null || work.status.token === "running";
144
+ const processProblem = result === null ? null : store.stopQuiescenceProblem(result.id);
145
+ // The exact completed result, scope, family and custody fences apply to
146
+ // every deliverable. Human acceptance remains its own recorded authority;
147
+ // it never changes a machine verdict or supplies a missing report.
148
+ const ready = current.state === "done" && result !== null && completionKind !== null &&
149
+ scope !== null && scope.termsProblem == null && approvalOf(scope).approved && scope.digest === result.scopeDigest &&
150
+ store.activeHolds(current.refId, now).length === 0 && store.applicableStopFor(result.id) === null &&
151
+ processProblem === null &&
152
+ family.problem === null && earlierActive.length === 0 && unfinished === null && store.currentLiveLease(current.refId, now) === null && questions.length === 0;
153
+ if (family.problem !== null)
154
+ state = "needs-decision";
155
+ else if (current.state === "cancelled") {
156
+ state = "cancelled";
157
+ detail = "This assignment was cancelled.";
158
+ primaryAction = { code: "inspect-task", label: "View assignment", target: { taskId: current.id, runId: null, decisionId: null }, access: "read", retry: "read-again" };
159
+ }
160
+ else if (!live && processProblem !== null && result !== null) {
161
+ state = "needs-decision";
162
+ detail = processProblem;
163
+ primaryAction = { code: "inspect-run", label: "Inspect run", target: { taskId: current.id, runId: result.id, decisionId: null }, access: "read", retry: "read-again" };
164
+ }
165
+ else if (current.state === "done" && questions.length > 0 && work.status.tone !== "problem" &&
166
+ !["stopping", "stopped", "review-failed", "review-exhausted"].includes(work.status.token) &&
167
+ store.activeHolds(current.refId, now).length === 0 && (result === null || store.applicableStopFor(result.id) === null)) {
168
+ const question = questions[0];
169
+ state = "needs-decision";
170
+ detail = question.decision.question;
171
+ primaryAction = workDecisionAction(question.taskId, question.decision, access.principal);
172
+ }
173
+ else if (ready && receipt !== null) {
174
+ state = "ready-to-check";
175
+ detail = completionKind === "research-report" ? "The research report is ready for the lead to read."
176
+ : completionKind === "accepted-exception" ? "An operator accepted this result with its recorded limitations. The lead can inspect that decision; the recorded checks are unchanged."
177
+ : receipt.checks.detail;
178
+ primaryAction = { code: "open-result", label: completionKind === "research-report" ? "Read report" : receipt.checks.status === "failed" ? "Inspect failed check" : completionKind === "accepted-exception" ? "Review acceptance" : "Open result", target: { taskId: current.id, runId: result.id, decisionId: null }, access: "read", retry: "read-again" };
179
+ const checked = store.handle.prepare("SELECT actor,at FROM action_ledger WHERE task_id = ? AND run_id = ? AND action = ? AND outcome = ? AND source = 'work' ORDER BY id DESC")
180
+ .all(family.root.id, result.id, CHECK_ACTION, receipt.digest).find(row => /^(operator|coordinator|lead):.+/.test(String(row["actor"])));
181
+ // This ledger fact was authorized when written. Credential rotation,
182
+ // membership changes and ownership transfer cannot revoke past completion.
183
+ // The exact result digest still fences changes to work, scope and history.
184
+ if (checked !== undefined) {
185
+ completion = { actor: String(checked["actor"]), at: String(checked["at"]), digest: receipt.digest };
186
+ state = "complete";
187
+ primaryAction = { ...primaryAction, label: completionKind === "research-report" ? "Read report" : "Open result" };
188
+ const label = completion.actor.startsWith("operator:") ? completion.actor.slice(9) : owner && completion.actor === actorOf(owner) ? owner.label : "the previous lead";
189
+ detail = completionKind === "research-report" ? `Research report checked by ${label}. No deployment is implied.`
190
+ : `Handled by ${label}. ${receipt.checks.detail} Publication and deployment are separate.`;
191
+ }
192
+ }
193
+ else if (work.status.rank === 0 || (!live && (current.state === "done" || current.state === "failed" || work.status.views.includes("needs-you")))) {
194
+ state = "needs-decision";
195
+ if (current.state === "done" && work.status.tone !== "attention" && work.status.tone !== "problem")
196
+ detail = result?.role === "scout"
197
+ ? completionKind === null ? "The research report is missing or incomplete. Inspect the saved report before checking this handoff."
198
+ : "The saved report is awaiting resolution of its current scope or hold."
199
+ : "Inspect the saved result and resolve its remaining execution or scope issue.";
200
+ }
201
+ if (earlierActive.length > 0) {
202
+ attention.push(`${earlierActive.length} earlier task version${earlierActive.length === 1 ? " is" : "s are"} still active.`);
203
+ if (state === "ready-to-check" || state === "complete" || current.state === "done") {
204
+ state = "needs-decision";
205
+ detail = "Earlier work is still active. Resolve it before completing this assignment.";
206
+ const earlier = earlierActive[0];
207
+ primaryAction = taskWorkSummaryOf(store, earlier.id, now, access)?.primaryAction ?? {
208
+ code: "inspect-task", label: "Review active work", target: { taskId: earlier.id, runId: null, decisionId: null }, access: "read", retry: "read-again",
209
+ };
210
+ }
211
+ }
212
+ if (state === "needs-decision")
213
+ attention.push(detail);
214
+ if (receipt !== null) {
215
+ if (finishedBuild && receipt.checks.status !== "passed")
216
+ attention.push(receipt.checks.detail);
217
+ if (proof?.verdict !== "verified")
218
+ attention.push(...(proof?.reasons ?? []).filter(reason => !historicalAssessmentReason(reason)));
219
+ attention.push(...receipt.caveats.filter(reason => !proof?.reasons.includes(reason)));
220
+ }
221
+ if (state !== "complete")
222
+ completion = null;
223
+ if (current.state !== "cancelled")
224
+ attention.push(...questions.map(question => question.decision.question));
225
+ if (owner !== null && !owner.active)
226
+ attention.push(owner.kind === "lead" ? "This lead is paused. A manager can resume it or transfer responsibility." : "The previous lead no longer has access. Another lead can claim this assignment.");
227
+ const handoff = state === "ready-to-check" || state === "complete" ? { kind: "result", digest: receipt.digest, acknowledged: state === "complete" }
228
+ : state === "cancelled" ? { kind: "attention", digest: digest({ root: family.root.id, current: current.id, state }), acknowledged: false }
229
+ : state === "needs-decision" ? { kind: primaryAction?.target.decisionId != null ? "decision" : "attention",
230
+ digest: digest({ root: family.root.id, current: current.id, detail,
231
+ action: primaryAction === null ? null : { code: primaryAction.code, target: primaryAction.target },
232
+ attention, receipt: receipt?.digest ?? null }), acknowledged: false } : null;
233
+ const publication = result === null ? null : store.publicationForRun(result.id);
234
+ // Existing saved inputs and output, read only after family admission. Keep
235
+ // polling briefs small; full reads disclose exactly which excerpts are shortened.
236
+ const planId = result?.planRevision == null ? null : store.getPlanRevision(result.planRevision)?.artifact;
237
+ const plan = planId == null ? store.latestPlanArtifact(current.refId) : store.getArtifact(planId);
238
+ const selected = [plan, ...["terminal-diff", "check-log", "report", "handoff"].map(kind => artifacts.filter(artifact => artifact.kind === kind).at(-1) ?? null)].filter((one) => one !== null);
239
+ const savedContext = { goal: scope?.goal ?? null, outOfScope: scope?.outOfScope ?? null,
240
+ excerpts: selected.map(artifact => {
241
+ const read = root === undefined ? null : readVerifiedArtifact(root, artifact);
242
+ const text = read?.ok ? read.content.toString("utf8") : null;
243
+ return { artifactId: artifact.id, runId: artifact.run, kind: artifact.kind, sha256: artifact.sha256,
244
+ text: text?.slice(0, 8000) ?? null, shortened: artifact.truncated || (text?.length ?? 0) > 8000,
245
+ problem: read?.ok ? artifact.captureStatus === "failed" ? "The original capture failed." : null : "Saved bytes are unavailable or changed." };
246
+ }) };
247
+ return { version: 1, rootId: family.root.id, activeTaskId: current.id, repo: current.repo, title: family.root.title,
248
+ state, detail, primaryAction, attention: [...new Set(attention)], attempts, owner, receipt, savedContext, completion, handoff,
249
+ publication: publication === null ? null : { state: publication.state, prUrl: publication.prUrl, remoteState: publication.remoteState },
250
+ deployment: { status: "not-recorded" } };
251
+ }
252
+ function admittedOwner(store, taskId, owner, now, root) {
253
+ if (owner.kind !== "coordinator")
254
+ return null; // A stable lead is identity, not a bearer credential.
255
+ const row = store.handle.prepare("SELECT repos, revoked_at FROM coordinator_credential WHERE cid = ?").get(owner.id);
256
+ if (row === undefined || row["revoked_at"] !== null)
257
+ return null;
258
+ let repos;
259
+ try {
260
+ repos = JSON.parse(String(row["repos"]));
261
+ }
262
+ catch {
263
+ return null;
264
+ }
265
+ if (!Array.isArray(repos) || repos.some(r => typeof r !== "string"))
266
+ return null;
267
+ return assignmentOf(store, taskId, now, { principal: "coordinator", repos }, root);
268
+ }
269
+ export function claimAssignment(store, taskId, owner, now, root) {
270
+ return store.transact(() => {
271
+ const current = admittedOwner(store, taskId, owner, now, root);
272
+ if (current === null)
273
+ return { ok: false, reason: "not-found", message: "No assignment is available in your projects." };
274
+ if (current.owner?.kind === "lead" || current.owner?.active && current.owner.id !== owner.id)
275
+ return { ok: false, reason: "owned", message: "Another lead already owns this assignment." };
276
+ if (current.owner?.id !== owner.id) {
277
+ store.recordAction({ at: now.toISOString(), actor: actorOf(owner), repo: current.repo,
278
+ taskId: current.rootId, runId: null, action: OWNER_ACTION, outcome: "owner", source: "work" });
279
+ store.bumpWake();
280
+ }
281
+ const assignment = admittedOwner(store, current.rootId, owner, now, root);
282
+ noteAssignmentHandoff(store, assignment, now);
283
+ noteAssignmentStatus(store, assignment, now);
284
+ return { ok: true, assignment };
285
+ });
286
+ }
287
+ /** Diagnostic only: artifact availability does not authorize or block a human
288
+ * handoff. Deployment independently validates its actual native check. */
289
+ export function assignmentEvidenceIntact(store, root, receipt) {
290
+ try {
291
+ const family = store.taskFamilyOf(receipt.taskId, null, true);
292
+ if (family === null || family.problem !== null || family.root.id !== receipt.rootId ||
293
+ !family.versions.every(version => store.runsFor(version.refId).every(run => store.artifactsFor(run.id).every(artifact => readVerifiedArtifact(root, artifact).ok))))
294
+ return false;
295
+ if (receipt.completionKind === "research-report") {
296
+ const report = readVerifiedReport(store, root, store.lookupRef(receipt.taskId).id);
297
+ return report?.ok === true && report.run === receipt.runId;
298
+ }
299
+ return receipt.completionKind !== null;
300
+ }
301
+ catch {
302
+ return false;
303
+ }
304
+ }
305
+ function acknowledgeCurrent(store, current, receiptDigest, actor, now, root, access) {
306
+ if (!/^[a-f0-9]{64}$/.test(receiptDigest) || current.receipt?.digest !== receiptDigest)
307
+ return { ok: false, reason: "stale", message: "The result changed. Read the current assignment before checking it." };
308
+ const receipt = current.receipt;
309
+ if (current.state !== "ready-to-check" && current.state !== "complete")
310
+ return { ok: false, reason: "not-ready", message: "This assignment still has unresolved execution, scope or decisions." };
311
+ if (current.state !== "complete") {
312
+ // v102: declared paths are only a promise. A result whose actual diff reaches protected files, on a
313
+ // scope one person approved, completes only by someone else — two people have then seen the work.
314
+ const problem = store.protectedResultProblem(receipt.taskId, familyChangedFiles(store, receipt.taskId, receipt.runId, root), actor.startsWith("operator:") ? actor.slice("operator:".length) : null);
315
+ if (problem !== null)
316
+ return { ok: false, reason: "approval-rules", message: problem };
317
+ store.recordAction({ at: now.toISOString(), actor, repo: current.repo,
318
+ taskId: current.rootId, runId: receipt.runId, action: CHECK_ACTION, outcome: receiptDigest, source: "work" });
319
+ store.bumpWake();
320
+ }
321
+ const assignment = assignmentOf(store, current.rootId, now, access, root);
322
+ noteAssignmentStatus(store, assignment, now);
323
+ return { ok: true, assignment };
324
+ }
325
+ export function checkAssignment(store, taskId, receiptDigest, owner, now, root = evidenceRoot(homedir())) {
326
+ return store.transact(() => {
327
+ const current = admittedOwner(store, taskId, owner, now, root);
328
+ if (current === null)
329
+ return { ok: false, reason: "not-found", message: "No assignment is available in your projects." };
330
+ if (current.owner?.kind !== owner.kind || current.owner.id !== owner.id || !current.owner.active)
331
+ return { ok: false, reason: "not-owner", message: "Claim this assignment before checking its handoff." };
332
+ return acknowledgeCurrent(store, current, receiptDigest, actorOf(owner), now, root, { principal: "coordinator", repos: [current.repo] });
333
+ });
334
+ }
335
+ /** The signed-in user can mark the same exact receipt handled without taking
336
+ * lead ownership. This records review, never check success or new authority. */
337
+ export function checkAssignmentAsOperator(store, taskId, receiptDigest, who, now, root = evidenceRoot(homedir())) {
338
+ return store.transact(() => {
339
+ if (!reproveApprover(store, who).ok)
340
+ return { ok: false, reason: "unauthenticated", message: "Sign in again before marking this result complete." };
341
+ const access = { principal: "operator", repos: who.repos };
342
+ const current = assignmentOf(store, taskId, now, access, root);
343
+ if (current === null || !store.accountCanAccess(who.name, current.repo))
344
+ return { ok: false, reason: "not-found", message: "No assignment is available in your projects." };
345
+ return acknowledgeCurrent(store, current, receiptDigest, `operator:${who.name}`, now, root, access);
346
+ });
347
+ }
348
+ function noteAssignmentHandoff(store, assignment, now) {
349
+ if (!assignment.owner?.active || assignment.handoff === null || assignment.handoff.acknowledged)
350
+ return;
351
+ const ref = store.lookupRef(assignment.rootId);
352
+ if (!ref || !ref.repo)
353
+ return;
354
+ store.enqueueNotification({ dedupeKey: `assignment:${ref.id}:${assignment.owner.id}:${assignment.handoff.digest}`,
355
+ kind: "assignment-handoff", source: { taskRef: ref.id }, subject: assignment.state === "cancelled" ? "Assignment cancelled" : assignment.state === "ready-to-check" ? "Ready" : "Assignment needs a decision",
356
+ body: assignment.detail, link: `/t/${encodeURIComponent(assignment.rootId)}` }, now);
357
+ }
358
+ /** The ordinary worker reconciles at most 50 owned roots per pass. A lost
359
+ * wakeup is recovered after restart; immutable notification keys dedupe it. */
360
+ export function syncAssignmentHandoffs(store, now, repos, root) {
361
+ if (repos.length === 0)
362
+ return;
363
+ store.transact(() => {
364
+ const key = `assignment-handoff:${digest([...new Set(repos)].sort())}`;
365
+ const cursor = store.serviceCursor(key);
366
+ const rows = store.handle.prepare(`SELECT t.id,t.external_id FROM task_ref t WHERE t.backend = 'built-in' AND t.revision_of IS NULL
367
+ AND t.repo IN (SELECT value FROM json_each(?)) AND t.id > ?
368
+ AND (t.coordinator_cid IS NOT NULL OR EXISTS(SELECT 1 FROM team_task_owner o WHERE o.task_ref=t.id) OR EXISTS (SELECT 1 FROM action_ledger a WHERE a.task_id = t.external_id AND a.action = ?))
369
+ ORDER BY t.id LIMIT 50`).all(JSON.stringify(repos), cursor, OWNER_ACTION);
370
+ for (const row of rows) {
371
+ const assignment = assignmentOf(store, String(row["external_id"]), now, { principal: "operator", repos }, root);
372
+ if (assignment !== null) {
373
+ noteAssignmentHandoff(store, assignment, now);
374
+ noteAssignmentStatus(store, assignment, now);
375
+ }
376
+ }
377
+ store.setServiceCursor(key, rows.length < 50 ? 0 : Number(rows.at(-1)["id"]), now);
378
+ });
379
+ }
380
+ export function assignmentUpdates(store, now, access, query, root) {
381
+ const after = Number.isSafeInteger(query.after) && query.after >= 0 ? query.after : 0;
382
+ const limit = Math.max(1, Math.min(100, Math.floor(query.limit) || 50));
383
+ const rows = store.handle.prepare(`SELECT n.id,n.task_id,n.dedupe_key,n.created_at FROM notification n
384
+ JOIN task_ref t ON t.id = n.task_ref AND t.backend = 'built-in' AND t.external_id = n.task_id AND t.repo = n.project
385
+ WHERE n.id > ? AND n.kind = 'assignment-handoff' AND n.provenance_scope = 'task'
386
+ AND (? = 1 OR n.project IN (SELECT value FROM json_each(?))) ORDER BY n.id LIMIT ?`)
387
+ .all(after, access.repos === null ? 1 : 0, JSON.stringify(access.repos ?? []), limit + 1);
388
+ const page = rows.slice(0, limit);
389
+ const events = page.flatMap(row => {
390
+ const assignment = assignmentOf(store, String(row["task_id"]), now, access, root);
391
+ if (assignment === null)
392
+ return [];
393
+ const parts = String(row["dedupe_key"]).split(":");
394
+ const receiptDigest = parts.at(-1);
395
+ return [{ id: Number(row["id"]), createdAt: String(row["created_at"]), rootId: assignment.rootId, digest: receiptDigest,
396
+ superseded: assignment.handoff?.digest !== receiptDigest || assignment.owner?.id !== parts.at(-2), assignment: assignmentBrief(assignment) }];
397
+ });
398
+ return { events, nextCursor: page.length === 0 ? after : Number(page.at(-1)["id"]), hasMore: rows.length > limit };
399
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Tier-2 attestation (Parity II Phase 3, spec v1 D6 + v2 A2 + v3 B3 + v4 C3):
3
+ * a provider outside tier 1 runs ONLY at versions its conformance fixtures
4
+ * were proven against. The check is enforced at the one spawning gateway —
5
+ * this module only states ranges and probes binaries; it spawns no agent.
6
+ *
7
+ * Guarantee, stated exactly (v4 C3): attestation proves the version of the
8
+ * binary OBSERVED AT SPAWN TIME — probe and spawn share one resolved
9
+ * absolute path, revalidated by a fresh stat immediately before use. A
10
+ * concurrent atomic replacement between that stat and the kernel exec is
11
+ * acknowledged as unprovable without content-addressed snapshots, and
12
+ * nothing here claims otherwise.
13
+ *
14
+ * Re-attestation is a release act: run the conformance suite against the
15
+ * new CLI, move `ceiling` in a reviewed commit. Removal criterion (ruling
16
+ * 13's N, fixed): three consecutive minor releases failing conformance
17
+ * without a fixable adapter change retire the adapter, typed.
18
+ */
19
+ import { type ProviderId } from "./provider.js";
20
+ export type AttestationRange = {
21
+ /** Lowest plain release the fixtures cover, inclusive. */
22
+ floor: string;
23
+ /** First release the fixtures do NOT cover, exclusive. */
24
+ ceiling: string;
25
+ /** The exact version the current fixture set was recorded against. */
26
+ fixturesAt: string;
27
+ };
28
+ /** Tier-1 providers deliberately have NO entry: no probe, no new refusal —
29
+ * their spawn road stays byte-identical (spec A2). */
30
+ export declare const ATTESTATIONS: Partial<Record<ProviderId, AttestationRange>>;
31
+ export declare function attestationOf(provider: ProviderId): AttestationRange | null;
32
+ export type AttestOutcome = {
33
+ ok: true;
34
+ executable: string;
35
+ version: string;
36
+ } | {
37
+ ok: false;
38
+ problem: string;
39
+ version: string | null;
40
+ };
41
+ export type VersionProbe = (file: string, args: readonly string[], timeoutMs: number) => Promise<{
42
+ code: number;
43
+ stdout: string;
44
+ }>;
45
+ export declare function versionInRange(version: string, range: AttestationRange): boolean;
46
+ /** PATH resolution to ONE absolute realpath — the path the probe runs and
47
+ * the path the gateway spawns (v3 B3: no second resolution). */
48
+ export declare function resolveExecutable(binary: string): string | null;
49
+ /** Tests only. */
50
+ export declare function resetAttestationCache(): void;
51
+ /**
52
+ * The pre-spawn check (v2 A2): resolve, revalidate, probe if anything
53
+ * moved, compare. Every failure is a typed refusal with words — never a
54
+ * throw, never a silent pass. Returns null for tier-1 providers.
55
+ */
56
+ export declare function attestProvider(provider: ProviderId, binary: string, probe?: VersionProbe): Promise<AttestOutcome | null>;
package/dist/attest.js ADDED
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Tier-2 attestation (Parity II Phase 3, spec v1 D6 + v2 A2 + v3 B3 + v4 C3):
3
+ * a provider outside tier 1 runs ONLY at versions its conformance fixtures
4
+ * were proven against. The check is enforced at the one spawning gateway —
5
+ * this module only states ranges and probes binaries; it spawns no agent.
6
+ *
7
+ * Guarantee, stated exactly (v4 C3): attestation proves the version of the
8
+ * binary OBSERVED AT SPAWN TIME — probe and spawn share one resolved
9
+ * absolute path, revalidated by a fresh stat immediately before use. A
10
+ * concurrent atomic replacement between that stat and the kernel exec is
11
+ * acknowledged as unprovable without content-addressed snapshots, and
12
+ * nothing here claims otherwise.
13
+ *
14
+ * Re-attestation is a release act: run the conformance suite against the
15
+ * new CLI, move `ceiling` in a reviewed commit. Removal criterion (ruling
16
+ * 13's N, fixed): three consecutive minor releases failing conformance
17
+ * without a fixable adapter change retire the adapter, typed.
18
+ */
19
+ import { execFile } from "node:child_process";
20
+ import { realpathSync, statSync, accessSync, constants } from "node:fs";
21
+ import { delimiter, isAbsolute, join } from "node:path";
22
+ import { ALL_CREDENTIAL_ENV } from "./provider.js";
23
+ /** Tier-1 providers deliberately have NO entry: no probe, no new refusal —
24
+ * their spawn road stays byte-identical (spec A2). */
25
+ export const ATTESTATIONS = {
26
+ gemini: { floor: "0.57.0", ceiling: "0.58.0", fixturesAt: "0.57.0" },
27
+ };
28
+ export function attestationOf(provider) {
29
+ return ATTESTATIONS[provider] ?? null;
30
+ }
31
+ const PROBE_TIMEOUT_MS = 5_000;
32
+ /** Only a PLAIN release attests (v2 A2): prerelease, nightly, malformed,
33
+ * or empty version strings are out of range BY RULE, not by comparison. */
34
+ const PLAIN_SEMVER = /^(\d+)\.(\d+)\.(\d+)$/;
35
+ function parsePlain(version) {
36
+ const match = PLAIN_SEMVER.exec(version.trim());
37
+ if (match === null)
38
+ return null;
39
+ return [Number(match[1]), Number(match[2]), Number(match[3])];
40
+ }
41
+ function atLeast(a, b) {
42
+ if (a[0] !== b[0])
43
+ return a[0] > b[0];
44
+ if (a[1] !== b[1])
45
+ return a[1] > b[1];
46
+ return a[2] >= b[2];
47
+ }
48
+ export function versionInRange(version, range) {
49
+ const v = parsePlain(version);
50
+ const floor = parsePlain(range.floor);
51
+ const ceiling = parsePlain(range.ceiling);
52
+ if (v === null || floor === null || ceiling === null)
53
+ return false;
54
+ return atLeast(v, floor) && !atLeast(v, ceiling);
55
+ }
56
+ /** PATH resolution to ONE absolute realpath — the path the probe runs and
57
+ * the path the gateway spawns (v3 B3: no second resolution). */
58
+ export function resolveExecutable(binary) {
59
+ const candidates = [];
60
+ if (binary.includes("/") || isAbsolute(binary)) {
61
+ candidates.push(binary);
62
+ }
63
+ else {
64
+ for (const dir of (process.env["PATH"] ?? "").split(delimiter)) {
65
+ if (dir !== "")
66
+ candidates.push(join(dir, binary));
67
+ }
68
+ }
69
+ for (const candidate of candidates) {
70
+ try {
71
+ accessSync(candidate, constants.X_OK);
72
+ return realpathSync(candidate);
73
+ }
74
+ catch {
75
+ continue;
76
+ }
77
+ }
78
+ return null;
79
+ }
80
+ const cache = new Map();
81
+ /** Tests only. */
82
+ export function resetAttestationCache() {
83
+ cache.clear();
84
+ }
85
+ const defaultProbe = (file, args, timeoutMs) => new Promise(resolve => {
86
+ // A version probe needs NO credential (Codex gemini verify, finding
87
+ // 2): strip every provider key from the child so an authoritative
88
+ // attestation spawn cannot leak one.
89
+ const env = { ...process.env };
90
+ for (const name of ALL_CREDENTIAL_ENV)
91
+ delete env[name];
92
+ execFile(file, [...args], { timeout: timeoutMs, encoding: "utf8", env }, (error, stdout) => {
93
+ resolve({ code: error === null ? 0 : 1, stdout: String(stdout ?? "") });
94
+ });
95
+ });
96
+ /**
97
+ * The pre-spawn check (v2 A2): resolve, revalidate, probe if anything
98
+ * moved, compare. Every failure is a typed refusal with words — never a
99
+ * throw, never a silent pass. Returns null for tier-1 providers.
100
+ */
101
+ export async function attestProvider(provider, binary, probe = defaultProbe) {
102
+ const range = attestationOf(provider);
103
+ if (range === null)
104
+ return null;
105
+ const resolved = resolveExecutable(binary);
106
+ if (resolved === null) {
107
+ return { ok: false, problem: `${binary} is not installed on this runner's PATH`, version: null };
108
+ }
109
+ let stat;
110
+ try {
111
+ const s = statSync(resolved);
112
+ stat = { dev: s.dev, ino: s.ino, ctimeMs: s.ctimeMs, size: s.size };
113
+ }
114
+ catch {
115
+ return { ok: false, problem: `${resolved} vanished while being checked`, version: null };
116
+ }
117
+ const cached = cache.get(provider);
118
+ let version;
119
+ if (cached !== undefined &&
120
+ cached.realpath === resolved &&
121
+ cached.dev === stat.dev &&
122
+ cached.ino === stat.ino &&
123
+ cached.ctimeMs === stat.ctimeMs &&
124
+ cached.size === stat.size) {
125
+ version = cached.version;
126
+ }
127
+ else {
128
+ const answer = await probe(resolved, ["--version"], PROBE_TIMEOUT_MS);
129
+ const raw = answer.stdout.trim().slice(0, 100);
130
+ if (answer.code !== 0 || raw === "") {
131
+ cache.delete(provider);
132
+ return { ok: false, problem: `${resolved} did not answer --version`, version: null };
133
+ }
134
+ if (parsePlain(raw) === null) {
135
+ cache.delete(provider);
136
+ return {
137
+ ok: false,
138
+ problem: `${binary} reports version \`${raw}\` — only plain releases attest, and this is not one`,
139
+ version: raw,
140
+ };
141
+ }
142
+ version = raw;
143
+ cache.set(provider, { realpath: resolved, ...stat, version });
144
+ }
145
+ if (!versionInRange(version, range)) {
146
+ return {
147
+ ok: false,
148
+ problem: `${binary} ${version} is installed; ${range.floor} up to (not including) ${range.ceiling} is the attested range — re-attestation is a release act, not a retry`,
149
+ version,
150
+ };
151
+ }
152
+ return { ok: true, executable: resolved, version };
153
+ }