@jr2/orchestrator 0.3.0 → 0.5.1

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 (354) hide show
  1. package/README.md +20 -2
  2. package/bin/server.ts +7 -4
  3. package/console/canvas.ts +27 -14
  4. package/console/components/app.ts +12 -1
  5. package/console/components/fleet.ts +52 -6
  6. package/console/components/machine-pane.ts +128 -2
  7. package/console/components/nav.ts +1 -1
  8. package/console/components/schema-form.ts +12 -4
  9. package/console/json-field.ts +23 -0
  10. package/console/main.ts +122 -39
  11. package/console/store.ts +321 -21
  12. package/console/style.css +111 -0
  13. package/docs/agents-block.md +5 -0
  14. package/docs/concepts/agents-and-turns.md +442 -0
  15. package/docs/concepts/architecture.md +230 -0
  16. package/docs/concepts/charts.md +143 -0
  17. package/docs/concepts/composition.md +357 -0
  18. package/docs/concepts/converge.md +254 -0
  19. package/docs/concepts/durable-runs.md +189 -0
  20. package/docs/concepts/effects.md +603 -0
  21. package/docs/concepts/gates.md +208 -0
  22. package/docs/concepts/machines-and-workflows.md +289 -0
  23. package/docs/concepts/pools-and-sources.md +230 -0
  24. package/docs/concepts/secrets-and-trust.md +222 -0
  25. package/docs/concepts/the-menu.md +378 -0
  26. package/docs/concepts/workspaces.md +678 -0
  27. package/docs/get-started/a-model-decides.md +563 -0
  28. package/docs/get-started/an-agent-in-a-sandbox.md +381 -0
  29. package/docs/get-started/connect-a-model.md +248 -0
  30. package/docs/get-started/create-an-instance.md +194 -0
  31. package/docs/get-started/have-your-assistant-write-a-machine.md +922 -0
  32. package/docs/get-started/install.md +126 -0
  33. package/docs/guides/add-tools-to-the-sandbox.md +295 -0
  34. package/docs/guides/answer-a-gate.md +304 -0
  35. package/docs/guides/bind-open-parts.md +223 -0
  36. package/docs/guides/cancel-a-run.md +146 -0
  37. package/docs/guides/clean-up.md +206 -0
  38. package/docs/guides/fix-a-failed-converge.md +361 -0
  39. package/docs/guides/give-the-cluster-git-credentials.md +222 -0
  40. package/docs/guides/iterate-on-a-machine-on-kind.md +190 -0
  41. package/docs/guides/let-an-agent-write-a-chart.md +226 -0
  42. package/docs/guides/look-inside-a-sandbox.md +174 -0
  43. package/docs/guides/mirror-the-kit-images.md +176 -0
  44. package/docs/guides/move-from-kind-to-a-shared-cluster.md +302 -0
  45. package/docs/guides/open-the-console.md +91 -0
  46. package/docs/guides/publish-a-machine-as-an-npm-package.md +350 -0
  47. package/docs/guides/push-and-sign-a-branch.md +486 -0
  48. package/docs/guides/run-a-chart-by-name.md +270 -0
  49. package/docs/guides/run-a-command-or-call-a-url.md +544 -0
  50. package/docs/guides/run-one-worker-per-item.md +321 -0
  51. package/docs/guides/set-an-agents-access-and-dials.md +375 -0
  52. package/docs/guides/size-a-workspace.md +204 -0
  53. package/docs/guides/start-a-run-from-a-run.md +237 -0
  54. package/docs/guides/start-a-run.md +207 -0
  55. package/docs/guides/upgrade-the-kit-version.md +240 -0
  56. package/docs/guides/use-a-hosted-provider.md +208 -0
  57. package/docs/guides/use-a-local-model.md +313 -0
  58. package/docs/guides/watch-a-run.md +326 -0
  59. package/docs/guides/write-a-workflow.md +318 -0
  60. package/docs/index.md +44 -0
  61. package/docs/llms.txt +216 -0
  62. package/docs/reference/authoring-surface/agent.md +128 -0
  63. package/docs/reference/authoring-surface/answer.md +140 -0
  64. package/docs/reference/authoring-surface/arg.md +60 -0
  65. package/docs/reference/authoring-surface/basic.md +62 -0
  66. package/docs/reference/authoring-surface/bearer.md +53 -0
  67. package/docs/reference/authoring-surface/chartschema.md +23 -0
  68. package/docs/reference/authoring-surface/chartschemafor.md +48 -0
  69. package/docs/reference/authoring-surface/command.md +191 -0
  70. package/docs/reference/authoring-surface/customize.md +64 -0
  71. package/docs/reference/authoring-surface/defineconfig.md +41 -0
  72. package/docs/reference/authoring-surface/defineevent.md +114 -0
  73. package/docs/reference/authoring-surface/dispatch.md +126 -0
  74. package/docs/reference/authoring-surface/fail.md +83 -0
  75. package/docs/reference/authoring-surface/file.md +122 -0
  76. package/docs/reference/authoring-surface/frompick.md +277 -0
  77. package/docs/reference/authoring-surface/http.md +159 -0
  78. package/docs/reference/authoring-surface/isfailure.md +58 -0
  79. package/docs/reference/authoring-surface/jr2setup.md +237 -0
  80. package/docs/reference/authoring-surface/open.md +74 -0
  81. package/docs/reference/authoring-surface/openbody.md +86 -0
  82. package/docs/reference/authoring-surface/paramsof.md +125 -0
  83. package/docs/reference/authoring-surface/pool.md +186 -0
  84. package/docs/reference/authoring-surface/push.md +112 -0
  85. package/docs/reference/authoring-surface/secret.md +118 -0
  86. package/docs/reference/authoring-surface/sentby.md +83 -0
  87. package/docs/reference/authoring-surface/source.md +51 -0
  88. package/docs/reference/authoring-surface/text.md +62 -0
  89. package/docs/reference/authoring-surface/type-agentdeclaration.md +27 -0
  90. package/docs/reference/authoring-surface/type-agentdefinition.md +80 -0
  91. package/docs/reference/authoring-surface/type-agentlogic.md +15 -0
  92. package/docs/reference/authoring-surface/type-agentslots.md +12 -0
  93. package/docs/reference/authoring-surface/type-answeraction.md +12 -0
  94. package/docs/reference/authoring-surface/type-arg.md +19 -0
  95. package/docs/reference/authoring-surface/type-argnames.md +12 -0
  96. package/docs/reference/authoring-surface/type-binding.md +62 -0
  97. package/docs/reference/authoring-surface/type-bindingof.md +12 -0
  98. package/docs/reference/authoring-surface/type-bodyacceptsdoor.md +15 -0
  99. package/docs/reference/authoring-surface/type-bodyacceptsslots.md +17 -0
  100. package/docs/reference/authoring-surface/type-ceilings.md +41 -0
  101. package/docs/reference/authoring-surface/type-chainlink.md +19 -0
  102. package/docs/reference/authoring-surface/type-chartaction.md +46 -0
  103. package/docs/reference/authoring-surface/type-chartagent.md +28 -0
  104. package/docs/reference/authoring-surface/type-chartevent.md +20 -0
  105. package/docs/reference/authoring-surface/type-chartguard.md +20 -0
  106. package/docs/reference/authoring-surface/type-chartinvoke.md +28 -0
  107. package/docs/reference/authoring-surface/type-chartjson.md +14 -0
  108. package/docs/reference/authoring-surface/type-chartstate.md +46 -0
  109. package/docs/reference/authoring-surface/type-charttext.md +40 -0
  110. package/docs/reference/authoring-surface/type-charttransition.md +22 -0
  111. package/docs/reference/authoring-surface/type-charttransitions.md +14 -0
  112. package/docs/reference/authoring-surface/type-chartvalue.md +15 -0
  113. package/docs/reference/authoring-surface/type-childat.md +12 -0
  114. package/docs/reference/authoring-surface/type-childslots.md +12 -0
  115. package/docs/reference/authoring-surface/type-commandenv.md +15 -0
  116. package/docs/reference/authoring-surface/type-commandinput.md +19 -0
  117. package/docs/reference/authoring-surface/type-commandoptions.md +78 -0
  118. package/docs/reference/authoring-surface/type-commandoutput.md +104 -0
  119. package/docs/reference/authoring-surface/type-customize.md +109 -0
  120. package/docs/reference/authoring-surface/type-dispatchdefinition.md +39 -0
  121. package/docs/reference/authoring-surface/type-dispatchinput.md +14 -0
  122. package/docs/reference/authoring-surface/type-dispatchopenparts.md +14 -0
  123. package/docs/reference/authoring-surface/type-dispatchoutput.md +65 -0
  124. package/docs/reference/authoring-surface/type-duration.md +15 -0
  125. package/docs/reference/authoring-surface/type-effectbinding.md +93 -0
  126. package/docs/reference/authoring-surface/type-effectlogic.md +12 -0
  127. package/docs/reference/authoring-surface/type-envopenparts.md +14 -0
  128. package/docs/reference/authoring-surface/type-eventaudience.md +27 -0
  129. package/docs/reference/authoring-surface/type-eventdef.md +45 -0
  130. package/docs/reference/authoring-surface/type-eventfrom.md +16 -0
  131. package/docs/reference/authoring-surface/type-eventsemantics.md +26 -0
  132. package/docs/reference/authoring-surface/type-execoutcome.md +34 -0
  133. package/docs/reference/authoring-surface/type-failslot.md +14 -0
  134. package/docs/reference/authoring-surface/type-failure.md +19 -0
  135. package/docs/reference/authoring-surface/type-failureinput.md +20 -0
  136. package/docs/reference/authoring-surface/type-filebody.md +41 -0
  137. package/docs/reference/authoring-surface/type-frominput.md +14 -0
  138. package/docs/reference/authoring-surface/type-hostinjectedinput.md +58 -0
  139. package/docs/reference/authoring-surface/type-httpdefinition.md +101 -0
  140. package/docs/reference/authoring-surface/type-httpinput.md +12 -0
  141. package/docs/reference/authoring-surface/type-httpmethod.md +14 -0
  142. package/docs/reference/authoring-surface/type-httpopenparts.md +12 -0
  143. package/docs/reference/authoring-surface/type-httpoutput.md +89 -0
  144. package/docs/reference/authoring-surface/type-httprequestparts.md +33 -0
  145. package/docs/reference/authoring-surface/type-jr2config.md +126 -0
  146. package/docs/reference/authoring-surface/type-lends.md +38 -0
  147. package/docs/reference/authoring-surface/type-logicat.md +12 -0
  148. package/docs/reference/authoring-surface/type-markedif.md +12 -0
  149. package/docs/reference/authoring-surface/type-mergedactors.md +12 -0
  150. package/docs/reference/authoring-surface/type-namedsecret.md +25 -0
  151. package/docs/reference/authoring-surface/type-noslotspec.md +26 -0
  152. package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +32 -0
  153. package/docs/reference/authoring-surface/type-openbodydeclaration.md +40 -0
  154. package/docs/reference/authoring-surface/type-openbodylogic.md +14 -0
  155. package/docs/reference/authoring-surface/type-openbodyoutput.md +42 -0
  156. package/docs/reference/authoring-surface/type-openbodyslot.md +18 -0
  157. package/docs/reference/authoring-surface/type-opencommandinput.md +17 -0
  158. package/docs/reference/authoring-surface/type-openeffect.md +12 -0
  159. package/docs/reference/authoring-surface/type-openeffectslots.md +12 -0
  160. package/docs/reference/authoring-surface/type-openof.md +12 -0
  161. package/docs/reference/authoring-surface/type-opensecret.md +23 -0
  162. package/docs/reference/authoring-surface/type-opensecretmark.md +12 -0
  163. package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +31 -0
  164. package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +32 -0
  165. package/docs/reference/authoring-surface/type-poolmachine.md +28 -0
  166. package/docs/reference/authoring-surface/type-poolspec.md +60 -0
  167. package/docs/reference/authoring-surface/type-pushinput.md +15 -0
  168. package/docs/reference/authoring-surface/type-pushoptions.md +79 -0
  169. package/docs/reference/authoring-surface/type-pushoutput.md +124 -0
  170. package/docs/reference/authoring-surface/type-pushwireoutput.md +12 -0
  171. package/docs/reference/authoring-surface/type-quantity.md +14 -0
  172. package/docs/reference/authoring-surface/type-reached.md +12 -0
  173. package/docs/reference/authoring-surface/type-reposlot.md +70 -0
  174. package/docs/reference/authoring-surface/type-reposlotsof.md +16 -0
  175. package/docs/reference/authoring-surface/type-sandboxoptions.md +77 -0
  176. package/docs/reference/authoring-surface/type-secret.md +25 -0
  177. package/docs/reference/authoring-surface/type-sender.md +19 -0
  178. package/docs/reference/authoring-surface/type-sentbyguards.md +12 -0
  179. package/docs/reference/authoring-surface/type-size.md +85 -0
  180. package/docs/reference/authoring-surface/type-slothandles.md +32 -0
  181. package/docs/reference/authoring-surface/type-sourcenextresult.md +17 -0
  182. package/docs/reference/authoring-surface/type-sourcespec.md +44 -0
  183. package/docs/reference/authoring-surface/type-syncstate.md +12 -0
  184. package/docs/reference/authoring-surface/type-text.md +19 -0
  185. package/docs/reference/authoring-surface/type-textpart.md +24 -0
  186. package/docs/reference/authoring-surface/type-thinkinglevel.md +39 -0
  187. package/docs/reference/authoring-surface/type-toparameterizedobject.md +14 -0
  188. package/docs/reference/authoring-surface/type-toprovidedactor.md +14 -0
  189. package/docs/reference/authoring-surface/type-unknown.md +21 -0
  190. package/docs/reference/authoring-surface/type-usercontainer.md +77 -0
  191. package/docs/reference/authoring-surface/type-withoutemptyindex.md +20 -0
  192. package/docs/reference/authoring-surface/type-workflowevent.md +46 -0
  193. package/docs/reference/authoring-surface/type-workspaceaccess.md +16 -0
  194. package/docs/reference/authoring-surface/type-workspaced.md +94 -0
  195. package/docs/reference/authoring-surface/type-workspacehandles.md +23 -0
  196. package/docs/reference/authoring-surface/type-workspacemachine.md +29 -0
  197. package/docs/reference/authoring-surface/type-workspaceof.md +13 -0
  198. package/docs/reference/authoring-surface/type-workspaceoptions.md +39 -0
  199. package/docs/reference/authoring-surface/type-workspacespec.md +37 -0
  200. package/docs/reference/authoring-surface/workspace.md +259 -0
  201. package/docs/reference/authoring-surface.md +197 -0
  202. package/docs/reference/cli.md +433 -0
  203. package/docs/reference/config.md +756 -0
  204. package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +113 -0
  205. package/docs/reference/decisions/0002-duplex-streaming-actor.md +110 -0
  206. package/docs/reference/decisions/0004-worktree-provisioning-model.md +124 -0
  207. package/docs/reference/decisions/0005-sandbox-pod-composition.md +230 -0
  208. package/docs/reference/decisions/0006-agent-control-surface.md +47 -0
  209. package/docs/reference/decisions/0007-durable-machine-state.md +109 -0
  210. package/docs/reference/decisions/0008-orchestrator-as-deployed-app.md +60 -0
  211. package/docs/reference/decisions/0009-cli-and-instance-interface.md +275 -0
  212. package/docs/reference/decisions/0010-bdd-acceptance-tests.md +160 -0
  213. package/docs/reference/decisions/0011-workflow-defined-events.md +141 -0
  214. package/docs/reference/decisions/0012-workspace-wrapper-machine.md +103 -0
  215. package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +157 -0
  216. package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +95 -0
  217. package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +265 -0
  218. package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +124 -0
  219. package/docs/reference/decisions/0017-pool-over-a-source-port.md +69 -0
  220. package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +111 -0
  221. package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +275 -0
  222. package/docs/reference/decisions/0020-private-ca-trust-is-a-named-concept.md +60 -0
  223. package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +100 -0
  224. package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +103 -0
  225. package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +176 -0
  226. package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +439 -0
  227. package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +65 -0
  228. package/docs/reference/decisions/0026-a-turn-that-is-over-is-never-prompted.md +62 -0
  229. package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +237 -0
  230. package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +89 -0
  231. package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +154 -0
  232. package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +100 -0
  233. package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +190 -0
  234. package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +61 -0
  235. package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +127 -0
  236. package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +57 -0
  237. package/docs/reference/decisions/0035-a-runaway-turn-is-ended-rerolled-once-then-a-fault.md +92 -0
  238. package/docs/reference/decisions/0036-a-turn-compacts-its-own-context-mid-flight.md +138 -0
  239. package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +196 -0
  240. package/docs/reference/decisions/0038-jr2-up-builds-every-image-it-deploys.md +170 -0
  241. package/docs/reference/decisions/0039-image-garbage-collects-by-reachability.md +115 -0
  242. package/docs/reference/decisions/0041-a-build-the-host-already-holds-is-not-spent-again.md +64 -0
  243. package/docs/reference/decisions/0042-ready-is-not-routable-an-admission-retries-its-connection.md +142 -0
  244. package/docs/reference/decisions/0043-the-kit-is-tested-as-installed-a-local-registry-stands-in-for-npm.md +170 -0
  245. package/docs/reference/decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md +85 -0
  246. package/docs/reference/decisions/0045-the-platform-joins-the-image-address-and-the-cluster-chooses-it.md +82 -0
  247. package/docs/reference/decisions/0046-a-converge-failure-carries-its-diagnosis.md +34 -0
  248. package/docs/reference/decisions/0047-the-git-ssh-key-source-is-the-users-choice.md +47 -0
  249. package/docs/reference/decisions/0048-the-orchestrator-boots-without-its-repos.md +36 -0
  250. package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +126 -0
  251. package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +73 -0
  252. package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +227 -0
  253. package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +81 -0
  254. package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +111 -0
  255. package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +126 -0
  256. package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +107 -0
  257. package/docs/reference/decisions/0056-a-global-jr2-hands-off-to-the-instances-own-and-an-instance-has-one-kit-version.md +62 -0
  258. package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +152 -0
  259. package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +106 -0
  260. package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +384 -0
  261. package/docs/reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md +111 -0
  262. package/docs/reference/decisions/0061-a-memory-kill-ends-the-agents-processes-not-the-harness.md +83 -0
  263. package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +212 -0
  264. package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +83 -0
  265. package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +79 -0
  266. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +65 -0
  267. package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +550 -0
  268. package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +430 -0
  269. package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +464 -0
  270. package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +180 -0
  271. package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +323 -0
  272. package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +183 -0
  273. package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +144 -0
  274. package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +122 -0
  275. package/docs/reference/decisions/0074-an-unrouted-mechanism-event-is-refused-at-load-and-faults-the-run.md +76 -0
  276. package/docs/reference/decisions.md +83 -0
  277. package/docs/reference/glossary.md +648 -0
  278. package/docs/reference/http-api.md +1348 -0
  279. package/docs/reference/machines.md +190 -0
  280. package/docs/reference/mechanism-events.md +72 -0
  281. package/docs/why.md +206 -0
  282. package/package.json +6 -4
  283. package/src/actor.ts +976 -61
  284. package/src/agent.ts +114 -38
  285. package/src/ambient.ts +4 -1
  286. package/src/assembly-checks.ts +347 -0
  287. package/src/assembly-tar.ts +494 -0
  288. package/src/assembly.ts +721 -0
  289. package/src/cause.ts +234 -0
  290. package/src/chart.ts +2182 -0
  291. package/src/charts.ts +748 -0
  292. package/src/config.ts +520 -162
  293. package/src/content-hash.ts +105 -0
  294. package/src/custodian.lua +6 -5
  295. package/src/custodian.ts +143 -39
  296. package/src/customize.ts +388 -55
  297. package/src/dispatch-effect.ts +945 -0
  298. package/src/door-compat.ts +217 -0
  299. package/src/durability.ts +11 -4
  300. package/src/effect-checks.ts +557 -0
  301. package/src/effect.ts +1202 -0
  302. package/src/effector-wire.ts +674 -0
  303. package/src/fail.ts +209 -0
  304. package/src/fingerprint.ts +4 -3
  305. package/src/gate.ts +8 -0
  306. package/src/git-clone.ts +65 -0
  307. package/src/git-push.ts +336 -0
  308. package/src/harness-client.ts +764 -48
  309. package/src/held-secrets.ts +82 -26
  310. package/src/holds.ts +156 -0
  311. package/src/http-effect.ts +1423 -0
  312. package/src/http.ts +916 -113
  313. package/src/images.ts +47 -21
  314. package/src/index.ts +62 -43
  315. package/src/instance.ts +505 -59
  316. package/src/internal.ts +84 -0
  317. package/src/kube-client.ts +333 -0
  318. package/src/machine-doc.ts +106 -6
  319. package/src/mechanism-routes.ts +168 -0
  320. package/src/model-keys.generated.ts +53 -0
  321. package/src/model-keys.ts +18 -58
  322. package/src/mount-digest.ts +53 -0
  323. package/src/names.ts +66 -8
  324. package/src/notices.ts +141 -0
  325. package/src/open-body.ts +1580 -0
  326. package/src/open-effect.ts +217 -0
  327. package/src/open.ts +59 -6
  328. package/src/parts.ts +709 -41
  329. package/src/party.ts +534 -0
  330. package/src/pick.ts +761 -0
  331. package/src/pool.ts +248 -37
  332. package/src/registration.ts +382 -19
  333. package/src/repo-fetch.ts +60 -85
  334. package/src/repos.ts +65 -75
  335. package/src/rest.ts +133 -0
  336. package/src/run-host.ts +2383 -115
  337. package/src/run-output.ts +38 -0
  338. package/src/sandbox-effect.ts +1126 -0
  339. package/src/sandbox-effector.ts +111 -0
  340. package/src/sandbox-kube.ts +1721 -0
  341. package/src/sandbox-watch.ts +260 -0
  342. package/src/secret-placement.ts +529 -0
  343. package/src/server.ts +284 -84
  344. package/src/setup.ts +819 -117
  345. package/src/size.ts +454 -0
  346. package/src/snapshot-store.ts +115 -20
  347. package/src/stub-harness.ts +49 -16
  348. package/src/sync-client.ts +54 -0
  349. package/src/timers.ts +191 -0
  350. package/src/tokens.ts +35 -4
  351. package/src/vocabulary.ts +135 -15
  352. package/src/wire.ts +238 -10
  353. package/src/workspace.ts +1195 -338
  354. package/src/sandbox-kubectl.ts +0 -1108
