@jr2/orchestrator 0.5.1 → 0.7.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 (350) hide show
  1. package/console/components/app.ts +55 -15
  2. package/console/components/bottom-drawer.ts +259 -0
  3. package/console/components/drawer.ts +14 -6
  4. package/console/components/fleet.ts +36 -13
  5. package/console/components/machine-pane.ts +61 -5
  6. package/console/components/nav.ts +54 -8
  7. package/console/conversation.ts +161 -0
  8. package/console/login.ts +123 -0
  9. package/console/main.ts +600 -60
  10. package/console/store.ts +611 -64
  11. package/console/style.css +231 -0
  12. package/docs/agents-block.md +2 -2
  13. package/docs/concepts/agents-and-turns.md +142 -29
  14. package/docs/concepts/architecture.md +60 -34
  15. package/docs/concepts/callers-and-hooks.md +205 -0
  16. package/docs/concepts/charts.md +13 -8
  17. package/docs/concepts/composition.md +10 -1
  18. package/docs/concepts/converge.md +7 -2
  19. package/docs/concepts/durable-runs.md +43 -16
  20. package/docs/concepts/effects.md +133 -50
  21. package/docs/concepts/gates.md +95 -25
  22. package/docs/concepts/machines-and-workflows.md +14 -4
  23. package/docs/concepts/pools-and-sources.md +193 -17
  24. package/docs/concepts/secrets-and-trust.md +186 -62
  25. package/docs/concepts/the-menu.md +14 -0
  26. package/docs/concepts/workspaces.md +135 -56
  27. package/docs/get-started/a-model-decides.md +14 -13
  28. package/docs/get-started/an-agent-in-a-sandbox.md +46 -35
  29. package/docs/get-started/connect-a-model.md +1 -1
  30. package/docs/get-started/create-an-instance.md +17 -14
  31. package/docs/get-started/have-your-assistant-write-a-machine.md +111 -40
  32. package/docs/get-started/install.md +4 -0
  33. package/docs/guides/add-tools-to-the-sandbox.md +72 -15
  34. package/docs/guides/answer-a-gate-from-a-forge.md +304 -0
  35. package/docs/guides/answer-a-gate.md +74 -37
  36. package/docs/guides/bind-open-parts.md +29 -12
  37. package/docs/guides/call-an-mcp-tool-from-a-machine.md +572 -0
  38. package/docs/guides/cancel-a-run.md +26 -16
  39. package/docs/guides/cut-a-worktree.md +560 -0
  40. package/docs/guides/fix-a-failed-converge.md +19 -7
  41. package/docs/guides/give-a-caller-a-scope.md +203 -0
  42. package/docs/guides/give-an-agent-mcp-tools.md +422 -0
  43. package/docs/guides/iterate-on-a-machine-on-kind.md +10 -9
  44. package/docs/guides/let-an-agent-write-a-chart.md +14 -7
  45. package/docs/guides/look-inside-a-sandbox.md +115 -42
  46. package/docs/guides/move-from-kind-to-a-shared-cluster.md +16 -0
  47. package/docs/guides/open-the-console.md +63 -14
  48. package/docs/guides/push-and-sign-a-branch.md +67 -21
  49. package/docs/guides/read-a-conversation.md +225 -0
  50. package/docs/guides/run-a-chart-by-name.md +17 -16
  51. package/docs/guides/run-a-command-or-call-a-url.md +84 -41
  52. package/docs/guides/run-one-worker-per-item.md +34 -27
  53. package/docs/guides/set-an-agents-access-and-dials.md +69 -22
  54. package/docs/guides/size-a-workspace.md +19 -6
  55. package/docs/guides/start-a-run-for-each-alert.md +290 -0
  56. package/docs/guides/start-a-run-from-a-run.md +18 -16
  57. package/docs/guides/start-a-run.md +24 -18
  58. package/docs/guides/steer-an-agent.md +332 -0
  59. package/docs/guides/use-a-hosted-provider.md +7 -1
  60. package/docs/guides/watch-a-run.md +146 -117
  61. package/docs/guides/write-a-hook-kind.md +238 -0
  62. package/docs/guides/write-a-tool-as-an-mcp-server.md +351 -0
  63. package/docs/guides/write-a-workflow.md +18 -8
  64. package/docs/llms.txt +110 -23
  65. package/docs/reference/authoring-surface/agent.md +35 -12
  66. package/docs/reference/authoring-surface/answer.md +20 -4
  67. package/docs/reference/authoring-surface/arg.md +28 -6
  68. package/docs/reference/authoring-surface/basic.md +1 -1
  69. package/docs/reference/authoring-surface/bearer.md +1 -1
  70. package/docs/reference/authoring-surface/branchname.md +15 -0
  71. package/docs/reference/authoring-surface/carry.md +23 -0
  72. package/docs/reference/authoring-surface/chartschema.md +1 -1
  73. package/docs/reference/authoring-surface/chartschemafor.md +1 -1
  74. package/docs/reference/authoring-surface/command.md +37 -22
  75. package/docs/reference/authoring-surface/customize.md +4 -1
  76. package/docs/reference/authoring-surface/defineconfig.md +1 -1
  77. package/docs/reference/authoring-surface/defineevent.md +1 -1
  78. package/docs/reference/authoring-surface/dispatch.md +5 -4
  79. package/docs/reference/authoring-surface/fail.md +18 -5
  80. package/docs/reference/authoring-surface/file.md +37 -17
  81. package/docs/reference/authoring-surface/frompick.md +1 -1
  82. package/docs/reference/authoring-surface/gate.md +118 -0
  83. package/docs/reference/authoring-surface/group-agents.md +15 -0
  84. package/docs/reference/authoring-surface/group-charts.md +16 -0
  85. package/docs/reference/authoring-surface/group-composition.md +25 -0
  86. package/docs/reference/authoring-surface/group-config.md +17 -0
  87. package/docs/reference/authoring-surface/group-effects.md +48 -0
  88. package/docs/reference/authoring-surface/group-failure.md +13 -0
  89. package/docs/reference/authoring-surface/group-gates.md +16 -0
  90. package/docs/reference/authoring-surface/group-machine-and-events.md +15 -0
  91. package/docs/reference/authoring-surface/group-steering.md +12 -0
  92. package/docs/reference/authoring-surface/group-types-these-signatures-name.md +137 -0
  93. package/docs/reference/authoring-surface/group-workspaces-and-repos.md +15 -0
  94. package/docs/reference/authoring-surface/http.md +109 -9
  95. package/docs/reference/authoring-surface/isfailure.md +1 -1
  96. package/docs/reference/authoring-surface/isready.md +14 -0
  97. package/docs/reference/authoring-surface/jr2setup.md +14 -4
  98. package/docs/reference/authoring-surface/mcp.md +107 -0
  99. package/docs/reference/authoring-surface/open.md +41 -8
  100. package/docs/reference/authoring-surface/openbody.md +1 -1
  101. package/docs/reference/authoring-surface/paramsof.md +23 -5
  102. package/docs/reference/authoring-surface/pool.md +79 -11
  103. package/docs/reference/authoring-surface/push.md +31 -13
  104. package/docs/reference/authoring-surface/readyof.md +21 -0
  105. package/docs/reference/authoring-surface/reread.md +19 -0
  106. package/docs/reference/authoring-surface/secret.md +26 -5
  107. package/docs/reference/authoring-surface/sentby.md +1 -1
  108. package/docs/reference/authoring-surface/skip.md +22 -0
  109. package/docs/reference/authoring-surface/source.md +59 -4
  110. package/docs/reference/authoring-surface/steer.md +93 -0
  111. package/docs/reference/authoring-surface/text.md +1 -1
  112. package/docs/reference/authoring-surface/type-agentdefinition.md +16 -3
  113. package/docs/reference/authoring-surface/type-agentmcpserver.md +54 -0
  114. package/docs/reference/authoring-surface/type-agentslots.md +4 -1
  115. package/docs/reference/authoring-surface/type-anyframepath.md +14 -0
  116. package/docs/reference/authoring-surface/type-anyworktreepath.md +15 -0
  117. package/docs/reference/authoring-surface/type-bindactors.md +14 -0
  118. package/docs/reference/authoring-surface/type-binding.md +6 -7
  119. package/docs/reference/authoring-surface/type-caller.md +40 -0
  120. package/docs/reference/authoring-surface/type-callerrecord.md +32 -0
  121. package/docs/reference/authoring-surface/type-carry.md +19 -0
  122. package/docs/reference/authoring-surface/type-chainlink.md +3 -3
  123. package/docs/reference/authoring-surface/type-commandinput.md +4 -3
  124. package/docs/reference/authoring-surface/type-commandoptions.md +0 -22
  125. package/docs/reference/authoring-surface/type-commandoutput.md +23 -5
  126. package/docs/reference/authoring-surface/type-customize.md +20 -3
  127. package/docs/reference/authoring-surface/type-delivered.md +17 -0
  128. package/docs/reference/authoring-surface/type-deliveredevent.md +18 -0
  129. package/docs/reference/authoring-surface/type-dispatchdefinition.md +4 -3
  130. package/docs/reference/authoring-surface/type-dispatchoutput.md +9 -2
  131. package/docs/reference/authoring-surface/type-doorlessinput.md +19 -0
  132. package/docs/reference/authoring-surface/type-effectbinding.md +12 -2
  133. package/docs/reference/authoring-surface/type-filebody.md +4 -8
  134. package/docs/reference/authoring-surface/type-framepath.md +14 -0
  135. package/docs/reference/authoring-surface/type-gatebinding.md +15 -0
  136. package/docs/reference/authoring-surface/type-gatehooks.md +12 -0
  137. package/docs/reference/authoring-surface/type-gatelook.md +37 -0
  138. package/docs/reference/authoring-surface/type-gateoutcome.md +32 -0
  139. package/docs/reference/authoring-surface/type-gatereply.md +19 -0
  140. package/docs/reference/authoring-surface/type-gateslot.md +21 -0
  141. package/docs/reference/authoring-surface/type-gateslotinput.md +13 -0
  142. package/docs/reference/authoring-surface/type-gateslotparts.md +18 -0
  143. package/docs/reference/authoring-surface/type-gateslots.md +12 -0
  144. package/docs/reference/authoring-surface/type-gatetypesat.md +13 -0
  145. package/docs/reference/authoring-surface/type-hostinjectedinput.md +3 -5
  146. package/docs/reference/authoring-surface/type-httpdefinition.md +6 -3
  147. package/docs/reference/authoring-surface/type-httpfileinput.md +20 -0
  148. package/docs/reference/authoring-surface/type-httpoutput.md +8 -2
  149. package/docs/reference/authoring-surface/type-jr2config.md +37 -2
  150. package/docs/reference/authoring-surface/type-lateroutcome.md +21 -0
  151. package/docs/reference/authoring-surface/type-lends.md +5 -1
  152. package/docs/reference/authoring-surface/type-lookoutput.md +14 -0
  153. package/docs/reference/authoring-surface/type-mcpcalloutput.md +78 -0
  154. package/docs/reference/authoring-surface/type-mcpnotreturned.md +42 -0
  155. package/docs/reference/authoring-surface/type-mcpoptions.md +47 -0
  156. package/docs/reference/authoring-surface/type-mcpoutput.md +50 -0
  157. package/docs/reference/authoring-surface/type-mcpreadoutput.md +53 -0
  158. package/docs/reference/authoring-surface/type-mcpremoteserver.md +50 -0
  159. package/docs/reference/authoring-surface/type-mcpserver.md +41 -0
  160. package/docs/reference/authoring-surface/type-mcpstdioserver.md +42 -0
  161. package/docs/reference/authoring-surface/type-namedsecret.md +4 -4
  162. package/docs/reference/authoring-surface/type-namestart.md +77 -0
  163. package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +1 -6
  164. package/docs/reference/authoring-surface/type-notworktreekeys.md +12 -0
  165. package/docs/reference/authoring-surface/type-openbodydeclaration.md +1 -1
  166. package/docs/reference/authoring-surface/type-openbodyoutput.md +1 -1
  167. package/docs/reference/authoring-surface/type-opencommandinput.md +7 -2
  168. package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +1 -6
  169. package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +5 -10
  170. package/docs/reference/authoring-surface/type-poolnextinput.md +22 -0
  171. package/docs/reference/authoring-surface/type-poolspec.md +11 -6
  172. package/docs/reference/authoring-surface/type-pushinput.md +22 -3
  173. package/docs/reference/authoring-surface/type-pushoutput.md +33 -8
  174. package/docs/reference/authoring-surface/type-pushsourcespec.md +38 -0
  175. package/docs/reference/authoring-surface/type-readsourcespec.md +47 -0
  176. package/docs/reference/authoring-surface/type-reposlot.md +6 -6
  177. package/docs/reference/authoring-surface/type-reread.md +18 -0
  178. package/docs/reference/authoring-surface/type-runsconfig.md +41 -0
  179. package/docs/reference/authoring-surface/type-sandboxoptions.md +11 -4
  180. package/docs/reference/authoring-surface/type-sender.md +26 -1
  181. package/docs/reference/authoring-surface/type-sendercallerfield.md +14 -0
  182. package/docs/reference/authoring-surface/type-size.md +1 -1
  183. package/docs/reference/authoring-surface/type-skip.md +19 -0
  184. package/docs/reference/authoring-surface/type-slothandles.md +5 -13
  185. package/docs/reference/authoring-surface/type-sourcehooks.md +23 -0
  186. package/docs/reference/authoring-surface/type-sourcein.md +25 -0
  187. package/docs/reference/authoring-surface/type-sourcereply.md +18 -0
  188. package/docs/reference/authoring-surface/type-sourcespec.md +26 -17
  189. package/docs/reference/authoring-surface/type-sourceverdict.md +49 -0
  190. package/docs/reference/authoring-surface/type-standingpoolmachine.md +12 -0
  191. package/docs/reference/authoring-surface/type-standingpoolspec.md +51 -0
  192. package/docs/reference/authoring-surface/type-steerargs.md +20 -0
  193. package/docs/reference/authoring-surface/type-thinkinglevel.md +1 -1
  194. package/docs/reference/authoring-surface/type-usercontainer.md +1 -1
  195. package/docs/reference/authoring-surface/type-workspaced.md +30 -9
  196. package/docs/reference/authoring-surface/type-workspacehandles.md +5 -6
  197. package/docs/reference/authoring-surface/type-workspaceoptions.md +1 -13
  198. package/docs/reference/authoring-surface/type-worktreefound.md +16 -0
  199. package/docs/reference/authoring-surface/type-worktreeinput.md +56 -0
  200. package/docs/reference/authoring-surface/type-worktreekey.md +14 -0
  201. package/docs/reference/authoring-surface/type-worktreeoptions.md +29 -0
  202. package/docs/reference/authoring-surface/type-worktreeoutput.md +45 -0
  203. package/docs/reference/authoring-surface/type-worktreepath.md +16 -0
  204. package/docs/reference/authoring-surface/type-worktreeready.md +37 -0
  205. package/docs/reference/authoring-surface/type-worktreerefused.md +21 -0
  206. package/docs/reference/authoring-surface/workspace.md +66 -38
  207. package/docs/reference/authoring-surface/worktree.md +71 -0
  208. package/docs/reference/authoring-surface.md +88 -147
  209. package/docs/reference/cli.md +413 -74
  210. package/docs/reference/config.md +248 -6
  211. package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +10 -9
  212. package/docs/reference/decisions/0002-duplex-streaming-actor.md +81 -14
  213. package/docs/reference/decisions/0004-worktree-provisioning-model.md +27 -21
  214. package/docs/reference/decisions/0005-sandbox-pod-composition.md +39 -25
  215. package/docs/reference/decisions/0006-agent-control-surface.md +6 -3
  216. package/docs/reference/decisions/0007-durable-machine-state.md +1 -1
  217. package/docs/reference/decisions/0009-cli-and-instance-interface.md +150 -49
  218. package/docs/reference/decisions/0010-bdd-acceptance-tests.md +5 -3
  219. package/docs/reference/decisions/0011-workflow-defined-events.md +256 -12
  220. package/docs/reference/decisions/0012-workspace-wrapper-machine.md +39 -32
  221. package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +54 -30
  222. package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +53 -27
  223. package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +26 -16
  224. package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +9 -7
  225. package/docs/reference/decisions/0017-pool-over-a-source-port.md +226 -10
  226. package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +15 -7
  227. package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +53 -27
  228. package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +16 -2
  229. package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +4 -4
  230. package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +124 -43
  231. package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +36 -38
  232. package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +10 -5
  233. package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +16 -7
  234. package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +36 -19
  235. package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +18 -10
  236. package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +3 -2
  237. package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +23 -15
  238. package/docs/reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md +101 -0
  239. package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +22 -22
  240. package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +6 -6
  241. package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +13 -12
  242. package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +23 -23
  243. package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +6 -1
  244. package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +57 -46
  245. package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +5 -0
  246. package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +20 -8
  247. package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +55 -40
  248. package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +14 -13
  249. package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +31 -24
  250. package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +18 -10
  251. package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +137 -86
  252. package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +165 -91
  253. package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +7 -7
  254. package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +2 -2
  255. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md +109 -0
  256. package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +53 -23
  257. package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +221 -153
  258. package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +161 -96
  259. package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +32 -9
  260. package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +48 -33
  261. package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +56 -30
  262. package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +35 -25
  263. package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +1 -1
  264. package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +296 -0
  265. package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +347 -0
  266. package/docs/reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md +79 -0
  267. package/docs/reference/decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md +285 -0
  268. package/docs/reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md +198 -0
  269. package/docs/reference/decisions.md +9 -4
  270. package/docs/reference/glossary.md +138 -45
  271. package/docs/reference/hooks.md +1077 -0
  272. package/docs/reference/http-api.md +988 -123
  273. package/docs/reference/machines.md +0 -1
  274. package/docs/why.md +7 -5
  275. package/package.json +10 -3
  276. package/src/actor.ts +194 -42
  277. package/src/agent.ts +56 -6
  278. package/src/ambient.ts +3 -5
  279. package/src/assembly-checks.ts +530 -4
  280. package/src/callers.ts +245 -0
  281. package/src/chart.ts +238 -26
  282. package/src/charts.ts +9 -2
  283. package/src/config.ts +566 -7
  284. package/src/conversations.ts +453 -0
  285. package/src/custodian.lua +17 -5
  286. package/src/custodian.ts +257 -77
  287. package/src/customize.ts +154 -7
  288. package/src/dispatch-effect.ts +142 -26
  289. package/src/durability.ts +2 -0
  290. package/src/duration.ts +20 -0
  291. package/src/effect-checks.ts +52 -4
  292. package/src/effect.ts +401 -132
  293. package/src/effector-wire.ts +278 -30
  294. package/src/fail.ts +17 -4
  295. package/src/gate-brand.ts +16 -0
  296. package/src/gate.ts +634 -48
  297. package/src/harness-client.ts +84 -35
  298. package/src/harness-env.ts +33 -0
  299. package/src/held-secrets.ts +197 -39
  300. package/src/holds.ts +5 -2
  301. package/src/hook-kinds/discord.ts +92 -0
  302. package/src/hook-kinds/door.ts +107 -0
  303. package/src/hook-kinds/github.ts +89 -0
  304. package/src/hook-kinds/gitlab.ts +72 -0
  305. package/src/hook-kinds/hook.ts +7 -0
  306. package/src/hook-kinds/index.ts +465 -0
  307. package/src/hook-kinds/slack.ts +151 -0
  308. package/src/hook-kinds/webhook.ts +113 -0
  309. package/src/hooks.ts +506 -0
  310. package/src/http-effect.ts +164 -70
  311. package/src/http.ts +933 -99
  312. package/src/index.ts +30 -5
  313. package/src/instance.ts +196 -26
  314. package/src/internal.ts +23 -3
  315. package/src/kube-client.ts +6 -3
  316. package/src/machine-doc.ts +29 -5
  317. package/src/mcp-effect.ts +424 -0
  318. package/src/model-keys.ts +24 -0
  319. package/src/mount-digest.ts +41 -7
  320. package/src/names.ts +82 -7
  321. package/src/notices.ts +576 -59
  322. package/src/open-body.ts +110 -30
  323. package/src/open-effect.ts +17 -4
  324. package/src/open.ts +40 -7
  325. package/src/parts.ts +125 -35
  326. package/src/party.ts +35 -1
  327. package/src/pick.ts +43 -9
  328. package/src/pool.ts +1172 -172
  329. package/src/registration.ts +249 -17
  330. package/src/repo-identity.ts +7 -3
  331. package/src/repos.ts +20 -2
  332. package/src/run-host.ts +1614 -190
  333. package/src/run-list.ts +191 -0
  334. package/src/sandbox-effect.ts +217 -66
  335. package/src/sandbox-kube.ts +116 -21
  336. package/src/secret-placement.ts +248 -35
  337. package/src/server.ts +53 -4
  338. package/src/setup.ts +158 -38
  339. package/src/snapshot-store.ts +565 -48
  340. package/src/steer.ts +111 -0
  341. package/src/stub-harness.ts +6 -2
  342. package/src/tokens.ts +362 -46
  343. package/src/vocabulary.ts +23 -4
  344. package/src/wire.ts +27 -10
  345. package/src/workspace.ts +314 -259
  346. package/src/worktree.ts +249 -0
  347. package/docs/reference/authoring-surface/type-noslotspec.md +0 -26
  348. package/docs/reference/authoring-surface/type-workspacespec.md +0 -37
  349. package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +0 -61
  350. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +0 -65
