@jr2/orchestrator 0.4.1 → 0.6.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 (361) hide show
  1. package/README.md +20 -2
  2. package/console/components/app.ts +2 -0
  3. package/console/components/fleet.ts +14 -1
  4. package/console/components/machine-pane.ts +41 -2
  5. package/console/main.ts +13 -1
  6. package/console/store.ts +102 -6
  7. package/console/style.css +21 -0
  8. package/docs/agents-block.md +5 -0
  9. package/docs/concepts/agents-and-turns.md +478 -0
  10. package/docs/concepts/architecture.md +243 -0
  11. package/docs/concepts/charts.md +146 -0
  12. package/docs/concepts/composition.md +357 -0
  13. package/docs/concepts/converge.md +257 -0
  14. package/docs/concepts/durable-runs.md +189 -0
  15. package/docs/concepts/effects.md +658 -0
  16. package/docs/concepts/gates.md +208 -0
  17. package/docs/concepts/machines-and-workflows.md +298 -0
  18. package/docs/concepts/pools-and-sources.md +230 -0
  19. package/docs/concepts/secrets-and-trust.md +306 -0
  20. package/docs/concepts/the-menu.md +381 -0
  21. package/docs/concepts/workspaces.md +756 -0
  22. package/docs/get-started/a-model-decides.md +563 -0
  23. package/docs/get-started/an-agent-in-a-sandbox.md +383 -0
  24. package/docs/get-started/connect-a-model.md +248 -0
  25. package/docs/get-started/create-an-instance.md +194 -0
  26. package/docs/get-started/have-your-assistant-write-a-machine.md +993 -0
  27. package/docs/get-started/install.md +130 -0
  28. package/docs/guides/add-tools-to-the-sandbox.md +308 -0
  29. package/docs/guides/answer-a-gate.md +304 -0
  30. package/docs/guides/bind-open-parts.md +224 -0
  31. package/docs/guides/cancel-a-run.md +146 -0
  32. package/docs/guides/clean-up.md +206 -0
  33. package/docs/guides/cut-a-worktree.md +560 -0
  34. package/docs/guides/fix-a-failed-converge.md +361 -0
  35. package/docs/guides/give-the-cluster-git-credentials.md +222 -0
  36. package/docs/guides/iterate-on-a-machine-on-kind.md +190 -0
  37. package/docs/guides/let-an-agent-write-a-chart.md +230 -0
  38. package/docs/guides/look-inside-a-sandbox.md +177 -0
  39. package/docs/guides/mirror-the-kit-images.md +176 -0
  40. package/docs/guides/move-from-kind-to-a-shared-cluster.md +318 -0
  41. package/docs/guides/open-the-console.md +91 -0
  42. package/docs/guides/publish-a-machine-as-an-npm-package.md +350 -0
  43. package/docs/guides/push-and-sign-a-branch.md +532 -0
  44. package/docs/guides/run-a-chart-by-name.md +270 -0
  45. package/docs/guides/run-a-command-or-call-a-url.md +587 -0
  46. package/docs/guides/run-one-worker-per-item.md +322 -0
  47. package/docs/guides/set-an-agents-access-and-dials.md +420 -0
  48. package/docs/guides/size-a-workspace.md +217 -0
  49. package/docs/guides/start-a-run-from-a-run.md +237 -0
  50. package/docs/guides/start-a-run.md +207 -0
  51. package/docs/guides/upgrade-the-kit-version.md +240 -0
  52. package/docs/guides/use-a-hosted-provider.md +214 -0
  53. package/docs/guides/use-a-local-model.md +313 -0
  54. package/docs/guides/watch-a-run.md +349 -0
  55. package/docs/guides/write-a-workflow.md +318 -0
  56. package/docs/index.md +44 -0
  57. package/docs/llms.txt +237 -0
  58. package/docs/reference/authoring-surface/agent.md +151 -0
  59. package/docs/reference/authoring-surface/answer.md +156 -0
  60. package/docs/reference/authoring-surface/arg.md +82 -0
  61. package/docs/reference/authoring-surface/basic.md +62 -0
  62. package/docs/reference/authoring-surface/bearer.md +53 -0
  63. package/docs/reference/authoring-surface/branchname.md +15 -0
  64. package/docs/reference/authoring-surface/chartschema.md +23 -0
  65. package/docs/reference/authoring-surface/chartschemafor.md +48 -0
  66. package/docs/reference/authoring-surface/command.md +206 -0
  67. package/docs/reference/authoring-surface/customize.md +64 -0
  68. package/docs/reference/authoring-surface/defineconfig.md +41 -0
  69. package/docs/reference/authoring-surface/defineevent.md +114 -0
  70. package/docs/reference/authoring-surface/dispatch.md +126 -0
  71. package/docs/reference/authoring-surface/fail.md +96 -0
  72. package/docs/reference/authoring-surface/file.md +142 -0
  73. package/docs/reference/authoring-surface/frompick.md +277 -0
  74. package/docs/reference/authoring-surface/http.md +259 -0
  75. package/docs/reference/authoring-surface/isfailure.md +58 -0
  76. package/docs/reference/authoring-surface/isready.md +14 -0
  77. package/docs/reference/authoring-surface/jr2setup.md +237 -0
  78. package/docs/reference/authoring-surface/open.md +105 -0
  79. package/docs/reference/authoring-surface/openbody.md +86 -0
  80. package/docs/reference/authoring-surface/paramsof.md +143 -0
  81. package/docs/reference/authoring-surface/pool.md +186 -0
  82. package/docs/reference/authoring-surface/push.md +130 -0
  83. package/docs/reference/authoring-surface/readyof.md +21 -0
  84. package/docs/reference/authoring-surface/secret.md +139 -0
  85. package/docs/reference/authoring-surface/sentby.md +83 -0
  86. package/docs/reference/authoring-surface/source.md +51 -0
  87. package/docs/reference/authoring-surface/text.md +62 -0
  88. package/docs/reference/authoring-surface/type-agentdeclaration.md +27 -0
  89. package/docs/reference/authoring-surface/type-agentdefinition.md +80 -0
  90. package/docs/reference/authoring-surface/type-agentlogic.md +15 -0
  91. package/docs/reference/authoring-surface/type-agentslots.md +15 -0
  92. package/docs/reference/authoring-surface/type-answeraction.md +12 -0
  93. package/docs/reference/authoring-surface/type-anyframepath.md +14 -0
  94. package/docs/reference/authoring-surface/type-anyworktreepath.md +15 -0
  95. package/docs/reference/authoring-surface/type-arg.md +19 -0
  96. package/docs/reference/authoring-surface/type-argnames.md +12 -0
  97. package/docs/reference/authoring-surface/type-bindactors.md +14 -0
  98. package/docs/reference/authoring-surface/type-binding.md +61 -0
  99. package/docs/reference/authoring-surface/type-bindingof.md +12 -0
  100. package/docs/reference/authoring-surface/type-bodyacceptsdoor.md +15 -0
  101. package/docs/reference/authoring-surface/type-bodyacceptsslots.md +17 -0
  102. package/docs/reference/authoring-surface/type-ceilings.md +41 -0
  103. package/docs/reference/authoring-surface/type-chainlink.md +19 -0
  104. package/docs/reference/authoring-surface/type-chartaction.md +46 -0
  105. package/docs/reference/authoring-surface/type-chartagent.md +28 -0
  106. package/docs/reference/authoring-surface/type-chartevent.md +20 -0
  107. package/docs/reference/authoring-surface/type-chartguard.md +20 -0
  108. package/docs/reference/authoring-surface/type-chartinvoke.md +28 -0
  109. package/docs/reference/authoring-surface/type-chartjson.md +14 -0
  110. package/docs/reference/authoring-surface/type-chartstate.md +46 -0
  111. package/docs/reference/authoring-surface/type-charttext.md +40 -0
  112. package/docs/reference/authoring-surface/type-charttransition.md +22 -0
  113. package/docs/reference/authoring-surface/type-charttransitions.md +14 -0
  114. package/docs/reference/authoring-surface/type-chartvalue.md +15 -0
  115. package/docs/reference/authoring-surface/type-childat.md +12 -0
  116. package/docs/reference/authoring-surface/type-childslots.md +12 -0
  117. package/docs/reference/authoring-surface/type-commandenv.md +15 -0
  118. package/docs/reference/authoring-surface/type-commandinput.md +20 -0
  119. package/docs/reference/authoring-surface/type-commandoptions.md +56 -0
  120. package/docs/reference/authoring-surface/type-commandoutput.md +122 -0
  121. package/docs/reference/authoring-surface/type-customize.md +111 -0
  122. package/docs/reference/authoring-surface/type-dispatchdefinition.md +39 -0
  123. package/docs/reference/authoring-surface/type-dispatchinput.md +14 -0
  124. package/docs/reference/authoring-surface/type-dispatchopenparts.md +14 -0
  125. package/docs/reference/authoring-surface/type-dispatchoutput.md +72 -0
  126. package/docs/reference/authoring-surface/type-doorlessinput.md +19 -0
  127. package/docs/reference/authoring-surface/type-duration.md +15 -0
  128. package/docs/reference/authoring-surface/type-effectbinding.md +93 -0
  129. package/docs/reference/authoring-surface/type-effectlogic.md +12 -0
  130. package/docs/reference/authoring-surface/type-envopenparts.md +14 -0
  131. package/docs/reference/authoring-surface/type-eventaudience.md +27 -0
  132. package/docs/reference/authoring-surface/type-eventdef.md +45 -0
  133. package/docs/reference/authoring-surface/type-eventfrom.md +16 -0
  134. package/docs/reference/authoring-surface/type-eventsemantics.md +26 -0
  135. package/docs/reference/authoring-surface/type-execoutcome.md +34 -0
  136. package/docs/reference/authoring-surface/type-failslot.md +14 -0
  137. package/docs/reference/authoring-surface/type-failure.md +19 -0
  138. package/docs/reference/authoring-surface/type-failureinput.md +20 -0
  139. package/docs/reference/authoring-surface/type-filebody.md +37 -0
  140. package/docs/reference/authoring-surface/type-framepath.md +14 -0
  141. package/docs/reference/authoring-surface/type-frominput.md +14 -0
  142. package/docs/reference/authoring-surface/type-hostinjectedinput.md +56 -0
  143. package/docs/reference/authoring-surface/type-httpdefinition.md +104 -0
  144. package/docs/reference/authoring-surface/type-httpfileinput.md +20 -0
  145. package/docs/reference/authoring-surface/type-httpinput.md +12 -0
  146. package/docs/reference/authoring-surface/type-httpmethod.md +14 -0
  147. package/docs/reference/authoring-surface/type-httpopenparts.md +12 -0
  148. package/docs/reference/authoring-surface/type-httpoutput.md +95 -0
  149. package/docs/reference/authoring-surface/type-httprequestparts.md +33 -0
  150. package/docs/reference/authoring-surface/type-jr2config.md +126 -0
  151. package/docs/reference/authoring-surface/type-lateroutcome.md +21 -0
  152. package/docs/reference/authoring-surface/type-lends.md +38 -0
  153. package/docs/reference/authoring-surface/type-logicat.md +12 -0
  154. package/docs/reference/authoring-surface/type-markedif.md +12 -0
  155. package/docs/reference/authoring-surface/type-mergedactors.md +12 -0
  156. package/docs/reference/authoring-surface/type-namedsecret.md +25 -0
  157. package/docs/reference/authoring-surface/type-namestart.md +77 -0
  158. package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +27 -0
  159. package/docs/reference/authoring-surface/type-notworktreekeys.md +12 -0
  160. package/docs/reference/authoring-surface/type-openbodydeclaration.md +40 -0
  161. package/docs/reference/authoring-surface/type-openbodylogic.md +14 -0
  162. package/docs/reference/authoring-surface/type-openbodyoutput.md +42 -0
  163. package/docs/reference/authoring-surface/type-openbodyslot.md +18 -0
  164. package/docs/reference/authoring-surface/type-opencommandinput.md +22 -0
  165. package/docs/reference/authoring-surface/type-openeffect.md +12 -0
  166. package/docs/reference/authoring-surface/type-openeffectslots.md +12 -0
  167. package/docs/reference/authoring-surface/type-openof.md +12 -0
  168. package/docs/reference/authoring-surface/type-opensecret.md +23 -0
  169. package/docs/reference/authoring-surface/type-opensecretmark.md +12 -0
  170. package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +26 -0
  171. package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +27 -0
  172. package/docs/reference/authoring-surface/type-poolmachine.md +28 -0
  173. package/docs/reference/authoring-surface/type-poolnextinput.md +22 -0
  174. package/docs/reference/authoring-surface/type-poolspec.md +60 -0
  175. package/docs/reference/authoring-surface/type-pushinput.md +34 -0
  176. package/docs/reference/authoring-surface/type-pushoptions.md +79 -0
  177. package/docs/reference/authoring-surface/type-pushoutput.md +149 -0
  178. package/docs/reference/authoring-surface/type-pushwireoutput.md +12 -0
  179. package/docs/reference/authoring-surface/type-quantity.md +14 -0
  180. package/docs/reference/authoring-surface/type-reached.md +12 -0
  181. package/docs/reference/authoring-surface/type-reposlot.md +70 -0
  182. package/docs/reference/authoring-surface/type-reposlotsof.md +16 -0
  183. package/docs/reference/authoring-surface/type-sandboxoptions.md +84 -0
  184. package/docs/reference/authoring-surface/type-secret.md +25 -0
  185. package/docs/reference/authoring-surface/type-sender.md +19 -0
  186. package/docs/reference/authoring-surface/type-sentbyguards.md +12 -0
  187. package/docs/reference/authoring-surface/type-size.md +85 -0
  188. package/docs/reference/authoring-surface/type-slothandles.md +24 -0
  189. package/docs/reference/authoring-surface/type-sourcenextresult.md +17 -0
  190. package/docs/reference/authoring-surface/type-sourcespec.md +44 -0
  191. package/docs/reference/authoring-surface/type-syncstate.md +12 -0
  192. package/docs/reference/authoring-surface/type-text.md +19 -0
  193. package/docs/reference/authoring-surface/type-textpart.md +24 -0
  194. package/docs/reference/authoring-surface/type-thinkinglevel.md +39 -0
  195. package/docs/reference/authoring-surface/type-toparameterizedobject.md +14 -0
  196. package/docs/reference/authoring-surface/type-toprovidedactor.md +14 -0
  197. package/docs/reference/authoring-surface/type-unknown.md +21 -0
  198. package/docs/reference/authoring-surface/type-usercontainer.md +77 -0
  199. package/docs/reference/authoring-surface/type-withoutemptyindex.md +20 -0
  200. package/docs/reference/authoring-surface/type-workflowevent.md +46 -0
  201. package/docs/reference/authoring-surface/type-workspaceaccess.md +16 -0
  202. package/docs/reference/authoring-surface/type-workspaced.md +115 -0
  203. package/docs/reference/authoring-surface/type-workspacehandles.md +22 -0
  204. package/docs/reference/authoring-surface/type-workspacemachine.md +29 -0
  205. package/docs/reference/authoring-surface/type-workspaceof.md +13 -0
  206. package/docs/reference/authoring-surface/type-workspaceoptions.md +27 -0
  207. package/docs/reference/authoring-surface/type-worktreefound.md +16 -0
  208. package/docs/reference/authoring-surface/type-worktreeinput.md +56 -0
  209. package/docs/reference/authoring-surface/type-worktreekey.md +14 -0
  210. package/docs/reference/authoring-surface/type-worktreeoptions.md +29 -0
  211. package/docs/reference/authoring-surface/type-worktreeoutput.md +45 -0
  212. package/docs/reference/authoring-surface/type-worktreepath.md +16 -0
  213. package/docs/reference/authoring-surface/type-worktreeready.md +37 -0
  214. package/docs/reference/authoring-surface/type-worktreerefused.md +21 -0
  215. package/docs/reference/authoring-surface/workspace.md +287 -0
  216. package/docs/reference/authoring-surface/worktree.md +71 -0
  217. package/docs/reference/authoring-surface.md +217 -0
  218. package/docs/reference/cli.md +433 -0
  219. package/docs/reference/config.md +765 -0
  220. package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +114 -0
  221. package/docs/reference/decisions/0002-duplex-streaming-actor.md +117 -0
  222. package/docs/reference/decisions/0004-worktree-provisioning-model.md +130 -0
  223. package/docs/reference/decisions/0005-sandbox-pod-composition.md +240 -0
  224. package/docs/reference/decisions/0006-agent-control-surface.md +50 -0
  225. package/docs/reference/decisions/0007-durable-machine-state.md +109 -0
  226. package/docs/reference/decisions/0008-orchestrator-as-deployed-app.md +60 -0
  227. package/docs/reference/decisions/0009-cli-and-instance-interface.md +275 -0
  228. package/docs/reference/decisions/0010-bdd-acceptance-tests.md +160 -0
  229. package/docs/reference/decisions/0011-workflow-defined-events.md +141 -0
  230. package/docs/reference/decisions/0012-workspace-wrapper-machine.md +103 -0
  231. package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +175 -0
  232. package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +95 -0
  233. package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +271 -0
  234. package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +126 -0
  235. package/docs/reference/decisions/0017-pool-over-a-source-port.md +71 -0
  236. package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +111 -0
  237. package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +287 -0
  238. package/docs/reference/decisions/0020-private-ca-trust-is-a-named-concept.md +60 -0
  239. package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +101 -0
  240. package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +103 -0
  241. package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +175 -0
  242. package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +436 -0
  243. package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +65 -0
  244. package/docs/reference/decisions/0026-a-turn-that-is-over-is-never-prompted.md +62 -0
  245. package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +245 -0
  246. package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +90 -0
  247. package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +154 -0
  248. package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +100 -0
  249. package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +193 -0
  250. package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +61 -0
  251. package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +126 -0
  252. package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +57 -0
  253. package/docs/reference/decisions/0035-a-runaway-turn-is-ended-rerolled-once-then-a-fault.md +92 -0
  254. package/docs/reference/decisions/0036-a-turn-compacts-its-own-context-mid-flight.md +138 -0
  255. package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +196 -0
  256. package/docs/reference/decisions/0038-jr2-up-builds-every-image-it-deploys.md +170 -0
  257. package/docs/reference/decisions/0039-image-garbage-collects-by-reachability.md +115 -0
  258. package/docs/reference/decisions/0041-a-build-the-host-already-holds-is-not-spent-again.md +64 -0
  259. package/docs/reference/decisions/0042-ready-is-not-routable-an-admission-retries-its-connection.md +142 -0
  260. package/docs/reference/decisions/0043-the-kit-is-tested-as-installed-a-local-registry-stands-in-for-npm.md +170 -0
  261. package/docs/reference/decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md +85 -0
  262. package/docs/reference/decisions/0045-the-platform-joins-the-image-address-and-the-cluster-chooses-it.md +82 -0
  263. package/docs/reference/decisions/0046-a-converge-failure-carries-its-diagnosis.md +34 -0
  264. package/docs/reference/decisions/0047-the-git-ssh-key-source-is-the-users-choice.md +47 -0
  265. package/docs/reference/decisions/0048-the-orchestrator-boots-without-its-repos.md +36 -0
  266. package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +126 -0
  267. package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +73 -0
  268. package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +238 -0
  269. package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +86 -0
  270. package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +123 -0
  271. package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +126 -0
  272. package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +107 -0
  273. package/docs/reference/decisions/0056-a-global-jr2-hands-off-to-the-instances-own-and-an-instance-has-one-kit-version.md +62 -0
  274. package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +152 -0
  275. package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +108 -0
  276. package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +427 -0
  277. package/docs/reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md +111 -0
  278. package/docs/reference/decisions/0061-a-memory-kill-ends-the-agents-processes-not-the-harness.md +83 -0
  279. package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +239 -0
  280. package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +82 -0
  281. package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +79 -0
  282. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +65 -0
  283. package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +552 -0
  284. package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +458 -0
  285. package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +475 -0
  286. package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +180 -0
  287. package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +334 -0
  288. package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +183 -0
  289. package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +144 -0
  290. package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +122 -0
  291. package/docs/reference/decisions/0074-an-unrouted-mechanism-event-is-refused-at-load-and-faults-the-run.md +76 -0
  292. package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +295 -0
  293. package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +320 -0
  294. package/docs/reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md +79 -0
  295. package/docs/reference/decisions.md +86 -0
  296. package/docs/reference/glossary.md +687 -0
  297. package/docs/reference/http-api.md +1386 -0
  298. package/docs/reference/machines.md +189 -0
  299. package/docs/reference/mechanism-events.md +72 -0
  300. package/docs/why.md +207 -0
  301. package/package.json +5 -3
  302. package/src/actor.ts +694 -106
  303. package/src/agent.ts +114 -38
  304. package/src/ambient.ts +3 -4
  305. package/src/assembly-checks.ts +189 -7
  306. package/src/cause.ts +234 -0
  307. package/src/chart.ts +345 -46
  308. package/src/charts.ts +43 -8
  309. package/src/config.ts +440 -178
  310. package/src/custodian.lua +17 -5
  311. package/src/custodian.ts +325 -99
  312. package/src/customize.ts +199 -49
  313. package/src/dispatch-effect.ts +945 -0
  314. package/src/door-compat.ts +217 -0
  315. package/src/durability.ts +11 -4
  316. package/src/effect-checks.ts +50 -3
  317. package/src/effect.ts +641 -128
  318. package/src/effector-wire.ts +165 -13
  319. package/src/fail.ts +222 -0
  320. package/src/harness-client.ts +587 -50
  321. package/src/harness-env.ts +33 -0
  322. package/src/held-secrets.ts +125 -16
  323. package/src/holds.ts +3 -0
  324. package/src/http-effect.ts +556 -58
  325. package/src/http.ts +480 -30
  326. package/src/index.ts +74 -82
  327. package/src/instance.ts +68 -8
  328. package/src/internal.ts +85 -0
  329. package/src/kube-client.ts +6 -3
  330. package/src/machine-doc.ts +24 -7
  331. package/src/mechanism-routes.ts +168 -0
  332. package/src/model-keys.generated.ts +53 -0
  333. package/src/model-keys.ts +42 -58
  334. package/src/names.ts +19 -6
  335. package/src/notices.ts +483 -41
  336. package/src/open-body.ts +242 -40
  337. package/src/open-effect.ts +81 -8
  338. package/src/open.ts +90 -6
  339. package/src/parts.ts +213 -30
  340. package/src/party.ts +101 -2
  341. package/src/pick.ts +497 -11
  342. package/src/pool.ts +282 -50
  343. package/src/registration.ts +133 -12
  344. package/src/repo-identity.ts +7 -3
  345. package/src/repos.ts +22 -3
  346. package/src/run-host.ts +665 -45
  347. package/src/run-output.ts +38 -0
  348. package/src/sandbox-effect.ts +457 -71
  349. package/src/sandbox-kube.ts +66 -17
  350. package/src/secret-placement.ts +59 -17
  351. package/src/server.ts +3 -0
  352. package/src/setup.ts +325 -62
  353. package/src/size.ts +121 -9
  354. package/src/snapshot-store.ts +54 -10
  355. package/src/stub-harness.ts +44 -16
  356. package/src/timers.ts +14 -1
  357. package/src/tokens.ts +107 -32
  358. package/src/vocabulary.ts +88 -14
  359. package/src/wire.ts +100 -26
  360. package/src/workspace.ts +771 -238
  361. package/src/worktree.ts +249 -0