@@ -0,0 +1,217 @@
1
+ // An Effect's OPEN parts (ADR-0054, ADR-0067): a packaged Machine cannot know the host its http
2
+ // Effect calls, the program its command runs, or the secret its composer spends, so it leaves that
3
+ // part Open — the `open` sentinel in place of an `http` url (whatever its body) or of a command's
4
+ // argv, or `secret(open)` in place of a secret's name in its auth, a header or a command's env — and
5
+ // the composer binds it once, with `customize(machine, { effects: { <slot>: { url } | { argv } |
6
+ // { secret } } })`. An Effect may leave its url or its argv Open AND name an Open secret: one
7
+ // binding object takes both keys. Never per run: the binding is a value, not a mapper over the door,
8
+ // so the host stays fixed before any run starts and `jr2 up` reads the bound part as it reads one
9
+ // the author wrote — the placement, the secrets it names, the Effector's fence.
10
+ //
11
+ // An Open Effect is a slot whose logic is unbound: it carries the parts the walk reads (the
12
+ // kind, the placement, the secrets its other parts name, each Open part marked) and a binder, and
13
+ // it runs nothing. Binding calls the Effect's own constructor again with the definition and the
14
+ // bound parts, so a bound Effect is checked by every rule the constructor checks for an Effect
15
+ // written whole, and is the same logic; a binding that leaves one of two Open parts unbound gives an
16
+ // Effect still Open in that part. The compiler's check is the one it misses: an Open argv's input is
17
+ // one string per key, so a slot the invoke does not supply faults when the Effect starts. `jr2 up`
18
+ // refuses a registered Machine whose Open part nothing bound, naming the `customize` line; the
19
+ // unbound logic is the second fence, for every path that walk never saw — a run of it faults
20
+ // before anything is sent.
21
+ //
22
+ // This module holds only the sentinel's Effect half: the binder's key, the unbound logic, and the
23
+ // phantom type `customize()` reads. It imports no Effect kind, so every kind imports it.
24
+
25
+ import type { ActorLogic, AnyActorRef, EventObject } from "xstate";
26
+ import { open } from "./open.ts";
27
+ import type { Arg, EffectLogic, EffectParts, EffectSnapshot } from "./effect.ts";
28
+ import type { Secret, Text } from "./http-effect.ts";
29
+
30
+ /** The parts of an Effect a package may leave Open: an http url, a command's argv, a secret's name,
31
+ * a dispatch's target (its url and token together, ADR-0071). */
32
+ export type OpenEffectPart = "url" | "argv" | "secret" | "target";
33
+
34
+ // What a composer binds an Effect's Open parts to, each key one part (ADR-0054); a dispatch's
35
+ // target is its url and token, bound as one (ADR-0071). One object for an
36
+ // Effect with two Open parts. `customize()` reads each Effect's own binding type off its logic
37
+ // (`BindingOf`, customize.ts), so this loose shape is what the implementation walks.
38
+ /**
39
+ * The values that bind the Open parts of one Effect. A packaged Machine leaves a part of an Effect
40
+ * Open when it cannot know it. That part is the url of an `http` Effect, the argv of a `command`,
41
+ * the name of a secret, written `secret(open)`, or the target of a `dispatch`: the url of another
42
+ * Orchestrator and the secret that holds its Instance token, bound as one. You bind it once, where you register the
43
+ * Machine, with `customize(machine, { effects: { <slot>: binding } })`. Each key binds one Open
44
+ * part. For an Effect with two Open parts, one object holds both keys.
45
+ *
46
+ * The binding is a value, never a function of the run: no run chooses an Effect's url, argv or
47
+ * secret. `customize()` builds the Effect again with the bound parts, so a bound part gets every
48
+ * check that a part written in the definition gets.
49
+ *
50
+ * `customize()` refuses:
51
+ * - an empty binding, or a key for a part that is not Open: `customize(): the <kind> Effect
52
+ * "<slot>" leaves its <parts> Open — bind it with <binding> (ADR-0054)`
53
+ * - an Effect with no Open part: ``customize(): the <kind> Effect "<slot>" of machine "<id>"
54
+ * leaves nothing Open — its parts are fixed in its definition, and only a part a package left
55
+ * `open` is bound, once (ADR-0054).``
56
+ * - `open` as a value: ``customize(): the <kind> Effect "<slot>"'s <part> is bound once, to a
57
+ * value — not `open` again: no run chooses an Effect's <part> (ADR-0054)``. A function as a
58
+ * value gives the same text, with `a function of the run` for `` `open` again ``.
59
+ * - a secret that is not a string: `customize(): the <kind> Effect "<slot>"'s secret is bound to
60
+ * a secret's name, a string — the file the Effector reads it from: { secret: "<name>" }
61
+ * (ADR-0054, ADR-0068)`
62
+ *
63
+ * `jr2 up` refuses a registered Machine with an Open part that nobody bound, and prints the
64
+ * `customize` line that binds it.
65
+ *
66
+ * @example
67
+ * ```ts
68
+ * import { customize, http, jr2Setup, open, type EffectBinding } from "@jr2/orchestrator";
69
+ *
70
+ * const notifier = jr2Setup({
71
+ * actors: { notify: http({ method: "POST", url: open }) },
72
+ * }).createMachine({
73
+ * id: "notifier",
74
+ * initial: "sending",
75
+ * states: {
76
+ * sending: { invoke: { src: "notify", onDone: "done" } },
77
+ * done: { type: "final" },
78
+ * },
79
+ * });
80
+ *
81
+ * const notify = { url: "https://hooks.example.com/build" } satisfies EffectBinding;
82
+ *
83
+ * export const machine = customize(notifier, { effects: { notify } });
84
+ * ```
85
+ *
86
+ * @see docs/guides/bind-open-parts.md
87
+ * @see docs/concepts/effects.md
88
+ * @see docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md
89
+ * @see docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md
90
+ */
91
+ export type EffectBinding = {
92
+ /** The url of an `http` Effect whose url is Open: a string, or a `text` template with a secret
93
+ * in its path, such as `` text`https://hooks.example.com/services/${secret("hook")}` ``. Its
94
+ * scheme and host must be literal. */
95
+ readonly url?: string | Text;
96
+ /** The argv of a `command` whose argv is Open: one entry for each argument, never shell text.
97
+ * An entry is a string or an `arg("<param>")` that the invoke's input fills. It must not be
98
+ * empty. */
99
+ readonly argv?: readonly (string | Arg)[];
100
+ /** The name of the secret that `secret(open)` stands for: an entry of `secrets` in
101
+ * `jr2.config.ts`. The Effector reads it from a file of that name. */
102
+ readonly secret?: string;
103
+ readonly target?: { readonly url: string; readonly token: Secret };
104
+ };
105
+
106
+ declare const openPart: unique symbol;
107
+
108
+ /**
109
+ * The TYPE half of an Open Effect: its logic type says which parts are Open, so `customize()`'s
110
+ * `effects` offers exactly the Open slots, each with the binding its parts take — the intersection
111
+ * of each part's, for an Effect with two. Phantom, like `JR2Wrapper`: the property exists in the
112
+ * type alone.
113
+ *
114
+ * @internal
115
+ */
116
+ export type OpenEffect<P extends OpenEffectPart> = { readonly [openPart]: P };
117
+
118
+ /**
119
+ * The phantom for these Open parts, or nothing for none: what a constructor's type adds.
120
+ *
121
+ * @internal
122
+ */
123
+ export type OpenOf<P extends OpenEffectPart> = [P] extends [never] ? unknown : OpenEffect<P>;
124
+
125
+ /** The binder an Open Effect carries, under a `Symbol.for` key so a second copy of this module (an
126
+ * Instance's own `@jr2/orchestrator` beside the CLI's) reads it. Not enumerable. */
127
+ const BIND: unique symbol = Symbol.for("jr2.effect.bind");
128
+
129
+ type Binder = (binding: EffectBinding) => EffectLogic<unknown, unknown>;
130
+
131
+ /** Which parts of these parts are Open, in binding order: the url, the argv or the target, then the
132
+ * secret. A dispatch's target is one part: its token is never `secret(open)` (ADR-0071). */
133
+ export function openPartsOf(parts: EffectParts): OpenEffectPart[] {
134
+ const out: OpenEffectPart[] = [];
135
+ if (parts.kind === "http" && parts.url === open) out.push("url");
136
+ if (parts.kind === "command" && parts.argv === open) out.push("argv");
137
+ if (parts.kind === "dispatch" && parts.target === open) out.push("target");
138
+ if (parts.kind !== "push" && parts.openSecret) out.push("secret");
139
+ return out;
140
+ }
141
+
142
+ /** The binder of an Open Effect's logic; undefined for an Effect whose parts are all fixed. */
143
+ export function binderOf(logic: unknown): Binder | undefined {
144
+ const bind = (logic as { [BIND]?: unknown } | null | undefined)?.[BIND];
145
+ return typeof bind === "function" ? (bind as Binder) : undefined;
146
+ }
147
+
148
+ /** What the fix line writes for each Open part: a sample of the value its binding takes. */
149
+ const BINDING_SAMPLE: Record<OpenEffectPart, string> = {
150
+ url: 'url: "https://<host>/<path>"',
151
+ argv: 'argv: ["<program>", "<arg>"]',
152
+ secret: 'secret: "<name>"',
153
+ target: 'target: { url: "https://<host>", token: secret("<name>") }',
154
+ };
155
+
156
+ /** One binding object for these Open parts — `{ url: "…", secret: "<name>" }` for two. */
157
+ export function effectBindingShape(parts: OpenEffectPart | readonly OpenEffectPart[]): string {
158
+ const list = typeof parts === "string" ? [parts] : parts;
159
+ return `{ ${list.map((p) => BINDING_SAMPLE[p]).join(", ")} }`;
160
+ }
161
+
162
+ /** The fix line for an Effect's Open parts, as `customize()` takes it under `effects`. */
163
+ export function effectBindingLine(slot: string, parts: OpenEffectPart | readonly OpenEffectPart[]): string {
164
+ return `{ effects: { ${slot}: ${effectBindingShape(parts)} } }`;
165
+ }
166
+
167
+ /** The Open parts in words: "url", "url and secret". */
168
+ export function openPartsText(parts: OpenEffectPart | readonly OpenEffectPart[]): string {
169
+ return (typeof parts === "string" ? [parts] : parts).join(" and ");
170
+ }
171
+
172
+ type Fault = { type: "jr2.effect.error"; error: unknown };
173
+
174
+ /**
175
+ * The unbound logic of an Effect with Open parts: the parts the walk reads, the binder
176
+ * `customize()` calls, and a start that faults (a config defect, ADR-0067) naming the line that
177
+ * binds them. It sends nothing and writes no ledger row.
178
+ */
179
+ export function openEffectLogic<I, O, P extends OpenEffectPart>(
180
+ parts: EffectParts,
181
+ open: readonly P[],
182
+ bind: Binder,
183
+ ): EffectLogic<I, O> & OpenEffect<P> {
184
+ const logic: ActorLogic<EffectSnapshot<O, I>, EventObject, I> = {
185
+ getInitialSnapshot: (_scope, input) => ({
186
+ status: "active",
187
+ output: undefined,
188
+ error: undefined,
189
+ input,
190
+ effectId: "",
191
+ }),
192
+ transition: (snapshot, event) => {
193
+ if (snapshot.status !== "active") return snapshot;
194
+ if (event.type === "jr2.effect.error") {
195
+ return { ...snapshot, status: "error", error: (event as Fault).error, input: undefined };
196
+ }
197
+ if (event.type === "xstate.stop") return { ...snapshot, status: "stopped", input: undefined };
198
+ return snapshot;
199
+ },
200
+ start: (snapshot, { self }) => {
201
+ if (snapshot.status !== "active") return;
202
+ const slot = slotOf(self);
203
+ const error = new Error(
204
+ `${parts.kind} "${slot}" leaves its ${openPartsText(open)} Open — nobody bound it; bind it where the ` +
205
+ `Machine is registered (\`customize(<machine>, ${effectBindingLine(slot, open)})\`), because a packaged ` +
206
+ "Machine cannot know it; nothing was sent (ADR-0054)",
207
+ );
208
+ const fault: Fault = { type: "jr2.effect.error", error };
209
+ self.send(fault);
210
+ },
211
+ getPersistedSnapshot: (snapshot) => snapshot,
212
+ };
213
+ Object.defineProperty(logic, BIND, { value: bind, enumerable: false });
214
+ return Object.assign(logic, { effect: parts }) as unknown as EffectLogic<I, O> & OpenEffect<P>;
215
+ }
216
+
217
+ const slotOf = (self: AnyActorRef): string => (typeof self.src === "string" ? self.src : self.id);
package/src/open.ts CHANGED
@@ -5,13 +5,66 @@
5
5
  // and a `workspace()`'s Repo Slots (parts.ts, which already imports agent.ts). A module with
