delegation-layer 0.3.0 → 0.4.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.
Files changed (33) hide show
  1. package/README.md +4 -2
  2. package/package.json +1 -1
  3. package/plugins/delegation-layer/.claude-plugin/plugin.json +1 -1
  4. package/plugins/delegation-layer/.codex-plugin/plugin.json +1 -1
  5. package/plugins/delegation-layer/skills/agent-integration/SKILL.md +16 -8
  6. package/plugins/delegation-layer/skills/agent-integration/evals/evals.json +23 -3
  7. package/plugins/delegation-layer/skills/agent-integration/examples/json-results.md +5 -2
  8. package/plugins/delegation-layer/skills/agent-integration/examples/managed-workspace.md +25 -10
  9. package/plugins/delegation-layer/skills/agent-integration/examples/read-only-task.md +3 -1
  10. package/plugins/delegation-layer/skills/agent-integration/references/ccr.md +5 -4
  11. package/plugins/delegation-layer/skills/agent-integration/references/collaboration.md +2 -2
  12. package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +69 -33
  13. package/plugins/delegation-layer/skills/agent-integration/references/continuation.md +7 -4
  14. package/plugins/delegation-layer/skills/agent-integration/references/interaction.md +6 -5
  15. package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +7 -4
  16. package/plugins/delegation-layer/skills/agent-integration/references/routing-rule.json +1 -1
  17. package/plugins/delegation-layer/skills/agent-integration/references/workspaces.md +18 -14
  18. package/plugins/delegation-layer/skills/agent-integration/scripts/delegate-routing-context.sh +2 -2
  19. package/scripts/installer/routing-store.mjs +79 -46
  20. package/skills/agent-integration/SKILL.md +16 -8
  21. package/skills/agent-integration/evals/evals.json +23 -3
  22. package/skills/agent-integration/examples/json-results.md +5 -2
  23. package/skills/agent-integration/examples/managed-workspace.md +25 -10
  24. package/skills/agent-integration/examples/read-only-task.md +3 -1
  25. package/skills/agent-integration/references/ccr.md +5 -4
  26. package/skills/agent-integration/references/collaboration.md +2 -2
  27. package/skills/agent-integration/references/command-reference.md +69 -33
  28. package/skills/agent-integration/references/continuation.md +7 -4
  29. package/skills/agent-integration/references/interaction.md +6 -5
  30. package/skills/agent-integration/references/result-handling.md +7 -4
  31. package/skills/agent-integration/references/routing-rule.json +1 -1
  32. package/skills/agent-integration/references/workspaces.md +18 -14
  33. package/skills/agent-integration/scripts/delegate-routing-context.sh +2 -2
