delegation-layer 0.1.28 → 0.1.29

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.
Files changed (35) hide show
  1. package/README.md +58 -14
  2. package/docs/assets/delegation-layer-hero.jpg +0 -0
  3. package/package.json +3 -2
  4. package/plugins/delegation-layer/.claude-plugin/plugin.json +1 -1
  5. package/plugins/delegation-layer/.codex-plugin/plugin.json +1 -1
  6. package/plugins/delegation-layer/skills/agent-integration/SKILL.md +27 -8
  7. package/plugins/delegation-layer/skills/agent-integration/examples/json-results.md +6 -7
  8. package/plugins/delegation-layer/skills/agent-integration/examples/managed-workspace.md +68 -0
  9. package/plugins/delegation-layer/skills/agent-integration/references/collaboration.md +22 -6
  10. package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +53 -20
  11. package/plugins/delegation-layer/skills/agent-integration/references/continuation.md +36 -0
  12. package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +46 -2
  13. package/plugins/delegation-layer/skills/agent-integration/references/workspaces.md +197 -0
  14. package/scripts/install-agent-integration.mjs +15 -829
  15. package/scripts/install-cli.mjs +26 -66
  16. package/scripts/installer/application.mjs +250 -0
  17. package/scripts/installer/arguments.mjs +123 -0
  18. package/scripts/installer/catalog.mjs +95 -0
  19. package/scripts/installer/detection.mjs +41 -0
  20. package/scripts/installer/filesystem.mjs +97 -0
  21. package/scripts/installer/paths.mjs +14 -0
  22. package/scripts/installer/picker-state.mjs +46 -0
  23. package/scripts/installer/routing-rules.mjs +99 -0
  24. package/scripts/installer/routing-store.mjs +151 -0
  25. package/scripts/installer/selection.mjs +34 -0
  26. package/scripts/installer/skill-store.mjs +33 -0
  27. package/scripts/installer/terminal.mjs +104 -0
  28. package/skills/agent-integration/SKILL.md +27 -8
  29. package/skills/agent-integration/examples/json-results.md +6 -7
  30. package/skills/agent-integration/examples/managed-workspace.md +68 -0
  31. package/skills/agent-integration/references/collaboration.md +22 -6
  32. package/skills/agent-integration/references/command-reference.md +53 -20
  33. package/skills/agent-integration/references/continuation.md +36 -0
  34. package/skills/agent-integration/references/result-handling.md +46 -2
  35. package/skills/agent-integration/references/workspaces.md +197 -0
@@ -5,10 +5,9 @@ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" status "$TASK_ID" --j
5
5
  delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect "$TASK_ID" --watch 5s --json
