@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
|
@@ -18,13 +18,15 @@ credential that an [Effect](../reference/glossary.md#effect) uses, and only an
|
|
|
18
18
|
## Why it exists
|
|
19
19
|
|
|
20
20
|
An Agent's [Working tools](../reference/glossary.md#working-tools) give it a shell in the Harness container. Thus the
|
|
21
|
-
Agent can
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
Agent can run each program of the image, and it can send what it reads out of the pod. If a model API key were in its
|
|
22
|
+
reach, the Agent could take it away. If the credential of the Orchestrator's API were in its reach, the Agent could
|
|
23
|
+
answer its own review [Gate](../reference/glossary.md#gate), or send a pick for a different Agent.
|
|
24
24
|
|
|
25
|
-
jr2 does not try to hide the API from the Agent. Instead, it keeps the credentials out of
|
|
26
|
-
token enters no Harness pod. Each credential of the `secrets` list, and the key of `harness.provider.apiKey`,
|
|
27
|
-
container in which the Agent executes nothing. [Architecture](architecture.md) tells where those containers
|
|
25
|
+
jr2 does not try to hide the API from the Agent. Instead, it keeps the credentials out of the Agent's reach. The
|
|
26
|
+
Instance token enters no Harness pod. Each credential of the `secrets` list, and the key of `harness.provider.apiKey`,
|
|
27
|
+
goes to a container in which the Agent executes nothing. [Architecture](architecture.md) tells where those containers
|
|
28
|
+
run. The Harness itself holds one secret value, and [Confined programs](#confined-programs) tells how jr2 keeps it from
|
|
29
|
+
the Agent's code.
|
|
28
30
|
|
|
29
31
|
## One list, and the name decides
|
|
30
32
|
|
|
@@ -49,10 +51,15 @@ export default defineConfig({
|
|
|
49
51
|
```
|
|
50
52
|
|
|
51
53
|
- A pod claims a Held secret when its [`workspace()`](../reference/authoring-surface/workspace.md) lists the name under
|
|
52
|
-
`secrets`. A pod also claims the key of each provider that an Agent in that pod uses
|
|
54
|
+
`secrets`. A pod also claims the key of each provider that an Agent in that pod uses, and the `secret` of each MCP
|
|
55
|
+
server that an Agent in that pod names.
|
|
53
56
|
- The [Instance Harness](../reference/glossary.md#instance-harness) claims only the model keys of the Menu-only Agents
|
|
54
|
-
that it hosts.
|
|
55
|
-
- An Effect claims an Effect secret when it names it with [`secret()`](../reference/authoring-surface/secret.md).
|
|
57
|
+
that it hosts, and the secrets of the MCP servers that they name.
|
|
58
|
+
- An Effect claims an Effect secret when it names it with [`secret()`](../reference/authoring-surface/secret.md). An
|
|
59
|
+
`mcp` Effect claims the `secret` of its server for the
|
|
60
|
+
[Instance Effector](../reference/glossary.md#instance-effector).
|
|
61
|
+
- A [Hook](../reference/glossary.md#hook) that checks a signature with a shared secret (`mac`) claims that secret for
|
|
62
|
+
the Instance Effector, as an Effect does.
|
|
56
63
|
- One entry can be a Held secret and an Effect secret at the same time. The placement is a fact of each place that names
|
|
57
64
|
it, not of the entry.
|
|
58
65
|
- An entry that nothing names goes nowhere, and [`jr2 up`](../reference/cli.md#up) warns about it.
|
|
@@ -65,47 +72,124 @@ containers that hold it. An entry can also name a key of a Secret that you manag
|
|
|
65
72
|
|
|
66
73
|
## Held secrets
|
|
67
74
|
|
|
68
|
-
The Harness
|
|
69
|
-
|
|
70
|
-
that
|
|
75
|
+
The Harness of a pod holds one Stand-in for each Held secret of the pod, in a file that only the Harness reads. jr2
|
|
76
|
+
makes a new Stand-in for each pod, and it is secret. It has a meaning only to the Custodian of that pod. A program of an
|
|
77
|
+
Agent gets the Stand-in of a Held secret only when the `workspace()` lists that secret under `secrets`. The fetch
|
|
78
|
+
Stand-in is the one public Stand-in (see below).
|
|
71
79
|
|
|
72
|
-
When a pod holds a Held secret other than the Sandbox
|
|
73
|
-
Custodian (`HTTPS_PROXY`). For each request to a host that a Held secret is bound to, the Custodian does
|
|
80
|
+
When a pod holds a Held secret other than the tokens of its Sandbox, the Harness container sends its HTTPS traffic
|
|
81
|
+
through the Custodian (`HTTPS_PROXY`). For each request to a host that a Held secret is bound to, the Custodian does
|
|
82
|
+
these things:
|
|
74
83
|
|
|
75
84
|
1. It ends the TLS connection with a certificate that `jr2 up` issued from the CA of the
|
|
76
85
|
[Instance](../reference/glossary.md#instance).
|
|
77
86
|
2. It replaces the Stand-in with the value, in the headers that the entry names.
|
|
78
87
|
3. It opens its own TLS connection to the host, and verifies the certificate of the host.
|
|
79
88
|
|
|
80
|
-
|
|
81
|
-
|
|
89
|
+
Two Held secrets can go to one host in one header, such as the tokens of two MCP servers of one service. The Custodian
|
|
90
|
+
chooses the value by the Stand-in that the header holds. The Custodian sends the traffic to each other host with no
|
|
91
|
+
change. It refuses a loopback, link-local or unspecified address. A request to a bound host that has no Stand-in in its
|
|
92
|
+
headers does not leave the pod.
|
|
82
93
|
|
|
83
94
|
These fields of an entry bind a Held secret. They do not place it:
|
|
84
95
|
|
|
85
96
|
- [`hosts`](../reference/config.md#secrets-hosts): the hosts that the value can go to. A known model key with one
|
|
86
|
-
default host, such as `ANTHROPIC_API_KEY`, can leave it out. It then goes only to the host of its provider.
|
|
97
|
+
default host, such as `ANTHROPIC_API_KEY`, can leave it out. It then goes only to the host of its provider. The
|
|
98
|
+
`secret` of an MCP server can leave it out too. It then goes only to the host of the server's URL, in the header
|
|
99
|
+
`authorization`.
|
|
87
100
|
- [`headers`](../reference/config.md#secrets-headers): the headers in which the Custodian replaces the Stand-in.
|
|
88
101
|
- [`paths`](../reference/config.md#secrets-paths): the path prefixes that the value can go to.
|
|
89
102
|
|
|
90
|
-
The Custodian also holds the
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
103
|
+
The Custodian also holds the two tokens of its [Sandbox](../reference/glossary.md#sandbox): the control token and the
|
|
104
|
+
fetch token.
|
|
105
|
+
|
|
106
|
+
- The Harness reads the [Menu](../reference/glossary.md#menu) and sends each pick with the control Stand-in, and the
|
|
107
|
+
Custodian replaces it with the control token. The control Stand-in is secret. Only the Harness holds it, in a file
|
|
108
|
+
that no program of an Agent can read. With each request, the Harness also tells which Agent the conversation is for,
|
|
109
|
+
and the Orchestrator checks it.
|
|
110
|
+
- A `git fetch` in the Sandbox sends the fetch Stand-in, which is public. The Custodian replaces it with the fetch token
|
|
111
|
+
only for a fetch. It refuses the fetch Stand-in for the Menu and for a pick.
|
|
112
|
+
|
|
113
|
+
The Instance Harness has a token of its own for the Menu. It runs no program of an Agent.
|
|
94
114
|
|
|
95
115
|
### What a Held secret does not stop
|
|
96
116
|
|
|
97
|
-
- **The Agent can spend the
|
|
98
|
-
host. A key that can make new keys gives the Agent a key
|
|
99
|
-
narrow `paths`.
|
|
117
|
+
- **The Agent's code can spend a key that the `workspace()` lists.** While the pod lives, a program of the Agent can
|
|
118
|
+
send requests through the Custodian to the bound host of that key. A key that can make new keys gives the Agent a key
|
|
119
|
+
that it can take away. Use a key with no admin rights. Set narrow `paths`.
|
|
100
120
|
- **A response passes with no change.** If a host puts the full key in a response, the Agent reads it.
|
|
101
|
-
- **jr2
|
|
102
|
-
nothing outside the pod. The cluster decides which hosts a pod can reach.
|
|
121
|
+
- **jr2 controls egress only at the cloud metadata addresses.** A client that does not use the Custodian sends only the
|
|
122
|
+
Stand-in, which is worth nothing outside the pod. The cluster decides which hosts a pod can reach. One exception: a
|
|
123
|
+
NetworkPolicy of jr2 stops each Harness pod at the metadata addresses of the large cloud providers (`169.254.169.254`,
|
|
124
|
+
`fd00:ec2::254`, `169.254.170.2`, `169.254.170.23` and `100.100.100.200`). There, the metadata service of a node can
|
|
125
|
+
give the node's cloud credential to a pod. The list is not complete for every provider, and only a CNI that enforces
|
|
126
|
+
NetworkPolicy applies it. See
|
|
127
|
+
[Move from kind to a shared cluster](../guides/move-from-kind-to-a-shared-cluster.md#check-the-cluster).
|
|
103
128
|
- **A key that signs the request cannot be a Held secret.** A SigV4 or ADC credential signs the request, and the
|
|
104
129
|
Custodian cannot put a value into a signature. Use an Effect secret for such a credential. For a model provider, use a
|
|
105
130
|
gateway that holds the credential, and make the key of the gateway a Held secret.
|
|
106
|
-
- **A tool must trust the CA of the Instance.** When a pod holds a Held secret other than the Sandbox
|
|
107
|
-
the trust variables of Node.js, OpenSSL, Python and git in its Harness container. A client that does not trust
|
|
108
|
-
such as a Java client, cannot connect to a bound host. It sends nothing.
|
|
131
|
+
- **A tool must trust the CA of the Instance.** When a pod holds a Held secret other than the tokens of its Sandbox, jr2
|
|
132
|
+
sets the trust variables of Node.js, OpenSSL, Python and git in its Harness container. A client that does not trust
|
|
133
|
+
the CA, such as a Java client, cannot connect to a bound host. It sends nothing.
|
|
134
|
+
|
|
135
|
+
## Confined programs
|
|
136
|
+
|
|
137
|
+
The Harness runs the [Turns](../reference/glossary.md#turn) of each Agent of the Sandbox. The Harness process itself
|
|
138
|
+
runs only jr2's code. Each other process in the Harness container runs confined with Landlock: each command of the
|
|
139
|
+
Agent's shell, and so the tests, the builds, git and its hooks; the search tools; the I/O of the read, write and edit
|
|
140
|
+
tools; jr2's own git; each stdio MCP server; and each `command` Effect that names no Effect secret. Code that one Agent
|
|
141
|
+
writes in `/work` can run in a program of a different Agent, for example when a reviewer runs the tests of a coder. Thus
|
|
142
|
+
jr2 confines each such program, and not only the programs of one Agent.
|
|
143
|
+
|
|
144
|
+
All these programs are in one Landlock domain. They can see, signal and trace each other, as the programs of one user on
|
|
145
|
+
a computer can. Thus a later shell command can find and stop a server that an earlier command started. When the process
|
|
146
|
+
that starts these programs stops, the Harness starts it again, in a new domain. The programs of the old domain continue,
|
|
147
|
+
and a program of the new domain cannot trace them.
|
|
148
|
+
|
|
149
|
+
A confined program can do all that the user of the container can do, with these exceptions:
|
|
150
|
+
|
|
151
|
+
- It cannot read, write, make, remove, move or link a file in `/run/jr2`. That folder holds the control Stand-in, the
|
|
152
|
+
Stand-in of each Held secret, the socket of the Custodian for the picks, and the conversations of the Harness. A
|
|
153
|
+
program can list the names in `/run/jr2`, as it can list each folder: `ls /` and `find /` work. The names are not
|
|
154
|
+
secrets.
|
|
155
|
+
- It cannot make a socket in `/run/jr2`. It can connect to the socket of the Custodian, but the Custodian refuses each
|
|
156
|
+
request on the socket that does not have the control Stand-in, and the program cannot read that Stand-in.
|
|
157
|
+
- It cannot trace the Harness process, or read its environment or its memory.
|
|
158
|
+
- When the kernel has Landlock ABI 6 or later, it cannot send a signal to the Harness process, or connect to an abstract
|
|
159
|
+
Unix socket that the Harness or the Custodian made.
|
|
160
|
+
|
|
161
|
+
Thus a program can write in a folder of the image that its user owns, move a file from one folder to another, and run
|
|
162
|
+
the tools of the image. The kernel keeps the shared parts safe: the caches of each [Repo](../reference/glossary.md#repo)
|
|
163
|
+
at `/repos`, the runtime of jr2 at `/opt/jr2` and the CA bundles are read-only. The pod has no ServiceAccount token. A
|
|
164
|
+
program can connect to each address that the pod can reach.
|
|
165
|
+
|
|
166
|
+
The environment of a confined program is the environment with which the container started: the `ENV` of the image,
|
|
167
|
+
`harness.env`, `harness.envFrom`, and the proxy and trust variables. jr2 removes its own `JR2_` names from it, except
|
|
168
|
+
`JR2_CUSTODIAN_URL`. jr2 adds `HOME`, `TMPDIR` and the Stand-in of each Held secret that the `workspace()` lists, under
|
|
169
|
+
the name of that secret. The environment holds no control Stand-in. It holds the Stand-in of a model key only when the
|
|
170
|
+
`workspace()` lists that key. Thus code in `/work` cannot call the model with your key unless you allow it. jr2 records
|
|
171
|
+
the use of each Turn, and a call that you did not allow cannot go around that record.
|
|
172
|
+
|
|
173
|
+
The read, write and edit tools reach the same paths as the shell. A path in `/run/jr2`, or a link to one, gives the
|
|
174
|
+
error of a file that the user cannot read. In a path, `~` is the `HOME` of the confined programs.
|
|
175
|
+
|
|
176
|
+
The Harness process has its own `HOME`, in `/run/jr2`, from before Node starts. Thus a file that a program writes in its
|
|
177
|
+
`HOME`, such as `~/.aws/config` or a module in `~/.node_modules`, does not change what the Harness process does. The
|
|
178
|
+
Harness does not start when Node would look for a module outside `/opt/jr2` and `/run/jr2`.
|
|
179
|
+
|
|
180
|
+
The Harness process gets only the env that jr2 composes: `harness.env`, `harness.envFrom`, the proxy and trust
|
|
181
|
+
variables, and jr2's own names. It does not get the `ENV` of the image. It also does not get a name that loads code from
|
|
182
|
+
a path, such as `NODE_OPTIONS`, `LD_PRELOAD` or `OPENSSL_CONF`, from any of them. Thus an image with
|
|
183
|
+
`NODE_OPTIONS=--require /app/hook.js` changes the Agent's programs, as you expect, and not the Harness process. In
|
|
184
|
+
`kubectl exec`, each key of `harness.envFrom` has the prefix `JR2_ENVFROM_`. The programs of the Agent see each key
|
|
185
|
+
under its own name. A name that starts with `JR2_` is jr2's own: `jr2 up` refuses one in `harness.env` or in a Secret or
|
|
186
|
+
a ConfigMap that `harness.envFrom` loads, and the Harness does not start with one from `harness.envFrom`.
|
|
187
|
+
|
|
188
|
+
Thus code in `/work` cannot send a pick for an Agent, also when a different Agent runs it. An Agent can still try to
|
|
189
|
+
change what a different Agent does with the text that it writes, such as a comment in a file. The other Agent's model
|
|
190
|
+
decides each of its own picks.
|
|
191
|
+
|
|
192
|
+
jr2 needs Landlock in the kernel of each node. See [Rules](#rules).
|
|
109
193
|
|
|
110
194
|
## Effect secrets
|
|
111
195
|
|
|
@@ -125,8 +209,7 @@ encodings. It does not find a changed form of an Effect secret, such as a hash o
|
|
|
125
209
|
## Git credentials
|
|
126
210
|
|
|
127
211
|
The [`git.credentials`](../reference/config.md#git-credentials) entries give the cluster its git credentials. The
|
|
128
|
-
Orchestrator matches a
|
|
129
|
-
reads a git credential:
|
|
212
|
+
Orchestrator matches a Repo to an entry, and names the Secret of that entry. It never reads a git credential:
|
|
130
213
|
|
|
131
214
|
- The clone credential goes into a Secret that only the Repo cache reads.
|
|
132
215
|
- The push credential and the signing key go to the [Sandbox Effector](../reference/glossary.md#sandbox-effector) of the
|
|
@@ -138,44 +221,71 @@ make the Sandbox. [Give the cluster git credentials](../guides/give-the-cluster-
|
|
|
138
221
|
## The tokens
|
|
139
222
|
|
|
140
223
|
jr2 makes its own tokens. `jr2 up` makes the Instance token and the signing key the first time, and keeps them in the
|
|
141
|
-
`jr2-instance` Secret. Each
|
|
224
|
+
`jr2-instance` Secret. Each token of a pod comes from the signing key, so the Orchestrator stores no token for each pod.
|
|
142
225
|
|
|
143
|
-
| Token
|
|
144
|
-
|
|
|
145
|
-
| Instance token
|
|
146
|
-
|
|
|
147
|
-
|
|
|
148
|
-
|
|
|
226
|
+
| Token | Who holds it | What it lets the holder do |
|
|
227
|
+
| ------------------ | ----------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
228
|
+
| Instance token | You and the CLI, through the Kubernetes API | Everything: start a run, read its full state, answer a Gate, cancel a run, and the routes that no scope opens. |
|
|
229
|
+
| Named Caller token | A [Caller](../reference/glossary.md#caller) that has no access to the cluster, such as a CI job | The scopes that `callers.tokens` gives its name, for the Workflows that each scope names. |
|
|
230
|
+
| Control token | The Custodian of one Sandbox, as a file | Read the Menu and send the picks of the Agents in that Sandbox, for the Agent that the Harness names. |
|
|
231
|
+
| Fetch token | The Custodian of one Sandbox, as a file | Ask for a fetch of a Repo that the Sandbox mounts. |
|
|
232
|
+
| Harness bearer | The Orchestrator. The Harness holds only its SHA-256 digest. | Call the Harness in one pod: start a Turn, read it, stop it, set up a Worktree, and run a `command` Effect. |
|
|
233
|
+
| Effector key | The Orchestrator, and the Effector of one placement | Sign a request to that Effector, and sign its answer. |
|
|
149
234
|
|
|
150
235
|
- The Instance token enters no Harness pod. The CLI reads it from the `jr2-instance` Secret over the Kubernetes API.
|
|
151
|
-
Thus Kubernetes RBAC decides who holds it.
|
|
152
|
-
|
|
153
|
-
|
|
236
|
+
Thus Kubernetes RBAC decides who holds it. The CLI is the Caller `token/instance`. It also sends the name of your
|
|
237
|
+
Kubernetes user, and the run records it as the party that the Caller acts for.
|
|
238
|
+
- [`callers.tokens`](../reference/config.md#callers-tokens) declares each named Caller token. `jr2 up` makes its value
|
|
239
|
+
one time, in a Secret of its own, `jr2-caller-<name>`. The Orchestrator holds only the SHA-256 digest of each value,
|
|
240
|
+
in the `jr2-caller-digests` Secret, which it mounts. `jr2 caller token <name>` prints the value, which it reads over
|
|
241
|
+
the Kubernetes API.
|
|
242
|
+
- `jr2 caller rotate <name>` makes a new value. The Orchestrator reads the digests again when the mount changes. The
|
|
243
|
+
kubelet updates the mount in about one minute, and `jr2 caller rotate` waits for it. When it returns, the old value no
|
|
244
|
+
longer works. No pod restarts.
|
|
245
|
+
- When `callers.tokens` no longer declares a name, the next `jr2 up` deletes its Secret, and its value stops working.
|
|
246
|
+
- A control token or a fetch token cannot answer a Gate, and cannot speak for a different pod. The Orchestrator accepts
|
|
247
|
+
each one only on its own routes. Thus an Agent cannot approve its own work, and a Sandbox cannot send a pick for an
|
|
248
|
+
Agent in a different Sandbox. No token of a pod is a Caller.
|
|
154
249
|
- A Harness can check its bearer, but it cannot make a bearer. Thus an Agent cannot drive a conversation in a different
|
|
155
250
|
pod.
|
|
156
251
|
|
|
252
|
+
[Callers and Hooks](callers-and-hooks.md) tells how jr2 knows a Caller, and what each scope opens.
|
|
253
|
+
[Give a Caller a scope](../guides/give-a-caller-a-scope.md) declares a named Caller token and uses it.
|
|
254
|
+
|
|
157
255
|
## Open observation, guarded control
|
|
158
256
|
|
|
159
|
-
Each route of the [HTTP API](../reference/http-api.md) is in one of
|
|
257
|
+
Each route of the [HTTP API](../reference/http-api.md) is in one of these access bands:
|
|
160
258
|
|
|
161
259
|
- [**Open**](../reference/http-api.md#band-open), with no token: the [Workflows](../reference/glossary.md#workflow), the
|
|
162
260
|
structure of each Machine, and the live runs of a Workflow with their states. An open route shows no context of a run,
|
|
163
261
|
and an [Emit](../reference/glossary.md#emit) shows only its type.
|
|
164
|
-
- [**Authenticated**](../reference/http-api.md#band-authenticated), with the Instance token or a Sandbox
|
|
165
|
-
routes of the Agent's Menu and the fetch. A Sandbox
|
|
166
|
-
- [**
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
262
|
+
- [**Authenticated**](../reference/http-api.md#band-authenticated), with the Instance token or a token of a Sandbox: the
|
|
263
|
+
routes of the Agent's Menu and the fetch. A token of a Sandbox reaches only its own routes, in its own pod.
|
|
264
|
+
- [**A Caller with a scope**](../reference/http-api.md#band-guarded): the start of a run, the full state of a run, the
|
|
265
|
+
Gates, and cancel. Each route needs one scope of a Caller (`start`, `read`, `answer`, `cancel` or `steer`) for the
|
|
266
|
+
Workflow of the run. The Instance token has each scope for each Workflow. A named Caller token has the scopes that its
|
|
267
|
+
entry gives it. A token of a Sandbox is not a Caller.
|
|
268
|
+
- [**Instance token only**](../reference/http-api.md#band-instanceonly): the routes that no scope opens, such as a
|
|
269
|
+
runtime Chart, the report of the Repos and the log of a Hook (`GET /hooks/:name`).
|
|
270
|
+
- [**A Hook's verifier**](../reference/http-api.md#band-hook), with no bearer token: `POST /hooks/:name`. The verifier
|
|
271
|
+
of the Hook checks each delivery.
|
|
272
|
+
|
|
273
|
+
Thus the Console shows the Machines and the runs without a token. When you type a Caller's token in the Console, or log
|
|
274
|
+
in at an issuer that the Instance declares, the Console also shows the controls that the Caller's scopes open: start,
|
|
275
|
+
the Gates, cancel and steer. The Console keeps the credential in the session storage of the browser tab, and forgets it
|
|
276
|
+
when you close the tab. [Open the Console](../guides/open-the-console.md) tells how.
|
|
172
277
|
|
|
173
278
|
"Open" means open to each caller that can reach the Service of the Orchestrator: a port forward, a pod in the cluster,
|
|
174
279
|
or an ingress. The names of the states and the types of the Emits are open.
|
|
175
280
|
|
|
176
281
|
The Harness writes each Agent's conversation to its container log. The log has the prompts, the model's text and
|
|
177
|
-
thinking, its tool calls and the answers to its picks. It does not write the results of the Working tools
|
|
178
|
-
who can read the pod logs of the namespace can read these conversations.
|
|
282
|
+
thinking, its tool calls and the answers to its picks. It does not write the results of the Working tools or of the MCP
|
|
283
|
+
tools. Each person who can read the pod logs of the namespace can read these conversations.
|
|
284
|
+
|
|
285
|
+
The Orchestrator also keeps each conversation, with the same cut, for `runs.retain` (30 days by default). Thus the kept
|
|
286
|
+
copy has the same residual as the log: an answer to a pick can carry a held value that an upstream wrote into a
|
|
287
|
+
`command` output, or a secret in a form that the scrub does not catch. A Caller with `read` on the Workflow can read the
|
|
288
|
+
kept copy with `GET /runs/:runId/conversations`.
|
|
179
289
|
|
|
180
290
|
## Rules
|
|
181
291
|
|
|
@@ -185,7 +295,13 @@ who can read the pod logs of the namespace can read these conversations.
|
|
|
185
295
|
not `https://`. A local model over plain `http://` has no key.
|
|
186
296
|
- [`harness.env`](../reference/config.md#harness-env) and `harness.envFrom` put each value into the Harness container,
|
|
187
297
|
and the Agent can read it. Put a credential in the `secrets` list.
|
|
188
|
-
- A
|
|
298
|
+
- A file that the Harness process reads, such as the one that `AWS_CONFIG_FILE` or `GOOGLE_APPLICATION_CREDENTIALS`
|
|
299
|
+
names in `harness.env`, cannot be in `/work`, `/tmp`, `/dev/shm` or `/home/jr2`: `jr2 up` refuses it. In another
|
|
300
|
+
folder, `jr2 up` gives a warning: make sure that the user of the Sandbox cannot write the file.
|
|
301
|
+
- A Held secret must name its `hosts`, unless it is a known model key with one default host, or the `secret` of an MCP
|
|
302
|
+
server.
|
|
303
|
+
- An MCP server with a `secret` has an `https://` URL. When an entry sets `hosts`, `headers` or `paths`, they must let
|
|
304
|
+
the Stand-in through to the URL of each server that names the entry.
|
|
189
305
|
- A name that a `workspace()` lists must be in the `secrets` list. A name that an Effect gives to `secret()` must be in
|
|
190
306
|
it too.
|
|
191
307
|
- An Effect secret has 8 characters or more.
|
|
@@ -193,30 +309,38 @@ who can read the pod logs of the namespace can read these conversations.
|
|
|
193
309
|
- The Orchestrator can make and change a Secret, but it cannot get or list one.
|
|
194
310
|
- A changed value does not reach a live Sandbox. A new Sandbox gets it. When a Menu-only Agent uses the value, the next
|
|
195
311
|
`jr2 up` restarts the Instance Harness with it.
|
|
196
|
-
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
312
|
+
- jr2 needs Landlock ABI 3 or later in the kernel of each Sandbox node: Linux 6.2 or later, or a kernel with a backport,
|
|
313
|
+
with `landlock` in its list of security modules. `jr2 up` refuses to converge while a Sandbox node has no Landlock, or
|
|
314
|
+
only ABI 1 or 2. On a node without it, a Harness or a Sandbox Effector does not start, and the provision of the
|
|
315
|
+
Sandbox fails.
|
|
316
|
+
- A name in `harness.env`, or a key that `harness.envFrom` loads, cannot start with `JR2_`.
|
|
317
|
+
- When a pod holds a Held secret other than the tokens of its Sandbox, `SSL_CERT_FILE` and the other trust variables
|
|
318
|
+
replace the trust store of the image. They hold the public roots, `harness.caBundle` and the CA of the Instance. Thus
|
|
319
|
+
a private CA goes in [`harness.caBundle`](../reference/config.md#harness-cabundle), not in the image.
|
|
201
320
|
- `jr2 up` makes the CA of the Instance one time, in the `jr2-held-ca` Secret, and never changes it. No pod mounts that
|
|
202
321
|
Secret. When you delete it, the next `jr2 up` makes a new CA.
|
|
203
322
|
|
|
204
323
|
## Read next
|
|
205
324
|
|
|
325
|
+
- [Give a Caller a scope](../guides/give-a-caller-a-scope.md)
|
|
206
326
|
- [Use a local model](../guides/use-a-local-model.md)
|
|
207
327
|
- [Use a hosted provider or a gateway](../guides/use-a-hosted-provider.md)
|
|
208
328
|
- [Give the cluster git credentials](../guides/give-the-cluster-git-credentials.md)
|
|
209
329
|
- [Run a command or call a URL with an Effect](../guides/run-a-command-or-call-a-url.md)
|
|
330
|
+
- [Give an Agent MCP tools](../guides/give-an-agent-mcp-tools.md)
|
|
210
331
|
- [Open the Console](../guides/open-the-console.md)
|
|
211
|
-
- [Architecture](architecture.md) and [Effects](effects.md)
|
|
332
|
+
- [Callers and Hooks](callers-and-hooks.md), [Architecture](architecture.md) and [Effects](effects.md)
|
|
212
333
|
- The [`secrets`](../reference/config.md#secrets), [`git`](../reference/config.md#git) and
|
|
213
334
|
[`harness`](../reference/config.md#harness) fields of `jr2.config.ts`,
|
|
214
335
|
[`secret()`](../reference/authoring-surface/secret.md), and the [HTTP API](../reference/http-api.md)
|
|
215
336
|
- [ADR-0013](../reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md),
|
|
216
337
|
[ADR-0014](../reference/decisions/0014-observation-is-open-run-state-is-not.md),
|
|
217
338
|
[ADR-0023](../reference/decisions/0023-the-harness-prints-the-conversation.md),
|
|
218
|
-
[ADR-0032](../reference/decisions/0032-the-console-unlocks-with-
|
|
339
|
+
[ADR-0032](../reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md),
|
|
219
340
|
[ADR-0051](../reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md),
|
|
220
341
|
[ADR-0058](../reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md),
|
|
221
|
-
[ADR-0059](../reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md)
|
|
222
|
-
[ADR-0068](../reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md)
|
|
342
|
+
[ADR-0059](../reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md),
|
|
343
|
+
[ADR-0068](../reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md),
|
|
344
|
+
[ADR-0076](../reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md),
|
|
345
|
+
[ADR-0077](../reference/decisions/0077-jr2-requires-landlock-on-every-sandbox-node.md) and
|
|
346
|
+
[ADR-0079](../reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md)
|
|
@@ -21,6 +21,11 @@ and the tools block is first in it. A change to the tools block makes the provid
|
|
|
21
21
|
Thus jr2 keeps the Menu the same, and tells each [Turn](../reference/glossary.md#turn) which part of it the Turn can
|
|
22
22
|
pick now.
|
|
23
23
|
|
|
24
|
+
The Menu is the last part of the tools block. The [Working tools](../reference/glossary.md#working-tools) come first,
|
|
25
|
+
then the [MCP tools](../reference/glossary.md#mcp-tools), then the Menu. The model reads a Menu tool as
|
|
26
|
+
`mcp__jr2__<event>`, and an MCP tool as `mcp__<server>__<tool>`, where `<server>` is never `jr2`. Only a call of a Menu
|
|
27
|
+
tool is a pick. A call of an MCP tool acts on a service outside the Machine, and the Turn goes on after it.
|
|
28
|
+
|
|
24
29
|
## Where the Menu comes from
|
|
25
30
|
|
|
26
31
|
You do not write the Menu. `jr2Setup` makes the Menu from the Machine when you call `createMachine`:
|
|
@@ -336,6 +341,11 @@ Each event that a party sends carries its [Sender](../reference/glossary.md#send
|
|
|
336
341
|
[`Sender`](../reference/authoring-surface/type-sender.md)). The [Orchestrator](../reference/glossary.md#orchestrator)
|
|
337
342
|
writes it on each event that a party delivers. An event that the Machine sends to itself has no Sender.
|
|
338
343
|
|
|
344
|
+
A Gate's event also carries the [Caller](../reference/glossary.md#caller) that answered it: `via`, `name`, and
|
|
345
|
+
`onBehalfOf` when the Caller says that it acts for a person or a service. `checked` names the fields that jr2 verified.
|
|
346
|
+
jr2 always verifies `via` and `name`. It does not verify `onBehalfOf`, except for a Hook, whose signature covers it. So
|
|
347
|
+
do not use an unchecked `onBehalfOf` to decide who may do something.
|
|
348
|
+
|
|
339
349
|
Use the Sender when two parties can send the same event to one state. The guard
|
|
340
350
|
[`sentBy(id)`](../reference/authoring-surface/sentby.md) is true for an event from that party, and for an event with no
|
|
341
351
|
Sender. It is false for an event from a different party, so xstate tries the next transition. `sentBy` can only make a
|
|
@@ -344,6 +354,7 @@ transition refuse other senders. It never gives an event to a party. The positio
|
|
|
344
354
|
## Rules
|
|
345
355
|
|
|
346
356
|
- jr2 refuses a pick that is not on the Menu.
|
|
357
|
+
- A call of an MCP tool is not a pick. It does not move the Machine, and it does not end the Turn.
|
|
347
358
|
- A pick that is on the Menu but not in the Allowed picks moves nothing. Its answer gives the Allowed picks.
|
|
348
359
|
- While a pick is outstanding, or while the Agent's state is not at Rest, jr2 refuses each pick and delivers nothing.
|
|
349
360
|
This includes a pick that would end the Turn.
|
|
@@ -352,6 +363,9 @@ transition refuse other senders. It never gives an event to a party. The positio
|
|
|
352
363
|
body that has one.
|
|
353
364
|
- `createMachine` refuses an `on` key that no listed event has, and a listed event that no state takes.
|
|
354
365
|
- `createMachine` refuses a parallel state at or below a state that invokes an Agent.
|
|
366
|
+
- `createMachine` refuses one Agent slot in two states that can be active together: two parallel regions, one state
|
|
367
|
+
inside the other, or one state that invokes the slot twice. The two Turns would have one sender and one conversation.
|
|
368
|
+
For two Agents at once, use two slots (one definition can fill both), a child Machine in each region, or a Pool.
|
|
355
369
|
- `createMachine` refuses a `sentBy` that names no Agent slot and no Gate invoke id of the Machine.
|
|
356
370
|
- `jr2 up` warns about a mode that no transition enters. Its picks are on the Menu, but never in the Allowed picks.
|
|
357
371
|
- `jr2 up` warns about a Gate below an Agent's state whose event has no target. The Gate stays open after that event, so
|