@@ -30,7 +30,7 @@ import { SENDER_KEY, type EventDef, type Sender } from "@jr2/agent-protocol";
30
30
  import type { AgentAdmission } from "./actor.ts";
31
31
  import type { EffectMarker, EffectRow } from "./effect.ts";
32
32
  import type { EffectorPlacement, EffectorTarget } from "./http-effect.ts";
33
- import type { NoticeScope, TakenNotices } from "./notices.ts";
33
+ import type { NoticeScope, RaiseOptions, TakenNotices } from "./notices.ts";
34
34
  import type { AnswerSeat } from "./pick.ts";
35
35
  import type { Notice, PickAnswer } from "./wire.ts";
36
36
  import type { SandboxPort } from "./workspace.ts";
@@ -38,6 +38,7 @@ import { invokingMachine, vocabularyOf } from "./vocabulary.ts";
38
38
  import type { ChartText } from "./chart.ts";
39
39
  import { notTaken, senderText, takesNow, type NotTakenWriting } from "./party.ts";
40
40
  import { restOf } from "./rest.ts";
41
+ import type { RunStatus } from "./run-host.ts";
41
42
 
42
43
  /** xstate doesn't export its internal AnyActorSystem; this matches what actors receive. */
43
44
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -81,6 +82,20 @@ export type Registration = {
81
82
  * Harness runs on the host, in no Sandbox at all): those are the Instance token's business.