@@ -5,10 +5,12 @@ description: "Declare a Source: where a `pool()` gets its work items, one at a t
5
5
 
6
6
  # `source`
7
7
 
8
- Function, in `@jr2/orchestrator/src/pool.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Composition.
8
+ Function, in `@jr2/orchestrator/src/pool.ts`. It is an export of `@jr2/orchestrator`, in the [Composition](group-composition.md) group of the [Authoring surface](../authoring-surface.md) page.
9
+
10
+ ## Overload 1
9
11
 
10
12
  ```ts
11
- function source<T>(spec: SourceSpec<T>): SourceSpec<T>
13
+ function source<T, TInput = unknown>(spec: SourceSpec<T, TInput>): SourceSpec<T, TInput>
12
14
  ```
13
15
 
14
16
  Declare a Source: where a `pool()` gets its work items, one at a time. It gives back the spec
@@ -25,7 +27,7 @@ that you pass. The item type `T` types what `next` gives. `pool()` does not carr
25
27
 
26
28
  ```ts
27
29
  import { fromPromise } from "xstate";
28
- import { source } from "@jr2/orchestrator";
30
+ import { source, type PoolNextInput } from "@jr2/orchestrator";
29
31
 
30
32
  type Issue = { id: string; title: string };
31
33
 
@@ -35,7 +37,7 @@ const backlog: Issue[] = [
35
37
  ];
