@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,381 @@
1
+ ---
2
+ title: An Agent in a Sandbox
3
+ description: A coder Agent fixes a bug in your fork of jr2, in a Sandbox. You push its branch, and approve.
4
+ ---
5
+
6
+ # An Agent in a Sandbox
7
+
8
+ At the end of this page, a coder [Agent](../reference/glossary.md#agent) has fixed a bug in your fork of jr2. The Agent
9
+ works in a [Sandbox](../reference/glossary.md#sandbox): a pod of its own, with a git checkout of your fork. You go into
10
+ the Sandbox and read the work. You ask for one more change, push the branch by hand, and approve the work.
11
+
12
+ ## Before you start
13
+
14
+ - Do [A model decides](a-model-decides.md) first. Your [Instance](../reference/glossary.md#instance) `my-instance` has
15
+ the model of your tab, and `kind-jr2` is the current kubectl context.
16
+ - You need a GitHub account.
17
+ - Open two terminals in `my-instance`. The first terminal shows the run. The second terminal sends commands to it.
18
+
19
+ ## Fork jr2
20
+
21
+ The Agent works on a [Repo](../reference/glossary.md#repo) that you can push to, so you fork jr2. Your fork holds the
22
+ tutorial fixture, `docs/site/tutorial/greet/`. It is a small Node CLI with one bug, and its test `trims the name` fails.
23
+
24
+ 1. Open `https://github.com/snapwich/jr2`.
25
+ 2. Click **Fork**.
26
+ 3. Clear **Copy the main branch only**, so that the fork gets the release tags.
27
+ 4. Click **Create fork**.
28
+
29
+ Make sure that the fork has the release tag of your Kit. `<you>` is your GitHub user name. `<version>` is the
30
+ [Kit version](../reference/glossary.md#kit-version): the version of `@jr2/orchestrator` in `package.json`, such as
31
+ `0.4.1`.
32
+
33
+ 1. Open `https://github.com/<you>/jr2/tags`.
34
+ 2. Find the tag `v<version>`, such as `v0.4.1`.
35
+
36
+ If the page shows no tags, delete the fork. Fork again with **Copy the main branch only** cleared.
37
+
38
+ ## Make a token for the fork
39
+
40
+ The Agent cannot push. You push its branch by hand, so you need a token for your fork. On GitHub, make a fine-grained
41
+ personal access token:
42
+
43
+ 1. Click your profile picture, then **Settings**.
44
+ 2. Click **Developer settings**, then **Personal access tokens**, then **Fine-grained tokens**.
45
+ 3. Click **Generate new token**.
46
+ 4. In **Repository access**, select **Only select repositories**.
47
+ 5. Select `<you>/jr2`.
48
+ 6. In **Permissions**, set **Contents** to **Read and write**.
49
+ 7. Click **Generate token**.
50
+ 8. Copy the token.
51
+
52
+ Keep the token in a safe place. You use it on this page and on the next page.
53
+
54
+ ## Install @jr2/machines
55
+
56
+ The Kit ships [Machines](../reference/glossary.md#machine) in the package `@jr2/machines`. Install it at the Kit
57
+ version:
58
+
59
+ ```sh
60
+ npm install --save-exact @jr2/machines@<version>
61
+ ```
62
+
63
+ ```text
64
+
65
+ added 1 package, and audited 15 packages in 266ms
66
+
67
+ 3 packages are looking for funding
68
+ run `npm fund` for details
69
+
70
+ found 0 vulnerabilities
71
+ ```
72
+
73
+ Your numbers can be different.
74
+
75
+ ## Write the Workflow
76
+
77
+ The shipped Machine [`task`](../reference/machines.md#task) gives one prompt to a coder Agent in a
78
+ [Workspace](../reference/glossary.md#workspace). Then the run waits at a [Gate](../reference/glossary.md#gate) named
79
+ `review`, until you approve the work. `task` puts the `review` Gate in its body, so the id of the Gate is `body.review`.
80
+
81
+ `task` cannot know your Repo, and it cannot pay for your model. Thus it leaves two parts
82
+ [Open](../reference/glossary.md#open): its [Repo Slots](../reference/glossary.md#repo-slot) and the model of its coder.
83
+ You bind the two with [`customize()`](../reference/authoring-surface/customize.md).
84
+
85
+ Make the file `workflows/task.ts`. Replace `<you>` and `<version>` in it:
86
+
87
+ **Anthropic**
88
+
89
+ ```ts
90
+ import { customize } from "@jr2/orchestrator";
91
+ import { task } from "@jr2/machines";
92
+
93
+ // `task` leaves two parts Open: its Repo Slots and the model of its coder. This file binds the two.
94
+ // The file name gives the Workflow its name: task.
95
+ export const machine = customize(task, {
96
+ // One Repo Slot, target: your fork, from the release tag of the Kit that you installed.
97
+ // Replace <you> with your GitHub user name. Replace <version> with the Kit version.
98
+ repos: { target: { url: "https://github.com/<you>/jr2.git", ref: "v<version>" } },
99
+ // The model that the coder Agent uses.
100
+ agents: { coder: { model: "anthropic/claude-haiku-5-5" } },
101
+ });
102
+ ```
103
+
104
+ **Local**
105
+
106
+ ```ts
107
+ import { customize } from "@jr2/orchestrator";
108
+ import { task } from "@jr2/machines";
109
+
110
+ // `task` leaves two parts Open: its Repo Slots and the model of its coder. This file binds the two.
111
+ // The file name gives the Workflow its name: task.
112
+ export const machine = customize(task, {
113
+ // One Repo Slot, target: your fork, from the release tag of the Kit that you installed.
114
+ // Replace <you> with your GitHub user name. Replace <version> with the Kit version.
115
+ repos: { target: { url: "https://github.com/<you>/jr2.git", ref: "v<version>" } },
116
+ // The model that the coder Agent uses.
117
+ agents: { coder: { model: "local/qwen3.6-35b-a3b" } },
118
+ });
119
+ ```
120
+
121
+ - `target` is the name of the Repo Slot. The coder works in the first Repo Slot.
122
+ - `ref` is the release tag. The branch of the Agent starts from it, so each reader of a release starts from the same
123
+ fixture.
124
+ - The file name gives the [Workflow](../reference/glossary.md#workflow) its name: `task`.
125
+
126
+ ## Converge the Instance
127
+
128
+ [`jr2 up`](../reference/cli.md#up) converges the Instance with the new Workflow:
129
+
130
+ ```sh
131
+ jr2 up
132
+ ```
133
+
134
+ ```text
135
+ …
136
+ seats: workflow "task" — who may send what, per state (ADR-0015)
137
+ task.working agent:coder: [finish]
138
+ task.review gate: [approve, request_changes]
139
+ …
140
+ sandbox image "default": building jr2-sandbox-my-instance-default:6389bdf72d50-amd64
141
+ no USER declared — the pod's uid-1000 fallback applies
142
+ kind load → cluster "jr2"
143
+ …
144
+ repos: 1 bound Repo(s) — the Orchestrator creates their Repo resources at boot and at each publish (ADR-0069); the cache agent clones on first need (`jr2 status` reports sync state)
145
+ converged — `jr2 run <workflow>` when ready
146
+ ```
147
+
148
+ `task` is the first Workflow of the Instance that has a Workspace. Thus this `jr2 up` also builds the
149
+ [Sandbox Image](../reference/glossary.md#sandbox-image) from `images/default/Dockerfile`, and loads it into the kind
150
+ cluster. If you did not bind an Open part, `jr2 up` stops and prints the `customize()` line that binds it.
151
+
152
+ ## Start the run
153
+
154
+ In the first terminal, start a run of `task` with [`jr2 run`](../reference/cli.md#run). The prompt tells the Agent what
155
+ to fix and how to check the fix:
156
+
157
+ ```sh
158
+ jr2 run task --input '{"prompt":"In docs/site/tutorial/greet, one test fails. Fix the bug in docs/site/tutorial/greet/src/greet.js. To check your fix, run node --test in docs/site/tutorial/greet. Do not change files outside that folder. Do not run the tests of the repo root."}'
159
+ ```
160
+
161
+ ```text
162
+ …
163
+ → context kind-jr2 / namespace my-instance
164
+ run a7a8fc26-851f-4459-9efb-845389acfda9 (task) — attached
165
+ → active "placing"
166
+ → active "provisioning"
167
+ → active "attaching"
168
+ → active "running"
169
+ …
170
+ ```
171
+
172
+ The line `run <run id> (task) — attached` gives the run id. Your run id is different. As on the last page, the first
173
+ line of the output, `→ .env:`, shows as `…`. Keep this terminal open. The run does not end until you approve the work.
174
+
175
+ ## Wait for the review Gate
176
+
177
+ The Sandbox starts, and the coder works. When the coder finishes, the run waits at the `review` Gate. In the second
178
+ terminal, read the status of the run with [`jr2 status`](../reference/cli.md#status). `<run id>` is the run id, or its
179
+ first 4 characters or more:
180
+
181
+ ```sh
182
+ jr2 status <run id>
183
+ ```
184
+
185
+ The status is one line of JSON. While the coder works, `gates` is `[]`. When the run waits at `review`, `gates` holds
186
+ the Gate. Its `gate` is `body.review`, and the line ends with its `meta`:
187
+
188
+ ```text
189
+ …"gate":"body.review",…,"meta":{"summary":"Fixed the \"trims the name\" test failure in docs/site/tutorial/greet. The bug was that the name wasn't being trimmed before constructing the greeting output. Added `.trim()` to the name extraction in src/greet.js, changing `args.find(...) ?? \"world\"` to `(args.find(...) ?? \"world\").trim()`. All 6 tests now pass.","branch":"jr2/task-d8f59a0c-9ea1-43fc-8d0c-b153caf70f16","worktree":"/work/target/jr2-task-d8f59a0c-9ea1-43fc-8d0c-b153caf70f16"}}]}
190
+ ```
191
+
192
+ Run the command again until `gates` holds the Gate.
193
+
194
+ - `summary` is what the coder says that it did, in the words of the model. Your summary is different.
195
+ - `branch` is the branch that the coder commits on.
196
+ - `worktree` is the folder in the Sandbox that holds the branch. It is
197
+ [the Worktree](../reference/glossary.md#worktree).
198
+
199
+ Copy `branch` and `worktree` from your output. The part after `jr2/task-`, here `d8f59a0c-9ea1-43fc-8d0c-b153caf70f16`,
200
+ is the [Instance ID](../reference/glossary.md#instance-id) of the run. `jr2 status` prints it as `instanceId`. It is not
201
+ the run id. Do not make the branch name from the run id. With the Instance token, the drawer of the
202
+ [Console](../reference/glossary.md#console) shows the same `meta`.
203
+
204
+ If `meta` has a `reason` and no `summary`, the [Turn](../reference/glossary.md#turn) of the coder failed. Send
205
+ `request_changes`, as in [Ask for a change](#ask-for-a-change), and the coder tries again.
206
+
207
+ ## Find the Sandbox
208
+
209
+ The label `jr2.dev/run` on the Sandbox holds the full run id. A prefix does not work here. Copy the full run id from the
210
+ line `run <run id> (task) — attached` in the first terminal:
211
+
212
+ ```sh
213
+ kubectl -n my-instance get sandboxes -l jr2.dev/run=<run id>
214
+ ```
215
+
216
+ ```text
217
+ NAME PHASE ENDPOINT AGE
218
+ ws-a7a8fc26-x-38-oakg23 Ready http://ws-a7a8fc26-x-38-oakg23.my-instance.svc:8080 5m10s
219
+ ```
220
+
221
+ `ws-a7a8fc26-x-38-oakg23` is the name of the Sandbox. Your Sandbox has a different name. It starts with `ws-` and the
222
+ first 8 characters of the run id. The pod of the Sandbox has the same name. The commands below write it as `<sandbox>`.
223
+
224
+ ## Look inside the Sandbox
225
+
226
+ Go into the `harness` container of the pod. The Agent's tools run in this container:
227
+
228
+ ```sh
229
+ kubectl -n my-instance exec -it <sandbox> -c harness -- bash
230
+ ```
231
+
232
+ In the Sandbox, go to the fixture in the Worktree. Then run its tests. `<worktree>` is the `worktree` that you copied:
233
+
234
+ ```sh
235
+ cd <worktree>/docs/site/tutorial/greet
236
+ node --test
237
+ ```
238
+
239
+ ```text
240
+ ✔ greets the world by default (1.172165ms)
241
+ ✔ greets a name (0.138615ms)
242
+ ✔ shouts (0.117168ms)
243
+ ✔ trims the name (0.067037ms)
244
+ ✔ prints help (0.642445ms)
245
+ ✔ refuses an unknown flag (0.281559ms)
246
+ ℹ tests 6
247
+ ℹ suites 0
248
+ ℹ pass 6
249
+ ℹ fail 0
250
+ ℹ cancelled 0
251
+ ℹ skipped 0
252
+ ℹ todo 0
253
+ ℹ duration_ms 55.318206
254
+ ```
255
+
256
+ Your times are different. Read the commits of the coder. The branch starts at the release tag, so the commits after the
257
+ tag are the commits of the coder:
258
+
259
+ ```sh
260
+ git log --oneline v<version>..HEAD
261
+ ```
262
+
263
+ ```text
264
+ 1a84393 Fix: trim the name before using it in greet output
265
+ ```
266
+
267
+ Each line is one commit. The commit ids and the messages come from the model. The author of each commit is
268
+ `jr2 Agent <agent@jr2.invalid>`, the default git author that jr2 gives a Sandbox. Then leave the Sandbox:
269
+
270
+ ```sh
271
+ exit
272
+ ```
273
+
274
+ ## Ask for a change
275
+
276
+ In the second terminal, send `request_changes` to the `review` Gate with [`jr2 send`](../reference/cli.md#send).
277
+ `--gate` takes the `gate` value from `jr2 status`. Put your notes in the input:
278
+
279
+ ```sh
280
+ jr2 send <run id> --gate body.review --event request_changes --input '{"notes":"Also add a test that trims the name when you pass --shout."}'
281
+ ```
282
+
283
+ ```text
284
+ …
285
+ → context kind-jr2 / namespace my-instance
286
+ delivered request_changes to gate "body.review" on a7a8fc26-851f-4459-9efb-845389acfda9
287
+ ```
288
+
289
+ The coder continues the same conversation, with your notes as its next prompt. The Sandbox and the branch stay. Run
290
+ `jr2 status <run id>` again until `gates` holds the `review` Gate. The new `summary` tells what the coder changed.
291
+
292
+ ## Push the branch
293
+
294
+ `task` does not push, and the Agent has no credential to push with. While the run waits at `review`, you push the branch
295
+ from the Sandbox. Go into the Sandbox again:
296
+
297
+ ```sh
298
+ kubectl -n my-instance exec -it <sandbox> -c harness -- bash
299
+ ```
300
+
301
+ In the Sandbox, go to the Worktree. Then push the branch. `<branch>` is the `branch` that you copied:
302
+
303
+ ```sh
304
+ cd <worktree>
305
+ git push origin <branch>
306
+ ```
307
+
308
+ `git push` asks for a user name and a password. Give `<you>` as the user name. Give the token as the password.
309
+
310
+ ```text
311
+ Username for 'https://github.com': <you>
312
+ Password for 'https://<you>@github.com':
313
+ …
314
+ To https://github.com/<you>/jr2.git
315
+ * [new branch] jr2/task-d8f59a0c-9ea1-43fc-8d0c-b153caf70f16 -> jr2/task-d8f59a0c-9ea1-43fc-8d0c-b153caf70f16
316
+ ```
317
+
318
+ `origin` fetches through the Repo cache of the node, and pushes to your fork. Open your fork on GitHub to see the
319
+ branch. Then leave the Sandbox:
320
+
321
+ ```sh
322
+ exit
323
+ ```
324
+
325
+ ## Approve the work
326
+
327
+ > **Caution**
328
+ >
329
+ > `approve` ends the run and removes the Sandbox. A commit that you did not push is lost.
330
+
331
+ In the second terminal, send `approve` to the `review` Gate. `approve` takes no input:
332
+
333
+ ```sh
334
+ jr2 send <run id> --gate body.review --event approve
335
+ ```
336
+
337
+ ```text
338
+ …
339
+ → context kind-jr2 / namespace my-instance
340
+ delivered approve to gate "body.review" on a7a8fc26-851f-4459-9efb-845389acfda9
341
+ ```
342
+
343
+ In the first terminal, `jr2 run` prints the end of the run, then the final status as one line of JSON, and stops:
344
+
345
+ ```text
346
+ …
347
+ → active "teardown"
348
+ → done "done"
349
+ {"runId":"a7a8fc26-851f-4459-9efb-845389acfda9","workflow":"task",…,"output":{"branch":"jr2/task-d8f59a0c-9ea1-43fc-8d0c-b153caf70f16"}}
350
+ ```
351
+
352
+ ## Make sure that the Sandbox is gone
353
+
354
+ Use the full run id again:
355
+
356
+ ```sh
357
+ kubectl -n my-instance get sandboxes -l jr2.dev/run=<run id>
358
+ ```
359
+
360
+ ```text
361
+ No resources found in my-instance namespace.
362
+ ```
363
+
364
+ ## What happened
365
+
366
+ - `task` is a Machine in a Workspace. The run made a Sandbox for the Workspace and cloned your fork into it. It cut the
367
+ branch from the release tag, in a Worktree in `/work/target/`. See [Workspaces](../concepts/workspaces.md).
368
+ - `task` left its Repo Slots and the model of its coder Open. `customize()` bound them where you registered the
369
+ Workflow, and `jr2 up` refuses a Workflow with an Open part. See [Composition](../concepts/composition.md) and
370
+ [ADR-0054](../reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md).
371
+ - The `review` Gate kept the Sandbox while the run waited. `request_changes` sent the coder back to the same
372
+ conversation. `approve` ended the run, and the end of the Workspace removed the Sandbox. See
373
+ [Gates](../concepts/gates.md) and [ADR-0012](../reference/decisions/0012-workspace-wrapper-machine.md).
374
+ - You used `kubectl exec` to go into the Sandbox. The guide [Look inside a Sandbox](../guides/look-inside-a-sandbox.md)
375
+ gives the same commands.
376
+ - You pushed by hand, because `task` does not push. On the next page, a Machine pushes the branch with an
377
+ [Effect](../reference/glossary.md#effect).
378
+
379
+ ## Next
380
+
381
+ [Have your Assistant write a Machine](have-your-assistant-write-a-machine.md)
@@ -0,0 +1,248 @@
1
+ ---
2
+ title: Connect a model
3
+ description: Add a model to the Instance, with its key or its address in .env, and converge the Instance again.
4
+ ---
5
+
6
+ # Connect a model
7
+
8
+ At the end of this page, the config of your [Instance](../reference/glossary.md#instance) names a model. `jr2.config.ts`
9
+ names its key or its endpoint, `.env` holds the value, and the cluster has the new config. The next page gives the model
10
+ its first task.
11
+
12
+ ## Before you start
13
+
14
+ Do [Create an Instance](create-an-instance.md) first. The Instance `my-instance` must be in the kind cluster.
15
+
16
+ Choose a tab. Choose Anthropic for a model of the Anthropic API. Choose Local for a model that you serve on a computer
17
+ on your network. Each page after this one uses the model of the tab that you choose.
18
+
19
+ **Anthropic**
20
+
21
+ You need an Anthropic API key. Make one on the [Anthropic website](https://console.anthropic.com/).
22
+
23
+ **Local**
24
+
25
+ You need a computer that can serve Qwen3.6-35B-A3B with a context window of 65536 tokens. It can be the computer that
26
+ runs kind, or a different one on your network. Install one of these two servers on it:
27
+
28
+ - [vLLM](https://docs.vllm.ai/en/latest/getting_started/installation/)
29
+ - [llama.cpp](https://github.com/ggml-org/llama.cpp/blob/master/docs/install.md)
30
+
31
+ ## Add the model to jr2.config.ts
32
+
33
+ **Anthropic**
34
+
35
+ Open `jr2.config.ts`. Find the line that starts with `// secrets:`. Remove the `//`. Keep the other lines and their
36
+ comments. This is the result. Its comments are shorter than the comments in your file:
37
+
38
+ ```ts
39
+ import { defineConfig } from "@jr2/orchestrator";
40
+
41
+ export default defineConfig({
42
+ git: {
43
+ // The credentials that the cluster uses to clone and push. The token comes from JR2_GIT_TOKEN in .env.
44
+ credentials: [{ match: "*", token: "JR2_GIT_TOKEN", sshKey: "jr2-git-ssh" }],
45
+ },
46
+ // The model key. jr2 up gives it only to the Custodian of each pod whose Agents use Anthropic.
47
+ secrets: [{ name: "ANTHROPIC_API_KEY", value: process.env.ANTHROPIC_API_KEY }],
48
+ });
49
+ ```
50
+
51
+ The `secrets` line gives jr2 the value of `ANTHROPIC_API_KEY` from `.env`. An [Agent](../reference/glossary.md#agent)
52
+ that names an `anthropic/` model uses this key.
53
+
54
+ **Local**
55
+
56
+ Open `jr2.config.ts`. Add the `harness` entry after the `git` entry. Keep the other lines and their comments. This is
57
+ the result. Its comments are shorter than the comments in your file:
58
+
59
+ ```ts
60
+ import { defineConfig } from "@jr2/orchestrator";
61
+
62
+ export default defineConfig({
63
+ git: {
64
+ // The credentials that the cluster uses to clone and push. The token comes from JR2_GIT_TOKEN in .env.
65
+ credentials: [{ match: "*", token: "JR2_GIT_TOKEN", sshKey: "jr2-git-ssh" }],
66
+ },
67
+ harness: {
68
+ // An OpenAI-compatible endpoint, such as vLLM or llama.cpp. An Agent names its model as local/<model>.
69
+ provider: {
70
+ id: "local",
71
+ api: "openai-completions",
72
+ // An address that a pod can reach, from .env. With no apiKey, plain http:// is permitted.
73
+ baseUrl: process.env.LOCAL_MODEL_URL ?? "",
74
+ // The key is the name that the endpoint gives for GET /v1/models. The limits agree with the server.
75
+ models: { "qwen3.6-35b-a3b": { contextWindow: 65536, maxTokens: 8192 } },
76
+ },
77
+ },
78
+ });
79
+ ```
80
+
81
+ The entry adds a custom provider with the id `local`. An [Agent](../reference/glossary.md#agent) names a model of this
82
+ provider as `local/<model>`, such as `local/qwen3.6-35b-a3b`. `<model>` is the name that the endpoint gives for
83
+ `GET /v1/models`.
84
+
85
+ The [config reference](../reference/config.md#secrets) gives each field of `secrets` and of
86
+ [`harness.provider`](../reference/config.md#harness-provider).
87
+
88
+ ## Put the value in .env
89
+
90
+ **Anthropic**
91
+
92
+ Make the file `.env` in `my-instance`. Put this line in it, with your key in place of `<your key>`:
93
+
94
+ ```text
95
+ ANTHROPIC_API_KEY=<your key>
96
+ ```
97
+
98
+ **Local**
99
+
100
+ Make the file `.env` in `my-instance`. Put this line in it:
101
+
102
+ ```text
103
+ LOCAL_MODEL_URL=http://<address>:8000/v1
104
+ ```
105
+
106
+ `<address>` is an address of the server computer that a pod can reach, such as its LAN address. Do not use `localhost`.
107
+ In a pod, `localhost` is the pod itself.
108
+
109
+ The jr2 CLI reads `.env` before each command, and names each key that it takes from `.env`. A variable that you set in
110
+ your shell has priority over `.env`. Do not put `.env` in git: the `.gitignore` that `jr2 init` wrote keeps it out.
111
+
112
+ ## Start the model server
113
+
114
+ **Anthropic**
115
+
116
+ There is no server to start. Go to the next step.
117
+
118
+ **Local**
119
+
120
+ On the server computer, start one of the two servers. Each command serves the model as `qwen3.6-35b-a3b`, on port 8000,
121
+ on all addresses (`0.0.0.0`). The pods cannot reach a server that listens only on its loopback address.
122
+
123
+ To start llama.cpp, run:
124
+
125
+ ```sh
126
+ llama-server -hf unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q6_K_XL --alias qwen3.6-35b-a3b --no-mmproj \
127
+ --host 0.0.0.0 --port 8000 --jinja -c 65536 \
128
+ --temp 0.6 --presence-penalty 1.0 -ctk q8_0 -ctv q8_0 -fa on
129
+ ```
130
+
131
+ `--jinja` lets the model call tools. `--temp 0.6` and `--presence-penalty 1.0` are the sampling settings for Qwen.
132
+ `-ctk q8_0 -ctv q8_0 -fa on` make the KV cache smaller, so that 65536 tokens fit in memory.
133
+
134
+ To start vLLM, run:
135
+
136
+ ```sh
137
+ vllm serve Qwen/Qwen3.6-35B-A3B --served-model-name qwen3.6-35b-a3b \
138
+ --host 0.0.0.0 --port 8000 --max-model-len 65536 \
139
+ --enable-auto-tool-choice --tool-call-parser qwen3_coder
140
+ ```
141
+
142
+ `--enable-auto-tool-choice` and `--tool-call-parser` let the model call tools.
143
+
144
+ With each of the two servers, the model must make tool calls. `jr2 up` asks the model for one tool call before it
145
+ converges, and stops when the model does not make one.
146
+
147
+ ## Check the model server
148
+
149
+ **Anthropic**
150
+
151
+ There is no server to check. Go to the next step.
152
+
153
+ **Local**
154
+
155
+ From the computer that runs kind, run:
156
+
157
+ ```sh
158
+ curl http://<address>:8000/v1/models
159
+ ```
160
+
161
+ The server sends a JSON object. This object is from vLLM. llama.cpp sends different fields:
162
+
163
+ ```text
164
+ {"object":"list","data":[{"id":"qwen3.6-35b-a3b","object":"model","created":1792819567,"owned_by":"vllm",…,"max_model_len":65536,…}]}
165
+ ```
166
+
167
+ The `data` list in the JSON that the server sends has the id `qwen3.6-35b-a3b`. If `curl` cannot connect, make sure that
168
+ the server listens on `0.0.0.0`. Also make sure that no firewall stops port 8000.
169
+
170
+ ## Converge the Instance again
171
+
172
+ Run:
173
+
174
+ ```sh
175
+ jr2 up
176
+ ```
177
+
178
+ `jr2 up` reads the new config and converges the cluster again. The namespace is there, so it does not ask this time.
179
+
180
+ **Anthropic**
181
+
182
+ ```text
183
+ → .env: ANTHROPIC_API_KEY
184
+ jr2 up — instance "my-instance" → context kind-jr2 / namespace my-instance
185
+ …
186
+ warning: secrets[0] (ANTHROPIC_API_KEY) is named by nothing; goes nowhere — no workspace() lists it, no Agent's provider reads it, and no Effect names it (ADR-0059, ADR-0068)
187
+ …
188
+ converged — `jr2 run <workflow>` when ready
189
+ ```
190
+
191
+ The warning is correct for now. No [Workflow](../reference/glossary.md#workflow) has an Agent that names an `anthropic/`
192
+ model, so no pod gets the key.
193
+
194
+ The next page adds a Workflow with an Agent that names the model. On the next page, `jr2 up` gives the key to the
195
+ [Custodian](../reference/glossary.md#custodian) of the pod where the Agent works. Then it asks the model for one tool
196
+ call through a Custodian that holds the key, before it converges. It is the first `jr2 up` that reaches the model.
197
+
198
+ **Local**
199
+
200
+ ```text
201
+ → .env: LOCAL_MODEL_URL
202
+ jr2 up — instance "my-instance" → context kind-jr2 / namespace my-instance
203
+ …
204
+ provider: http://<address>:8000/v1 configured, but no carried Agent names a "local/…" model — skipped
205
+ …
206
+ converged — `jr2 run <workflow>` when ready
207
+ ```
208
+
209
+ `jr2 up` skips the check of the provider for now. No [Workflow](../reference/glossary.md#workflow) has an Agent that
210
+ names a `local/` model, so there is no model to check.
211
+
212
+ The next page adds a Workflow with an Agent that names the model. On the next page, `jr2 up` checks the endpoint before
213
+ it converges. It is the first `jr2 up` that reaches the model.
214
+
215
+ `jr2 up` published the new `jr2.config.ts` to the [Orchestrator](../reference/glossary.md#orchestrator) in the
216
+ [Assembly](../reference/glossary.md#assembly). The Orchestrator loaded it with no restart, so the port forward of
217
+ [Create an Instance](create-an-instance.md) stays open.
218
+
219
+ ## What happened
220
+
221
+ **Anthropic**
222
+
223
+ The API key is a [Held secret](../reference/glossary.md#held-secret). In this Instance, `jr2 up` gives its value only to
224
+ the Custodian of each pod whose Agents use an `anthropic/` model. The Custodian is a container next to the
225
+ [Harness](../reference/glossary.md#harness) container, where the Agent works. The Harness container holds only a
226
+ [Stand-in](../reference/glossary.md#stand-in): a value that is worth nothing outside the pod. The Custodian puts the
227
+ real key into each request to the Anthropic API. Thus the Agent never holds the key
228
+ ([ADR-0059](../reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md)).
229
+
230
+ To use a gateway or a different hosted provider, read
231
+ [Use a hosted provider or a gateway](../guides/use-a-hosted-provider.md).
232
+
233
+ **Local**
234
+
235
+ `harness.provider` adds a custom provider to the [Harness](../reference/glossary.md#harness). The Harness speaks to it
236
+ over the OpenAI chat completions API
237
+ ([ADR-0018](../reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md)). When an Agent
238
+ names a `local/` model, `jr2 up` checks the endpoint from a pod in the cluster before it converges. It asks for the list
239
+ of models, and then for one tool call. If the check fails, `jr2 up` stops and says why.
240
+
241
+ This endpoint has no key, so jr2 permits plain `http://`. To add TLS and a key, read
242
+ [Use a local model](../guides/use-a-local-model.md).
243
+
244
+ [Secrets and trust](../concepts/secrets-and-trust.md) explains where each secret goes, and who can use it.
245
+
246
+ ## Next
247
+
248
+ [A model decides](a-model-decides.md).