82
83
  */
83
84
  sandbox?: string;
85
+ /**
86
+ * An Agent's: its SLOT (ADR-0076) — the actor path of its Machine and its agent name, which is its
87
+ * continued conversation's Instance ID without the run id ({@link continuedIid}). The Harness
88
+ * states it on every control request, from its own record of the conversation, and the
89
+ * Orchestrator speaks here only for that slot. Two Agents with one key in two child Machines are
90
+ * two slots. Absent on gates.
91
+ */
92
+ slot?: string;
93
+ /** An Agent's: the step boundary's read of its conversation's pending notices (ADR-0062), each
94
+ * reserved for this Turn until {@link noticesHeard} or the Turn's end releases it. */
95
+ boundaryNotices?: () => Promise<Array<{ id: string; notice: Notice }>>;
96
+ /** An Agent's: the Harness appended these step-boundary notices — they are heard, ledgered in one
97
+ * save. Answers how many were this Turn's reservations. */
98
+ noticesHeard?: (ids: readonly string[]) => number;
84
99
  /** Close over the invoking state's `sendBack`; delivery lands where the actor was invoked. */
85
100
  deliver: (event: DeliveredEvent) => void;
86
101
  /** An Agent's: the Harness read this surface (`GET /agents/:iid/surface`), so it has the Turn in
@@ -312,9 +327,15 @@ export function actorPath(ref: AnyActorRef): string[] {
312
327
  * Turn adds a random suffix, a burned conversation's successor its epoch), and the Agent's Actor
313
328
  * names the conversation it burns with it.
314
329
  */
