@jr2/orchestrator 0.4.1 → 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 (327) 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 +442 -0
  10. package/docs/concepts/architecture.md +230 -0
  11. package/docs/concepts/charts.md +143 -0
  12. package/docs/concepts/composition.md +357 -0
  13. package/docs/concepts/converge.md +254 -0
  14. package/docs/concepts/durable-runs.md +189 -0
  15. package/docs/concepts/effects.md +603 -0
  16. package/docs/concepts/gates.md +208 -0
  17. package/docs/concepts/machines-and-workflows.md +289 -0
  18. package/docs/concepts/pools-and-sources.md +230 -0
  19. package/docs/concepts/secrets-and-trust.md +222 -0
  20. package/docs/concepts/the-menu.md +378 -0
  21. package/docs/concepts/workspaces.md +678 -0
  22. package/docs/get-started/a-model-decides.md +563 -0
  23. package/docs/get-started/an-agent-in-a-sandbox.md +381 -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 +922 -0
  27. package/docs/get-started/install.md +126 -0
  28. package/docs/guides/add-tools-to-the-sandbox.md +295 -0
  29. package/docs/guides/answer-a-gate.md +304 -0
  30. package/docs/guides/bind-open-parts.md +223 -0
  31. package/docs/guides/cancel-a-run.md +146 -0
  32. package/docs/guides/clean-up.md +206 -0
  33. package/docs/guides/fix-a-failed-converge.md +361 -0
  34. package/docs/guides/give-the-cluster-git-credentials.md +222 -0
  35. package/docs/guides/iterate-on-a-machine-on-kind.md +190 -0
  36. package/docs/guides/let-an-agent-write-a-chart.md +226 -0
  37. package/docs/guides/look-inside-a-sandbox.md +174 -0
  38. package/docs/guides/mirror-the-kit-images.md +176 -0
  39. package/docs/guides/move-from-kind-to-a-shared-cluster.md +302 -0
  40. package/docs/guides/open-the-console.md +91 -0
  41. package/docs/guides/publish-a-machine-as-an-npm-package.md +350 -0
  42. package/docs/guides/push-and-sign-a-branch.md +486 -0
  43. package/docs/guides/run-a-chart-by-name.md +270 -0
  44. package/docs/guides/run-a-command-or-call-a-url.md +544 -0
  45. package/docs/guides/run-one-worker-per-item.md +321 -0
  46. package/docs/guides/set-an-agents-access-and-dials.md +375 -0
  47. package/docs/guides/size-a-workspace.md +204 -0
  48. package/docs/guides/start-a-run-from-a-run.md +237 -0
  49. package/docs/guides/start-a-run.md +207 -0
  50. package/docs/guides/upgrade-the-kit-version.md +240 -0
  51. package/docs/guides/use-a-hosted-provider.md +208 -0
  52. package/docs/guides/use-a-local-model.md +313 -0
  53. package/docs/guides/watch-a-run.md +326 -0
  54. package/docs/guides/write-a-workflow.md +318 -0
  55. package/docs/index.md +44 -0
  56. package/docs/llms.txt +216 -0
  57. package/docs/reference/authoring-surface/agent.md +128 -0
  58. package/docs/reference/authoring-surface/answer.md +140 -0
  59. package/docs/reference/authoring-surface/arg.md +60 -0
  60. package/docs/reference/authoring-surface/basic.md +62 -0
  61. package/docs/reference/authoring-surface/bearer.md +53 -0
  62. package/docs/reference/authoring-surface/chartschema.md +23 -0
  63. package/docs/reference/authoring-surface/chartschemafor.md +48 -0
  64. package/docs/reference/authoring-surface/command.md +191 -0
  65. package/docs/reference/authoring-surface/customize.md +64 -0
  66. package/docs/reference/authoring-surface/defineconfig.md +41 -0
  67. package/docs/reference/authoring-surface/defineevent.md +114 -0
  68. package/docs/reference/authoring-surface/dispatch.md +126 -0
  69. package/docs/reference/authoring-surface/fail.md +83 -0
  70. package/docs/reference/authoring-surface/file.md +122 -0
  71. package/docs/reference/authoring-surface/frompick.md +277 -0
  72. package/docs/reference/authoring-surface/http.md +159 -0
  73. package/docs/reference/authoring-surface/isfailure.md +58 -0
  74. package/docs/reference/authoring-surface/jr2setup.md +237 -0
  75. package/docs/reference/authoring-surface/open.md +74 -0
  76. package/docs/reference/authoring-surface/openbody.md +86 -0
  77. package/docs/reference/authoring-surface/paramsof.md +125 -0
  78. package/docs/reference/authoring-surface/pool.md +186 -0
  79. package/docs/reference/authoring-surface/push.md +112 -0
  80. package/docs/reference/authoring-surface/secret.md +118 -0
  81. package/docs/reference/authoring-surface/sentby.md +83 -0
  82. package/docs/reference/authoring-surface/source.md +51 -0
  83. package/docs/reference/authoring-surface/text.md +62 -0
  84. package/docs/reference/authoring-surface/type-agentdeclaration.md +27 -0
  85. package/docs/reference/authoring-surface/type-agentdefinition.md +80 -0
  86. package/docs/reference/authoring-surface/type-agentlogic.md +15 -0
  87. package/docs/reference/authoring-surface/type-agentslots.md +12 -0
  88. package/docs/reference/authoring-surface/type-answeraction.md +12 -0
  89. package/docs/reference/authoring-surface/type-arg.md +19 -0
  90. package/docs/reference/authoring-surface/type-argnames.md +12 -0
  91. package/docs/reference/authoring-surface/type-binding.md +62 -0
  92. package/docs/reference/authoring-surface/type-bindingof.md +12 -0
  93. package/docs/reference/authoring-surface/type-bodyacceptsdoor.md +15 -0
  94. package/docs/reference/authoring-surface/type-bodyacceptsslots.md +17 -0
  95. package/docs/reference/authoring-surface/type-ceilings.md +41 -0
  96. package/docs/reference/authoring-surface/type-chainlink.md +19 -0
  97. package/docs/reference/authoring-surface/type-chartaction.md +46 -0
  98. package/docs/reference/authoring-surface/type-chartagent.md +28 -0
  99. package/docs/reference/authoring-surface/type-chartevent.md +20 -0
  100. package/docs/reference/authoring-surface/type-chartguard.md +20 -0
  101. package/docs/reference/authoring-surface/type-chartinvoke.md +28 -0
  102. package/docs/reference/authoring-surface/type-chartjson.md +14 -0
  103. package/docs/reference/authoring-surface/type-chartstate.md +46 -0
  104. package/docs/reference/authoring-surface/type-charttext.md +40 -0
  105. package/docs/reference/authoring-surface/type-charttransition.md +22 -0
  106. package/docs/reference/authoring-surface/type-charttransitions.md +14 -0
  107. package/docs/reference/authoring-surface/type-chartvalue.md +15 -0
  108. package/docs/reference/authoring-surface/type-childat.md +12 -0
  109. package/docs/reference/authoring-surface/type-childslots.md +12 -0
  110. package/docs/reference/authoring-surface/type-commandenv.md +15 -0
  111. package/docs/reference/authoring-surface/type-commandinput.md +19 -0
  112. package/docs/reference/authoring-surface/type-commandoptions.md +78 -0
  113. package/docs/reference/authoring-surface/type-commandoutput.md +104 -0
  114. package/docs/reference/authoring-surface/type-customize.md +109 -0
  115. package/docs/reference/authoring-surface/type-dispatchdefinition.md +39 -0
  116. package/docs/reference/authoring-surface/type-dispatchinput.md +14 -0
  117. package/docs/reference/authoring-surface/type-dispatchopenparts.md +14 -0
  118. package/docs/reference/authoring-surface/type-dispatchoutput.md +65 -0
  119. package/docs/reference/authoring-surface/type-duration.md +15 -0
  120. package/docs/reference/authoring-surface/type-effectbinding.md +93 -0
  121. package/docs/reference/authoring-surface/type-effectlogic.md +12 -0
  122. package/docs/reference/authoring-surface/type-envopenparts.md +14 -0
  123. package/docs/reference/authoring-surface/type-eventaudience.md +27 -0
  124. package/docs/reference/authoring-surface/type-eventdef.md +45 -0
  125. package/docs/reference/authoring-surface/type-eventfrom.md +16 -0
  126. package/docs/reference/authoring-surface/type-eventsemantics.md +26 -0
  127. package/docs/reference/authoring-surface/type-execoutcome.md +34 -0
  128. package/docs/reference/authoring-surface/type-failslot.md +14 -0
  129. package/docs/reference/authoring-surface/type-failure.md +19 -0
  130. package/docs/reference/authoring-surface/type-failureinput.md +20 -0
  131. package/docs/reference/authoring-surface/type-filebody.md +41 -0
  132. package/docs/reference/authoring-surface/type-frominput.md +14 -0
  133. package/docs/reference/authoring-surface/type-hostinjectedinput.md +58 -0
  134. package/docs/reference/authoring-surface/type-httpdefinition.md +101 -0
  135. package/docs/reference/authoring-surface/type-httpinput.md +12 -0
  136. package/docs/reference/authoring-surface/type-httpmethod.md +14 -0
  137. package/docs/reference/authoring-surface/type-httpopenparts.md +12 -0
  138. package/docs/reference/authoring-surface/type-httpoutput.md +89 -0
  139. package/docs/reference/authoring-surface/type-httprequestparts.md +33 -0
  140. package/docs/reference/authoring-surface/type-jr2config.md +126 -0
  141. package/docs/reference/authoring-surface/type-lends.md +38 -0
  142. package/docs/reference/authoring-surface/type-logicat.md +12 -0
  143. package/docs/reference/authoring-surface/type-markedif.md +12 -0
  144. package/docs/reference/authoring-surface/type-mergedactors.md +12 -0
  145. package/docs/reference/authoring-surface/type-namedsecret.md +25 -0
  146. package/docs/reference/authoring-surface/type-noslotspec.md +26 -0
  147. package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +32 -0
  148. package/docs/reference/authoring-surface/type-openbodydeclaration.md +40 -0
  149. package/docs/reference/authoring-surface/type-openbodylogic.md +14 -0
  150. package/docs/reference/authoring-surface/type-openbodyoutput.md +42 -0
  151. package/docs/reference/authoring-surface/type-openbodyslot.md +18 -0
  152. package/docs/reference/authoring-surface/type-opencommandinput.md +17 -0
  153. package/docs/reference/authoring-surface/type-openeffect.md +12 -0
  154. package/docs/reference/authoring-surface/type-openeffectslots.md +12 -0
  155. package/docs/reference/authoring-surface/type-openof.md +12 -0
  156. package/docs/reference/authoring-surface/type-opensecret.md +23 -0
  157. package/docs/reference/authoring-surface/type-opensecretmark.md +12 -0
  158. package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +31 -0
  159. package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +32 -0
  160. package/docs/reference/authoring-surface/type-poolmachine.md +28 -0
  161. package/docs/reference/authoring-surface/type-poolspec.md +60 -0
  162. package/docs/reference/authoring-surface/type-pushinput.md +15 -0
  163. package/docs/reference/authoring-surface/type-pushoptions.md +79 -0
  164. package/docs/reference/authoring-surface/type-pushoutput.md +124 -0
  165. package/docs/reference/authoring-surface/type-pushwireoutput.md +12 -0
  166. package/docs/reference/authoring-surface/type-quantity.md +14 -0
  167. package/docs/reference/authoring-surface/type-reached.md +12 -0
  168. package/docs/reference/authoring-surface/type-reposlot.md +70 -0
  169. package/docs/reference/authoring-surface/type-reposlotsof.md +16 -0
  170. package/docs/reference/authoring-surface/type-sandboxoptions.md +77 -0
  171. package/docs/reference/authoring-surface/type-secret.md +25 -0
  172. package/docs/reference/authoring-surface/type-sender.md +19 -0
  173. package/docs/reference/authoring-surface/type-sentbyguards.md +12 -0
  174. package/docs/reference/authoring-surface/type-size.md +85 -0
  175. package/docs/reference/authoring-surface/type-slothandles.md +32 -0
  176. package/docs/reference/authoring-surface/type-sourcenextresult.md +17 -0
  177. package/docs/reference/authoring-surface/type-sourcespec.md +44 -0
  178. package/docs/reference/authoring-surface/type-syncstate.md +12 -0
  179. package/docs/reference/authoring-surface/type-text.md +19 -0
  180. package/docs/reference/authoring-surface/type-textpart.md +24 -0
  181. package/docs/reference/authoring-surface/type-thinkinglevel.md +39 -0
  182. package/docs/reference/authoring-surface/type-toparameterizedobject.md +14 -0
  183. package/docs/reference/authoring-surface/type-toprovidedactor.md +14 -0
  184. package/docs/reference/authoring-surface/type-unknown.md +21 -0
  185. package/docs/reference/authoring-surface/type-usercontainer.md +77 -0
  186. package/docs/reference/authoring-surface/type-withoutemptyindex.md +20 -0
  187. package/docs/reference/authoring-surface/type-workflowevent.md +46 -0
  188. package/docs/reference/authoring-surface/type-workspaceaccess.md +16 -0
  189. package/docs/reference/authoring-surface/type-workspaced.md +94 -0
  190. package/docs/reference/authoring-surface/type-workspacehandles.md +23 -0
  191. package/docs/reference/authoring-surface/type-workspacemachine.md +29 -0
  192. package/docs/reference/authoring-surface/type-workspaceof.md +13 -0
  193. package/docs/reference/authoring-surface/type-workspaceoptions.md +39 -0
  194. package/docs/reference/authoring-surface/type-workspacespec.md +37 -0
  195. package/docs/reference/authoring-surface/workspace.md +259 -0
  196. package/docs/reference/authoring-surface.md +197 -0
  197. package/docs/reference/cli.md +433 -0
  198. package/docs/reference/config.md +756 -0
  199. package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +113 -0
  200. package/docs/reference/decisions/0002-duplex-streaming-actor.md +110 -0
  201. package/docs/reference/decisions/0004-worktree-provisioning-model.md +124 -0
  202. package/docs/reference/decisions/0005-sandbox-pod-composition.md +230 -0
  203. package/docs/reference/decisions/0006-agent-control-surface.md +47 -0
  204. package/docs/reference/decisions/0007-durable-machine-state.md +109 -0
  205. package/docs/reference/decisions/0008-orchestrator-as-deployed-app.md +60 -0
  206. package/docs/reference/decisions/0009-cli-and-instance-interface.md +275 -0
  207. package/docs/reference/decisions/0010-bdd-acceptance-tests.md +160 -0
  208. package/docs/reference/decisions/0011-workflow-defined-events.md +141 -0
  209. package/docs/reference/decisions/0012-workspace-wrapper-machine.md +103 -0
  210. package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +157 -0
  211. package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +95 -0
  212. package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +265 -0
  213. package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +124 -0
  214. package/docs/reference/decisions/0017-pool-over-a-source-port.md +69 -0
  215. package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +111 -0
  216. package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +275 -0
  217. package/docs/reference/decisions/0020-private-ca-trust-is-a-named-concept.md +60 -0
  218. package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +100 -0
  219. package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +103 -0
  220. package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +176 -0
  221. package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +439 -0
  222. package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +65 -0
  223. package/docs/reference/decisions/0026-a-turn-that-is-over-is-never-prompted.md +62 -0
  224. package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +237 -0
  225. package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +89 -0
  226. package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +154 -0
  227. package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +100 -0
  228. package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +190 -0
  229. package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +61 -0
  230. package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +127 -0
  231. package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +57 -0
  232. package/docs/reference/decisions/0035-a-runaway-turn-is-ended-rerolled-once-then-a-fault.md +92 -0
  233. package/docs/reference/decisions/0036-a-turn-compacts-its-own-context-mid-flight.md +138 -0
  234. package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +196 -0
  235. package/docs/reference/decisions/0038-jr2-up-builds-every-image-it-deploys.md +170 -0
  236. package/docs/reference/decisions/0039-image-garbage-collects-by-reachability.md +115 -0
  237. package/docs/reference/decisions/0041-a-build-the-host-already-holds-is-not-spent-again.md +64 -0
  238. package/docs/reference/decisions/0042-ready-is-not-routable-an-admission-retries-its-connection.md +142 -0
  239. package/docs/reference/decisions/0043-the-kit-is-tested-as-installed-a-local-registry-stands-in-for-npm.md +170 -0
  240. package/docs/reference/decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md +85 -0
  241. package/docs/reference/decisions/0045-the-platform-joins-the-image-address-and-the-cluster-chooses-it.md +82 -0
  242. package/docs/reference/decisions/0046-a-converge-failure-carries-its-diagnosis.md +34 -0
  243. package/docs/reference/decisions/0047-the-git-ssh-key-source-is-the-users-choice.md +47 -0
  244. package/docs/reference/decisions/0048-the-orchestrator-boots-without-its-repos.md +36 -0
  245. package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +126 -0
  246. package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +73 -0
  247. package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +227 -0
  248. package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +81 -0
  249. package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +111 -0
  250. package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +126 -0
  251. package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +107 -0
  252. package/docs/reference/decisions/0056-a-global-jr2-hands-off-to-the-instances-own-and-an-instance-has-one-kit-version.md +62 -0
  253. package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +152 -0
  254. package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +106 -0
  255. package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +384 -0
  256. package/docs/reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md +111 -0
  257. package/docs/reference/decisions/0061-a-memory-kill-ends-the-agents-processes-not-the-harness.md +83 -0
  258. package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +212 -0
  259. package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +83 -0
  260. package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +79 -0
  261. package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +65 -0
  262. 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
  263. package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +430 -0
  264. package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +464 -0
  265. package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +180 -0
  266. package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +323 -0
  267. package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +183 -0
  268. package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +144 -0
  269. package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +122 -0
  270. package/docs/reference/decisions/0074-an-unrouted-mechanism-event-is-refused-at-load-and-faults-the-run.md +76 -0
  271. package/docs/reference/decisions.md +83 -0
  272. package/docs/reference/glossary.md +648 -0
  273. package/docs/reference/http-api.md +1348 -0
  274. package/docs/reference/machines.md +190 -0
  275. package/docs/reference/mechanism-events.md +72 -0
  276. package/docs/why.md +206 -0
  277. package/package.json +5 -3
  278. package/src/actor.ts +541 -79
  279. package/src/agent.ts +114 -38
  280. package/src/ambient.ts +2 -1
  281. package/src/assembly-checks.ts +189 -7
  282. package/src/cause.ts +234 -0
  283. package/src/chart.ts +169 -37
  284. package/src/charts.ts +34 -6
  285. package/src/config.ts +430 -178
  286. package/src/custodian.ts +74 -22
  287. package/src/customize.ts +188 -46
  288. package/src/dispatch-effect.ts +945 -0
  289. package/src/door-compat.ts +217 -0
  290. package/src/durability.ts +11 -4
  291. package/src/effect.ts +341 -44
  292. package/src/effector-wire.ts +160 -11
  293. package/src/fail.ts +209 -0
  294. package/src/harness-client.ts +541 -47
  295. package/src/http-effect.ts +495 -53
  296. package/src/http.ts +427 -16
  297. package/src/index.ts +60 -82
  298. package/src/instance.ts +68 -8
  299. package/src/internal.ts +84 -0
  300. package/src/machine-doc.ts +21 -3
  301. package/src/mechanism-routes.ts +168 -0
  302. package/src/model-keys.generated.ts +53 -0
  303. package/src/model-keys.ts +18 -58
  304. package/src/notices.ts +66 -13
  305. package/src/open-body.ts +159 -23
  306. package/src/open-effect.ts +81 -8
  307. package/src/open.ts +59 -6
  308. package/src/parts.ts +184 -13
  309. package/src/party.ts +68 -2
  310. package/src/pick.ts +463 -11
  311. package/src/pool.ts +247 -36
  312. package/src/registration.ts +83 -4
  313. package/src/repos.ts +2 -1
  314. package/src/run-host.ts +565 -31
  315. package/src/run-output.ts +38 -0
  316. package/src/sandbox-effect.ts +273 -38
  317. package/src/sandbox-kube.ts +3 -1
  318. package/src/secret-placement.ts +52 -17
  319. package/src/server.ts +3 -0
  320. package/src/setup.ts +239 -56
  321. package/src/size.ts +121 -9
  322. package/src/snapshot-store.ts +54 -10
  323. package/src/stub-harness.ts +44 -16
  324. package/src/timers.ts +14 -1
  325. package/src/vocabulary.ts +69 -14
  326. package/src/wire.ts +90 -16
  327. package/src/workspace.ts +697 -175
