@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
package/src/sandbox-kube.ts
CHANGED
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
// containers:
|
|
44
44
|
//
|
|
45
45
|
// volume runtime the kit's Harness image, as an `image` volume → /opt/jr2
|
|
46
|
-
// volume conversations an emptyDir → /conversations, the Harness container's alone
|
|
46
|
+
// volume conversations an emptyDir → /run/jr2/conversations, the Harness container's alone
|
|
47
47
|
// (ADR-0031: a Harness restart inside the pod keeps its conversations)
|
|
48
48
|
// initContainer preflight the USER'S image + that volume → ADR-0037's probe, the thing that
|
|
49
49
|
// proves a registry ref, whose first appearance is this provision
|
|
@@ -83,11 +83,14 @@ import {
|
|
|
83
83
|
custodianBootstrap,
|
|
84
84
|
custodianComposition,
|
|
85
85
|
custodianScript,
|
|
86
|
+
CREDENTIAL_KEYS,
|
|
87
|
+
heldStandInKey,
|
|
86
88
|
CUSTODIAN_BOOTSTRAP_KEY,
|
|
87
89
|
CUSTODIAN_SCRIPT_KEY,
|
|
88
90
|
type CustodianComposition,
|
|
89
91
|
} from "./custodian.ts";
|
|
90
|
-
import { readHeldManifest, workspaceHeldPod, type HeldManifest } from "./held-secrets.ts";
|
|
92
|
+
import { heldStandIn, readHeldManifest, workspaceHeldPod, type HeldManifest } from "./held-secrets.ts";
|
|
93
|
+
import { markHarnessEnv } from "./harness-env.ts";
|
|
91
94
|
import {
|
|
92
95
|
effectorManifestKey,
|
|
93
96
|
readSandboxEffectorManifest,
|
|
@@ -133,10 +136,14 @@ import {
|
|
|
133
136
|
type SandboxObject,
|
|
134
137
|
type SandboxWatch,
|
|
135
138
|
} from "./sandbox-watch.ts";
|
|
136
|
-
import { effectorKey, harnessToken, harnessTokenDigest, sandboxToken } from "./tokens.ts";
|
|
139
|
+
import { controlStandIn, controlToken, effectorKey, harnessToken, harnessTokenDigest, sandboxToken } from "./tokens.ts";
|
|
137
140
|
import type { AttachError, AttachRequest, AttachResponse } from "./wire.ts";
|
|
138
141
|
import type { Continuity, MemoryKill, PlacingWait, ProvisionedRepo, SandboxLoss, SandboxPort } from "./workspace.ts";
|
|
139
142
|
|
|
143
|
+
/** A Secret's `data`: each value base64'd. */
|
|
144
|
+
const base64Values = (values: Record<string, string>): Record<string, string> =>
|
|
145
|
+
Object.fromEntries(Object.entries(values).map(([k, v]) => [k, Buffer.from(v).toString("base64")]));
|
|
146
|
+
|
|
140
147
|
/** Where jr2's runtime lands in every container that gets it (ADR-0037). `/opt/jr2` and not `/app`
|
|
141
148
|
* because a stranger's base may already use `/app`, and one layout must serve both the stock
|
|
142
149
|
* Harness image and an arbitrary Sandbox Image. It is a PUBLISHED surface: `bin/` beside `lib/`
|
|
@@ -156,11 +163,21 @@ const RUNTIME_VOLUME_MOUNT = { name: RUNTIME_VOLUME, mountPath: RUNTIME_MOUNT, s
|
|
|
156
163
|
/** The primary container's command (ADR-0037). Absolute, so it never depends on the image's
|
|
157
164
|
* `WORKDIR`, and identical to the stock Harness image's own `CMD` — one runtime, two placements.
|
|
158
165
|
* `tini` is PID 1 (ADR-0061): the Agent's processes are the Harness's children, and a tree the
|
|
159
|
-
* memory guard kills must leave no zombies behind.
|
|
166
|
+
* memory guard kills must leave no zombies behind. The Harness holds the Stand-ins in its memory,
|
|
167
|
+
* and below Landlock ABI 6 a confined child can still signal it (ADR-0076): `effector nocore`
|
|
168
|
+
* starts it with no core file, so a dumping signal writes nothing a child reads, and
|
|
169
|
+
* `--disable-sigusr1` keeps SIGUSR1 from opening Node's inspector, which would run a child's code
|
|
170
|
+
* in the Harness. `--harness-env` gives the Harness process only the names jr2 composed, less each
|
|
171
|
+
* name that loads code from a path, and the domain the whole start env (`harness-env.ts`). */
|
|
160
172
|
const HARNESS_COMMAND = [
|
|
161
173
|
`${RUNTIME_MOUNT}/bin/tini`,
|
|
162
174
|
"--",
|
|
175
|
+
`${RUNTIME_MOUNT}/bin/effector`,
|
|
176
|
+
"nocore",
|
|
177
|
+
"--harness-env",
|
|
178
|
+
"--",
|
|
163
179
|
`${RUNTIME_MOUNT}/bin/node`,
|
|
180
|
+
"--disable-sigusr1",
|
|
164
181
|
`${RUNTIME_MOUNT}/src/main.ts`,
|
|
165
182
|
];
|
|
166
183
|
|
|
@@ -834,8 +851,14 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
834
851
|
// Never empty: the Custodian's address is unconditional. The seat's own vars (the fallback
|
|
835
852
|
// `HOME`) come FIRST, so the instance's `harness.env` can still override them the way it
|
|
836
853
|
// overrides anything the image set.
|
|
837
|
-
|
|
838
|
-
...(
|
|
854
|
+
// Marked (`harness-env.ts`, ADR-0076): the Harness's start tells jr2's names from the image's.
|
|
855
|
+
...(() => {
|
|
856
|
+
const marked = markHarnessEnv(
|
|
857
|
+
[...seat.env, ...harnessEnv(req.name, custodian, cpuHintEnv())],
|
|
858
|
+
cfg().envFrom ?? [],
|
|
859
|
+
);
|
|
860
|
+
return { env: marked.env, ...(marked.envFrom.length ? { envFrom: marked.envFrom } : {}) };
|
|
861
|
+
})(),
|
|
839
862
|
// What the AGENT gets: an address on its own loopback and a Stand-in for every credential,
|
|
840
863
|
// and no credential anywhere. The Custodian beside it holds them (ADR-0013, ADR-0059).
|
|
841
864
|
sidecars,
|
|
@@ -902,7 +925,7 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
902
925
|
* `data`, not `stringData`: a server-side apply owns the fields it names, and `stringData` is
|
|
903
926
|
* write-only — it never reads back as the field applied.
|
|
904
927
|
*/
|
|
905
|
-
const applyTokenSecret = async (name: string, owner: KubeObject): Promise<void> => {
|
|
928
|
+
const applyTokenSecret = async (name: string, owner: KubeObject, manifest: HeldManifest): Promise<void> => {
|
|
906
929
|
if (!opts.signingKey) throw new Error("kubeSandbox: a Custodian needs a signingKey to mint its Sandbox token");
|
|
907
930
|
const uid = owner.metadata?.uid;
|
|
908
931
|
if (!uid) throw new Error(`Sandbox "${name}": the CR's apply answered with no uid to own its token Secret`);
|
|
@@ -925,7 +948,19 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
925
948
|
],
|
|
926
949
|
},
|
|
927
950
|
type: "Opaque",
|
|
928
|
-
|
|
951
|
+
// The pod's credentials (ADR-0076, C1, C1b): its fetch token and its control token, which the
|
|
952
|
+
// Custodian alone mounts; its secret control Stand-in; and one secret Stand-in per held secret
|
|
953
|
+
// the pod's manifest names, which the Custodian (for its swap) and the Harness container (as
|
|
954
|
+
// files under `/run/jr2/`) mount. Every one a signed name, so a re-provision re-applies the
|
|
955
|
+
// same values. Never a ConfigMap, the CR, an env, an event or a log line.
|
|
956
|
+
data: base64Values({
|
|
957
|
+
[CREDENTIAL_KEYS.fetchToken]: sandboxToken(opts.signingKey, name),
|
|
958
|
+
[CREDENTIAL_KEYS.controlToken]: controlToken(opts.signingKey, name),
|
|
959
|
+
[CREDENTIAL_KEYS.controlStandIn]: controlStandIn(opts.signingKey, name),
|
|
960
|
+
...Object.fromEntries(
|
|
961
|
+
manifest.secrets.map((s) => [heldStandInKey(s.name), heldStandIn(opts.signingKey!, name, s.name)]),
|
|
962
|
+
),
|
|
963
|
+
}),
|
|
929
964
|
});
|
|
930
965
|
};
|
|
931
966
|
|
|
@@ -1030,7 +1065,7 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
1030
1065
|
},
|
|
1031
1066
|
data: {
|
|
1032
1067
|
[CUSTODIAN_BOOTSTRAP_KEY]: JSON.stringify(custodianBootstrap(manifest, orchestrator)),
|
|
1033
|
-
[CUSTODIAN_SCRIPT_KEY]: custodianScript(manifest),
|
|
1068
|
+
[CUSTODIAN_SCRIPT_KEY]: custodianScript(manifest, { fetch: true }),
|
|
1034
1069
|
},
|
|
1035
1070
|
});
|
|
1036
1071
|
};
|
|
@@ -1257,8 +1292,9 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
1257
1292
|
image: refs.custodian,
|
|
1258
1293
|
pod,
|
|
1259
1294
|
config: sandboxCustodianConfigMap(req.name),
|
|
1260
|
-
|
|
1295
|
+
credentials: { secret: secretName(req.name) },
|
|
1261
1296
|
sandbox: req.name,
|
|
1297
|
+
...(req.secrets?.length ? { granted: req.secrets } : {}),
|
|
1262
1298
|
caBundle: cfg().caBundle === true,
|
|
1263
1299
|
resources: split.custodian,
|
|
1264
1300
|
});
|
|
@@ -1287,7 +1323,7 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
1287
1323
|
sandboxes();
|
|
1288
1324
|
const applied = await kube().apply(SANDBOXES, ns, cr).catch(noOperator(req.name, "Sandbox"));
|
|
1289
1325
|
// After the CR: its uid owns both, so they go when it goes.
|
|
1290
|
-
await applyTokenSecret(req.name, applied);
|
|
1326
|
+
await applyTokenSecret(req.name, applied, manifest);
|
|
1291
1327
|
await applyCustodianConfig(req.name, applied, manifest);
|
|
1292
1328
|
if (effectorManifest) {
|
|
1293
1329
|
await applyEffectorKey(req.name, applied);
|
|
@@ -1394,19 +1430,19 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
1394
1430
|
const endpoint = sandbox?.status?.endpoint;
|
|
1395
1431
|
if (!endpoint) throw new Error(`Sandbox "${req.name}" has no endpoint to attach through — is it gone?`);
|
|
1396
1432
|
if (req.repos.length === 0) {
|
|
1397
|
-
throw new Error(
|
|
1433
|
+
throw new Error(
|
|
1434
|
+
"the attach names no Repo Slot — nothing to attach (a Workspace with no Repo Slot skips the attach, ADR-0051)",
|
|
1435
|
+
);
|
|
1398
1436
|
}
|
|
1399
1437
|
const body: AttachRequest = {
|
|
1400
1438
|
slots: req.repos.map((r) => {
|
|
1401
1439
|
const { identity, key } = repoIdentity(r.url);
|
|
1402
1440
|
return { slot: r.slot, url: r.url, identity, key, ...(r.ref !== undefined ? { ref: r.ref } : {}) };
|
|
1403
1441
|
}),
|
|
1404
|
-
branch: req.spec.branch,
|
|
1405
|
-
...(req.spec.reviewSha ? { reviewSha: req.spec.reviewSha } : {}),
|
|
1406
1442
|
};
|
|
1407
|
-
const { repos,
|
|
1443
|
+
const { repos, bases } = await postAttach(req.name, endpoint, body);
|
|
1408
1444
|
const stale = staleSlots(req.repos, staleByName.get(req.name));
|
|
1409
|
-
return { repos,
|
|
1445
|
+
return { repos, bases, ...(stale ? { stale } : {}) };
|
|
1410
1446
|
},
|
|
1411
1447
|
|
|
1412
1448
|
leaseIntervalMs,
|
|
@@ -1456,7 +1492,20 @@ export function kubeSandbox(opts: KubeSandboxOptions = {}): SandboxPort {
|
|
|
1456
1492
|
async destroy(name) {
|
|
1457
1493
|
staleByName.delete(name);
|
|
1458
1494
|
// The token Secret is the CR's child from birth, so deleting the CR reaps it (ADR-0001).
|
|
1459
|
-
await kube().delete(SANDBOXES, ns, name);
|
|
1495
|
+
await kube().delete(SANDBOXES, ns, name, { foreground: true });
|
|
1496
|
+
// A retry of the same invoke id takes the same name, and the pod takes it too: a new Sandbox
|
|
1497
|
+
// must not find the old pod on its way out, and read `Lost` (ADR-0075). So the wait is
|
|
1498
|
+
// for the pod as well: foreground keeps the CR until the pod is gone. Bounded: a stuck finalizer
|
|
1499
|
+
// is the operator's to report, and the run does not wait on it for ever.
|
|
1500
|
+
for (let i = 0; i < 120; i++) {
|
|
1501
|
+
if (
|
|
1502
|
+
(await kube()
|
|
1503
|
+
.get<SandboxObject>(SANDBOXES, ns, name)
|
|
1504
|
+
.catch(() => undefined)) === undefined
|
|
1505
|
+
)
|
|
1506
|
+
return;
|
|
1507
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
1508
|
+
}
|
|
1460
1509
|
},
|
|
1461
1510
|
};
|
|
1462
1511
|
}
|
package/src/secret-placement.ts
CHANGED
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
// - the Instance Harness: the model keys of the `"none"` Agents it hosts, and nothing else (they
|
|
7
7
|
// cannot execute code, ADR-0031, so nothing else is theirs to use);
|
|
8
8
|
// - an Effector: what its Effects name with `secret("name")` — the Instance Effector what its
|
|
9
|
-
// `http` Effects name
|
|
9
|
+
// `http` Effects name and the token of each `dispatch` with a target (ADR-0071; a dispatch with
|
|
10
|
+
// no target runs in the Orchestrator's own process and names nothing); a Workspace's Sandbox Effector what its file-body `http`s and
|
|
10
11
|
// credentialed `command`s name. The push credential its `push`es spend is not placed here: the provision
|
|
11
12
|
// names the entry the slot's url matches on the Sandbox, by reference (git-push.ts, ADR-0051).
|
|
12
13
|
//
|
|
@@ -27,6 +28,7 @@ import {
|
|
|
27
28
|
type HeldLookups,
|
|
28
29
|
} from "./held-secrets.ts";
|
|
29
30
|
import type { JR2Config } from "./config.ts";
|
|
31
|
+
import { needsASlot } from "./effect.ts";
|
|
30
32
|
import { declaredPushKinds, pushRefusal } from "./git-push.ts";
|
|
31
33
|
import { INSTANCE_HARNESS_HELD_POD } from "./names.ts";
|
|
32
34
|
import { routeText, type CarriedEffect, type WorkspacePod } from "./parts.ts";
|
|
@@ -140,7 +142,36 @@ export function refuseEffectSecrets(config: JR2Config, walk: PlacementWalk): voi
|
|
|
140
142
|
// An empty value is refused later with the list's own rule (`sourceOf`): it is an unset variable.
|
|
141
143
|
if (namedBy.has(e.name) && e.value) shortRefusal(e, e.value.length);
|
|
142
144
|
}
|
|
143
|
-
for (const ws of walk.workspaces)
|
|
145
|
+
for (const ws of walk.workspaces) {
|
|
146
|
+
refuseWithNoSlot(ws);
|
|
147
|
+
pushesOf(config, ws);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
* A Workspace with no Repo Slot (ADR-0051) has no branch and no commit, so the two Sandbox Effector kinds that
|
|
153
|
+
* run on a commit of a slot's branch have none: a `push`, and a `command` with an Effect secret
|
|
154
|
+
* (ADR-0067). A `worktree()` has no clone to cut from (ADR-0075). Refused here, before anything is
|
|
155
|
+
* built, as the invoke would refuse them mid-run. A file-body `http` reads `/work` and stays.
|
|
156
|
+
*/
|
|
157
|
+
function refuseWithNoSlot(ws: PlacedWorkspace): void {
|
|
158
|
+
if (!ws.pod.noSlot) return;
|
|
159
|
+
for (const effect of ws.pod.effects) {
|
|
160
|
+
// Every `command` placed in a Sandbox Effector names a secret: the others run beside the Agent.
|
|
161
|
+
const why = needsASlot(effect.kind);
|
|
162
|
+
if (why === undefined) continue;
|
|
163
|
+
throw new Error(
|
|
164
|
+
`workflow "${ws.workflow}": ${effect.kind} "${effect.name}" runs in ${workspaceLabel(ws)}, which has no Repo ` +
|
|
165
|
+
`Slot: ${why} (ADR-0051)`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
const [cut] = ws.pod.cuts ?? [];
|
|
169
|
+
if (cut !== undefined) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`workflow "${ws.workflow}": worktree "${cut}" runs in ${workspaceLabel(ws)}, which has no Repo Slot: ` +
|
|
172
|
+
`${needsASlot("worktree")} (ADR-0075)`,
|
|
173
|
+
);
|
|
174
|
+
}
|
|
144
175
|
}
|
|
145
176
|
|
|
146
177
|
/**
|
|
@@ -153,7 +184,7 @@ export function secretPlacementsOf(
|
|
|
153
184
|
walk: PlacementWalk,
|
|
154
185
|
lookups: Pick<HeldLookups, "secretKeys" | "valueLength"> = {},
|
|
155
186
|
): SecretPlacements {
|
|
156
|
-
const { entries, namedBy,
|
|
187
|
+
const { entries, namedBy, instancePlaced } = namesOf(config, walk);
|
|
157
188
|
const { pods, redundant } = heldPodsOf(config, walk, new Set(entries.map((e) => e.name)));
|
|
158
189
|
const claimed = new Set(pods.flatMap((p) => p.names));
|
|
159
190
|
|
|
@@ -207,12 +238,12 @@ export function secretPlacementsOf(
|
|
|
207
238
|
report.push(`${label}: secrets lists ${name}, which its Agents' provider claims already — redundant`);
|
|
208
239
|
}
|
|
209
240
|
|
|
210
|
-
const instanceSecrets = new Set(
|
|
241
|
+
const instanceSecrets = new Set(instancePlaced.flatMap((p) => p.effect.secrets));
|
|
211
242
|
const instance =
|
|
212
|
-
|
|
243
|
+
instancePlaced.length === 0
|
|
213
244
|
? undefined
|
|
214
245
|
: effectorPlan(
|
|
215
|
-
|
|
246
|
+
instancePlaced,
|
|
216
247
|
secrets.filter((s) => instanceSecrets.has(s.name)),
|
|
217
248
|
values,
|
|
218
249
|
);
|
|
@@ -267,6 +298,7 @@ function sandboxPlanOf(
|
|
|
267
298
|
x.scheme === t.scheme && x.host === t.host && x.port === t.port && x.secrets.join() === t.secrets.join();
|
|
268
299
|
if (!targets.some(same)) targets.push(t);
|
|
269
300
|
}
|
|
301
|
+
refuseWithNoSlot(ws);
|
|
270
302
|
const pushes = pushesOf(config, ws);
|
|
271
303
|
const commands = ws.pod.effects.some((e) => e.kind === "command" && (e.secrets?.length ?? 0) > 0);
|
|
272
304
|
return {
|
|
@@ -322,10 +354,12 @@ function pushesOf(config: JR2Config, ws: PlacedWorkspace): SandboxPush[] {
|
|
|
322
354
|
return out;
|
|
323
355
|
}
|
|
324
356
|
|
|
325
|
-
function effectorPlan(
|
|
357
|
+
function effectorPlan(placed: InstancePlaced[], secrets: EffectSecret[], values: Record<string, string>): EffectorPlan {
|
|
326
358
|
const targets: EffectorTargetConfig[] = [];
|
|
327
|
-
for (const { effect } of
|
|
328
|
-
// An Open url has no target, so it allows nothing: `jr2 up` refuses
|
|
359
|
+
for (const { effect } of placed) {
|
|
360
|
+
// An Open url or an Open dispatch target has no target, so it allows nothing: `jr2 up` refuses
|
|
361
|
+
// it before this (ADR-0054). A dispatch's target is its origin, its one secret the token
|
|
362
|
+
// (ADR-0071).
|
|
329
363
|
if (effect.target === undefined) continue;
|
|
330
364
|
const t = { ...effect.target, secrets: [...effect.secrets].sort() };
|
|
331
365
|
const same = (x: EffectorTargetConfig) =>
|
|
@@ -337,12 +371,17 @@ function effectorPlan(http: HttpPlaced[], secrets: EffectSecret[], values: Recor
|
|
|
337
371
|
secrets,
|
|
338
372
|
values,
|
|
339
373
|
targets,
|
|
340
|
-
|
|
341
|
-
|
|
374
|
+
// The grace a rollout gives a replica covers the http Effects alone (ADR-0071): a dispatch is
|
|
375
|
+
// idempotent by construction, so a `wait` a rollout cuts is sent again under its key and its
|
|
376
|
+
// poll resumes, and a wait of hours never stretches the Effector's grace.
|
|
377
|
+
longestTimeoutMs: Math.max(0, ...placed.flatMap((p) => (p.effect.kind === "http" ? [p.effect.timeoutMs] : []))),
|
|
378
|
+
effects: placed.map((p) => `${p.workflow}/${p.effect.name}`),
|
|
342
379
|
};
|
|
343
380
|
}
|
|
344
381
|
|
|
345
|
-
|
|
382
|
+
/** An Effect the Instance Effector runs: an http one with no Worktree file, or a dispatch with a
|
|
383
|
+
* target (ADR-0068, ADR-0071). */
|
|
384
|
+
type InstancePlaced = { workflow: string; effect: Extract<CarriedEffect, { kind: "http" | "dispatch" }> };
|
|
346
385
|
|
|
347
386
|
/** A Workspace as a human reads it: its workflow and the placement route to it, an inline hop as
|
|
348
387
|
* `invoked inline in state <id>`. */
|
|
@@ -423,11 +462,14 @@ function namesOf(config: JR2Config, walk: PlacementWalk) {
|
|
|
423
462
|
}
|
|
424
463
|
byName.set(e.name, e);
|
|
425
464
|
}
|
|
426
|
-
// Every Effect that names a secret names it, whatever its kind: an `http` one
|
|
427
|
-
// Effector, a file-body `http` and a credentialed `command` in their
|
|
465
|
+
// Every Effect that names a secret names it, whatever its kind: an `http` one and a `dispatch`'s
|
|
466
|
+
// token in the Instance Effector, a file-body `http` and a credentialed `command` in their
|
|
467
|
+
// Workspace's Sandbox Effector. A dispatch with no target is placed "orchestrator" and names none
|
|
468
|
+
// (ADR-0071).
|
|
428
469
|
const namedBy = new Map<string, Array<{ label: string; where: string }>>();
|
|
429
|
-
const
|
|
430
|
-
(p): p is
|
|
470
|
+
const instancePlaced = walk.effects.filter(
|
|
471
|
+
(p): p is InstancePlaced =>
|
|
472
|
+
(p.effect.kind === "http" || p.effect.kind === "dispatch") && p.effect.placement === "instance",
|
|
431
473
|
);
|
|
432
474
|
// Keyed by the Effect's placement route and slot name, as workspacePodsOf keys a pod's Effects:
|
|
433
475
|
// two slots of one name in one workflow — one in a workspace(), one outside it — are two Effects,
|
|
@@ -463,7 +505,7 @@ function namesOf(config: JR2Config, walk: PlacementWalk) {
|
|
|
463
505
|
namedBy.set(name, [...(namedBy.get(name) ?? []), { label, where }]);
|
|
464
506
|
}
|
|
465
507
|
}
|
|
466
|
-
return { entries, namedBy,
|
|
508
|
+
return { entries, namedBy, instancePlaced };
|
|
467
509
|
}
|
|
468
510
|
|
|
469
511
|
/** An Effect secret shorter than 8 characters is refused, and the refusal says why. */
|
package/src/server.ts
CHANGED
|
@@ -295,6 +295,9 @@ export async function serverMain(opts: ServerMainOptions): Promise<RunningInstan
|
|
|
295
295
|
instanceHarness: namespace
|
|
296
296
|
? `http://${INSTANCE_HARNESS_SERVICE}.${namespace}.svc:${INSTANCE_HARNESS_PORT}`
|
|
297
297
|
: undefined,
|
|
298
|
+
// What a foreign dispatch names this Orchestrator by at the callee's door (ADR-0071): its
|
|
299
|
+
// namespace, which is stable and not secret — never a run's Instance ID.
|
|
300
|
+
...(namespace ? { orchestratorName: namespace } : {}),
|
|
298
301
|
// Where an http Effect runs (ADR-0068): the Instance Effector's headless Service. `jr2 up`
|
|
299
302
|
// converges it whenever a registered Machine carries an http Effect.
|
|
300
303
|
...(namespace ? { instanceEffector: `${INSTANCE_EFFECTOR}.${namespace}.svc:${EFFECTOR_PORT}` } : {}),
|