@jr2/orchestrator 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -2
- package/console/components/app.ts +2 -0
- package/console/components/fleet.ts +14 -1
- package/console/components/machine-pane.ts +41 -2
- package/console/main.ts +13 -1
- package/console/store.ts +102 -6
- package/console/style.css +21 -0
- package/docs/agents-block.md +5 -0
- package/docs/concepts/agents-and-turns.md +478 -0
- package/docs/concepts/architecture.md +243 -0
- package/docs/concepts/charts.md +146 -0
- package/docs/concepts/composition.md +357 -0
- package/docs/concepts/converge.md +257 -0
- package/docs/concepts/durable-runs.md +189 -0
- package/docs/concepts/effects.md +658 -0
- package/docs/concepts/gates.md +208 -0
- package/docs/concepts/machines-and-workflows.md +298 -0
- package/docs/concepts/pools-and-sources.md +230 -0
- package/docs/concepts/secrets-and-trust.md +306 -0
- package/docs/concepts/the-menu.md +381 -0
- package/docs/concepts/workspaces.md +756 -0
- package/docs/get-started/a-model-decides.md +563 -0
- package/docs/get-started/an-agent-in-a-sandbox.md +383 -0
- package/docs/get-started/connect-a-model.md +248 -0
- package/docs/get-started/create-an-instance.md +194 -0
- package/docs/get-started/have-your-assistant-write-a-machine.md +993 -0
- package/docs/get-started/install.md +130 -0
- package/docs/guides/add-tools-to-the-sandbox.md +308 -0
- package/docs/guides/answer-a-gate.md +304 -0
- package/docs/guides/bind-open-parts.md +224 -0
- package/docs/guides/cancel-a-run.md +146 -0
- package/docs/guides/clean-up.md +206 -0
- package/docs/guides/cut-a-worktree.md +560 -0
- package/docs/guides/fix-a-failed-converge.md +361 -0
- package/docs/guides/give-the-cluster-git-credentials.md +222 -0
- package/docs/guides/iterate-on-a-machine-on-kind.md +190 -0
- package/docs/guides/let-an-agent-write-a-chart.md +230 -0
- package/docs/guides/look-inside-a-sandbox.md +177 -0
- package/docs/guides/mirror-the-kit-images.md +176 -0
- package/docs/guides/move-from-kind-to-a-shared-cluster.md +318 -0
- package/docs/guides/open-the-console.md +91 -0
- package/docs/guides/publish-a-machine-as-an-npm-package.md +350 -0
- package/docs/guides/push-and-sign-a-branch.md +532 -0
- package/docs/guides/run-a-chart-by-name.md +270 -0
- package/docs/guides/run-a-command-or-call-a-url.md +587 -0
- package/docs/guides/run-one-worker-per-item.md +322 -0
- package/docs/guides/set-an-agents-access-and-dials.md +420 -0
- package/docs/guides/size-a-workspace.md +217 -0
- package/docs/guides/start-a-run-from-a-run.md +237 -0
- package/docs/guides/start-a-run.md +207 -0
- package/docs/guides/upgrade-the-kit-version.md +240 -0
- package/docs/guides/use-a-hosted-provider.md +214 -0
- package/docs/guides/use-a-local-model.md +313 -0
- package/docs/guides/watch-a-run.md +349 -0
- package/docs/guides/write-a-workflow.md +318 -0
- package/docs/index.md +44 -0
- package/docs/llms.txt +237 -0
- package/docs/reference/authoring-surface/agent.md +151 -0
- package/docs/reference/authoring-surface/answer.md +156 -0
- package/docs/reference/authoring-surface/arg.md +82 -0
- package/docs/reference/authoring-surface/basic.md +62 -0
- package/docs/reference/authoring-surface/bearer.md +53 -0
- package/docs/reference/authoring-surface/branchname.md +15 -0
- package/docs/reference/authoring-surface/chartschema.md +23 -0
- package/docs/reference/authoring-surface/chartschemafor.md +48 -0
- package/docs/reference/authoring-surface/command.md +206 -0
- package/docs/reference/authoring-surface/customize.md +64 -0
- package/docs/reference/authoring-surface/defineconfig.md +41 -0
- package/docs/reference/authoring-surface/defineevent.md +114 -0
- package/docs/reference/authoring-surface/dispatch.md +126 -0
- package/docs/reference/authoring-surface/fail.md +96 -0
- package/docs/reference/authoring-surface/file.md +142 -0
- package/docs/reference/authoring-surface/frompick.md +277 -0
- package/docs/reference/authoring-surface/http.md +259 -0
- package/docs/reference/authoring-surface/isfailure.md +58 -0
- package/docs/reference/authoring-surface/isready.md +14 -0
- package/docs/reference/authoring-surface/jr2setup.md +237 -0
- package/docs/reference/authoring-surface/open.md +105 -0
- package/docs/reference/authoring-surface/openbody.md +86 -0
- package/docs/reference/authoring-surface/paramsof.md +143 -0
- package/docs/reference/authoring-surface/pool.md +186 -0
- package/docs/reference/authoring-surface/push.md +130 -0
- package/docs/reference/authoring-surface/readyof.md +21 -0
- package/docs/reference/authoring-surface/secret.md +139 -0
- package/docs/reference/authoring-surface/sentby.md +83 -0
- package/docs/reference/authoring-surface/source.md +51 -0
- package/docs/reference/authoring-surface/text.md +62 -0
- package/docs/reference/authoring-surface/type-agentdeclaration.md +27 -0
- package/docs/reference/authoring-surface/type-agentdefinition.md +80 -0
- package/docs/reference/authoring-surface/type-agentlogic.md +15 -0
- package/docs/reference/authoring-surface/type-agentslots.md +15 -0
- package/docs/reference/authoring-surface/type-answeraction.md +12 -0
- package/docs/reference/authoring-surface/type-anyframepath.md +14 -0
- package/docs/reference/authoring-surface/type-anyworktreepath.md +15 -0
- package/docs/reference/authoring-surface/type-arg.md +19 -0
- package/docs/reference/authoring-surface/type-argnames.md +12 -0
- package/docs/reference/authoring-surface/type-bindactors.md +14 -0
- package/docs/reference/authoring-surface/type-binding.md +61 -0
- package/docs/reference/authoring-surface/type-bindingof.md +12 -0
- package/docs/reference/authoring-surface/type-bodyacceptsdoor.md +15 -0
- package/docs/reference/authoring-surface/type-bodyacceptsslots.md +17 -0
- package/docs/reference/authoring-surface/type-ceilings.md +41 -0
- package/docs/reference/authoring-surface/type-chainlink.md +19 -0
- package/docs/reference/authoring-surface/type-chartaction.md +46 -0
- package/docs/reference/authoring-surface/type-chartagent.md +28 -0
- package/docs/reference/authoring-surface/type-chartevent.md +20 -0
- package/docs/reference/authoring-surface/type-chartguard.md +20 -0
- package/docs/reference/authoring-surface/type-chartinvoke.md +28 -0
- package/docs/reference/authoring-surface/type-chartjson.md +14 -0
- package/docs/reference/authoring-surface/type-chartstate.md +46 -0
- package/docs/reference/authoring-surface/type-charttext.md +40 -0
- package/docs/reference/authoring-surface/type-charttransition.md +22 -0
- package/docs/reference/authoring-surface/type-charttransitions.md +14 -0
- package/docs/reference/authoring-surface/type-chartvalue.md +15 -0
- package/docs/reference/authoring-surface/type-childat.md +12 -0
- package/docs/reference/authoring-surface/type-childslots.md +12 -0
- package/docs/reference/authoring-surface/type-commandenv.md +15 -0
- package/docs/reference/authoring-surface/type-commandinput.md +20 -0
- package/docs/reference/authoring-surface/type-commandoptions.md +56 -0
- package/docs/reference/authoring-surface/type-commandoutput.md +122 -0
- package/docs/reference/authoring-surface/type-customize.md +111 -0
- package/docs/reference/authoring-surface/type-dispatchdefinition.md +39 -0
- package/docs/reference/authoring-surface/type-dispatchinput.md +14 -0
- package/docs/reference/authoring-surface/type-dispatchopenparts.md +14 -0
- package/docs/reference/authoring-surface/type-dispatchoutput.md +72 -0
- package/docs/reference/authoring-surface/type-doorlessinput.md +19 -0
- package/docs/reference/authoring-surface/type-duration.md +15 -0
- package/docs/reference/authoring-surface/type-effectbinding.md +93 -0
- package/docs/reference/authoring-surface/type-effectlogic.md +12 -0
- package/docs/reference/authoring-surface/type-envopenparts.md +14 -0
- package/docs/reference/authoring-surface/type-eventaudience.md +27 -0
- package/docs/reference/authoring-surface/type-eventdef.md +45 -0
- package/docs/reference/authoring-surface/type-eventfrom.md +16 -0
- package/docs/reference/authoring-surface/type-eventsemantics.md +26 -0
- package/docs/reference/authoring-surface/type-execoutcome.md +34 -0
- package/docs/reference/authoring-surface/type-failslot.md +14 -0
- package/docs/reference/authoring-surface/type-failure.md +19 -0
- package/docs/reference/authoring-surface/type-failureinput.md +20 -0
- package/docs/reference/authoring-surface/type-filebody.md +37 -0
- package/docs/reference/authoring-surface/type-framepath.md +14 -0
- package/docs/reference/authoring-surface/type-frominput.md +14 -0
- package/docs/reference/authoring-surface/type-hostinjectedinput.md +56 -0
- package/docs/reference/authoring-surface/type-httpdefinition.md +104 -0
- package/docs/reference/authoring-surface/type-httpfileinput.md +20 -0
- package/docs/reference/authoring-surface/type-httpinput.md +12 -0
- package/docs/reference/authoring-surface/type-httpmethod.md +14 -0
- package/docs/reference/authoring-surface/type-httpopenparts.md +12 -0
- package/docs/reference/authoring-surface/type-httpoutput.md +95 -0
- package/docs/reference/authoring-surface/type-httprequestparts.md +33 -0
- package/docs/reference/authoring-surface/type-jr2config.md +126 -0
- package/docs/reference/authoring-surface/type-lateroutcome.md +21 -0
- package/docs/reference/authoring-surface/type-lends.md +38 -0
- package/docs/reference/authoring-surface/type-logicat.md +12 -0
- package/docs/reference/authoring-surface/type-markedif.md +12 -0
- package/docs/reference/authoring-surface/type-mergedactors.md +12 -0
- package/docs/reference/authoring-surface/type-namedsecret.md +25 -0
- package/docs/reference/authoring-surface/type-namestart.md +77 -0
- package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +27 -0
- package/docs/reference/authoring-surface/type-notworktreekeys.md +12 -0
- package/docs/reference/authoring-surface/type-openbodydeclaration.md +40 -0
- package/docs/reference/authoring-surface/type-openbodylogic.md +14 -0
- package/docs/reference/authoring-surface/type-openbodyoutput.md +42 -0
- package/docs/reference/authoring-surface/type-openbodyslot.md +18 -0
- package/docs/reference/authoring-surface/type-opencommandinput.md +22 -0
- package/docs/reference/authoring-surface/type-openeffect.md +12 -0
- package/docs/reference/authoring-surface/type-openeffectslots.md +12 -0
- package/docs/reference/authoring-surface/type-openof.md +12 -0
- package/docs/reference/authoring-surface/type-opensecret.md +23 -0
- package/docs/reference/authoring-surface/type-opensecretmark.md +12 -0
- package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +26 -0
- package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +27 -0
- package/docs/reference/authoring-surface/type-poolmachine.md +28 -0
- package/docs/reference/authoring-surface/type-poolnextinput.md +22 -0
- package/docs/reference/authoring-surface/type-poolspec.md +60 -0
- package/docs/reference/authoring-surface/type-pushinput.md +34 -0
- package/docs/reference/authoring-surface/type-pushoptions.md +79 -0
- package/docs/reference/authoring-surface/type-pushoutput.md +149 -0
- package/docs/reference/authoring-surface/type-pushwireoutput.md +12 -0
- package/docs/reference/authoring-surface/type-quantity.md +14 -0
- package/docs/reference/authoring-surface/type-reached.md +12 -0
- package/docs/reference/authoring-surface/type-reposlot.md +70 -0
- package/docs/reference/authoring-surface/type-reposlotsof.md +16 -0
- package/docs/reference/authoring-surface/type-sandboxoptions.md +84 -0
- package/docs/reference/authoring-surface/type-secret.md +25 -0
- package/docs/reference/authoring-surface/type-sender.md +19 -0
- package/docs/reference/authoring-surface/type-sentbyguards.md +12 -0
- package/docs/reference/authoring-surface/type-size.md +85 -0
- package/docs/reference/authoring-surface/type-slothandles.md +24 -0
- package/docs/reference/authoring-surface/type-sourcenextresult.md +17 -0
- package/docs/reference/authoring-surface/type-sourcespec.md +44 -0
- package/docs/reference/authoring-surface/type-syncstate.md +12 -0
- package/docs/reference/authoring-surface/type-text.md +19 -0
- package/docs/reference/authoring-surface/type-textpart.md +24 -0
- package/docs/reference/authoring-surface/type-thinkinglevel.md +39 -0
- package/docs/reference/authoring-surface/type-toparameterizedobject.md +14 -0
- package/docs/reference/authoring-surface/type-toprovidedactor.md +14 -0
- package/docs/reference/authoring-surface/type-unknown.md +21 -0
- package/docs/reference/authoring-surface/type-usercontainer.md +77 -0
- package/docs/reference/authoring-surface/type-withoutemptyindex.md +20 -0
- package/docs/reference/authoring-surface/type-workflowevent.md +46 -0
- package/docs/reference/authoring-surface/type-workspaceaccess.md +16 -0
- package/docs/reference/authoring-surface/type-workspaced.md +115 -0
- package/docs/reference/authoring-surface/type-workspacehandles.md +22 -0
- package/docs/reference/authoring-surface/type-workspacemachine.md +29 -0
- package/docs/reference/authoring-surface/type-workspaceof.md +13 -0
- package/docs/reference/authoring-surface/type-workspaceoptions.md +27 -0
- package/docs/reference/authoring-surface/type-worktreefound.md +16 -0
- package/docs/reference/authoring-surface/type-worktreeinput.md +56 -0
- package/docs/reference/authoring-surface/type-worktreekey.md +14 -0
- package/docs/reference/authoring-surface/type-worktreeoptions.md +29 -0
- package/docs/reference/authoring-surface/type-worktreeoutput.md +45 -0
- package/docs/reference/authoring-surface/type-worktreepath.md +16 -0
- package/docs/reference/authoring-surface/type-worktreeready.md +37 -0
- package/docs/reference/authoring-surface/type-worktreerefused.md +21 -0
- package/docs/reference/authoring-surface/workspace.md +287 -0
- package/docs/reference/authoring-surface/worktree.md +71 -0
- package/docs/reference/authoring-surface.md +217 -0
- package/docs/reference/cli.md +433 -0
- package/docs/reference/config.md +765 -0
- package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +114 -0
- package/docs/reference/decisions/0002-duplex-streaming-actor.md +117 -0
- package/docs/reference/decisions/0004-worktree-provisioning-model.md +130 -0
- package/docs/reference/decisions/0005-sandbox-pod-composition.md +240 -0
- package/docs/reference/decisions/0006-agent-control-surface.md +50 -0
- package/docs/reference/decisions/0007-durable-machine-state.md +109 -0
- package/docs/reference/decisions/0008-orchestrator-as-deployed-app.md +60 -0
- package/docs/reference/decisions/0009-cli-and-instance-interface.md +275 -0
- package/docs/reference/decisions/0010-bdd-acceptance-tests.md +160 -0
- package/docs/reference/decisions/0011-workflow-defined-events.md +141 -0
- package/docs/reference/decisions/0012-workspace-wrapper-machine.md +103 -0
- package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +175 -0
- package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +95 -0
- package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +271 -0
- package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +126 -0
- package/docs/reference/decisions/0017-pool-over-a-source-port.md +71 -0
- package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +111 -0
- package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +287 -0
- package/docs/reference/decisions/0020-private-ca-trust-is-a-named-concept.md +60 -0
- package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +101 -0
- package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +103 -0
- package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +175 -0
- package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +436 -0
- package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +65 -0
- package/docs/reference/decisions/0026-a-turn-that-is-over-is-never-prompted.md +62 -0
- package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +245 -0
- package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +90 -0
- package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +154 -0
- package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +100 -0
- package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +193 -0
- package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +61 -0
- package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +126 -0
- package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +57 -0
- package/docs/reference/decisions/0035-a-runaway-turn-is-ended-rerolled-once-then-a-fault.md +92 -0
- package/docs/reference/decisions/0036-a-turn-compacts-its-own-context-mid-flight.md +138 -0
- package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +196 -0
- package/docs/reference/decisions/0038-jr2-up-builds-every-image-it-deploys.md +170 -0
- package/docs/reference/decisions/0039-image-garbage-collects-by-reachability.md +115 -0
- package/docs/reference/decisions/0041-a-build-the-host-already-holds-is-not-spent-again.md +64 -0
- package/docs/reference/decisions/0042-ready-is-not-routable-an-admission-retries-its-connection.md +142 -0
- package/docs/reference/decisions/0043-the-kit-is-tested-as-installed-a-local-registry-stands-in-for-npm.md +170 -0
- package/docs/reference/decisions/0044-kit-images-live-at-a-canonical-home-a-self-host-mirrors-it.md +85 -0
- package/docs/reference/decisions/0045-the-platform-joins-the-image-address-and-the-cluster-chooses-it.md +82 -0
- package/docs/reference/decisions/0046-a-converge-failure-carries-its-diagnosis.md +34 -0
- package/docs/reference/decisions/0047-the-git-ssh-key-source-is-the-users-choice.md +47 -0
- package/docs/reference/decisions/0048-the-orchestrator-boots-without-its-repos.md +36 -0
- package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +126 -0
- package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +73 -0
- package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +238 -0
- package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +86 -0
- package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +123 -0
- package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +126 -0
- package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +107 -0
- package/docs/reference/decisions/0056-a-global-jr2-hands-off-to-the-instances-own-and-an-instance-has-one-kit-version.md +62 -0
- package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +152 -0
- package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +108 -0
- package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +427 -0
- package/docs/reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md +111 -0
- package/docs/reference/decisions/0061-a-memory-kill-ends-the-agents-processes-not-the-harness.md +83 -0
- package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +239 -0
- package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +82 -0
- package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +79 -0
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +65 -0
- package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +552 -0
- package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +458 -0
- package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +475 -0
- package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +180 -0
- package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +334 -0
- package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +183 -0
- package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +144 -0
- package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +122 -0
- package/docs/reference/decisions/0074-an-unrouted-mechanism-event-is-refused-at-load-and-faults-the-run.md +76 -0
- package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +295 -0
- package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +320 -0
- package/docs/reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md +79 -0
- package/docs/reference/decisions.md +86 -0
- package/docs/reference/glossary.md +687 -0
- package/docs/reference/http-api.md +1386 -0
- package/docs/reference/machines.md +189 -0
- package/docs/reference/mechanism-events.md +72 -0
- package/docs/why.md +207 -0
- package/package.json +5 -3
- package/src/actor.ts +694 -106
- package/src/agent.ts +114 -38
- package/src/ambient.ts +3 -4
- package/src/assembly-checks.ts +189 -7
- package/src/cause.ts +234 -0
- package/src/chart.ts +345 -46
- package/src/charts.ts +43 -8
- package/src/config.ts +440 -178
- package/src/custodian.lua +17 -5
- package/src/custodian.ts +325 -99
- package/src/customize.ts +199 -49
- package/src/dispatch-effect.ts +945 -0
- package/src/door-compat.ts +217 -0
- package/src/durability.ts +11 -4
- package/src/effect-checks.ts +50 -3
- package/src/effect.ts +641 -128
- package/src/effector-wire.ts +165 -13
- package/src/fail.ts +222 -0
- package/src/harness-client.ts +587 -50
- package/src/harness-env.ts +33 -0
- package/src/held-secrets.ts +125 -16
- package/src/holds.ts +3 -0
- package/src/http-effect.ts +556 -58
- package/src/http.ts +480 -30
- package/src/index.ts +74 -82
- package/src/instance.ts +68 -8
- package/src/internal.ts +85 -0
- package/src/kube-client.ts +6 -3
- package/src/machine-doc.ts +24 -7
- package/src/mechanism-routes.ts +168 -0
- package/src/model-keys.generated.ts +53 -0
- package/src/model-keys.ts +42 -58
- package/src/names.ts +19 -6
- package/src/notices.ts +483 -41
- package/src/open-body.ts +242 -40
- package/src/open-effect.ts +81 -8
- package/src/open.ts +90 -6
- package/src/parts.ts +213 -30
- package/src/party.ts +101 -2
- package/src/pick.ts +497 -11
- package/src/pool.ts +282 -50
- package/src/registration.ts +133 -12
- package/src/repo-identity.ts +7 -3
- package/src/repos.ts +22 -3
- package/src/run-host.ts +665 -45
- package/src/run-output.ts +38 -0
- package/src/sandbox-effect.ts +457 -71
- package/src/sandbox-kube.ts +66 -17
- package/src/secret-placement.ts +59 -17
- package/src/server.ts +3 -0
- package/src/setup.ts +325 -62
- package/src/size.ts +121 -9
- package/src/snapshot-store.ts +54 -10
- package/src/stub-harness.ts +44 -16
- package/src/timers.ts +14 -1
- package/src/tokens.ts +107 -32
- package/src/vocabulary.ts +88 -14
- package/src/wire.ts +100 -26
- package/src/workspace.ts +771 -238
- package/src/worktree.ts +249 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Architecture
|
|
3
|
+
description: What runs on your computer, in the cluster and in a Sandbox, and which part does what.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Architecture
|
|
7
|
+
|
|
8
|
+
Most parts of an [Instance](../reference/glossary.md#instance) run in one Kubernetes namespace. The
|
|
9
|
+
[Orchestrator](../reference/glossary.md#orchestrator) runs your [Machines](../reference/glossary.md#machine). A
|
|
10
|
+
[Harness](../reference/glossary.md#harness) runs each [Agent](../reference/glossary.md#agent)'s
|
|
11
|
+
[Turn](../reference/glossary.md#turn). A [Custodian](../reference/glossary.md#custodian) holds the credentials of a
|
|
12
|
+
Harness pod. An [Effector](../reference/glossary.md#effector) runs each `http` and `push`
|
|
13
|
+
[Effect](../reference/glossary.md#effect), each `command` that names an
|
|
14
|
+
[Effect secret](../reference/glossary.md#effect-secret), and each `dispatch` to a different Orchestrator. The operator
|
|
15
|
+
makes the pod of each [Sandbox](../reference/glossary.md#sandbox). One operator serves each cluster. The Repo cache
|
|
16
|
+
keeps a copy of each [Repo](../reference/glossary.md#repo) on each node that needs it. This page tells where each part
|
|
17
|
+
runs and what it does.
|
|
18
|
+
|
|
19
|
+
## Why the parts are separate
|
|
20
|
+
|
|
21
|
+
An Agent that works on a Repo runs code. Its [Working tools](../reference/glossary.md#working-tools) give it a shell.
|
|
22
|
+
With the shell, it can run each program of its image on the files in `/work`. It can also connect to each address that
|
|
23
|
+
its pod can reach. Thus jr2 puts each thing that the Agent must not touch in a different place:
|
|
24
|
+
|
|
25
|
+
- The control of a run is in the Orchestrator. An Agent cannot change its own Machine. It can only pick from its
|
|
26
|
+
[Menu](../reference/glossary.md#menu), and the Orchestrator decides what each pick does.
|
|
27
|
+
- Each [Workspace](../reference/glossary.md#workspace) has its own Sandbox: a pod with its own filesystem, network and
|
|
28
|
+
processes. Agents in two Workspaces share no files and no ports. [Workspaces](workspaces.md) tells more.
|
|
29
|
+
- The credentials are in containers in which the Agent executes nothing: the Custodian, the Effector and the Repo cache.
|
|
30
|
+
[Secrets and trust](secrets-and-trust.md) tells how.
|
|
31
|
+
- The Harness holds one secret value, with which it sends the picks. Each program that it starts runs confined with
|
|
32
|
+
Landlock, so the code of an Agent cannot read that value.
|
|
33
|
+
|
|
34
|
+
## What runs where
|
|
35
|
+
|
|
36
|
+
**What runs where, from your computer to the world outside the cluster**
|
|
37
|
+
|
|
38
|
+
- **You**: your computer, where no part of a run executes
|
|
39
|
+
- jr2 CLI
|
|
40
|
+
- **Console**: in a browser
|
|
41
|
+
- **Assistant**: writes your Machines
|
|
42
|
+
- ↓ the HTTP API, through a port forward
|
|
43
|
+
- **the cluster**
|
|
44
|
+
- **Instance**: in the namespace of the Instance, one of each
|
|
45
|
+
- **Orchestrator**: runs your Machines, and keeps each run
|
|
46
|
+
- **Instance Harness**: runs the Turns of the Menu-only Agents
|
|
47
|
+
- Harness
|
|
48
|
+
- Custodian
|
|
49
|
+
- **Instance Effector**: runs the Effects that read no Worktree file
|
|
50
|
+
- **Repo cache**: one pod on each Sandbox node
|
|
51
|
+
- ↓ a Turn, an Effect · ↑ a pick, through the Custodian · ↓ the Repo cache gives each Repo
|
|
52
|
+
- **Sandbox**: one pod for each Workspace, in the same namespace
|
|
53
|
+
- **Harness**: runs the Turns of the Agents that work on a Repo
|
|
54
|
+
- **Custodian**: holds the Held secrets of the pod
|
|
55
|
+
- **Sandbox Effector**: runs the Effects that work on the Worktree
|
|
56
|
+
- **User Container**: when the Workspace names one
|
|
57
|
+
- ↑ the operator makes the pod of each Sandbox
|
|
58
|
+
- **jr2-system**: one for each cluster
|
|
59
|
+
- **operator**: makes each Sandbox pod, and removes it when its Lease lapses
|
|
60
|
+
- ↓ the Custodians call the model provider · ↓ the Repo cache fetches from the git host
|
|
61
|
+
- **Outside**: what the work uses
|
|
62
|
+
- model provider
|
|
63
|
+
- git host
|
|
64
|
+
|
|
65
|
+
The [Instance Harness](../reference/glossary.md#instance-harness), the
|
|
66
|
+
[Instance Effector](../reference/glossary.md#instance-effector), the Repo cache and the
|
|
67
|
+
[Sandbox Effector](../reference/glossary.md#sandbox-effector) exist only when a Machine of the Instance needs them. The
|
|
68
|
+
sections below tell when.
|
|
69
|
+
|
|
70
|
+
A Sandbox pod can also have a [User Container](../reference/glossary.md#user-container), when its `workspace()` names
|
|
71
|
+
one. It runs its own image, and it mounts `/work`, with each [Worktree](../reference/glossary.md#worktree), read-write.
|
|
72
|
+
[Workspaces](workspaces.md) tells more.
|
|
73
|
+
|
|
74
|
+
## On your computer
|
|
75
|
+
|
|
76
|
+
The [jr2 CLI](../reference/glossary.md#jr2-cli) runs on your computer, in the Instance folder. The
|
|
77
|
+
[Assistant](../reference/glossary.md#assistant) works there too, and writes Machines and config in that folder. Nothing
|
|
78
|
+
of a run executes on your computer.
|
|
79
|
+
|
|
80
|
+
[`jr2 up`](../reference/cli.md#up) reads the folder and converges the cluster of the current kubectl context.
|
|
81
|
+
[Converge](converge.md) tells what it makes. By default, each other command that talks to the Orchestrator, such as
|
|
82
|
+
[`jr2 run`](../reference/cli.md#run), reads the Instance token from the cluster. Then it opens a `kubectl port-forward`
|
|
83
|
+
to the Orchestrator's Service, for the life of the command. The [global options](../reference/cli.md#global-options)
|
|
84
|
+
tell how to give a URL and a token instead. The CLI keeps no local state about the cluster.
|
|
85
|
+
|
|
86
|
+
The [Console](../reference/glossary.md#console) is a page that the Orchestrator serves. You open it in a browser,
|
|
87
|
+
through a port forward that you start. [Open the Console](../guides/open-the-console.md) gives the commands.
|
|
88
|
+
|
|
89
|
+
## The Orchestrator
|
|
90
|
+
|
|
91
|
+
The Orchestrator is one pod for each Instance (`replicas: 1`), with the Service `jr2-orchestrator` on port 4000. It
|
|
92
|
+
hosts all the [Workflows](../reference/glossary.md#workflow) of the Instance and many runs of each Workflow. It keeps
|
|
93
|
+
the snapshot of each run on its own volume, so a run continues after a restart. [Durable runs](durable-runs.md) tells
|
|
94
|
+
how.
|
|
95
|
+
|
|
96
|
+
The pod runs the `jr2-orchestrator` [Kit image](../reference/glossary.md#kit-image), which holds no code of yours. The
|
|
97
|
+
Orchestrator loads your Workflows and your config from the [Assembly](../reference/glossary.md#assembly) that `jr2 up`
|
|
98
|
+
publishes to it, and it keeps each Assembly on its volume. [Converge](converge.md#the-assembly) tells how.
|
|
99
|
+
|
|
100
|
+
The Orchestrator does these things:
|
|
101
|
+
|
|
102
|
+
- It runs each Machine as an [xstate](https://xstate.js.org) actor, and holds the state of each run.
|
|
103
|
+
- It serves the HTTP API that the CLI, the Console, a webhook and the Custodians call. See the
|
|
104
|
+
[HTTP API](../reference/http-api.md).
|
|
105
|
+
- It sends each Turn to a Harness, and judges each pick that comes back.
|
|
106
|
+
- It writes a Sandbox resource when a run enters a Workspace. Then it watches the Sandbox resource until the Workspace
|
|
107
|
+
ends.
|
|
108
|
+
- It sends each Effect to the place where it runs. It runs a `dispatch` with no target itself: the Effect starts a run
|
|
109
|
+
of a Workflow of the same Instance.
|
|
110
|
+
|
|
111
|
+
The Orchestrator does no work of an Agent. It runs no model and no Working tools. That work runs in the pods that the
|
|
112
|
+
cluster places.
|
|
113
|
+
|
|
114
|
+
To isolate two sets of Workflows, use two Instances. Each Instance has its own namespace and its own Orchestrator.
|
|
115
|
+
|
|
116
|
+
## The Harness
|
|
117
|
+
|
|
118
|
+
The Harness is jr2's own server for the Turns of Agents. It speaks to the model provider. It gives the model the Agent's
|
|
119
|
+
Menu and its Working tools. It executes each Working tool that the model calls, and sends each pick through the
|
|
120
|
+
Custodian. Each program that a Working tool starts runs confined with Landlock. The Harness holds no Agents of its own.
|
|
121
|
+
Each Turn brings the Agent's definition with it. [Agents and Turns](agents-and-turns.md) tells what happens in a Turn.
|
|
122
|
+
|
|
123
|
+
The Harness has two placements:
|
|
124
|
+
|
|
125
|
+
- **In each Sandbox.** The Harness is the primary container of the Sandbox pod, named `harness`. It runs in the
|
|
126
|
+
[Sandbox Image](../reference/glossary.md#sandbox-image), and jr2 mounts the Harness into the pod at `/opt/jr2`. Thus
|
|
127
|
+
the Working tools of the Agent reach the tools of that image. Each Agent that works on a Repo has its Turns here: one
|
|
128
|
+
Harness serves all the Agents of the Sandbox.
|
|
129
|
+
- **As the Instance Harness.** The Instance Harness is one StatefulSet for each Instance, `jr2-instance-harness`. Each
|
|
130
|
+
Turn of a Menu-only Agent (`workspace: "none"`) runs here. Its pod has a Harness and a Custodian, and no Worktree. It
|
|
131
|
+
keeps each conversation on its volume while a run can continue it. `jr2 up` converges it when a Machine of the
|
|
132
|
+
Instance has a Menu-only Agent.
|
|
133
|
+
|
|
134
|
+
A Harness answers only the Orchestrator. The Orchestrator sends a bearer token on each call, and the Harness accepts no
|
|
135
|
+
call without it, except its health check. `jr2 up` also converges NetworkPolicies that let only the Orchestrator's pods
|
|
136
|
+
connect to a Harness pod, and that stop each Harness pod at the cloud metadata addresses
|
|
137
|
+
([Secrets and trust](secrets-and-trust.md#what-a-held-secret-does-not-stop)).
|
|
138
|
+
|
|
139
|
+
## The Custodian
|
|
140
|
+
|
|
141
|
+
Each Harness pod has a Custodian: each Sandbox, and the Instance Harness. The Custodian is a container beside the
|
|
142
|
+
Harness. The Agent executes no code in it. It does two things:
|
|
143
|
+
|
|
144
|
+
- It carries five kinds of call from the pod to the Orchestrator: the Menu reads, the picks, the polls for the answer to
|
|
145
|
+
a pick, the reports that a step boundary gave its notices to the model, and the fetch asks. It sends the first four
|
|
146
|
+
with the control token of the Sandbox, and the fetch asks with its fetch token. These five routes are all that it
|
|
147
|
+
forwards. It refuses all other routes. The Harness sends the first four on a Unix socket in `/run/jr2`. A confined
|
|
148
|
+
program cannot make a socket there, and the Custodian refuses a request on it that does not have the control Stand-in.
|
|
149
|
+
The fetch asks go to port `8081` on loopback.
|
|
150
|
+
- It holds the [Held secrets](../reference/glossary.md#held-secret) of its pod, such as a model API key. It puts the
|
|
151
|
+
value into the requests that go to the hosts of each Held secret.
|
|
152
|
+
|
|
153
|
+
The Custodian runs Envoy, from a [Pinned image](../reference/glossary.md#pinned-image). The Orchestrator writes its
|
|
154
|
+
config for a Sandbox, and `jr2 up` writes it for the Instance Harness. [Secrets and trust](secrets-and-trust.md) tells
|
|
155
|
+
how the Custodian holds a credential.
|
|
156
|
+
|
|
157
|
+
## The Effector
|
|
158
|
+
|
|
159
|
+
The Effector runs each `http` and `push` Effect, each `command` that names an Effect secret, and each `dispatch` that
|
|
160
|
+
names a target. Thus a credential that an Effect uses stays out of the Harness container. The Effector is jr2's own
|
|
161
|
+
program, and it runs in a container in which the Agent executes nothing. [Effects](effects.md) tells which Effect runs
|
|
162
|
+
where. It has two placements:
|
|
163
|
+
|
|
164
|
+
- **The Sandbox Effector** is a container in a Sandbox pod, named `effector`. It mounts `/work` read-only. It runs a
|
|
165
|
+
`push`, an `http` Effect whose body is a Worktree file, and a `command` that names an Effect secret. Its image is the
|
|
166
|
+
Sandbox Image, unless the `workspace()` names a different image.
|
|
167
|
+
- **The Instance Effector** is one pod for each Instance, `jr2-instance-effector`. It runs each `http` Effect that reads
|
|
168
|
+
no Worktree file, and each `dispatch` that starts a run on a different Orchestrator. It holds the Instance token of
|
|
169
|
+
that Orchestrator as an Effect secret. It runs in the `jr2-harness` Kit image.
|
|
170
|
+
|
|
171
|
+
Each placement exists only when a Machine of the Instance puts an Effect there. A `command` that names no Effect secret
|
|
172
|
+
does not use an Effector. It runs in the Harness container of its Sandbox, with the same tools and access as the Agent,
|
|
173
|
+
and confined in the same way.
|
|
174
|
+
|
|
175
|
+
The Orchestrator signs each request that it sends to an Effector, and the Effector signs each answer. The Orchestrator
|
|
176
|
+
only asks, and the Effector holds the credentials.
|
|
177
|
+
|
|
178
|
+
## The operator
|
|
179
|
+
|
|
180
|
+
The operator is a Kubernetes operator. One copy serves the whole cluster: it runs in the namespace `jr2-system`, and
|
|
181
|
+
each Instance on the cluster shares it. By default, `jr2 up` converges it. With `operator.manage: false`, you run it
|
|
182
|
+
yourself.
|
|
183
|
+
|
|
184
|
+
The operator reconciles two custom resources:
|
|
185
|
+
|
|
186
|
+
- A **Sandbox resource** becomes one pod and a Service. The Orchestrator writes the Sandbox resource, and the operator
|
|
187
|
+
makes the pod and reports its state. The operator never makes a second pod for a Sandbox. When the pod ends, the
|
|
188
|
+
Sandbox is lost.
|
|
189
|
+
- A **Repo** names one git repository that the Repo cache keeps.
|
|
190
|
+
|
|
191
|
+
The operator knows nothing about Agents, Turns or Worktrees. The Orchestrator does that work after the Sandbox is ready.
|
|
192
|
+
The operator also removes a Sandbox resource when its [Lease](../reference/glossary.md#lease) lapses, for example after
|
|
193
|
+
the Orchestrator stopped for longer than the Lease allows. [Workspaces](workspaces.md) tells how the Lease works.
|
|
194
|
+
|
|
195
|
+
## The Repo cache
|
|
196
|
+
|
|
197
|
+
The Repo cache keeps one bare clone of each Repo on each node that needs it. It is a DaemonSet, `jr2-repo-cache`, in the
|
|
198
|
+
namespace of the Instance. It has one pod on each [Sandbox node](../reference/glossary.md#sandbox-node). `jr2 up`
|
|
199
|
+
converges it when a Machine of the Instance uses a Sandbox. Each pod also checks that the kernel of its node has
|
|
200
|
+
Landlock. On a node without Landlock, the pod is not ready, and `jr2 up` names that node and refuses to converge.
|
|
201
|
+
|
|
202
|
+
The operator mounts the cache of each Repo into a Sandbox, read-only, at `/repos`. The clone in the Sandbox gets its
|
|
203
|
+
objects from that cache. A `git fetch origin` in the Sandbox asks the Repo cache for a fetch. Then the Repo cache
|
|
204
|
+
fetches from the host of the Repo, with the clone credential of the cluster. Thus the Harness container needs no git
|
|
205
|
+
credential to fetch.
|
|
206
|
+
|
|
207
|
+
## Rules
|
|
208
|
+
|
|
209
|
+
- An Instance has exactly one Orchestrator, and the Orchestrator always runs in the cluster.
|
|
210
|
+
- A namespace holds one Instance. `jr2 up` refuses a namespace that a different Instance owns.
|
|
211
|
+
- By default, the CLI reaches the cluster of the current kubectl context. Kubernetes RBAC decides who can read the
|
|
212
|
+
Instance token.
|
|
213
|
+
- A Harness accepts a call only from the Orchestrator, with the bearer of its own pod. Only its health check needs no
|
|
214
|
+
bearer.
|
|
215
|
+
- The Agent executes code only in the Harness container. It executes nothing in the Custodian or in the Effector.
|
|
216
|
+
- In the Harness container, each program that the Harness starts runs confined. It cannot read what the Harness holds.
|
|
217
|
+
- Each Sandbox node needs Landlock in its kernel. `jr2 up` refuses to converge while a Sandbox node has none.
|
|
218
|
+
- The Orchestrator watches the Sandbox resources and never reads a pod. The operator puts the facts of the pod on the
|
|
219
|
+
status of the Sandbox resource.
|
|
220
|
+
- A Sandbox has one pod for its life. A lost pod is never made again.
|
|
221
|
+
|
|
222
|
+
## Read next
|
|
223
|
+
|
|
224
|
+
- [Open the Console](../guides/open-the-console.md)
|
|
225
|
+
- [Look inside a Sandbox](../guides/look-inside-a-sandbox.md)
|
|
226
|
+
- [Watch a run](../guides/watch-a-run.md)
|
|
227
|
+
- [Workspaces](workspaces.md), [Secrets and trust](secrets-and-trust.md) and [Converge](converge.md)
|
|
228
|
+
- The [HTTP API](../reference/http-api.md) and the [`operator`](../reference/config.md#operator) and
|
|
229
|
+
[`sandbox`](../reference/config.md#sandbox) fields of `jr2.config.ts`
|
|
230
|
+
- [ADR-0001](../reference/decisions/0001-operator-owned-generic-sandbox.md),
|
|
231
|
+
[ADR-0005](../reference/decisions/0005-sandbox-pod-composition.md),
|
|
232
|
+
[ADR-0008](../reference/decisions/0008-orchestrator-as-deployed-app.md),
|
|
233
|
+
[ADR-0013](../reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md),
|
|
234
|
+
[ADR-0019](../reference/decisions/0019-one-converging-command-against-the-current-context.md),
|
|
235
|
+
[ADR-0031](../reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md),
|
|
236
|
+
[ADR-0051](../reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md),
|
|
237
|
+
[ADR-0053](../reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md),
|
|
238
|
+
[ADR-0058](../reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md),
|
|
239
|
+
[ADR-0059](../reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md),
|
|
240
|
+
[ADR-0063](../reference/decisions/0063-the-orchestrator-watches-the-cluster.md),
|
|
241
|
+
[ADR-0068](../reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md),
|
|
242
|
+
[ADR-0076](../reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md) and
|
|
243
|
+
[ADR-0077](../reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md)
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Charts
|
|
3
|
+
description: How an Agent writes a Machine as data at run time, which cannot reach the process of the Orchestrator.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Charts
|
|
7
|
+
|
|
8
|
+
A [Chart](../reference/glossary.md#chart) is a [Machine](../reference/glossary.md#machine) that is written as data, in
|
|
9
|
+
JSON, with no code. An [Agent](../reference/glossary.md#agent) writes it while a run runs, or you keep it in a file. A
|
|
10
|
+
Chart runs only under a [Chart wrapper](../reference/glossary.md#chart-wrapper): a Machine that declares an
|
|
11
|
+
[Open body](../reference/glossary.md#open-body). The Open body names the parts that a Chart can use.
|
|
12
|
+
|
|
13
|
+
## Why Charts exist
|
|
14
|
+
|
|
15
|
+
Some work has a shape that nobody knows before the run. A planner Agent reads the task and decides the steps: first a
|
|
16
|
+
coder, then a reviewer, then a person. You cannot write that Machine before the run.
|
|
17
|
+
|
|
18
|
+
An Agent cannot write code for the [Orchestrator](../reference/glossary.md#orchestrator). Only
|
|
19
|
+
[`jr2 up`](../reference/cli.md#up) publishes code, because the Orchestrator holds the credentials of the
|
|
20
|
+
[Instance](../reference/glossary.md#instance). Code that an Agent wrote could reach them. A Chart is data: the
|
|
21
|
+
Orchestrator reads it, but it cannot reach the process of the Orchestrator or its credentials. It can only name parts
|
|
22
|
+
that your code gives it, and jr2 checks each name before the Chart runs. Thus an Agent can make a Machine while a run
|
|
23
|
+
runs, and it can do only what the Open body lets it do. A Chart becomes a Workflow only when it is kept under a name
|
|
24
|
+
(see [Four ways to run a Chart](#four-ways-to-run-a-chart)). This is true also when the model is wrong or someone gives
|
|
25
|
+
it bad text.
|
|
26
|
+
|
|
27
|
+
## The Open body
|
|
28
|
+
|
|
29
|
+
[`openBody()`](../reference/authoring-surface/openbody.md) makes the actor slot that a Chart binds. It is the one
|
|
30
|
+
[Open](../reference/glossary.md#open) part that a run binds, not a composer. Its declaration has three parts:
|
|
31
|
+
|
|
32
|
+
- **`lends`**: the parts of the Chart wrapper that a Chart can use, by their slot keys. These are Agents, Effects,
|
|
33
|
+
Machines, guards, actions and delays. `gate: true` lends the [Gate](../reference/glossary.md#gate), so that a Chart
|
|
34
|
+
can wait for a person. `fail: true` lends [`fail()`](../reference/authoring-surface/fail.md), so that a Chart can end
|
|
35
|
+
its run as a [Failure](../reference/glossary.md#failure) with `invoke: { src: "fail", input: { reason } }`.
|
|
36
|
+
- **`allows`**: what the Agents that a Chart adds can have. `models` lists the models, and `workspace` lists the
|
|
37
|
+
Workspace accesses. With no model, a Chart cannot add an Agent.
|
|
38
|
+
- **`ceilings`**: the limits of one Chart: the Agent Turns, the wall clock, the transitions, the children at one time,
|
|
39
|
+
and the size of the Chart in bytes.
|
|
40
|
+
|
|
41
|
+
A Chart gets nothing else. A lent Effect keeps its url, its argv and its secrets, so a Chart fills only its input. A
|
|
42
|
+
lent [`worktree()`](../reference/authoring-surface/worktree.md) must state `expect`, because a Chart cannot state it. A
|
|
43
|
+
Chart reads the cut with the kit guard `jr2.ready`, then gives the same literal path as `cwd` and `worktree`. A Chart
|
|
44
|
+
has no url, no secret, no image and no Repo of its own. The Open body also decides where each Turn of the Chart runs: in
|
|
45
|
+
the Sandbox of its `workspace()`, or on the [Instance Harness](../reference/glossary.md#instance-harness).
|
|
46
|
+
|
|
47
|
+
## What a Chart holds
|
|
48
|
+
|
|
49
|
+
A Chart is [xstate](https://xstate.js.org)'s own JSON config, with these limits:
|
|
50
|
+
|
|
51
|
+
- States, transitions, `after` delays, and nested and parallel states. A Chart has 200 states at most, 8 levels deep.
|
|
52
|
+
- Each `invoke.src` is a lent slot key or an Agent of the Chart. Each guard, action and delay is a lent name. Each Chart
|
|
53
|
+
also has the guard `jr2.failure`, which is true on an `onError` when the error is a Failure, and the guard
|
|
54
|
+
`jr2.ready`, which is true on an `onDone` when the cut is `ready`.
|
|
55
|
+
- A state that invokes an Agent can route [`agent.fault`](../reference/mechanism-events.md#agent-fault) in its `on`, but
|
|
56
|
+
it does not have to. When no transition of the Chart takes `agent.fault`, the Open body sends it, unchanged, to the
|
|
57
|
+
Chart wrapper. The wrapper's own `agent.fault` route takes it, as for an Agent of the wrapper, so one route on the
|
|
58
|
+
wrapper's root is the route for each Agent of each Chart.
|
|
59
|
+
- Its events, with a JSON Schema for the input of each. An Agent of the Chart picks these events.
|
|
60
|
+
- Its own Agents, under `agents`, each with a model that the Open body allows.
|
|
61
|
+
- Its `context`, and the `output` of its final state. A Chart reads that `output`. A Machine that you write in
|
|
62
|
+
TypeScript does not: it needs a root `output`. `createMachine` refuses an `output` on a final state directly below the
|
|
63
|
+
root when the root has none (see [Write a Workflow](../guides/write-a-workflow.md#give-the-run-an-output)).
|
|
64
|
+
|
|
65
|
+
A Chart moves data with a [Reference](../reference/glossary.md#reference): a path that jr2 reads when the state starts.
|
|
66
|
+
`{{input.topic}}` reads the input of the Chart, `{{context.notes}}` reads its context, and `{{event.summary}}` reads the
|
|
67
|
+
pick that a transition handles. `{ "$ref": "event.summary" }` is the same. A Reference is a path, not an expression:
|
|
68
|
+
`{{context.round + 1}}` is refused. Four actions write the context: `set`, `append`, `increment` and `clear`.
|
|
69
|
+
|
|
70
|
+
A placeholder in data stays text. When a ticket holds `{{context.notes}}`, the prompt gets those characters, not the
|
|
71
|
+
notes.
|
|
72
|
+
|
|
73
|
+
## The door
|
|
74
|
+
|
|
75
|
+
jr2 checks each Chart before it runs. The door reads the whole Chart, and gives one line for each problem:
|
|
76
|
+
|
|
77
|
+
- each name that is not lent, or not declared by the Chart
|
|
78
|
+
- each event that no state handles, and each payload schema that uses a part that jr2 does not check
|
|
79
|
+
- each model that the Open body does not allow
|
|
80
|
+
- each loop with no guard, and each Agent state that nothing can end
|
|
81
|
+
- each Reference that nothing supplies, such as `{{context.summary}}` when no `set` writes `summary`
|
|
82
|
+
|
|
83
|
+
A refusal is the output of the Open body: `{ outcome: "refused", report }`. The Chart wrapper routes it. Usually it goes
|
|
84
|
+
back to the planner as the answer to its pick, and the planner sends a corrected Chart. The other outputs are
|
|
85
|
+
`{ outcome: "done", output }` when the Chart ends, and `{ outcome: "ceiling", ceiling }` when it gets to a ceiling.
|
|
86
|
+
|
|
87
|
+
The pick of a planner carries the Chart as its parameter. Its schema is
|
|
88
|
+
[`chartSchemaFor(declaration)`](../reference/authoring-surface/chartschemafor.md): the Chart grammar with the lent names
|
|
89
|
+
of this Open body. Thus the model gets the grammar as the parameters of its tool. On each Turn where the pick is an
|
|
90
|
+
[Allowed pick](../reference/glossary.md#allowed-picks), the [Briefing](../reference/glossary.md#briefing) also tells the
|
|
91
|
+
Agent how a Chart runs.
|
|
92
|
+
|
|
93
|
+
## Four ways to run a Chart
|
|
94
|
+
|
|
95
|
+
| Who | One time | By name |
|
|
96
|
+
| -------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
97
|
+
| You, a tool or a CLI | The Chart in the run input of the Chart wrapper | A Chart file, or a runtime Chart, run as `jr2 run <wrapper>/<name>` |
|
|
98
|
+
| An Agent | Its pick carries the Chart, and a state invokes the Open body | The Open body gets `{ chart: { name } }` |
|
|
99
|
+
|
|
100
|
+
A Chart wrapper takes a Chart in its run input when a field of its input is
|
|
101
|
+
[`chartSchema`](../reference/authoring-surface/chartschema.md). Only such a wrapper keeps Charts under a name. A named
|
|
102
|
+
Chart is a [Workflow](../reference/glossary.md#workflow), with the name `<wrapper>/<name>`, and it runs under that
|
|
103
|
+
wrapper only. It comes from one of two places:
|
|
104
|
+
|
|
105
|
+
- A **Chart file** in the Assembly: `workflows/<wrapper>/<name>.chart.json`. `jr2 up` checks it at the door before it
|
|
106
|
+
converges, and refuses a Chart file that the door refuses.
|
|
107
|
+
- A **runtime Chart**: `PUT /workflows/<wrapper>/charts/<name>`, with the Instance token. The Orchestrator keeps it on
|
|
108
|
+
its volume. `DELETE` on the same path removes it.
|
|
109
|
+
|
|
110
|
+
[`jr2 runs`](../reference/cli.md#runs) lists each named Chart under its wrapper. When a publish removes a part that a
|
|
111
|
+
runtime Chart uses, the Chart stays, and it is unrunnable until a publish gives the part back.
|
|
112
|
+
|
|
113
|
+
## A run keeps its Chart
|
|
114
|
+
|
|
115
|
+
The run keeps the text of its Chart in its snapshot. Thus a run continues when its named Chart changes or goes. After a
|
|
116
|
+
restart, jr2 checks the text at the door again. A Chart that the door refuses then makes the run `drifted`.
|
|
117
|
+
|
|
118
|
+
The [Console](../reference/glossary.md#console) draws the Machine that the run binds, with its Chart in it. Thus you see
|
|
119
|
+
the states of the Chart while it runs.
|
|
120
|
+
|
|
121
|
+
## Rules
|
|
122
|
+
|
|
123
|
+
- A Chart runs only under a Chart wrapper.
|
|
124
|
+
- A Chart names only the parts that the Open body lends, its own Agents, and the four generic actions.
|
|
125
|
+
- An Agent of a Chart has a model that the Open body allows, and a Workspace access that it allows.
|
|
126
|
+
- A Reference starts at `context`, `event` or `input`, and something must supply it.
|
|
127
|
+
- The door refuses the whole Chart when it finds one problem, and it lists each problem.
|
|
128
|
+
- A Chart cannot go past a ceiling. The Open body then stops it.
|
|
129
|
+
- Only a wrapper with a `chartSchema` field in its input takes a Chart in the run input, and keeps named Charts.
|
|
130
|
+
- A Chart file and a runtime Chart with the same name: the Chart file wins, and the runtime Chart is unrunnable.
|
|
131
|
+
|
|
132
|
+
[Let an Agent write a Chart](../guides/let-an-agent-write-a-chart.md) and
|
|
133
|
+
[Run a Chart by name](../guides/run-a-chart-by-name.md) give the refusal text of each rule.
|
|
134
|
+
|
|
135
|
+
## Read next
|
|
136
|
+
|
|
137
|
+
- [Let an Agent write a Chart](../guides/let-an-agent-write-a-chart.md)
|
|
138
|
+
- [Run a Chart by name](../guides/run-a-chart-by-name.md)
|
|
139
|
+
- [Composition](composition.md), [The Menu](the-menu.md), [Agents and Turns](agents-and-turns.md)
|
|
140
|
+
- Reference: [`openBody`](../reference/authoring-surface/openbody.md),
|
|
141
|
+
[`OpenBodyDeclaration`](../reference/authoring-surface/type-openbodydeclaration.md),
|
|
142
|
+
[`OpenBodyOutput`](../reference/authoring-surface/type-openbodyoutput.md),
|
|
143
|
+
[`chartSchema`](../reference/authoring-surface/chartschema.md),
|
|
144
|
+
[`chartSchemaFor`](../reference/authoring-surface/chartschemafor.md),
|
|
145
|
+
[`PUT /workflows/:wrapper/charts/:name`](../reference/http-api.md#put-workflows-wrapper-charts-name)
|
|
146
|
+
- [ADR-0070](../reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md): a Machine lends its parts to a Chart
|