36
38
 
37
39
  export const issues = source<Issue>({
38
- next: fromPromise(async ({ input }: { input: { active: string[] } }) => {
40
+ next: fromPromise(async ({ input }: { input: PoolNextInput }) => {
39
41
  const issue = backlog.find((i) => !input.active.includes(i.id)) ?? null;
40
42
  if (issue) backlog.splice(backlog.indexOf(issue), 1);
41
43
  return issue;
@@ -49,3 +51,56 @@ export const issues = source<Issue>({
49
51
  - [Run one worker per item](../../guides/run-one-worker-per-item.md)
50
52
  - [Pools and Sources](../../concepts/pools-and-sources.md)
51
53
  - [ADR-0017: The run loop is a jr2 `pool` over a generalized source port](../decisions/0017-pool-over-a-source-port.md)
54
+
55
+ ## Overload 2
56
+
57
+ ```ts
58
+ function source<const S extends z.ZodType>(spec: {
59
+ item: S;
60
+ hooks: SourceHooks<Carry<z.output<NoInfer<S>>>, {}>;
61
+ hold?: number;
62
+ reply?: SourceReply<z.output<NoInfer<S>>>;
63
+ }): PushSourceSpec<z.output<S>>
64
+ ```
65
+
66
+ Declare a PUSH Source: the schema of an item, and the handlers that carry it. Only a standing
67
+ Pool of runs takes it.
68
+
69
+ **Parameters**
70
+
71
+ - `spec`: `item`, `hooks`, `hold` and `reply`. See [`PushSourceSpec`](type-pushsourcespec.md).
72
+
73
+ - `item`: `S`
74
+ - `hooks`: `SourceHooks<Carry<z.output<NoInfer<S>>>, {}>`
75
+ - `hold` (optional): `number`
76
+ - `reply` (optional): `SourceReply<z.output<NoInfer<S>>>`
77
+
78
+ **Returns**: The same spec.
79
+
80
+ **See also**
81
+
82
+ - [Pools and Sources](../../concepts/pools-and-sources.md)
83
+
84
+ ## Overload 3
85
+
86
+ ```ts
87
+ function source<
88
+ T,
89
+ TInput = unknown,
90
+ R extends AnyActorLogic = AnyActorLogic,
91
+ >(
92
+ spec: ReadSourceSpec<T, TInput, R>,
93
+ ): ReadSourceSpec<T, TInput, R>
94
+ ```
95
+
96
+ Declare a READ Source: a read of the whole set, and the items in its answer.
97
+
98
+ **Parameters**
99
+
100
+ - `spec`: `read`, `items`, `wake`, `pollEvery`, `hooks` and `reply`. See [`ReadSourceSpec`](type-readsourcespec.md).
101
+
102
+ **Returns**: The same spec.
103
+
104
+ **See also**
105
+
106
+ - [Pools and Sources](../../concepts/pools-and-sources.md)
@@ -0,0 +1,93 @@
1
+ ---
2
+ title: steer
3
+ description: "Send a Steering message to one Agent of this Machine: an action for a transition."
4
+ ---
5
+
6
+ # `steer`
7
+
8
+ Function, in `@jr2/orchestrator/src/steer.ts`. It is an export of `@jr2/orchestrator`, in the [Steering](group-steering.md) group of the [Authoring surface](../authoring-surface.md) page.
9
+
10
+ ```ts
11
+ function steer<
12
+ TContext extends MachineContext,
13
+ TExpressionEvent extends EventObject,
14
+ TParams extends ParameterizedObject["params"] | undefined,
15
+ TEvent extends EventObject,
16
+ TActor extends ProvidedActor,
17
+ >(
18
+ agent: string,
19
+ text: string | ((args: SteerArgs<TContext, TExpressionEvent>) => string),
20
+ opts: { from?: Sender | ((args: SteerArgs<TContext, TExpressionEvent>) => Sender | undefined) } = {},
21
+ ): ActionFunction<TContext, TExpressionEvent, TEvent, TParams, TActor, never, never, never, never>
22
+ ```
23
+
24
+ Send a Steering message to one Agent of this Machine: an action for a transition. The Agent hears
25
+ the text once, without an interrupt. When a Turn of the Agent is open, its Harness adds the text
26
+ at the Turn's next step boundary. Otherwise the text waits for the Agent's next Turn in this
27
+ Machine instance. When this Machine instance ends first, the message is not delivered.
28
+
29
+ A Steering message is not an event: no guard reads it, and no Gate takes it. The Agent decides
30
+ what to do with it, and acts on the workflow only by its picks.
31
+
32
+ Use it to relay what one Agent says to another. Give `from` the Sender of the event (the
33
+ `sender` field that the Orchestrator writes on it): the Agent then reads the text as the word of
34
+ a peer, not as an order. When the Sender is a Gate, the Agent reads the text as what the Gate
35
+ received, not as an order. With no `from`, the Agent reads the text as the workflow's own.
36
+
37
+ `agent` is the name of an Agent in this Machine's `actors`. A text longer than 16 KiB is cut.
38
+ The Machine can steer an Agent whose definition says `steerable: false`: that refuses Callers
39
+ only.
40
+
41
+ **Parameters**
42
+
43
+ - `agent`
44
+ - `text`
45
+ - `opts`
46
+
47
+ - `from` (optional): `Sender | ((args: SteerArgs<TContext, TExpressionEvent>) => Sender | undefined)`
48
+
49
+ **Example**
50
+
51
+ ```ts
52
+ import { z } from "zod";
53
+ import { agent, defineEvent, jr2Setup, steer } from "@jr2/orchestrator";
54
+
55
+ const done = defineEvent({ name: "done", description: "The draft is ready.", input: z.object({}) });
56
+ const note = defineEvent({
57
+ name: "note",
58
+ description: "Send the draft back to the writer, with what to change.",
59
+ input: z.object({ text: z.string().min(1) }),
60
+ });
61
+
62
+ export const machine = jr2Setup({
63
+ events: [done, note],
64
+ actors: {
65
+ writer: agent({ model: "anthropic/claude-haiku-5-5", instructions: "You write.", workspace: "none" }),
66
+ reviewer: agent({ model: "anthropic/claude-haiku-5-5", instructions: "You review.", workspace: "none" }),
67
+ },
68
+ }).createMachine({
69
+ initial: "writing",
70
+ states: {
71
+ writing: {
72
+ invoke: { src: "writer", input: { prompt: "Write the notes.", continue: true } },
73
+ on: { done: "reviewing" },
74
+ },
75
+ reviewing: {
76
+ invoke: { src: "reviewer", input: { prompt: "Review the notes." } },
77
+ on: {
78
+ // The writer's next Turn hears the note as the reviewer's word, not as an order.
79
+ note: {
80
+ target: "writing",
81
+ actions: steer("writer", ({ event }) => event.text, { from: ({ event }) => event.sender }),
82
+ },
83
+ },
84
+ },
85
+ },
86
+ });
87
+ ```
88
+
89
+ **See also**
90
+
91
+ - [Steer an Agent](../../guides/steer-an-agent.md)
92
+ - [Agents and Turns](../../concepts/agents-and-turns.md)
93
+ - [ADR-0002: The agent actor is a duplex channel; its control plane is Menu tool calls](../decisions/0002-duplex-streaming-actor.md)
@@ -5,7 +5,7 @@ description: "Make a string from literal text and Effect secrets, as a tagged te
5
5
 
6
6
  # `text`
7
7
 
8
- Function, in `@jr2/orchestrator/src/http-effect.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.
8
+ Function, in `@jr2/orchestrator/src/http-effect.ts`. It is an export of `@jr2/orchestrator`, in the [Effects](group-effects.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
11
  function text<
@@ -5,7 +5,7 @@ description: "An Agent's definition: which model it runs, its instructions, and
5
5
 
6
6
  # `AgentDefinition`
7
7
 
8
- Type, in `@jr2/orchestrator/src/agent.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Agents.
8
+ Type, in `@jr2/orchestrator/src/agent.ts`. It is an export of `@jr2/orchestrator`, in the [Agents](group-agents.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
11
  type AgentDefinition = {
@@ -14,6 +14,8 @@ type AgentDefinition = {
14
14
  description?: string;
15
15
  thinkingLevel?: ThinkingLevel;
16
16
  workspace?: WorkspaceAccess;
17
+ mcp?: readonly AgentMcpServer[];
18
+ steerable?: boolean;
17
19
  };
18
20
  ```
19
21
 
@@ -51,10 +53,21 @@ cannot change `instructions` or `workspace`.
51
53
  What the Agent may do to the Workspace. Default: `"write"`.
52
54
  - `"write"`: all the Working tools (read, write, edit, bash, grep, glob).
53
55
  - `"read"`: no write or edit tool. The Agent keeps bash, so `"read"` does not stop a command
54
- that writes. To keep the Agent from changing the branch, frame its Turn in the review
55
- Worktree: `reviewSha` in the spec, then `cwd: context.workspace.review?.<slot>`.
56
+ that writes. To keep the Agent from changing the branch, frame its Turn in a detached
57
+ Worktree: cut it with `{ path, detach: sha }`, then give that `path` as `cwd`.
56
58
  - `"none"`: no Working tools. The Agent only reads its prompt and picks from its Menu. Its Turn
57
59
  runs on the Instance Harness, not in a Sandbox, so it needs no `workspace()` around it.
60
+ - `mcp` (optional): `readonly AgentMcpServer[]`
61
+
62
+ The MCP servers whose tools the Agent gets, each with its allowlist: see
63
+ [`AgentMcpServer`](type-agentmcpserver.md). The tools join the Agent's tools, after its Working tools and before
64
+ its Menu. A call to one is not a pick, and the Turn goes on after it. Default: none. A composer
65
+ replaces the whole list with `customize(machine, { agents: { <slot>: { mcp: [...] } } })`.
66
+ - `steerable` (optional): `boolean`
67
+
68
+ May a Caller send this Agent a Steering message? Default: `true`. With `false`,
69
+ `POST /runs/:runId/steering` and `jr2 steer` refuse it, and `GET /runs/:runId/agents` says
70
+ `steerable: false`. The Machine can still steer the Agent with the `steer` action.
58
71
 
59
72
  **Example**
60
73
 
@@ -0,0 +1,54 @@
1
+ ---
2
+ title: AgentMcpServer
3
+ description: One MCP server that an Agent uses, and the tools that it may call there.
4
+ ---
5
+
6
+ # `AgentMcpServer`
7
+
8
+ Type, in `@jr2/orchestrator/src/agent.ts`. It is an export of `@jr2/orchestrator`, in the [Agents](group-agents.md) group of the [Authoring surface](../authoring-surface.md) page.
9
+
10
+ ```ts
11
+ type AgentMcpServer = {
12
+ server: string;
13
+ tools?: readonly string[] | "*";
14
+ };
15
+ ```
16
+
17
+ One MCP server that an Agent uses, and the tools that it may call there.
18
+
19
+ - `server` is a name of the `mcp` block of `jr2.config.ts`. `jr2 up` refuses a name that the
20
+ block does not declare, and prints the `customize()` line that binds the Agent to one it does.
21
+ - `tools` is the allowlist. A remote server needs it: a list of tool names, or `"*"` for every
22
+ tool. The Harness offers and runs only those tools. When Workspace code in the Agent's Sandbox
23
+ can spend the server's secret, `jr2 up` takes only `"*"`, because a list would then not be a
24
+ limit. A stdio server takes no `tools`: the Agent gets every tool of the server.
25
+
26
+ The model reads each tool as `mcp__<server>__<tool>`. A tool name in the list must keep that name
27
+ within `[A-Za-z0-9_-]` and 128 characters.
28
+
29
+ **Fields**
30
+
31
+ - `server`: `string`
32
+
33
+ A server name of the `mcp` block of `jr2.config.ts`.
34
+ - `tools` (optional): `readonly string[] | "*"`
35
+
36
+ The allowlist: tool names of the server, or `"*"` for every tool. Required for a remote
37
+ server; absent for a stdio server.
38
+
39
+ **Example**
40
+
41
+ ```ts
42
+ import { agent } from "@jr2/orchestrator";
43
+
44
+ export const triage = agent({
45
+ model: "anthropic/claude-haiku-5-5",
46
+ instructions: "You read the ticket and post a summary to the channel.",
47
+ workspace: "none",
48
+ mcp: [{ server: "slack-acme", tools: ["post_message", "read_channel"] }],
49
+ });
50
+ ```
51
+
52
+ **See also**
53
+
54
+ - [ADR-0079: An Agent holds MCP tools, a Machine calls them as an Effect, and the Machine is the approval](../decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md)
@@ -8,5 +8,8 @@ description: A type that the Authoring surface names.
8
8
  Type, in `@jr2/orchestrator/src/customize.ts`. It is type plumbing: it computes a type from the types of a Machine or of its parts, and a workflow module does not write it. The signature of an export, or a type that it names, names this type, so its declaration is here. The [Authoring surface](../authoring-surface.md) page lists each export.
9
9
 
10
10
  ```ts
11
- type AgentSlots<M extends AnyStateMachine> = Extract<SlotsOf<M>, { logic: AgentLogic }>["src"];
11
+ type AgentSlots<M extends AnyStateMachine> = Extract<
12
+ SlotsOf<M>,
13
+ { logic: CallbackActorLogic<AgentRunReceiveEvent, any> }
14
+ >["src"];
12
15
  ```
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: AnyFramePath
3
+ description: "A Turn's Frame: a Worktree, or `/work`, stated."
4
+ ---
5
+
6
+ # `AnyFramePath`
7
+
8
+ Type, in `@jr2/orchestrator/src/worktree.ts`. It is an export of `@jr2/orchestrator`, in the [Effects](group-effects.md) group of the [Authoring surface](../authoring-surface.md) page.
9
+
10
+ ```ts
11
+ type AnyFramePath = "/work" | `/work/${string}`;
12
+ ```
13
+
14
+ A Turn's Frame: a Worktree, or `/work`, stated. `jr2Setup` narrows it to the body's slots.
@@ -0,0 +1,15 @@
1
+ ---
2
+ title: AnyWorktreePath
3
+ description: "A Worktree of any Repo Slot: what a kit factory states, before `jr2Setup` narrows it to the slots of the body."
4
+ ---
5
+
6
+ # `AnyWorktreePath`
7
+
8
+ Type, in `@jr2/orchestrator/src/worktree.ts`. It is an export of `@jr2/orchestrator`, in the [Effects](group-effects.md) group of the [Authoring surface](../authoring-surface.md) page.
9
+
10
+ ```ts
11
+ type AnyWorktreePath = `/work/${string}/${string}`;
12
+ ```
13
+
14
+ A Worktree of any Repo Slot: what a kit factory states, before `jr2Setup` narrows it to the
15
+ slots of the body.
@@ -0,0 +1,14 @@
1
+ ---
2
+ title: BindActors
3
+ description: A type that the Authoring surface names.
4
+ ---
5
+
6
+ # `BindActors`
7
+
8
+ Type, in `@jr2/orchestrator/src/setup.ts`. It is type plumbing: it computes a type from the types of a Machine or of its parts, and a workflow module does not write it. The signature of an export, or a type that it names, names this type, so its declaration is here. The [Authoring surface](../authoring-surface.md) page lists each export.
9
+
10
+ ```ts
11
+ type BindActors<A extends Record<string, UnknownActorLogic>, TInput, TContext> = {
12
+ [K in keyof A]: BindLogic<A[K], RepoSlotsOf<TInput, TContext>>;
13
+ };
14
+ ```
@@ -5,7 +5,7 @@ description: "The repository of a Repo Slot: `{ url, ref }`."
5
5
 
6
6
  # `Binding`
7
7
 
8
- Type, in `@jr2/orchestrator/src/parts.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Workspaces and Repos.
8
+ Type, in `@jr2/orchestrator/src/parts.ts`. It is an export of `@jr2/orchestrator`, in the [Workspaces and Repos](group-workspaces-and-repos.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
11
  type Binding = {
@@ -14,9 +14,9 @@ type Binding = {
14
14
  };
15
15
  ```
16
16
 
17
- The repository of a Repo Slot: `{ url, ref }`. `url` is the Repo's git url. `ref` is the branch
18
- or commit that the branch Worktree starts from; absent, the Repo's default branch. Where only a
19
- url is needed, a string is enough.
17
+ The repository of a Repo Slot: `{ url, ref }`. `url` is the Repo's git url. `ref` is the branch,
18
+ the tag or the commit that the clone stays on, and that a new branch starts from; absent, the
19
+ Repo's default branch. Where only a url is needed, a string is enough.
20
20
 
21
21
  `workspace()` and `customize()` refuse:
22
22
  - an empty `url`: ``<where>: Repo Slot "<slot>" is bound to an empty url (got <value>) — a slot
@@ -34,8 +34,8 @@ url is needed, a string is enough.
34
34
  The Repo's git url.
35
35
  - `ref` (optional): `string`
36
36
 
37
- The branch or commit that the branch Worktree starts from. Default: the Repo's default
38
- branch.
37
+ The branch, tag or commit that the clone stays on, and that a new branch starts from. Default:
38
+ the Repo's default branch.
39
39
 
40
40
  **Example**
41
41
 
@@ -52,7 +52,6 @@ const body = jr2Setup().createMachine({
52
52
 
53
53
  export const machine = workspace(body, {
54
54
  repos: { app },
55
- spec: () => ({ branch: "jr2/hotfix" }),
56
55
  });
57
56
  ```
58
57
 
@@ -0,0 +1,40 @@
1
+ ---
2
+ title: Caller
3
+ description: "A request's Caller (ADR-0078): who acts, through which authenticator, and what it may do."
4
+ ---
5
+
6
+ # `Caller`
7
+
8
+ Type, in `@jr2/orchestrator/src/tokens.ts`. The signature of an export, or a type that it names, names this type. The [Authoring surface](../authoring-surface.md) page lists each export. This type is not an export of `@jr2/orchestrator`, so a workflow module does not import it by name.
9
+
10
+ ```ts
11
+ type Caller = {
12
+ via: "token" | "jwt" | "hook";
13
+ name: string;
14
+ shown?: string;
15
+ may: Scopes;
16
+ onBehalfOf?: string;
17
+ };
18
+ ```
19
+
20
+ A request's Caller ([ADR-0078](../decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md)): who acts, through which authenticator, and what it may do.
21
+
22
+ **Fields**
23
+
24
+ - `via`: `"token" | "jwt" | "hook"`
25
+
26
+ The authenticator that made the Caller: `token` (the Instance token or a named token), `jwt`
27
+ or `hook`.
28
+ - `name`: `string`
29
+
30
+ The Caller's name for that authenticator: `instance`, a named token's name, a JWT's `sub`, a
31
+ Hook's name.
32
+ - `shown` (optional): `string`
33
+
34
+ The name that jr2 shows, when it is not `name` (a JWT's `email`).
35
+ - `may`: [`Scopes`](../config.md#callers-tokens-name-may)
36
+
37
+ What the Caller may do.
38
+ - `onBehalfOf` (optional): `string`
39
+
40
+ The Caller's claim about the party it acts for. jr2 records it and never checks it.
@@ -0,0 +1,32 @@
1
+ ---
2
+ title: CallerRecord
3
+ description: "A Caller as a run records it (ADR-0078): who acted, and the party it says it acted for."
4
+ ---
5
+
6
+ # `CallerRecord`
7
+
8
+ Type, in `@jr2/orchestrator/src/callers.ts`. The signature of an export, or a type that it names, names this type. The [Authoring surface](../authoring-surface.md) page lists each export. This type is not an export of `@jr2/orchestrator`, so a workflow module does not import it by name.
9
+
10
+ ```ts
11
+ type CallerRecord = {
12
+ via: Caller["via"];
13
+ name: string;
14
+ shown?: string;
15
+ onBehalfOf?: string;
16
+ };
17
+ ```
18
+
19
+ A Caller as a run records it ([ADR-0078](../decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md)): who acted, and the party it says it acted for. Never its
20
+ scopes.
21
+
22
+ **Fields**
23
+
24
+ - `via`: `Caller["via"]`
25
+ - `name`: `string`
26
+ - `shown` (optional): `string`
27
+
28
+ The name that jr2 shows, when it is not `name` (a JWT's `email`).
29
+ - `onBehalfOf` (optional): `string`
30
+
31
+ The Caller's claim about the party it acts for. jr2 records it and never checks it, except for
32
+ a Hook, whose signature covers it.
@@ -0,0 +1,19 @@
1
+ ---
2
+ title: Carry
3
+ description: What `carry(item)` gives.
4
+ ---
5
+
6
+ # `Carry`
7
+
8
+ Type, in `@jr2/orchestrator/src/pool.ts`. The signature of an export, or a type that it names, names this type. The [Authoring surface](../authoring-surface.md) page lists each export. This type is not an export of `@jr2/orchestrator`, so a workflow module does not import it by name.
9
+
10
+ ```ts
11
+ type Carry<T> = { readonly [VERDICT]: "carry"; readonly item: T };
12
+ ```
13
+
14
+ What `carry(item)` gives. Only a push Source (one with an `item` schema) gives it.
15
+
16
+ **Fields**
17
+
18
+ - `[VERDICT]`: `"carry"`
19
+ - `item`: `T`
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: ChainLink
3
- description: "One reply since the pick, as the author reads it: an invoked actor's output, typed by its slot (`src`); or an event that answered a state below the Agent's — a Gate's answer, a nested Agent's pick — typed by the Machine's events."
3
+ description: One reply since the pick, as the author reads it.
4
4
  ---
5
5
 
6
6
  # `ChainLink`
@@ -13,7 +13,7 @@ type ChainLink<TActor extends ProvidedActor, TEvent extends EventObject> =
13
13
  | { kind: "event"; event: Exclude<TEvent, { type: `${string}.${string}` }> };
14
14
  ```
15
15
 
16
- One reply since the pick, as the author reads it: an invoked actor's output, typed by its slot
17
- (`src`); or an event that answered a state below the Agent's — a Gate's answer, a nested Agent's
16
+ One reply since the pick, as the author reads it. It is an invoked actor's output, typed by its
17
+ slot (`src`); or an event that answered a state below the Agent's — a Gate's answer, a nested Agent's
18
18
  pick — typed by the Machine's events. A reply is from outside the Machine: the events it sends
19
19
  itself are not links.
@@ -8,11 +8,12 @@ description: "A command's input: one string per argv slot, and with `pin` the ap
8
8
  Type, in `@jr2/orchestrator/src/effect.ts`. The signature of an export, or a type that it names, names this type. The [Authoring surface](../authoring-surface.md) page lists each export. This type is not an export of `@jr2/orchestrator`, so a workflow module does not import it by name.
9
9
 
10
10
  ```ts
11
- type CommandInput<A extends readonly unknown[], P = false> = [
11
+ type CommandInput<A extends readonly unknown[], P = false, Opt = unknown> = [
12
12
  ArgNames<A> | ([P] extends [true] ? "sha" : never),
13
13
  ] extends [never]
14
- ? void
15
- : { [K in ArgNames<A> | ([P] extends [true] ? "sha" : never)]: string };
14
+ ? (WorktreeKey<Opt> & NotWorktreeKeys) | ([Opt] extends [{ readonly env: object }] ? never : void)
15
+ : { [K in ArgNames<A> | ([P] extends [true] ? "sha" : never)]: string } & WorktreeKey<Opt> &
16
+ Omit<NotWorktreeKeys, ArgNames<A>>;
16
17
  ```
17
18
 
18
19
  A command's input: one string per argv slot, and with `pin` the approved commit (`{ sha }`);
@@ -9,7 +9,6 @@ Type, in `@jr2/orchestrator/src/effect.ts`. The signature of an export, or a typ
9
9
 
10
10
  ```ts
11
11
  type CommandOptions = {
12
- slot?: string;
13
12
  timeout?: Duration;
14
13
  tail?: number;
15
14
  env?: CommandEnv;
@@ -22,27 +21,6 @@ output it keeps, its Effect secrets, and the commit it runs against.
22
21
 
23
22
  **Fields**
24
23
 
25
- - `slot` (optional): `string`
26
-
27
- The Repo Slot whose Worktree is the working directory of the command. Write it only when the
28
- Workspace has more than one Repo Slot. In a Workspace with no Repo Slot, the command starts in
29
- `/work`, the folder that the steps of the Workspace share.
30
-
31
- The command starts in the root of that Worktree. To run it in a subfolder, give the path as an
32
- argument, or write `["sh", "-c", "cd <dir> && <program>"]`.
33
-
34
- When it starts, it refuses:
35
- - no `slot` under a Workspace with more than one Repo Slot: `command "<slot>" runs under a
36
- Workspace carrying more than one Repo Slot (<slots>) and names none — say which Worktree it
37
- runs in: command(argv, { slot: "<slot>" }) (ADR-0051)`. When `env` names an Effect secret,
38
- the text is `command "<slot>" runs under a Workspace carrying more than one Repo Slot
39
- (<slots>) — say which: { slot: "<slot>" } (ADR-0051)`.
40
- - with an Effect secret in `env`, a Workspace with no Repo Slot: `command "<slot>" runs under
41
- a Workspace with no Repo Slot: a command with an Effect secret runs against one commit of a
42
- Repo Slot's branch, and there is none — declare a Repo Slot, or name no secret in its env, and
43
- it runs in /work beside the Agent (ADR-0051)`.
44
- - a `slot` that the Workspace does not have: `command "<slot>" names Repo Slot "<name>", which
45
- its Workspace does not carry (<slots>)`.
46
24
  - `timeout` (optional): [`Duration`](type-duration.md)
47
25
 
48
26
  How long the command can run: a number and a unit, such as `"90s"`, `"10m"` or `"1h"`.
@@ -5,10 +5,10 @@ description: "The output of a `command` Effect: what the `onDone` of its state g
5
5
 
6
6
  # `CommandOutput`
7
7
 
8
- Type, in `@jr2/orchestrator/src/effect.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.
8
+ Type, in `@jr2/orchestrator/src/effect.ts`. It is an export of `@jr2/orchestrator`, in the [Effects](group-effects.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
- type CommandOutput = (ExecOutcome & { dirty?: boolean }) | Unknown;
11
+ type CommandOutput = (ExecOutcome & { dirty?: boolean }) | Unknown | LaterOutcome;
12
12
  ```
13
13
 
14
14
  The output of a `command` Effect: what the `onDone` of its state gets as `event.output`. Every
@@ -25,6 +25,8 @@ outcome is output. A failed program is output too. Route on `outcome`:
25
25
  characters. `dirty` is `true` when a command that names an Effect secret ran against a commit,
26
26
  and the Worktree held changes that it did not see.
27
27
 
28
+ The union is open ([`LaterOutcome`](type-lateroutcome.md)): give the rest a last arm with no guard.
29
+
28
30
  **Forms**: it is one of these objects.
29
31
 
30
32
  - Form 1: `outcome`, `code`, `tail`, `dirty`
@@ -48,6 +50,10 @@ and the Worktree held changes that it did not see.
48
50
 
49
51
  - `outcome`: `"unknown"`
50
52
  - `reason`: `string`
53
+ - Form 5: `outcome`, `reason`
54
+
55
+ - `outcome`: `"(a later outcome)"`
56
+ - `reason` (optional): `string`
51
57
 
52
58
  **Example**
53
59
 
@@ -56,28 +62,40 @@ import {
56
62
  command,
57
63
  type CommandOutput,
58
64
  fail,
65
+ isReady,
59
66
  jr2Setup,
60
67
  workspace,
68
+ worktree,
61
69
  type Workspaced,
62
70
  } from "@jr2/orchestrator";
63
71
 
64
72
  type Input = Workspaced<{}, "app">;
65
73
 
74
+ const testTree = (context: Input) => `${context.workspace.repos.app}/test` as const;
75
+
66
76
  const passed = (output: CommandOutput): boolean =>
67
77
  output.outcome === "exited" && output.code === 0;
68
78
 
69
79
  const body = jr2Setup({
70
80
  types: {} as { context: Input; input: Input },
71
- actors: { tests: command(["npm", "test"], { timeout: "15m" }), fail: fail() },
81
+ actors: { cut: worktree(), tests: command(["npm", "test"], { timeout: "15m" }), fail: fail() },
72
82
  }).createMachine({
73
83
  id: "tests",
74
84
  context: ({ input }) => input,
75
85
  on: { "workspace.lost": ".lost" },
76
- initial: "testing",
86
+ initial: "cutting",
77
87
  states: {
88
+ cutting: {
89
+ invoke: {
90
+ src: "cut",
91
+ input: ({ context }) => ({ path: testTree(context), branch: "tests" }),
92
+ onDone: [{ guard: ({ event }) => isReady(event.output), target: "testing" }, { target: "notCut" }],
93
+ },
94
+ },
78
95
  testing: {
79
96
  invoke: {
80
97
  src: "tests",
98
+ input: ({ context }) => ({ worktree: testTree(context) }),
81
99
  onDone: [
82
100
  { guard: ({ event }) => passed(event.output), target: "green" },
83
101
  { target: "red" },
@@ -87,13 +105,13 @@ const body = jr2Setup({
87
105
  green: { type: "final" },
88
106
  // Not a final state: a final state means `done`, and the run ends `failed` here.
89
107
  red: { invoke: { src: "fail", input: { reason: "npm test did not pass" } } },
108
+ notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
90
109
  lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
91
110
  },
92
111
  });
93
112
 
94
113
  export const machine = workspace(body, {
95
114
  repos: { app: { url: "https://github.com/you/app.git" } },
96
- spec: () => ({ branch: "tests" }),
97
115
  });
98
116
  ```
99
117