6
6
  ```
7
7
 
8
- Decision order:
9
-
10
- 1. Save `task_id`.
11
- 2. Check `admission` and `error`.
12
- 3. Wait while publication is pending.
13
- 4. Accept only a committed terminal `outcome`.
14
- 5. If `status` is `timed_out`, follow `continuation.resumable`.
8
+ Apply [result handling](../references/result-handling.md) to each response and
9
+ follow [Observe and collect](../SKILL.md#5-observe-and-collect). Those sections
10
+ own the decision order for task creation, failures, timeout continuation,
11
+ terminal outcomes, pending interaction, and bounded collection. Read them
12
+ before interpreting these commands; pending publication alone is not a reason
13
+ to wait when the task needs an answer or timeout recovery.
@@ -0,0 +1,68 @@
1
+ # Managed workspace example
2
+
3
+ Use this example for independent write work that should be isolated in a
4
+ retained Git worktree. The source must be a Git checkout and the state root
5
+ must remain outside provider-writable workspaces.
6
+
7
+ ```sh
8
+ SOURCE="$PWD"
9
+ BRIEF="$(mktemp)"
10
+ RESPONSE="$(mktemp)"
11
+ printf '%s\n' 'Implement the requested change and report the files changed.' >"$BRIEF"
12
+
13
+ if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --auto \
14
+ --brief "$BRIEF" --cwd "$SOURCE" \
15
+ --permission workspace-write --isolation git-worktree \
16
+ --base HEAD --workspace-budget 5m --budget 30m --json >"$RESPONSE"; then
17
+ dispatch_exit=0
18
+ else
19
+ dispatch_exit=$?
20
+ fi
21
+ printf '%s\n' "$dispatch_exit" >"$RESPONSE.exit"
22
+ cat "$RESPONSE"
23
+ ```
24
+
25
+ Read the saved JSON before running another command. When
26
+ `task_record: "created"`, use its `task_id` as `TASK_ID` below. When no task
27
+ was created, follow the [result decisions](../references/result-handling.md#managed-workspace-results);
28
+ do not run task status or collection against that nonexistent record.
29
+
30
+ ```sh
31
+ if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" status TASK_ID --json >"$RESPONSE.status"; then
32
+ status_exit=0
33
+ else
34
+ status_exit=$?
35
+ fi
36
+ printf '%s\n' "$status_exit" >"$RESPONSE.status.exit"
37
+ if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect TASK_ID --watch 5s --json >"$RESPONSE.collect"; then
38
+ collect_exit=0
39
+ else
40
+ collect_exit=$?
41
+ fi
42
+ printf '%s\n' "$collect_exit" >"$RESPONSE.collect.exit"
43
+ ```
44
+
45
+ Continue observing that created task when collection exits `3`. Wait for the
46
+ workspace to return to `state: retained` and inspect its final capture. Only
47
+ after the Lead explicitly chooses release, run:
48
+
49
+ ```sh
50
+ if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" workspace release WORKSPACE_ID \
51
+ --budget 5m --json >"$RESPONSE.release"; then
52
+ release_exit=0
53
+ else
54
+ release_exit=$?
55
+ fi
56
+ printf '%s\n' "$release_exit" >"$RESPONSE.release.exit"
57
+ ```
58
+
59
+ Read the release acknowledgement. `watch_workspace` means observe this
60
+ accepted release; a `retry_release` acknowledgement means it was not accepted.
61
+ Follow the same result decisions rather than assuming either response is
62
+ completed cleanup.
63
+
64
+ Save each response and exit code once. A created task is observed with
65
+ `status` first and collected in the foreground. Exit `3` means pending, not
66
+ success; continue observing the same task. The Lead reviews the capture and
67
+ owns landing any changes. `workspace release` is explicit; no automatic
68
+ apply, commit, branch merge, TTL eviction, or provider-CLI fallback occurs.
@@ -1,5 +1,13 @@
1
1
  # Parallel reviews and debates
2
2
 
3
+ For independent parallel write work, choose `--isolation git-worktree`
4
+ automatically unless the user explicitly chooses shared coordination. The
5
+ model chooses fan-out and task scope; the supervisor has no fixed task-count
6
+ cap or TTL eviction. A read-only review may attach a retained workspace with
7
+ `--workspace ID`. The single managed-workspace policy, capture boundary, and
8
+ release rules live in [managed workspace guidance](workspaces.md); do not
9
+ restate them in each collaboration brief.
10
+
3
11
  ## Keep each request identifiable
4
12
 
5
13
  Choose the fan-out needed for the user's task. Each participant needs its own
@@ -19,18 +27,26 @@ RECEIPTS="$(mktemp -d)" || exit 1
19
27
  # Set these absolute paths and catalog IDs in this same tool invocation.
20
28
  # BRIEF_A and BRIEF_B contain the real independent assignments.
21
29
  (
22
- delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --provider "$PROVIDER_A" \
30
+ if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --provider "$PROVIDER_A" \
23
31
  --brief "$BRIEF_A" --cwd "$WORKSPACE_A" \
24
32
  --permission read-only --budget 30m --json \
25
- >"$RECEIPTS/review-a.json" 2>"$RECEIPTS/review-a.stderr"
26
- printf '%s\n' "$?" >"$RECEIPTS/review-a.exit"
33
+ >"$RECEIPTS/review-a.json" 2>"$RECEIPTS/review-a.stderr"; then
34
+ dispatch_exit=0
35
+ else
36
+ dispatch_exit=$?
37
+ fi
38
+ printf '%s\n' "$dispatch_exit" >"$RECEIPTS/review-a.exit"
27
39
  ) &
28
40
  (
29
- delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --provider "$PROVIDER_B" \
41
+ if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --provider "$PROVIDER_B" \
30
42
  --brief "$BRIEF_B" --cwd "$WORKSPACE_B" \
31
43
  --permission read-only --budget 30m --json \
32
- >"$RECEIPTS/review-b.json" 2>"$RECEIPTS/review-b.stderr"
33
- printf '%s\n' "$?" >"$RECEIPTS/review-b.exit"
44
+ >"$RECEIPTS/review-b.json" 2>"$RECEIPTS/review-b.stderr"; then
45
+ dispatch_exit=0
46
+ else
47
+ dispatch_exit=$?
48
+ fi
49
+ printf '%s\n' "$dispatch_exit" >"$RECEIPTS/review-b.exit"
34
50
  ) &
35
51
  wait
36
52
  printf 'Read each response separately in %s\n' "$RECEIPTS"
@@ -5,28 +5,30 @@ All paths passed to `--root`, `--cwd`, and `--brief` must be absolute. Add
5
5
 
6
6
  Pass the intended workspace directly. Delegate handles provider launch options;
7
7
  do not initialize Git, change trust settings, or call a provider CLI as a
8
- workspace workaround. Ordinary Codex tasks support non-Git directories;
9
- Git-targeted native review requires a suitable repository.
8
+ workspace workaround. Ordinary tasks support non-Git directories. Git is
9
+ required for managed worktree creation/attachment only; native review retains
10
+ its separate explicit review-target contract. See [managed workspace guidance](workspaces.md)
11
+ for the policy owner.
10
12
 
11
13
  | Command | Purpose | Launches provider work? |
12
14
  | --- | --- | --- |
13
15
  | `delegate --version` | Confirm the installed control CLI | No |
14
- | `delegate providers --json` | List compiled provider metadata | No |
15
- | `delegate capabilities --provider ID --json` | Read the catalog contract | No |
16
- | `delegate models --provider ID [--cwd ABS] --json` | Discover advisory native model and effort facts | Native inspection only; no admitted task |
17
- | `delegate preflight --provider ID --cwd ABS --json` | Check static provider admission | No |
18
- | `delegate dispatch --auto ... --json` | Select and admit one bounded turn | Yes, at most once |
19
- | `delegate status TASK --json` | Reconcile and observe task state | No provider launch |
20
- | `delegate collect TASK --watch 5s --json` | Read or wait for publication | No provider launch |
21
- | `delegate recheck TASK --json` | Reassess eligible rejected evidence offline | No provider launch; original outcome unchanged |
22
- | `delegate continue --task TASK ... --json` | Create an exact-session successor | Yes, at most once for the successor |
23
- | `delegate reply TASK --request ID --answers FILE --id MESSAGE_ID --json` | Answer a pending native question | No new launch |
24
- | `delegate steer TASK --brief FILE --id MESSAGE_ID --json` | Guide a supported active turn | No new launch |
25
- | `delegate events TASK --after SEQUENCE --watch 5s --json` | Read a bounded interaction event page | No |
26
- | `delegate logs TASK --json` | Return validated output descriptors | No |
27
- | `delegate cancel TASK --json` | Record one explicit stop request | Stops, does not relaunch |
28
-
29
- `delegate supervisor migrate --json` is the single command-neutral recovery
16
+ | `delegate --root ROOT providers --json` | List compiled provider metadata | No |
17
+ | `delegate --root ROOT capabilities --provider ID --json` | Read the catalog contract | No |
18
+ | `delegate --root ROOT models --provider ID [--cwd ABS] --json` | Discover advisory native model and effort facts | Native inspection only; no admitted task |
19
+ | `delegate --root ROOT preflight --provider ID --cwd ABS --json` | Check static provider admission | No |
20
+ | `delegate --root ROOT dispatch --auto ... --json` | Select and admit one bounded turn | Yes, at most once |
21
+ | `delegate --root ROOT status TASK --json` | Reconcile and observe task state | No provider launch |
22
+ | `delegate --root ROOT collect TASK --watch 5s --json` | Read or wait for publication | No provider launch |
23
+ | `delegate --root ROOT recheck TASK --json` | Reassess eligible rejected evidence offline | No provider launch; original outcome unchanged |
24
+ | `delegate --root ROOT continue --task TASK ... --json` | Create an exact-session successor | Yes, at most once for the successor |
25
+ | `delegate --root ROOT reply TASK --request ID --answers FILE --id MESSAGE_ID --json` | Answer a pending native question | No new launch |
26
+ | `delegate --root ROOT steer TASK --brief FILE --id MESSAGE_ID --json` | Guide a supported active turn | No new launch |
27
+ | `delegate --root ROOT events TASK --after SEQUENCE --watch 5s --json` | Read a bounded interaction event page | No |
28
+ | `delegate --root ROOT logs TASK --json` | Return validated output descriptors | No |
29
+ | `delegate --root ROOT cancel TASK --json` | Record one explicit stop request | Stops, does not relaunch |
30
+
31
+ `delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" supervisor migrate --json` is the single command-neutral recovery
30
32
  step for a `supervisor_upgrade_required` admission response. Run it once with
