@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
|
@@ -7,7 +7,8 @@ description: How a run survives a restart of the Orchestrator, what ends it, and
|
|
|
7
7
|
|
|
8
8
|
A run is durable. The [Orchestrator](../reference/glossary.md#orchestrator) saves each run after each transition of its
|
|
9
9
|
[Machine](../reference/glossary.md#machine). When the Orchestrator starts again, it continues each run that did not end,
|
|
10
|
-
from the state that it saved. A run that ended stays readable for
|
|
10
|
+
from the state that it saved. A run that ended stays readable for [`runs.retain`](../reference/config.md#runs), 30 days
|
|
11
|
+
by default.
|
|
11
12
|
|
|
12
13
|
## Why runs are durable
|
|
13
14
|
|
|
@@ -78,7 +79,7 @@ A run that the Orchestrator does not continue gets one of these results:
|
|
|
78
79
|
|
|
79
80
|
| Result | When | What stays |
|
|
80
81
|
| --------- | ----------------------------------------------------------------------------------------------------------- | -------------------------------------------------- |
|
|
81
|
-
| `lost` | No Workflow has the name of the run's file, or the row holds no snapshot. | The row and the reason, for
|
|
82
|
+
| `lost` | No Workflow has the name of the run's file, or the row holds no snapshot. | The row and the reason, for `runs.retain`. |
|
|
82
83
|
| `drifted` | The Orchestrator cannot read the Assembly of the run, or the Machine of the Workflow has a different shape. | The row and the snapshot. |
|
|
83
84
|
| `failed` | The restore of the run stopped with an error. | The run stays live. The next start tries it again. |
|
|
84
85
|
|
|
@@ -112,8 +113,9 @@ Orchestrator cannot read the Assembly that the run holds:
|
|
|
112
113
|
|
|
113
114
|
The Orchestrator keeps a drifted run, and you can read it. [`jr2 status`](../reference/cli.md#status) shows its status,
|
|
114
115
|
`drifted`, with the reason. The reason names the Workflow and the two digests, or the Assembly and why it cannot load.
|
|
115
|
-
[`jr2 runs`](../reference/cli.md#runs)
|
|
116
|
-
|
|
116
|
+
By default, [`jr2 runs`](../reference/cli.md#runs) shows only the live runs, so it does not show a drifted run.
|
|
117
|
+
`jr2 runs --status drifted`, `--status ended` or `--status all` shows it with its reason. jr2 cannot move a drifted run
|
|
118
|
+
to a new Machine. Thus, before you change the Kit version, let the runs end, or cancel them.
|
|
117
119
|
|
|
118
120
|
## CANCEL and stop
|
|
119
121
|
|
|
@@ -137,18 +139,40 @@ The operator removes them after the same idle timeout. A run that a Machine fail
|
|
|
137
139
|
|
|
138
140
|
`jr2 status` shows a cancelled run with the status `cancelled` and the state that it was in.
|
|
139
141
|
|
|
140
|
-
##
|
|
142
|
+
## History
|
|
141
143
|
|
|
142
|
-
jr2 keeps the row of a run that ended for
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
jr2 keeps the row of a run that ended for 30 days after its last write. `runs.retain` in `jr2.config.ts` changes this
|
|
145
|
+
time, for example `runs: { retain: "90d" }`. It is a number and `m`, `h`, `d` or `w`, and it is at least `1h`. This is
|
|
146
|
+
true for each status that is not live: `done`, `failed`, `error`, `cancelled`, `lost` and `drifted`. The Orchestrator
|
|
147
|
+
deletes the older rows when it starts, and one time each hour after that. A live run stays, whatever its age. A run that
|
|
148
|
+
waits at a Gate for a month is still there.
|
|
146
149
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
+
`jr2 runs --status ended` lists the runs that ended, newest first. `--workflow` and `--since` make the list shorter. jr2
|
|
151
|
+
is not the record of the results of a run. A Machine sends its results where they belong, such as a pull request.
|
|
152
|
+
`jr2 status` on a run that ended is for debugging. After `runs.retain`, `jr2 status` says that the run does not exist,
|
|
153
|
+
and a prefix of its id no longer finds it.
|
|
150
154
|
|
|
151
|
-
The
|
|
155
|
+
The time of a drifted run starts at the restart or the publish that refused it, not at its last transition.
|
|
156
|
+
|
|
157
|
+
The same time applies to the [Conversations](../reference/glossary.md#conversation) of a run and to the log of each
|
|
158
|
+
[Hook](../reference/glossary.md#hook). The Orchestrator keeps each conversation of an Agent while the run is kept, and
|
|
159
|
+
deletes it with the row of the run. Thus `jr2 logs` reads the conversations of a run that ended, also after its
|
|
160
|
+
[Sandbox](../reference/glossary.md#sandbox) is gone. [Read a conversation](../guides/read-a-conversation.md) gives the
|
|
161
|
+
commands.
|
|
162
|
+
|
|
163
|
+
### The state volume
|
|
164
|
+
|
|
165
|
+
The Orchestrator keeps the rows of the runs, the conversations, the Assemblies and the
|
|
166
|
+
[Charts](../reference/glossary.md#chart) on its state volume. A new volume claim is `5Gi` by default, and `jr2 up` keeps
|
|
167
|
+
the size of a claim that exists. `runs.volume` in `jr2.config.ts` sets its size, such as `runs: { volume: "20Gi" }`.
|
|
168
|
+
`jr2 up` makes the claim larger when its StorageClass allows expansion, and refuses otherwise. It never makes a claim
|
|
169
|
+
smaller, because Kubernetes cannot.
|
|
170
|
+
|
|
171
|
+
A space guard keeps the volume from becoming full. When the volume is more than 80% full, the Orchestrator deletes the
|
|
172
|
+
conversations of the runs that ended, the oldest run first, until the volume is less than 80% full. The rows of the runs
|
|
173
|
+
stay, and each one shows that its conversations went for space. The guard never deletes a conversation of a live run.
|
|
174
|
+
When the volume is more than 95% full and no ended run has a conversation left, the Orchestrator keeps no more entries
|
|
175
|
+
of the open conversations. One conversation also has a limit of 8 MiB, after which the Orchestrator keeps no more of it.
|
|
152
176
|
|
|
153
177
|
[`jr2 down`](../reference/cli.md#down) deletes the namespace of the Instance, and the store with it. The live runs go
|
|
154
178
|
too.
|
|
@@ -162,7 +186,9 @@ too.
|
|
|
162
186
|
- The Orchestrator never continues a drifted run, and never moves it to a new Machine.
|
|
163
187
|
- The Orchestrator never continues a cancelled run.
|
|
164
188
|
- `CANCEL` is the only run event that `jr2 send` sends without `--gate`. `--keep` goes only with `CANCEL`.
|
|
165
|
-
- jr2 keeps a run that ended for
|
|
189
|
+
- jr2 keeps a run that ended for `runs.retain`, 30 days by default. The hourly sweep never deletes a live run.
|
|
190
|
+
- jr2 keeps the conversations of a run for as long as it keeps the run, unless the space guard deletes them first. The
|
|
191
|
+
space guard never deletes a conversation of a live run.
|
|
166
192
|
|
|
167
193
|
[Cancel a run](../guides/cancel-a-run.md) and [Watch a run](../guides/watch-a-run.md) give the commands and their
|
|
168
194
|
output.
|
|
@@ -170,6 +196,7 @@ output.
|
|
|
170
196
|
## Read next
|
|
171
197
|
|
|
172
198
|
- [Watch a run](../guides/watch-a-run.md)
|
|
199
|
+
- [Read a conversation](../guides/read-a-conversation.md)
|
|
173
200
|
- [Cancel a run](../guides/cancel-a-run.md)
|
|
174
201
|
- [Iterate on a Machine on kind](../guides/iterate-on-a-machine-on-kind.md)
|
|
175
202
|
- [Effects](effects.md), [Workspaces](workspaces.md) and [Converge](converge.md)
|
|
@@ -183,7 +210,7 @@ output.
|
|
|
183
210
|
- [ADR-0025](../reference/decisions/0025-cancel-ends-a-run-stop-parks-it.md): `CANCEL` ends a run, and a stop parks it
|
|
184
211
|
- [ADR-0030](../reference/decisions/0030-a-snapshot-names-the-machine-it-was-written-under.md): a snapshot names the
|
|
185
212
|
Machine that wrote it
|
|
186
|
-
- [ADR-0065](../reference/decisions/0065-a-persist-survives-a-crash-and-history-is-a-
|
|
187
|
-
and jr2 keeps
|
|
213
|
+
- [ADR-0065](../reference/decisions/0065-a-persist-survives-a-crash-and-history-is-kept-for-a-set-time.md): a save
|
|
214
|
+
survives a crash, and jr2 keeps history for `runs.retain`
|
|
188
215
|
- [ADR-0069](../reference/decisions/0069-the-orchestrator-is-a-kit-image-and-an-instance-publishes-its-assembly.md): a
|
|
189
216
|
run holds the Assembly that it started under
|
package/docs/concepts/effects.md
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Effects
|
|
3
|
-
description: How a Machine runs a command, calls a URL, pushes a branch or starts a run
|
|
3
|
+
description: How a Machine runs a command, calls a URL or an MCP tool, pushes a branch or starts a run.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Effects
|
|
7
7
|
|
|
8
8
|
An [Effect](../reference/glossary.md#effect) is work that a [Machine](../reference/glossary.md#machine) does outside
|
|
9
|
-
itself. jr2 has
|
|
10
|
-
calls a URL, `push` pushes the
|
|
11
|
-
[Workflow](../reference/glossary.md#workflow)
|
|
12
|
-
[
|
|
9
|
+
itself. jr2 has five kinds: `command` runs a program in the [Workspace](../reference/glossary.md#workspace), `http`
|
|
10
|
+
calls a URL, `push` pushes the branch of a [Worktree](../reference/glossary.md#worktree), `dispatch` starts a run of a
|
|
11
|
+
[Workflow](../reference/glossary.md#workflow), and `mcp` calls a tool of an MCP server. The Kit also gives
|
|
12
|
+
[`worktree()`](../reference/authoring-surface/worktree.md), an Effect on the `command` machinery that cuts a Worktree.
|
|
13
|
+
You write an Effect as an actor slot, beside the [Agents](../reference/glossary.md#agent) of the Machine.
|
|
13
14
|
|
|
14
15
|
## Why Effects exist
|
|
15
16
|
|
|
@@ -26,8 +27,8 @@ two times. A plain [xstate](https://xstate.js.org) promise has no such record.
|
|
|
26
27
|
|
|
27
28
|
Put an Effect under `actors` in [`jr2Setup`](../reference/authoring-surface/jr2setup.md). Invoke it by its key from a
|
|
28
29
|
state. The state's `onDone` gets the output of the Effect. This example is a Workflow with a Workspace. An Agent fixes
|
|
29
|
-
the code
|
|
30
|
-
the branch:
|
|
30
|
+
the code in a Worktree that the Machine cuts first. It can ask for a test run with the pick `run_tests`. When the Agent
|
|
31
|
+
picks `finished`, the Machine pushes the branch:
|
|
31
32
|
|
|
32
33
|
**Anthropic**
|
|
33
34
|
|
|
@@ -39,9 +40,11 @@ import {
|
|
|
39
40
|
command,
|
|
40
41
|
defineEvent,
|
|
41
42
|
fail,
|
|
43
|
+
isReady,
|
|
42
44
|
jr2Setup,
|
|
43
45
|
push,
|
|
44
46
|
workspace,
|
|
47
|
+
worktree,
|
|
45
48
|
type CommandOutput,
|
|
46
49
|
type Workspaced,
|
|
47
50
|
} from "@jr2/orchestrator";
|
|
@@ -61,6 +64,9 @@ const finished = defineEvent({
|
|
|
61
64
|
const runInput = z.object({ prompt: z.string(), branch: z.string() });
|
|
62
65
|
type BodyInput = Workspaced<z.infer<typeof runInput>, "app">;
|
|
63
66
|
|
|
67
|
+
// The Worktree that the coder, the tests and the push all name.
|
|
68
|
+
const appTree = (context: BodyInput) => `${context.workspace.repos.app}/fix` as const;
|
|
69
|
+
|
|
64
70
|
const passed = (output: CommandOutput): boolean => output.outcome === "exited" && output.code === 0;
|
|
65
71
|
|
|
66
72
|
const body = jr2Setup({
|
|
@@ -71,7 +77,8 @@ const body = jr2Setup({
|
|
|
71
77
|
model: "anthropic/claude-haiku-5-5",
|
|
72
78
|
instructions: "You are a careful engineer. You commit your work on the branch.",
|
|
73
79
|
}),
|
|
74
|
-
//
|
|
80
|
+
// Three Effects. Each is an actor slot, beside the Agent.
|
|
81
|
+
cut: worktree(),
|
|
75
82
|
tests: command(["node", "--test"], { timeout: "5m" }),
|
|
76
83
|
publish: push(),
|
|
77
84
|
fail: fail(),
|
|
@@ -80,12 +87,20 @@ const body = jr2Setup({
|
|
|
80
87
|
id: "test-and-push",
|
|
81
88
|
context: ({ input }) => input,
|
|
82
89
|
on: { "workspace.lost": ".lost", "agent.fault": ".failed" },
|
|
83
|
-
initial: "
|
|
90
|
+
initial: "cutting",
|
|
84
91
|
states: {
|
|
92
|
+
// The Workspace only clones. The Machine cuts the Worktree that the Agent works in.
|
|
93
|
+
cutting: {
|
|
94
|
+
invoke: {
|
|
95
|
+
src: "cut",
|
|
96
|
+
input: ({ context }) => ({ path: appTree(context), branch: context.branch }),
|
|
97
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "coding" }, { target: "notCut" }],
|
|
98
|
+
},
|
|
99
|
+
},
|
|
85
100
|
coding: {
|
|
86
101
|
invoke: {
|
|
87
102
|
src: "coder",
|
|
88
|
-
input: ({ context }) => ({ prompt: context.prompt, cwd: context
|
|
103
|
+
input: ({ context }) => ({ prompt: context.prompt, cwd: appTree(context) }),
|
|
89
104
|
},
|
|
90
105
|
on: { finished: "publishing" },
|
|
91
106
|
initial: "ready",
|
|
@@ -94,6 +109,7 @@ const body = jr2Setup({
|
|
|
94
109
|
testing: {
|
|
95
110
|
invoke: {
|
|
96
111
|
src: "tests",
|
|
112
|
+
input: ({ context }) => ({ worktree: appTree(context) }),
|
|
97
113
|
onDone: {
|
|
98
114
|
target: "ready",
|
|
99
115
|
// The Agent reads this text as the answer to its run_tests pick.
|
|
@@ -110,10 +126,12 @@ const body = jr2Setup({
|
|
|
110
126
|
publishing: {
|
|
111
127
|
invoke: {
|
|
112
128
|
src: "publish",
|
|
129
|
+
input: ({ context }) => ({ worktree: appTree(context) }),
|
|
113
130
|
onDone: [{ guard: ({ event }) => event.output.outcome === "pushed", target: "done" }, { target: "notPushed" }],
|
|
114
131
|
},
|
|
115
132
|
},
|
|
116
133
|
done: { type: "final" },
|
|
134
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
117
135
|
// A Failure ends the body, and jr2 deletes the Sandbox with its commits. To keep them, wait at
|
|
118
136
|
// a Gate before this state.
|
|
119
137
|
notPushed: { invoke: { src: "fail", input: { reason: "the push did not publish the fix" } } },
|
|
@@ -125,7 +143,6 @@ const body = jr2Setup({
|
|
|
125
143
|
export const machine = workspace(body, {
|
|
126
144
|
input: runInput,
|
|
127
145
|
repos: { app: "https://github.com/you/app.git" },
|
|
128
|
-
spec: ({ input }) => ({ branch: input.branch }),
|
|
129
146
|
});
|
|
130
147
|
```
|
|
131
148
|
|
|
@@ -139,9 +156,11 @@ import {
|
|
|
139
156
|
command,
|
|
140
157
|
defineEvent,
|
|
141
158
|
fail,
|
|
159
|
+
isReady,
|
|
142
160
|
jr2Setup,
|
|
143
161
|
push,
|
|
144
162
|
workspace,
|
|
163
|
+
worktree,
|
|
145
164
|
type CommandOutput,
|
|
146
165
|
type Workspaced,
|
|
147
166
|
} from "@jr2/orchestrator";
|
|
@@ -161,6 +180,9 @@ const finished = defineEvent({
|
|
|
161
180
|
const runInput = z.object({ prompt: z.string(), branch: z.string() });
|
|
162
181
|
type BodyInput = Workspaced<z.infer<typeof runInput>, "app">;
|
|
163
182
|
|
|
183
|
+
// The Worktree that the coder, the tests and the push all name.
|
|
184
|
+
const appTree = (context: BodyInput) => `${context.workspace.repos.app}/fix` as const;
|
|
185
|
+
|
|
164
186
|
const passed = (output: CommandOutput): boolean => output.outcome === "exited" && output.code === 0;
|
|
165
187
|
|
|
166
188
|
const body = jr2Setup({
|
|
@@ -171,7 +193,8 @@ const body = jr2Setup({
|
|
|
171
193
|
model: "local/qwen3.6-35b-a3b",
|
|
172
194
|
instructions: "You are a careful engineer. You commit your work on the branch.",
|
|
173
195
|
}),
|
|
174
|
-
//
|
|
196
|
+
// Three Effects. Each is an actor slot, beside the Agent.
|
|
197
|
+
cut: worktree(),
|
|
175
198
|
tests: command(["node", "--test"], { timeout: "5m" }),
|
|
176
199
|
publish: push(),
|
|
177
200
|
fail: fail(),
|
|
@@ -180,12 +203,20 @@ const body = jr2Setup({
|
|
|
180
203
|
id: "test-and-push",
|
|
181
204
|
context: ({ input }) => input,
|
|
182
205
|
on: { "workspace.lost": ".lost", "agent.fault": ".failed" },
|
|
183
|
-
initial: "
|
|
206
|
+
initial: "cutting",
|
|
184
207
|
states: {
|
|
208
|
+
// The Workspace only clones. The Machine cuts the Worktree that the Agent works in.
|
|
209
|
+
cutting: {
|
|
210
|
+
invoke: {
|
|
211
|
+
src: "cut",
|
|
212
|
+
input: ({ context }) => ({ path: appTree(context), branch: context.branch }),
|
|
213
|
+
onDone: [{ guard: ({ event }) => isReady(event.output), target: "coding" }, { target: "notCut" }],
|
|
214
|
+
},
|
|
215
|
+
},
|
|
185
216
|
coding: {
|
|
186
217
|
invoke: {
|
|
187
218
|
src: "coder",
|
|
188
|
-
input: ({ context }) => ({ prompt: context.prompt, cwd: context
|
|
219
|
+
input: ({ context }) => ({ prompt: context.prompt, cwd: appTree(context) }),
|
|
189
220
|
},
|
|
190
221
|
on: { finished: "publishing" },
|
|
191
222
|
initial: "ready",
|
|
@@ -194,6 +225,7 @@ const body = jr2Setup({
|
|
|
194
225
|
testing: {
|
|
195
226
|
invoke: {
|
|
196
227
|
src: "tests",
|
|
228
|
+
input: ({ context }) => ({ worktree: appTree(context) }),
|
|
197
229
|
onDone: {
|
|
198
230
|
target: "ready",
|
|
199
231
|
// The Agent reads this text as the answer to its run_tests pick.
|
|
@@ -210,10 +242,12 @@ const body = jr2Setup({
|
|
|
210
242
|
publishing: {
|
|
211
243
|
invoke: {
|
|
212
244
|
src: "publish",
|
|
245
|
+
input: ({ context }) => ({ worktree: appTree(context) }),
|
|
213
246
|
onDone: [{ guard: ({ event }) => event.output.outcome === "pushed", target: "done" }, { target: "notPushed" }],
|
|
214
247
|
},
|
|
215
248
|
},
|
|
216
249
|
done: { type: "final" },
|
|
250
|
+
notCut: { invoke: { src: "fail", input: { reason: "the Worktree was not cut" } } },
|
|
217
251
|
// A Failure ends the body, and jr2 deletes the Sandbox with its commits. To keep them, wait at
|
|
218
252
|
// a Gate before this state.
|
|
219
253
|
notPushed: { invoke: { src: "fail", input: { reason: "the push did not publish the fix" } } },
|
|
@@ -225,7 +259,6 @@ const body = jr2Setup({
|
|
|
225
259
|
export const machine = workspace(body, {
|
|
226
260
|
input: runInput,
|
|
227
261
|
repos: { app: "https://github.com/you/app.git" },
|
|
228
|
-
spec: ({ input }) => ({ branch: input.branch }),
|
|
229
262
|
});
|
|
230
263
|
```
|
|
231
264
|
|
|
@@ -242,6 +275,7 @@ example above, `jr2 up` prints these lines:
|
|
|
242
275
|
|
|
243
276
|
```text
|
|
244
277
|
effects: workflow "test-and-push" — what it runs outside itself (ADR-0067)
|
|
278
|
+
cut: worktree — 600s, in the Harness
|
|
245
279
|
tests: command ["node","--test"] — 300s, in the Harness
|
|
246
280
|
publish: push — 300s, in the Sandbox Effector
|
|
247
281
|
```
|
|
@@ -253,12 +287,13 @@ run `failed`:
|
|
|
253
287
|
|
|
254
288
|
```text
|
|
255
289
|
failures: workflow "test-and-push" — the states that fail the run (ADR-0073)
|
|
290
|
+
test-and-push.notCut: invokes fail
|
|
256
291
|
test-and-push.notPushed: invokes fail
|
|
257
292
|
test-and-push.failed: invokes fail
|
|
258
293
|
test-and-push.lost: invokes fail
|
|
259
294
|
```
|
|
260
295
|
|
|
261
|
-
## The
|
|
296
|
+
## The five kinds
|
|
262
297
|
|
|
263
298
|
### `command`
|
|
264
299
|
|
|
@@ -268,10 +303,9 @@ argument that the input of the Effect fills. Thus an Agent's text cannot become
|
|
|
268
303
|
in the argv: `["sh", "-c", "…"]`. Then the result is the result of your script. The Agent can change the files that the
|
|
269
304
|
script runs, so do not trust its result more than the Agent.
|
|
270
305
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
option). The full output goes to the run's feed.
|
|
306
|
+
Under [Repo Slots](../reference/glossary.md#repo-slot), the input of a `command` names its Worktree: `{ worktree }`, a
|
|
307
|
+
Worktree that a cut made, or `/work/<slot>/default`. Its default timeout is 10 minutes. Its output keeps the end of what
|
|
308
|
+
the program wrote: 4096 characters by default (the `tail` option). The full output goes to the run's feed.
|
|
275
309
|
|
|
276
310
|
### `http`
|
|
277
311
|
|
|
@@ -413,15 +447,18 @@ export const machine = jr2Setup({
|
|
|
413
447
|
});
|
|
414
448
|
```
|
|
415
449
|
|
|
416
|
-
The body can also be a file of
|
|
417
|
-
The
|
|
450
|
+
The body can also be a file of a Worktree: `body: file(path)` (see [`file`](../reference/authoring-surface/file.md)).
|
|
451
|
+
The input then names the Worktree, `{ worktree }`, and a cut must have made it. A path alone does not name the target of
|
|
452
|
+
a credential. The default timeout of an `http` Effect is 30 seconds.
|
|
418
453
|
|
|
419
454
|
### `push`
|
|
420
455
|
|
|
421
|
-
[`push`](../reference/authoring-surface/push.md) pushes the
|
|
422
|
-
[Binding](../reference/glossary.md#binding) of its Repo Slot.
|
|
423
|
-
|
|
424
|
-
credential.
|
|
456
|
+
[`push`](../reference/authoring-surface/push.md) pushes the branch of a Worktree to the
|
|
457
|
+
[Binding](../reference/glossary.md#binding) of its Repo Slot. Its input names the Worktree, `{ worktree }`, and has no
|
|
458
|
+
branch. jr2 reads the branch from the cut of that path, so an Agent that moves `HEAD` does not change what jr2 pushes.
|
|
459
|
+
It uses the push credential of the `git.credentials` entry that the URL matches (see
|
|
460
|
+
[`git.credentials`](../reference/config.md#git-credentials)). The Agent never reads that credential. These options
|
|
461
|
+
change what a push publishes:
|
|
425
462
|
|
|
426
463
|
- `pin`: push the commit that the input names, such as a commit that a [Gate](../reference/glossary.md#gate) approved.
|
|
427
464
|
Without `pin`, jr2 pushes the tip of the Agent's branch when the Effect starts.
|
|
@@ -429,18 +466,26 @@ credential. These options change what a push publishes:
|
|
|
429
466
|
- `squash`: push one commit that holds all the changes, with the message that the input gives.
|
|
430
467
|
- `force`: replace what the remote branch holds.
|
|
431
468
|
|
|
432
|
-
With `pin`, the input gives `{ sha }`. With `squash`, it gives `{ message }`.
|
|
469
|
+
With `pin`, the input also gives `{ sha }`. With `squash`, it also gives `{ message }`.
|
|
433
470
|
|
|
434
471
|
After a signed or a squashed push, the commits on the remote are not the Agent's own commits. Then jr2 moves the Agent's
|
|
435
472
|
branch to the published commits. The Agent's files, index and stash do not change. The default timeout is 5 minutes.
|
|
436
473
|
|
|
474
|
+
### `worktree`
|
|
475
|
+
|
|
476
|
+
[`worktree()`](../reference/authoring-surface/worktree.md) cuts a Worktree, or reads the one that a cut made at that
|
|
477
|
+
path. Its outcomes are `ready`, `refused` and `unknown`. It runs in the Harness container, and it is idempotent. Each
|
|
478
|
+
thing that an Agent's word can cause is `refused`, and nothing changes. [Workspaces](workspaces.md) tells what a
|
|
479
|
+
Worktree is, and [Cut a Worktree](../guides/cut-a-worktree.md) tells how to use it.
|
|
480
|
+
|
|
437
481
|
### `dispatch`
|
|
438
482
|
|
|
439
483
|
[`dispatch`](../reference/authoring-surface/dispatch.md) starts a run of a Workflow. The new run is a run of its own: it
|
|
440
484
|
has its own line in [`jr2 runs`](../reference/cli.md#runs), its own Workspaces and its own `CANCEL`. Its record names
|
|
441
485
|
the run that started it: it is **dispatched by** that run. Use `dispatch` when a Machine waits for work, for example at
|
|
442
|
-
a [Gate](../reference/glossary.md#gate) that a
|
|
443
|
-
have. To use a Machine as a part of one run, invoke it in the run instead (see
|
|
486
|
+
a [Gate](../reference/glossary.md#gate) that a [Hook](../reference/glossary.md#hook) answers, and each item of work
|
|
487
|
+
needs a run of a Workflow that you have. To use a Machine as a part of one run, invoke it in the run instead (see
|
|
488
|
+
[Composition](composition.md)).
|
|
444
489
|
|
|
445
490
|
- The name of the Workflow is a constant of the definition, as `jr2 run` writes it: `"triage"`, or `"<wrapper>/<name>"`
|
|
446
491
|
for a named [Chart](../reference/glossary.md#chart). An Agent cannot choose it.
|
|
@@ -452,12 +497,27 @@ have. To use a Machine as a part of one run, invoke it in the run instead (see [
|
|
|
452
497
|
minutes with `wait`.
|
|
453
498
|
- With no `target`, the new run starts in the same Orchestrator. With
|
|
454
499
|
`target: { url: "https://<host>", token: secret("<name>") }`, it starts on a different Orchestrator. `url` is the
|
|
455
|
-
origin of that Orchestrator, and the secret holds
|
|
500
|
+
origin of that Orchestrator, and the secret holds the token of a [Caller](../reference/glossary.md#caller) of that
|
|
501
|
+
Orchestrator with the `start` scope for the Workflow, and also `read` when `wait` is `true`.
|
|
456
502
|
- The new run starts under the current [Assembly](../reference/glossary.md#assembly), as a run of `jr2 run` does.
|
|
457
503
|
|
|
458
504
|
The two runs are independent. A `CANCEL` of one run does not cancel the other. When the run that dispatched ends, the
|
|
459
505
|
new run continues.
|
|
460
506
|
|
|
507
|
+
### `mcp`
|
|
508
|
+
|
|
509
|
+
[`mcp`](../reference/authoring-surface/mcp.md) calls an MCP server: `mcp.call(server, tool, { input })` calls a tool,
|
|
510
|
+
`mcp.read(server, uri)` reads a resource, and `mcp.prompt(server, name, { input })` gets a prompt. `server` is a name of
|
|
511
|
+
the [`mcp`](../reference/config.md#mcp) block of `jr2.config.ts`, which holds the URL and the secret of the server. Thus
|
|
512
|
+
the definition holds no URL and no credential, and an Agent's word can reach only the arguments, through the input.
|
|
513
|
+
|
|
514
|
+
An Agent can also hold the tools of a server as [MCP tools](../reference/glossary.md#mcp-tools), and call them in its
|
|
515
|
+
Turn with no approval (see [Agents and Turns](agents-and-turns.md#the-mcp-tools)). Use an `mcp` Effect when the call
|
|
516
|
+
needs the approval of a person, or when the Machine makes the call with no model. The Agent picks, a Gate waits for the
|
|
517
|
+
approval, and the Effect calls the tool. The output of the Effect is the answer to the pick. Thus the approval is in the
|
|
518
|
+
record of the run, and the Machine routes on it. The default timeout is the `timeout` of the server: 60 seconds when it
|
|
519
|
+
sets none. [Call an MCP tool from a Machine](../guides/call-an-mcp-tool-from-a-machine.md) has an example.
|
|
520
|
+
|
|
461
521
|
## Where an Effect runs
|
|
462
522
|
|
|
463
523
|
You do not choose where an Effect runs. The kind, and what the Effect names, decide it. Each
|
|
@@ -467,40 +527,51 @@ commands in it:
|
|
|
467
527
|
| The Effect | Where it runs |
|
|
468
528
|
| --------------------------------------- | ----------------------------------------------------------------------------------- |
|
|
469
529
|
| A `command` that names no Effect secret | The [Harness](../reference/glossary.md#harness) container of the Sandbox |
|
|
530
|
+
| A `worktree()` | The Harness container of the Sandbox |
|
|
470
531
|
| A `command` that names an Effect secret | The [Sandbox Effector](../reference/glossary.md#sandbox-effector), against a commit |
|
|
471
532
|
| An `http` Effect | The [Instance Effector](../reference/glossary.md#instance-effector) |
|
|
472
533
|
| An `http` Effect with a Worktree file | The Sandbox Effector |
|
|
473
534
|
| A `push` | The Sandbox Effector |
|
|
474
535
|
| A `dispatch` with no `target` | The Orchestrator, in its own process |
|
|
475
536
|
| A `dispatch` with a `target` | The Instance Effector |
|
|
537
|
+
| An `mcp` Effect | The Instance Effector |
|
|
476
538
|
|
|
477
539
|
A `command` that names no Effect secret runs beside the Agent's [Working tools](../reference/glossary.md#working-tools).
|
|
478
|
-
It runs as the Agent's user, with the tools of the [Sandbox Image](../reference/glossary.md#sandbox-image).
|
|
479
|
-
|
|
540
|
+
It runs as the Agent's user, with the tools of the [Sandbox Image](../reference/glossary.md#sandbox-image). The Harness
|
|
541
|
+
confines it with Landlock, as it confines the Agent's shell. It has the same
|
|
542
|
+
[Stand-ins](../reference/glossary.md#stand-in) as the Agent's shell, and no credential of its own.
|
|
480
543
|
|
|
481
544
|
A `command` that names an Effect secret in its `env` runs in the Sandbox Effector, a container in which the Agent runs
|
|
482
545
|
nothing. It does not run in the live Worktree. It runs against one commit: the tip of the branch when it starts, or with
|
|
483
546
|
`pin`, the commit that its input names. When the Worktree held changes that the command did not see, its output has
|
|
484
547
|
`dirty: true`.
|
|
485
548
|
|
|
486
|
-
A `command`, a `push` and an `http` Effect with a file body need a Workspace. Invoke them from the body
|
|
487
|
-
[`workspace()`](../reference/authoring-surface/workspace.md). [Architecture](architecture.md) tells what each
|
|
488
|
-
is, and [Secrets and trust](secrets-and-trust.md) tells how an Effector holds the Effect secrets.
|
|
549
|
+
A `command`, a `worktree()`, a `push` and an `http` Effect with a file body need a Workspace. Invoke them from the body
|
|
550
|
+
of a [`workspace()`](../reference/authoring-surface/workspace.md). [Architecture](architecture.md) tells what each
|
|
551
|
+
Effector is, and [Secrets and trust](secrets-and-trust.md) tells how an Effector holds the Effect secrets.
|
|
489
552
|
|
|
490
553
|
## Every outcome is output
|
|
491
554
|
|
|
492
555
|
An Effect gives each outcome to `onDone`, a failure too. Route on the `outcome` field:
|
|
493
556
|
|
|
494
|
-
| Kind | The outcomes
|
|
495
|
-
| ---------- |
|
|
496
|
-
| `
|
|
497
|
-
| `
|
|
498
|
-
| `
|
|
499
|
-
| `
|
|
557
|
+
| Kind | The outcomes | The output type |
|
|
558
|
+
| ---------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
559
|
+
| `worktree` | `ready`, `refused`, `unknown` | [`WorktreeOutput`](../reference/authoring-surface/type-worktreeoutput.md) |
|
|
560
|
+
| `command` | `exited`, `timeout`, `killed`, `unknown` | [`CommandOutput`](../reference/authoring-surface/type-commandoutput.md) |
|
|
561
|
+
| `http` | `response`, `unreachable`, `refused`, `unknown` | [`HttpOutput`](../reference/authoring-surface/type-httpoutput.md) |
|
|
562
|
+
| `push` | `pushed`, `rejected`, `diverged`, `unknown` | [`PushOutput`](../reference/authoring-surface/type-pushoutput.md) |
|
|
563
|
+
| `dispatch` | `started`, `settled`, `refused`, `unreachable`, `unknown` | [`DispatchOutput`](../reference/authoring-surface/type-dispatchoutput.md) |
|
|
564
|
+
| `mcp` | `returned`, `refused`, `unreachable`, `input-required`, `unknown` | [`McpCallOutput`](../reference/authoring-surface/type-mcpcalloutput.md) |
|
|
500
565
|
|
|
501
566
|
A test that fails is `exited` with a code that is not 0. A program that the container does not have is `exited` with
|
|
502
567
|
code 127. An HTTP 4xx or 5xx status is a `response`. A Workflow that refuses the run input of a `dispatch` is `refused`,
|
|
503
|
-
with the status code and the report of the refusal. `
|
|
568
|
+
with the status code and the report of the refusal. A tool of an `mcp` Effect that ran and failed is `returned` with
|
|
569
|
+
`isError: true`. `unknown` means that jr2 cannot tell what the Effect did.
|
|
570
|
+
|
|
571
|
+
Each union is open: it holds a stand-in member, `LaterOutcome`, so a later release can add an outcome and your Machine
|
|
572
|
+
still works. Route on what you know, and give the rest a last arm with no guard. With no match, the run stays in that
|
|
573
|
+
state and shows no fault. So `createMachine`, `jr2 check`, `jr2 up` and the Chart door refuse an `onDone` with a guard
|
|
574
|
+
on its last arm. An invoke with no `onDone` is legal: the Effect settles, and the state stays.
|
|
504
575
|
|
|
505
576
|
The `onError` route of an Effect is only for a defect in the Machine or in the config. For example, the Effect is not in
|
|
506
577
|
a Workspace, or an `arg()` has no value, or an Open part has no binding. An outcome that means that the work did not
|
|
@@ -521,8 +592,10 @@ jr2 records its output. After an Orchestrator restart, jr2 reads the record:
|
|
|
521
592
|
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
522
593
|
| A `command` that names no Effect secret | jr2 attaches to it again. When the Harness does not know it, the outcome is `unknown`. It never runs again. |
|
|
523
594
|
| A `command` that names an Effect secret | jr2 follows it. When the Sandbox Effector lost it, jr2 runs it again against the same commit. With no commit recorded, the outcome is `unknown`. |
|
|
595
|
+
| A `worktree()` | jr2 attaches to it again. When the Harness does not know it, jr2 sends it again: a cut is idempotent. |
|
|
524
596
|
| A `push` | jr2 follows it. When the Sandbox Effector lost it, jr2 pushes the same commit again, and no other commit. With no commit recorded, the outcome is `unknown`. |
|
|
525
597
|
| An `http` Effect | jr2 follows it. When no Effector holds it, jr2 sends it again only if it is `idempotent`. Else the outcome is `unknown`. |
|
|
598
|
+
| An `mcp` Effect | As an `http` Effect. jr2 does not read the `idempotentHint` of a tool: only your `idempotent` mark counts. |
|
|
526
599
|
| A `dispatch` | jr2 sends the start again, with the same key. The Orchestrator answers with the run that the key started, and it starts no second run. |
|
|
527
600
|
|
|
528
601
|
A `command` that names no Effect secret runs the code of the Worktree, and that code can spend a Stand-in. Thus jr2 does
|
|
@@ -530,7 +603,8 @@ not run it two times. A `push`, and a `command` that names an Effect secret, run
|
|
|
530
603
|
jr2 can send them again with that commit.
|
|
531
604
|
|
|
532
605
|
To try again, write it in the Machine: a route from the outcome back into the state. Mark an `http` Effect `idempotent`
|
|
533
|
-
only when a second call is safe: the call has its own idempotency key, or it only reads.
|
|
606
|
+
only when a second call is safe: the call has its own idempotency key, or it only reads. The same rule is true for an
|
|
607
|
+
`mcp` Effect.
|
|
534
608
|
|
|
535
609
|
## When the state exits
|
|
536
610
|
|
|
@@ -539,8 +613,8 @@ When the run leaves the state, the Effect stops:
|
|
|
539
613
|
- jr2 kills the process group of a `command` that names no Effect secret.
|
|
540
614
|
- The Sandbox Effector stops a `command` that names an Effect secret. It sends `SIGTERM`, waits 5 seconds, then sends
|
|
541
615
|
`SIGKILL`.
|
|
542
|
-
- An `http` Effect and a `push` have no stop. jr2 stops waiting for the output, but the Effector can
|
|
543
|
-
work.
|
|
616
|
+
- An `http` Effect, an `mcp` Effect and a `push` have no stop. jr2 stops waiting for the output, but the Effector can
|
|
617
|
+
still finish the work.
|
|
544
618
|
- A `dispatch` with `wait` stops its wait. The run that it started continues.
|
|
545
619
|
|
|
546
620
|
jr2 records the stop, and the Machine gets no output. There is no "finally" in a Machine: cleanup is a state. Put an
|
|
@@ -569,8 +643,10 @@ pick waits for its answer.
|
|
|
569
643
|
## Rules
|
|
570
644
|
|
|
571
645
|
- An Effect is a key of `actors`. `createMachine` refuses an Effect that you write directly in an `invoke`.
|
|
572
|
-
-
|
|
573
|
-
|
|
646
|
+
- The last arm of an Effect's `onDone` has no guard. `createMachine` refuses one that has:
|
|
647
|
+
`machine "<id>": state "<state>" (Effect "<slot>") has an onDone with no unguarded last arm — … (ADR-0075)`.
|
|
648
|
+
- A `command`, a `worktree()`, a `push` and an `http` Effect with a file body run only inside a `workspace()`.
|
|
649
|
+
- Under a Workspace with more than one Repo Slot, a `push` names its `slot`.
|
|
574
650
|
- The host of an `http` URL is literal. An Effect secret never goes in the host, the query or the fragment of a URL.
|
|
575
651
|
- Each Effect secret that an Effect names is in the `secrets` list of `jr2.config.ts`, with a value of 8 characters or
|
|
576
652
|
more. `jr2 up` refuses a name that is not in the list, and a value that is shorter.
|
|
@@ -578,11 +654,14 @@ pick waits for its answer.
|
|
|
578
654
|
a `committer` field there.
|
|
579
655
|
- Each param of a pick that enters an Effect's state has a reader: the Effect's input, `fill`, a guard or an `assign`.
|
|
580
656
|
`createMachine` refuses a param that nothing reads, and a `fill` key that is also a param.
|
|
581
|
-
- A packaged Machine can leave an `http` URL, a `command` argv, one Effect secret name
|
|
582
|
-
Open. The composer binds it one time with `customize()`. `jr2 up` refuses
|
|
657
|
+
- A packaged Machine can leave an `http` URL, a `command` argv, one Effect secret name, the `target` of a `dispatch`, or
|
|
658
|
+
the server and the tool of an `mcp` Effect Open. The composer binds it one time with `customize()`. `jr2 up` refuses
|
|
659
|
+
an Open part that nobody bound.
|
|
583
660
|
- A `dispatch` with no `target` names a Workflow that the Assembly has. `jr2 up` refuses a name that it does not have,
|
|
584
661
|
and an `input` schema that the input of that Workflow does not take.
|
|
585
662
|
- The `url` of a `dispatch` target is an origin only: a scheme, a host and a port, with no path, no query and no user.
|
|
663
|
+
- An `mcp` Effect names a remote server that the `mcp` block declares. `jr2 up` refuses a server that the block does not
|
|
664
|
+
declare, and a stdio server.
|
|
586
665
|
|
|
587
666
|
The guides give the refusal text of each rule.
|
|
588
667
|
|
|
@@ -591,13 +670,17 @@ The guides give the refusal text of each rule.
|
|
|
591
670
|
- [Run a command or call a URL with an Effect](../guides/run-a-command-or-call-a-url.md)
|
|
592
671
|
- [Push and sign a branch](../guides/push-and-sign-a-branch.md)
|
|
593
672
|
- [Start a run from a run](../guides/start-a-run-from-a-run.md)
|
|
673
|
+
- [Call an MCP tool from a Machine](../guides/call-an-mcp-tool-from-a-machine.md)
|
|
594
674
|
- [Workspaces](workspaces.md), [The Menu](the-menu.md), [Secrets and trust](secrets-and-trust.md)
|
|
595
675
|
- Reference: [`command`](../reference/authoring-surface/command.md), [`http`](../reference/authoring-surface/http.md),
|
|
596
676
|
[`push`](../reference/authoring-surface/push.md), [`dispatch`](../reference/authoring-surface/dispatch.md),
|
|
597
|
-
[`
|
|
677
|
+
[`mcp`](../reference/authoring-surface/mcp.md), [`fromPick`](../reference/authoring-surface/frompick.md),
|
|
678
|
+
[`answer`](../reference/authoring-surface/answer.md)
|
|
598
679
|
- [ADR-0067](../reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md):
|
|
599
680
|
an Effect is an actor slot, and runs at most once unless marked idempotent
|
|
600
681
|
- [ADR-0068](../reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md): an Effector holds
|
|
601
682
|
an Effect's secrets and signs its wire
|
|
602
683
|
- [ADR-0071](../reference/decisions/0071-a-run-starts-a-run-through-a-dispatch-effect.md): a run starts a run through a
|
|
603
684
|
`dispatch` Effect
|
|
685
|
+
- [ADR-0079](../reference/decisions/0079-an-agent-holds-mcp-tools-a-machine-calls-them-as-an-effect-and-the-machine-is-the-approval.md):
|
|
686
|
+
a Machine calls an MCP server as an Effect, and the Machine is the approval
|