@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
|
@@ -8,10 +8,10 @@ description: How a Workflow gets a Sandbox with a git Worktree or a shared folde
|
|
|
8
8
|
A [Workspace](../reference/glossary.md#workspace) is a [Machine](../reference/glossary.md#machine) that runs a body
|
|
9
9
|
Machine in a [Sandbox](../reference/glossary.md#sandbox). The Sandbox is a pod of its own, with a folder, `/work`, that
|
|
10
10
|
the Agents and Effects of the body share. When the Workspace names [Repos](../reference/glossary.md#repo), `/work` holds
|
|
11
|
-
a git [Worktree](../reference/glossary.md#worktree)
|
|
12
|
-
the folder (see [A Workspace with no Repo](#a-workspace-with-no-repo)). You make a Workspace
|
|
13
|
-
[`workspace()`](../reference/authoring-surface/workspace.md). The Workspace makes the Sandbox when the run enters
|
|
14
|
-
and deletes the Sandbox when the body reaches a final state.
|
|
11
|
+
a clone of each Repo. The body cuts each git [Worktree](../reference/glossary.md#worktree) that it needs. A Workspace
|
|
12
|
+
that names no Repo has only the folder (see [A Workspace with no Repo](#a-workspace-with-no-repo)). You make a Workspace
|
|
13
|
+
with [`workspace()`](../reference/authoring-surface/workspace.md). The Workspace makes the Sandbox when the run enters
|
|
14
|
+
it, and deletes the Sandbox when the body reaches a final state.
|
|
15
15
|
|
|
16
16
|
## Why Workspaces exist
|
|
17
17
|
|
|
@@ -27,14 +27,24 @@ Agent.
|
|
|
27
27
|
## A Workspace and its body
|
|
28
28
|
|
|
29
29
|
This example is a [Workflow](../reference/glossary.md#workflow). A coder changes the `app` Repo, and reads the
|
|
30
|
-
`handbook` Repo beside it. Then a person approves the change at a
|
|
31
|
-
pushes the branch:
|
|
30
|
+
`handbook` Repo beside it. The Machine first cuts the coder's Worktree. Then a person approves the change at a
|
|
31
|
+
[Gate](../reference/glossary.md#gate), and the Machine pushes the branch:
|
|
32
32
|
|
|
33
33
|
**Anthropic**
|
|
34
34
|
|
|
35
35
|
```ts
|
|
36
36
|
import { z } from "zod";
|
|
37
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
agent,
|
|
39
|
+
defineEvent,
|
|
40
|
+
fail,
|
|
41
|
+
isReady,
|
|
42
|
+
jr2Setup,
|
|
43
|
+
push,
|
|
44
|
+
workspace,
|
|
45
|
+
worktree,
|
|
46
|
+
type Workspaced,
|
|
47
|
+
} from "@jr2/orchestrator";
|
|
38
48
|
|
|
39
49
|
const finished = defineEvent({
|
|
40
50
|
name: "finished",
|
|
@@ -51,6 +61,10 @@ const approve = defineEvent({
|
|
|
51
61
|
const runInput = z.object({ ticket: z.string(), prompt: z.string() });
|
|
52
62
|
type BodyInput = Workspaced<z.infer<typeof runInput>, "app" | "handbook">;
|
|
53
63
|
|
|
64
|
+
// The folder of the Worktree, and its branch. The Machine knows both before the cut.
|
|
65
|
+
const fixTree = (context: BodyInput) => `${context.workspace.repos.app}/fix` as const;
|
|
66
|
+
const branchOf = (context: BodyInput) => `docs/${context.ticket}`;
|
|
67
|
+
|
|
54
68
|
const body = jr2Setup({
|
|
55
69
|
types: {} as { context: BodyInput; input: BodyInput },
|
|
56
70
|
events: [finished, approve],
|
|
@@ -59,6 +73,7 @@ const body = jr2Setup({
|
|
|
59
73
|
model: "anthropic/claude-haiku-5-5",
|
|
60
74
|
instructions: "You are a careful engineer. You commit your work on the branch.",
|
|
61
75
|
}),
|
|
76
|
+
cut: worktree(),
|
|
62
77
|
// Two Repo Slots, so the push names the slot that it pushes.
|
|
63
78
|
publish: push({ slot: "app" }),
|
|
64
79
|
fail: fail(),
|
|
@@ -66,17 +81,25 @@ const body = jr2Setup({
|
|
|
66
81
|
}).createMachine({
|
|
67
82
|
id: "docs-fix",
|
|
68
83
|
context: ({ input }) => input,
|
|
69
|
-
initial: "
|
|
84
|
+
initial: "cutting",
|
|
70
85
|
// The Sandbox is gone, and its unpushed commits with it. This body fails the run.
|
|
71
86
|
on: { "agent.fault": ".failed", "workspace.lost": ".lost" },
|
|
72
87
|
states: {
|
|
88
|
+
// The Workspace only clones. The Machine cuts the Worktree that the Agent works in.
|
|
89
|
+
cutting: {
|
|
90
|
+
invoke: {
|
|
91
|
+
src: "cut",
|
|
92
|
+
input: ({ context }) => ({ path: fixTree(context), branch: branchOf(context) }),
|
|
93
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "working" }, { target: "notCut" }],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
73
96
|
working: {
|
|
74
97
|
invoke: {
|
|
75
98
|
src: "coder",
|
|
76
99
|
input: ({ context }) => ({
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
cwd: context
|
|
100
|
+
// A slot that is only read needs no cut: its `default` folder is on the Binding's base.
|
|
101
|
+
prompt: `${context.prompt}\nRead the style rules in ${context.workspace.repos.handbook}/default.`,
|
|
102
|
+
cwd: fixTree(context),
|
|
80
103
|
}),
|
|
81
104
|
},
|
|
82
105
|
on: { finished: "review" },
|
|
@@ -86,7 +109,7 @@ const body = jr2Setup({
|
|
|
86
109
|
invoke: {
|
|
87
110
|
src: "gate",
|
|
88
111
|
input: ({ context }) => ({
|
|
89
|
-
meta: { branch: context
|
|
112
|
+
meta: { branch: branchOf(context), worktree: fixTree(context) },
|
|
90
113
|
}),
|
|
91
114
|
},
|
|
92
115
|
on: { approve: "publishing" },
|
|
@@ -96,11 +119,14 @@ const body = jr2Setup({
|
|
|
96
119
|
publishing: {
|
|
97
120
|
invoke: {
|
|
98
121
|
src: "publish",
|
|
122
|
+
// The Worktree names what to push: jr2 reads its branch from the cut.
|
|
123
|
+
input: ({ context }) => ({ worktree: fixTree(context) }),
|
|
99
124
|
onDone: [{ guard: ({ event }) => event.output.outcome === "pushed", target: "done" }, { target: "review" }],
|
|
100
125
|
},
|
|
101
126
|
},
|
|
102
127
|
done: { type: "final" },
|
|
103
128
|
// Not final states: a final state means `done`. Each one fails the run, and the run ends `failed`.
|
|
129
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
104
130
|
lost: { invoke: { src: "fail", input: { reason: "the Sandbox was lost" } } },
|
|
105
131
|
failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
|
|
106
132
|
},
|
|
@@ -115,7 +141,6 @@ export const machine = workspace(body, {
|
|
|
115
141
|
app: { url: "https://github.com/you/app.git", ref: "main" },
|
|
116
142
|
handbook: "https://github.com/you/handbook.git",
|
|
117
143
|
},
|
|
118
|
-
spec: ({ input }) => ({ branch: `docs/${input.ticket}` }),
|
|
119
144
|
});
|
|
120
145
|
```
|
|
121
146
|
|
|
@@ -123,7 +148,17 @@ export const machine = workspace(body, {
|
|
|
123
148
|
|
|
124
149
|
```ts
|
|
125
150
|
import { z } from "zod";
|
|
126
|
-
import {
|
|
151
|
+
import {
|
|
152
|
+
agent,
|
|
153
|
+
defineEvent,
|
|
154
|
+
fail,
|
|
155
|
+
isReady,
|
|
156
|
+
jr2Setup,
|
|
157
|
+
push,
|
|
158
|
+
workspace,
|
|
159
|
+
worktree,
|
|
160
|
+
type Workspaced,
|
|
161
|
+
} from "@jr2/orchestrator";
|
|
127
162
|
|
|
128
163
|
const finished = defineEvent({
|
|
129
164
|
name: "finished",
|
|
@@ -140,6 +175,10 @@ const approve = defineEvent({
|
|
|
140
175
|
const runInput = z.object({ ticket: z.string(), prompt: z.string() });
|
|
141
176
|
type BodyInput = Workspaced<z.infer<typeof runInput>, "app" | "handbook">;
|
|
142
177
|
|
|
178
|
+
// The folder of the Worktree, and its branch. The Machine knows both before the cut.
|
|
179
|
+
const fixTree = (context: BodyInput) => `${context.workspace.repos.app}/fix` as const;
|
|
180
|
+
const branchOf = (context: BodyInput) => `docs/${context.ticket}`;
|
|
181
|
+
|
|
143
182
|
const body = jr2Setup({
|
|
144
183
|
types: {} as { context: BodyInput; input: BodyInput },
|
|
145
184
|
events: [finished, approve],
|
|
@@ -148,6 +187,7 @@ const body = jr2Setup({
|
|
|
148
187
|
model: "local/qwen3.6-35b-a3b",
|
|
149
188
|
instructions: "You are a careful engineer. You commit your work on the branch.",
|
|
150
189
|
}),
|
|
190
|
+
cut: worktree(),
|
|
151
191
|
// Two Repo Slots, so the push names the slot that it pushes.
|
|
152
192
|
publish: push({ slot: "app" }),
|
|
153
193
|
fail: fail(),
|
|
@@ -155,17 +195,25 @@ const body = jr2Setup({
|
|
|
155
195
|
}).createMachine({
|
|
156
196
|
id: "docs-fix",
|
|
157
197
|
context: ({ input }) => input,
|
|
158
|
-
initial: "
|
|
198
|
+
initial: "cutting",
|
|
159
199
|
// The Sandbox is gone, and its unpushed commits with it. This body fails the run.
|
|
160
200
|
on: { "agent.fault": ".failed", "workspace.lost": ".lost" },
|
|
161
201
|
states: {
|
|
202
|
+
// The Workspace only clones. The Machine cuts the Worktree that the Agent works in.
|
|
203
|
+
cutting: {
|
|
204
|
+
invoke: {
|
|
205
|
+
src: "cut",
|
|
206
|
+
input: ({ context }) => ({ path: fixTree(context), branch: branchOf(context) }),
|
|
207
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "working" }, { target: "notCut" }],
|
|
208
|
+
},
|
|
209
|
+
},
|
|
162
210
|
working: {
|
|
163
211
|
invoke: {
|
|
164
212
|
src: "coder",
|
|
165
213
|
input: ({ context }) => ({
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
cwd: context
|
|
214
|
+
// A slot that is only read needs no cut: its `default` folder is on the Binding's base.
|
|
215
|
+
prompt: `${context.prompt}\nRead the style rules in ${context.workspace.repos.handbook}/default.`,
|
|
216
|
+
cwd: fixTree(context),
|
|
169
217
|
}),
|
|
170
218
|
},
|
|
171
219
|
on: { finished: "review" },
|
|
@@ -175,7 +223,7 @@ const body = jr2Setup({
|
|
|
175
223
|
invoke: {
|
|
176
224
|
src: "gate",
|
|
177
225
|
input: ({ context }) => ({
|
|
178
|
-
meta: { branch: context
|
|
226
|
+
meta: { branch: branchOf(context), worktree: fixTree(context) },
|
|
179
227
|
}),
|
|
180
228
|
},
|
|
181
229
|
on: { approve: "publishing" },
|
|
@@ -185,11 +233,14 @@ const body = jr2Setup({
|
|
|
185
233
|
publishing: {
|
|
186
234
|
invoke: {
|
|
187
235
|
src: "publish",
|
|
236
|
+
// The Worktree names what to push: jr2 reads its branch from the cut.
|
|
237
|
+
input: ({ context }) => ({ worktree: fixTree(context) }),
|
|
188
238
|
onDone: [{ guard: ({ event }) => event.output.outcome === "pushed", target: "done" }, { target: "review" }],
|
|
189
239
|
},
|
|
190
240
|
},
|
|
191
241
|
done: { type: "final" },
|
|
192
242
|
// Not final states: a final state means `done`. Each one fails the run, and the run ends `failed`.
|
|
243
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
193
244
|
lost: { invoke: { src: "fail", input: { reason: "the Sandbox was lost" } } },
|
|
194
245
|
failed: { invoke: { src: "fail", input: { reason: "the Agent's Turn could not go on" } } },
|
|
195
246
|
},
|
|
@@ -204,28 +255,26 @@ export const machine = workspace(body, {
|
|
|
204
255
|
app: { url: "https://github.com/you/app.git", ref: "main" },
|
|
205
256
|
handbook: "https://github.com/you/handbook.git",
|
|
206
257
|
},
|
|
207
|
-
spec: ({ input }) => ({ branch: `docs/${input.ticket}` }),
|
|
208
258
|
});
|
|
209
259
|
```
|
|
210
260
|
|
|
211
261
|
[Agents and Turns](agents-and-turns.md) tells how to define an Agent.
|
|
212
262
|
|
|
213
263
|
The options of `workspace()` say what the Sandbox is. [`jr2 up`](../reference/cli.md#up) reads them before a run starts.
|
|
214
|
-
Only
|
|
264
|
+
Only a per-run [Repo Slot](../reference/glossary.md#repo-slot) reads the run input:
|
|
215
265
|
|
|
216
266
|
- `input` is the schema of the run input: what [`jr2 run`](../reference/cli.md#run) gives with `--input`. Put it on the
|
|
217
267
|
`workspace()`, not on the body.
|
|
218
268
|
- `repos` gives the Repo Slots that the Sandbox clones. Leave it out for a Workspace with no Repo.
|
|
219
|
-
- `spec` is a function from the run input to the branch. Its input also holds `instanceId` (see
|
|
220
|
-
[`HostInjectedInput`](../reference/authoring-surface/type-hostinjectedinput.md)).
|
|
221
269
|
- `resources` is the [Size](../reference/glossary.md#size). `image`, `user` and `effector` name the images of the pod's
|
|
222
270
|
containers.
|
|
223
271
|
- `secrets` names the [Held secrets](../reference/glossary.md#held-secret) that the Sandbox can use (see
|
|
224
272
|
[Secrets and trust](secrets-and-trust.md)).
|
|
273
|
+
- `workGroup` is the group id that owns the files in `/work`. The default is 2000.
|
|
225
274
|
|
|
226
275
|
The body gets the run input, plus `workspace`: the handles of the Workspace (see
|
|
227
|
-
[`WorkspaceHandles`](../reference/authoring-surface/type-workspacehandles.md)). `workspace.repos` gives the
|
|
228
|
-
|
|
276
|
+
[`WorkspaceHandles`](../reference/authoring-surface/type-workspacehandles.md)). `workspace.repos` gives the folder of
|
|
277
|
+
each Repo Slot, `/work/<slot>`. This folder is not a Worktree. Give the path of a Worktree to an Agent's
|
|
229
278
|
[Turn](../reference/glossary.md#turn) as its `cwd`, as the example does. Type the body's input with
|
|
230
279
|
[`Workspaced`](../reference/authoring-surface/type-workspaced.md), also when the run input is `z.object({})`.
|
|
231
280
|
|
|
@@ -243,7 +292,8 @@ A Repo Slot is a key of the `repos` option. The key is your Machine's name for t
|
|
|
243
292
|
Repo under `/work`. Each slot is one of three kinds:
|
|
244
293
|
|
|
245
294
|
- **Bound**: the Machine gives the url, or a [Binding](../reference/glossary.md#binding) `{ url, ref }`. `ref` is the
|
|
246
|
-
branch or the commit that the
|
|
295
|
+
branch, the tag or the commit that the clone stays on, and a new branch starts from it. Without `ref`, it is the
|
|
296
|
+
Repo's default branch.
|
|
247
297
|
- **[Open](../reference/glossary.md#open)**: the Machine gives [`open`](../reference/authoring-surface/open.md). The
|
|
248
298
|
[Instance](../reference/glossary.md#instance) that registers the Machine binds the slot with
|
|
249
299
|
[`customize()`](../reference/authoring-surface/customize.md) (see [Composition](composition.md)).
|
|
@@ -251,7 +301,7 @@ Repo under `/work`. Each slot is one of three kinds:
|
|
|
251
301
|
|
|
252
302
|
A Machine that names no slot writes `repos: open` for the whole map. Then the composer names each slot.
|
|
253
303
|
`workspace.repos` keeps the slots in the order that `repos` declares them. jr2 gives no slot a special meaning. Your
|
|
254
|
-
Machine says
|
|
304
|
+
Machine says where each Agent works.
|
|
255
305
|
|
|
256
306
|
The cluster keeps one read-only cache of each Repo on each node. A Sandbox clones from that cache, and a fetch in the
|
|
257
307
|
pod goes through it. [Architecture](architecture.md) tells about the Repo cache. Run
|
|
@@ -259,23 +309,44 @@ pod goes through it. [Architecture](architecture.md) tells about the Repo cache.
|
|
|
259
309
|
|
|
260
310
|
## The folders in the Sandbox
|
|
261
311
|
|
|
262
|
-
Each Repo Slot gets a folder under `/work`. The clone of the Repo is `/work/<slot>/default/`.
|
|
263
|
-
is
|
|
264
|
-
|
|
265
|
-
[Project layout](../reference/glossary.md#project-layout).
|
|
312
|
+
Each Repo Slot gets a folder under `/work`. The clone of the Repo is `/work/<slot>/default/`. It stays on the base of
|
|
313
|
+
the Binding: a branch is attached, and a tag or a commit is detached. No work happens in `default/`. A slot that an
|
|
314
|
+
Agent only reads needs nothing more: the Agent reads `/work/<slot>/default`. This is the
|
|
315
|
+
[Project layout](../reference/glossary.md#project-layout). `/work/.jr2/` is reserved for jr2.
|
|
316
|
+
|
|
317
|
+
The Workspace only clones. Your Machine cuts each Worktree with the
|
|
318
|
+
[`worktree()`](../reference/authoring-surface/worktree.md) Effect, in a state of the body. You give the path, and the
|
|
319
|
+
branch or the commit:
|
|
320
|
+
|
|
321
|
+
- `{ path: "/work/app/fix", branch: "docs/123" }` cuts a branch Worktree. The cut finds a local branch, then
|
|
322
|
+
`origin/<branch>`, tracked, after a fetch. With neither, it makes a new branch from `from` or the base of the Binding.
|
|
323
|
+
- `{ path: "/work/app/review", detach: sha }` cuts a detached Worktree for a reviewer. Each cut forces it to the commit
|
|
324
|
+
and cleans it. Ignored files stay, so that the reviewer can run the tests.
|
|
325
|
+
|
|
326
|
+
The path is exactly `/work/<slot>/<name>`. The name is one segment that is not `default` and starts with neither `.` nor
|
|
327
|
+
`-`. So your Machine knows the path before the cut, and the folder name does not change with the branch name.
|
|
328
|
+
|
|
329
|
+
The output of a cut is `ready`, `refused` or `unknown`. A later outcome can come, so route the last arm of `onDone` with
|
|
330
|
+
no guard. A bad path or a bad branch name is `refused`, and nothing changes. A cut is idempotent: the same cut again
|
|
331
|
+
reads the same Worktree, and its `head` is the tip of the branch.
|
|
332
|
+
|
|
333
|
+
`worktree({ expect: "new" })` refuses a branch that exists. `worktree({ expect: "existing" })` refuses a branch that
|
|
334
|
+
does not exist, and makes nothing.
|
|
335
|
+
|
|
336
|
+
The author chooses how many Agents work in a Workspace. Agents in one Worktree share git, as people in one checkout do.
|
|
337
|
+
Each coder that needs its own branch gets its own Worktree of the one clone.
|
|
266
338
|
|
|
267
|
-
|
|
268
|
-
|
|
339
|
+
Your Machine chooses the branch name. Give each run a different branch, so that two runs do not push to one branch. Make
|
|
340
|
+
it from a field of the run input, or from `instanceId` when the run input has no field that is different for each run.
|
|
341
|
+
Only a root `workspace()` gets `instanceId` from jr2. A `workspace()` that a different Machine invokes gets it only when
|
|
342
|
+
its parent gives it.
|
|
269
343
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
344
|
+
An Agent, a `command`, a `push`, and an `http` Effect with a file body each name their Worktree by its path: `cwd` for a
|
|
345
|
+
Turn, `worktree` for an Effect. A `push` has no branch in its input. jr2 reads the branch from the cut of that path. So
|
|
346
|
+
an Agent that moves `HEAD` does not change what is pushed.
|
|
273
347
|
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
no field that is different for each run: ``spec: ({ input }) => ({ branch: `fix/${input.instanceId}` })``. Only a root
|
|
277
|
-
`workspace()` gets `instanceId` from jr2. A `workspace()` that a different Machine invokes gets it only when its parent
|
|
278
|
-
gives it.
|
|
348
|
+
jr2 has no Effect that removes a Worktree. To remove one, run `git worktree remove` in a `command`.
|
|
349
|
+
[Cut a Worktree](../guides/cut-a-worktree.md) gives the procedure.
|
|
279
350
|
|
|
280
351
|
## A Workspace with no Repo
|
|
281
352
|
|
|
@@ -504,15 +575,16 @@ export const machine = workspace(body, { input: runInput });
|
|
|
504
575
|
|
|
505
576
|
In a Workspace with no Repo:
|
|
506
577
|
|
|
507
|
-
- Type the body's input as `Workspaced<RunInput, never>`. The handles are `{ repos: {} }
|
|
578
|
+
- Type the body's input as `Workspaced<RunInput, never>`. The handles are `{ repos: {} }`.
|
|
508
579
|
- An Agent's Turn that gives no `cwd` works in `/work`. The Agent's `workspace` access is the same as in each Workspace:
|
|
509
580
|
`"write"` gives it `write`, `edit` and `bash`, and `"read"` gives it `bash` only.
|
|
510
581
|
- A `command` with no Effect secret runs in `/work`.
|
|
511
582
|
- An `http` Effect sends a file of `/work` with `file(path)`. The path is relative to `/work`.
|
|
512
|
-
- `
|
|
513
|
-
|
|
583
|
+
- A `worktree()` needs a Repo Slot, a `push` needs a branch, and a `command` with an Effect secret runs on a commit.
|
|
584
|
+
Thus `jr2 up` refuses all three.
|
|
514
585
|
|
|
515
|
-
jr2 deletes `/work` with the Sandbox. Send what must stay before the body ends, as the example does with `upload`.
|
|
586
|
+
jr2 deletes `/work` with the Sandbox. Send what must stay before the body ends, as the example does with `upload`. The
|
|
587
|
+
secret `files` that `upload` names is an entry of the `secrets` list of `jr2.config.ts`, as each Effect secret is. A
|
|
516
588
|
Lost Sandbox has lost all of its work, because no commit was pushed.
|
|
517
589
|
|
|
518
590
|
## The pod
|
|
@@ -529,10 +601,10 @@ A Sandbox pod has two containers, and two more when the Machine needs them:
|
|
|
529
601
|
### The Sandbox Image
|
|
530
602
|
|
|
531
603
|
The [Sandbox Image](../reference/glossary.md#sandbox-image) is the image of the Harness container. It holds the tools
|
|
532
|
-
that an Agent's Working tools can use, and the shell that you get
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
604
|
+
that an Agent's Working tools can use, and the shell that you get with `jr2 workspace shell`. The image is yours. Its
|
|
605
|
+
floor is glibc, git and a writable `HOME`. [Add tools to the Sandbox](../guides/add-tools-to-the-sandbox.md) gives the
|
|
606
|
+
full list. jr2 adds nothing to the image. It mounts its own runtime into the pod at `/opt/jr2`, and starts the Harness
|
|
607
|
+
from there. Thus the `ENTRYPOINT` and the `CMD` of the image do not run.
|
|
536
608
|
|
|
537
609
|
`image` names it in one of two forms:
|
|
538
610
|
|
|
@@ -593,8 +665,7 @@ A Workspace goes through these states:
|
|
|
593
665
|
|
|
594
666
|
1. `placing`: jr2 writes the Sandbox, and waits for a node.
|
|
595
667
|
2. `provisioning`: the pod starts.
|
|
596
|
-
3. `attaching`: the Harness clones each Repo Slot
|
|
597
|
-
do.
|
|
668
|
+
3. `attaching`: the Harness clones each Repo Slot. With no Repo Slot, this state has nothing to do.
|
|
598
669
|
4. `running`: the body runs.
|
|
599
670
|
5. `teardown`: the body is in a final state, and jr2 deletes the Sandbox.
|
|
600
671
|
6. `failing`: the body invoked [`fail`](../reference/authoring-surface/fail.md), and jr2 deletes the Sandbox. Then the
|
|
@@ -643,29 +714,37 @@ the Harness container does not lose the Workspace: the pod and `/work` stay.
|
|
|
643
714
|
- A per-run url must match an entry of [`git.credentials`](../reference/config.md#git-credentials). jr2 refuses the url
|
|
644
715
|
before it makes the Sandbox when no entry matches it. Thus a run cannot send the cluster's credentials to a host that
|
|
645
716
|
it chooses.
|
|
646
|
-
- `
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
- With no Repo Slot, `jr2 up` refuses a `push`, and a `command` that names an Effect secret.
|
|
717
|
+
- `jr2 up` refuses a Repo Slot name that starts with `.`, because `/work/.jr2/` is reserved for jr2.
|
|
718
|
+
- A cut of the branch that `default/` holds is `refused`, and the reason names `/work/<slot>/default`.
|
|
719
|
+
- With no Repo Slot, `jr2 up` refuses a `worktree()`, a `push`, and a `command` that names an Effect secret.
|
|
650
720
|
- A Size has only `limits.memory` and `limits.cpu`. jr2 refuses `requests` and each other key.
|
|
651
721
|
- `jr2 up` refuses a Size that leaves the Harness container less than 256Mi of memory, or no cpu.
|
|
652
|
-
- Under a Workspace with
|
|
722
|
+
- Under a Workspace with Repo Slots, a Turn states its `cwd`, and a `command`, a `push` and an `http` Effect with a file
|
|
723
|
+
body state their `worktree`. A Turn that wants `/work` states `cwd: "/work"`. An Agent with `workspace: "none"` needs
|
|
724
|
+
no `cwd`.
|
|
725
|
+
- A `push`, a `command` that names an Effect secret, and an `http` Effect with a file body need a Worktree that a cut of
|
|
726
|
+
this run made.
|
|
727
|
+
- Under a Workspace with more than one Repo Slot, a `push` names its `slot`.
|
|
653
728
|
|
|
654
729
|
The guides and the Reference give the refusal text of each rule.
|
|
655
730
|
|
|
656
731
|
## Read next
|
|
657
732
|
|
|
733
|
+
- [Cut a Worktree](../guides/cut-a-worktree.md)
|
|
658
734
|
- [Look inside a Sandbox](../guides/look-inside-a-sandbox.md)
|
|
659
735
|
- [Add tools to the Sandbox](../guides/add-tools-to-the-sandbox.md)
|
|
660
736
|
- [Size a Workspace](../guides/size-a-workspace.md)
|
|
661
737
|
- [Give the cluster git credentials](../guides/give-the-cluster-git-credentials.md)
|
|
662
738
|
- [Effects](effects.md), [Composition](composition.md), [Architecture](architecture.md)
|
|
663
739
|
- Reference: [`workspace`](../reference/authoring-surface/workspace.md),
|
|
740
|
+
[`worktree`](../reference/authoring-surface/worktree.md),
|
|
664
741
|
[`RepoSlot`](../reference/authoring-surface/type-reposlot.md), [`Size`](../reference/authoring-surface/type-size.md),
|
|
665
742
|
[`UserContainer`](../reference/authoring-surface/type-usercontainer.md),
|
|
666
743
|
[`workspace.lost`](../reference/mechanism-events.md#workspace-lost), [`sandbox`](../reference/config.md#sandbox)
|
|
667
744
|
- [ADR-0012](../reference/decisions/0012-workspace-wrapper-machine.md): `workspace()` wraps a body Machine and owns only
|
|
668
745
|
Sandbox lifecycle
|
|
746
|
+
- [ADR-0075](../reference/decisions/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md): a Machine cuts a
|
|
747
|
+
Worktree, and the Workspace only clones
|
|
669
748
|
- [ADR-0051](../reference/decisions/0051-a-repo-is-a-slot-on-the-workspace-and-a-cache-on-the-node.md): a Repo is a slot
|
|
670
749
|
on the `workspace()` and a cache on the node
|
|
671
750
|
- [ADR-0060](../reference/decisions/0060-a-workspace-states-its-size-and-jr2-reserves-all-of-it.md): a Workspace states
|
|
@@ -406,8 +406,7 @@ there:
|
|
|
406
406
|
```text
|
|
407
407
|
…
|
|
408
408
|
→ context kind-jr2 / namespace my-instance
|
|
409
|
-
run
|
|
410
|
-
→ active "triaging"
|
|
409
|
+
run f40a189e-b554-4310-b6e5-3b92c74e414e (triage) — attached
|
|
411
410
|
→ active "triaging"
|
|
412
411
|
→ active "clarify"
|
|
413
412
|
```
|
|
@@ -427,10 +426,10 @@ can show the same state. `jr2 run` does not return while the run waits. Keep it
|
|
|
427
426
|
> ```text
|
|
428
427
|
> …
|
|
429
428
|
> → context kind-jr2 / namespace my-instance
|
|
430
|
-
> run
|
|
429
|
+
> run 4eafe1a5-b45d-4613-8ae3-4c85b26eeb0c (triage) — attached
|
|
431
430
|
> → active "triaging"
|
|
432
431
|
> → done "accepted"
|
|
433
|
-
> {"runId":"
|
|
432
|
+
> {"runId":"4eafe1a5-b45d-4613-8ae3-4c85b26eeb0c","workflow":"triage","instanceId":"d4daa575-f8ac-4ba9-af2e-406084adbd89","startedAt":"2026-11-06T19:24:22.161Z","startedBy":{"kind":"caller","via":"token","name":"instance","onBehalfOf":"kubernetes-admin"},"status":"done","value":"accepted","context":{"request":"Add a --version flag to the CLI. It prints the installed version and exits.","exchange":[],"summary":"Add a --version flag to the CLI that prints the installed version and exits."},"children":[],"waiting":[],"held":[],"assembly":"9ff0a4d3c5da","output":{"outcome":"accepted","summary":"Add a --version flag to the CLI that prints the installed version and exits."}}
|
|
434
433
|
> ```
|
|
435
434
|
>
|
|
436
435
|
> Your run id and your [Instance ID](../reference/glossary.md#instance-id) are different, and so is the `summary`, the
|
|
@@ -444,14 +443,15 @@ The Gate holds the question of the Agent in its `meta`. In the send terminal, ru
|
|
|
444
443
|
jr2 status <run id>
|
|
445
444
|
```
|
|
446
445
|
|
|
447
|
-
`<run id>` is the run id that `jr2 run` printed. You can give its first 4 characters or more, such as `
|
|
446
|
+
`<run id>` is the run id that `jr2 run` printed. You can give its first 4 characters or more, such as `f40a189e`.
|
|
448
447
|
[`jr2 status`](../reference/cli.md#status) prints the status of the run as one line of JSON. The Gate is in `gates`, at
|
|
449
448
|
the end:
|
|
450
449
|
|
|
451
450
|
```text
|
|
452
451
|
…
|
|
453
452
|
→ context kind-jr2 / namespace my-instance
|
|
454
|
-
{"runId":"
|
|
453
|
+
{"runId":"f40a189e-b554-4310-b6e5-3b92c74e414e","workflow":"triage","instanceId":"6a6fb1c4-d6d8-4867-a51b-693c0772cc7b","startedAt":"2026-11-06T19:23:30.814Z","startedBy":{"kind":"caller","via":"token","name":"instance","onBehalfOf":"kubernetes-admin"},"status":"active","value":"clarify","context":{"request":"People keep asking what version they are running.","exchange":[{"question":"Where should the version number be displayed to users (e.g., a specific command like `--version`, an 'About' screen, or a startup log message)?"}]},"children":[],"waiting":[],"held":[],"assembly":"9ff0a4d3c5da","gates":[{"gate":"clarify","path":["clarify"],"accepts":[{"name":"answer","description":"Answer the triager's question. It triages the request again with the answer in hand.","input":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"info":{"type":"string","description":"The answer, in prose."}},"required":["info"],"additionalProperties":false}}],"acceptsNow":["answer"],"meta":{"question":"Where should the version number be displayed to users (e.g., a specific command like `--version`, an 'About' screen, or a startup log message)?"}}]}
|
|
454
|
+
started by: token/instance on behalf of kubernetes-admin
|
|
455
455
|
```
|
|
456
456
|
|
|
457
457
|
The `question` is in the words of the model, so your question is different. Your instance id is different too. The Gate
|
|
@@ -470,7 +470,7 @@ jr2 send <run id> --gate clarify --event answer --input '{"info":"Add a --versio
|
|
|
470
470
|
```text
|
|
471
471
|
…
|
|
472
472
|
→ context kind-jr2 / namespace my-instance
|
|
473
|
-
delivered answer to gate "clarify" on
|
|
473
|
+
delivered answer to gate "clarify" on f40a189e-b554-4310-b6e5-3b92c74e414e
|
|
474
474
|
```
|
|
475
475
|
|
|
476
476
|
The run goes back to `triaging`, and the Agent reads your answer. Look at the first terminal. When the Agent picks
|
|
@@ -481,7 +481,7 @@ The run goes back to `triaging`, and the Agent reads your answer. Look at the fi
|
|
|
481
481
|
→ active "triaging"
|
|
482
482
|
→ active "triaging"
|
|
483
483
|
→ done "accepted"
|
|
484
|
-
{"runId":"
|
|
484
|
+
{"runId":"f40a189e-b554-4310-b6e5-3b92c74e414e","workflow":"triage","instanceId":"6a6fb1c4-d6d8-4867-a51b-693c0772cc7b","startedAt":"2026-11-06T19:23:30.814Z","startedBy":{"kind":"caller","via":"token","name":"instance","onBehalfOf":"kubernetes-admin"},"status":"done","value":"accepted","context":{"request":"People keep asking what version they are running.","exchange":[{"question":"Where should the version number be displayed to users (e.g., a specific command like `--version`, an 'About' screen, or a startup log message)?","info":"Add a --version flag to the CLI. It prints the installed version and exits."}],"summary":"Add a --version flag to the CLI that prints the installed version and exits."},"children":[],"waiting":[],"held":[],"answers":[{"gate":"clarify","type":"answer","at":"2026-11-06T19:24:02.957Z","answeredBy":{"via":"token","name":"instance","onBehalfOf":"kubernetes-admin"}}],"assembly":"9ff0a4d3c5da","output":{"outcome":"accepted","summary":"Add a --version flag to the CLI that prints the installed version and exits."}}
|
|
485
485
|
```
|
|
486
486
|
|
|
487
487
|
`summary` is the request as the model wrote it again, in one sentence. Your summary is different. The `output` of the
|
|
@@ -502,24 +502,25 @@ This request does not say what is wrong. The run goes to `clarify` and waits, as
|
|
|
502
502
|
```text
|
|
503
503
|
…
|
|
504
504
|
→ context kind-jr2 / namespace my-instance
|
|
505
|
-
run
|
|
505
|
+
run 7e6c9deb-ca65-4103-b517-abf6b0028aff (triage) — attached
|
|
506
506
|
→ active "triaging"
|
|
507
507
|
→ active "clarify"
|
|
508
508
|
```
|
|
509
509
|
|
|
510
|
-
`
|
|
510
|
+
`7e6c9deb-ca65-4103-b517-abf6b0028aff` is the id of the second run. Your run id is different. If the Agent picks
|
|
511
511
|
`accept` or `reject`, start the run again.
|
|
512
512
|
|
|
513
513
|
## Answer from the Console
|
|
514
514
|
|
|
515
|
-
Open `http://localhost:4000` in your browser. If the
|
|
516
|
-
step. If the
|
|
515
|
+
Open `http://localhost:4000` in your browser. If the nav shows `as token/instance` and the badge `live`, go to the next
|
|
516
|
+
step. If the nav shows the `Caller token` box, get the token. In the send terminal, run:
|
|
517
517
|
|
|
518
518
|
```sh
|
|
519
519
|
kubectl -n my-instance get secret jr2-instance -o jsonpath='{.data.JR2_INSTANCE_TOKEN}' | base64 -d
|
|
520
520
|
```
|
|
521
521
|
|
|
522
|
-
Type the token in the `
|
|
522
|
+
Type the token in the `Caller token` box. Push Enter. The badge after the box shows `live`, and the nav shows
|
|
523
|
+
`as token/instance`.
|
|
523
524
|
|
|
524
525
|
Click `triage` in the Fleet rail on the left. The center shows the Machine of `triage`, with its states and transitions.
|
|
525
526
|
Click the run in the rail. The Console lights the state of the run, `clarify`.
|