@@ -7,6 +7,10 @@ or attaches to a managed workspace (`--isolation git-worktree` or
7
7
  `--workspace ID`), or creates or removes a [Git checkpoint](#git-checkpoints).
8
8
 
9
9
  This reference is self-contained guidance for using managed workspaces.
10
+ Commands use the CLI default under the main skill's
11
+ [root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief). For a workspace
12
+ or checkpoint in an explicit custom or recorded historical root, pass that
13
+ exact `--root` on every related command.
10
14
 
11
15
  Provider-native permissions still apply inside an isolated checkout. A provider
12
16
  may edit files but be unable to stage or commit because linked-worktree Git
@@ -41,7 +45,7 @@ row ending or a provider outcome alone is not closure evidence.
41
45
  Create a managed workspace from a committed source base:
42
46
 
43
47
  ```text
44
- delegate --root ROOT dispatch --isolation git-worktree --cwd ABS \
48
+ delegate dispatch --isolation git-worktree --cwd ABS \
45
49
  [--base REV] [--workspace-budget DURATION] ... --json
46
50
  ```
47
51
 
@@ -55,7 +59,7 @@ removing that source does not block capture, release, or forget. A request that
55
59
  workspace uses its recorded checkout and source identity:
56
60
 
57
61
  ```text
58
- delegate --root ROOT dispatch --workspace WORKSPACE_ID ... --json
62
+ delegate dispatch --workspace WORKSPACE_ID ... --json
59
63
  ```
60
64
 
61
65
  Public `--workspace` cannot be combined with `--cwd`, `--base`, or
@@ -80,11 +84,11 @@ made no write outside the promised content scope.
80
84
  The CLI currently exposes these managed-workspace commands:
81
85
 
82
86
  ```text
83
- delegate --root ROOT workspace list [--after ID] [--limit 1..50] --json
84
- delegate --root ROOT workspace status ID [--operation OP] [--watch DURATION] --json
85
- delegate --root ROOT workspace exec ID --budget DURATION --json -- ARGV...
86
- delegate --root ROOT workspace release ID [--discard] [--budget DURATION] --json
87
- delegate --root ROOT workspace forget ID [--budget DURATION] --json
87
+ delegate workspace list [--after ID] [--limit 1..50] --json
88
+ delegate workspace status ID [--operation OP] [--watch DURATION] --json
89
+ delegate workspace exec ID --budget DURATION --json -- ARGV...
90
+ delegate workspace release ID [--discard] [--budget DURATION] --json
91
+ delegate workspace forget ID [--budget DURATION] --json
88
92
  ```
89
93
 
90
94
  `workspace exec` passes `ARGV...` directly to the supervised helper; the
@@ -110,7 +114,7 @@ must not mutate the predecessor's immutable records. A retained workspace can be
110
114
  read-only review by attaching its ID, for example:
111
115
 
112
116
  ```text
113
- delegate --root ROOT dispatch --provider codex:review \
117
+ delegate dispatch --provider codex:review \
114
118
  --workspace WORKSPACE_ID --review-target TARGET --brief ABS_BRIEF \
115
119
  --permission read-only --budget 1h --json
116
120
  ```
@@ -183,11 +187,11 @@ fixed Delegate values; trailers carry the checkpoint ID and request digest.
183
187
  This is unrelated to a provider continuation `mode: "checkpoint"`.
184
188
 
185
189
  ```text
186
- delegate --root ROOT checkpoint create --cwd ABS [--budget DURATION] --json
187
- delegate --root ROOT checkpoint create --workspace ID [--budget DURATION] --json
188
- delegate --root ROOT checkpoint status CHECKPOINT_ID [--operation OP] [--watch DURATION] --json
189
- delegate --root ROOT checkpoint list [--after CHECKPOINT_ID] [--limit 1..50] --json
190
- delegate --root ROOT checkpoint remove CHECKPOINT_ID [--budget DURATION] --json
190
+ delegate checkpoint create --cwd ABS [--budget DURATION] --json
191
+ delegate checkpoint create --workspace ID [--budget DURATION] --json
192
+ delegate checkpoint status CHECKPOINT_ID [--operation OP] [--watch DURATION] --json
193
+ delegate checkpoint list [--after CHECKPOINT_ID] [--limit 1..50] --json
194
+ delegate checkpoint remove CHECKPOINT_ID [--budget DURATION] --json
191
195
  ```
192
196
 
193
197
  - `create` names exactly one target: `--cwd` for an absolute ordinary Git
@@ -232,7 +236,7 @@ Save every response and exit code once; follow
232
236
  the same repository as `--cwd`, normally the source the Lead already uses:
233
237
 
234
238
  ```text
235
- delegate --root ROOT dispatch --auto --brief ABS_BRIEF --cwd ABS_SOURCE \
239
+ delegate dispatch --auto --brief ABS_BRIEF --cwd ABS_SOURCE \
236
240
  --isolation git-worktree --base COMMIT_OID \
237
241
  --permission workspace-write --budget 30m --json
238
242
  ```
@@ -5,11 +5,11 @@ case "${1:-}" in
5
5
  SessionStart|SubagentStart) event=$1 ;;
