@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
package/console/main.ts CHANGED
@@ -25,9 +25,29 @@
25
25
  // hand-rolled memo()/paint() machinery did. This file is the BOOTSTRAP and owns only working
26
26
  // state — the machine-doc cache, the input-schema cache, the fetch serials, the zoom readout; the
27
27
  // diagram's own working state (fold set, viewport, what is shown) lives in canvas.ts.
28
+ //
29
+ // A run that binds a Chart (ADR-0070) draws ITS Machine, not the Workflow's: the definition's doc
30
+ // has the Open body as one opaque child, and a Chart one cannot watch is a Chart one cannot trust.
31
+ // So the doc the center pane draws is chosen per selection (`machineDocSource`): the Workflow's
32
+ // Machine, or, when the selected run's observation says `bound`, the run's own from
33
+ // `GET /workflows/:name/runs/:runId/machine`, cached per run id. The live child still joins its
34
+ // subgraph by `src`, which the per-run doc keeps as the body's slot key.
28
35
 
29
36
  import { h, render } from "preact";
30
- import { applyFrame, emptyStore, type Frame, type GateCard, type ObservedRun, type Store } from "./store.ts";
37
+ import {
38
+ applyFrame,
39
+ emptyStore,
40
+ failureReason,
41
+ machineDocSource,
42
+ selectedRun,
43
+ type Frame,
44
+ type GateCard,
45
+ type ObservedRun,
46
+ type Store,
47
+ type HeldLine,
48
+ type WaitingLine,
49
+ type WorkflowListing,
50
+ } from "./store.ts";
31
51
  import { zoomFit, zoomIn, zoomOut, zoomReset, type MachineDoc } from "./canvas.ts";
32
52
  import { App, type AppApi, type MachineView } from "./components/app.ts";
33
53
 