@@ -0,0 +1,176 @@
1
+ ---
2
+ title: Mirror the Kit images
3
+ description: Copy the Kit images and the Pinned image into your own registry, and make the cluster pull them from there.
4
+ ---
5
+
6
+ # Mirror the Kit images
7
+
8
+ Copy the Kit images and the Pinned image into your own registry, and make the cluster pull them from there.
9
+
10
+ An installed Kit builds none of its own images. The nodes pull the three
11
+ [Kit images](../reference/glossary.md#kit-image), `jr2-harness`, `jr2-operator` and `jr2-orchestrator`, from
12
+ `ghcr.io/snapwich`. They pull the [Pinned image](../reference/glossary.md#pinned-image), the Envoy image of the
13
+ [Custodian](../reference/glossary.md#custodian), from `docker.io`. Mirror these four images when the nodes cannot reach
14
+ those registries, or when the cluster pulls from one registry only.
15
+
16
+ `jr2 up` also checks each model that an [Agent](../reference/glossary.md#agent) names, from a pod in the cluster. That
17
+ pod uses the Harness Kit image and the Envoy image, so the nodes also pull the images of that pod from the mirror.
18
+
19
+ [`jr2 kit push`](../reference/cli.md#kit-push) copies the images. [`kitRegistry`](../reference/config.md#kitregistry)
20
+ tells `jr2 up` where the nodes pull them from:
21
+
22
+ ```ts
23
+ import { defineConfig } from "@jr2/orchestrator";
24
+
25
+ export default defineConfig({
26
+ git: {
27
+ credentials: [{ match: "*", token: "JR2_GIT_TOKEN", sshKey: "jr2-git-ssh" }],
28
+ },
29
+ // The registry that holds the copy of the Kit images, such as registry.example.com/jr2.
30
+ // When JR2_KIT_REGISTRY is not set, the cluster pulls them from ghcr.io/snapwich.
31
+ kitRegistry: process.env.JR2_KIT_REGISTRY,
32
+ });
33
+ ```
34
+
35
+ ## Before you start
36
+
37
+ - An [Instance](../reference/glossary.md#instance), with its dependencies installed at the
38
+ [Kit version](../reference/glossary.md#kit-version) that you want to mirror.
39
+ - Docker with Buildx on your computer. `jr2 kit push` uses `docker buildx imagetools`.
40
+ - A registry that you can push to, and that the nodes can pull from. Log in to it with `docker login`. In the commands
41
+ on this page, `<registry>` is the registry and its path, such as `registry.example.com/jr2`.
42
+ - Your computer can pull from `ghcr.io` and `docker.io`.
43
+
44
+ ## Copy the images
45
+
46
+ Run `jr2 kit push` in the Instance folder:
47
+
48
+ ```sh
49
+ jr2 kit push <registry>
50
+ ```
51
+
52
+ ```text
53
+ …
54
+ jr2 kit push — mirroring the v<version> kit images to <registry>
55
+ harness: copied ghcr.io/snapwich/jr2-harness:<version> → <registry>/jr2-harness:<version>
56
+ operator: copied ghcr.io/snapwich/jr2-operator:<version> → <registry>/jr2-operator:<version>
57
+ orchestrator: copied ghcr.io/snapwich/jr2-orchestrator:<version> → <registry>/jr2-orchestrator:<version>
58
+ custodian: copied docker.io/envoyproxy/envoy:<tag>@<digest> → <registry>/envoy:<tag>@<digest>
59
+ mirrored 4 image(s), 0 already present
60
+ {"registry":"<registry>","version":"<version>","images":{"harness":"<registry>/jr2-harness:<version>","operator":"<registry>/jr2-operator:<version>","orchestrator":"<registry>/jr2-orchestrator:<version>","custodian":"<registry>/envoy:<tag>@<digest>"}}
61
+ ```
62
+
63
+ `<version>` is the Kit version. `<tag>` and `<digest>` are the tag and the digest of the Envoy image that this Kit
64
+ version pins. The first line (`…`) is the `.env` line, when `.env` sets a variable that your shell does not set. The
65
+ last line is on stdout. The other lines are on stderr.
66
+
67
+ `jr2 kit push` copies the images from registry to registry. It copies each platform of an image, with the same digests,
68
+ and it does not put the images on your computer.
69
+
70
+ `jr2 kit push` does not read the Instance. In the Instance folder, the global `jr2` runs the Instance's own `@jr2/cli`
71
+ ([Handoff](../reference/glossary.md#handoff)), so the command copies the images of the Instance's Kit version. Outside
72
+ an Instance, it copies the images of the version of your global `jr2`.
73
+
74
+ A version tag of jr2 never moves to different content. Thus `jr2 kit push` does not copy an image that is in the
75
+ registry already. You can run it again at any time:
76
+
77
+ ```text
78
+ …
79
+ jr2 kit push — mirroring the v<version> kit images to <registry>
80
+ harness: already present — <registry>/jr2-harness:<version>
81
+ operator: already present — <registry>/jr2-operator:<version>
82
+ orchestrator: already present — <registry>/jr2-orchestrator:<version>
83
+ custodian: already present — <registry>/envoy:<tag>@<digest>
84
+ mirrored 0 image(s), 4 already present
85
+ …
86
+ ```
87
+
88
+ ## Pull from the mirror
89
+
90
+ Set `kitRegistry` in `jr2.config.ts`, as in the example. The example reads it from `.env`. Add this line to `.env`:
91
+
92
+ ```text
93
+ JR2_KIT_REGISTRY=<registry>
94
+ ```
95
+
96
+ Give `kitRegistry` the same value that you gave `jr2 kit push`, with no `/` at the end. The nodes then pull
97
+ `<registry>/jr2-harness:<version>`, `<registry>/jr2-operator:<version>`, `<registry>/jr2-orchestrator:<version>` and
98
+ `<registry>/envoy:<tag>@<digest>`.
99
+
100
+ `jr2 version --local` shows where the Kit images come from:
101
+
102
+ ```sh
103
+ jr2 version --local
104
+ ```
105
+
106
+ ```text
107
+ → .env: JR2_KIT_REGISTRY, …
108
+ cli: <version> <instance folder>/node_modules/@jr2/cli
109
+ global: <global version> <global folder>
110
+ kit: <version> <instance folder>/node_modules/@jr2/orchestrator ok
111
+ instance: my-instance <instance folder> (installed kit → <registry>)
112
+ node: v24.18.0
113
+ ```
114
+
115
+ `<instance folder>` is the path of your Instance folder. `<global version>` and `<global folder>` are the version and
116
+ the folder of your global `jr2`, which runs the Instance's own `@jr2/cli`. `node` gives your version of Node.js.
117
+
118
+ Then converge:
119
+
120
+ ```sh
121
+ jr2 up
122
+ ```
123
+
124
+ ```text
125
+ …
126
+ images: installed kit — the published v<version> Harness, operator and Orchestrator, pulled from <registry> (kitRegistry)
127
+ custodian image: <registry>/envoy:<tag>@<digest> (pinned, deployed — never built)
128
+ …
129
+ converged — `jr2 run <workflow>` when ready
130
+ ```
131
+
132
+ ## Mirror each new Kit version
133
+
134
+ The mirror holds the images of the versions that you copied, and no others. `jr2 up` never pushes to `kitRegistry`.
135
+ Thus, when you upgrade the Kit version, run `jr2 kit push <registry>` again before `jr2 up`. Run it in the Instance
136
+ folder after you install the new version. See [Upgrade the Kit version](upgrade-the-kit-version.md).
137
+
138
+ One mirror can serve each Instance on the cluster, and each cluster of your organization. It can hold the images of more
139
+ than one Kit version.
140
+
141
+ `kitRegistry` is not `registry`. [`registry`](../reference/config.md#registry) is where `jr2 up` pushes the images that
142
+ it builds. `kitRegistry` is where the nodes pull the Kit images and the Pinned image. You can set one, the other, or
143
+ both.
144
+
145
+ jr2 sets no image pull secret on its pods. The nodes must pull from the mirror with no pull secret.
146
+
147
+ ## Rules
148
+
149
+ - `jr2 kit push` needs the registry:
150
+
151
+ ```text
152
+ jr2 kit push: no target registry
153
+ usage: jr2 kit push <registry>
154
+ …
155
+ ```
156
+
157
+ It exits with code 2.
158
+
159
+ - `push` is the only subcommand of `jr2 kit`. `jr2 kit` refuses any other word with `unknown kit subcommand: <word>`,
160
+ and exits with code 2. With no word, it prints `jr2 kit: no subcommand`, and exits with code 2.
161
+ - When the image is not at its published place, `jr2 kit push` stops:
162
+ `error: <image>: <source> is not there, so nothing can be mirrored to <target>`. `<image>` is `harness`, `operator`,
163
+ `orchestrator` or `custodian`. `<source>` is its published reference, and `<target>` is its reference in the mirror.
164
+ The next lines of the error say why. Check that `<version>` is a released Kit version.
165
+ - When a copy fails, `jr2 kit push` stops, and exits with code 1. It gives
166
+ `error: Command failed: docker buildx imagetools create -t <target> <source>`, then the lines of Docker. Check that
167
+ `docker login` has logged you in to the registry, and that the registry is reachable.
168
+
169
+ ## Read next
170
+
171
+ - [Converge](../concepts/converge.md)
172
+ - [ADR-0044](../reference/decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md): the canonical
173
+ place of the Kit images, and the mirror.
174
+ - [ADR-0059](../reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md): the Custodian
175
+ and its Envoy image.
176
+ - [Move from kind to a shared cluster](move-from-kind-to-a-shared-cluster.md)
@@ -0,0 +1,302 @@
1
+ ---
2
+ title: Move from kind to a shared cluster
3
+ description: Converge an Instance into a shared cluster, with a registry, Sandbox nodes, priority classes and a quota.
4
+ ---
5
+
6
+ # Move from kind to a shared cluster
7
+
8
+ Converge your [Instance](../reference/glossary.md#instance) into a shared Kubernetes cluster, after it runs on kind.
9
+
10
+ The [Workflows](../reference/glossary.md#workflow) of the Instance do not change. [`jr2 up`](../reference/cli.md#up)
11
+ converges into the cluster of the kubectl context, so you give it a different context. A shared cluster also needs some
12
+ facts that kind does not need. These facts are a registry for the images, the platforms of the nodes, the nodes for the
13
+ [Sandboxes](../reference/glossary.md#sandbox), and the priority classes. This `jr2.config.ts` gives all of them:
14
+
15
+ ```ts
16
+ import { defineConfig } from "@jr2/orchestrator";
17
+
18
+ export default defineConfig({
19
+ git: {
20
+ credentials: [{ match: "*", token: "JR2_GIT_TOKEN", sshKey: "jr2-git-ssh" }],
21
+ },
22
+ // Where jr2 up pushes the images that it builds, such as registry.example.com/team.
23
+ registry: process.env.JR2_REGISTRY,
24
+ // The platforms to build for, such as linux/arm64. When JR2_PLATFORMS is not set, jr2 up reads them from the nodes.
25
+ platforms: process.env.JR2_PLATFORMS?.split(","),
26
+ // The Sandboxes run only on the nodes of the agents pool. Its nodes have the taint pool=agents:NoSchedule.
27
+ sandbox: {
28
+ nodeSelector: { pool: "agents" },
29
+ tolerations: [{ key: "pool", operator: "Equal", value: "agents", effect: "NoSchedule" }],
30
+ },
31
+ // The PriorityClasses of the cluster. jr2 up creates none for a key that you set here.
32
+ priorityClasses: { control: "platform-critical", sandbox: "batch-low" },
33
+ });
34
+ ```
35
+
36
+ Add the fields to your own `jr2.config.ts`. Keep the fields that it has, such as `secrets` or `harness`. Each section
37
+ below explains one field. Set only the fields that your cluster needs.
38
+
39
+ ## Before you start
40
+
41
+ - An Instance that converges on kind. See [Iterate on a Machine on kind](iterate-on-a-machine-on-kind.md).
42
+ - A kubectl context for the shared cluster. In the commands on this page, `<context>` is its name.
43
+ - An image registry that you can push to from your computer, and that the nodes can pull from. In the commands on this
44
+ page, `<registry>` is its prefix, such as `registry.example.com/team`.
45
+ - Docker on your computer, logged in to the registry with `docker login`.
46
+
47
+ ## Check the cluster
48
+
49
+ `jr2 up` checks the cluster before it applies the Instance. The cluster must have these properties:
50
+
51
+ - Kubernetes 1.35 or later. Each Sandbox mounts the runtime of jr2 as an image volume.
52
+ - Pod-level resources. A [Workspace](../reference/glossary.md#workspace) reserves its whole
53
+ [Size](../reference/glossary.md#size) as one pod-level limit. The `PodLevelResources` feature gate must be on in the
54
+ API server and in the kubelets.
55
+ - A container runtime that mounts image volumes, such as containerd 2.1 or later, or CRI-O 1.31 or later. `jr2 up` does
56
+ not check the runtime. With an older runtime, the first Sandbox fails, and its pod events give the cause.
57
+ - Your kubectl user can apply objects outside the namespace of the Instance. `jr2 up` applies the operator in the
58
+ `jr2-system` namespace, with its CustomResourceDefinitions, ClusterRoles and ClusterRoleBindings. It also applies two
59
+ PriorityClasses, unless you name your own.
60
+
61
+ All the Instances on a cluster share one operator. `jr2 up` does not downgrade it. See
62
+ [Converge](../concepts/converge.md#kit-version-and-handoff).
63
+
64
+ ## Set the registry
65
+
66
+ On kind, `jr2 up` loads each image that it builds into the nodes with `kind load`. A shared cluster is not kind, so
67
+ `jr2 up` pushes each image to [`registry`](../reference/config.md#registry), and the nodes pull it from there. These are
68
+ the [Sandbox Images](../reference/glossary.md#sandbox-image) that `jr2 up` builds: `images/default` and each `file:`
69
+ URL. When no registered Machine makes a [Sandbox](../reference/glossary.md#sandbox), `jr2 up` builds no image, and the
70
+ Instance needs no `registry`.
71
+
72
+ The example reads `registry` from `JR2_REGISTRY`. Put this line in `.env`:
73
+
74
+ ```text
75
+ JR2_REGISTRY=<registry>
76
+ ```
77
+
78
+ `jr2 up` reads `.env`. A variable of the shell wins over `.env`.
79
+
80
+ When `registry` is set, `jr2 up` pushes to it on kind too. To converge into kind again, remove `JR2_REGISTRY` from
81
+ `.env`, or set it only in the shell for the shared cluster.
82
+
83
+ jr2 sets no image pull secret on its pods. The nodes must pull from the registry with no pull secret, for example with
84
+ credentials on the nodes or with anonymous pulls.
85
+
86
+ The [Kit images](../reference/glossary.md#kit-image) do not go to `registry`. The image of the
87
+ [Orchestrator](../reference/glossary.md#orchestrator) is one of them. The nodes pull them from `ghcr.io/snapwich`, and
88
+ the Envoy image of the [Custodian](../reference/glossary.md#custodian) from `docker.io`. When the nodes cannot reach
89
+ those registries, see [Mirror the Kit images](mirror-the-kit-images.md).
90
+
91
+ `jr2 up` also checks each model that an [Agent](../reference/glossary.md#agent) names, from a pod in the cluster. That
92
+ pod uses the Harness Kit image and the Envoy image of the Custodian, so it needs no other image.
93
+
94
+ ## Choose the platforms
95
+
96
+ `jr2 up` builds each image for the platforms of the nodes. It reads the architecture of each node on which a pod can
97
+ run, and of each [Sandbox node](../reference/glossary.md#sandbox-node). jr2 releases its images for `linux/amd64` and
98
+ `linux/arm64` only. `jr2 up` skips a node of a different architecture, and tells you. This output is from a cluster with
99
+ one `amd64` node and one `s390x` node:
100
+
101
+ ```text
102
+ platforms: linux/amd64 (from 2 schedulable node(s))
103
+ skipping node arch s390x — the kit publishes no Kit image for it, so no pod there could run
104
+ ```
105
+
106
+ When the cluster has nodes of the two architectures, `jr2 up` builds each image for both, and pushes it as one manifest
107
+ list. This needs `registry`.
108
+
109
+ Set [`platforms`](../reference/config.md#platforms) when the nodes do not give the correct set:
110
+
111
+ - A node group that scales up from zero has no node to read yet.
112
+ - A node group that needs no image, such as an amd64 GPU group beside arm64 nodes, adds a platform that you do not want.
113
+
114
+ `platforms` replaces the set that `jr2 up` reads from the nodes. It does not add to that set. The example reads it from
115
+ `JR2_PLATFORMS`, as a list with commas, such as `JR2_PLATFORMS=linux/arm64`.
116
+
117
+ When you set `platforms`, `jr2 up` does not read the nodes. Thus it also does not check the Sandbox nodes or the Size.
118
+ See [Choose the Sandbox nodes](#choose-the-sandbox-nodes).
119
+
120
+ When a platform is not the platform of your computer, Docker emulates it with QEMU. `jr2 up` stops before the build when
121
+ your computer cannot do this, and gives the command that installs QEMU.
122
+
123
+ ## Choose the Sandbox nodes
124
+
125
+ By default, a Sandbox runs on each node on which an ordinary pod can run. That is a node that is not cordoned and has no
126
+ `NoSchedule` or `NoExecute` taint. You do not add a label for jr2.
127
+
128
+ To put the Sandboxes on a node pool of their own, set [`sandbox`](../reference/config.md#sandbox).
129
+ [`sandbox.nodeSelector`](../reference/config.md#sandbox-nodeselector) gives the labels that a Sandbox node must have.
130
+ [`sandbox.tolerations`](../reference/config.md#sandbox-tolerations) gives the taints that a Sandbox tolerates. Both have
131
+ the shapes of the Kubernetes pod spec. The Repo cache runs on the same nodes as the Sandboxes.
132
+
133
+ When you do not set `platforms` and a Workflow uses a Workspace, `jr2 up` gives the Sandbox nodes that it finds. In this
134
+ output, the cluster has one node, `jr2-control-plane`:
135
+
136
+ ```text
137
+ sandbox nodes: jr2-control-plane
138
+ ```
139
+
140
+ When it finds none, it gives a warning and continues. It names each node and the reason that the node is not a Sandbox
141
+ node:
142
+
143
+ ```text
144
+ warning: no Sandbox node right now — a Sandbox stays Pending until one appears:
145
+ jr2-control-plane: lacks the label pool that sandbox.nodeSelector requires
146
+ a Sandbox lands where an ordinary pod lands; to admit a tainted or labeled node, set `sandbox: { nodeSelector, tolerations }` in jr2.config.ts (raw pod-spec shapes, ADR-0052).
147
+ ```
148
+
149
+ The Repo cache runs only on the Sandbox nodes, so it has no pod either. `jr2 up` says so later in its output:
150
+ `repo cache: WARNING — rollout succeeded but no pod matched app=jr2-repo-cache (nothing verified)`.
151
+
152
+ When no Sandbox node can hold the Size of a Workspace now, `jr2 up` also gives a warning and continues. In this output,
153
+ the Workflow `hold` asks for a Size of 512Gi of memory and 64 cpus:
154
+
155
+ ```text
156
+ warning: no Sandbox node right now has the allocatable for a Size of memory 512Gi, cpu 64 (workflow "hold") — its Sandbox stays Pending until one does
157
+ ```
158
+
159
+ The Workspace stays in [Placing](../reference/glossary.md#placing) until a Sandbox node can hold its Sandbox, for
160
+ example a node that an autoscaler adds.
161
+
162
+ Write `sandbox` in `jr2.config.ts` itself. Do not read it from `process.env`. The Orchestrator reads `jr2.config.ts`
163
+ again in the cluster, where your shell and `.env` are not available.
164
+
165
+ ## Use the priority classes of the cluster
166
+
167
+ `jr2 up` creates two PriorityClasses by default. `jr2-control` is for the Orchestrator, the operator, the Repo cache and
168
+ the [Instance Effector](../reference/glossary.md#instance-effector). `jr2-sandbox` is for the Sandboxes and the
169
+ [Instance Harness](../reference/glossary.md#instance-harness). An ordinary pod cannot preempt a Sandbox, and a Sandbox
170
+ that waits for a node preempts no pod.
171
+
172
+ When the cluster has its own priority scheme, set [`priorityClasses`](../reference/config.md#priorityclasses) to the
173
+ names of its classes. `jr2 up` creates no class for a key that you set, and tells you which classes it uses:
174
+
175
+ ```text
176
+ priority: the Instance's own — control "platform-critical", sandbox "batch-low"
177
+ ```
178
+
179
+ `jr2 up` does not create a class that you name, so it must exist in the cluster. Write `priorityClasses` in
180
+ `jr2.config.ts` itself. Do not read it from `process.env`, for the same reason as `sandbox`.
181
+
182
+ > **Caution**
183
+ >
184
+ > `sandbox` and `priorityClasses` apply in each cluster that the folder converges into. Thus a folder that sets them works
185
+ > only in a cluster that has those classes and those labels. On kind, `jr2 up` fails, because Kubernetes creates no pod
186
+ > that names a class that the cluster does not have. Also, a Sandbox waits for a node with the label `pool: agents`.
187
+
188
+ ## Work under a quota
189
+
190
+ jr2 writes no ResourceQuota, and it has no limit of its own on the number of Workspaces. The owner of the cluster can
191
+ put a ResourceQuota on the namespace of the Instance. Each Sandbox requests its whole Size, so the quota counts the
192
+ whole Size of each Sandbox.
193
+
194
+ When the quota refuses the pod of a Sandbox, the Workspace waits in Placing. It does the same when no node has room. jr2
195
+ sets no time limit on this wait. `jr2 run` shows the reason, in the words of the quota. In this output, the quota
196
+ `team-quota` permits 512Mi of memory limits, and the Size asks for 1Gi:
197
+
198
+ ```text
199
+ …
200
+ → active "placing"
201
+ placing: waits for quota — pods "ws-5e817334-x-0-61ru0u" is forbidden: exceeded quota: team-quota, requested: limits.memory=1Gi, used: limits.memory=2Gi, limited: limits.memory=512Mi
202
+ ```
203
+
204
+ For a Workspace that is not the root of the Workflow, the line adds the path of the child after `placing`.
205
+
206
+ [`jr2 runs`](../reference/cli.md#runs) marks each run that has a Workspace in Placing. To see why it waits, run
207
+ `jr2 status <run id>`. `<run id>` is the run id or a prefix of it (see [run ids](../reference/cli.md#run-ids)). To limit
208
+ the time that a Workflow waits, put `after` on the state of the [Machine](../reference/glossary.md#machine) that holds
209
+ the Workspace.
210
+
211
+ ## Converge
212
+
213
+ Run `jr2 up` with the context of the shared cluster. For the first converge into a namespace, `jr2 up` asks you before
214
+ it continues. In CI, add `--yes`.
215
+
216
+ ```sh
217
+ jr2 up --context <context>
218
+ ```
219
+
220
+ ```text
221
+ → .env: JR2_REGISTRY, …
222
+ jr2 up — instance "my-instance" → context <context> / namespace my-instance
223
+ typecheck: tsc --noEmit (the instance's own compiler)
224
+ …
225
+ kubernetes: v1.36.1 (floor 1.35, ADR-0037)
226
+ first contact: deploy instance "my-instance" to context <context> (create namespace "my-instance")? [y/N] y
227
+ platforms: linux/amd64 (from 1 schedulable node(s))
228
+ sandbox nodes: jr2-control-plane
229
+ images: installed kit — the published v<version> Harness, operator and Orchestrator, pulled from ghcr.io/snapwich
230
+ …
231
+ priority: the Instance's own — control "platform-critical", sandbox "batch-low"
232
+ sandbox image "default": building <registry>/jr2-sandbox-my-instance-default:6389bdf72d50-amd64
233
+ no USER declared — the pod's uid-1000 fallback applies
234
+ push → <registry>
235
+ …
236
+ assembly: publishing 6355c2bb032a (no current Assembly)
237
+ assembly: 6355c2bb032a is current — workflows: hold, ping
238
+ …
239
+ converged — `jr2 run <workflow>` when ready
240
+ ```
241
+
242
+ In this output, the cluster runs Kubernetes v1.36.1 and has one node, `jr2-control-plane`, with the label
243
+ `pool: agents`. The Workflows are `ping` and `hold`, a Workflow with a Workspace. `<version>` is the
244
+ [Kit version](../reference/glossary.md#kit-version) of the Instance. `6389bdf72d50` changes when the inputs of the image
245
+ change. `6355c2bb032a` is the hash of the [Assembly](../reference/glossary.md#assembly) of the Instance. Your version of
246
+ Kubernetes, your nodes and your hashes are different.
247
+
248
+ The other commands take the same `--context`, such as `jr2 run ping --context <context>`.
249
+
250
+ These things also change in a shared cluster:
251
+
252
+ - The pods must reach the model. A LAN address of your computer that works from kind can fail from a shared cluster. See
253
+ [Use a local model](use-a-local-model.md) and [Use a hosted provider or a gateway](use-a-hosted-provider.md).
254
+ - The cluster needs the git credentials. See [Give the cluster git credentials](give-the-cluster-git-credentials.md).
255
+ - The cluster needs your Secrets. `jr2.config.ts` can name a Secret in the namespace of the Instance, with `valueFrom`
256
+ in `secrets`, with `valueFrom` in `harness.env`, or with `harness.envFrom`. A Secret that you made on kind is not in
257
+ the shared cluster. Make each of these Secrets in the namespace of the shared cluster before you converge.
258
+
259
+ ## Rules
260
+
261
+ - On a cluster that is not kind, `jr2 up` refuses to build a Sandbox Image when you do not set `registry`. A kind
262
+ cluster is a context whose name starts with `kind-`:
263
+ ``error: context <context> is not a kind cluster and no `registry` is configured — set `registry` in jr2.config.ts (from env) so the image can be pushed (ADR-0019)``
264
+ - `jr2 up` refuses a cluster earlier than Kubernetes 1.35:
265
+ `refusing: <context> runs Kubernetes <kubernetes version>; jr2 needs Kubernetes 1.35 or newer (every Sandbox mounts jr2's runtime as an image volume, ADR-0037). Nothing was applied.`
266
+ - `jr2 up` refuses a cluster that does not keep pod-level resources:
267
+ `refusing: <context> (Kubernetes <kubernetes version>) drops pod-level resources — the PodLevelResources feature gate is off, and a Workspace's Size cannot hold (ADR-0060). Enable the gate on the API server and kubelets. The namespace was created; nothing else was applied.`
268
+ - `jr2 up` refuses a namespace that a different Instance owns:
269
+ `refusing: namespace "<namespace>" on <context> belongs to another instance ("<instance>")`. Give a different
270
+ namespace with `-n`, or a different context.
271
+ - A first converge into a namespace needs an answer. With no terminal and no `--yes`, `jr2 up` stops:
272
+ `first contact: deploy instance "<name>" to context <context> (<what>)? — not a tty; pass --yes to proceed non-interactively`
273
+ - `platforms` holds `linux/amd64` and `linux/arm64` only:
274
+ ``error: `platforms` names <platforms> — the kit releases images for linux/amd64, linux/arm64 and nothing else, so an image built for anything else could not be joined by a Kit image in the same pod. Set `platforms` in jr2.config.ts (docker platform strings, e.g. "linux/arm64") to name the set to build for.``
275
+ - When no node has a released platform, `jr2 up` refuses:
276
+ ``error: this cluster's schedulable nodes report <architectures> — the kit releases images for linux/amd64, linux/arm64 and nothing else, so an image built for anything else could not be joined by a Kit image in the same pod. Set `platforms` in jr2.config.ts (docker platform strings, e.g. "linux/arm64") to name the set to build for.``
277
+ - When your computer cannot emulate a platform of the build, `jr2 up` stops before the build:
278
+ `error: this host cannot build for <missing platforms>: a foreign architecture's RUN steps need qemu binfmt emulation, and none is registered (this builder targets <builder platforms>). Install it, then re-run:`,
279
+ then `docker run --privileged --rm tonistiigi/binfmt --install <arches>`. `<missing platforms>` are the platforms that
280
+ your builder cannot build, `<builder platforms>` are the platforms that it can build, and `<arches>` are the
281
+ architectures of the missing platforms.
282
+ - `jr2 up` refuses a Secret that `jr2.config.ts` names and that is not in the namespace. For `valueFrom` in `secrets`:
283
+ `error: secrets[<i>].valueFrom names Secret "<name>", which does not exist in the instance's namespace — create it first: kubectl create secret generic <name> --from-literal=<key>=... (ADR-0019, ADR-0059)`.
284
+ For `harness.envFrom`:
285
+ `error: harness.envFrom references Secret "<name>", which does not exist in namespace "<namespace>" — create it first: kubectl -n <namespace> create secret generic <name> --from-literal=KEY=...`.
286
+ - `priorityClasses` has the keys `control` and `sandbox` only, and each is a name that is not empty:
287
+ `error: <file> at priorityClasses<path>: <problem> — { control?, sandbox? }, each the name of an existing PriorityClass (ADR-0060)`
288
+
289
+ ## Read next
290
+
291
+ - [Converge](../concepts/converge.md)
292
+ - [Workspaces](../concepts/workspaces.md): the Size, the Sandbox nodes, and Placing.
293
+ - [ADR-0019](../reference/decisions/0019-one-converging-command-against-the-current-context.md): one command against the
294
+ current context.
295
+ - [ADR-0045](../reference/decisions/0045-the-platform-joins-the-image-address-and-the-cluster-chooses-it.md): the
296
+ platforms.
297
+ - [ADR-0052](../reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md): the
298
+ Sandbox nodes.
299
+ - [ADR-0060](../reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md): the Size and the
300
+ priority classes.
301
+ - [ADR-0064](../reference/decisions/0064-a-workspace-waits-for-capacity.md): the wait for capacity and the quota.
302
+ - [Mirror the Kit images](mirror-the-kit-images.md)
@@ -0,0 +1,91 @@
1
+ ---
2
+ title: Open the Console
3
+ description: Forward the port of the Orchestrator, open the Console, and unlock it with the Instance token.
4
+ ---
5
+
6
+ # Open the Console
7
+
8
+ Open the [Console](../reference/glossary.md#console) in a browser, and paste the Instance token to start runs and answer
9
+ [Gates](../reference/glossary.md#gate).
10
+
11
+ The [Orchestrator](../reference/glossary.md#orchestrator) serves the Console on port 4000, in the cluster. To reach it
12
+ from your computer, forward the port with `kubectl`. In the commands on this page, replace `<namespace>` with the
13
+ namespace of your [Instance](../reference/glossary.md#instance). It is the [`name`](../reference/config.md#name) in
14
+ `jr2.config.ts`. When `jr2.config.ts` sets no `name`, it is the name of the Instance folder. No `jr2` command opens the
15
+ Console.
16
+
17
+ ## Forward the port
18
+
19
+ ```sh
20
+ kubectl -n <namespace> port-forward svc/jr2-orchestrator 4000:4000
21
+ ```
22
+
23
+ ```text
24
+ Forwarding from 127.0.0.1:4000 -> 4000
25
+ Forwarding from [::1]:4000 -> 4000
26
+ ```
27
+
28
+ The command stays in the foreground. Keep it open while you use the Console. Give the other commands in a second
29
+ terminal. To use a different port on your computer, change the first number, such as `8080:4000`. For a cluster that is
30
+ not the current kubectl context, add `--context <context>`, with the name of its kubectl context.
31
+
32
+ ## Open the page in a browser
33
+
34
+ Open `http://localhost:4000` in a browser.
35
+
36
+ Without the token, the Console shows the runs, and you cannot change them:
37
+
38
+ - The Fleet rail on the left lists each [Workflow](../reference/glossary.md#workflow), with the number of its live runs.
39
+ Click the caret of a Workflow to list its runs.
40
+ - The center shows the [Machine](../reference/glossary.md#machine) of the Workflow that you select. When you select a
41
+ run, the Console shows the states that the run is in.
42
+ - The Activity tab of the right drawer lists the type of each [Emit](../reference/glossary.md#emit) of the runs of the
43
+ Workflow, the newest first.
44
+
45
+ The address shows the Workflow that you select. Open `http://localhost:4000/workflows/<workflow>` to go to one Workflow
46
+ directly. Replace `<workflow>` with its name, such as `ping`.
47
+
48
+ ## Get the Instance token
49
+
50
+ `jr2 up` makes the [Instance token](../concepts/secrets-and-trust.md#the-tokens) when it first converges the Instance,
51
+ and keeps it after that. It is in the Kubernetes Secret `jr2-instance`:
52
+
53
+ ```sh
54
+ kubectl -n <namespace> get secret jr2-instance -o jsonpath='{.data.JR2_INSTANCE_TOKEN}' | base64 -d
55
+ ```
56
+
57
+ The command prints the token, with no line break after it.
58
+
59
+ > **Caution**
60
+ >
61
+ > The Instance token starts runs, answers Gates and cancels runs. Keep it as you keep a password.
62
+
63
+ ## Paste the token
64
+
65
+ Paste the token into the box `instance token` in the nav of the Console. Push Enter. The badge after the box shows `…`
66
+ while the Console checks the token, then `live`. With a live token, the Console shows more:
67
+
68
+ - A `start` button for each Workflow in the Fleet rail. It opens a form for the run input of the Workflow. A Workflow
69
+ that declares no run input gets a box for JSON.
70
+ - The Attention tab of the right drawer. It shows a card for each open Gate of the selected Workflow, with a form to
71
+ send each event that the Gate takes. Select `all workflows` to see the Gates of each Workflow.
72
+
73
+ The Console keeps the token in the browser tab. A reload keeps it. When you close the tab, the token is gone.
74
+
75
+ ## Rules
76
+
77
+ - A token that the Orchestrator does not accept reads `invalid`. The Console then shows no `start` button and no
78
+ Attention tab.
79
+ - When the Orchestrator refuses the token later, with the status 401, the Console goes back to view only.
80
+ - Only the Instance token unlocks the Console. A [Sandbox](../reference/glossary.md#sandbox) token reads `invalid`.
81
+ - The port forward stops when you stop its command, or when the Orchestrator pod restarts. Then run the command again.
82
+
83
+ ## Read next
84
+
85
+ - [Architecture](../concepts/architecture.md)
86
+ - [ADR-0032](../reference/decisions/0032-the-console-unlocks-with-the-instance-token.md): why the token unlocks the
87
+ Console.
88
+ - [ADR-0014](../reference/decisions/0014-observation-is-open-run-state-is-not.md): what the Console shows with no token.
89
+ - [`GET /`](../reference/http-api.md#get) and the [open band](../reference/http-api.md#band-open)
90
+ - [Answer a Gate](answer-a-gate.md)
91
+ - [Start a run](start-a-run.md)