@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,7 +5,7 @@ description: "Leave a part of a Machine Open: for the Instance that registers th
5
5
 
6
6
  # `open`
7
7
 
8
- Constant, in `@jr2/orchestrator/src/open.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Composition.
8
+ Constant, in `@jr2/orchestrator/src/open.ts`. It is an export of `@jr2/orchestrator`, in the [Composition](group-composition.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
11
  const open: unique symbol
@@ -17,18 +17,31 @@ part that the package cannot know or pay for:
17
17
  - a Repo Slot: `repos: { app: open }`, or the whole map: `repos: open`;
18
18
  - an Agent's model: `agent({ model: open, … })`;
19
19
  - an Effect's url or argv: `http({ url: open, … })`, `command(open)`;
20
- - the secret of an Effect's auth, of a header, or of a command's `env`: `secret(open)`.
20
+ - the secret of an Effect's auth, of a header, or of a command's `env`: `secret(open)`;
21
+ - the look of a Gate slot: `gate({ …, look: open })`.
21
22
 
22
23
  `jr2 up` refuses a Workflow with an Open part that nobody bound, and prints the `customize()`
23
24
  line that binds it: ``refusing: workflow "<name>" leaves <part> open — bind it where the Machine
24
25
  is registered: export const machine = customize(<import>, …) (<adr>)``. A run never sees an
25
- Open part.
26
+ Open part. An Open look is the one exception: `jr2 up` warns about it and does not refuse,
27
+ because a person can still answer the Gate with `jr2 send`.
26
28
 
27
29
  **Example**
28
30
 
29
31
  ```ts
30
32
  import { z } from "zod";
31
- import { agent, customize, defineEvent, fail, jr2Setup, open, workspace } from "@jr2/orchestrator";
33
+ import {
34
+ agent,
35
+ customize,
36
+ defineEvent,
37
+ fail,
38
+ isReady,
39
+ jr2Setup,
40
+ open,
41
+ workspace,
42
+ worktree,
43
+ type Workspaced,
44
+ } from "@jr2/orchestrator";
32
45
 