315
- export function continuedIid(machine: AnyActorRef | undefined, runId: string, agentName: string): string {
330
+ /** An Agent's slot (ADR-0076): its continued conversation's Instance ID without the run id —
331
+ * `<machine actor path>/<agent>`. What the Harness states and the registration records. */
332
+ export function agentSlot(machine: AnyActorRef | undefined, agentName: string): string {
316
333
  const path = (machine ? actorPath(machine).join(".") : "") || "root";
317
- return `${runId}/${path}/${agentName}`;
334
+ return `${path}/${agentName}`;
335
+ }
336
+
337
+ export function continuedIid(machine: AnyActorRef | undefined, runId: string, agentName: string): string {
338
+ return `${runId}/${agentSlot(machine, agentName)}`;
318
339
  }
319
340
 
320
341
  /** The address of a run's gate: gate ids are run-scoped by construction (ADR-0011). */
@@ -329,6 +350,9 @@ export function agentAddress(instanceId: string): string {
329
350
 
330
351
  export class RegistrationTable {
331
352
  private readonly byAddress = new Map<string, Registration>();
353
+ /** The same registrations by run, so a run's are read without a scan of every run's: the run host
354
+ * reads them on every microstep of the run (`cause.ts`). */
355
+ private readonly ofRun = new Map<string, Set<Registration>>();
332
356
 
333
357
  /** Register a live surface; returns its disposer (actors call it from their stop cleanup). */
334
358
  register(reg: Registration): () => void {
@@ -338,10 +362,16 @@ export class RegistrationTable {
338
362
  );
339
363
  }
340
364
  this.byAddress.set(reg.address, reg);
365
+ const ofRun = this.ofRun.get(reg.runId) ?? new Set<Registration>();
366
+ ofRun.add(reg);
367
+ this.ofRun.set(reg.runId, ofRun);
341
368
  return () => {
342
369
  // Dispose only our own entry — a re-registration under the same address must not be
343
370
  // clobbered by a stale disposer running late (dev reload, restore races).
344
371
  if (this.byAddress.get(reg.address) === reg) this.byAddress.delete(reg.address);
372
+ const runRegs = this.ofRun.get(reg.runId);
373
+ runRegs?.delete(reg);
374
+ if (runRegs?.size === 0) this.ofRun.delete(reg.runId);
345
375
  };
346
376
  }
347
377
 
@@ -349,9 +379,10 @@ export class RegistrationTable {
349
379
  return this.byAddress.get(address);
350
380
  }
351
381
 
352
- /** All live registrations for one run — the `GET /runs/:id` discovery listing. */
382
+ /** All live registrations for one run, in the order they registered — the `GET /runs/:id`
383
+ * discovery listing. */
353
384
  byRun(runId: string): Registration[] {
354
- return [...this.byAddress.values()].filter((r) => r.runId === runId);
385
+ return [...(this.ofRun.get(runId) ?? [])];
355
386
  }
356
387
 
357
388
  /**
@@ -398,10 +429,55 @@ export class RegistrationTable {
398
429
  }
399
430
  }
400
431
 
432
+ /**
433
+ * Which run dispatched a run (ADR-0071): the caller's run id, the slot of its `dispatch` Effect, and
434
+ * that Effect's ledger row id, which is the idempotency key — a start that carries a key some run
435
+ * already carries answers that run. `depth` is the dispatched run's depth in the chain, one below
436
+ * its caller, stated by the caller and recorded as sent: one meaning on the wire, on the binding
437
+ * and on the row. `instance` is set for a foreign caller, whose Orchestrator this one cannot
438
+ * verify: opaque text, never resolved.
439
+ */
440
+ export type DispatchedBy = { run: string; slot: string; effect: string; depth: number; instance?: string };
441
+
442
+ /** The header a foreign `dispatch` carries its {@link DispatchedBy} in, as JSON (ADR-0071): out of
443
+ * band, so the callee's door reserves no body field for it. */
444
+ export const DISPATCHED_BY_HEADER = "jr2-dispatched-by";
445
+
446
+ /**
447
+ * A dispatch's start as the run host answers it in-process (ADR-0071): the run, and whether the key
448
+ * found one that already existed; or the door's refusal, with the status `POST /workflows/:name/runs`
449
+ * would answer — 400 input the door refuses, 404 a name the current Assembly lacks, 409 a named
450
+ * Chart that cannot run now, 422 a Chart the door refuses — and its report. A refusal is the
451
+ * Effect's output, never thrown.
452
+ */
453
+ export type DispatchStart =
454
+ | { ok: true; runId: string; existing: boolean }
455
+ | { ok: false; status: 400 | 404 | 409 | 422; report: string[] };
456
+
401
457
  /** What a callback actor needs from its host: run identity, the table, and the host's ports. */
402
458
  export type RunBinding = {
403
459
  runId: string;
404
460
  workflow: string;
461
+ /** The name this run's Orchestrator gives itself at another Orchestrator's door (ADR-0071): the
462
+ * `instance` of a foreign dispatch's `dispatchedBy` — stable across its runs and restarts, and not
463
+ * secret, since the callee serves it on its open band. Deployed, its namespace. Never an Instance
464
+ * ID, which names an Agent's conversation and stays behind the token. Absent on a bare unit-test
465
+ * binding and an undeployed Orchestrator. */
466
+ orchestratorName?: string;
467
+ /** The run's depth in a chain of dispatches (ADR-0071): 0 for a run nothing dispatched. Absent
468
+ * on a bare unit-test binding, which reads 0. */
469
+ depth?: number;
470
+ /**
471
+ * The in-process half of a `dispatch` Effect (ADR-0071): the run host, reached directly, with no
472
+ * wire and no token — the Orchestrator is the single writer of runs. `start` answers a refusal as
473
+ * {@link DispatchStart}, never by throwing; `settled` resolves with the run's status once it is no
474
+ * longer live — at once for a run already settled, and across a restore in either order — and
475
+ * rejects when `signal` aborts. Absent outside a RunHost: a dispatch with no target faults.
476
+ */
477
+ dispatch?: {
478
+ start(workflow: string, input: Record<string, unknown>, by: DispatchedBy): Promise<DispatchStart>;
479
+ settled(runId: string, signal: AbortSignal): Promise<RunStatus>;
480
+ };
405
481
  /** The hash of the Assembly the run holds (ADR-0069): the one it started under, through
406
482
  * restarts. Absent for a run no Assembly started. */
407
483
  assembly?: string;
@@ -432,9 +508,18 @@ export type RunBinding = {
432
508
  * Record an Agent invocation's durable admission in the host ledger (ADR-0016): persisted
433
509
  * beside the snapshot in the same RunBlob save, keyed by iid (globally unique, so the map is
434
510
  * flat). Optional so a bare unit-test binding can omit it — then admissions simply are not
435
- * durable.
511
+ * durable. `delivered` are the notices the admission carried, delivered by this save in `taker`'s
512
+ * conversation — the Instance ID the admission rides (ADR-0062). `member`: the Workspace the
513
+ * conversation was admitted in, its slot and whether it continues — so it is in the audience of
514
+ * every kill there from now on, in the same save.
436
515
  */
437
- recordAdmission?: (instanceId: string, admission: AgentAdmission, delivered?: readonly string[]) => void;
516
+ recordAdmission?: (
517
+ instanceId: string,
518
+ admission: AgentAdmission,
519
+ delivered?: readonly string[],
520
+ taker?: string,
521
+ member?: { workspace: string; slot: string; continued: boolean },
522
+ ) => void;
438
523
  /**
439
524
  * The admission ledger's READ half (ADR-0016): the last admission ledgered under this iid. A
440
525
  * continued Turn asks it whether its conversation was ever admitted — only then can the Harness
@@ -461,14 +546,31 @@ export type RunBinding = {
461
546
  /**
462
547
  * The notices' write half (ADR-0062): keep a notice for the next admission in scope — `to` is a
463
548
  * continued conversation's base id or a Sandbox name, as the notice's `scope` says. Persisted at
464
- * the write, like the ledgers. `source` names the event, so one event raised twice is one notice.
549
+ * the write, like the ledgers. `source` names the event, so one event raised twice is one notice;
550
+ * `older` names earlier events this one tells the same as, marked raised with it (`NoticeLedger`).
465
551
  * A burned conversation's notice is raised by `bumpEpoch` itself, in the same save.
466
552
  */
467
- raiseNotice?: (notice: Notice, to: string, source?: string) => void;
468
- /** Reserve the pending notices in one admission's scope. They are delivered by the
469
- * `recordAdmission` that ledgers it (its `delivered` ids), or released if the admission fails. */
553
+ raiseNotice?: (notice: Notice, to: string, source?: string, older?: readonly string[], opts?: RaiseOptions) => void;
554
+ /** Put back a notice an admission carried that no model heard, WITH its source (`NoticeLedger.restore`):
555
+ * a raise would drop it, its source being seen. A Workspace notice is pending again for `taker`,
556
+ * the conversation that did not hear it. Persisted at the write. */
557
+ restoreNotice?: (notice: Notice, to: string, source?: string, taker?: string) => void;
558
+ /** Reserve the pending notices in one admission's scope, for its conversation (`scope.taker`).
559
+ * They are delivered by the `recordAdmission` that ledgers it (its `delivered` ids and `taker`),
560
+ * or released for that conversation if the admission fails. */
470
561
  takeNotices?: (scope: NoticeScope) => TakenNotices;
471
- releaseNotices?: (ids: readonly string[]) => void;
562
+ releaseNotices?: (ids: readonly string[], taker?: string) => void;
563
+ /** What `takeNotices` would reserve in this scope, reserving nothing (`NoticeLedger.peek`). */
564
+ peekNotices?: (scope: NoticeScope) => Array<{ id: string; notice: Notice; source?: string }>;
565
+ /** The Harness acknowledged a step boundary's notices (ADR-0062): each that `taker` reserved is
566
+ * heard there, persisted at the write. Answers how many were. */
567
+ acknowledgeNotices?: (ids: readonly string[], taker: string) => number;
568
+ /** The conversations each kill's `bash` answer told (ADR-0062, D4 rule 3), off the pod's list:
569
+ * they leave that kill's audience. Persisted at the write when anything changed. */
570
+ noticesTold?: (told: ReadonlyArray<{ source: string; takers: readonly string[] }>) => void;
571
+ /** A Turn of these conversations in `workspace` ended: a fresh one leaves every audience there,
572
+ * a continued one stays for its next Turn (ADR-0062). Persisted at the write. */
573
+ noticeTurnEnded?: (workspace: string, takers: readonly string[]) => void;
472
574
  /**
473
575
  * The pick the Turn now at this address has outstanding, or answered and not yet read (ADR-0024):
474
576
  * what the Agent's Actor asks when its Harness restarted under a Turn — a Turn whose pick is still
@@ -480,6 +582,18 @@ export type RunBinding = {
480
582
  /** The held answer reached the model by another road — a re-admission's notice — so the poll's
481
583
  * copy is spent (ADR-0031). */
482
584
  heldAnswerDelivered?: (instanceId: string) => void;
585
+ /**
586
+ * Did this Turn's own pick end it (ADR-0024)? Asked by the Agent's Actor as its invocation stops,
587
+ * before its registration goes, so its sweep can say so (`cause: "pick"`) and the Harness settles
588
+ * the Submission `ended`. True exactly when the transition that stopped the invocation came from
589
+ * the Turn's own pick, by the four rules of ADR-0024 (`cause.ts`): the pick in its own send; the
590
+ * work below the Agent's state while the pick is out; a send of an actor that takes a relay from
591
+ * the pick (rule 3); and a timer armed while its Machine took such a relay (rule 4) — so a timer
592
+ * that the pick's route armed gives true. False for every other end — a timer armed before the
593
+ * pick, an outside event, another party's event, the run's CANCEL, a fault. Absent outside a RunHost: the
594
+ * sweep then says no cause.
595
+ */
596
+ turnEndedByPick?: (instanceId: string) => boolean;
483
597
  /**
484
598
  * Surface absorbed-retry telemetry on the run feed (ADR-0016): attempts are observable, but
485
599
  * as `{ child, attempt }` — state-key-class data, never iids (ADR-0014's line holds on the
@@ -509,6 +623,13 @@ export type RunBinding = {
509
623
  * process), so it says so here, before it stops the actor.
510
624
  */
511
625
  hostStopping?: boolean;
626
+ /**
627
+ * The Sandbox names that a live Workspace of this run holds now, a Workspace in `placing` too
628
+ * (ADR-0064, ADR-0073). A delete that runs after a stop leaves these alone: a parent that invokes
629
+ * the same Machine again gives its new Workspace the same invoke id, and so the same name. Absent
630
+ * outside a RunHost: no name is held.
631
+ */
632
+ heldSandboxes?: () => ReadonlySet<string>;
512
633
  /**
513
634
  * Every reply since the pick that `machine`'s Agent has outstanding, or is delivering now, oldest
514
635
  * first (ADR-0024) — what an `answer` action reads as its `chain` (ADR-0067). `seat` is the place
@@ -18,7 +18,8 @@ export type RepoIdentity = {
18
18
  * absolute path for a local repository. Path case is KEPT: hosts are case-insensitive, paths on
19
19
  * most forges are not. */
20
20
  identity: string;
21
- /** `<slug>-<sha256(identity)[:8]>` — a DNS-1123 label of at most 49 characters. */
21
+ /** `<slug>-<sha256(identity)[:32]>` — a DNS-1123 label of at most 49 characters: a slug of at
22
+ * most 16 characters and 128 bits of the hash, so no one finds two identities with one key. */
22
23
  key: string;
23
24
  scheme: "https" | "http" | "ssh" | "git" | "local";
24
25
  };
@@ -139,7 +140,10 @@ function keyOf(identity: string): string {
139
140
  .toLowerCase()
140
141
  .replace(/[^a-z0-9]+/g, "-")
141
142
  .replace(/^-+|-+$/g, "")
142
- .slice(0, 40)
143
+ .slice(0, 16)
143
144
  .replace(/-+$/, "") || "repo";
144
- return `${slug}-${createHash("sha256").update(identity).digest("hex").slice(0, 8)}`;
145
+ // 128 bits (ADR-0051): the key names the cache that a Sandbox mounts, and a per-run url is the
146
+ // Agent's text. With 32 bits a search found a url of another repository with the same key in
147
+ // seconds, and that url mounted the other repository's cache.
148
+ return `${slug}-${createHash("sha256").update(identity).digest("hex").slice(0, 32)}`;
145
149
  }
package/src/repos.ts CHANGED
@@ -54,7 +54,8 @@ export type RepoNodeState = {
54
54
 
55
55
  /** One `Repo` resource as the instance reports it (`GET /repos`). */
56
56
  export type RepoStatus = {
57
- /** The cache key (repo-identity.ts): the resource's name, the hostPath leaf, `/repos/<key>`. */
57
+ // repo-identity.ts makes the key.
58
+ /** The cache key: the resource's name, the hostPath leaf, `/repos/<key>`. */
58
59
  key: string;
59
60
  /** The Binding's own spelling — what the cache clones. */
60
61
  url: string;
@@ -191,10 +192,28 @@ export function kubeRepos(opts: KubeReposOptions): RepoResources {
191
192
  return item;
192
193
  };
193
194
 
195
+ /** The resource that stands under `repo.key`, when it is `repo`'s identity; else a throw that names
196
+ * both urls (ADR-0051). The key is collision-resistant, so another identity under one key is a
197
+ * defect or an attack, and no statement of this port writes a resource of another identity: not
198
+ * its url, not its `secretRef`, not its clock. */
199
+ const sameIdentity = async (repo: { url: string; identity: string; key: string }): Promise<RepoItem> => {
200
+ const item = await get(repo.key);
201
+ const stands = item.metadata?.annotations?.[ANNOTATION_REPO_IDENTITY];
202
+ if (stands !== repo.identity) {
203
+ throw new Error(
204
+ `Repo "${repo.key}" stands for ${stands === undefined ? "no stated identity" : `"${stands}"`} ` +
205
+ `(url ${item.spec?.url ?? "unknown"}), not for "${repo.identity}" (url ${repo.url}): one key, two ` +
206
+ "repositories, so jr2 changes nothing on it (ADR-0051). Delete that Repo if it is stale.",
207
+ );
208
+ }
209
+ return item;
210
+ };
211
+
194
212
  return {
195
213
  async bind(repo) {
196
214
  const { secretRef, cr } = await resourceFor({ ...repo, bound: true });
197
215
  if (await create(cr)) return;
216
+ await sameIdentity(repo);
198
217
  // Already there from an earlier deploy: ONE merge patch says what the Machine resolves now —
199
218
  // url, credential, and the label `jr2 gc` honors. `secretRef: null` clears a credential the
200
219
  // config no longer names, so a dropped entry does not linger. The clock is not touched: it
@@ -215,12 +234,12 @@ export function kubeRepos(opts: KubeReposOptions): RepoResources {
215
234
  // Already there — the boot's statement, or an earlier run's. The eviction clock moves: the
216
235
  // run attached it now. The url stays as stated, whatever spelling this run brought.
217
236
  const clock = { metadata: { annotations: { [ANNOTATION_REPO_LAST_ATTACHED]: attached } } };
237
+ const standing = await sameIdentity(repo);
218
238
  // A Machine's slot binds it: the boot is its writer, and restates the credential at the next
219
- // deploy. Read nothing.
239
+ // deploy.
220
240
  if (repo.bound) return patch(repo.key, clock);
221
241
  // This run's slot is per-run, but another registered Machine may bind the identity — the
222
242
  // label says so, and then the boot is still the writer.
223
- const standing = await get(repo.key);
224
243
  if (standing.metadata?.labels?.[LABEL_REPO_BOUND] === "true") return patch(repo.key, clock);
225
244
  // Nothing binds it: no boot ever restates it, so this attach does — the credential resolved
226
245
  // against the url that STANDS, since the scheme picks the Secret's kind (config.ts) and the