delegation-layer 0.1.39 → 0.3.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 (31) hide show
  1. package/README.md +49 -319
  2. package/docs/assets/delegation-layer-hero.jpg +0 -0
  3. package/package.json +1 -1
  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 +127 -359
  7. package/plugins/delegation-layer/skills/agent-integration/evals/cases.json +240 -0
  8. package/plugins/delegation-layer/skills/agent-integration/evals/routing.json +54 -0
  9. package/plugins/delegation-layer/skills/agent-integration/examples/managed-workspace.md +25 -7
  10. package/plugins/delegation-layer/skills/agent-integration/examples/read-only-task.md +29 -6
  11. package/plugins/delegation-layer/skills/agent-integration/examples/workspace-write-task.md +12 -10
  12. package/plugins/delegation-layer/skills/agent-integration/references/ccr.md +7 -4
  13. package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +509 -145
  14. package/plugins/delegation-layer/skills/agent-integration/references/continuation.md +20 -19
  15. package/plugins/delegation-layer/skills/agent-integration/references/interaction.md +20 -7
  16. package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +306 -90
  17. package/plugins/delegation-layer/skills/agent-integration/references/routing-rule.json +1 -1
  18. package/plugins/delegation-layer/skills/agent-integration/references/workspaces.md +33 -0
  19. package/skills/agent-integration/SKILL.md +127 -359
  20. package/skills/agent-integration/evals/cases.json +240 -0
  21. package/skills/agent-integration/evals/routing.json +54 -0
  22. package/skills/agent-integration/examples/managed-workspace.md +25 -7
  23. package/skills/agent-integration/examples/read-only-task.md +29 -6
  24. package/skills/agent-integration/examples/workspace-write-task.md +12 -10
  25. package/skills/agent-integration/references/ccr.md +7 -4
  26. package/skills/agent-integration/references/command-reference.md +509 -145
  27. package/skills/agent-integration/references/continuation.md +20 -19
  28. package/skills/agent-integration/references/interaction.md +20 -7
  29. package/skills/agent-integration/references/result-handling.md +306 -90
  30. package/skills/agent-integration/references/routing-rule.json +1 -1
  31. package/skills/agent-integration/references/workspaces.md +33 -0
@@ -1,170 +1,536 @@
1
1
  # Command reference
2
2
 