31
33
  the failed command's exact root. A successful response names its next action
32
34
  `retry_dispatch`, but the original command and argv remain authoritative:
@@ -55,6 +57,35 @@ Dispatch flags:
55
57
  - `--interactive`: enable advertised native clarification and steering; see [interaction](interaction.md);
56
58
  - `--native-timeout DURATION`: optional provider-native timeout where advertised.
57
59
 
60
+ ## Managed workspace commands
61
+
62
+ Managed workspaces are optional. For independent parallel writes, choose
63
+ `--isolation git-worktree` unless the user explicitly chooses shared
64
+ coordination. The model chooses fan-out and task scope; there is no fixed task
65
+ count cap or TTL eviction. Use the canonical [workspace reference](workspaces.md)
66
+ for retention, capture, release, forgetting, and review-scope rules.
67
+
68
+ The public forms are:
69
+
70
+ ```sh
71
+ delegate --root ROOT dispatch --isolation git-worktree --cwd ABS \
72
+ [--base REV] [--workspace-budget DURATION] ... --json
73
+ delegate --root ROOT dispatch --workspace WORKSPACE_ID ... --json
74
+ delegate --root ROOT workspace list [--after ID] [--limit 1..50] --json
75
+ delegate --root ROOT workspace status ID [--operation OP] [--watch DURATION] --json
76
+ delegate --root ROOT workspace exec ID --budget DURATION -- ARGV...
77
+ delegate --root ROOT workspace release ID [--discard] [--budget DURATION] --json
78
+ delegate --root ROOT workspace forget ID [--budget DURATION] --json
79
+ ```
80
+
81
+ `--workspace` cannot be combined with public `--cwd`, `--base`, or
82
+ `--isolation`. `workspace exec` passes literal argv after `--` and initially
83
+ returns asynchronously; exit `3` means the operation is pending. The helper
84
+ budget defaults to 5m, is persisted/overridable, and does not renew the task
85
+ budget. `continue --task TASK` inherits the predecessor workspace, cwd, and
86
+ session while creating a new task ID. A read-only review may attach a retained
87
+ workspace with `--workspace ID`.
88
+
58
89
  Model discovery uses the same `--provider ID` profiles and accepts an optional
