@jr2/orchestrator 0.5.1 → 0.7.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/console/components/app.ts +55 -15
- package/console/components/bottom-drawer.ts +259 -0
- package/console/components/drawer.ts +14 -6
- package/console/components/fleet.ts +36 -13
- package/console/components/machine-pane.ts +61 -5
- package/console/components/nav.ts +54 -8
- package/console/conversation.ts +161 -0
- package/console/login.ts +123 -0
- package/console/main.ts +600 -60
- package/console/store.ts +611 -64
- package/console/style.css +231 -0
- package/docs/agents-block.md +2 -2
- package/docs/concepts/agents-and-turns.md +142 -29
- package/docs/concepts/architecture.md +60 -34
- package/docs/concepts/callers-and-hooks.md +205 -0
- package/docs/concepts/charts.md +13 -8
- package/docs/concepts/composition.md +10 -1
- package/docs/concepts/converge.md +7 -2
- package/docs/concepts/durable-runs.md +43 -16
- package/docs/concepts/effects.md +133 -50
- package/docs/concepts/gates.md +95 -25
- package/docs/concepts/machines-and-workflows.md +14 -4
- package/docs/concepts/pools-and-sources.md +193 -17
- package/docs/concepts/secrets-and-trust.md +186 -62
- package/docs/concepts/the-menu.md +14 -0
- package/docs/concepts/workspaces.md +135 -56
- package/docs/get-started/a-model-decides.md +14 -13
- package/docs/get-started/an-agent-in-a-sandbox.md +46 -35
- package/docs/get-started/connect-a-model.md +1 -1
- package/docs/get-started/create-an-instance.md +17 -14
- package/docs/get-started/have-your-assistant-write-a-machine.md +111 -40
- package/docs/get-started/install.md +4 -0
- package/docs/guides/add-tools-to-the-sandbox.md +72 -15
- package/docs/guides/answer-a-gate-from-a-forge.md +304 -0
- package/docs/guides/answer-a-gate.md +74 -37
- package/docs/guides/bind-open-parts.md +29 -12
- package/docs/guides/call-an-mcp-tool-from-a-machine.md +572 -0
- package/docs/guides/cancel-a-run.md +26 -16
- package/docs/guides/cut-a-worktree.md +560 -0
- package/docs/guides/fix-a-failed-converge.md +19 -7
- package/docs/guides/give-a-caller-a-scope.md +203 -0
- package/docs/guides/give-an-agent-mcp-tools.md +422 -0
- package/docs/guides/iterate-on-a-machine-on-kind.md +10 -9
- package/docs/guides/let-an-agent-write-a-chart.md +14 -7
- package/docs/guides/look-inside-a-sandbox.md +115 -42
- package/docs/guides/move-from-kind-to-a-shared-cluster.md +16 -0
- package/docs/guides/open-the-console.md +63 -14
- package/docs/guides/push-and-sign-a-branch.md +67 -21
- package/docs/guides/read-a-conversation.md +225 -0
- package/docs/guides/run-a-chart-by-name.md +17 -16
- package/docs/guides/run-a-command-or-call-a-url.md +84 -41
- package/docs/guides/run-one-worker-per-item.md +34 -27
- package/docs/guides/set-an-agents-access-and-dials.md +69 -22
- package/docs/guides/size-a-workspace.md +19 -6
- package/docs/guides/start-a-run-for-each-alert.md +290 -0
- package/docs/guides/start-a-run-from-a-run.md +18 -16
- package/docs/guides/start-a-run.md +24 -18
- package/docs/guides/steer-an-agent.md +332 -0
- package/docs/guides/use-a-hosted-provider.md +7 -1
- package/docs/guides/watch-a-run.md +146 -117
- package/docs/guides/write-a-hook-kind.md +238 -0
- package/docs/guides/write-a-tool-as-an-mcp-server.md +351 -0
- package/docs/guides/write-a-workflow.md +18 -8
- package/docs/llms.txt +110 -23
- package/docs/reference/authoring-surface/agent.md +35 -12
- package/docs/reference/authoring-surface/answer.md +20 -4
- package/docs/reference/authoring-surface/arg.md +28 -6
- package/docs/reference/authoring-surface/basic.md +1 -1
- package/docs/reference/authoring-surface/bearer.md +1 -1
- package/docs/reference/authoring-surface/branchname.md +15 -0
- package/docs/reference/authoring-surface/carry.md +23 -0
- package/docs/reference/authoring-surface/chartschema.md +1 -1
- package/docs/reference/authoring-surface/chartschemafor.md +1 -1
- package/docs/reference/authoring-surface/command.md +37 -22
- package/docs/reference/authoring-surface/customize.md +4 -1
- package/docs/reference/authoring-surface/defineconfig.md +1 -1
- package/docs/reference/authoring-surface/defineevent.md +1 -1
- package/docs/reference/authoring-surface/dispatch.md +5 -4
- package/docs/reference/authoring-surface/fail.md +18 -5
- package/docs/reference/authoring-surface/file.md +37 -17
- package/docs/reference/authoring-surface/frompick.md +1 -1
- package/docs/reference/authoring-surface/gate.md +118 -0
- package/docs/reference/authoring-surface/group-agents.md +15 -0
- package/docs/reference/authoring-surface/group-charts.md +16 -0
- package/docs/reference/authoring-surface/group-composition.md +25 -0
- package/docs/reference/authoring-surface/group-config.md +17 -0
- package/docs/reference/authoring-surface/group-effects.md +48 -0
- package/docs/reference/authoring-surface/group-failure.md +13 -0
- package/docs/reference/authoring-surface/group-gates.md +16 -0
- package/docs/reference/authoring-surface/group-machine-and-events.md +15 -0
- package/docs/reference/authoring-surface/group-steering.md +12 -0
- package/docs/reference/authoring-surface/group-types-these-signatures-name.md +137 -0
- package/docs/reference/authoring-surface/group-workspaces-and-repos.md +15 -0
- package/docs/reference/authoring-surface/http.md +109 -9
- package/docs/reference/authoring-surface/isfailure.md +1 -1
- package/docs/reference/authoring-surface/isready.md +14 -0
- package/docs/reference/authoring-surface/jr2setup.md +14 -4
- package/docs/reference/authoring-surface/mcp.md +107 -0
- package/docs/reference/authoring-surface/open.md +41 -8
- package/docs/reference/authoring-surface/openbody.md +1 -1
- package/docs/reference/authoring-surface/paramsof.md +23 -5
- package/docs/reference/authoring-surface/pool.md +79 -11
- package/docs/reference/authoring-surface/push.md +31 -13
- package/docs/reference/authoring-surface/readyof.md +21 -0
- package/docs/reference/authoring-surface/reread.md +19 -0
- package/docs/reference/authoring-surface/secret.md +26 -5
- package/docs/reference/authoring-surface/sentby.md +1 -1
- package/docs/reference/authoring-surface/skip.md +22 -0
- package/docs/reference/authoring-surface/source.md +59 -4
- package/docs/reference/authoring-surface/steer.md +93 -0
- package/docs/reference/authoring-surface/text.md +1 -1
- package/docs/reference/authoring-surface/type-agentdefinition.md +16 -3
- package/docs/reference/authoring-surface/type-agentmcpserver.md +54 -0
- package/docs/reference/authoring-surface/type-agentslots.md +4 -1
- 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-bindactors.md +14 -0
- package/docs/reference/authoring-surface/type-binding.md +6 -7
- package/docs/reference/authoring-surface/type-caller.md +40 -0
- package/docs/reference/authoring-surface/type-callerrecord.md +32 -0
- package/docs/reference/authoring-surface/type-carry.md +19 -0
- package/docs/reference/authoring-surface/type-chainlink.md +3 -3
- package/docs/reference/authoring-surface/type-commandinput.md +4 -3
- package/docs/reference/authoring-surface/type-commandoptions.md +0 -22
- package/docs/reference/authoring-surface/type-commandoutput.md +23 -5
- package/docs/reference/authoring-surface/type-customize.md +20 -3
- package/docs/reference/authoring-surface/type-delivered.md +17 -0
- package/docs/reference/authoring-surface/type-deliveredevent.md +18 -0
- package/docs/reference/authoring-surface/type-dispatchdefinition.md +4 -3
- package/docs/reference/authoring-surface/type-dispatchoutput.md +9 -2
- package/docs/reference/authoring-surface/type-doorlessinput.md +19 -0
- package/docs/reference/authoring-surface/type-effectbinding.md +12 -2
- package/docs/reference/authoring-surface/type-filebody.md +4 -8
- package/docs/reference/authoring-surface/type-framepath.md +14 -0
- package/docs/reference/authoring-surface/type-gatebinding.md +15 -0
- package/docs/reference/authoring-surface/type-gatehooks.md +12 -0
- package/docs/reference/authoring-surface/type-gatelook.md +37 -0
- package/docs/reference/authoring-surface/type-gateoutcome.md +32 -0
- package/docs/reference/authoring-surface/type-gatereply.md +19 -0
- package/docs/reference/authoring-surface/type-gateslot.md +21 -0
- package/docs/reference/authoring-surface/type-gateslotinput.md +13 -0
- package/docs/reference/authoring-surface/type-gateslotparts.md +18 -0
- package/docs/reference/authoring-surface/type-gateslots.md +12 -0
- package/docs/reference/authoring-surface/type-gatetypesat.md +13 -0
- package/docs/reference/authoring-surface/type-hostinjectedinput.md +3 -5
- package/docs/reference/authoring-surface/type-httpdefinition.md +6 -3
- package/docs/reference/authoring-surface/type-httpfileinput.md +20 -0
- package/docs/reference/authoring-surface/type-httpoutput.md +8 -2
- package/docs/reference/authoring-surface/type-jr2config.md +37 -2
- package/docs/reference/authoring-surface/type-lateroutcome.md +21 -0
- package/docs/reference/authoring-surface/type-lends.md +5 -1
- package/docs/reference/authoring-surface/type-lookoutput.md +14 -0
- package/docs/reference/authoring-surface/type-mcpcalloutput.md +78 -0
- package/docs/reference/authoring-surface/type-mcpnotreturned.md +42 -0
- package/docs/reference/authoring-surface/type-mcpoptions.md +47 -0
- package/docs/reference/authoring-surface/type-mcpoutput.md +50 -0
- package/docs/reference/authoring-surface/type-mcpreadoutput.md +53 -0
- package/docs/reference/authoring-surface/type-mcpremoteserver.md +50 -0
- package/docs/reference/authoring-surface/type-mcpserver.md +41 -0
- package/docs/reference/authoring-surface/type-mcpstdioserver.md +42 -0
- package/docs/reference/authoring-surface/type-namedsecret.md +4 -4
- package/docs/reference/authoring-surface/type-namestart.md +77 -0
- package/docs/reference/authoring-surface/type-noslotworkspaceoptions.md +1 -6
- package/docs/reference/authoring-surface/type-notworktreekeys.md +12 -0
- package/docs/reference/authoring-surface/type-openbodydeclaration.md +1 -1
- package/docs/reference/authoring-surface/type-openbodyoutput.md +1 -1
- package/docs/reference/authoring-surface/type-opencommandinput.md +7 -2
- package/docs/reference/authoring-surface/type-permissivenoslotworkspaceoptions.md +1 -6
- package/docs/reference/authoring-surface/type-permissiveworkspaceoptions.md +5 -10
- package/docs/reference/authoring-surface/type-poolnextinput.md +22 -0
- package/docs/reference/authoring-surface/type-poolspec.md +11 -6
- package/docs/reference/authoring-surface/type-pushinput.md +22 -3
- package/docs/reference/authoring-surface/type-pushoutput.md +33 -8
- package/docs/reference/authoring-surface/type-pushsourcespec.md +38 -0
- package/docs/reference/authoring-surface/type-readsourcespec.md +47 -0
- package/docs/reference/authoring-surface/type-reposlot.md +6 -6
- package/docs/reference/authoring-surface/type-reread.md +18 -0
- package/docs/reference/authoring-surface/type-runsconfig.md +41 -0
- package/docs/reference/authoring-surface/type-sandboxoptions.md +11 -4
- package/docs/reference/authoring-surface/type-sender.md +26 -1
- package/docs/reference/authoring-surface/type-sendercallerfield.md +14 -0
- package/docs/reference/authoring-surface/type-size.md +1 -1
- package/docs/reference/authoring-surface/type-skip.md +19 -0
- package/docs/reference/authoring-surface/type-slothandles.md +5 -13
- package/docs/reference/authoring-surface/type-sourcehooks.md +23 -0
- package/docs/reference/authoring-surface/type-sourcein.md +25 -0
- package/docs/reference/authoring-surface/type-sourcereply.md +18 -0
- package/docs/reference/authoring-surface/type-sourcespec.md +26 -17
- package/docs/reference/authoring-surface/type-sourceverdict.md +49 -0
- package/docs/reference/authoring-surface/type-standingpoolmachine.md +12 -0
- package/docs/reference/authoring-surface/type-standingpoolspec.md +51 -0
- package/docs/reference/authoring-surface/type-steerargs.md +20 -0
- package/docs/reference/authoring-surface/type-thinkinglevel.md +1 -1
- package/docs/reference/authoring-surface/type-usercontainer.md +1 -1
- package/docs/reference/authoring-surface/type-workspaced.md +30 -9
- package/docs/reference/authoring-surface/type-workspacehandles.md +5 -6
- package/docs/reference/authoring-surface/type-workspaceoptions.md +1 -13
- 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 +66 -38
- package/docs/reference/authoring-surface/worktree.md +71 -0
- package/docs/reference/authoring-surface.md +88 -147
- package/docs/reference/cli.md +413 -74
- package/docs/reference/config.md +248 -6
- package/docs/reference/decisions/0001-operator-owned-generic-sandbox.md +10 -9
- package/docs/reference/decisions/0002-duplex-streaming-actor.md +81 -14
- package/docs/reference/decisions/0004-worktree-provisioning-model.md +27 -21
- package/docs/reference/decisions/0005-sandbox-pod-composition.md +39 -25
- package/docs/reference/decisions/0006-agent-control-surface.md +6 -3
- package/docs/reference/decisions/0007-durable-machine-state.md +1 -1
- package/docs/reference/decisions/0009-cli-and-instance-interface.md +150 -49
- package/docs/reference/decisions/0010-bdd-acceptance-tests.md +5 -3
- package/docs/reference/decisions/0011-workflow-defined-events.md +256 -12
- package/docs/reference/decisions/0012-workspace-wrapper-machine.md +39 -32
- package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +54 -30
- package/docs/reference/decisions/0014-observation-is-open-run-state-is-not.md +53 -27
- package/docs/reference/decisions/0015-authoring-surface-absorbs-the-mechanism.md +26 -16
- package/docs/reference/decisions/0016-agent-turn-mechanics-are-internal.md +9 -7
- package/docs/reference/decisions/0017-pool-over-a-source-port.md +226 -10
- package/docs/reference/decisions/0018-instance-agents-are-definitions-jr2-assembles-the-harness.md +15 -7
- package/docs/reference/decisions/0019-one-converging-command-against-the-current-context.md +53 -27
- package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +16 -2
- package/docs/reference/decisions/0022-observation-is-a-level-triggered-feed.md +4 -4
- package/docs/reference/decisions/0023-the-harness-prints-the-conversation.md +124 -43
- package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +36 -38
- package/docs/reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md +10 -5
- package/docs/reference/decisions/0027-the-harness-is-jr2s-own-server-flue-retires-the-wire-stays.md +16 -7
- package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +36 -19
- package/docs/reference/decisions/0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md +18 -10
- package/docs/reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md +3 -2
- package/docs/reference/decisions/0031-menu-only-agents-run-on-the-instance-harness.md +23 -15
- package/docs/reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md +101 -0
- package/docs/reference/decisions/0033-a-machine-declares-the-input-that-starts-it.md +22 -22
- package/docs/reference/decisions/0034-the-console-renders-with-preact-and-the-server-erases-the-types.md +6 -6
- package/docs/reference/decisions/0037-an-instance-builds-its-sandbox-images-jr2-injects-the-harness.md +13 -12
- package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +23 -23
- package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +6 -1
- package/docs/reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md +57 -46
- package/docs/reference/decisions/0052-a-sandbox-lands-where-an-ordinary-pod-lands-and-the-cache-follows-it.md +5 -0
- package/docs/reference/decisions/0053-a-fetch-inside-the-pod-asks-the-node-cache-and-the-cache-asks-the-remote.md +20 -8
- package/docs/reference/decisions/0054-the-kit-ships-machines-and-a-shipped-machine-leaves-its-parts-open.md +55 -40
- package/docs/reference/decisions/0055-a-release-is-a-pushed-tag-and-the-publish-guard-is-the-credential.md +14 -13
- package/docs/reference/decisions/0057-a-turn-is-its-frame-its-dials-and-whether-it-continues.md +31 -24
- package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +18 -10
- package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +137 -86
- package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +165 -91
- package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +7 -7
- package/docs/reference/decisions/0064-a-workspace-waits-for-capacity.md +2 -2
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md +109 -0
- package/docs/reference/decisions/0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md +53 -23
- package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +221 -153
- package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +161 -96
- package/docs/reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md +32 -9
- package/docs/reference/decisions/0070-a-machine-lends-its-parts-to-a-chart.md +48 -33
- package/docs/reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md +56 -30
- package/docs/reference/decisions/0072-the-docs-ship-inside-the-kit-and-an-instances-agents-md-indexes-them.md +35 -25
- package/docs/reference/decisions/0073-a-machine-fails-a-run-with-fail-and-an-uncaught-failure-ends-it-failed.md +1 -1
- package/docs/reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +296 -0
- package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +347 -0
- package/docs/reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md +79 -0
- package/docs/reference/decisions/0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md +285 -0
- package/docs/reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md +198 -0
- package/docs/reference/decisions.md +9 -4
- package/docs/reference/glossary.md +138 -45
- package/docs/reference/hooks.md +1077 -0
- package/docs/reference/http-api.md +988 -123
- package/docs/reference/machines.md +0 -1
- package/docs/why.md +7 -5
- package/package.json +10 -3
- package/src/actor.ts +194 -42
- package/src/agent.ts +56 -6
- package/src/ambient.ts +3 -5
- package/src/assembly-checks.ts +530 -4
- package/src/callers.ts +245 -0
- package/src/chart.ts +238 -26
- package/src/charts.ts +9 -2
- package/src/config.ts +566 -7
- package/src/conversations.ts +453 -0
- package/src/custodian.lua +17 -5
- package/src/custodian.ts +257 -77
- package/src/customize.ts +154 -7
- package/src/dispatch-effect.ts +142 -26
- package/src/durability.ts +2 -0
- package/src/duration.ts +20 -0
- package/src/effect-checks.ts +52 -4
- package/src/effect.ts +401 -132
- package/src/effector-wire.ts +278 -30
- package/src/fail.ts +17 -4
- package/src/gate-brand.ts +16 -0
- package/src/gate.ts +634 -48
- package/src/harness-client.ts +84 -35
- package/src/harness-env.ts +33 -0
- package/src/held-secrets.ts +197 -39
- package/src/holds.ts +5 -2
- package/src/hook-kinds/discord.ts +92 -0
- package/src/hook-kinds/door.ts +107 -0
- package/src/hook-kinds/github.ts +89 -0
- package/src/hook-kinds/gitlab.ts +72 -0
- package/src/hook-kinds/hook.ts +7 -0
- package/src/hook-kinds/index.ts +465 -0
- package/src/hook-kinds/slack.ts +151 -0
- package/src/hook-kinds/webhook.ts +113 -0
- package/src/hooks.ts +506 -0
- package/src/http-effect.ts +164 -70
- package/src/http.ts +933 -99
- package/src/index.ts +30 -5
- package/src/instance.ts +196 -26
- package/src/internal.ts +23 -3
- package/src/kube-client.ts +6 -3
- package/src/machine-doc.ts +29 -5
- package/src/mcp-effect.ts +424 -0
- package/src/model-keys.ts +24 -0
- package/src/mount-digest.ts +41 -7
- package/src/names.ts +82 -7
- package/src/notices.ts +576 -59
- package/src/open-body.ts +110 -30
- package/src/open-effect.ts +17 -4
- package/src/open.ts +40 -7
- package/src/parts.ts +125 -35
- package/src/party.ts +35 -1
- package/src/pick.ts +43 -9
- package/src/pool.ts +1172 -172
- package/src/registration.ts +249 -17
- package/src/repo-identity.ts +7 -3
- package/src/repos.ts +20 -2
- package/src/run-host.ts +1614 -190
- package/src/run-list.ts +191 -0
- package/src/sandbox-effect.ts +217 -66
- package/src/sandbox-kube.ts +116 -21
- package/src/secret-placement.ts +248 -35
- package/src/server.ts +53 -4
- package/src/setup.ts +158 -38
- package/src/snapshot-store.ts +565 -48
- package/src/steer.ts +111 -0
- package/src/stub-harness.ts +6 -2
- package/src/tokens.ts +362 -46
- package/src/vocabulary.ts +23 -4
- package/src/wire.ts +27 -10
- package/src/workspace.ts +314 -259
- package/src/worktree.ts +249 -0
- package/docs/reference/authoring-surface/type-noslotspec.md +0 -26
- package/docs/reference/authoring-surface/type-workspacespec.md +0 -37
- package/docs/reference/decisions/0032-the-console-unlocks-with-the-instance-token.md +0 -61
- package/docs/reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-week.md +0 -65
package/docs/reference/config.md
CHANGED
|
@@ -15,7 +15,7 @@ Sandbox Image: a Machine names those itself.
|
|
|
15
15
|
Every field is optional, and an Instance can run with no `jr2.config.ts`. Write the file as
|
|
16
16
|
`export default defineConfig({ … })`. When the config loads, a file with no default export is
|
|
17
17
|
refused: `` <file> has no default export (use `export default defineConfig({…})`) ``. The load also
|
|
18
|
-
checks the shape of `git.credentials`, `secrets`, `harness.catalog` and `
|
|
18
|
+
checks the shape of `git.credentials`, `secrets`, `harness.catalog`, `priorityClasses` and `mcp`. It
|
|
19
19
|
checks that `sandbox` is an object, and checks its `resources`. Each refusal names the field.
|
|
20
20
|
`jr2 up` checks the rest.
|
|
21
21
|
|
|
@@ -42,7 +42,7 @@ export default defineConfig({ name: "my-instance", harness });
|
|
|
42
42
|
- [Secrets and trust](../concepts/secrets-and-trust.md)
|
|
43
43
|
- [ADR-0050: What code names, config declares; what the CLI names, discovery finds](decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md)
|
|
44
44
|
|
|
45
|
-
Fields: [`name`](#name), [`secrets`](#secrets), [`git`](#git), [`harness`](#harness), [`sandbox`](#sandbox), [`priorityClasses`](#priorityclasses), [`registry`](#registry), [`kitRegistry`](#kitregistry), [`platforms`](#platforms), [`operator`](#operator).
|
|
45
|
+
Fields: [`name`](#name), [`secrets`](#secrets), [`git`](#git), [`harness`](#harness), [`sandbox`](#sandbox), [`priorityClasses`](#priorityclasses), [`callers`](#callers), [`cors`](#cors), [`hooks`](#hooks), [`mcp`](#mcp), [`runs`](#runs), [`registry`](#registry), [`kitRegistry`](#kitregistry), [`platforms`](#platforms), [`operator`](#operator).
|
|
46
46
|
|
|
47
47
|
<a id="name"></a>
|
|
48
48
|
|
|
@@ -76,8 +76,9 @@ config loads: `<file> at secrets[<i>]<path>: <problem>`, followed by the shape o
|
|
|
76
76
|
- Type: `string`
|
|
77
77
|
- Required: yes
|
|
78
78
|
|
|
79
|
-
As a Held secret, the name of
|
|
80
|
-
|
|
79
|
+
As a Held secret, the name of its Stand-in: the file the Harness reads it from, the env var
|
|
80
|
+
that the engine reads a model key from, and the env var of the Agent's programs when the
|
|
81
|
+
`workspace()` lists it under `secrets`. As an Effect secret, the name that `secret("<name>")` names, and the name of the
|
|
81
82
|
Effector's file. For a Held secret, it must match `[A-Z_][A-Z0-9_]*`:
|
|
82
83
|
`secrets[<i>].name "<name>" is not an env var name ([A-Z_][A-Z0-9_]*)`. It must not start with
|
|
83
84
|
`JR2_` and must not be a proxy or trust variable of the kit:
|
|
@@ -377,7 +378,7 @@ checks from inside the cluster that the endpoint answers.
|
|
|
377
378
|
|
|
378
379
|
The API key, when the endpoint needs one. Read it from `process.env`. It is a Held secret,
|
|
379
380
|
`JR2_PROVIDER_API_KEY`: `jr2 up` gives the value to the Custodian only, bound to the host of
|
|
380
|
-
`baseUrl`, and the Harness
|
|
381
|
+
`baseUrl`, and the Harness process holds only its secret Stand-in. Thus `baseUrl` must be
|
|
381
382
|
`https://` when you set it:
|
|
382
383
|
`harness.provider.apiKey is set, and harness.provider.baseUrl is not https://`.
|
|
383
384
|
|
|
@@ -467,6 +468,11 @@ deployments, so read it from `process.env` (`.env`).
|
|
|
467
468
|
|
|
468
469
|
Env vars for the Harness container. The Agent can read every one of them, so do not put a
|
|
469
470
|
credential here. A known model key is refused here. Put it in the top-level `secrets` list.
|
|
471
|
+
The Harness process gets each one, except a name that loads code from a path, such as
|
|
472
|
+
`NODE_OPTIONS` or `LD_PRELOAD`, and `HOME`, which is its own; the Agent's programs get each
|
|
473
|
+
one. A name that starts with `JR2_` is jr2's own, and is refused. A credential file that the
|
|
474
|
+
Harness process reads, such as `AWS_CONFIG_FILE`, is refused in a folder that the Agent's code
|
|
475
|
+
writes (`/work`, `/tmp`, `/home/jr2`), and gives a warning anywhere else.
|
|
470
476
|
See `HarnessEnvVar`.
|
|
471
477
|
|
|
472
478
|
<a id="harness-env-name"></a>
|
|
@@ -508,7 +514,10 @@ pod as it is. A reference to a Secret of the kit is refused:
|
|
|
508
514
|
- Required: no
|
|
509
515
|
|
|
510
516
|
Secrets and ConfigMaps that you manage, whose keys all become env vars of the Harness
|
|
511
|
-
|
|
517
|
+
process and of the Agent's programs, as `env` does. In the container's spec each key has the
|
|
518
|
+
prefix `JR2_ENVFROM_`, so that the Harness can tell jr2's names from the image's; the Harness
|
|
519
|
+
removes it. A key that starts with `JR2_` is refused: `jr2 up` refuses it, and the Harness does
|
|
520
|
+
not start with one. See `HarnessEnvFromSource`.
|
|
512
521
|
|
|
513
522
|
<a id="harness-envfrom-prefix"></a>
|
|
514
523
|
|
|
@@ -692,6 +701,239 @@ An existing PriorityClass for the Orchestrator, the operator and the Repo cache
|
|
|
692
701
|
|
|
693
702
|
An existing PriorityClass for the Sandboxes and the Instance Harness.
|
|
694
703
|
|
|
704
|
+
<a id="callers"></a>
|
|
705
|
+
|
|
706
|
+
## `callers`
|
|
707
|
+
|
|
708
|
+
- Type: `CallersConfig`
|
|
709
|
+
- Required: no
|
|
710
|
+
- Default: none; only the Instance token acts
|
|
711
|
+
|
|
712
|
+
The Callers that act on the Instance with a credential of their own, and what each may do.
|
|
713
|
+
See `CallersConfig`.
|
|
714
|
+
|
|
715
|
+
<a id="callers-tokens"></a>
|
|
716
|
+
|
|
717
|
+
### `callers.tokens`
|
|
718
|
+
|
|
719
|
+
- Type: `Readonly<Record<string, CallerToken>>`
|
|
720
|
+
- Required: no
|
|
721
|
+
|
|
722
|
+
The named Caller tokens, by name. A name is lowercase letters, digits and `-`, at most 40
|
|
723
|
+
characters, from a letter to a letter or digit. The config load refuses `instance`, the
|
|
724
|
+
Instance token's name. A name that the config no longer declares stops working at the next
|
|
725
|
+
`jr2 up`.
|
|
726
|
+
|
|
727
|
+
<a id="callers-tokens-name-may"></a>
|
|
728
|
+
|
|
729
|
+
### `callers.tokens.<name>.may`
|
|
730
|
+
|
|
731
|
+
- Type: `Scopes`
|
|
732
|
+
- Required: yes
|
|
733
|
+
|
|
734
|
+
What the token may do. See `Scopes`.
|
|
735
|
+
|
|
736
|
+
<a id="callers-tokens-name-may-start"></a>
|
|
737
|
+
|
|
738
|
+
### `callers.tokens.<name>.may.start`
|
|
739
|
+
|
|
740
|
+
- Type: `ScopeGrant`
|
|
741
|
+
- Required: no
|
|
742
|
+
|
|
743
|
+
Start a run.
|
|
744
|
+
|
|
745
|
+
<a id="callers-tokens-name-may-answer"></a>
|
|
746
|
+
|
|
747
|
+
### `callers.tokens.<name>.may.answer`
|
|
748
|
+
|
|
749
|
+
- Type: `AnswerGrant`
|
|
750
|
+
- Required: no
|
|
751
|
+
|
|
752
|
+
Answer a Gate, and read a run's open Gates without its context. A list item
|
|
753
|
+
`{ workflow, gates }` opens only the Gates that it names, by invoke id (see `GateGrant`).
|
|
754
|
+
|
|
755
|
+
<a id="callers-tokens-name-may-cancel"></a>
|
|
756
|
+
|
|
757
|
+
### `callers.tokens.<name>.may.cancel`
|
|
758
|
+
|
|
759
|
+
- Type: `ScopeGrant`
|
|
760
|
+
- Required: no
|
|
761
|
+
|
|
762
|
+
Cancel a run.
|
|
763
|
+
|
|
764
|
+
<a id="callers-tokens-name-may-read"></a>
|
|
765
|
+
|
|
766
|
+
### `callers.tokens.<name>.may.read`
|
|
767
|
+
|
|
768
|
+
- Type: `ScopeGrant`
|
|
769
|
+
- Required: no
|
|
770
|
+
|
|
771
|
+
Read a run's state: its status, its context and its feed.
|
|
772
|
+
|
|
773
|
+
<a id="callers-tokens-name-may-steer"></a>
|
|
774
|
+
|
|
775
|
+
### `callers.tokens.<name>.may.steer`
|
|
776
|
+
|
|
777
|
+
- Type: `ScopeGrant`
|
|
778
|
+
- Required: no
|
|
779
|
+
|
|
780
|
+
Send a Steering message to an Agent of a run.
|
|
781
|
+
|
|
782
|
+
<a id="callers-issuers"></a>
|
|
783
|
+
|
|
784
|
+
### `callers.issuers`
|
|
785
|
+
|
|
786
|
+
- Type: `readonly JwtIssuer[]`
|
|
787
|
+
- Required: no
|
|
788
|
+
|
|
789
|
+
The identity providers whose JWTs are Callers. See `JwtIssuer`. Two entries with one
|
|
790
|
+
`issuer` are refused.
|
|
791
|
+
|
|
792
|
+
<a id="callers-issuers-issuer"></a>
|
|
793
|
+
|
|
794
|
+
### `callers.issuers[].issuer`
|
|
795
|
+
|
|
796
|
+
- Type: `string`
|
|
797
|
+
- Required: yes
|
|
798
|
+
|
|
799
|
+
The issuer's URL, exactly as the `iss` claim gives it, such as `https://dex.example.com`.
|
|
800
|
+
|
|
801
|
+
<a id="callers-issuers-audience"></a>
|
|
802
|
+
|
|
803
|
+
### `callers.issuers[].audience`
|
|
804
|
+
|
|
805
|
+
- Type: `string`
|
|
806
|
+
- Required: yes
|
|
807
|
+
|
|
808
|
+
The audience that a JWT must name in its `aud` claim: for a login, the client id.
|
|
809
|
+
|
|
810
|
+
<a id="callers-issuers-jwks"></a>
|
|
811
|
+
|
|
812
|
+
### `callers.issuers[].jwks`
|
|
813
|
+
|
|
814
|
+
- Type: `string`
|
|
815
|
+
- Required: no
|
|
816
|
+
- Default: the `jwks_uri` of the issuer's `/.well-known/openid-configuration`
|
|
817
|
+
|
|
818
|
+
The URL of the issuer's public keys (a JWKS).
|
|
819
|
+
|
|
820
|
+
<a id="callers-issuers-claims"></a>
|
|
821
|
+
|
|
822
|
+
### `callers.issuers[].claims`
|
|
823
|
+
|
|
824
|
+
- Type: `object`
|
|
825
|
+
- Required: no
|
|
826
|
+
- Default: `{ name: "sub", shown: "email", groups: "groups" }`
|
|
827
|
+
|
|
828
|
+
The claims to read.
|
|
829
|
+
|
|
830
|
+
<a id="callers-issuers-claims-name"></a>
|
|
831
|
+
|
|
832
|
+
### `callers.issuers[].claims.name`
|
|
833
|
+
|
|
834
|
+
- Type: `string`
|
|
835
|
+
- Required: no
|
|
836
|
+
|
|
837
|
+
The claim that is the Caller's name. Use a claim that the provider never reassigns.
|
|
838
|
+
|
|
839
|
+
<a id="callers-issuers-claims-shown"></a>
|
|
840
|
+
|
|
841
|
+
### `callers.issuers[].claims.shown`
|
|
842
|
+
|
|
843
|
+
- Type: `string`
|
|
844
|
+
- Required: no
|
|
845
|
+
|
|
846
|
+
The claim that is the name that jr2 shows.
|
|
847
|
+
|
|
848
|
+
<a id="callers-issuers-claims-groups"></a>
|
|
849
|
+
|
|
850
|
+
### `callers.issuers[].claims.groups`
|
|
851
|
+
|
|
852
|
+
- Type: `string`
|
|
853
|
+
- Required: no
|
|
854
|
+
|
|
855
|
+
The claim that holds the list of groups or roles that `groups` maps to scopes.
|
|
856
|
+
|
|
857
|
+
<a id="callers-issuers-groups"></a>
|
|
858
|
+
|
|
859
|
+
### `callers.issuers[].groups`
|
|
860
|
+
|
|
861
|
+
- Type: `Readonly<Record<string, Scopes>>`
|
|
862
|
+
- Required: yes
|
|
863
|
+
|
|
864
|
+
The scopes that each value of the groups claim gives, such as
|
|
865
|
+
`{ "jr2-ops": { start: "all", answer: "all" } }`. A JWT with more than one value gets the scopes
|
|
866
|
+
of each, joined. A value that is not here gives nothing.
|
|
867
|
+
|
|
868
|
+
<a id="callers-issuers-login"></a>
|
|
869
|
+
|
|
870
|
+
### `callers.issuers[].login`
|
|
871
|
+
|
|
872
|
+
- Type: `boolean`
|
|
873
|
+
- Required: no
|
|
874
|
+
- Default: `false`, because an issuer for machines (a CI provider's tokens) has no login page
|
|
875
|
+
|
|
876
|
+
The Console offers a login against this issuer ([ADR-0032](decisions/0032-the-console-unlocks-with-a-callers-credential.md)): OIDC, the authorization code flow
|
|
877
|
+
with PKCE, as a public client, with `audience` as the client id. Register the client as public
|
|
878
|
+
(no secret), with the Console's root (`https://<console>/`) as its redirect URI. The Console
|
|
879
|
+
reads the issuer and the client id before the login, from the open route
|
|
880
|
+
`GET /console/config`: both are public values. A login needs the Console on https or on
|
|
881
|
+
localhost, and the issuer must let the Console's origin call its discovery document and its
|
|
882
|
+
token endpoint (CORS).
|
|
883
|
+
|
|
884
|
+
<a id="cors"></a>
|
|
885
|
+
|
|
886
|
+
## `cors`
|
|
887
|
+
|
|
888
|
+
- Type: `readonly string[]`
|
|
889
|
+
- Required: no
|
|
890
|
+
- Default: none
|
|
891
|
+
|
|
892
|
+
The origins from which a browser app may call the Instance's HTTP API, such as
|
|
893
|
+
`https://ops.example.com`. Each entry is an origin alone: a scheme, a host and an optional port,
|
|
894
|
+
with no path. The Console is served from the Orchestrator's own origin, so it
|
|
895
|
+
needs no entry. The config load refuses an entry that is not an origin:
|
|
896
|
+
`<file> at cors[<i>]: <entry> is not an origin — scheme://host[:port], with no path`.
|
|
897
|
+
|
|
898
|
+
<a id="hooks"></a>
|
|
899
|
+
|
|
900
|
+
## `hooks`
|
|
901
|
+
|
|
902
|
+
- Type: `Readonly<Record<string, Hook>>`
|
|
903
|
+
- Required: no
|
|
904
|
+
- Default: none
|
|
905
|
+
|
|
906
|
+
The Hooks of the Instance, by name: each one is a door, `POST /hooks/<name>`, for one outside
|
|
907
|
+
service. A Hook's value comes from its kind's constructor, which the config imports:
|
|
908
|
+
`github({ secret: secret("GH_HOOK") })`, `gitlab({ secret: secret("GL_HOOK"), may })`,
|
|
909
|
+
`discord({ publicKey: "…" })`. `may.answer` names the Workflows whose Gates the Hook may answer,
|
|
910
|
+
every Workflow by default. A Hook never starts a run. A name has the rule of a Caller token's
|
|
911
|
+
name. When the config loads, a bad entry is refused: `<file> at hooks.<name>: <problem>`.
|
|
912
|
+
|
|
913
|
+
<a id="mcp"></a>
|
|
914
|
+
|
|
915
|
+
## `mcp`
|
|
916
|
+
|
|
917
|
+
- Type: `Readonly<Record<string, McpServer>>`
|
|
918
|
+
- Required: no
|
|
919
|
+
- Default: none
|
|
920
|
+
|
|
921
|
+
The MCP servers, by a name of yours: `[a-z][a-z0-9-]*`, not `jr2`. A remote server has a
|
|
922
|
+
`url` (`https://` with a secret), a `secret` (a name of the `secrets` list; with no `hosts`, it
|
|
923
|
+
is bound to the url's host) and a `timeout` (default `"60s"`). A stdio server has a `command`
|
|
924
|
+
of the Sandbox Image, its `args` and a `timeout`. An Agent names a server in its `mcp` list.
|
|
925
|
+
See [`McpServer`](authoring-surface/type-mcpserver.md).
|
|
926
|
+
|
|
927
|
+
<a id="runs"></a>
|
|
928
|
+
|
|
929
|
+
## `runs`
|
|
930
|
+
|
|
931
|
+
- Type: [`RunsConfig`](authoring-surface/type-runsconfig.md)
|
|
932
|
+
- Required: no
|
|
933
|
+
- Default: `{ retain: "30d", volume: "5Gi" }`
|
|
934
|
+
|
|
935
|
+
How long ended runs are kept, and the volume size.
|
|
936
|
+
|
|
695
937
|
<a id="registry"></a>
|
|
696
938
|
|
|
697
939
|
## `registry`
|
|
@@ -34,7 +34,7 @@ Sandbox will run must be in the spec at spin-up.
|
|
|
34
34
|
|
|
35
35
|
One Harness **image** serves many **Agents** — the Harness resolves model, instructions, and its Menu at runtime without
|
|
36
36
|
a rebuild, reading the definition each admission carries (ADR-0018, ADR-0049) and reading the Menu through the Custodian
|
|
37
|
-
per turn (ADR-0013). So the Orchestrator injects a fixed Harness image plus **config** (env + the prepared
|
|
37
|
+
per turn (ADR-0013). So the Orchestrator injects a fixed Harness image plus **config** (env + the prepared clones),
|
|
38
38
|
never a per-Agent image build. The HTTP prompt body itself carries only `{message, images}`, so anything persona-shaping
|
|
39
39
|
is set at provision time, not per request.
|
|
40
40
|
|
|
@@ -91,14 +91,15 @@ one keeps the name and the endpoint and costs no node anything. Deferred until a
|
|
|
91
91
|
These are accepted gaps in the current operator, recorded so they aren't silently forgotten. Each is a deliberate
|
|
92
92
|
deferral.
|
|
93
93
|
|
|
94
|
-
- **Egress is
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
credential
|
|
100
|
-
|
|
101
|
-
|
|
94
|
+
- **Egress is open.** The pod is hardened at the host boundary — `automountServiceAccountToken: false`, pod/container
|
|
95
|
+
`securityContext` (`runAsNonRoot`, `allowPrivilegeEscalation: false`, drop `ALL`, seccomp `RuntimeDefault`) — and its
|
|
96
|
+
_ingress_ is the Orchestrator's alone: `jr2 up` converges a NetworkPolicy that admits no other pod to a Sandbox
|
|
97
|
+
([ADR-0058](0058-a-harness-answers-the-orchestrator-alone.md)), which kind's `kindnet` enforces. _Egress_ is open
|
|
98
|
+
except for the cloud metadata addresses, which no Harness pod reaches
|
|
99
|
+
([ADR-0076](0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md)): an untrusted Agent can
|
|
100
|
+
still reach the cluster's API server IP (it holds no credential there) and the internet. A default-deny egress policy
|
|
101
|
+
with an allowlist is the next layer, and ADR-0058 records it open. The ADR-0013 boundary does not depend on either:
|
|
102
|
+
only the token bounds what a pod may _do_; NetworkPolicy bounds where it may _talk_.
|
|
102
103
|
- **Sidecars are plain containers, not native sidecars.** They are scheduled as ordinary `containers`, not Kubernetes
|
|
103
104
|
≥1.29 native sidecars (`initContainers` with `restartPolicy: Always`). There is no start-ordering or
|
|
104
105
|
termination-ordering guarantee between the Harness and its sidecars — the Harness may begin serving before the
|
|
@@ -16,21 +16,88 @@ action observably occurred only post-approval.
|
|
|
16
16
|
|
|
17
17
|
The split-channel model:
|
|
18
18
|
|
|
19
|
-
| Direction | Kind
|
|
20
|
-
| --------- |
|
|
21
|
-
| up | control / decision (the workflow's events, ADR-0011)
|
|
22
|
-
| up | progress / telemetry (tokens, attempts, "still working")
|
|
23
|
-
| down | the next turn's prompt (feedback, steering at a boundary)
|
|
24
|
-
| down | the Turn part, restated (the Allowed picks changed)
|
|
25
|
-
| down |
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
19
|
+
| Direction | Kind | Mechanism |
|
|
20
|
+
| --------- | -------------------------------------------------------------- | --------------------------------------------- |
|
|
21
|
+
| up | control / decision (the workflow's events, ADR-0011) | Menu tool call → Custodian → delivery |
|
|
22
|
+
| up | progress / telemetry (tokens, attempts, "still working") | Harness stream (lossy, observation-only) |
|
|
23
|
+
| down | the next turn's prompt (feedback, steering at a boundary) | a new submission on the same iid |
|
|
24
|
+
| down | the Turn part, restated (the Allowed picks changed) | the Harness's read at each step boundary |
|
|
25
|
+
| down | a jr2 notice (a memory kill, ADR-0062), typed, to its audience | the same step-boundary read, per conversation |
|
|
26
|
+
| down | a Steering message (a Caller's or the Machine's free text) | the same step-boundary read, per Agent slot |
|
|
27
|
+
| down | interrupts (deliberate terminal cancel) | `abort` on the wire |
|
|
28
|
+
|
|
29
|
+
Tool calls are Agent-initiated, so the Machine answers a pick only when the Agent makes one. Inside a Turn, three other
|
|
30
|
+
things reach the Agent, and each one at a step boundary. The first is the **restated Turn part**: when something other
|
|
31
|
+
than the Agent's own pick changes its Allowed picks — a Gate's answer, an outside event — the Harness learns it by
|
|
32
|
+
reading the surface at each step boundary and appends the new list
|
|
30
33
|
([ADR-0029](0029-a-menu-is-fixed-for-a-conversation-and-a-turn-is-told-its-allowed-picks.md)). It is a pull, not a push:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
+
the Harness asks at a step boundary, and nothing reaches it that it did not ask for. What is restated is fixed text plus
|
|
35
|
+
Menu names. The second is jr2's own **typed notices**, which ride that same step-boundary read: the read of an open Turn
|
|
36
|
+
returns its conversation's pending notices, the Harness appends them, and its acknowledgment of the append delivers
|
|
37
|
+
them. So a running Agent hears a fact the mechanism knows — a memory kill above all — without an interrupt. A notice is
|
|
38
|
+
typed data, and the Harness words it ([ADR-0062](0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md)). The third
|
|
39
|
+
is a **Steering message**: free text to an Agent that has not asked for it, on the same read (below). Each is a pull at
|
|
40
|
+
a step boundary, never an interrupt.
|
|
41
|
+
|
|
42
|
+
## Steering messages
|
|
43
|
+
|
|
44
|
+
- **Two senders.** A Caller ([ADR-0078](0078-a-caller-comes-from-one-authenticator-seam-and-acts-within-its-scopes.md))
|
|
45
|
+
sends one with `POST /runs/:runId/steering { agent, text }` or `jr2 steer <run> <agent> "<text>"`, and needs the
|
|
46
|
+
`steer` scope for the run's Workflow. A text above 16 KiB of UTF-8 is 413, and an empty one 400. The route answers 202
|
|
47
|
+
`{ id, agent, open }`: `open` says whether a Turn of the slot was open when the message came. The message names the
|
|
48
|
+
Caller by the name that jr2 shows (a JWT's `email`, else its name), with its `via` and its `onBehalfOf` claim. The
|
|
49
|
+
Machine sends one with the authoring action `steer(<agent>, text, { from? })` in a transition, to an Agent of the
|
|
50
|
+
Machine that runs the action; `from` is the Sender whose words it carries. The action cuts a text above 16 KiB and
|
|
51
|
+
says so in the text, because a relayed payload is not the author's to bound, and a refusal there would fail the
|
|
52
|
+
transition.
|
|
53
|
+
- **Addressed by Agent slot.** `agent` names an Agent slot of the run, as the run's slot list names it. The list,
|
|
54
|
+
`{ agent, open, steerable }` for each slot at `GET /runs/:runId/agents`, is open to a Caller with `steer`, so a Caller
|
|
55
|
+
can see where a message would go. It lists each Agent that each live Machine instance carries in its `actors`, with or
|
|
56
|
+
without an open Turn, and `jr2 steer <run>` prints it. An Instance ID is not the address: jr2 computes it, a Caller
|
|
57
|
+
cannot know it, and a fresh Turn gets a new one. A slot is the name that the author gave, and the walk lets at most
|
|
58
|
+
one state of a Machine instance hold it at a time ([ADR-0015](0015-authoring-surface-absorbs-the-mechanism.md)), so it
|
|
59
|
+
names one conversation at a time.
|
|
60
|
+
- **Delivery.** When the slot has an open Turn, its Harness appends the message at the Turn's next step boundary, on the
|
|
61
|
+
same read as a notice. A pick that ends the Turn skips that read. Thus a message that comes while the Turn's last
|
|
62
|
+
model request runs is held for the slot's next Turn, as when no Turn is open, and `jr2 steer` says that both can
|
|
63
|
+
occur. Otherwise the message is held for the slot's next Turn of the same Machine instance, and that Turn's admission
|
|
64
|
+
carries it. A held message belongs to the Machine instance that was live when it was sent: when that instance ends,
|
|
65
|
+
the message retires, and the run records it "not delivered". A Machine instance ends when it leaves its parent's
|
|
66
|
+
children, when it reaches `done` or `error`, and when the run ends; a host that stops parks the run, and ends nothing.
|
|
67
|
+
An instance below one that ended ends with it. When no live Machine instance holds the slot — it has ended, or it
|
|
68
|
+
never was — the route answers 409 with the run's slots, because the Orchestrator cannot tell a slot that ended from
|
|
69
|
+
one that never was; an unknown run is 404, and a run that is not live is 409. The Agent hears each message once, by
|
|
70
|
+
the rules of a notice (ADR-0062). The run records each message with its author, its text, when it was sent and its
|
|
71
|
+
outcome (`held`, `heard`, `not-delivered`), in the run's persisted state; the record keeps the newest 100 and each one
|
|
72
|
+
still held. The run's status carries it as `steering`, behind `read` like `context` (ADR-0014): a message is a
|
|
73
|
+
Caller's working text, never the open band's.
|
|
74
|
+
- **Never a Machine event.** A Steering message is in no Vocabulary, no Gate takes it, and no guard reads it. The Agent
|
|
75
|
+
decides what to do with it, and acts on the workflow only by its picks.
|
|
76
|
+
- **Agents message each other only through the Machine.** An Agent's Menu offers a pick that the author declared; the
|
|
77
|
+
Machine's transition relays its payload with `steer(<agent>, …)`. jr2 gives no built-in message tool.
|
|
78
|
+
- **The Harness frames the message by its author** (ADR-0062). A Caller's message is an instruction from outside the
|
|
79
|
+
run, with the Caller's name. A message that the Machine relays from another Agent is information from a peer, and the
|
|
80
|
+
frame says that it is not an instruction. A Machine's message that relays no one is the workflow's own text.
|
|
81
|
+
- **`steerable: false` on an Agent definition refuses Callers only** (403). The Machine can still steer that Agent: the
|
|
82
|
+
author wrote both. The admission strips it from the definition, because the model never reads it.
|
|
83
|
+
- **What a model reads changes, so two `@model` claims are owed**
|
|
84
|
+
([ADR-0066](0066-a-model-tier-runs-a-real-model-and-a-change-to-what-it-reads-runs-the-tier.md)): `steer-follow`, an
|
|
85
|
+
Agent follows a Caller's Steering message that comes in its open Turn, and `peer-not-order`, an Agent does not obey a
|
|
86
|
+
peer's relayed word as an order. Their floors were set before a measured run, as `chart-refusal`'s was: `steer-follow`
|
|
87
|
+
9 of 10, a list read last's floor, because the message is the newest text that the model read; and `peer-not-order` 7
|
|
88
|
+
of 10, because there the peer's word comes after the workflow's text, and ADR-0029 measured how much the text read
|
|
89
|
+
last pulls.
|
|
90
|
+
|
|
91
|
+
Considered and rejected: address a message by conversation (an Instance ID), which a Caller cannot know and which
|
|
92
|
+
changes at a fresh Turn; a built-in tool with which an Agent messages another Agent, which goes around the Machine that
|
|
93
|
+
the author wrote; and a Steering message as a Machine event, which makes free text control.
|
|
94
|
+
|
|
95
|
+
Considered and not chosen now: a held message turns back a pick that ends the Turn. The Harness would refuse that pick
|
|
96
|
+
while a message waits for the slot, and the model would read the message and pick again, so a message always reaches the
|
|
97
|
+
Turn that was open when it came. It costs a new refusal that the model reads (an `@model` claim), one more model request
|
|
98
|
+
in that case, and a pick that a Caller's message can undo, where today a pick is final. The case is one model request
|
|
99
|
+
wide, and a Gate or the Machine can still send the Agent back. Look at it again if Callers need a message to reach the
|
|
100
|
+
Turn that was open.
|
|
34
101
|
|
|
35
102
|
## Durability: the admission is the handle
|
|
36
103
|
|
|
@@ -91,34 +91,40 @@ fast setup.
|
|
|
91
91
|
|
|
92
92
|
## Where setup runs
|
|
93
93
|
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
[ADR-0063](0063-the-orchestrator-watches-the-cluster.md)), once `Ready` says every cache is present and fetched.
|
|
94
|
+
The clone is a post-`Ready` step owned by the Orchestrator: the Sandbox CRD names repositories by identity so the
|
|
95
|
+
operator can place and mount them, but it knows nothing about clones or worktrees (ADR-0001, ADR-0051). `workspace()`'s
|
|
96
|
+
attach is one idempotent in-pod script the Harness runs on `POST /attach` (ADR-0012,
|
|
97
|
+
[ADR-0063](0063-the-orchestrator-watches-the-cluster.md)), once `Ready` says every cache is present and fetched. The
|
|
98
|
+
attach only clones. A Machine cuts each Worktree with the kit Effect `worktree()`
|
|
99
|
+
([ADR-0075](0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md)).
|
|
98
100
|
|
|
99
101
|
## In-Sandbox layout: worktrees off the per-Sandbox clone (gwtmux convention)
|
|
100
102
|
|
|
101
103
|
"Not a shared worktree" above means _not a worktree off a fleet-shared `.git`_. **Inside** a Sandbox, worktrees are the
|
|
102
|
-
intended ergonomic — taken off the Sandbox's **own** clone. The per-Sandbox clone _is_ the `default/`, and
|
|
103
|
-
|
|
104
|
-
|
|
104
|
+
intended ergonomic — taken off the Sandbox's **own** clone. The per-Sandbox clone _is_ the `default/`, and the Worktrees
|
|
105
|
+
are its siblings, matching the layout [gwtmux](https://github.com/snapwich/gwtmux) already expects, under the slot the
|
|
106
|
+
Machine gave the repository (ADR-0051):
|
|
105
107
|
|
|
106
108
|
```
|
|
107
|
-
/work/<slot>/default/ the per-Sandbox `git clone --shared` (holds the pod-local .git;
|
|
108
|
-
/work/<slot>/<
|
|
109
|
+
/work/<slot>/default/ the per-Sandbox `git clone --shared` (holds the pod-local .git; stays on the Binding's base)
|
|
110
|
+
/work/<slot>/<name>/ `git worktree add` siblings: folders a Machine cuts, each with one branch or one commit
|
|
109
111
|
```
|
|
110
112
|
|
|
111
113
|
Because the layout is identical to the one used outside the cluster, existing worktree tooling works **unchanged** when
|
|
112
|
-
you exec into a Sandbox. Object resolution falls through: a
|
|
114
|
+
you exec into a Sandbox. Object resolution falls through: a Worktree shares the per-Sandbox `default/.git`, whose
|
|
113
115
|
alternates point at the read-only cache — existing objects are read from the cache, new commits land in the pod-local
|
|
114
|
-
`.git`. `default/`
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
116
|
+
`.git`. `default/` stays on the Binding's base: a branch is attached, a tag or a commit is detached, and with no base it
|
|
117
|
+
is the Repo's default branch, as gwtmux's `default/` is outside the cluster. No work happens in it: work happens in the
|
|
118
|
+
Worktrees, and `default/` is the reference tree that a human, a tool or an Agent that only reads finds where it expects
|
|
119
|
+
one. Not `--no-checkout`: an empty working tree reads as every tracked file deleted to `git status`, which misleads an
|
|
120
|
+
Agent that looks. A Worktree's folder cannot be named `default`, and a cut of the branch that `default/` holds is
|
|
121
|
+
`refused`, with a reason that names `/work/<slot>/default`. `origin`'s push url is the binding's own spelling, so a
|
|
122
|
+
Machine that bound over ssh pushes over ssh even when the cache was cloned over https.
|
|
123
|
+
|
|
124
|
+
This does **not** reintroduce jr's contention: the shared `.git` here is _per-Sandbox_, so what contends stays in one
|
|
125
|
+
pod and never crosses the fleet. Inside the pod it is the author's choice. A Machine that runs concurrent Agents in
|
|
126
|
+
Worktrees of one clone, or an Agent that spawns parallel git-touching subagents, takes that contention, and a Machine
|
|
127
|
+
that does not want it uses separate Sandboxes. Two things keep one clone safe to share. The attach sets `gc.auto=0` and
|
|
128
|
+
`maintenance.auto=false` in the clone, because a `gc` beside a cut or a commit can prune what another Worktree needs.
|
|
129
|
+
And all Worktrees of a clone share `refs/remotes/origin/*`, so `jr2-upload-pack` holds a per-clone lock for each fetch
|
|
130
|
+
(ADR-0053, ADR-0075).
|