@@ -49,6 +69,9 @@ function rerender(): void {
49
69
  function dispatch(frame: Frame): void {
50
70
  store = applyFrame(store, frame);
51
71
  rerender();
72
+ // A frame can change which doc the pane draws: a new selection, a run selected, a run that now
73
+ // binds a Chart. The check is a key compare; only a change fetches.
74
+ void syncMachine();
52
75
  }
53
76
 
54
77
  // ---- The token (ADR-0032) -----------------------------------------------------------------------
@@ -98,7 +121,7 @@ async function validateToken(): Promise<void> {
98
121
  dispatch({ kind: "token", state: "live" });
99
122
  const runs = (await res.json()) as Array<{ runId: string; workflow: string }>;
100
123
  if (serial !== tokenSerial) return;
101
- for (const r of runs) void refreshGates(r.runId, r.workflow);
124
+ for (const r of runs) void refreshRun(r.runId, r.workflow);
102
125
  }
103
126
 
104
127
  function setToken(value: string): void {
@@ -112,7 +135,7 @@ function setToken(value: string): void {
112
135
  void validateToken();
113
136
  }
114
137
 
115
- // ---- Gate discovery (frame-triggered — ADR-0032) ------------------------------------------------
138
+ // ---- Gate discovery and waits (frame-triggered — ADR-0032, ADR-0064) ----------------------------
116
139
 
117
140
  /** Per-run re-fetch serials — fetch bookkeeping like `docs`, not belief. The browser runs these
118
141
  * requests on parallel connections, so answers can land out of ORDER: a re-fetch triggered by the
@@ -121,21 +144,36 @@ function setToken(value: string): void {
121
144
  * emptied — pinning the ⚑ and inviting a second delivery until the run's next frame, which a run
122
145
  * parked in a long agent step may not land for minutes. Only the latest-STARTED re-fetch may
123
146
  * speak for a run; superseded answers are dropped before they reach the store. */
124
- const gateFetchSerial = new Map<string, number>();
147
+ const runFetchSerial = new Map<string, number>();
125
148
 
126
149
  /** Re-read one run's open gates off the guarded surface and fold the WHOLE answer in. Called on
127
150
  * every frame that touches the run — that is the synchronization: a gate opens with a state entry
128
151
  * and closes with its exit, and every entry/exit lands a frame. A delivery's success is the next
129
- * re-fetch coming back empty; nothing here concludes anything on its own. */
130
- async function refreshGates(runId: string, workflow: string): Promise<void> {
152
+ * re-fetch coming back empty; nothing here concludes anything on its own. The same answer carries
153
+ * why the run's Workspaces in `placing` wait (ADR-0064), folded as its own frame by the same rules:
154
+ * a Workspace enters and leaves `placing` with a frame too. */
155
+ async function refreshRun(runId: string, workflow: string): Promise<void> {
131
156
  if (store.token !== "live") return; // observer mode: the inbox does not exist
132
- const serial = (gateFetchSerial.get(runId) ?? 0) + 1;
133
- gateFetchSerial.set(runId, serial);
157
+ const serial = (runFetchSerial.get(runId) ?? 0) + 1;
158
+ runFetchSerial.set(runId, serial);
134
159
  const res = await gfetch(`/runs/${encodeURIComponent(runId)}`);
135
160
  if (!res) return; // 401 already dropped the page to observer
136
- const gates = res.ok ? (((await res.json()) as { gates?: GateCard[] }).gates ?? []) : []; // !ok: settled + evicted
137
- if (gateFetchSerial.get(runId) !== serial) return; // superseded — a newer re-fetch owns the answer
138
- dispatch({ kind: "gates", runId, workflow, gates });
161
+ // !ok: settled + evicted — no gates, and nothing waits.
162
+ const body = res.ok
163
+ ? ((await res.json()) as {
164
+ status?: string;
165
+ output?: unknown;
166
+ gates?: GateCard[];
167
+ waiting?: WaitingLine[];
168
+ held?: HeldLine[];
169
+ })
170
+ : {};
171
+ if (runFetchSerial.get(runId) !== serial) return; // superseded — a newer re-fetch owns the answer
172
+ dispatch({ kind: "gates", runId, workflow, gates: body.gates ?? [] });
173
+ dispatch({ kind: "waiting", runId, workflow, waiting: body.waiting ?? [], held: body.held ?? [] });
174
+ // The reason of a run that ended `failed` (ADR-0073). A 404 says nothing about it, so a reason
175
+ // the page has stays.
176
+ if (res.ok) dispatch({ kind: "failure", runId, reason: failureReason(body) });
139
177
  }
140
178
 
141
179
  // ---- The two writes (start-run + gate delivery — ADR-0033) --------------------------------------
@@ -215,34 +253,68 @@ async function selectWorkflow(
215
253
  const moved = name !== store.workflow;
216
254
  if (push && moved) history.pushState({}, "", name ? `/workflows/${encodeURIComponent(name)}` : "/");
217
255
  document.title = name ? `jr2 · ${name}` : "jr2 · Console";
218
- dispatch({ kind: "select", workflow: name });
256
+ // Re-selecting the selection (a popstate re-fire) with its diagram in hand keeps the feed.
257
+ const reconnect = moved || !view.doc;
258
+ if (reconnect) {
259
+ feed?.close();
260
+ feed = null;
261
+ // Forget the old diagram NOW, before the `select` frame: the new feed's frames start landing
262
+ // before the new doc is in hand, and they must not re-layout (or highlight) the machine the
263
+ // reader just left — the render reaches the canvas effect, which clears it.
264
+ view = { doc: null, placeholder: name ? null : "select a workflow from the fleet", note: null };
265
+ shownKey = null;
266
+ }
267
+ dispatch({ kind: "select", workflow: name }); // the dispatch starts the doc's fetch (syncMachine)
219
268
  if (runId) dispatch({ kind: "selectRun", runId });
220
- if (!moved && view.doc) return; // re-selecting the selection (a popstate re-fire): nothing to do
221
- feed?.close();
222
- feed = null;
223
- // Forget the old diagram NOW: the new feed's frames start landing before the new doc is in hand,
224
- // and they must not re-layout (or highlight) the machine the reader just left — the render below
225
- // reaches the canvas effect, which clears it.
226
- view = { doc: null, placeholder: name ? null : "select a workflow from the fleet", note: null };
227
- rerender();
228
- if (!name) return;
269
+ if (!reconnect || !name) return;
229
270
  connectFeed(name);
230
- await loadMachine(name);
271
+ await syncMachine();
231
272
  }
232
273
 
233
- /** The selected workflow's Machine docs, kept across navigations — structure does not change under
234
- * a running orchestrator, so going back to a workflow is instant. Misses are NOT cached: a name
235
- * can be registered after this page loaded, and re-selecting it should find it. */
274
+ /** Machine docs, kept across navigations and keyed by `machineDocSource`: a Workflow's doc is one
275
+ * per name (structure does not change under a running orchestrator, so going back is instant), and
276
+ * a run that binds a Chart has its own per run id (ADR-0070). Misses are NOT cached: a name can be
277
+ * registered after this page loaded, and re-selecting it should find it. */
236
278
  const docs = new Map<string, MachineDoc>();
237
279
 
238
- async function loadMachine(name: string): Promise<void> {
239
- let doc: MachineDoc | null | undefined = docs.get(name);
240
- if (doc === undefined) {
241
- const res = await fetch(`/workflows/${encodeURIComponent(name)}/machine`);
242
- doc = res.ok ? ((await res.json()) as MachineDoc) : null;
243
- if (doc) docs.set(name, doc);
280
+ /** The doc key the pane draws or is fetching — so a frame that changes nothing fetches nothing, and
281
+ * an answer for a key the reader has left is dropped. */
282
+ let shownKey: string | null = null;
283
+
284
+ async function fetchDoc(source: { key: string; path: string }): Promise<MachineDoc | null> {
285
+ const cached = docs.get(source.key);
286
+ if (cached) return cached;
287
+ try {
288
+ const res = await fetch(source.path);
289
+ const doc = res.ok ? ((await res.json()) as MachineDoc) : null;
290
+ if (doc) docs.set(source.key, doc);
291
+ return doc;
292
+ } catch {
293
+ return null; // network trouble reads as a miss; the next selection retries
294
+ }
295
+ }
296
+
297
+ /** Bring the pane's doc in line with the selection: the selected run's bound Machine when it binds
298
+ * a Chart, else the Workflow's (`machineDocSource`, ADR-0070). */
299
+ async function syncMachine(): Promise<void> {
300
+ const name = store.workflow;
301
+ if (!name) return;
302
+ const source = machineDocSource(name, selectedRun(store));
303
+ if (source.key === shownKey) return;
304
+ shownKey = source.key;
305
+ let doc = await fetchDoc(source);
306
+ if (shownKey !== source.key) return; // the reader moved on while the fetch was out
307
+ let note: MachineView["note"] = null;
308
+ if (!doc && source.key.startsWith("run:")) {
309
+ // The run's own Machine could not be read (an Orchestrator older than the route, or the run
310
+ // left the store): draw the Workflow's, and say the Chart's states are not in it.
311
+ doc = await fetchDoc(machineDocSource(name, null));
312
+ if (shownKey !== source.key) return;
313
+ note = {
314
+ text: "this run binds a Chart, and its Machine could not be read: the Chart's states are not shown",
315
+ notice: true,
316
+ };
244
317
  }
245
- if (store.workflow !== name) return; // the reader moved on while the fetch was out
246
318
  if (!doc) {
247
319
  view = { doc: null, placeholder: null, note: { text: `no workflow "${name}"`, notice: false } };
248
320
  rerender();
@@ -251,10 +323,21 @@ async function loadMachine(name: string): Promise<void> {
251
323
  // Nothing live yet: every child machine renders once, as a dimmed template (the canvas effect
252
324
  // picks the doc up from here). The first status frame of a run with children swaps those for
253
325
  // one subgraph per instance.
254
- view = { doc, placeholder: null, note: opaqueNotice(doc) };
326
+ view = { doc, placeholder: null, note: note ?? notDrawnNotice(doc) ?? opaqueNotice(doc) };
255
327
  rerender();
256
328
  }
257
329
 
330
+ /** Say so when a run's doc could not draw a Chart the run binds (ADR-0070, D-B): its Open body then
331
+ * shows the slot's own subgraph, and the server names why (`MachineDoc.chartsNotDrawn`). */
332
+ function notDrawnNotice(doc: MachineDoc): MachineView["note"] {
333
+ const missing = doc.chartsNotDrawn ?? [];
334
+ if (!missing.length) return null;
335
+ return {
336
+ notice: true,
337
+ text: `this run binds a Chart this diagram does not draw — ${missing.map((m) => `body "${m.src}" (${m.path}): ${m.reason}`).join("; ")}`,
338
+ };
339
+ }
340
+
258
341
  /** Say so when the diagram is knowingly incomplete: a child spawned inside an `enqueueActions`
259
342
  * closure cannot be found by the static walk, so those states may be missing children entirely.
260
343
  * Computed server-side (`MachineDoc.opaqueStates`) and surfaced HERE, where the reader is. */
@@ -282,12 +365,12 @@ function connectFeed(name: string): void {
282
365
  feed.addEventListener("runs", (e) => {
283
366
  const runs = JSON.parse((e as MessageEvent<string>).data) as ObservedRun[];
284
367
  dispatch({ kind: "runs", runs });
285
- for (const r of runs) void refreshGates(r.runId, name);
368
+ for (const r of runs) void refreshRun(r.runId, name);
286
369
  });
287
370
  feed.addEventListener("status", (e) => {
288
371
  const status = JSON.parse((e as MessageEvent<string>).data) as ObservedRun;
289
372
  dispatch({ kind: "status", status });
290
- void refreshGates(status.runId, name);
373
+ void refreshRun(status.runId, name);
291
374
  });
292
375
  feed.addEventListener("gone", (e) => {
293
376
  const { runId } = JSON.parse((e as MessageEvent<string>).data) as { runId: string };
@@ -295,7 +378,7 @@ function connectFeed(name: string): void {
295
378
  // The reducer already dropped the card (a gate exists only while its state is entered —
296
379
  // ADR-0011); the re-fetch is the same frame-triggered discipline as `runs`/`status`, and its
297
380
  // 404 converges on the same empty answer.
298
- void refreshGates(runId, name);
381
+ void refreshRun(runId, name);
299
382
  });
300
383
  feed.addEventListener("emit", (e) => {
301
384
  const { runId, type } = JSON.parse((e as MessageEvent<string>).data) as { runId: string; type: string };
@@ -318,7 +401,7 @@ async function snapshotWorkflow(name: string): Promise<void> {
318
401
  if (!res.ok) return;
319
402
  const runs = (await res.json()) as ObservedRun[];
320
403
  dispatch({ kind: "fleet", workflow: name, runs });
321
- for (const r of runs) void refreshGates(r.runId, name);
404
+ for (const r of runs) void refreshRun(r.runId, name);
322
405
  } catch {
323
406
  // transient — the next tick tries again
324
407
  }
@@ -327,7 +410,7 @@ async function snapshotWorkflow(name: string): Promise<void> {
327
410
  async function snapshotFleet(): Promise<void> {
328
411
  try {
329
412
  const res = await fetch("/workflows");
330
- if (res.ok) dispatch({ kind: "workflows", workflows: (await res.json()) as string[] });
413
+ if (res.ok) dispatch({ kind: "workflows", workflows: (await res.json()) as WorkflowListing[] });
331
414
  } catch {
332
415
  // transient — the next tick tries again
333
416
  }
@@ -368,7 +451,7 @@ async function boot(): Promise<void> {
368
451
  // observation), then the selection the address carries — deep links work on load.
369
452
  try {
370
453
  const res = await fetch("/workflows");
371
- if (res.ok) dispatch({ kind: "workflows", workflows: (await res.json()) as string[] });
454
+ if (res.ok) dispatch({ kind: "workflows", workflows: (await res.json()) as WorkflowListing[] });
372
455
  } catch {
373
456
  // the interval retries; the rail says "no workflows registered" until then
374
457
  }