6
6
  *) printf '%s\n' 'Expected SessionStart or SubagentStart.' >&2; exit 2 ;;
7
7
  esac
8
- script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
8
+ script_dir=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd)
9
9
  rule_file="$script_dir/../references/routing-rule.json"
10
10
  # Read before emitting anything so a missing asset cannot produce partial JSON.
11
11
  rule=$(cat "$rule_file")
12
- skill_file="$(CDPATH= cd -- "$script_dir/.." && pwd)/SKILL.md"
12
+ skill_file="$(CDPATH='' cd -- "$script_dir/.." && pwd)/SKILL.md"
13
13
  DELEGATE_ROUTING_EVENT="$event" DELEGATE_ROUTING_RULE="$rule" DELEGATE_ROUTING_SKILL="$skill_file" awk '
14
14
  BEGIN {
15
15
  # Paths are task data, not shell code. Escape every JSON control character.
@@ -5,7 +5,7 @@ import { assertNoSymlinkComponents, existingPath } from "./filesystem.mjs";
5
5
  import { countRoutingEvents, createRoutingPlan, routingPath, validateHookConfig } from "./routing-rules.mjs";
6
6
  import { targetFor } from "./selection.mjs";
7
7
 
8
- export async function prepareRouting(selected, action, { environment, platform, sourceDirectory }) {
8
+ export async function prepareRouting(selected, action, { environment, platform }) {
9
9
  const plans = [];
10
10
  for (const name of new Set(selected.harnessNames)) {
11
11
  const path = routingPath(name, {
@@ -55,85 +55,118 @@ export async function prepareRouting(selected, action, { environment, platform,
55
55
  return plans;
56
56
  }
57
57
 
58
- async function replaceRoutingConfig(plan, before, after) {
59
- await assertNoSymlinkComponents(plan.path);
60
- await mkdir(dirname(plan.path), { recursive: true });
58
+ const routingFileOperations = Object.freeze({ open, mkdir, readFile, rename, unlink, existingPath, assertNoSymlinkComponents });
59
+
60
+ function errorMessage(error) {
61
+ return error instanceof Error ? error.message : String(error);
62
+ }
63
+
64
+ function combinedFailure(failures) {
65
+ if (failures.length === 1) return failures[0];
66
+ return new AggregateError(failures, failures.map(errorMessage).join("; "), { cause: failures[0] });
67
+ }
68
+
69
+ async function writeAndClose(file, contents) {
70
+ const failures = [];
71
+ try {
72
+ await file.writeFile(contents);
73
+ await file.sync();
74
+ } catch (error) {
75
+ failures.push(error);
76
+ }
77
+ try {
78
+ await file.close();
79
+ } catch (error) {
80
+ failures.push(error);
81
+ }
82
+ if (failures.length) throw combinedFailure(failures);
83
+ }
84
+
85
+ async function cleanupReplacement(lock, temporary, lockPath, operations) {
86
+ const failures = [];
87
+ try {
88
+ await operations.unlink(temporary);
89
+ } catch (error) {
90
+ if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) failures.push(error);
91
+ }
92
+ try {
93
+ await lock.close();
94
+ } catch (error) {
95
+ failures.push(error);
96
+ }
97
+ try {
98
+ await operations.unlink(lockPath);
99
+ } catch (error) {
100
+ failures.push(error);
101
+ }
102
+ return failures;
103
+ }
104
+
105
+ async function replaceRoutingConfig(plan, before, after, operations, onCommitted) {
106
+ await operations.assertNoSymlinkComponents(plan.path);
107
+ await operations.mkdir(dirname(plan.path), { recursive: true });
61
108
  const lockPath = plan.path + ".delegation-layer.lock";
62
109
  let lock;
63
110
  try {
64
- lock = await open(lockPath, "wx", 0o600);
111
+ lock = await operations.open(lockPath, "wx", 0o600);
65
112
  } catch (error) {
66
113
  if (error && typeof error === "object" && "code" in error && error.code === "EEXIST") {
67
- throw new Error(`routing configuration is locked: ${lockPath}; verify no other installer is running before removing a stale lock`);
114
+ throw new Error(`routing configuration is locked: ${lockPath}; verify no other installer is running before removing a stale lock`, { cause: error });
68
115
  }
69
116
  throw error;
70
117
  }
71
118
  const suffix = `${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`;
72
119
  const temporary = plan.path + `.delegation-layer-stage-${suffix}`;
120
+ const failures = [];
73
121
  try {
74
- const stat = await existingPath(plan.path);
122
+ const stat = await operations.existingPath(plan.path);
75
123
  if (stat && (!stat.isFile() || stat.isSymbolicLink())) {
76
124
  throw new Error(`routing configuration changed during installation: ${plan.path}`);
77
125
  }
78
- const current = stat ? await readFile(plan.path, "utf8") : null;
126
+ const current = stat ? await operations.readFile(plan.path, "utf8") : null;
79
127
  if (current !== before) throw new Error(`routing configuration changed during installation; retry: ${plan.path}`);
80
128
  if (before !== null) {
81
- const backup = await open(plan.path + `.delegation-layer-backup-${suffix}`, "wx", 0o600);
82
- try {
83
- await backup.writeFile(before);
84
- await backup.sync();
85
- } finally {
86
- await backup.close();
87
- }
129
+ const backup = await operations.open(plan.path + `.delegation-layer-backup-${suffix}`, "wx", 0o600);
130
+ await writeAndClose(backup, before);
88
131
  }
89
132
  if (after === null) {
90
- await unlink(plan.path);
91
- return;
92
- }
93
- const staged = await open(temporary, "wx", plan.mode);
94
- try {
95
- await staged.writeFile(after);
96
- await staged.sync();
97
- } finally {
98
- await staged.close();
99
- }
100
- await rename(temporary, plan.path);
101
- } finally {
102
- try {
103
- try {
104
- await unlink(temporary);
105
- } catch (error) {
106
- if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) throw error;
107
- }
108
- } finally {
109
- try {
110
- await lock.close();
111
- } finally {
112
- await unlink(lockPath);
113
- }
133
+ await operations.unlink(plan.path);
134
+ } else {
135
+ const staged = await operations.open(temporary, "wx", plan.mode);
136
+ await writeAndClose(staged, after);
137
+ await operations.rename(temporary, plan.path);
114
138
  }
139
+ onCommitted?.();
140
+ } catch (error) {
141
+ failures.push(error);
115
142
  }
143
+ failures.push(...await cleanupReplacement(lock, temporary, lockPath, operations));
144
+ if (failures.length) throw combinedFailure(failures);
116
145
  }
117
146
 
118
- export async function applyRouting(plans) {
147
+ export async function applyRouting(plans, fileOperations = {}) {
148
+ const operations = { ...routingFileOperations, ...fileOperations };
149
+ // This transaction owns committed mutations, including commits followed by a cleanup failure.
119
150
  const applied = [];
120
151
  try {
121
152
  for (const plan of plans) {
122
153
  if (!plan.path || plan.before === plan.after) continue;
123
- await replaceRoutingConfig(plan, plan.before, plan.after);
124
- applied.push(plan);
154
+ await replaceRoutingConfig(plan, plan.before, plan.after, operations, () => applied.push(plan));
125
155
  }
126
156
  } catch (error) {
127
157
  const failures = [];
128
158
  for (const plan of applied.reverse()) {
129
159
  try {
130
- await replaceRoutingConfig(plan, plan.after, plan.before);
160
+ await replaceRoutingConfig(plan, plan.after, plan.before, operations);
131
161
  } catch (rollbackError) {
132
- failures.push(rollbackError instanceof Error ? rollbackError.message : String(rollbackError));
162
+ failures.push(rollbackError);
133
163
  }
134
164
  }
135
- const reason = error instanceof Error ? error.message : String(error);
136
- throw new Error(`${reason}${failures.length ? `; rollback needs attention: ${failures.join("; ")}` : "; earlier routing changes rolled back"}`);
165
+ const reason = errorMessage(error);
166
+ if (failures.length) {
167
+ throw new AggregateError([error, ...failures], `${reason}; rollback needs attention: ${failures.map(errorMessage).join("; ")}`, { cause: error });
168
+ }
169
+ throw new Error(`${reason}; earlier routing changes rolled back`, { cause: error });
137
170
  }
138
171
  }
139
172
 
@@ -87,11 +87,16 @@ Use a supplied brief or write the worker's bounded assignment and acceptance
87
87
  criteria to a regular file. Do not copy the orchestration request or ask workers
88
88
  to recruit others unless recursive delegation was requested.
89
89
 
90
- Keep the state root outside provider-writable workspaces, provider runtime
91
- directories, and temporary trees they may write. For every task command pass
92
- `--root "${DELEGATE_ROOT:-$HOME/delegation-state}"` directly in that shell
93
- invocation. If the user explicitly requests another root, use that exact path
94
- consistently. Task IDs separate tasks; do not invent per-task roots.
90
+ For ordinary task, schedule, observation, interaction, and continuation commands,
91
+ omit `--root`; the CLI owns default-root resolution for the user's configuration
92
+ context, independently of the project cwd. Do not assemble a default path, use a
93
+ sample path or shell fallback, or treat ambient `DELEGATE_ROOT` as authority.
94
+ Only pass `--root` when the user explicitly supplies a root or existing work has
95
+ an already recorded custom or historical root; preserve that exact path for
96
+ every command concerning that work. Never search other roots for an old task.
97
+ Task IDs separate tasks; do not invent per-task or per-project roots. The state
98
+ root must remain outside provider-writable workspaces, provider runtime
99
+ directories, and temporary trees they may write.
95
100
 
96
101
  Prepare paths and dispatch in one tool invocation; shell variables may not
97
102
  persist between calls. Use saved absolute paths in later calls. Do not use
@@ -125,13 +130,16 @@ original command and intent.
125
130
  ### 5. Observe and collect
126
131
 
127
132
  Follow [observation decisions](references/result-handling.md#observe-and-collect)
128
- with the same root and created task ID:
133
+ with the created task ID, using the CLI default for ordinary work:
129
134
 
130
135
  ```sh
131
- delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" status TASK_ID --json
132
- delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect TASK_ID --watch 5s --json
136
+ delegate status TASK_ID --json
137
+ delegate collect TASK_ID --watch 5s --json
133
138
  ```
134
139
 
140
+ For work bound to an explicit custom or historical root, add its exact
141
+ `--root` to both commands under the [root rule](#3-prepare-separate-paths-and-a-finite-brief).
142
+
135
143
  Apply the owning decision order before waiting: terminal outcomes and concrete
136
144
  errors, cancellation/timeout/interruption, interaction, then pending
137
145
  observation. Keep collection in the foreground until completion or a reported
@@ -10,7 +10,7 @@
10
10
  {
11
11
  "name": "normal-dispatch",
12
12
  "prompt": "Run one bounded task through the available agent provider.",
13
- "expected": ["dispatch --auto", "--json", "save task_id", "status", "collect"]
13
+ "expected": ["dispatch --auto", "omit --root on ordinary commands", "--json", "save task_id", "status", "collect"]
14
14
  },
15
15
  {
16
16
  "name": "model-discovery-when-needed",
@@ -68,9 +68,29 @@
68
68
  "expected": ["use status with returned task_id", "read saved dispatch response if needed", "do not dispatch again to print an exit code", "exactly one admitted task for the assignment"]
69
69
  },
70
70
  {
71
- "name": "supplied-root-across-shell-calls",
71
+ "name": "ambient-root-ignored-across-shell-calls",
72
72
  "prompt": "DELEGATE_ROOT is already set. Consult a separate external agent and answer its questions; each shell tool call starts a new shell.",
73
- "expected": ["use supplied DELEGATE_ROOT on dispatch, status, collect, reply, steer, and continue", "resolve the same root in each shell call", "no invented task-specific root"]
73
+ "expected": ["omit --root on dispatch, status, collect, reply, steer, and continue", "ambient DELEGATE_ROOT has no root-selection authority", "CLI resolves its default in the same user/configuration context", "no assembled default, shell fallback, sample path, or per-task root"]
74
+ },
75
+ {
76
+ "name": "ordinary-root-from-another-project",
77
+ "prompt": "DELEGATE_ROOT is unset. An admitted task was dispatched without --root in project A. Observe and continue it from project B in the same user/configuration context.",
78
+ "expected": ["omit --root on status, collect, and continue", "use the recorded task ID", "CLI default is independent of project cwd", "no path guessed from project A or B", "no search across roots"]
79
+ },
80
+ {
81
+ "name": "explicit-root-across-shell-calls",
82
+ "prompt": "For this isolated test, I explicitly choose the state root /state/custom with spaces. Consult a separate external agent and answer its questions; each shell tool call starts a new shell.",
83
+ "expected": ["pass --root with the exact single argument /state/custom with spaces on dispatch, status, collect, reply, steer, and continue", "quote the root in shell commands", "save and reassign absolute brief and response paths in each needed shell invocation", "no ambient variable or fallback overrides the explicit choice"]
84
+ },
85
+ {
86
+ "name": "historical-root-continuation",
87
+ "prompt": "An eligible predecessor task has recorded historical root /state/legacy with spaces. Continue that exact task and collect its successor. The current CLI default is different.",
88
+ "expected": ["pass the exact recorded --root argument /state/legacy with spaces on continue, status, and collect", "use the exact predecessor and returned successor IDs", "no fresh dispatch", "do not move or search for the task in the default root"]
89
+ },
90
+ {
91
+ "name": "ordinary-schedule-root",
92
+ "prompt": "Create a recurring task in this project, then inspect its definition, history, and execution from another project in the same user/configuration context. No custom state root was requested.",
93
+ "expected": ["omit --root on schedule create, list, show, history, and execution", "keep the definition's own project --cwd", "no per-project root", "do not start a persistent scheduler inside the agent task", "forward any returned scheduler.serve_command argv intact"]
74
94
  },
75
95
  {
76
96
  "name": "pending-without-questions",
@@ -1,8 +1,11 @@
1
1
  # JSON decision sketch
2
2
 
3
+ Use the created task's exact ID as `TASK_ID` and follow the main skill's
4
+ [root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief).
5
+
3
6
  ```sh
4
- delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" status "$TASK_ID" --json
5
- delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect "$TASK_ID" --watch 5s --json
7
+ delegate status TASK_ID --json
8
+ delegate collect TASK_ID --watch 5s --json
6
9
  ```
7
10
 
8
11
  Apply [result handling](../references/result-handling.md) to each response and
@@ -3,14 +3,18 @@
3
3
  Use this example for independent write work that should be isolated in a
4
4
  retained Git worktree. The source must be a Git checkout and the state root
5
5
  must remain outside provider-writable workspaces.
6
+ Commands use the CLI default under the main skill's
7
+ [root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief); preserve any
8
+ explicit custom or recorded historical root on all related commands.
6
9
 
7
10
  ```sh
8
11
  SOURCE="$PWD"
9
- BRIEF="$(mktemp)"
10
- RESPONSE="$(mktemp)"
12
+ BRIEF="$(mktemp)" || exit 1
13
+ RESPONSE="$(mktemp)" || exit 1
11
14
  printf '%s\n' 'Implement the requested change and report the files changed.' >"$BRIEF"
15
+ printf 'Saved response: %s\n' "$RESPONSE"
12
16
 
13
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --auto \
17
+ if delegate dispatch --auto \
14
18
  --brief "$BRIEF" --cwd "$SOURCE" \
15
19
  --permission workspace-write --isolation git-worktree \
16
20
  --base HEAD --workspace-budget 5m --budget 30m --json >"$RESPONSE"; then
@@ -26,9 +30,13 @@ Read the saved JSON before running another command. When
26
30
  `task_record: "created"`, use its `task_id` as `TASK_ID` below. When no task
27
31
  was created, follow the [result decisions](../references/result-handling.md#managed-workspace-results);
28
32
  do not run task status or collection against that nonexistent record.
33
+ Each later block is a separate shell invocation. Replace `ABS_SAVED_RESPONSE`
34
+ with the printed absolute response path and the ID placeholders with the actual
35
+ returned IDs; reassign the path in each invocation.
29
36
 
30
37
  ```sh
31
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" status TASK_ID --json >"$RESPONSE.status"; then
38
+ RESPONSE="ABS_SAVED_RESPONSE"
39
+ if delegate status TASK_ID --json >"$RESPONSE.status"; then
32
40
  status_exit=0
33
41
  else
34
42
  status_exit=$?
@@ -43,7 +51,8 @@ before running another command. Run the collection below only when that
43
51
  guidance calls for it.
44
52
 
45
53
  ```sh
46
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect TASK_ID --watch 5s --json >"$RESPONSE.collect"; then
54
+ RESPONSE="ABS_SAVED_RESPONSE"
55
+ if delegate collect TASK_ID --watch 5s --json >"$RESPONSE.collect"; then
47
56
  collect_exit=0
48
57
  else
49
58
  collect_exit=$?
@@ -64,7 +73,8 @@ Before release, wait for the workspace to return to `state: retained` and inspec
64
73
  its final capture. Only after the Lead explicitly chooses release, run:
65
74
 
66
75
  ```sh
67
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" workspace release WORKSPACE_ID \
76
+ RESPONSE="ABS_SAVED_RESPONSE"
77
+ if delegate workspace release WORKSPACE_ID \
68
78
  --budget 5m --json >"$RESPONSE.release"; then
69
79
  release_exit=0
70
80
  else
@@ -95,8 +105,9 @@ owns every response decision.
95
105
 
96
106
  ```sh
97
107
  SOURCE="$PWD"
98
- RESPONSE="$(mktemp)"
99
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint create \
108
+ RESPONSE="$(mktemp)" || exit 1
109
+ printf 'Saved response: %s\n' "$RESPONSE"
110
+ if delegate checkpoint create \
100
111
  --cwd "$SOURCE" --budget 5m --json >"$RESPONSE.checkpoint"; then
101
112
  checkpoint_exit=0
102
113
  else
@@ -109,9 +120,12 @@ cat "$RESPONSE.checkpoint"
109
120
  Exit `3` with `checkpoint.id` and `next_action: "watch_checkpoint"` means the
110
121
  request was accepted, not captured. Use that `checkpoint.id` as
111
122
  `CHECKPOINT_ID`. Do not run `create` again.
123
+ For the later checkpoint blocks, replace `ABS_SAVED_RESPONSE` with the absolute
124
+ response path printed by this checkpoint invocation.
112
125
 
113
126
  ```sh
114
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint status CHECKPOINT_ID \
127
+ RESPONSE="ABS_SAVED_RESPONSE"
128
+ if delegate checkpoint status CHECKPOINT_ID \
115
129
  --watch 30s --json >"$RESPONSE.checkpoint.status"; then
116
130
  checkpoint_status_exit=0
117
131
  else
@@ -130,7 +144,8 @@ dispatch example, replacing `--base HEAD` with `--base COMMIT_OID`. Report a
130
144
  When the Lead no longer needs the checkpoint, remove it explicitly:
131
145
 
132
146
  ```sh
133
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint remove CHECKPOINT_ID \
147
+ RESPONSE="ABS_SAVED_RESPONSE"
148
+ if delegate checkpoint remove CHECKPOINT_ID \
134
149
  --budget 5m --json >"$RESPONSE.checkpoint.remove"; then
135
150
  checkpoint_remove_exit=0
136
151
  else
@@ -2,6 +2,8 @@
2
2
 
3
3
  Run from the intended workspace, outside Delegate's private state root.
4
4
  Use a catalog provider ID in place of `--auto` when a destination was named.
5
+ This example uses the CLI default under the main skill's
6
+ [root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief).
5
7
  Prepare paths and dispatch in this same shell invocation:
6
8
 
7
9
  ```sh
@@ -13,7 +15,7 @@ Inspect the workspace and summarize the current test failures. Do not edit files
13
15
  You are the assigned worker; perform this task without delegating it.
14
16
  EOF
15
17
  printf 'Saved response: %s\n' "$RESPONSE"
16
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --auto \
18
+ if delegate dispatch --auto \
17
19
  --brief "$BRIEF" --cwd "$WORKSPACE" \
18
20
  --permission read-only --budget 30m --json >"$RESPONSE"; then
19
21
  dispatch_exit=0
@@ -3,18 +3,19 @@
3
3
  Use this reference when asked to consult Claude Code Router (CCR), use one of
4
4
  its configured model aliases, or compare its models with other harnesses.
5
5
  CCR runs Claude Code against a configured third-party or local provider.
6
- `ROOT` below is the exact absolute state root selected for dispatch; use it
7
- unchanged for model discovery and dispatch.
6
+ Use the CLI default under the main skill's
7
+ [root rule](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief); preserve any
8
+ explicit custom or recorded historical root for model discovery and dispatch.
8
9
 
9
10
  1. Resolve CCR through `delegate providers --json`; its profile is `ccr:print`.
10
11
  2. Preserve an explicitly requested CCR alias as `--model ALIAS`. Do not replace
11
12
  it with an upstream model ID or reject it solely because discovery omitted it.
12
13
  3. If no alias was chosen, run
13
- `delegate --root ROOT models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
14
+ `delegate models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
14
15
  Choose a suitable configured alias from the available metadata and report
15
16
  the choice. Clarify when the intended model remains ambiguous. If discovery
16
17
  is unavailable and no alias is known, report the blocker; do not guess.
17
- 4. Dispatch through Delegate with the same `--root ROOT`,
18
+ 4. Dispatch through Delegate with
18
19
  `--provider ccr:print --model ALIAS`, the brief, workspace, permission, finite
19
20
  budget, and `--json`. Use the normal status, collect, and continuation procedure
20
21
  from the main skill.
@@ -45,7 +45,7 @@ RECEIPTS="$(mktemp -d)" || exit 1
45
45
  # Set these absolute paths and catalog IDs in this same tool invocation.
46
46
  # BRIEF_A and BRIEF_B contain the real independent assignments.
47
47
  (
48
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --provider "$PROVIDER_A" \
48
+ if delegate dispatch --provider "$PROVIDER_A" \
49
49
  --brief "$BRIEF_A" --cwd "$WORKSPACE_A" \
50
50
  --permission read-only --budget 30m --json \
51
51
  >"$RECEIPTS/review-a.json" 2>"$RECEIPTS/review-a.stderr"; then
@@ -56,7 +56,7 @@ RECEIPTS="$(mktemp -d)" || exit 1
56
56
  printf '%s\n' "$dispatch_exit" >"$RECEIPTS/review-a.exit"
57
57
  ) &
58
58
  (
59
- if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" dispatch --provider "$PROVIDER_B" \
59
+ if delegate dispatch --provider "$PROVIDER_B" \
60
60
  --brief "$BRIEF_B" --cwd "$WORKSPACE_B" \
61
61
  --permission read-only --budget 30m --json \
62
62
  >"$RECEIPTS/review-b.json" 2>"$RECEIPTS/review-b.stderr"; then