@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,33 @@
|
|
|
1
|
+
// What a Harness container's env tells its start (ADR-0076): which names jr2 composed. The Harness
|
|
2
|
+
// starts as `effector nocore --harness-env -- node …`, and that gives the Harness PROCESS only the
|
|
3
|
+
// names jr2 composed, less each name that loads code from a path (`NODE_OPTIONS`, `LD_*`,
|
|
4
|
+
// `OPENSSL_CONF` …), because the image's `ENV` can name a file that Workspace code writes. The
|
|
5
|
+
// domain, where the Agent's programs run, still gets the container's whole start env.
|
|
6
|
+
//
|
|
7
|
+
// Two marks make the names jr2 composed visible inside the container:
|
|
8
|
+
// - `JR2_HARNESS_ENV_NAMES`: the names of the container's `env`, comma-separated.
|
|
9
|
+
// - The prefix `JR2_ENVFROM_` before each `envFrom` key (with a source's own prefix after it):
|
|
10
|
+
// its keys are not known here, a user's Secret or ConfigMap among them. The start puts each key
|
|
11
|
+
// back under its own name, below a name of `env`, as Kubernetes orders them.
|
|
12
|
+
|
|
13
|
+
/** The env name that lists the names of the Harness container's `env`. */
|
|
14
|
+
export const HARNESS_ENV_NAMES_ENV = "JR2_HARNESS_ENV_NAMES";
|
|
15
|
+
|
|
16
|
+
/** The prefix before each `envFrom` key of a Harness container. */
|
|
17
|
+
export const HARNESS_ENVFROM_PREFIX = "JR2_ENVFROM_";
|
|
18
|
+
|
|
19
|
+
/** The Harness container's `env` with `JR2_HARNESS_ENV_NAMES` last, and its `envFrom` with the
|
|
20
|
+
* prefix `JR2_ENVFROM_`. Both Harness placements use it: a Sandbox's and the Instance Harness. */
|
|
21
|
+
export function markHarnessEnv<E extends { name: string }, F extends { prefix?: string }>(
|
|
22
|
+
env: readonly E[],
|
|
23
|
+
envFrom: readonly F[],
|
|
24
|
+
): { env: (E | { name: string; value: string })[]; envFrom: F[] } {
|
|
25
|
+
const names = [...new Set(env.map((v) => v.name))].filter((n) => n !== HARNESS_ENV_NAMES_ENV);
|
|
26
|
+
return {
|
|
27
|
+
env: [
|
|
28
|
+
...env.filter((v) => v.name !== HARNESS_ENV_NAMES_ENV),
|
|
29
|
+
{ name: HARNESS_ENV_NAMES_ENV, value: names.join(",") },
|
|
30
|
+
],
|
|
31
|
+
envFrom: envFrom.map((f) => ({ ...f, prefix: `${HARNESS_ENVFROM_PREFIX}${f.prefix ?? ""}` })),
|
|
32
|
+
};
|
|
33
|
+
}
|
package/src/held-secrets.ts
CHANGED
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
//
|
|
10
10
|
// This module is the pure half, shared by every seat that needs it:
|
|
11
11
|
//
|
|
12
|
-
//
|
|
12
|
+
// heldStandIn(...) a held secret's Stand-in, minted per pod by the pod's maker — secret
|
|
13
|
+
// standIn(name) the fetch Stand-in's form — deterministic and public, for that one alone
|
|
13
14
|
// heldSecretsOf(...) `jr2 up`'s normalization of the claimed entries: every refusal (R1–R13),
|
|
14
15
|
// every warning, and the engine-neutral bindings each pod's manifest
|
|
15
16
|
// (`held-<pod>.json`) takes its own from
|
|
@@ -23,23 +24,46 @@ import { createHash } from "node:crypto";
|
|
|
23
24
|
import { readFile } from "node:fs/promises";
|
|
24
25
|
import { isIP } from "node:net";
|
|
25
26
|
import type { JR2Config, HarnessEnvVar } from "./config.ts";
|
|
26
|
-
import {
|
|
27
|
-
|
|
27
|
+
import {
|
|
28
|
+
CREDENTIAL_FILES,
|
|
29
|
+
DOMAIN_WRITABLE_ROOTS,
|
|
30
|
+
MODEL_KEYS,
|
|
31
|
+
MODEL_KEY_PROVIDERS,
|
|
32
|
+
SIGNING_CREDENTIALS,
|
|
33
|
+
} from "./model-keys.ts";
|
|
34
|
+
import {
|
|
35
|
+
HELD_CA_SECRET,
|
|
36
|
+
HELD_SECRETS_SECRET,
|
|
37
|
+
HELD_TLS_SECRET,
|
|
38
|
+
INSTANCE_EFFECTOR,
|
|
39
|
+
INSTANCE_HARNESS_SERVICE,
|
|
40
|
+
INSTANCE_SECRET,
|
|
41
|
+
} from "./names.ts";
|
|
28
42
|
import type { PlacementRoute } from "./parts.ts";
|
|
43
|
+
import { sign } from "./tokens.ts";
|
|
29
44
|
|
|
30
45
|
/** The kit's Secrets no Harness container may read (R13): the Instance token and signing key, each
|
|
31
46
|
* pod's literal held values, the leaves, the CA, and every Effector's (ADR-0068) — the Instance
|
|
32
47
|
* Effector's Effect secrets and key, each Workspace's Sandbox Effector Secret (`jr2-effector-<pod>`),
|
|
33
48
|
* each Sandbox's Effector key (`<sandbox>-effector`), and each `git.credentials` entry's clone and
|
|
34
|
-
* push Secrets (`jr2-git-<hash>`, `jr2-git-push-<hash>`, ADR-0051)
|
|
35
|
-
|
|
49
|
+
* push Secrets (`jr2-git-<hash>`, `jr2-git-push-<hash>`, ADR-0051) — and each pod's own credentials
|
|
50
|
+
* (ADR-0076): the Instance Harness's (`jr2-instance-harness-token`) and each Sandbox's
|
|
51
|
+
* (`<sandbox>-token`), which hold the real control token beside the Stand-ins. */
|
|
52
|
+
const KIT_SECRETS: readonly string[] = [
|
|
53
|
+
INSTANCE_SECRET,
|
|
54
|
+
HELD_TLS_SECRET,
|
|
55
|
+
HELD_CA_SECRET,
|
|
56
|
+
INSTANCE_EFFECTOR,
|
|
57
|
+
`${INSTANCE_HARNESS_SERVICE}-token`,
|
|
58
|
+
];
|
|
36
59
|
const KIT_SECRET_PREFIXES: readonly string[] = [`${HELD_SECRETS_SECRET}-`, "jr2-effector-", "jr2-git-"];
|
|
37
60
|
const isKitSecret = (name: string): boolean =>
|
|
38
61
|
KIT_SECRETS.includes(name) ||
|
|
39
62
|
name === HELD_SECRETS_SECRET ||
|
|
40
63
|
KIT_SECRET_PREFIXES.some((p) => name.startsWith(p)) ||
|
|
41
|
-
// A Sandbox's own Effector key: every Sandbox's name starts `ws-`
|
|
42
|
-
(
|
|
64
|
+
// A Sandbox's own Effector key and its credentials: every Sandbox's name starts `ws-`
|
|
65
|
+
// (`workspaceName`).
|
|
66
|
+
(name.startsWith("ws-") && (name.endsWith("-effector") || name.endsWith("-token")));
|
|
43
67
|
|
|
44
68
|
/**
|
|
45
69
|
* The pod key of one Workspace (ADR-0059): its registered workflow and the placement route to its
|
|
@@ -70,18 +94,36 @@ export function providerClaims(config: JR2Config, models: readonly string[]): st
|
|
|
70
94
|
}
|
|
71
95
|
|
|
72
96
|
/**
|
|
73
|
-
* The Stand-in
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* something only to the Custodian and only toward a bound host. Unique per name, so one request can
|
|
77
|
-
* carry two secrets' Stand-ins and the Custodian can tell them apart. ASCII letters, digits, `-`
|
|
78
|
-
* and `_` only, so it is a valid header and env value; and it never contains `sk-ant-oat`, which pi
|
|
79
|
-
* reads as an Anthropic OAuth token and answers with different auth headers.
|
|
97
|
+
* The PUBLIC Stand-in form, `jr2-held-<NAME>`. Since ADR-0076 one Stand-in alone takes it: the fetch
|
|
98
|
+
* Stand-in, `standIn("JR2_SANDBOX_TOKEN")`, which `jr2-upload-pack` holds as a constant and the
|
|
99
|
+
* Custodian swaps on the fetch route alone. Every other Stand-in is secret ({@link heldStandIn}).
|
|
80
100
|
*/
|
|
81
101
|
export function standIn(name: string): string {
|
|
82
102
|
return `jr2-held-${name}`;
|
|
83
103
|
}
|
|
84
104
|
|
|
105
|
+
/** What a Stand-in must never contain (ADR-0059): pi reads a key with it as an Anthropic OAuth
|
|
106
|
+
* token, and answers with different auth headers. */
|
|
107
|
+
const OAUTH_MARK = "sk-ant-oat";
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The SECRET Stand-in of one held secret in one pod (ADR-0059, ADR-0076): what the Harness process
|
|
111
|
+
* holds for it, as the file `/run/jr2/standins/<NAME>`, and what the Custodian of that pod swaps for
|
|
112
|
+
* the value. `jr2-held-<NAME>.<hmac>` — the readable prefix keeps a log scrub's pattern, and the
|
|
113
|
+
* HMAC under the signing key makes it unguessable, so Workspace code can spend only the secrets its
|
|
114
|
+
* `workspace()` grants. `pod` is the Sandbox's name, or `instance` for the Instance Harness. The
|
|
115
|
+
* pod's maker mints it: the Orchestrator for a Sandbox, `jr2 up` for the Instance Harness and a
|
|
116
|
+
* check pod. ASCII letters, digits, `-`, `_` and `.` only, so it is a valid header and env value,
|
|
117
|
+
* and it never contains `sk-ant-oat`: a signature that would is signed again under a counter.
|
|
118
|
+
*/
|
|
119
|
+
export function heldStandIn(key: Buffer, pod: string, name: string): string {
|
|
120
|
+
for (let n = 0; ; n++) {
|
|
121
|
+
const domain = `held-standin:${pod}/${name}${n === 0 ? "" : `#${n}`}`;
|
|
122
|
+
const value = `${standIn(name)}.${sign(key, domain)}`;
|
|
123
|
+
if (!value.includes(OAUTH_MARK)) return value;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
85
127
|
/** The request headers a Stand-in is swapped in when a held secret names none — the four places a
|
|
86
128
|
* model API carries its key: `Authorization: Bearer` (OpenAI-compatible, `ANTHROPIC_AUTH_TOKEN`),
|
|
87
129
|
* `x-api-key` (Anthropic), `x-goog-api-key` (Gemini), `api-key` (Azure). */
|
|
@@ -99,10 +141,15 @@ export const CREDENTIAL_HEADERS: readonly string[] = [...DEFAULT_CREDENTIAL_HEAD
|
|
|
99
141
|
/** The env var the custom provider's key rides as (ADR-0018) — held since ADR-0059, and the kit's. */
|
|
100
142
|
export const PROVIDER_KEY_NAME = "JR2_PROVIDER_API_KEY";
|
|
101
143
|
|
|
102
|
-
/** The
|
|
103
|
-
* Orchestrator (ADR-0059).
|
|
144
|
+
/** The fetch token's held name (ADR-0013, ADR-0076) — a held secret of the kit's own, bound to the
|
|
145
|
+
* Orchestrator's fetch route (ADR-0059). Its Stand-in is the public `jr2-held-JR2_SANDBOX_TOKEN`,
|
|
146
|
+
* which `jr2-upload-pack` holds; the Custodian holds the token. */
|
|
104
147
|
export const SANDBOX_TOKEN_NAME = "JR2_SANDBOX_TOKEN";
|
|
105
148
|
|
|
149
|
+
/** The control token's held name (ADR-0076) — the kit's own, bound to the agent routes. Its Stand-in
|
|
150
|
+
* is secret: the Harness process alone holds it, as `/run/jr2/control/standin`. */
|
|
151
|
+
export const CONTROL_TOKEN_NAME = "JR2_CONTROL_TOKEN";
|
|
152
|
+
|
|
106
153
|
/** The env names the mechanism owns on a Harness container (ADR-0059): the proxy, the trust
|
|
107
154
|
* bundles, and every `JR2_` name. A held secret may not choose them, and while a held secret exists,
|
|
108
155
|
* `harness.env` may not either — the Custodian cannot chain to a second proxy yet (R11). */
|
|
@@ -233,6 +280,35 @@ export function heldSecretsOf(
|
|
|
233
280
|
catalogHosts.set(id, target.port === 443 ? target.host : `${target.host}:${target.port}`);
|
|
234
281
|
}
|
|
235
282
|
|
|
283
|
+
// jr2's own names (ADR-0076): the Harness's start takes a `JR2_` name from jr2's composition alone,
|
|
284
|
+
// and refuses to start on an envFrom key that starts with `JR2_` (`effector nocore --harness-env`).
|
|
285
|
+
// A user's `JR2_MENU_ONLY` or `JR2_START_ENV` would turn the domain off or replace its env.
|
|
286
|
+
for (const [i, v] of env.entries()) {
|
|
287
|
+
if (v.name.startsWith("JR2_")) {
|
|
288
|
+
throw new Error(
|
|
289
|
+
`harness.env[${i}] sets ${v.name}: JR2_ names are jr2's own, and the Harness takes them from jr2 alone ` +
|
|
290
|
+
"(ADR-0076). Name the env var your program reads.",
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
for (const [i, ref] of (harness.envFrom ?? []).entries()) {
|
|
295
|
+
const lookup = ref.secretRef
|
|
296
|
+
? `secret/${ref.secretRef.name}`
|
|
297
|
+
: ref.configMapRef
|
|
298
|
+
? `configmap/${ref.configMapRef.name}`
|
|
299
|
+
: "";
|
|
300
|
+
const own = (lookups.envFromKeys?.get(lookup) ?? [])
|
|
301
|
+
.map((key) => (ref.prefix ?? "") + key)
|
|
302
|
+
.find((key) => key.startsWith("JR2_"));
|
|
303
|
+
if (own !== undefined) {
|
|
304
|
+
const where = ref.secretRef ? `Secret "${ref.secretRef.name}"` : `ConfigMap "${ref.configMapRef?.name}"`;
|
|
305
|
+
throw new Error(
|
|
306
|
+
`harness.envFrom[${i}] loads ${where}, which carries ${own}: JR2_ names are jr2's own, and the Harness ` +
|
|
307
|
+
"does not start with one from envFrom (ADR-0076). Drop the key, or give the source a prefix.",
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
236
312
|
// R1: a known model key the Agent could read.
|
|
237
313
|
for (const [i, v] of env.entries()) {
|
|
238
314
|
if (!(v.name in MODEL_KEYS)) continue;
|
|
@@ -268,6 +344,39 @@ export function heldSecretsOf(
|
|
|
268
344
|
}
|
|
269
345
|
}
|
|
270
346
|
|
|
347
|
+
// A credential file that the Harness process reads (ADR-0076): never one that the domain writes.
|
|
348
|
+
for (const [i, v] of env.entries()) {
|
|
349
|
+
if (!CREDENTIAL_FILES.includes(v.name)) continue;
|
|
350
|
+
const path = v.value;
|
|
351
|
+
if (path !== undefined) {
|
|
352
|
+
const writable = DOMAIN_WRITABLE_ROOTS.find((root) => path === root || path.startsWith(`${root}/`));
|
|
353
|
+
if (!path.startsWith("/") || writable !== undefined || path.split("/").includes("..")) {
|
|
354
|
+
throw new Error(
|
|
355
|
+
`harness.env[${i}] sets ${v.name} to "${path}", ${writable !== undefined ? `which is in ${writable}, a folder the Agent's code writes` : "which is not an absolute path"}: the Harness process reads that file, and code that writes it acts outside the Agent's confinement (ADR-0076). Point it at a file of the image that the Sandbox's user cannot write.`,
|
|
356
|
+
);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
warnings.push(
|
|
360
|
+
`harness.env sets ${v.name}: the Harness process reads ${path !== undefined ? `"${path}"` : "the file it names"}, ` +
|
|
361
|
+
"so the Sandbox's user must not be able to write it — a folder of the image that the user owns is one the " +
|
|
362
|
+
"Agent's code writes (ADR-0076)",
|
|
363
|
+
);
|
|
364
|
+
}
|
|
365
|
+
for (const [i, ref] of (harness.envFrom ?? []).entries()) {
|
|
366
|
+
const lookup = ref.secretRef
|
|
367
|
+
? `secret/${ref.secretRef.name}`
|
|
368
|
+
: ref.configMapRef
|
|
369
|
+
? `configmap/${ref.configMapRef.name}`
|
|
370
|
+
: "";
|
|
371
|
+
for (const key of (lookups.envFromKeys?.get(lookup) ?? []).map((k) => (ref.prefix ?? "") + k)) {
|
|
372
|
+
if (!CREDENTIAL_FILES.includes(key)) continue;
|
|
373
|
+
warnings.push(
|
|
374
|
+
`harness.envFrom[${i}] sets ${key}: the Harness process reads the file it names, so the Sandbox's user must ` +
|
|
375
|
+
"not be able to write it — a folder of the image that the user owns is one the Agent's code writes (ADR-0076)",
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
271
380
|
type Entry = {
|
|
272
381
|
at: string;
|
|
273
382
|
name: string;
|
package/src/holds.ts
CHANGED
|
@@ -38,6 +38,9 @@ export type Hold = {
|
|
|
38
38
|
/** The Sandbox whose token may read the answer (ADR-0013) — the registration's, kept because the
|
|
39
39
|
* answer outlives a registration that a route out of the Agent's state ends. */
|
|
40
40
|
sandbox?: string;
|
|
41
|
+
/** The slot whose stated control requests may read the answer (ADR-0076) — the registration's,
|
|
42
|
+
* kept with `sandbox` for the same reason. */
|
|
43
|
+
slot?: string;
|
|
41
44
|
/** The invoke id of the Agent's state when the pick was made: a re-registration of the same
|
|
42
45
|
* address by another state is another Turn. */
|
|
43
46
|
invokeId?: string;
|