33
46
  const finish = defineEvent({
34
47
  name: "finish",
@@ -36,19 +49,40 @@ const finish = defineEvent({
36
49
  input: z.object({}),
37
50
  });
38
51
 
52
+ type Input = Workspaced<{}, "app">;
53
+
54
+ const fixTree = (context: Input) => `${context.workspace.repos.app}/fix` as const;
55
+
39
56
  const body = jr2Setup({
57
+ types: {} as { context: Input; input: Input },
40
58
  events: [finish],
41
- actors: { coder: agent({ model: open, instructions: "You fix the failing test." }), fail: fail() },
59
+ actors: {
60
+ coder: agent({ model: open, instructions: "You fix the failing test." }),
61
+ cut: worktree(),
62
+ fail: fail(),
63
+ },
42
64
  }).createMachine({
43
65
  id: "fix",
66
+ context: ({ input }) => input,
44
67
  on: { "workspace.lost": ".lost", "agent.fault": ".failed" },
45
- initial: "coding",
68
+ initial: "cutting",
46
69
  states: {
70
+ cutting: {
71
+ invoke: {
72
+ src: "cut",
73
+ input: ({ context }) => ({ path: fixTree(context), branch: "jr2/fix" }),
74
+ onDone: [{ guard: ({ event }) => isReady(event.output), target: "coding" }, { target: "notCut" }],
75
+ },
76
+ },
47
77
  coding: {
48
- invoke: { src: "coder", input: { prompt: "Make `node --test` pass." } },
78
+ invoke: {
79
+ src: "coder",
80
+ input: ({ context }) => ({ prompt: "Make `node --test` pass.", cwd: fixTree(context) }),
81
+ },
49
82
  on: { finish: "done" },
50
83
  },
51
84
  done: { type: "final" },
85
+ notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
52
86
  failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
53
87
  lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
54
88
  },
@@ -57,7 +91,6 @@ const body = jr2Setup({
57
91
  // What a package exports: the repository and the model are Open.
58
92
  export const fix = workspace(body, {
59
93
  repos: { app: open },
60
- spec: () => ({ branch: "jr2/fix" }),
61
94
  });
62
95
 
63
96
  // What an Instance's `workflows/fix.ts` exports: the same Machine, its Open parts bound.
@@ -5,7 +5,7 @@ description: "Make an Open body: the actor slot that a Chart binds."
5
5
 
6
6
  # `openBody`
7
7
 
8
- Function, in `@jr2/orchestrator/src/open-body.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Charts.
8
+ Function, in `@jr2/orchestrator/src/open-body.ts`. It is an export of `@jr2/orchestrator`, in the [Charts](group-charts.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
11
  function openBody(decl: OpenBodyDeclaration): OpenBodyLogic
@@ -5,7 +5,7 @@ description: Read the params of a pick from the event that entered the state.
5
5
 
6
6
  # `paramsOf`
7
7
 
8
- Function, in `@jr2/orchestrator/src/pick.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Effects.
8
+ Function, in `@jr2/orchestrator/src/pick.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 paramsOf<
@@ -50,9 +50,11 @@ import {
50
50
  command,
51
51
  defineEvent,
52
52
  fail,
53
+ isReady,
53
54
  jr2Setup,
54
55
  paramsOf,
55
56
  workspace,
57
+ worktree,
56
58
  type Workspaced,
57
59
  } from "@jr2/orchestrator";
58
60
 
@@ -70,6 +72,8 @@ const finished = defineEvent({
70
72
 
71
73
  type Input = Workspaced<{}, "app">;
72
74
 
75
+ const fixTree = (context: Input) => `${context.workspace.repos.app}/fix` as const;
76
+
73
77
  const body = jr2Setup({
74
78
  types: {} as { context: Input; input: Input },
75
79
  events: [runTest, finished],
@@ -78,6 +82,7 @@ const body = jr2Setup({
78
82
  model: "anthropic/claude-haiku-5-5",
79
83
  instructions: "You are a careful engineer.",
80
84
  }),
85
+ cut: worktree(),
81
86
  test: command(["node", "--test", arg("file")]),
82
87
  fail: fail(),
83
88
  },
@@ -85,12 +90,22 @@ const body = jr2Setup({
85
90
  id: "fix-tests",
86
91
  context: ({ input }) => input,
87
92
  on: { "workspace.lost": ".lost", "agent.fault": ".failed" },
88
- initial: "coding",
93
+ initial: "cutting",
89
94
  states: {
95
+ cutting: {
96
+ invoke: {
97
+ src: "cut",
98
+ input: ({ context }) => ({ path: fixTree(context), branch: "fix-tests" }),
99
+ onDone: [{ guard: ({ event }) => isReady(event.output), target: "coding" }, { target: "notCut" }],
100
+ },
101
+ },
90
102
  coding: {
91
103
  invoke: {
92
104
  src: "coder",
93
- input: { prompt: "Make the tests pass. Run the tests of one module at a time." },
105
+ input: ({ context }) => ({
106
+ prompt: "Make the tests pass. Run the tests of one module at a time.",
107
+ cwd: fixTree(context),
108
+ }),
94
109
  },
95
110
  on: { finished: "done" },
96
111
  initial: "ready",
@@ -100,13 +115,17 @@ const body = jr2Setup({
100
115
  invoke: {
101
116
  src: "test",
102
117
  // A plain mapper: the Machine makes the file name from the pick's `module`.
103
- input: ({ event }) => ({ file: `test/${paramsOf(event, runTest).module}.test.js` }),
118
+ input: ({ context, event }) => ({
119
+ file: `test/${paramsOf(event, runTest).module}.test.js`,
120
+ worktree: fixTree(context),
121
+ }),
104
122
  onDone: "ready",
105
123
  },
106
124
  },
107
125
  },
108
126
  },
109
127
  done: { type: "final" },
128
+ notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
110
129
  failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
111
130
  lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
112
131
  },
@@ -114,7 +133,6 @@ const body = jr2Setup({
114
133
 
115
134
  export const machine = workspace(body, {
116
135
  repos: { app: { url: "https://github.com/you/app.git" } },
117
- spec: () => ({ branch: "fix-tests" }),
118
136
  });
119
137
  ```
120
138
 
@@ -1,11 +1,11 @@
1
1
  ---
2
2
  title: pool
3
- description: "Make a Pool: a Machine that runs one worker Machine for each item that a Source gives, with at most `cap` workers at once."
3
+ description: "Make a Pool: a Machine that runs one worker for each item that a Source gives, with at most `cap` workers at once."
4
4
  ---
5
5
 
6
6
  # `pool`
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
9
 
10
10
  ## Overload 1
11
11
 
@@ -19,9 +19,12 @@ function pool<
19
19
  ): PoolMachine<TWorker, z.infer<TSchema>>
20
20
  ```
21
21
 
22
- Make a Pool: a Machine that runs one worker Machine for each item that a Source gives, with at
23
- most `cap` workers at once. Use it as the root of a Workflow (`export const machine = pool(…)`),
24
- or compose it in another Machine.
22
+ Make a Pool: a Machine that runs one worker for each item that a Source gives, with at most
23
+ `cap` workers at once. Use it as the root of a Workflow (`export const machine = pool(…)`), or
24
+ compose it in another Machine.
25
+
26
+ The worker is a Machine, which runs inside the Pool's run, or a `dispatch(...)` slot, which makes
27
+ each item a run of its own (a Pool of runs, which stands; see the third form).
25
28
 
26
29
  The run ends when the Source has no item ready and no worker runs. Its output is
27
30
  `{ status, items, failures }`: `status` is `"drained"` when no item is left, or `"deadlocked"`
@@ -51,9 +54,10 @@ its own.
51
54
  The run input of the Pool, as a zod object: what a caller sends to start a run. `cap` and
52
55
  `itemInput` read it, typed by it. A worker never gets it: each worker gets its item. Default:
53
56
  none, and then their `input` is `unknown`.
54
- - `source`: `SourceSpec<T>`
57
+ - `source`: `SourceSpec<T, TInput> | SourceSpec<T> | ReadSourceSpec<T, TInput> | ReadSourceSpec<T>`
55
58
 
56
- Where the items come from. Make it with [`source`](source.md).
59
+ Where the items come from: a pull or a read Source. Make it with [`source`](source.md). A push Source
60
+ needs a standing Pool of runs.
57
61
  - `itemId`: `(item: T) => string`
58
62
 
59
63
  The id of an item. The Pool uses it as the id of the item's worker and in the `active` list
@@ -76,6 +80,9 @@ its own.
76
80
  ends with failures, `drained` or `deadlocked`, it fails the run with the reason
77
81
  `"<n> of <m> items failed"` and the detail `{ status, items, failures }`. `"report"`: the Pool
78
82
  ends `done`, with the failures in its output. Default: `"fail"`.
83
+ - `standing` (optional): `false`
84
+
85
+ A Pool of child Machines never stands: a child cannot be handed over.
79
86
 
80
87
  **Returns**: The Pool, as a Machine.
81
88
 
@@ -83,7 +90,7 @@ its own.
83
90
 
84
91
  ```ts
85
92
  import { fromPromise } from "xstate";
86
- import { customize, pool, source } from "@jr2/orchestrator";
93
+ import { customize, pool, source, type PoolNextInput } from "@jr2/orchestrator";
87
94
  import { task } from "@jr2/machines";
88
95
 
89
96
  type Issue = { id: string; title: string };
@@ -94,7 +101,7 @@ const backlog: Issue[] = [
94
101
  ];
95
102
 
96
103
  const issues = source<Issue>({
97
- next: fromPromise(async ({ input }: { input: { active: string[] } }) => {
104
+ next: fromPromise(async ({ input }: { input: PoolNextInput }) => {
98
105
  const issue = backlog.find((i) => !input.active.includes(i.id)) ?? null;
99
106
  if (issue) backlog.splice(backlog.indexOf(issue), 1);
100
107
  return issue;
@@ -151,9 +158,10 @@ an example.
151
158
  The run input of the Pool, as a zod object: what a caller sends to start a run. `cap` and
152
159
  `itemInput` read it, typed by it. A worker never gets it: each worker gets its item. Default:
153
160
  none, and then their `input` is `unknown`.
154
- - `source`: `SourceSpec<T>`
161
+ - `source`: `SourceSpec<T, TInput> | SourceSpec<T> | ReadSourceSpec<T, TInput> | ReadSourceSpec<T>`
155
162
 
156
- Where the items come from. Make it with [`source`](source.md).
163
+ Where the items come from: a pull or a read Source. Make it with [`source`](source.md). A push Source
164
+ needs a standing Pool of runs.
157
165
  - `itemId`: `(item: T) => string`
158
166
 
159
167
  The id of an item. The Pool uses it as the id of the item's worker and in the `active` list
@@ -176,6 +184,9 @@ an example.
176
184
  ends with failures, `drained` or `deadlocked`, it fails the run with the reason
177
185
  `"<n> of <m> items failed"` and the detail `{ status, items, failures }`. `"report"`: the Pool
178
186
  ends `done`, with the failures in its output. Default: `"fail"`.
187
+ - `standing` (optional): `false`
188
+
189
+ A Pool of child Machines never stands: a child cannot be handed over.
179
190
 
180
191
  **Returns**: The Pool, as a Machine.
181
192
 
@@ -184,3 +195,60 @@ an example.
184
195
  - [Run one worker per item](../../guides/run-one-worker-per-item.md)
185
196
  - [Pools and Sources](../../concepts/pools-and-sources.md)
186
197
  - [ADR-0017: The run loop is a jr2 `pool` over a generalized source port](../decisions/0017-pool-over-a-source-port.md)
198
+
199
+ ## Overload 3
200
+
201
+ ```ts
202
+ function pool<
203
+ I,
204
+ T,
205
+ >(
206
+ worker: EffectLogic<I, DispatchOutput>,
207
+ spec: StandingPoolSpec<T, I>,
208
+ ): StandingPoolMachine
209
+ ```
210
+
211
+ Make a standing Pool of runs: each item that the Source gives is a run of the `dispatch` slot's
212
+ Workflow, keyed by `itemId` in that Workflow, with at most `cap` live at once ([ADR-0017](../decisions/0017-pool-over-a-source-port.md)). The
213
+ slot says `wait: true` and has no `target`. The Pool never ends by itself: when it has no work, it
214
+ waits for a Hook's delivery, a `reread` or its `pollEvery`. A run that ends in any way frees its
215
+ slot, and is a `settled` mark on the run's feed; it is never the Pool's error, because the run is
216
+ not the Pool's child. Use it as the top Machine of its Workflow, in a file of its own.
217
+
218
+ **Parameters**
219
+
220
+ - `worker` ([`EffectLogic`](type-effectlogic.md)): The `dispatch(...)` slot of the Workflow that runs each item.
221
+ - `spec`: The Source, the item id, the cap and the run's body. See [`StandingPoolSpec`](type-standingpoolspec.md).
222
+
223
+ **Returns**: The standing Pool, as a Machine.
224
+
225
+ **Example**
226
+
227
+ ```ts
228
+ import { z } from "zod";
229
+ import { carry, dispatch, pool, skip, source } from "@jr2/orchestrator";
230
+ import type {} from "@jr2/orchestrator/hooks/gitlab";
231
+
232
+ const failed = z.object({ sha: z.string() });
233
+
234
+ export const machine = pool(dispatch("triage", { input: failed, wait: true }), {
235
+ id: "pipelines",
236
+ standing: true,
237
+ source: source({
238
+ item: failed,
239
+ hooks: {
240
+ gitlab: {
241
+ "pipeline.failed": ({ payload }) =>
242
+ payload.object_attributes.sha === "" ? skip("no commit") : carry({ sha: payload.object_attributes.sha }),
243
+ },
244
+ },
245
+ }),
246
+ itemId: (p) => `pipeline-${p.sha}`,
247
+ cap: 4,
248
+ });
249
+ ```
250
+
251
+ **See also**
252
+
253
+ - [Pools and Sources](../../concepts/pools-and-sources.md)
254
+ - [ADR-0017: The run loop is a jr2 `pool` over a generalized source port](../decisions/0017-pool-over-a-source-port.md)
@@ -1,24 +1,23 @@
1
1
  ---
2
2
  title: push
3
- description: "Make a `push` Effect: it pushes the branch of the Workspace to the Binding of its Repo Slot."
3
+ description: "Make a `push` Effect: it pushes the branch of a Worktree to the Binding of its Repo Slot."
4
4
  ---
5
5
 
6
6
  # `push`
7
7
 
8
- Function, in `@jr2/orchestrator/src/sandbox-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/sandbox-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
- function push<
12
- const O extends PushOptions,
13
- >(
14
- options?: O,
15
- ): EffectLogic<PushInput<O> | void, PushOutput>
11
+ function push<const O extends PushOptions>(options?: O): EffectLogic<PushInput<O>, PushOutput>
16
12
  ```
17
13
 
18
- Make a `push` Effect: it pushes the branch of the Workspace to the Binding of its Repo Slot.
14
+ Make a `push` Effect: it pushes the branch of a Worktree to the Binding of its Repo Slot.
19
15
  Put it in `actors`, and invoke it from the body of a `workspace()`: `actors: { publish: push({
20
16
  sign: true }) }`.
21
17
 
18
+ Its input names the Worktree: `{ worktree }`. It has no branch. jr2 reads the branch from the
19
+ `worktree()` cut of that path, so an Agent that moves `HEAD` does not change what jr2 pushes.
20
+
22
21
  It runs in the Sandbox Effector of the Workspace, with the push credential of the
23
22
  `git.credentials` entry that the Binding matches. The Agent never reads that credential. It
24
23
  pushes one commit: the tip of the Agent's branch when the Effect starts, or, with `pin`, the
@@ -26,8 +25,10 @@ commit that the input names. After an Orchestrator restart, jr2 pushes only that
26
25
  again. With `sign` or `squash`, the commit on the remote is not the Agent's own. Then jr2 moves
27
26
  the Agent's branch to it.
28
27
 
29
- Every outcome is output (`PushOutput`): `pushed`, `rejected`, `diverged` or `unknown`. Each
30
- field of [`PushOptions`](type-pushoptions.md) tells what it refuses. When it starts, it also refuses a push
28
+ Every outcome is output (`PushOutput`): `pushed`, `rejected`, `diverged` or `unknown`. A
29
+ `worktree` that no cut made in this Sandbox, a Worktree of another Repo Slot, and a detached
30
+ Worktree are `rejected` at `stage` `start`, and nothing is pushed. Each field of
31
+ [`PushOptions`](type-pushoptions.md) tells what it refuses. When it starts, it also refuses a push
31
32
  outside a Workspace: `push "<slot>" runs in the Sandbox Effector of a Workspace, and its state is
32
33
  not inside a workspace() — invoke it from a Workspace's body (ADR-0067)`.
33
34
 
@@ -45,9 +46,11 @@ import {
45
46
  agent,
46
47
  defineEvent,
47
48
  fail,
49
+ isReady,
48
50
  jr2Setup,
49
51
  push,
50
52
  workspace,
53
+ worktree,
51
54
  type Workspaced,
52
55
  } from "@jr2/orchestrator";
53
56
 
@@ -59,6 +62,8 @@ const committed = defineEvent({
59
62
 
60
63
  type Input = Workspaced<{}, "app">;
61
64
 
65
+ const fixTree = (context: Input) => `${context.workspace.repos.app}/fix` as const;
66
+
62
67
  const body = jr2Setup({
63
68
  types: {} as { context: Input; input: Input },
64
69
  events: [committed],
@@ -67,6 +72,7 @@ const body = jr2Setup({
67
72
  model: "anthropic/claude-haiku-5-5",
68
73
  instructions: "You are a careful engineer.",
69
74
  }),
75
+ cut: worktree(),
70
76
  publish: push({ sign: true }),
71
77
  fail: fail(),
72
78
  },
@@ -74,10 +80,20 @@ const body = jr2Setup({
74
80
  id: "fix-test",
75
81
  context: ({ input }) => input,
76
82
  on: { "workspace.lost": ".failed", "agent.fault": ".failed" },
77
- initial: "coding",
83
+ initial: "cutting",
78
84
  states: {
85
+ cutting: {
86
+ invoke: {
87
+ src: "cut",
88
+ input: ({ context }) => ({ path: fixTree(context), branch: "fix-test" }),
89
+ onDone: [{ guard: ({ event }) => isReady(event.output), target: "coding" }, { target: "notCut" }],
90
+ },
91
+ },
79
92
  coding: {
80
- invoke: { src: "coder", input: { prompt: "Fix the failing test, and commit the fix." } },
93
+ invoke: {
94
+ src: "coder",
95
+ input: ({ context }) => ({ prompt: "Fix the failing test, and commit the fix.", cwd: fixTree(context) }),
96
+ },
81
97
  // The Agent moves the Machine on with a pick. An Agent's actor never ends, so `onDone`
82
98
  // never fires.
83
99
  on: { committed: "publishing" },
@@ -85,6 +101,8 @@ const body = jr2Setup({
85
101
  publishing: {
86
102
  invoke: {
87
103
  src: "publish",
104
+ // jr2 reads the branch from the cut of this Worktree.
105
+ input: ({ context }) => ({ worktree: fixTree(context) }),
88
106
  onDone: [
89
107
  { guard: ({ event }) => event.output.outcome === "pushed", target: "done" },
90
108
  { target: "failed" },
@@ -92,6 +110,7 @@ const body = jr2Setup({
92
110
  },
93
111
  },
94
112
  done: { type: "final" },
113
+ notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
95
114
  // Not a final state: the run ends `failed`, and the Workspace deletes the Sandbox.
96
115
  failed: { invoke: { src: "fail", input: { reason: "the fix was not pushed" } } },
97
116
  },
@@ -99,7 +118,6 @@ const body = jr2Setup({
99
118
 
100
119
  export const machine = workspace(body, {
101
120
  repos: { app: { url: "https://github.com/you/app.git" } },
102
- spec: () => ({ branch: "fix-test" }),
103
121
  });
104
122
  ```
105
123
 
@@ -0,0 +1,21 @@
1
+ ---
2
+ title: readyOf
3
+ description: The `ready` output of an `onDone` arm that `isReady` guards.
4
+ ---
5
+
6
+ # `readyOf`
7
+
8
+ Function, 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
+ function readyOf<O extends { outcome: string }>(output: O): Extract<O, { outcome: "ready" }>
12
+ ```
13
+
14
+ The `ready` output of an `onDone` arm that `isReady` guards. xstate carries no guard's narrowing
15
+ to its actions, so an `assign` reads the output through this.
16
+
17
+ **Parameters**
18
+
19
+ - `output`
20
+
21
+ - `outcome`: `string`
@@ -0,0 +1,19 @@
1
+ ---
2
+ title: reread
3
+ description: Read the Source again.
4
+ ---
5
+
6
+ # `reread`
7
+
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
+ ```ts
11
+ function reread(): Reread
12
+ ```
13
+
14
+ Read the Source again. The Pool calls its `next`, or runs its `read`, at once; a read that runs
15
+ now reads once more after it ends. Only a Source that can read gives it.
16
+
17
+ **See also**
18
+
19
+ - [Pools and Sources](../../concepts/pools-and-sources.md)
@@ -5,7 +5,7 @@ description: "Name an Effect secret: `secret(\"jira\")`."
5
5
 
6
6
  # `secret`
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
  ## Overload 1
11
11
 
@@ -56,13 +56,25 @@ And at `jr2 up`:
56
56
  **Example**
57
57
 
58
58
  ```ts
59
- import { command, fail, jr2Setup, secret, workspace, type Workspaced } from "@jr2/orchestrator";
59
+ import {
60
+ command,
61
+ fail,
62
+ isReady,
63
+ jr2Setup,
64
+ secret,
65
+ workspace,
66
+ worktree,
67
+ type Workspaced,
68
+ } from "@jr2/orchestrator";
60
69
 
61
70
  type Input = Workspaced<{}, "app">;
62
71
 
72
+ const deployTree = (context: Input) => `${context.workspace.repos.app}/deploy` as const;
73
+
63
74
  const body = jr2Setup({
64
75
  types: {} as { context: Input; input: Input },
65
76
  actors: {
77
+ cut: worktree(),
66
78
  // The command reads the file at $KUBECONFIG. The Agent never reads the secret.
67
79
  deploy: command(["kubectl", "apply", "-f", "k8s/"], {
68
80
  env: { KUBECONFIG: secret("kube").path },
@@ -73,17 +85,26 @@ const body = jr2Setup({
73
85
  id: "deploy",
74
86
  context: ({ input }) => input,
75
87
  on: { "workspace.lost": ".lost" },
76
- initial: "deploying",
88
+ initial: "cutting",
77
89
  states: {
78
- deploying: { invoke: { src: "deploy", onDone: "done" } },
90
+ cutting: {
91
+ invoke: {
92
+ src: "cut",
93
+ input: ({ context }) => ({ path: deployTree(context), branch: "deploy" }),
94
+ onDone: [{ guard: ({ event }) => isReady(event.output), target: "deploying" }, { target: "notCut" }],
95
+ },
96
+ },
97
+ deploying: {
98
+ invoke: { src: "deploy", input: ({ context }) => ({ worktree: deployTree(context) }), onDone: "done" },
99
+ },
79
100
  done: { type: "final" },
101
+ notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
80
102
  lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
81
103
  },
82
104
  });
83
105
 
84
106
  export const machine = workspace(body, {
85
107
  repos: { app: { url: "https://github.com/you/app.git" } },
86
- spec: () => ({ branch: "deploy" }),
87
108
  });
88
109
  ```
89
110
 
@@ -5,7 +5,7 @@ description: "A guard that is true for an event that one party sent, and false f
5
5
 
6
6
  # `sentBy`
7
7
 
8
- Function, in `@jr2/orchestrator/src/party.ts`. It is an export of `@jr2/orchestrator`, on the [Authoring surface](../authoring-surface.md) page, in Machine and events.
8
+ Function, in `@jr2/orchestrator/src/party.ts`. It is an export of `@jr2/orchestrator`, in the [Machine and events](group-machine-and-events.md) group of the [Authoring surface](../authoring-surface.md) page.
9
9
 
10
10
  ```ts
11
11
  function sentBy<const Id extends string>(id: Id): { type: typeof SENT_BY; params: { id: Id } }
@@ -0,0 +1,22 @@
1
+ ---
2
+ title: skip
3
+ description: Bring nothing, and say why.
4
+ ---
5
+
6
+ # `skip`
7
+
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
+ ```ts
11
+ function skip(reason: string): Skip
12
+ ```
13
+
14
+ Bring nothing, and say why. The reason goes in the Hook's answer and in its hook log.
15
+
16
+ **Parameters**
17
+
18
+ - `reason`: Why the delivery brings nothing, for a person to read.
19
+
20
+ **See also**
21
+
22
+ - [Pools and Sources](../../concepts/pools-and-sources.md)