3
- All paths passed to `--root`, `--cwd`, and `--brief` must be absolute. Add
4
- `--json` to commands that return an agent-consumable response.
5
-
6
- Pass the intended workspace directly. Delegate handles provider launch options;
7
- do not initialize Git, change trust settings, or call a provider CLI as a
8
- workspace workaround. Ordinary tasks support non-Git directories. Git is
9
- required for managed worktree creation/attachment and checkpoint creation or
10
- removal only; native review retains
11
- its separate explicit review-target contract. See [managed workspace guidance](workspaces.md)
12
- for the policy owner.
13
-
14
- | Command | Purpose | Launches provider work? |
3
+ Paths passed to `--root`, `--cwd`, and `--brief` must be absolute.
4
+ Use `--json` and preserve the response and process exit separately.
5
+ The main skill owns [root selection](../SKILL.md#3-prepare-separate-paths-and-a-finite-brief).
6
+
7
+ | Command | Purpose | Provider execution |
15
8
  | --- | --- | --- |
16
- | `delegate --version` | Confirm the installed control CLI | No |
17
- | `delegate --root ROOT providers --json` | List compiled provider metadata | No |
18
- | `delegate --root ROOT capabilities --provider ID --json` | Read the catalog contract | No |
19
- | `delegate --root ROOT models --provider ID [--cwd ABS] --json` | Discover advisory native model and effort facts | Native inspection only; no admitted task |
20
- | `delegate --root ROOT preflight --provider ID --cwd ABS --json` | Check static provider admission | No |
21
- | `delegate --root ROOT dispatch --auto ... --json` | Select and admit one bounded turn | Yes, at most once |
22
- | `delegate --root ROOT status TASK --json` | Reconcile and observe task state | No provider launch |
23
- | `delegate --root ROOT collect TASK --watch 5s --json` | Read or wait for publication | No provider launch |
24
- | `delegate --root ROOT recheck TASK --json` | Reassess eligible rejected evidence offline | No provider launch; original outcome unchanged |
25
- | `delegate --root ROOT continue --task TASK ... --json` | Create an exact-session successor | Yes, at most once for the successor |
26
- | `delegate --root ROOT reply TASK --request ID --answers FILE --id MESSAGE_ID --json` | Answer a pending native question | No new launch |
27
- | `delegate --root ROOT steer TASK --brief FILE --id MESSAGE_ID --json` | Guide a supported active turn | No new launch |
28
- | `delegate --root ROOT events TASK --after SEQUENCE --watch 5s --json` | Read a bounded interaction event page | No |
29
- | `delegate --root ROOT logs TASK --json` | Return validated output descriptors | No |
30
- | `delegate --root ROOT cancel TASK --json` | Record one explicit stop request | Stops, does not relaunch |
31
-
32
- `delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" supervisor migrate --json` is the single command-neutral recovery
33
- step for a `supervisor_upgrade_required` admission response. Run it once with
34
- the failed command's exact root. A successful response names its next action
35
- `retry_dispatch`, but the original command and argv remain authoritative:
36
- retry `dispatch` as `dispatch` or `continue` as `continue`, exactly once.
37
-
38
- The bundled supervisor is managed by the released CLI under the state root.
39
- Collection remains observational. Provider authentication remains the
40
- provider’s own responsibility and is never performed by this skill.
41
-
42
- Dispatch flags:
43
-
44
- - `--brief FILE`: bounded task instructions; for `codex:review`, the brief is
45
- retained as task evidence and the explicit review target supplies Codex's
46
- native scope;
47
- - `--cwd ABS`: workspace for the delegated turn;
48
- - `--permission read-only|workspace-write`: read-only investigation or authorized unattended write execution, including commands (not independent containment);
49
- - `--budget DURATION`: finite turn budget;
50
- - `--auto`: let the CLI select a ready provider;
51
- - `--provider ID`: preserve the caller’s named harness or provider, resolved through the catalog;
52
- - `--review-target uncommitted|base:BRANCH|commit:SHA`: select the explicit Git state for `codex:review`; it is required for that read-only profile and unsupported by other profiles;
53
- - `--model MODEL` and `--effort VALUE`: provider-advertised choices (CCR requires a model alias);
54
- Codex maps effort to TOML `model_reasoning_effort` for ordinary turns or a native
55
- turn parameter for interactive turns, while Claude and AGY
56
- pass native effort flags; Pi maps effort to `--thinking`; OpenCode sends model
57
- and effort as acknowledged ACP session options; CCR forwards effort to Claude and uses `--model` as a CCR alias; `default` is omitted;
58
- - `--interactive`: enable advertised native clarification and steering; see [interaction](interaction.md);
59
- - `--native-timeout DURATION`: optional provider-native timeout where advertised.
9
+ | `delegate --version` | Check the control CLI | None |
10
+ | `providers --json` | List compiled profiles | None |
11
+ | `capabilities --provider ID --json` | Read a compiled contract | None |
12
+ | `models --provider ID [--cwd ABS] --json` | Discover model/effort facts | Native inspection, no admitted task |
13
+ | `preflight --provider ID --cwd ABS --json` | Check static readiness | None |
14
+ | `dispatch [--auto \| --provider ID] ... --json` | Admit a bounded turn; a Member may supply the destination | At most one launch attempt |
15
+ | `status TASK --json` | Observe task state | No launch |
16
+ | `collect TASK [--watch DURATION] --json` | Read or wait for publication | No launch |
17
+ | `logs TASK --json` | Read validated stream descriptors | No launch |
18
+ | `cancel TASK --json` | Record an explicit stop | No launch |
19
+ | `continue --task TASK ... --json` | Create an exact-session successor | At most one successor launch attempt |
20
+ | `recheck TASK --json` | Reassess eligible evidence offline | None |
21
+ | `reply`, `steer`, `events` | [Active interaction](interaction.md) | No new launch |
22
+ | `workspace`, `checkpoint` | [Git resources](workspaces.md) | Helpers, not provider turns |
23
+ | `teams` | [Optional configuration and Member selection](#teams) | None |
24
+ | `schedule` | [Recurring definitions](#schedules), [history and execution evidence](#schedule-history-and-execution) | None |
25
+ | `scheduler serve/status/stop` (when supported), `scheduler run` | [User-started host and compatibility runtime](#scheduler-runtime) | Due occurrences use normal dispatch; status/stop do not launch providers |
60
26
 
61
- ## Managed workspace commands
27
+ Prefix every task command with `delegate --root ROOT`, using the same
28
+ explicit root across invocations.
29
+
30
+ ## Dispatch
31
+
32
+ ```text
33
+ delegate --root ROOT dispatch [--auto | --provider ID] --brief FILE \
34
+ --cwd ABS [--id TASK_ID] [--permission MODE] [--budget DURATION] \
35
+ [--model MODEL] [--effort EFFORT] [--native-timeout DURATION] \
36
+ [--interactive] [--review-target TARGET] [--resume-task TASK_ID] \
37
+ [--team-scope user|project --team TEAM_ID --member MEMBER_ID] \
38
+ [--project-root ABS] --json
39
+ ```
40
+
41
+ | Option | Contract |
42
+ | --- | --- |
43
+ | `--brief FILE` | Regular file, at most 8 MiB; task input, not a raw provider argument. |
44
+ | `--cwd ABS` | Existing workspace, disjoint from the private state root. Ordinary tasks support non-Git directories. |
45
+ | `--auto` | Try static admission in deterministic provider-ID order; choose the first statically ready candidate. |
46
+ | `--provider ID` | Named catalog profile; mutually exclusive with `--auto`. |
47
+ | `--id TASK_ID` | Optional 32-character lowercase hexadecimal ID; omit to allocate. |
48
+ | `--permission MODE` | Default `read-only`; authorized `workspace-write` requests unattended commands and edits. Native access can extend beyond the workspace. |
49
+ | `--budget DURATION` | Positive Go duration; default `30m`, or `1h` for `codex:review`. Queue time is excluded. |
50
+ | `--model MODEL` | Exact selector for a profile advertising `model`: Codex, CCR, Claude, AGY, Pi, or OpenCode. CCR requires a configured alias. |
51
+ | `--effort VALUE` | Advertised effort selector; omitted or `default` preserves native defaults. |
52
+ | `--native-timeout DURATION` | Antigravity print timeout, no greater than `--budget`. |
53
+ | `--interactive` | Enable the profile's advertised native interaction; steering is a separate capability. See [interaction](interaction.md). |
54
+ | `--review-target TARGET` | Required only for native [Codex review](#codex-review). |
55
+ | `--resume-task TASK_ID` | Compatibility form for exact-predecessor continuation; prefer [continue](continuation.md). |
56
+ | `--team-scope`, `--team`, `--member` | Supply all three to choose one explicit [Member](#using-a-member); no implicit Team or Role-only target. |
57
+ | `--project-root ABS` | Explicit containing root for a non-Git project-scoped Member; invalid without that target or in a Git context. |
58
+
59
+ Without a Team target, exactly one of `--provider` and `--auto` is required.
60
+ A bound Member may supply an omitted destination; an unbound Member still
61
+ requires an explicit provider or auto. See [Teams](#teams) for saved defaults.
62
+
63
+ Codex maps effort to TOML `model_reasoning_effort` for ordinary turns or a
64
+ native parameter for interactive turns. CCR, Claude, and AGY pass their native
65
+ effort flag. Pi maps it to `--thinking`; OpenCode sends acknowledged ACP
66
+ session options, with model before effort. CCR treats model as a CCR alias.
67
+
68
+ Raw provider arguments, token ceilings, and dollar ceilings are not public
69
+ options. Preserve the selected workspace; do not initialize Git or change
70
+ trust settings as a workaround.
71
+
72
+ Every task ID identifies one immutable request and at most one provider launch
73
+ attempt. Changing its request is rejected; repeating it cannot grant another
74
+ launch. A selected provider's failure does not select a fallback.
75
+ Read [task creation](result-handling.md#task-creation) before any retry.
76
+
77
+ Omit `--runner`: Delegate selects its managed worker. A custom override
78
+ conflicting with managed workspaces or a predecessor returns `invalid_request`
79
+ with `managed_workspace_runner_conflict` or `continuation_runner_conflict`.
80
+ Correct it only under the returned task-creation guidance.
81
+
82
+ ## Teams
83
+
84
+ Teams are optional configuration managed through the CLI and stored in SQLite.
85
+ The [Teams guide](https://github.com/hishamkaram/delegation-layer/blob/main/docs/teams.md)
86
+ owns definition examples, scopes/worktrees, safe edits, optional project defaults,
87
+ availability, saved-task semantics and limitations. Do not edit the catalog as
88
+ JSON or introduce another catalog file. `--root` remains an execution-state
89
+ option; it does not select a Team catalog or initialize execution state for
90
+ management commands.
91
+
92
+ ```text
93
+ delegate teams register --scope user|project --definition FILE_OR_DASH \
94
+ [--cwd ABS] [--project-root ABS] --json
95
+ delegate teams update --scope user|project --team TEAM_ID --expected-revision N \
96
+ --definition FILE_OR_DASH [--cwd ABS] [--project-root ABS] --json
97
+ delegate teams delete --scope user|project --team TEAM_ID --expected-revision N \
98
+ [--cwd ABS] [--project-root ABS] --json
99
+ delegate teams list [--cwd ABS] [--project-root ABS] [--limit N] [--after CURSOR] --json
100
+ delegate teams show --scope user|project --team TEAM_ID \
101
+ [--cwd ABS] [--project-root ABS] --json
102
+ delegate teams default show --cwd ABS [--project-root ABS] --json
103
+ delegate teams default set --cwd ABS [--project-root ABS] \
104
+ --team-scope user|project --team TEAM_ID --json
105
+ delegate teams default clear --cwd ABS [--project-root ABS] --json
106
+ ```
107
+
108
+ - `--definition` reads a strict bounded definition from a file, or stdin when
109
+ its value is `-`. Register takes the Team ID from that definition; update
110
+ requires it to match `--team`. Update/delete require a positive current
111
+ `--expected-revision`; read it with show before deciding on a mutation.
112
+ - `--scope user` management takes no project context. `--scope project` requires
113
+ explicit `--cwd`; non-Git context also requires `--project-root`. List without
114
+ `--cwd` returns user Teams only; with context it also includes project Teams.
115
+ List defaults to 50 rows, at most 100. Pass returned `next_cursor` unchanged
116
+ as the exclusive `--after` cursor, retaining the same project context.
117
+ - Default commands always require project context. Set references a user Team
118
+ or a Team in that project. Show reports `unset`, `resolved` or `stale`;
119
+ clear is idempotent. The preference never selects a Member automatically.
120
+ - List, show and default show are passive; they neither initialize/migrate/repair
121
+ storage nor inspect provider readiness. A missing catalog lists as empty;
122
+ unreadable/corrupt storage remains an error. Safe partial listings carry
123
+ diagnostics, including unresolved project context or invalid individual rows.
124
+
125
+ Management JSON uses `schema_version: 1`, `command: "teams"`, `action`,
126
+ optional `default_action`, and `status` (`ok`, `empty`, `partial`, or `failed`).
127
+ Optional typed fields are `catalog_id`, `team`, `teams`, `next_cursor`,
128
+ `mutation`, `default`, `diagnostics`, `failure`, and `error` with
129
+ `error_truncated` when needed. Show's `team` has `reference`, `revision`,
130
+ and `definition`; list returns summaries, not complete definitions.
131
+ Register/update return `mutation.validation` with `definition: "validated"`,
132
+ `provider_capabilities: "validated"`, and `readiness: "not_checked"`.
133
+ Management never claims that a provider/model can execute.
62
134
 
63
- Managed workspaces are optional. For independent parallel writes, choose
64
- `--isolation git-worktree` unless the user explicitly chooses shared
65
- coordination. The model chooses fan-out and task scope; there is no fixed task
66
- count cap or TTL eviction. Use the canonical [workspace reference](workspaces.md)
67
- for retention, capture, release, forgetting, and review-scope rules.
135
+ Handler exit `0` means a successful read/mutation, including empty/no-default
136
+ and safe partial results. Exit `2` means invalid input/definition, an unknown
137
+ explicit target, revision conflict or project/catalog identity mismatch.
138
+ Exit `1` means operational/storage/schema failure. These do not replace task
139
+ or scheduler exit semantics. Argument errors may retain normal stderr usage
140
+ without JSON. Responses are bounded to 2 MiB; a successful mutation with output
141
+ failure is not permission to repeat it. Inspect the same target/default first.
142
+ For a revision conflict, inspect the current revision; for uncertain storage
143
+ or close errors, inspect durable state before deciding on another mutation.
68
144
 
69
- The public forms are:
145
+ ### Using a Member
146
+
147
+ The lead inspects list/show and optional project-default guidance, then passes
148
+ all three target flags on dispatch or schedule creation. Match a named provider
149
+ through the existing provider catalog; preserve exact caller model/effort IDs.
150
+ Models are advisory, not an admission allowlist. Blocked optional discovery
151
+ does not prevent registration of a valid supported definition.
152
+
153
+ Caller options override Member defaults. A provider change discards model/effort
154
+ inherited from the previous provider; explicit replacement values survive.
155
+ `--auto` conflicts with a provider-bound Member. Roles grant no permission,
156
+ budget or routing authority. Keep the requested workspace, root and permissions.
157
+ For a Local target, the canonical source project owns identity across linked
158
+ worktrees; reject a mismatch rather than retargeting.
159
+
160
+ New task IDs and new scheduled occurrences resolve latest defaults once.
161
+ Same-ID replay/recovery and exact-session continuation retain saved selection
162
+ and settings without a catalog read. Continuation accepts its existing supported
163
+ overrides but rejects new Team/Member targeting flags. Preserve explicit target
164
+ failures; no substitution or automatic retry is added. If no Team target was
165
+ requested, ordinary provider/auto delegation stays available without catalog
166
+ setup, even when there is no matching Team or project default.
167
+
168
+ ### Team task context
169
+
170
+ After a task record is created, inspect the same ID and root:
70
171
 
71
172
  ```sh
72
- delegate --root ROOT dispatch --isolation git-worktree --cwd ABS \
73
- [--base REV] [--workspace-budget DURATION] ... --json
74
- delegate --root ROOT dispatch --workspace WORKSPACE_ID ... --json
75
- delegate --root ROOT workspace list [--after ID] [--limit 1..50] --json
76
- delegate --root ROOT workspace status ID [--operation OP] [--watch DURATION] --json
77
- delegate --root ROOT workspace exec ID --budget DURATION -- ARGV...
78
- delegate --root ROOT workspace release ID [--discard] [--budget DURATION] --json
79
- delegate --root ROOT workspace forget ID [--budget DURATION] --json
173
+ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" status TASK_ID --json
174
+ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect TASK_ID --watch 5s --json
175
+ ```
176
+
177
+ Dispatch/status/collect optionally expose top-level `team`, the admitted
178
+ immutable context from the task request. It includes the scoped target and
179
+ catalog ID, Team revision, names/purpose, Roles, Member and original caller
180
+ intent. Human output includes scope, Team ID, Member ID and revision. These
181
+ reads do not consult the catalog; an edit or deletion cannot change that saved
182
+ view. This differs from the live catalog record returned by `teams show`.
183
+ The task's canonical execution fields remain authoritative. Apply normal
184
+ [result decisions](result-handling.md#task-control-response); Team context does
185
+ not prove admission, provider readiness or successful publication.
186
+
187
+ ## Schedules
188
+
189
+ The management commands below save and inspect definitions; they do not start a
190
+ scheduler, launch a provider themselves, or prove that a task ran. On builds with
191
+ [host controls](#scheduler-runtime), create/resume check for a compatible live
192
+ host after saving. When a response includes `scheduler.serve_command`, retain
193
+ the saved ID and give that argv array intact to the user for an independent
194
+ terminal or tmux pane. For run-only builds, use the
195
+ [compatibility instructions](#scheduler-runtime); do not expect those host fields.
196
+ Never start a persistent scheduler inside the agent's bounded task or submit
197
+ another create to obtain a running scheduler.
198
+ See [definition and host results](result-handling.md#schedule-definition-and-host-results).
199
+
200
+ ```text
201
+ delegate --root ROOT schedule create --brief FILE --cwd ABS \
202
+ [--auto | --provider ID] --cron 'MIN HOUR DOM MONTH DOW' \
203
+ [--timezone ZONE] [--id SCHEDULE_ID] [--model MODEL] [--effort EFFORT] \
204
+ [--permission MODE] [--budget DURATION] [--native-timeout DURATION] \
205
+ [--review-target TARGET] \
206
+ [--team-scope user|project --team TEAM_ID --member MEMBER_ID] \
207
+ [--project-root ABS] --json
208
+ delegate --root ROOT schedule list [--after SCHEDULE_ID] [--limit N] --json
209
+ delegate --root ROOT schedule show SCHEDULE_ID --json
210
+ delegate --root ROOT schedule pause SCHEDULE_ID --json
211
+ delegate --root ROOT schedule resume SCHEDULE_ID --json
212
+ delegate --root ROOT schedule delete SCHEDULE_ID --json
213
+ ```
214
+
215
+ - Requested provider options remain as supplied, including omissions. Creation
216
+ validates inputs without checking provider installation, authentication or
217
+ readiness. It does not create a managed workspace. Interactive requests,
218
+ continuation/session options and supervisor/runner overrides are unsupported.
219
+ - Optional [Member targeting](#using-a-member) follows dispatch's destination
220
+ requirements. Creation validates the target and pins its catalog instance ID,
221
+ while saving raw caller overrides/omissions. Each new occurrence resolves
222
+ latest defaults; a different catalog instance or missing target fails without
223
+ fallback. A saved target change needs a new schedule. Follow the operator
224
+ [scheduler upgrade procedure](https://github.com/hishamkaram/delegation-layer/blob/main/docs/cli-reference.md#scheduler-upgrades)
225
+ before using Team-targeted definitions; mixed-version readers are unsupported.
226
+ - Cron has five fields and minute precision. Lists, ranges, steps and month/day
227
+ names are supported. Sunday is `0` or `SUN`, not `7`. `N/step` runs from `N`
228
+ through that field's maximum. Descriptors such as `@daily`, seconds, years,
229
+ embedded timezones, `?` and Quartz extensions are unsupported.
230
+ - Day-of-month and weekday restrictions follow the cron parser: when both fields
231
+ are restricted, either may match. `*` or `*/1` makes both fields necessary;
232
+ patterned steps such as `*/2` and full restricted ranges retain the either-field
233
+ behavior. Choose explicit fields for the intended recurrence.
234
+ - `--timezone` accepts a named zone such as `Europe/Berlin` or `UTC`. Omission
235
+ captures the host/process zone at creation. Later host changes do not change
236
+ it. An empty value or `Local` is invalid; if automatic resolution fails,
237
+ supply the zone explicitly.
238
+ - Missing dates/local times are skipped without moving the appointment or
239
+ disabling the definition. February 29 runs in leap years. A repeated local
240
+ minute runs only at its first chronological occurrence. Warnings are advisory;
241
+ they do not predict every future timezone change.
242
+ - Definitions are immutable. Pause blocks future admissions; resume skips the
243
+ interval from the stored cursor through now without catch-up. A clock behind
244
+ the cursor leaves that cursor unchanged. Delete is terminal and retains
245
+ history. Pause/delete do not cancel an active occurrence or require a live
246
+ host. Create/resume preserve the saved definition even when the host is
247
+ absent, starting, in backoff or otherwise not confirmed ready.
248
+ - Only create initializes absent schedule storage. An absent store lists as
249
+ empty; show/state commands report not found. List defaults to 50 rows, at most
250
+ 100, including paused/deleted definitions. Use the returned cursor to page.
251
+ - Create/state responses are compact. Show returns saved requested choices and
252
+ brief metadata, not brief contents, with a 2 MiB response limit. Keep the ID
253
+ when output or storage reports uncertainty; inspect it with show rather than
254
+ submitting another create. Reusing an existing ID conflicts.
255
+
256
+ Handler results use exit `0` for confirmed completion/advisory warnings, `2` for
257
+ invalid input/state transitions and `1` for not-found, conflicts or operational
258
+ failures. On builds with host controls, create/resume also use exit `3` for saved
259
+ definitions needing user host start or pending host readiness; keep the same ID
260
+ and follow [result handling](result-handling.md#schedule-definition-and-host-results).
261
+ `--json` applies to handler responses; argument/usage errors retain the CLI's
262
+ normal stderr behavior. A valid rule with no future occurrence in the supported
263
+ timestamp range has a distinct range error, not a claim of permanent invalidity.
264
+
265
+ ### Schedule history and execution
266
+
267
+ ```text
268
+ delegate --root ROOT schedule history SCHEDULE_ID [--before RFC3339Nano] [--limit N] --json
269
+ delegate --root ROOT schedule execution TASK_ID --json
270
+ ```
271
+
272
+ `history` returns occurrence summaries and compact skipped intervals together,
273
+ newest first by occurrence due time or interval end. It defaults to 50 entries,
274
+ at most 100. The returned continuation timestamp is the exclusive `--before`
275
+ cursor; use it unchanged for the next page. Newer entries appear when you start
276
+ a fresh first page, not as a frozen snapshot across requests. A skip is one
277
+ stored `(from, to]` interval with a reason, not an invented task for each minute.
278
+
279
+ `execution` accepts the task ID of one scheduled occurrence, including a released
280
+ one. It joins validated local task evidence with the occurrence and its cached
281
+ observation. It does not observe live OS/provider state or infer unrecorded
282
+ events. Returned result and log descriptors refer to existing evidence; contents
283
+ are not inlined. An ordinary task without an occurrence is not a scheduled
284
+ execution.
285
+
286
+ Both commands are passive: no provider/supervisor call, task control, filesystem
287
+ capability probe, initialization, migration or repair. They work with the
288
+ scheduler running or stopped, subject to the database busy timeout. Paused and
289
+ deleted schedules retain history. An existing schedule with no history returns
290
+ an empty page; missing root, database, schedule or occurrence returns not-found.
291
+ Missing task files and corrupt evidence are distinct; see
292
+ [scheduled result handling](result-handling.md#scheduled-execution-results)
293
+ for freshness, no-result states, response bounds, exit codes and recovery.
294
+
295
+ ## Scheduler runtime
296
+
297
+ Check `delegate help` for the installed build's command surface. Use `serve`,
298
+ `status` and `stop` only when that help advertises them; prefer `serve` for managed
299
+ recovery. The signatures below describe the current command surface. Keep the
300
+ same explicit absolute `ROOT` used by the schedule commands.
301
+
302
+ ```text
303
+ delegate --root ROOT scheduler serve
304
+ delegate --root ROOT scheduler status
305
+ delegate --root ROOT scheduler stop
306
+ delegate --root ROOT scheduler run [--pueue-config ABS] [--json]
80
307
  ```
81
308
 
82
- `--workspace` cannot be combined with public `--cwd`, `--base`, or
83
- `--isolation`. `workspace exec` passes literal argv after `--` and initially
84
- returns asynchronously; exit `3` means the operation is pending. The helper
85
- budget defaults to 5m, is persisted/overridable, and does not renew the task
86
- budget. `continue --task TASK` inherits the predecessor workspace, cwd, and
87
- session while creating a new task ID. A read-only review may attach a retained
88
- workspace with `--workspace ID`.
89
-
90
- Model discovery uses the same `--provider ID` profiles and accepts an optional
91
- absolute `--cwd` (default: current directory). Its JSON has `status` values
92
- `available`, `partial`, `blocked`, `unavailable`, or `failed`; exits are `0`,
93
- `0`, `2`, `2`, and `1` respectively. `complete` describes model enumeration.
94
- Top-level or per-model `efforts: null` means unknown, while `[]` means no
95
- choices were explicitly reported. Discovery is advisory and never an admission
96
- allowlist; defaults remain valid when it is not run.
97
-
98
- Continuation flags:
99
-
100
- - `--task TASK`: predecessor task ID;
101
- - `--brief FILE`: optional new follow-up instruction;
102
- - `--budget DURATION`, `--model MODEL`, and `--effort VALUE`: optional overrides;
103
- - `--interactive`: enable interaction when supported; already-interactive predecessors keep it.
309
+ If installed help offers only `scheduler run`, the user runs
310
+ `delegate --root ROOT scheduler run` in an independent terminal or tmux pane and
311
+ leaves it in the foreground. Ctrl-C in its original pane stops it; it has no
312
+ automatic child restart. Keep the saved schedule ID and inspect
313
+ [history and execution](#schedule-history-and-execution) for actual occurrences.
314
+ Do not issue unsupported `scheduler status` or `scheduler stop` commands, or
315
+ expect `start_required` or `scheduler.serve_command` fields from that build.
316
+ The managed-host controls and response fields below apply only when installed
317
+ help supports them.
318
+
319
+ The user starts one foreground `serve` host per canonical execution root in an
320
+ independent terminal or tmux pane and leaves it running. It manages every saved
321
+ schedule in that root. When returned, agents give the exact
322
+ `scheduler.serve_command` argv array to the user. Agents must not start either
323
+ persistent scheduler command inside their own bounded task. The guard recognizes
324
+ an explicit Delegate task-scope marker and, on Linux, native Delegate
325
+ cgroup membership. It does not reconstruct guardian ownership or detect every
326
+ enclosing ancestor. A successful check or missing marker does not prove
327
+ independent placement; independent user launch remains required. Delegate
328
+ installs no OS service, enables no reboot/login startup and
329
+ does not automatically launch a detached host.
330
+
331
+ When present, `scheduler.serve_command` preserves spaces and shell metacharacters
332
+ as separate arguments. Human output also prints JSON argv, not an unquoted shell string.
333
+ Preserve those boundaries; see the [scheduler response fields](result-handling.md#schedule-definition-and-host-results).
334
+
335
+ Serve requires existing schedule storage; create owns initialization. A second
336
+ host or competing `run` cannot acquire the same root's ownership. The host uses
337
+ its retained launch context and the saved requested provider choices. For
338
+ Team-targeted schedules, new occurrences read the pinned catalog's latest Member
339
+ defaults through normal admission; existing task IDs retain saved settings. Use
340
+ the intended user configuration context, or a different catalog instance fails
341
+ admission even when Team/Member IDs match. Context changes require completed stop
342
+ and a fresh user start; full launch environments are not persisted.
343
+
344
+ While the host lives, it restarts its scheduler child after an unexpected exit,
345
+ including a clean exit while running is still desired. A successful Start needs
346
+ its exact child Wait before replacement; a definitively failed Start that
347
+ created no child may retry without Wait. Retry delays are 1, 2, 4, 8, 16, 30, 60,
348
+ 120 and 300 seconds, capped at five minutes indefinitely. Five continuous healthy
349
+ minutes reset the policy;
350
+ elapsed healthy time and delays use monotonic timing. Create/resume/status do not
351
+ reset cooldown. A live but unready child or uncertain launch is not replaced.
352
+ Before the child reports Ready or scans for due work, the application's
353
+ before-Ready check validates every current saved definition. An incompatible
354
+ definition leaves the host degraded and stops automatic child restart for that
355
+ incompatibility; it does not enter an endless crash/retry loop. Preserve the
356
+ saved definitions and report the compatibility fault.
357
+ If the host, terminal/tmux pane or machine stops, automatic recovery ends; the
358
+ user must run serve again.
359
+
360
+ `scheduler status` is passive: it does not start, migrate, repair or clean
361
+ anything. It observes starting, ready, backoff, degraded, stopping or stopped
362
+ state, or a compatibility runtime's `foreground` generation, and available
363
+ attempt, bounded diagnostic and retry information. Optional
364
+ `scheduler.fault: true` is the host owner's permanent fault decision; degraded state or
365
+ `last_error` alone is not that decision. After a definition is saved,
366
+ transport-only unreachability returns pending exit `3` without a top-level
367
+ `error`; a permanent host fault returns exit `1`, retaining
368
+ `schedule.saved: true` and the same ID.
369
+
370
+ `scheduler stop` persists a stopped fence, interrupts backoff, ends admission and
371
+ joins accepted controls, GoCron shutdown and child Wait. The host remains
372
+ responsive to authenticated status/stop while joining its child or waiting for a
373
+ prior execution owner. Under host ownership, it writes a closure witness once
374
+ execution ownership is free. Completed stop requires that witness and exact
375
+ host absence; acceptance, timeout or host death alone is not completion.
376
+ Authenticated acceptance remains visible even if later readback fails; concrete
377
+ faults remain visible too. SIGINT, SIGTERM and SIGHUP use the same fenced shutdown
378
+ path. Independently admitted tasks retain their own supervisors and budgets.
379
+ See [host result decisions](result-handling.md#schedule-definition-and-host-results).
380
+
381
+ `scheduler run` runs the foreground runtime directly and remains a compatibility
382
+ path without automatic child restart. On builds with host controls, it shares
383
+ root ownership with serve and announces its current foreground generation,
384
+ which an older managed-host stop
385
+ receipt cannot hide. Status reports `scheduler.state: foreground`.
386
+ `scheduler stop` does not terminate the raw invocation: it returns
387
+ `stop_accepted: false` and `next_action: stop_foreground_runtime`. The user ends
388
+ it with Ctrl-C in its original pane; prefer `scheduler serve` for managed
389
+ recovery. The existing manual OS-service hosting option is separate from the new
390
+ foreground host path; see [operator hosting](https://github.com/hishamkaram/delegation-layer/blob/main/docs/cli-reference.md#scheduler-hosting).
391
+
392
+ Serve and run require the automatic managed worker. Use colocated `delegate`
393
+ and `delegate-run` binaries from the same build and omit the advanced `--runner`
394
+ override. An override selects custom ownership even when it names the bundled
395
+ worker. `scheduler run` rejects it with exit `2` before opening storage or
396
+ acquiring a lease. `scheduler serve` checks existing state and schedule storage
397
+ before rejecting the override with exit `2`, so a storage error can take
398
+ precedence. Ordinary explicit custom-runner dispatch and continuation retain their
399
+ existing compatibility rules. Historical custom-runner claims are not
400
+ automatically repaired or released.
401
+
402
+ Startup skips past appointments. Expired, overlapping or capacity-limited
403
+ appointments are skipped with a recorded reason; no catch-up queue or automatic
404
+ provider retry/continuation is added. Downtime is recorded in compact skipped
405
+ intervals, never replayed minute by minute. Pause/delete prevent new claims,
406
+ without canceling already claimed tasks. Use [history and execution](#schedule-history-and-execution)
407
+ to inspect recorded work, and [result handling](result-handling.md#scheduled-execution-results)
408
+ to collect its answer. Schedule reservation release is separate from result
409
+ publication.
410
+
411
+ Each appointment starts a fresh leader with its saved budget or the normal
412
+ provider default. Overlap protection covers that leader. Independently admitted
413
+ Delegate workers keep their own budgets; provider-native in-session subagents do
414
+ not acquire independent Delegate lifetimes. The workflow owns saved progress,
415
+ worker IDs and deduplication; unknown acknowledgment is not permission to resend.
416
+
417
+ Interrupting the compatibility runtime joins its admission/control work before
418
+ releasing its owner lease. Accepted lifecycle calls settle independently of the stop signal;
419
+ there is no shutdown-time guarantee. Already admitted tasks continue under their
420
+ own supervisors. The compatibility command reports bounded identifiers/codes on
421
+ stderr; `--json` selects the final command response, not an event stream or
422
+ daemon-control protocol. Uncertain task
423
+ evidence blocks only its schedule until the existing owners can prove closure.
424
+
425
+ ## Codex review
426
+
427
+ For explicit native code review, select `codex:review` and one persisted
428
+ target: `uncommitted`, `base:BRANCH`, or `commit:SHA`. It is read-only
429
+ and supports neither `--interactive` nor continuation. Use `codex:exec`
430
+ for general investigation or edits. The brief is retained as task evidence;
431
+ Codex's native target flag supplies review scope because it cannot be combined
432
+ with a native prompt.
433
+
434
+ An `uncommitted` review includes current staged, unstaged, and untracked
435
+ changes, but excludes worker commits. For a complete managed turn use an
436
+ ordinary read-only task with sealed base/tree refs and `git diff BASE TREE`.
437
+ Preserve an explicitly requested narrower native target. See
438
+ [workspace review scope](workspaces.md#recovery-and-review-scope).
439
+
440
+ ## Managed workspace commands
441
+
442
+ [Workspaces](workspaces.md#public-commands) owns creation, attachment, helper
443
+ budgets, capture, review, release, and forgetting. Use managed worktrees for
444
+ independent parallel writes unless the user explicitly chooses shared coordination.
104
445
 
105
446
  ## Checkpoint commands
106
447
 
107
- Git checkpoints are optional and launch no provider work. Use them to fork a
108
- worker from current uncommitted content; the canonical
109
- [checkpoint guidance](workspaces.md#git-checkpoints) owns targets, limits, and
110
- the checkpoint-before-fork sequence, and
111
- [checkpoint results](result-handling.md#checkpoint-results) owns the decisions.
448
+ [Git checkpoints](workspaces.md#git-checkpoints) owns commands and limits;
449
+ [checkpoint results](result-handling.md#checkpoint-results) owns decisions.
450
+ A checkpoint is Git-content evidence, not a provider outcome.
451
+
452
+ ## Providers and capabilities
112
453
 
113
454
  ```sh
114
- delegate --root ROOT checkpoint create --cwd ABS [--budget DURATION] --json
115
- delegate --root ROOT checkpoint create --workspace ID [--budget DURATION] --json
116
- delegate --root ROOT checkpoint status CHECKPOINT_ID [--operation OP] [--watch DURATION] --json
117
- delegate --root ROOT checkpoint list [--after CHECKPOINT_ID] [--limit 1..50] --json
118
- delegate --root ROOT checkpoint remove CHECKPOINT_ID [--budget DURATION] --json
455
+ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" providers --json
456
+ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" capabilities --provider PROVIDER_ID --json
119
457
  ```
120
458
 
121
- `create` takes exactly one of `--cwd` or `--workspace`. `--operation` selects a
122
- removal attempt ID returned by `remove`; without it, `status` observes the
123
- creation and its latest removal. `list` pages with the returned
124
- `checkpoint_cursor` as `--after`.
459
+ `providers` returns `schema_version: 1` and a sorted `providers` array.
460
+ Each entry exposes `id`, `supported_modes`, `supported_options`, any
461
+ `required_options`, `continuation`, `read_only`, `interaction`, and
462
+ `runtime` metadata. Supply every required option:
463
+ `ccr:print` requires a configured CCR model alias; `codex:review` requires
464
+ a review target. See [CCR](ccr.md).
465
+
466
+ These commands create no task or state, contact no supervisor, and launch no
467
+ provider. The capability envelope has `schema_version: 1`,
468
+ `command: "capabilities"`, and `capability`. Its catalog projection uses
469
+ `contract: "runtime-capability-v1"`, `status: "unknown"`,
470
+ `verification: "catalog"`, and `live_acceptance.status: "not_run"`.
471
+ It describes compiled support, not installation, authentication, or host readiness.
472
+
473
+ `read_only.containment: "provider-owned"` describes native permissions,
474
+ separately from guardian-owned process lifetime. Runtime metadata lists required
475
+ help/flag behavior. Required native behavior determines compatibility;
476
+ provider versions are optional diagnostics.
477
+
478
+ Inspection-backed admission can return `status: "ready"` with
479
+ `verification: "runtime"` after its probe. Managed runtime-only admission
480
+ keeps the catalog projection; its supervised worker checks compatibility before
481
+ provider execution. Collect the created task to establish the result.
482
+ Optional protocol members `version` and `executable_sha256` are diagnostics,
483
+ not launch authority. Live acceptance remains separate (`not_run`, `passed`,
484
+ or `blocked`); a blocked prerequisite is unresolved.
125
485
 
126
486
  ## Choosing models and effort
127
487
 
128
- Pass an explicitly supplied model ID and effort unchanged, even if discovery
129
- is incomplete or does not list them. To resolve a natural-language model name
130
- or choose an option the caller left open, use native discovery:
488
+ Pass exact requested model IDs and effort unchanged, even if discovery omits
489
+ them. Keep defaults when no explicit choice is needed. Resolve a natural-language
490
+ name through native discovery:
131
491
 
132
492
  ```sh
133
493
  delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" models \
134
494
  --provider PROVIDER_ID --cwd ABSOLUTE_WORKSPACE --json
135
495
  ```
136
496
 
137
- Omit `--cwd` to use the current directory. Run discovery only when the caller
138
- needs a non-default choice; provider defaults are valid. The command uses the
139
- state-rooted supervisor and a bounded `model-discovery-v1` five-minute native
140
- inspection to allow first-run provider model/cache initialization. It creates
141
- inspection evidence without admitting a provider task, and may contact the
142
- provider CLI. It is advisory and never an admission allowlist. Do not reject a
143
- requested value merely because discovery did not list it, and do not infer
144
- per-model effort support from the harness-wide list. If a selected model has
145
- `efforts: null` or `efforts: []`, omit `--effort` unless the caller explicitly
146
- requested it; do not invent model aliases or combine options by guessing.
147
- If a natural-language name cannot be resolved to a single exact ID, ask one
148
- focused question for that ID. Do not silently select a default or transform
149
- spaces into hyphens to manufacture an ID. This ambiguity rule is guidance for
150
- selecting a value, not a new admission restriction.
151
-
152
- The response includes `schema_version`, `command: "models"`, `provider`,
497
+ If discovery cannot resolve a name to one exact ID, ask for that ID; never
498
+ manufacture an alias. An explicit ID needs no clarification just because it
499
+ is absent from discovery.
500
+
501
+ `--cwd` defaults to the current directory. Discovery uses the state-rooted
502
+ supervisor and a `model-discovery-v1` five-minute native inspection, allowing
503
+ first-run model/cache initialization. It may contact the provider, creates
504
+ inspection evidence, and admits no provider task. `codex:review` has no
505
+ model-discovery command.
506
+
507
+ The JSON envelope has `schema_version`, `command: "models"`, `provider`,
153
508
  `observed_at`, `status`, `reason_code`, `complete`, `source`, nullable
154
- `efforts`, and model rows with exact `id` values plus optional `name`, nullable
155
- `efforts`, and optional `default_effort`. `complete` describes model
156
- enumeration, not effort metadata. `null` means effort metadata is unknown;
157
- `[]` means the provider explicitly reported no choices. Discovery exits `0`
158
- for `available` or `partial`, `2` for `blocked` or `unavailable`, and `1` for
159
- `failed`. Preserve a blocked or unavailable discovery result as unresolved;
160
- defaults remain allowed. An operational discovery failure also includes an
161
- optional `failure` object and a fixed `error` message; keep both fields and
162
- follow `failure.next_action`.
509
+ `efforts`, and `models`. Rows have exact `id`, optional `name`, nullable
510
+ `efforts`, and optional `default_effort`.
511
+
512
+ `complete` describes enumeration, not effort knowledge. `efforts: null`
513
+ means unknown; `[]` means explicitly no choices. Do not apply harness-wide
514
+ efforts to every model. Omit effort for unknown/empty per-model metadata unless
515
+ explicitly requested. A listed model does not prove execution access;
516
+ discovery is advisory, never an admission allowlist.
517
+
518
+ | Status | Exit | Interpretation |
519
+ | --- | --- | --- |
520
+ | `available` or `partial` | `0` | Observed model facts; partial enumeration is incomplete. |
521
+ | `blocked` or `unavailable` | `2` | Unresolved prerequisite. |
522
+ | `failed` | `1` | Operational discovery failure. |
523
+ | `failed` | `2` | Invalid or unsupported request, such as invalid cwd or root/workspace overlap; not an authentication block. |
524
+
525
+ Validate the whole envelope. Keep optional typed `failure` and fixed `error`
526
+ with the result; follow `failure.next_action`, stopping on `stop_and_report`.
527
+ Supervisor refusals retain `supervisor_migration_blocked`,
528
+ `supervisor_migration_unsupported`, or `supervisor_upgrade_required` as
529
+ reason codes and return no model facts.
163
530
 
164
531
  ## Checking readiness
165
532
 
166
- Use `preflight` when the caller asks about static readiness, rather than as a
167
- required step before every dispatch:
533
+ Use static preflight when readiness was requested, not before every task:
168
534
 
169
535
  ```sh
170
536
  delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" preflight \
@@ -172,11 +538,9 @@ delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" preflight \
172
538
  --permission REQUESTED_MODE --json
173
539
  ```
174
540
 
175
- Use `read-only` for investigation or `workspace-write` for authorized edits.
176
- Supply any required provider options, including `--model ALIAS` for `ccr:print`
177
- and `--review-target TARGET` for `codex:review`.
178
- Preflight does not create a task, start the supervisor, or launch a provider.
179
- Its result is not proof of live authentication or successful execution. Report
180
- `blocked` or `unsupported` results; a readiness request does not authorize
181
- provider configuration changes. Honor `failure.next_action` without probing
182
- provider CLIs yourself.
541
+ Supply required options; the supported request options also include budget,
542
+ model, effort, native timeout, and review target where advertised.
543
+ Preflight creates no task, starts no supervisor, and launches no provider.
544
+ A ready `verification: "preflight"` result is not live authentication or
545
+ execution proof. Report blocked/unsupported results and follow the returned
546
+ guidance; readiness checks do not authorize provider configuration changes.