@jr2/orchestrator 0.6.0 → 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 +86 -9
- package/docs/concepts/architecture.md +41 -28
- package/docs/concepts/callers-and-hooks.md +205 -0
- package/docs/concepts/charts.md +7 -5
- package/docs/concepts/composition.md +10 -1
- package/docs/concepts/converge.md +4 -2
- package/docs/concepts/durable-runs.md +43 -16
- package/docs/concepts/effects.md +50 -22
- package/docs/concepts/gates.md +95 -25
- package/docs/concepts/machines-and-workflows.md +5 -4
- package/docs/concepts/pools-and-sources.md +187 -11
- package/docs/concepts/secrets-and-trust.md +73 -33
- package/docs/concepts/the-menu.md +11 -0
- package/docs/concepts/workspaces.md +6 -5
- package/docs/get-started/a-model-decides.md +14 -13
- package/docs/get-started/an-agent-in-a-sandbox.md +43 -34
- package/docs/get-started/connect-a-model.md +1 -1
- package/docs/get-started/create-an-instance.md +17 -14
- package/docs/guides/add-tools-to-the-sandbox.md +55 -11
- 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 +24 -8
- 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/fix-a-failed-converge.md +18 -6
- 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 +9 -6
- package/docs/guides/look-inside-a-sandbox.md +101 -31
- package/docs/guides/open-the-console.md +63 -14
- package/docs/guides/read-a-conversation.md +225 -0
- package/docs/guides/run-a-chart-by-name.md +17 -16
- package/docs/guides/run-one-worker-per-item.md +15 -9
- package/docs/guides/set-an-agents-access-and-dials.md +2 -0
- 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 +1 -1
- package/docs/guides/watch-a-run.md +127 -121
- 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 +17 -7
- package/docs/llms.txt +81 -15
- package/docs/reference/authoring-surface/agent.md +1 -1
- package/docs/reference/authoring-surface/answer.md +1 -1
- package/docs/reference/authoring-surface/arg.md +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/docs/reference/authoring-surface/file.md +1 -1
- 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 +1 -1
- package/docs/reference/authoring-surface/isfailure.md +1 -1
- package/docs/reference/authoring-surface/isready.md +1 -1
- package/docs/reference/authoring-surface/jr2setup.md +13 -3
- package/docs/reference/authoring-surface/mcp.md +107 -0
- package/docs/reference/authoring-surface/open.md +5 -3
- package/docs/reference/authoring-surface/openbody.md +1 -1
- package/docs/reference/authoring-surface/paramsof.md +1 -1
- package/docs/reference/authoring-surface/pool.md +77 -9
- package/docs/reference/authoring-surface/push.md +1 -1
- package/docs/reference/authoring-surface/readyof.md +1 -1
- package/docs/reference/authoring-surface/reread.md +19 -0
- package/docs/reference/authoring-surface/secret.md +1 -1
- 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 +56 -1
- 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 +14 -1
- package/docs/reference/authoring-surface/type-agentmcpserver.md +54 -0
- package/docs/reference/authoring-surface/type-anyframepath.md +1 -1
- package/docs/reference/authoring-surface/type-anyworktreepath.md +1 -1
- package/docs/reference/authoring-surface/type-binding.md +1 -1
- 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-commandoutput.md +1 -1
- package/docs/reference/authoring-surface/type-customize.md +16 -1
- 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 +1 -1
- package/docs/reference/authoring-surface/type-effectbinding.md +12 -2
- package/docs/reference/authoring-surface/type-framepath.md +1 -1
- 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 +1 -1
- package/docs/reference/authoring-surface/type-httpoutput.md +1 -1
- package/docs/reference/authoring-surface/type-jr2config.md +37 -2
- package/docs/reference/authoring-surface/type-lateroutcome.md +1 -1
- 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-openbodydeclaration.md +1 -1
- package/docs/reference/authoring-surface/type-openbodyoutput.md +1 -1
- package/docs/reference/authoring-surface/type-poolnextinput.md +1 -1
- package/docs/reference/authoring-surface/type-poolspec.md +11 -6
- package/docs/reference/authoring-surface/type-pushoutput.md +1 -1
- 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 +1 -1
- 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-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-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 +16 -7
- 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 +1 -1
- package/docs/reference/authoring-surface/type-worktreefound.md +3 -3
- package/docs/reference/authoring-surface/type-worktreeinput.md +1 -1
- package/docs/reference/authoring-surface/type-worktreeoptions.md +1 -1
- package/docs/reference/authoring-surface/type-worktreeoutput.md +1 -1
- package/docs/reference/authoring-surface/type-worktreepath.md +1 -1
- package/docs/reference/authoring-surface/type-worktreeready.md +1 -1
- package/docs/reference/authoring-surface/type-worktreerefused.md +4 -4
- package/docs/reference/authoring-surface/workspace.md +1 -1
- package/docs/reference/authoring-surface/worktree.md +1 -1
- package/docs/reference/authoring-surface.md +88 -167
- package/docs/reference/cli.md +413 -74
- package/docs/reference/config.md +235 -2
- package/docs/reference/decisions/0002-duplex-streaming-actor.md +71 -11
- package/docs/reference/decisions/0005-sandbox-pod-composition.md +14 -10
- package/docs/reference/decisions/0006-agent-control-surface.md +4 -4
- 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 +9 -2
- package/docs/reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md +20 -14
- 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 +18 -14
- package/docs/reference/decisions/0017-pool-over-a-source-port.md +226 -12
- 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 +32 -18
- package/docs/reference/decisions/0021-workspace-continuity-is-a-lease-that-answers-back.md +14 -1
- 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 +116 -34
- package/docs/reference/decisions/0024-an-agents-turn-ends-with-the-state-that-asked-for-it.md +38 -37
- 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 +7 -6
- package/docs/reference/decisions/0028-what-an-agent-may-do-to-the-workspace-is-part-of-its-definition.md +23 -7
- 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 -18
- 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 +4 -3
- 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 +5 -4
- package/docs/reference/decisions/0049-a-machine-carries-its-parts-and-composes-by-invoke.md +19 -19
- package/docs/reference/decisions/0050-what-code-names-config-declares-what-the-cli-names-discovery-finds.md +6 -1
- 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 +7 -0
- package/docs/reference/decisions/0058-a-harness-answers-the-orchestrator-alone.md +13 -7
- package/docs/reference/decisions/0059-a-harness-holds-stand-ins-and-the-custodian-holds-the-keys.md +38 -30
- package/docs/reference/decisions/0062-jr2-briefs-the-agent-on-its-seat-never-on-its-task.md +64 -17
- package/docs/reference/decisions/0063-the-orchestrator-watches-the-cluster.md +2 -1
- 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 +51 -23
- package/docs/reference/decisions/0067-an-effect-is-an-actor-slot-and-runs-at-most-once-unless-marked-idempotent.md +94 -54
- package/docs/reference/decisions/0068-an-effector-holds-an-effects-secrets-and-signs-its-wire.md +101 -47
- 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 +17 -13
- 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/0075-a-machine-cuts-a-worktree-and-the-workspace-only-clones.md +4 -3
- package/docs/reference/decisions/0076-an-agents-control-credential-lives-only-where-no-workspace-code-runs.md +37 -10
- 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 +6 -4
- package/docs/reference/glossary.md +96 -42
- package/docs/reference/hooks.md +1077 -0
- package/docs/reference/http-api.md +976 -149
- package/docs/why.md +2 -1
- package/package.json +10 -3
- package/src/actor.ts +36 -10
- package/src/agent.ts +50 -0
- package/src/assembly-checks.ts +530 -4
- package/src/callers.ts +245 -0
- package/src/chart.ts +52 -7
- package/src/config.ts +550 -1
- package/src/conversations.ts +453 -0
- package/src/custodian.ts +8 -2
- package/src/customize.ts +143 -4
- package/src/dispatch-effect.ts +142 -26
- package/src/durability.ts +2 -0
- package/src/duration.ts +20 -0
- package/src/effect-checks.ts +2 -1
- package/src/effect.ts +60 -7
- package/src/effector-wire.ts +272 -27
- package/src/gate-brand.ts +16 -0
- package/src/gate.ts +634 -48
- package/src/harness-client.ts +10 -4
- package/src/held-secrets.ts +72 -23
- package/src/holds.ts +2 -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 +76 -38
- package/src/http.ts +889 -94
- package/src/index.ts +16 -5
- package/src/instance.ts +196 -26
- package/src/internal.ts +22 -3
- package/src/machine-doc.ts +26 -1
- package/src/mcp-effect.ts +424 -0
- package/src/mount-digest.ts +41 -7
- package/src/names.ts +64 -2
- package/src/notices.ts +138 -10
- package/src/open-body.ts +25 -11
- package/src/open-effect.ts +17 -4
- package/src/open.ts +4 -2
- package/src/parts.ts +87 -9
- package/src/party.ts +2 -1
- package/src/pick.ts +2 -2
- package/src/pool.ts +1142 -163
- package/src/registration.ts +203 -13
- package/src/run-host.ts +1509 -171
- package/src/run-list.ts +191 -0
- package/src/sandbox-kube.ts +53 -5
- package/src/secret-placement.ts +239 -33
- package/src/server.ts +53 -4
- package/src/setup.ts +72 -32
- package/src/snapshot-store.ts +565 -48
- package/src/steer.ts +111 -0
- package/src/stub-harness.ts +6 -2
- package/src/tokens.ts +263 -22
- package/src/wire.ts +17 -0
- package/src/workspace.ts +50 -6
- package/src/worktree.ts +3 -3
- 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
|
@@ -84,7 +84,7 @@ jr2 run release --input '{"version":"1.4.0"}'
|
|
|
84
84
|
|
|
85
85
|
```text
|
|
86
86
|
→ context <context> / namespace <namespace>
|
|
87
|
-
run
|
|
87
|
+
run 0c948d65-fd6f-453a-87fa-71ec00c7fe68 (release) — attached
|
|
88
88
|
→ active "review"
|
|
89
89
|
```
|
|
90
90
|
|
|
@@ -96,12 +96,13 @@ next steps in a second terminal. [Start a run](start-a-run.md) gives the other w
|
|
|
96
96
|
Run [`jr2 status`](../reference/cli.md#status) with the run id:
|
|
97
97
|
|
|
98
98
|
```sh
|
|
99
|
-
jr2 status
|
|
99
|
+
jr2 status 0c94
|
|
100
100
|
```
|
|
101
101
|
|
|
102
102
|
```text
|
|
103
103
|
→ context <context> / namespace <namespace>
|
|
104
|
-
{"runId":"
|
|
104
|
+
{"runId":"0c948d65-fd6f-453a-87fa-71ec00c7fe68","workflow":"release","instanceId":"6db54032-0b87-4005-9583-049f7335b75f","startedAt":"2026-11-06T19:15:39.018Z","startedBy":{"kind":"caller","via":"token","name":"instance","onBehalfOf":"kubernetes-admin"},"status":"active","value":"review","context":{"version":"1.4.0"},"children":[],"waiting":[],"held":[],"assembly":"19d0bf0cbe10","gates":[{"gate":"review","path":["review"],"accepts":[{"name":"approve","description":"Release this version.","input":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false}},{"name":"reject","description":"Do not release this version. Say why.","input":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"reason":{"type":"string","minLength":1}},"required":["reason"],"additionalProperties":false}}],"acceptsNow":["approve","reject"],"meta":{"version":"1.4.0"}}]}
|
|
105
|
+
started by: token/instance on behalf of kubernetes-admin
|
|
105
106
|
```
|
|
106
107
|
|
|
107
108
|
`gates` holds each open Gate of the run, as a [`GateView`](../reference/http-api.md#type-gateview):
|
|
@@ -114,18 +115,37 @@ jr2 status 2319
|
|
|
114
115
|
|
|
115
116
|
A run that has no open Gate has `"gates":[]`.
|
|
116
117
|
|
|
118
|
+
To find the open Gates of all the live runs, run [`jr2 gates`](../reference/cli.md#gates). It prints the Gates that you
|
|
119
|
+
can answer, the oldest first. Give `--workflow <name>` to see only the Gates of the runs of one Workflow:
|
|
120
|
+
|
|
121
|
+
```sh
|
|
122
|
+
jr2 gates --workflow release
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
→ context <context> / namespace <namespace>
|
|
127
|
+
[{"runId":"0c948d65-fd6f-453a-87fa-71ec00c7fe68","workflow":"release","gate":"review","path":["review"],"accepts":[{"name":"approve","description":"Release this version.","input":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{},"additionalProperties":false}},{"name":"reject","description":"Do not release this version. Say why.","input":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"reason":{"type":"string","minLength":1}},"required":["reason"],"additionalProperties":false}}],"acceptsNow":["approve","reject"],"meta":{"version":"1.4.0"},"openedAt":"2026-11-06T19:15:39.019Z"}]
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
Each entry has the fields of a Gate in `gates`, and also `runId`, `workflow` and `openedAt`, the time when the Gate
|
|
131
|
+
opened. When the Gate hears a [Hook](../reference/glossary.md#hook), `hook` gives the
|
|
132
|
+
[Hook kinds](../reference/glossary.md#hook-kind). An entry never holds the `context` of the run. A Gate that takes no
|
|
133
|
+
event from a [Caller](../reference/glossary.md#caller), such as the `source` Gate of a
|
|
134
|
+
[Pool](../reference/glossary.md#pool) that hears only Hooks, is not in the list. `jr2 gates` reads
|
|
135
|
+
[`GET /gates`](../reference/http-api.md#get-gates), and it needs the `answer` scope.
|
|
136
|
+
|
|
117
137
|
## Answer from the CLI
|
|
118
138
|
|
|
119
139
|
Run [`jr2 send`](../reference/cli.md#send). Give the Gate in `--gate`, the event in `--event`, and the input of the
|
|
120
140
|
event as a JSON object in `--input`:
|
|
121
141
|
|
|
122
142
|
```sh
|
|
123
|
-
jr2 send
|
|
143
|
+
jr2 send 0c94 --gate review --event reject --input '{"reason":"The changelog is not ready."}'
|
|
124
144
|
```
|
|
125
145
|
|
|
126
146
|
```text
|
|
127
147
|
→ context <context> / namespace <namespace>
|
|
128
|
-
delivered reject to gate "review" on
|
|
148
|
+
delivered reject to gate "review" on 0c948d65-fd6f-453a-87fa-71ec00c7fe68
|
|
129
149
|
```
|
|
130
150
|
|
|
131
151
|
`jr2 send` prints `delivered` only when the run took the event. In the first terminal, the run ends. A `reject` ends the
|
|
@@ -136,7 +156,7 @@ ends `failed`. Its output is the [Failure](../reference/glossary.md#failure), an
|
|
|
136
156
|
→ active "rejected"
|
|
137
157
|
→ failed "rejected"
|
|
138
158
|
failed: The changelog is not ready.
|
|
139
|
-
{"runId":"
|
|
159
|
+
{"runId":"0c948d65-fd6f-453a-87fa-71ec00c7fe68","workflow":"release","instanceId":"6db54032-0b87-4005-9583-049f7335b75f","startedAt":"2026-11-06T19:15:39.018Z","startedBy":{"kind":"caller","via":"token","name":"instance","onBehalfOf":"kubernetes-admin"},"status":"failed","value":"rejected","context":{"version":"1.4.0","reason":"The changelog is not ready."},"children":[],"waiting":[],"held":[],"answers":[{"gate":"review","type":"reject","at":"2026-11-06T19:15:52.901Z","answeredBy":{"via":"token","name":"instance","onBehalfOf":"kubernetes-admin"}}],"assembly":"19d0bf0cbe10","output":{"reason":"The changelog is not ready."}}
|
|
140
160
|
```
|
|
141
161
|
|
|
142
162
|
The run ended, so its Gate closed. Each example below answers a run that waits. Before each example, start a new run in
|
|
@@ -154,24 +174,25 @@ jr2 send <run id> --gate review --event approve
|
|
|
154
174
|
|
|
155
175
|
```text
|
|
156
176
|
→ context <context> / namespace <namespace>
|
|
157
|
-
delivered approve to gate "review" on
|
|
177
|
+
delivered approve to gate "review" on 342fef91-53a1-4640-87bf-6fb4395beebf
|
|
158
178
|
```
|
|
159
179
|
|
|
160
180
|
`jr2 send` prints the full run id, also when you give a prefix.
|
|
161
181
|
|
|
162
182
|
## Answer from the Console
|
|
163
183
|
|
|
164
|
-
You need
|
|
165
|
-
|
|
184
|
+
You need a credential with the `answer` scope for the Workflow, such as the Instance token, to answer a Gate from the
|
|
185
|
+
Console. [Open the Console](open-the-console.md) tells how to open it, how to get the token and how to log in.
|
|
166
186
|
|
|
167
187
|
1. Open the Console.
|
|
168
|
-
2. Type the
|
|
188
|
+
2. Type the token in the `Caller token` box in the nav, or click `log in`.
|
|
169
189
|
3. Push Enter. The badge beside the box shows `…`, then `live`.
|
|
170
190
|
4. Click the `Attention` tab in the drawer on the right. It shows a card for each open Gate of the Workflow that you
|
|
171
|
-
selected. To see the Gates of all the Workflows, select
|
|
172
|
-
all.
|
|
173
|
-
|
|
174
|
-
|
|
191
|
+
selected and that your credential can answer, the oldest first. To see the Gates of all the Workflows, select
|
|
192
|
+
`all workflows`. When you select no Workflow, it shows them all. The Console reads the cards from
|
|
193
|
+
[`GET /gates`](../reference/http-api.md#get-gates).
|
|
194
|
+
5. Find the card. Its top line shows `⚑` and the id of the Gate at the left. At the right, it shows the Workflow, the
|
|
195
|
+
first 8 characters of the run id and `open since <time>`. Below it, the card shows the `meta` of the Gate.
|
|
175
196
|
6. The card has a form for each event that the Gate accepts. Fill in the form of the event that you send. A field that
|
|
176
197
|
has `*` after its name is necessary.
|
|
177
198
|
7. Click `send` in that form.
|
|
@@ -184,9 +205,13 @@ The `⚑` badge in the nav gives the number of open Gates in all the Workflows.
|
|
|
184
205
|
## Answer from a webhook or CI
|
|
185
206
|
|
|
186
207
|
A webhook handler or a CI job answers a Gate with
|
|
187
|
-
[`POST /runs/:runId/gates/:gate/events`](../reference/http-api.md#post-runs-runid-gates-gate-events) and the
|
|
188
|
-
|
|
189
|
-
|
|
208
|
+
[`POST /runs/:runId/gates/:gate/events`](../reference/http-api.md#post-runs-runid-gates-gate-events) and the token of a
|
|
209
|
+
named Caller with the `answer` scope for the Workflow. A CI job has no access to the cluster, so it cannot read the
|
|
210
|
+
Instance token, and it must not have it: the Instance token can do everything.
|
|
211
|
+
[Give a Caller a scope](give-a-caller-a-scope.md) makes the Caller token. A service that a Hook kind covers, such as a
|
|
212
|
+
forge, sends its webhook to a Hook: see [Answer a Gate from a forge](answer-a-gate-from-a-forge.md). Any other handler
|
|
213
|
+
or CI job uses the Gate route. It reads its own event, finds the run and the Gate, and sends the call. The body is the
|
|
214
|
+
event: `type` is the name of the event, and the other properties are its input.
|
|
190
215
|
|
|
191
216
|
`jr2 up` makes the Service `jr2-orchestrator` on port 4000, with no address outside the cluster. Thus a caller outside
|
|
192
217
|
the cluster uses a port forward, or an address that you make for the Service.
|
|
@@ -197,7 +222,8 @@ In a new terminal, forward a port to the Orchestrator. Keep this command open:
|
|
|
197
222
|
kubectl -n <namespace> port-forward svc/jr2-orchestrator 4000:4000
|
|
198
223
|
```
|
|
199
224
|
|
|
200
|
-
In a different terminal,
|
|
225
|
+
In a different terminal, put a token into a variable. A CI job uses its Caller token. To try the route from your own
|
|
226
|
+
terminal, you can use the Instance token:
|
|
201
227
|
|
|
202
228
|
```sh
|
|
203
229
|
TOKEN=$(kubectl -n <namespace> get secret jr2-instance -o jsonpath='{.data.JR2_INSTANCE_TOKEN}' | base64 -d)
|
|
@@ -217,9 +243,9 @@ curl -s -X POST http://localhost:4000/runs/<run id>/gates/review/events \
|
|
|
217
243
|
```
|
|
218
244
|
|
|
219
245
|
A webhook handler often knows a fact, such as a version, but not the run id. It can find the run from the `meta` of the
|
|
220
|
-
Gate. [`GET /
|
|
221
|
-
|
|
222
|
-
|
|
246
|
+
Gate. [`GET /gates`](../reference/http-api.md#get-gates) gives the open Gates of all the live runs that the token can
|
|
247
|
+
answer, each with its run id and its `meta`. It needs only the `answer` scope. This script approves the `release` run
|
|
248
|
+
that waits for one version. It needs `curl` and `jq`. Save it as `approve-release.sh`:
|
|
223
249
|
|
|
224
250
|
```sh
|
|
225
251
|
#!/bin/sh
|
|
@@ -229,15 +255,13 @@ set -eu
|
|
|
229
255
|
|
|
230
256
|
auth="Authorization: Bearer $JR2_TOKEN"
|
|
231
257
|
|
|
232
|
-
# The
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
echo
|
|
240
|
-
fi
|
|
258
|
+
# The open Gates of the live release runs that this token can answer, with their meta.
|
|
259
|
+
runs=$(curl -fsS -H "$auth" "$JR2_URL/gates?workflow=release" |
|
|
260
|
+
jq -r --arg v "$VERSION" '.gates[] | select(.gate == "review" and .meta.version == $v) | .runId')
|
|
261
|
+
for run in $runs; do
|
|
262
|
+
curl -fsS -X POST -H "$auth" -H "Content-Type: application/json" \
|
|
263
|
+
-d '{"type":"approve"}' "$JR2_URL/runs/$run/gates/review/events"
|
|
264
|
+
echo
|
|
241
265
|
done
|
|
242
266
|
```
|
|
243
267
|
|
|
@@ -258,15 +282,15 @@ JR2_URL=http://localhost:4000 JR2_TOKEN=$TOKEN jr2 send <run id> --gate review -
|
|
|
258
282
|
|
|
259
283
|
```text
|
|
260
284
|
→ http://localhost:4000
|
|
261
|
-
delivered approve to gate "review" on
|
|
285
|
+
delivered approve to gate "review" on cad78069-0d8d-4c04-9cf4-3f771693274f
|
|
262
286
|
```
|
|
263
287
|
|
|
264
288
|
## Rules
|
|
265
289
|
|
|
266
290
|
- The Orchestrator refuses a Gate that is not open on the run, with the status code `404`:
|
|
267
291
|
`no open gate "<gate>" on run "<run id>" (open: <gates>)`. The part `(open: <gates>)` shows only when the run has an
|
|
268
|
-
open Gate. When an event takes the run out of the state of the Gate, the Gate closes. Thus
|
|
269
|
-
refusal.
|
|
292
|
+
open Gate that the Caller can answer. When an event takes the run out of the state of the Gate, the Gate closes. Thus
|
|
293
|
+
a second answer gets this refusal.
|
|
270
294
|
- The Orchestrator refuses an event that the Gate does not accept, with the status code `400`:
|
|
271
295
|
`"<gate>" does not accept "<event>" (accepts: <events>)`
|
|
272
296
|
- The Orchestrator refuses an input that does not agree with the schema of the event, with the status code `400`:
|
|
@@ -278,10 +302,23 @@ delivered approve to gate "review" on c44c6e49-452d-4150-8ce4-4d036363d2a0
|
|
|
278
302
|
`event body must carry a string "type" (one of the gate's accepted names)`
|
|
279
303
|
- The Orchestrator refuses a body that holds `sender`, with the status code `400`:
|
|
280
304
|
`` `sender` is written by the Orchestrator on every delivered event; a caller cannot send it ``
|
|
281
|
-
- The Orchestrator refuses an event
|
|
305
|
+
- The Orchestrator refuses an event with no valid credential, with the status code `401`: `unauthorized`. A credential
|
|
306
|
+
is the Instance token, or that of a [Caller](../reference/glossary.md#caller) with the `answer` scope.
|
|
307
|
+
[Give a Caller a scope](give-a-caller-a-scope.md) makes one.
|
|
282
308
|
- The Orchestrator refuses an event with the token of a [Sandbox](../reference/glossary.md#sandbox), with the status
|
|
283
|
-
code `403`:
|
|
284
|
-
|
|
309
|
+
code `403`:
|
|
310
|
+
`this route needs a Caller, and a Sandbox token is not one: no Agent reaches run state, run control or a Gate`. Thus
|
|
311
|
+
an Agent cannot answer a Gate.
|
|
312
|
+
- The Orchestrator refuses an event from a Caller that has the `answer` scope for no Workflow, with the status code
|
|
313
|
+
`403`, before it reads the run: `the Caller <via>/<name> has no "answer" scope for any Workflow (ADR-0078)`. The body
|
|
314
|
+
also holds `scope`.
|
|
315
|
+
- The Orchestrator refuses an event from a Caller that does not have the `answer` scope for the Workflow of the run,
|
|
316
|
+
with the status code `403`: `the Caller <via>/<name> needs the "answer" scope for Workflow "<workflow>" (ADR-0078)`
|
|
317
|
+
- The Orchestrator refuses an event to an open Gate from a Caller whose `answer` scope names other Gates of the
|
|
318
|
+
Workflow, with the status code `403`:
|
|
319
|
+
`the Caller <via>/<name> needs the "answer" scope for Gate "<name>" of Workflow "<workflow>" (ADR-0078)`. `<name>` is
|
|
320
|
+
the name of the Gate, its invoke id. The body also holds `scope`, `workflow` and `gate`.
|
|
321
|
+
[Give a Caller a scope](give-a-caller-a-scope.md) tells how a scope names single Gates.
|
|
285
322
|
- `jr2 send` prints each refusal of the Orchestrator as `error: <refusal>`, and exits with `1`. After a `404` refusal,
|
|
286
323
|
it also prints the version of the Instance in one more line:
|
|
287
324
|
``instance: <version> (<hash>) — if it predates this CLI, `jr2 up` converges the cluster to this kit``. `<hash>` is
|
|
@@ -298,7 +335,7 @@ delivered approve to gate "review" on c44c6e49-452d-4150-8ce4-4d036363d2a0
|
|
|
298
335
|
- [ADR-0011](../reference/decisions/0011-workflow-defined-events.md): a Gate, its events, and its `meta`.
|
|
299
336
|
- [ADR-0013](../reference/decisions/0013-the-agent-reaches-its-machine-through-a-container-it-cannot-read.md): why an
|
|
300
337
|
Agent cannot answer a Gate, and why a refused event is not delivered.
|
|
301
|
-
- [ADR-0032](../reference/decisions/0032-the-console-unlocks-with-
|
|
338
|
+
- [ADR-0032](../reference/decisions/0032-the-console-unlocks-with-a-callers-credential.md): a Caller's credential in the
|
|
302
339
|
Console.
|
|
303
340
|
- [Start a run](start-a-run.md)
|
|
304
341
|
- [Watch a run](watch-a-run.md)
|
|
@@ -137,7 +137,9 @@ others. A Machine that names its slots, such as `repos: { app: open }`, takes on
|
|
|
137
137
|
|
|
138
138
|
`agents` takes the fields of the definition of an Agent, by slot. Each field goes over the field that the author wrote.
|
|
139
139
|
Thus `{ model }` changes only the model, and the coder keeps the instructions of `task`. You can also change other
|
|
140
|
-
fields, such as `thinkingLevel` or `instructions`.
|
|
140
|
+
fields, such as `thinkingLevel` or `instructions`. `{ mcp }` replaces the whole list of the MCP servers of the Agent.
|
|
141
|
+
`jr2 up` refuses a server name that the `mcp` block of `jr2.config.ts` does not declare, and prints the line with `mcp`
|
|
142
|
+
(see [Give an Agent MCP tools](give-an-agent-mcp-tools.md#bind-the-servers-of-a-packaged-machine)).
|
|
141
143
|
[`AgentDefinition`](../reference/authoring-surface/type-agentdefinition.md) gives the fields.
|
|
142
144
|
|
|
143
145
|
## Bind the parts of a Machine that you compose
|
|
@@ -164,19 +166,29 @@ When `task` is a child of your Machine, give it `branch` in its input. Only the
|
|
|
164
166
|
|
|
165
167
|
## Bind the Open parts of an Effect
|
|
166
168
|
|
|
167
|
-
A packaged Machine can leave the url of an `http` [Effect](../reference/glossary.md#effect), the argv of a `command`,
|
|
168
|
-
the name of a secret Open. Bind them with `effects`, by the slot of the
|
|
169
|
-
`customize(machine, { effects: { notify: { url } } })
|
|
170
|
-
|
|
171
|
-
|
|
169
|
+
A packaged Machine can leave the url of an `http` [Effect](../reference/glossary.md#effect), the argv of a `command`,
|
|
170
|
+
the name of a secret, or the server and the tool of an `mcp` Effect Open. Bind them with `effects`, by the slot of the
|
|
171
|
+
Effect: `customize(machine, { effects: { notify: { url } } })`, or
|
|
172
|
+
`customize(machine, { effects: { post: { server: "slack-acme", tool: "post_message" } } })`. One object binds all the
|
|
173
|
+
Open parts of one Effect. You bind each part one time, to a value. No run chooses it.
|
|
174
|
+
[`EffectBinding`](../reference/authoring-surface/type-effectbinding.md) gives the values, and
|
|
175
|
+
[Run a command or call a URL with an Effect](run-a-command-or-call-a-url.md) shows an Effect. A bound server is a name
|
|
176
|
+
of the `mcp` block. Its secret comes from that block, so an `mcp` Effect has no Open secret.
|
|
177
|
+
|
|
178
|
+
## Bind the look of a Gate
|
|
179
|
+
|
|
180
|
+
A packaged Machine can leave the look of a Gate slot Open: `look: open`. Bind it with `gates`, by the slot of the Gate:
|
|
181
|
+
`customize(machine, { gates: { review: { look } } })`. The same key adds, replaces or removes a handler of the Gate, by
|
|
182
|
+
Hook kind and event key, where `null` removes one. `jr2 up` does not refuse an Open look. It warns, because a person can
|
|
183
|
+
still answer the Gate with `jr2 send`. [Answer a Gate from a forge](answer-a-gate-from-a-forge.md) shows a Gate slot.
|
|
172
184
|
|
|
173
185
|
## Rules
|
|
174
186
|
|
|
175
187
|
- `jr2 up` refuses a registered Machine that leaves a part Open. It changes nothing in the cluster:
|
|
176
188
|
`refusing: workflow "<name>" leaves <part> open — bind it where the Machine is registered: export const machine = customize(<import>, <binding>) (<adr>)`.
|
|
177
189
|
`<part>` is one of `its Repo Slots`, `Repo Slot "<slot>"`, `Agent "<slot>"`, or `the <parts> of Effect "<slot>"`,
|
|
178
|
-
where `<parts>` is such as `url` or `
|
|
179
|
-
comes after `open`.
|
|
190
|
+
where `<parts>` is such as `url`, `url and secret`, `server` or `server and tool`. For a child Machine,
|
|
191
|
+
`(on the Machine composed as "<slot>")` comes after `open`.
|
|
180
192
|
- `jr2 up` refuses an Open part on a Machine that a state writes in its `invoke.src`, because no `customize()` gets to
|
|
181
193
|
it. Put that Machine under `actors`:
|
|
182
194
|
`refusing: workflow "<name>" leaves <part> open on a Machine invoked inline — no customize() reaches an actor without a slot key; declare that Machine under setup({ actors }) and bind it there (ADR-0049, <adr>)`
|
|
@@ -189,6 +201,7 @@ gives the values, and [Run a command or call a URL with an Effect](run-a-command
|
|
|
189
201
|
- `customize(): machine "<id>" composes no Machine under "<slot>" — the Machines it composes are: <slots> (ADR-0049).`
|
|
190
202
|
- `customize(): machine "<id>" declares no Repo Slot "<slot>" — its slots are: <slots> (ADR-0051)`
|
|
191
203
|
- `customize(): machine "<id>" carries no Effect slot "<slot>" — its Effects are: <slots> (ADR-0067). Only declared parts can be bound.`
|
|
204
|
+
- `customize(): machine "<id>" carries no Gate slot "<slot>" — its Gate slots are: <slots> (ADR-0011). Only declared parts can be bound.`
|
|
192
205
|
- `customize()` refuses an Open map that you bind with no slot:
|
|
193
206
|
``customize(): machine "<id>" declares its Repo Slots open as a map — name at least one: `repos: { app: "https://…" }` (ADR-0051).``
|
|
194
207
|
- `customize()` refuses a Repo Slot key that is not a directory name. The key becomes `/work/<slot>`:
|
|
@@ -201,6 +214,9 @@ gives the values, and [Run a command or call a URL with an Effect](run-a-command
|
|
|
201
214
|
- `customize()` refuses `open` or a function as the value of an Effect's part:
|
|
202
215
|
``customize(): the <kind> Effect "<slot>"'s <part> is bound once, to a value — not `open` again: no run chooses an Effect's <part> (ADR-0054)``.
|
|
203
216
|
For a function, the text says `a function of the run` in place of `` `open` again ``.
|
|
217
|
+
- `jr2 up` refuses an Agent that names an MCP server that the `mcp` block does not declare:
|
|
218
|
+
`refusing: workflow "<name>": Agent "<slot>" names the MCP server "<server>", which the mcp block declares "<names>" — bind the Agent to a declared server where the Machine is registered: export const machine = customize(<import>, { agents: { <slot>: { mcp: [<entries>] } } }); or declare it in jr2.config.ts: mcp: { "<server>": { url: "https://<host>/mcp", secret: "<SECRET>" } } (ADR-0079)`.
|
|
219
|
+
For a child Machine, the line names the child, and `customize()` goes through `actors`.
|
|
204
220
|
- An Agent does not start a [Turn](../reference/glossary.md#turn) while its model is Open:
|
|
205
221
|
``agent "<slot>" has an Open model — nobody bound it; bind it where the Machine is registered (`customize(<machine>, { agents: { <slot>: { model: "<provider>/<model>" } } })`), because a packaged Machine cannot pick a model on your behalf (ADR-0054)``.
|
|
206
222
|
`jr2 up` refuses this case first.
|