6
6
  // nothing but the sentinel in it is what lets both import it and neither import the other.
7
7
 
8
+ // `Symbol.for`, so an Instance's own copy of this module and the CLI's walk agree on it — a
9
+ // packaged Machine may be built against one and walked by the other.
8
10
  /**
9
- * Open (CONTEXT.md): this part is a composer's to bind, with `customize()` — a Repo Slot with no
10
- * url, an Agent with no model. The shape a packaged Machine ships in, because a package cannot
11
- * know the repository or pay for the model. `jr2 up` refuses an Open part nobody bound and names
12
- * the line that binds it; a run never sees one.
11
+ * Leave a part of a Machine Open: for the Instance that registers the Machine to bind with
12
+ * `customize()`. Write it where a value goes, in a Machine that you publish as a package, for a
13
+ * part that the package cannot know or pay for:
14
+ * - a Repo Slot: `repos: { app: open }`, or the whole map: `repos: open`;
15
+ * - an Agent's model: `agent({ model: open, … })`;
16
+ * - an Effect's url or argv: `http({ url: open, … })`, `command(open)`;
17
+ * - the secret of an Effect's auth, of a header, or of a command's `env`: `secret(open)`.
13
18
  *
14
- * `Symbol.for`, so an Instance's own copy of this module and the CLI's walk agree on it — a
15
- * packaged Machine may be built against one and walked by the other.
19
+ * `jr2 up` refuses a Workflow with an Open part that nobody bound, and prints the `customize()`
20
+ * line that binds it: ``refusing: workflow "<name>" leaves <part> open — bind it where the Machine
21
+ * is registered: export const machine = customize(<import>, …) (<adr>)``. A run never sees an
22
+ * Open part.
23
+ *
24
+ * @example
25
+ * ```ts
26
+ * import { z } from "zod";
27
+ * import { agent, customize, defineEvent, fail, jr2Setup, open, workspace } from "@jr2/orchestrator";
28
+ *
29
+ * const finish = defineEvent({
30
+ * name: "finish",
31
+ * description: "Call this when `node --test` passes.",
32
+ * input: z.object({}),
33
+ * });
34
+ *
35
+ * const body = jr2Setup({
36
+ * events: [finish],
37
+ * actors: { coder: agent({ model: open, instructions: "You fix the failing test." }), fail: fail() },
38
+ * }).createMachine({
39
+ * id: "fix",
40
+ * on: { "workspace.lost": ".lost", "agent.fault": ".failed" },
41
+ * initial: "coding",
42
+ * states: {
43
+ * coding: {
44
+ * invoke: { src: "coder", input: { prompt: "Make `node --test` pass." } },
45
+ * on: { finish: "done" },
46
+ * },
47
+ * done: { type: "final" },
48
+ * failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
49
+ * lost: { invoke: { src: "fail", input: { reason: "the Sandbox is gone" } } },
50
+ * },
51
+ * });
52
+ *
53
+ * // What a package exports: the repository and the model are Open.
54
+ * export const fix = workspace(body, {
55
+ * repos: { app: open },
56
+ * spec: () => ({ branch: "jr2/fix" }),
57
+ * });
58
+ *
59
+ * // What an Instance's `workflows/fix.ts` exports: the same Machine, its Open parts bound.
60
+ * export const machine = customize(fix, {
61
+ * repos: { app: { url: "https://github.com/you/app.git" } },
62
+ * agents: { coder: { model: "anthropic/claude-haiku-5-5" } },
63
+ * });
64
+ * ```
65
+ *
66
+ * @see docs/guides/bind-open-parts.md
67
+ * @see docs/concepts/composition.md
68
+ * @see docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md
16
69
  */
17
70
  export const open: unique symbol = Symbol.for("jr2.open");