59
90
  absolute `--cwd` (default: current directory). Its JSON has `status` values
60
91
  `available`, `partial`, `blocked`, `unavailable`, or `failed`; exits are `0`,
@@ -77,7 +108,8 @@ is incomplete or does not list them. To resolve a natural-language model name
77
108
  or choose an option the caller left open, use native discovery:
78
109
 
79
110
  ```sh
80
- delegate models --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE --json
111
+ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" models \
112
+ --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE --json
81
113
  ```
82
114
 
83
115
  Omit `--cwd` to use the current directory. Run discovery only when the caller
@@ -111,7 +143,8 @@ Use `preflight` when the caller asks about static readiness, rather than as a
111
143
  required step before every dispatch:
112
144
 
113
145
  ```sh
114
- delegate preflight --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE \
146
+ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" preflight \
147
+ --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE \
115
148
  --permission REQUESTED_MODE --json
116
149
  ```
117
150
 
@@ -40,6 +40,19 @@ but it does not authorize a fresh dispatch. Apply the remaining `task_record`
40
40
  error rules in [result handling](result-handling.md) before retrying or
41
41
  observing.
42
42
 
43
+ When the predecessor is bound to a managed workspace, `continue --task` carries
44
+ the recorded workspace, working directory, provider session, and environment
45
+ to the new task ID. It does not mutate the predecessor's immutable request or
46
+ reservation. A changed provider request is a new turn and must pass the normal
47
+ workspace-use reservation. Read [managed workspace guidance](workspaces.md)
48
+ before attaching another provider, review, or verification operation.
49
+
50
+ If `continue` returns `workspace_busy` with `task_record: "not_created"` and
51
+ `next_action: "watch_workspace"`, observe that workspace with the same root.
52
+ Then retry the exact `continue --task PREDECESSOR_ID` after it becomes retained.
53
+ Keep the original predecessor, brief, and budget; do not replace continuation
54
+ with a fresh dispatch. A created successor is only observed.
55
+
43
56
  `mode` describes the provider contract:
44
57
 
45
58
  - `native` uses the provider’s exact persisted conversation/session ID;
@@ -53,3 +66,26 @@ terminal outcome or a durable Pueue-ended observation backed by a guardian
53
66
  lifetime-termination record with independently proven empty scope for the
54
67
  session handoff; without one of those proofs it refuses continuation. Inspect
55
68
  the predecessor again rather than bypassing that boundary.
69
+
70
+ For a managed workspace timeout, capture is a new finite auxiliary operation
71
+ after canonical closure. The normal path proves the provider scope empty and
72
+ records the managed worker's exact `Wait`; recovery can instead use a validated
73
+ absence disposition or previous-boot termination without inventing a native
74
+ `Wait`. Capture never renews the expired provider deadline or reuses its scope. Closure with an
75
+ unavailable capture can still preserve continuation evidence; it does not
76
+ change the provider outcome.
77
+
78
+
79
+ ## Follow up after normal completion
80
+
81
+ A validated terminal outcome, committed or rejected, can also support a new
82
+ turn when the provider supports continuation, its exact session was recorded,
83
+ and the runner/session reservation has been released. Not every rejection has
84
+ a usable session. A normal completion without a budget stop need not expose
85
+ `continuation.resumable` in `status` or `collect`. Use `continue` with the exact
86
+ predecessor and a finite budget, then apply its task-creation and failure
87
+ response as described in [result handling](result-handling.md).
88
+
89
+ If the response says `stop_and_report`, stop that attempt; do not automatically
90
+ retry it. A caller may make a later request after observing the predecessor.
91
+ Native `codex:review` tasks cannot be continued.
@@ -13,8 +13,11 @@ the same as a successful provider result.
13
13
  `supervisor_control.next_action: "retry_dispatch"`, retry the exact original
14
14
  admission argv once. The retry is command-neutral: `dispatch` remains
15
15
  `dispatch`, and `continue` remains `continue`; never create a fresh dispatch
16
- or call a provider directly to replace a failed continuation. For every
17
- other `not_created` response, do not poll; correct the request only if
16
+ or call a provider directly to replace a failed continuation. Also handle
17
+ `workspace_provision_pending` or `workspace_busy` with `watch_workspace`
18
+ using [managed workspace recovery](#managed-workspace-results) before the
19
+ generic stop rule. For every other `not_created` response, do not poll;
20
+ correct the request only if
18
21
  `failure.next_action` is `correct_request`, otherwise report and stop. When
19
22
  `task_record` is `unknown`, stop and report without polling or retrying.
20
23
  Status and collect can report `admission: "unknown"` alongside valid terminal
@@ -68,6 +71,47 @@ Versions and help are observations, not semantic-version allowlists.
68
71
  Authentication is a separate live gate (`not_run`, `passed`, or `blocked`).
69
72
  Report a blocked prerequisite without inventing a login command or retrying.
70
73
 
74
+ ## Managed workspace results
75
+
76
+ Treat `response.workspace` as a separate resource and Git-content evidence
77
+ projection. It does not replace `outcome`, `publication`, or `continuation`.
78
+ The provider outcome is immutable and the workspace `CaptureReceipt` is a
79
+ separate immutable fact; a failed or unavailable capture must not be reported
80
+ as a provider failure when native closure is already proven.
81
+
82
+ Before a task record exists, a pending workspace provision returns
83
+ `task_record: "not_created"` with
84
+ `failure.code: "workspace_provision_pending"` and
85
+ `failure.next_action: "watch_workspace"`. Run the returned workspace-status
86
+ command with the same root and workspace ID. Once ready, retry the same
87
+ admission with the returned task ID in `--id` and unchanged provider, brief,
88
+ permission, model, effort, and source options. A proven never-launched attempt
89
+ gets a fresh helper deadline; a created task is only observed.
90
+
91
+ An occupied managed workspace can return `workspace_busy` with
92
+ `task_record: "not_created"` and `watch_workspace` before authorizing a task.
93
+ Observe the owning workspace, then retry the exact original admission command.
94
+ For `continue`, keep `continue --task PREDECESSOR_ID`; never replace it with a
95
+ dispatch. These two workspace responses are narrow exceptions to the generic
96
+ stop rule. Do not invent another recovery code or provider retry.
97
+
98
+ Read the acknowledgement before observing or repeating a workspace mutation:
99
+
100
+ | Response | Required action |
101
+ | --- | --- |
102
+ | Exit `3`, reason `requested_action_not_authorized`, next action `retry_exec`, `retry_release`, or `retry_forget` | The requested mutation was not accepted. Observe the workspace without `--operation` until the prior use ends, then retry that exact mutation. `exec` and `release` need `state: retained`; `forget` needs `state: released`. |
103
+ | Exit `3`, next action `watch_workspace` | The action is accepted. Observe the same workspace; add `--operation OP` only when its response supplies `operation_id`. Do not repeat the mutation or invent an operation ID. |
104
+ | A concrete failure or `stop_and_report` | Preserve the response and report it; do not turn it into a pending watch or provider fallback. |
105
+
106
+ Use `workspace status ID [--operation OP] --watch DURATION --json` for these
107
+ observations. An accepted action may not have a helper ID yet. An `exec`
108
+ result of `succeeded` proves the command finished; wait for `state: retained`
109
+ before another use, because recapture must finish too. Verification evidence
110
+ does not replace the provider outcome. Keep the checkout retained until the
111
+ Lead has terminal task/capture evidence and explicitly releases it. Read
112
+ [managed workspace guidance](workspaces.md) for the exact command surface and
113
+ review/capture/forgetting boundaries.
114
+
71
115
  ## Offline recovery
72
116
 
73
117
  When Delegate returns `failure.next_action: "recheck"`, use the same root and
@@ -0,0 +1,197 @@
1
+ # Optional managed Git workspaces
2
+
3
+ Managed workspaces are an optional Delegate feature for tasks that need a
4
+ retained Git worktree. Ordinary delegation, including ordinary work in a
5
+ non-Git directory, is unchanged. Git is required only when a request creates
6
+ or attaches to a managed workspace (`--isolation git-worktree` or
7
+ `--workspace ID`).
8
+
9
+ This reference is self-contained guidance for using managed workspaces.
10
+
11
+ Provider-native permissions still apply inside an isolated checkout. A provider
12
+ may edit files but be unable to stage or commit because linked-worktree Git
13
+ metadata lives outside that checkout. Leave edits uncommitted for capture;
14
+ do not bypass the provider's permissions. When a commit is needed, the Lead can
15
+ explicitly authorize a bounded Git command through `workspace exec`.
16
+
17
+ Delegate owns durable records, process lifetimes, capture, and recovery; use
18
+ the public commands below to observe and manage them.
19
+
20
+ ## Choose the boundary
21
+
22
+ For independent parallel write work, choose `--isolation git-worktree`
23
+ automatically unless the user explicitly chooses shared coordination. The
24
+ model chooses the fan-out and task scope; there is no fixed task-count cap and
25
+ no TTL eviction. Shared coordination means the caller deliberately accepts a
26
+ common checkout and its write conflicts. A separate managed workspace is the
27
+ safer default for independent edits.
28
+
29
+ Automatic provider-agnostic routing still goes through Delegate. A native
30
+ subagent in the current harness remains allowed, and an explicit bypass is
31
+ respected. This workspace feature does not force external routing or replace a
32
+ user's explicit integration choice.
33
+
34
+ The coordinator owns one workspace usage reservation at a time. A provider
35
+ turn, continuation, read-only review, or verification operation waits for the
36
+ canonical native closure and terminal capture of the current owner. A queue
37
+ row ending or a provider outcome alone is not closure evidence.
38
+
39
+ ## Source and checkout
40
+
41
+ Create a managed workspace from a committed source base:
42
+
43
+ ```text
44
+ delegate --root ROOT dispatch --isolation git-worktree --cwd ABS \
45
+ [--base REV] [--workspace-budget DURATION] ... --json
46
+ ```
47
+
48
+ `--base` resolves to a commit; the default is `HEAD`. Dirty and untracked
49
+ source changes are observed but excluded from the managed checkout. The
50
+ provider runs in the retained detached worktree, with the source-relative
51
+ working subdirectory preserved. A request that attaches to an existing
52
+ workspace uses its recorded checkout and source identity:
53
+
54
+ ```text
55
+ delegate --root ROOT dispatch --workspace WORKSPACE_ID ... --json
56
+ ```
57
+
58
+ Public `--workspace` cannot be combined with `--cwd`, `--base`, or
59
+ `--isolation`. It is an attachment by durable ID, not a path alias. The Lead
60
+ owns landing decisions; Delegate does not automatically apply changes, commit,
61
+ create branches, or merge them.
62
+
63
+ Git-content capture is not a complete filesystem backup, index partition, or
64
+ worker commit-history backup. It does not promise ignored runtime files,
65
+ submodule interiors, empty directories, extended attributes, or LFS payloads
66
+ behind pointers. Read paths from `workspace.artifacts` and verify each
67
+ descriptor’s length and SHA-256 before using its bytes. Entries marked
68
+ `forgetting`, `forgotten`, or `omitted` have no readable path.
69
+
70
+ Shared Git refs, config, and other global resources mean that
71
+ worktree separation is cooperative checkout isolation, not a security sandbox
72
+ or read-only enforcement. A clean Git status does not prove that a provider
73
+ made no write outside the promised content scope.
74
+
75
+ ## Public commands
76
+
77
+ The CLI currently exposes these managed-workspace commands:
78
+
79
+ ```text
80
+ delegate --root ROOT workspace list [--after ID] [--limit 1..50] --json
81
+ delegate --root ROOT workspace status ID [--operation OP] [--watch DURATION] --json
82
+ delegate --root ROOT workspace exec ID --budget DURATION --json -- ARGV...
83
+ delegate --root ROOT workspace release ID [--discard] [--budget DURATION] --json
84
+ delegate --root ROOT workspace forget ID [--budget DURATION] --json
85
+ ```
86
+
87
+ `workspace exec` passes `ARGV...` directly to the supervised helper; the
88
+ `--` delimiter makes the arguments literal and no shell is inserted. Its
89
+ initial response is asynchronous and uses exit code `3` while the operation
90
+ is pending. `status` can watch one operation, while `list` returns summaries
91
+ and a cursor for the next page. `--limit` is between 1 and 50.
92
+ Follow the [workspace acknowledgement decisions](result-handling.md#managed-workspace-results)
93
+ before retrying a mutation. A busy precondition and an accepted pending action
94
+ have different next actions; an accepted action can have no helper ID yet.
95
+
96
+ The workspace helper budget defaults to 5 minutes, is persisted with the
97
+ workspace or operation, and can be overridden by the corresponding budget
98
+ flag. This auxiliary budget is separate from and does not renew the provider
99
+ task budget. The existing `codex:review` default remains 1 hour.
100
+
101
+ `continue --task PREDECESSOR_ID` inherits the predecessor's managed workspace,
102
+ working directory, provider session, and recorded environment, while creating
103
+ a new task ID. A changed provider request is a new turn; it must not mutate the
104
+ predecessor's immutable records. A retained workspace can be used by a
105
+ read-only review by attaching its ID, for example:
106
+
107
+ ```text
108
+ delegate --root ROOT dispatch --provider codex:review \
109
+ --workspace WORKSPACE_ID --review-target TARGET --brief ABS_BRIEF \
110
+ --permission read-only --budget 1h --json
111
+ ```
112
+
113
+ ## Capture and verification
114
+
115
+ The provider outcome and Git-content `CaptureReceipt` are separate immutable
116
+ facts. Normal capture covers the initial committed base through the captured
117
+ tree, including worker commits and added untracked files that belong to the
118
+ Git-content view. It uses a private temporary Git index and records an owned
119
+ base pin plus tree/snapshot reference.
120
+ Optional binary patch and name-status artifacts are bounded to 8 MiB each; an
121
+ overflow is omitted, never silently truncated. Verification diagnostics retain
122
+ an 8 MiB prefix per stream, mark truncation explicitly, and continue draining
123
+ the stream. A verification command's exit is verification evidence, not the
124
+ provider task outcome.
125
+
126
+ A failed helper may retain an `error.txt` diagnostic with a bounded, validated
127
+ descriptor. It is operation evidence, not captured Git content or a provider
128
+ answer. Diagnostic write failure does not turn a known helper failure into
129
+ success. Temporary result-read errors keep capture retryable.
130
+
131
+ The normal timeout path is ordered: the provider's native scope closes, the
132
+ managed worker's exact `Wait` is recorded, then a new finite auxiliary capture
133
+ scope runs. Recovery may instead record a validated absence disposition; it
134
+ proves closure without inventing a native `Wait` or provider success. The
135
+ expired provider scope is never renewed or reused. If capture
136
+ is unavailable after closure, the closure evidence can still preserve a valid
137
+ continuation decision; it does not rewrite the provider outcome.
138
+
139
+ ## Retention and forgetting
140
+
141
+ A created managed checkout is retained for every outcome, including no-op and
142
+ provider-failure outcomes, until the Lead explicitly releases it. A failed
143
+ admission before checkout creation has no checkout to retain. Normal release
144
+ captures final content before exclusive durable cleanup. A failed capture or
145
+ identity check retains the checkout and evidence for retry. `--discard` accepts
146
+ loss of uncaptured checkout content; it does not waive native closure,
147
+ ownership, or identity proof.
148
+
149
+ Release leaves the pinned refs/blobs and capture receipts as evidence. After a
150
+ proven release, `workspace forget ID` writes an exact inventory intent before
151
+ removing only matching owned refs and optional artifacts by identity/CAS. It
152
+ retains capture receipts, tombstones, all provider outcomes, raw evidence, and
153
+ payload descriptors. Readers should label an intentionally forgotten item as
154
+ `forgotten`, not as corruption.
155
+
156
+ Release and forget keep a compact container anchor, ownership marker, and durable
157
+ journal metadata. They remove the checkout and the exact evidence authorized by
158
+ the forget inventory. A failed forget attempt can retain a diagnostic written
159
+ after its inventory was committed; do not delete these internal paths manually.
160
+
161
+ Unknown or busy workspace state is retained and receives no cleanup. There is
162
+ no TTL cleanup, workspace renaming, global Git prune, or unowned goroutine
163
+ unlink path.
164
+
165
+ ## Recovery and review scope
166
+
167
+ When provision is pending and Delegate proves the provider task was not created,
168
+ the response contains `task_record: "not_created"`,
169
+ `failure.code: "workspace_provision_pending"`, and
170
+ `failure.next_action: "watch_workspace"`. Run the returned recovery command
171
+ with the same state root and workspace ID. Do not poll a nonexistent task or
172
+ start the provider again. An explicit task ID can have unknown creation state;
173
+ follow the returned failure instead of inferring absence.
174
+
175
+ `state: "preparation_failed"` with `reason_code: "admission_not_launched"`
176
+ means the admission closed without a registered checkout or provider launch.
177
+ Report its `stop_and_report` failure; do not keep watching it as provisioning.
178
+ A short observation window does not cancel accepted scheduling or renew the
179
+ helper's deadline. Continue observing an accepted pending action as directed.
180
+
181
+ After provision, keep the returned task ID and the same admission inputs when
182
+ retrying a request proven not created. Delegate gives a safely closed attempt
183
+ a new helper identity and deadline; it never reopens the earlier worker or
184
+ renews its deadline. Changed provider input needs a new task ID. Partial setup keeps its
185
+ durable source and ownership records. Explicit release removes only an exactly
186
+ verified owned checkout; changed paths or unverifiable Git metadata remain
187
+ retained with an error. Recovery never creates a checkout just to delete it.
188
+
189
+ Review the whole delegated turn against its recorded initial base and captured
190
+ tree, including worker commits. For that scope, use an ordinary read-only task
191
+ with explicit base/snapshot refs and a `git diff BASE TREE` instruction. Native
192
+ Codex review targets have their own scope: `uncommitted` covers current staged,
193
+ unstaged, and untracked changes; `base:BRANCH` compares a branch; `commit:SHA`
194
+ reviews a commit. An uncommitted review does not cover changes already committed
195
+ by the worker. Do not pass a tree reference as a branch or assume a native
196
+ target reviews the complete delegated turn. Preserve an explicitly requested
197
+ native review target and state its scope.