delegation-layer 0.2.0 → 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.
- package/README.md +5 -0
- package/docs/assets/delegation-layer-hero.jpg +0 -0
- package/package.json +1 -1
- package/plugins/delegation-layer/.claude-plugin/plugin.json +1 -1
- package/plugins/delegation-layer/.codex-plugin/plugin.json +1 -1
- package/plugins/delegation-layer/skills/agent-integration/examples/managed-workspace.md +25 -7
- package/plugins/delegation-layer/skills/agent-integration/references/ccr.md +7 -4
- package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +123 -26
- package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +60 -0
- package/skills/agent-integration/examples/managed-workspace.md +25 -7
- package/skills/agent-integration/references/ccr.md +7 -4
- package/skills/agent-integration/references/command-reference.md +123 -26
- package/skills/agent-integration/references/result-handling.md +60 -0
package/README.md
CHANGED
|
@@ -8,6 +8,7 @@ and retrieving results with evidence.
|
|
|
8
8
|
· [Example](#ask-naturally)
|
|
9
9
|
· [Providers](https://github.com/hishamkaram/delegation-layer/blob/main/docs/providers.md)
|
|
10
10
|
· [Teams](https://github.com/hishamkaram/delegation-layer/blob/main/docs/teams.md)
|
|
11
|
+
· [Start recurring tasks](docs/getting-started.md#recurring-tasks)
|
|
11
12
|
· [Docs](https://github.com/hishamkaram/delegation-layer/blob/main/docs/README.md)
|
|
12
13
|
|
|
13
14
|
<p align="center">
|
|
@@ -55,6 +56,10 @@ for activation and limits.
|
|
|
55
56
|
For a manual CLI task, use the packaged
|
|
56
57
|
[read-only example](skills/agent-integration/examples/read-only-task.md).
|
|
57
58
|
|
|
59
|
+
For recurring work, follow the [scheduler walkthrough](docs/getting-started.md#recurring-tasks)
|
|
60
|
+
to save a definition, start the scheduler in your own terminal or tmux pane,
|
|
61
|
+
inspect its first result and stop or restart it.
|
|
62
|
+
|
|
58
63
|
## Help and contributing
|
|
59
64
|
|
|
60
65
|
See [troubleshooting](https://github.com/hishamkaram/delegation-layer/blob/main/docs/troubleshooting.md),
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delegation-layer",
|
|
3
3
|
"displayName": "Delegation Layer",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.3.0",
|
|
5
5
|
"description": "Consult external AI harnesses and CCR-configured models for reviews, research, implementation, and debate through the resumable Delegate CLI.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Hesham Karam",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delegation-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Consult external AI harnesses and CCR-configured models for reviews, research, implementation, and debate through the resumable Delegate CLI.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Hesham Karam",
|
|
@@ -34,17 +34,34 @@ else
|
|
|
34
34
|
status_exit=$?
|
|
35
35
|
fi
|
|
36
36
|
printf '%s\n' "$status_exit" >"$RESPONSE.status.exit"
|
|
37
|
+
cat "$RESPONSE.status"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Read the saved status JSON and apply
|
|
41
|
+
[Observe and collect](../references/result-handling.md#observe-and-collect)
|
|
42
|
+
before running another command. Run the collection below only when that
|
|
43
|
+
guidance calls for it.
|
|
44
|
+
|
|
45
|
+
```sh
|
|
37
46
|
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect TASK_ID --watch 5s --json >"$RESPONSE.collect"; then
|
|
38
47
|
collect_exit=0
|
|
39
48
|
else
|
|
40
49
|
collect_exit=$?
|
|
41
50
|
fi
|
|
42
51
|
printf '%s\n' "$collect_exit" >"$RESPONSE.collect.exit"
|
|
52
|
+
cat "$RESPONSE.collect"
|
|
43
53
|
```
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
Apply that same decision order to the collection JSON before treating exit `3`
|
|
56
|
+
as pending. Cancellation, `failure.code: "task_cancelled"` or
|
|
57
|
+
`failure.next_action: "stop_and_report"` ends pending polling; do not continue
|
|
58
|
+
the task or dispatch a replacement. Bounded
|
|
59
|
+
[failure diagnosis](../references/result-handling.md#failure-diagnosis)
|
|
60
|
+
remains available. Keep observing the same task with a finite watch only when
|
|
61
|
+
the canonical guidance calls for it.
|
|
62
|
+
|
|
63
|
+
Before release, wait for the workspace to return to `state: retained` and inspect
|
|
64
|
+
its final capture. Only after the Lead explicitly chooses release, run:
|
|
48
65
|
|
|
49
66
|
```sh
|
|
50
67
|
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" workspace release WORKSPACE_ID \
|
|
@@ -62,10 +79,11 @@ Follow the same result decisions rather than assuming either response is
|
|
|
62
79
|
completed cleanup.
|
|
63
80
|
|
|
64
81
|
Save each response and exit code once. A created task is observed with
|
|
65
|
-
`status` first and collected in the foreground
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
apply, commit, branch merge,
|
|
82
|
+
`status` first and collected in the foreground, following the canonical
|
|
83
|
+
observation decisions before each next step. Exit `3` alone is not a reason
|
|
84
|
+
to keep polling. The Lead reviews the capture and owns landing any changes.
|
|
85
|
+
`workspace release` is explicit; no automatic apply, commit, branch merge,
|
|
86
|
+
TTL eviction, or provider-CLI fallback occurs.
|
|
69
87
|
|
|
70
88
|
## Fork from a checkpoint
|
|
71
89
|
|
|
@@ -3,18 +3,21 @@
|
|
|
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
8
|
|
|
7
9
|
1. Resolve CCR through `delegate providers --json`; its profile is `ccr:print`.
|
|
8
10
|
2. Preserve an explicitly requested CCR alias as `--model ALIAS`. Do not replace
|
|
9
11
|
it with an upstream model ID or reject it solely because discovery omitted it.
|
|
10
12
|
3. If no alias was chosen, run
|
|
11
|
-
`delegate models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
|
|
13
|
+
`delegate --root ROOT models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
|
|
12
14
|
Choose a suitable configured alias from the available metadata and report
|
|
13
15
|
the choice. Clarify when the intended model remains ambiguous. If discovery
|
|
14
16
|
is unavailable and no alias is known, report the blocker; do not guess.
|
|
15
|
-
4. Dispatch through Delegate with
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
4. Dispatch through Delegate with the same `--root ROOT`,
|
|
18
|
+
`--provider ccr:print --model ALIAS`, the brief, workspace, permission, finite
|
|
19
|
+
budget, and `--json`. Use the normal status, collect, and continuation procedure
|
|
20
|
+
from the main skill.
|
|
18
21
|
|
|
19
22
|
CCR requires an explicit alias. Unspecified external collaboration still uses
|
|
20
23
|
`dispatch --auto`; do not prefer CCR unless the request calls for it. Multiple
|
|
@@ -22,7 +22,7 @@ The main skill owns [root selection](../SKILL.md#3-prepare-separate-paths-and-a-
|
|
|
22
22
|
| `workspace`, `checkpoint` | [Git resources](workspaces.md) | Helpers, not provider turns |
|
|
23
23
|
| `teams` | [Optional configuration and Member selection](#teams) | None |
|
|
24
24
|
| `schedule` | [Recurring definitions](#schedules), [history and execution evidence](#schedule-history-and-execution) | None |
|
|
25
|
-
| `scheduler run` | [
|
|
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 |
|
|
26
26
|
|
|
27
27
|
Prefix every task command with `delegate --root ROOT`, using the same
|
|
28
28
|
explicit root across invocations.
|
|
@@ -186,9 +186,16 @@ not prove admission, provider readiness or successful publication.
|
|
|
186
186
|
|
|
187
187
|
## Schedules
|
|
188
188
|
|
|
189
|
-
The management commands below save and inspect definitions
|
|
190
|
-
|
|
191
|
-
[
|
|
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).
|
|
192
199
|
|
|
193
200
|
```text
|
|
194
201
|
delegate --root ROOT schedule create --brief FILE --cwd ABS \
|
|
@@ -235,7 +242,9 @@ delegate --root ROOT schedule delete SCHEDULE_ID --json
|
|
|
235
242
|
- Definitions are immutable. Pause blocks future admissions; resume skips the
|
|
236
243
|
interval from the stored cursor through now without catch-up. A clock behind
|
|
237
244
|
the cursor leaves that cursor unchanged. Delete is terminal and retains
|
|
238
|
-
history. Pause/delete do not cancel an active occurrence
|
|
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.
|
|
239
248
|
- Only create initializes absent schedule storage. An absent store lists as
|
|
240
249
|
empty; show/state commands report not found. List defaults to 50 rows, at most
|
|
241
250
|
100, including paused/deleted definitions. Use the returned cursor to page.
|
|
@@ -244,8 +253,11 @@ delegate --root ROOT schedule delete SCHEDULE_ID --json
|
|
|
244
253
|
when output or storage reports uncertainty; inspect it with show rather than
|
|
245
254
|
submitting another create. Reusing an existing ID conflicts.
|
|
246
255
|
|
|
247
|
-
Handler results use exit `0` for
|
|
248
|
-
input/state transitions and `1` for not-found, conflicts or operational
|
|
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).
|
|
249
261
|
`--json` applies to handler responses; argument/usage errors retain the CLI's
|
|
250
262
|
normal stderr behavior. A valid rule with no future occurrence in the supported
|
|
251
263
|
timestamp range has a distinct range error, not a claim of permanent invalidity.
|
|
@@ -282,31 +294,116 @@ for freshness, no-result states, response bounds, exit codes and recovery.
|
|
|
282
294
|
|
|
283
295
|
## Scheduler runtime
|
|
284
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
|
+
|
|
285
302
|
```text
|
|
303
|
+
delegate --root ROOT scheduler serve
|
|
304
|
+
delegate --root ROOT scheduler status
|
|
305
|
+
delegate --root ROOT scheduler stop
|
|
286
306
|
delegate --root ROOT scheduler run [--pueue-config ABS] [--json]
|
|
287
307
|
```
|
|
288
308
|
|
|
289
|
-
|
|
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`
|
|
290
393
|
and `delegate-run` binaries from the same build and omit the advanced `--runner`
|
|
291
394
|
override. An override selects custom ownership even when it names the bundled
|
|
292
|
-
worker
|
|
293
|
-
lease.
|
|
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
|
|
294
399
|
existing compatibility rules. Historical custom-runner claims are not
|
|
295
400
|
automatically repaired or released.
|
|
296
401
|
|
|
297
|
-
This foreground command requires existing schedule storage. One process owns
|
|
298
|
-
each root; a second fails busy. It uses the service launch environment and the
|
|
299
|
-
saved requested provider choices. Saving a definition never starts the service.
|
|
300
|
-
For Team-targeted schedules, new occurrences read the pinned catalog's latest
|
|
301
|
-
Member defaults through normal admission; existing task IDs retain saved settings.
|
|
302
|
-
Use the same intended user configuration context as creation, or a different
|
|
303
|
-
catalog instance fails admission even when Team/Member IDs match.
|
|
304
|
-
See [operator hosting](https://github.com/hishamkaram/delegation-layer/blob/main/docs/cli-reference.md#scheduler-hosting).
|
|
305
|
-
|
|
306
402
|
Startup skips past appointments. Expired, overlapping or capacity-limited
|
|
307
403
|
appointments are skipped with a recorded reason; no catch-up queue or automatic
|
|
308
|
-
retry/continuation is added.
|
|
309
|
-
|
|
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)
|
|
310
407
|
to inspect recorded work, and [result handling](result-handling.md#scheduled-execution-results)
|
|
311
408
|
to collect its answer. Schedule reservation release is separate from result
|
|
312
409
|
publication.
|
|
@@ -317,12 +414,12 @@ Delegate workers keep their own budgets; provider-native in-session subagents do
|
|
|
317
414
|
not acquire independent Delegate lifetimes. The workflow owns saved progress,
|
|
318
415
|
worker IDs and deduplication; unknown acknowledgment is not permission to resend.
|
|
319
416
|
|
|
320
|
-
Interrupting the
|
|
321
|
-
owner lease. Accepted lifecycle calls settle independently of the stop signal;
|
|
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;
|
|
322
419
|
there is no shutdown-time guarantee. Already admitted tasks continue under their
|
|
323
|
-
own supervisors. The
|
|
324
|
-
|
|
325
|
-
|
|
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
|
|
326
423
|
evidence blocks only its schedule until the existing owners can prove closure.
|
|
327
424
|
|
|
328
425
|
## Codex review
|
|
@@ -166,6 +166,66 @@ asking again, but never infer it from a rejection or silently substitute a
|
|
|
166
166
|
destination. Keep the original failed attempt reported as failed; independent
|
|
167
167
|
requests and explicitly allowed recovery paths retain their existing rules.
|
|
168
168
|
|
|
169
|
+
## Schedule definition and host results
|
|
170
|
+
|
|
171
|
+
Use the installed build's help to check `scheduler serve/status/stop` support.
|
|
172
|
+
Keep three facts separate: the definition was
|
|
173
|
+
saved, the host is ready, and an occurrence produced an accepted provider result.
|
|
174
|
+
Neither saving nor host readiness proves that a task ran.
|
|
175
|
+
|
|
176
|
+
Schedule create/resume report confirmed persistence as `schedule.saved: true`;
|
|
177
|
+
keep `schedule.id` even if the command exits nonzero. The separate top-level
|
|
178
|
+
`scheduler` object carries host observation and guidance:
|
|
179
|
+
|
|
180
|
+
| JSON field | Meaning |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| `scheduler.state` | Observed lifecycle or availability state, including `foreground` for a current raw `scheduler run`. Read it with `ready` and the process exit. |
|
|
183
|
+
| `scheduler.epoch`, `scheduler.attempt` | Owner generation string and numeric child attempt, when known. Omission does not identify an owner. |
|
|
184
|
+
| `scheduler.ready` | Whether this observation confirms host/child readiness; it is not an occurrence result. |
|
|
185
|
+
| `scheduler.fault` | Optional `true` for a permanent fault reported by the host owner. Do not infer it from degraded state or `last_error`; omission is not proof that the whole command is fault-free. |
|
|
186
|
+
| `scheduler.next_retry_at` | Optional next retry timestamp during recovery. Observation does not reset it. |
|
|
187
|
+
| `scheduler.last_error` | Optional bounded host diagnostic. Keep it alongside pending or readiness facts. |
|
|
188
|
+
| `scheduler.next_action` | Caller guidance, such as `start_required`, `inspect_scheduler` or `stop_foreground_runtime`. |
|
|
189
|
+
| `scheduler.serve_command` | Optional exact argv array for an independent user start. Preserve every element and its argument boundary. |
|
|
190
|
+
| `scheduler.stop_accepted` | Optional boolean for acceptance of this stop request. `true` is accepted, `false` is explicitly not accepted, and omission is unknown. Acceptance does not prove shutdown completed. |
|
|
191
|
+
|
|
192
|
+
For `start_required`, both `schedule.next_action` and `scheduler.next_action`
|
|
193
|
+
carry that guidance. `scheduler.serve_command` is JSON argv, including the
|
|
194
|
+
resolved executable and exact root. Human output also prints JSON argv after
|
|
195
|
+
`run independently (argv):`, for example:
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
run independently (argv): ["/installation with spaces/delegate","--root","/state with spaces","scheduler","serve"]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Forward the array intact. It is not an unquoted shell command: do not join its
|
|
202
|
+
elements with spaces or pass the joined text through a shell. The user starts
|
|
203
|
+
serve independently with those exact argument boundaries; the agent must not
|
|
204
|
+
execute it inside its bounded task. An omitted `schedule.saved` does not confirm
|
|
205
|
+
persistence; preserve any ID and follow the reported storage/error guidance.
|
|
206
|
+
|
|
207
|
+
| Response or observation | Next action |
|
|
208
|
+
| --- | --- |
|
|
209
|
+
| Create/resume saved the definition and confirmed a compatible ready host; exit `0` | Keep its schedule ID/root. The host will handle future due work; use history/execution for actual occurrence evidence. |
|
|
210
|
+
| Create/resume returns exit `3`, `schedule.saved: true` and `scheduler.next_action: start_required` | The definition remains saved. Preserve the returned schedule ID/root and give `scheduler.serve_command` unchanged to the user to run in an independent terminal or tmux pane. Never start it inside the agent's bounded task, detach it in the background, or submit another create. |
|
|
211
|
+
| Create/resume saved the definition but reports starting, backoff or pending readiness; exit `3` | Keep the same ID and report its host state and available retry time. Use passive scheduler status for later observation; do not create another definition, start a competing host or reset cooldown. |
|
|
212
|
+
| Create/resume saved the definition but the host is temporarily unreachable; exit `3`, pending guidance and no top-level `error` | Preserve `schedule.saved: true` and the same ID. Use passive status to observe the uncertainty. A transport failure does not establish owner death or a permanent host fault. |
|
|
213
|
+
| Create/resume saved the definition and the host reports `scheduler.fault: true`; exit `1` | Report the permanent fault and available `scheduler.last_error`; retain `schedule.saved: true` and the ID. For an incompatible saved definition, the before-Ready check stops automatic child restart. Repeated create, serve or status calls are not a repair. |
|
|
214
|
+
| Scheduler status observes starting, ready, backoff, degraded, stopping or stopped; exit `0` | Observation completed. Report the observed state; exit `0` does not mean ready or that an occurrence succeeded. Status does not start, migrate, repair or clean resources. |
|
|
215
|
+
| Scheduler stop confirms completed stop; exit `0` | The exact stopped intent has a validated owner-written closure witness and the exact host is absent. The witness follows joined child shutdown and free execution ownership. Independently admitted tasks keep their existing lifetimes. A later host needs a fresh explicit user-run serve command. |
|
|
216
|
+
| Scheduler stop has `scheduler.stop_accepted: true` but completion is pending; exit `3` | Preserve its acceptance and pending state. The host remains control-responsive while joining its child or waiting for a prior execution owner. Host death before the closure witness does not complete stop. Observe the same generation; do not claim stopped, launch a replacement or repeat schedule creation. An omitted `stop_accepted` is unknown, not false. |
|
|
217
|
+
| Scheduler stop has authenticated `scheduler.stop_accepted: true` and a later readback fault; exit `1` | Preserve the accepted fact and report the concrete fault. Readback failure does not revoke acceptance or establish completed shutdown. |
|
|
218
|
+
| Status reports `scheduler.state: foreground`, or stop returns exit `3` with that state, `stop_accepted: false` and `next_action: stop_foreground_runtime` | The current compatibility `scheduler run` owns this generation; an older managed-host receipt cannot hide it. Public stop does not terminate it. Have the user end that invocation with Ctrl-C in its original pane. Prefer managed `scheduler serve` afterward. |
|
|
219
|
+
| Invalid input/state; exit `2`, or concrete operational/compatibility/cleanup fault; exit `1` | Report the error and retain any saved ID or accepted-control fact. A concrete fault joined to pending work remains a fault; it is not a pending-only result. |
|
|
220
|
+
|
|
221
|
+
If the host dies, its pane closes or the machine reboots, the user must start
|
|
222
|
+
serve again. Child crash recovery applies only while that host remains alive.
|
|
223
|
+
An absent heartbeat or unresponsive endpoint is uncertainty, not permission to
|
|
224
|
+
replace an owner. Do not install a service or invoke a detached bootstrap as a
|
|
225
|
+
recovery step. Pause/delete affect future claims and need no live host; they do
|
|
226
|
+
not cancel already admitted occurrences. [Scheduler runtime](command-reference.md#scheduler-runtime)
|
|
227
|
+
owns launch, backoff and calendar behavior.
|
|
228
|
+
|
|
169
229
|
## Scheduled execution results
|
|
170
230
|
|
|
171
231
|
Use [schedule history and execution](command-reference.md#schedule-history-and-execution)
|
|
@@ -34,17 +34,34 @@ else
|
|
|
34
34
|
status_exit=$?
|
|
35
35
|
fi
|
|
36
36
|
printf '%s\n' "$status_exit" >"$RESPONSE.status.exit"
|
|
37
|
+
cat "$RESPONSE.status"
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Read the saved status JSON and apply
|
|
41
|
+
[Observe and collect](../references/result-handling.md#observe-and-collect)
|
|
42
|
+
before running another command. Run the collection below only when that
|
|
43
|
+
guidance calls for it.
|
|
44
|
+
|
|
45
|
+
```sh
|
|
37
46
|
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" collect TASK_ID --watch 5s --json >"$RESPONSE.collect"; then
|
|
38
47
|
collect_exit=0
|
|
39
48
|
else
|
|
40
49
|
collect_exit=$?
|
|
41
50
|
fi
|
|
42
51
|
printf '%s\n' "$collect_exit" >"$RESPONSE.collect.exit"
|
|
52
|
+
cat "$RESPONSE.collect"
|
|
43
53
|
```
|
|
44
54
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
Apply that same decision order to the collection JSON before treating exit `3`
|
|
56
|
+
as pending. Cancellation, `failure.code: "task_cancelled"` or
|
|
57
|
+
`failure.next_action: "stop_and_report"` ends pending polling; do not continue
|
|
58
|
+
the task or dispatch a replacement. Bounded
|
|
59
|
+
[failure diagnosis](../references/result-handling.md#failure-diagnosis)
|
|
60
|
+
remains available. Keep observing the same task with a finite watch only when
|
|
61
|
+
the canonical guidance calls for it.
|
|
62
|
+
|
|
63
|
+
Before release, wait for the workspace to return to `state: retained` and inspect
|
|
64
|
+
its final capture. Only after the Lead explicitly chooses release, run:
|
|
48
65
|
|
|
49
66
|
```sh
|
|
50
67
|
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" workspace release WORKSPACE_ID \
|
|
@@ -62,10 +79,11 @@ Follow the same result decisions rather than assuming either response is
|
|
|
62
79
|
completed cleanup.
|
|
63
80
|
|
|
64
81
|
Save each response and exit code once. A created task is observed with
|
|
65
|
-
`status` first and collected in the foreground
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
apply, commit, branch merge,
|
|
82
|
+
`status` first and collected in the foreground, following the canonical
|
|
83
|
+
observation decisions before each next step. Exit `3` alone is not a reason
|
|
84
|
+
to keep polling. The Lead reviews the capture and owns landing any changes.
|
|
85
|
+
`workspace release` is explicit; no automatic apply, commit, branch merge,
|
|
86
|
+
TTL eviction, or provider-CLI fallback occurs.
|
|
69
87
|
|
|
70
88
|
## Fork from a checkpoint
|
|
71
89
|
|
|
@@ -3,18 +3,21 @@
|
|
|
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
8
|
|
|
7
9
|
1. Resolve CCR through `delegate providers --json`; its profile is `ccr:print`.
|
|
8
10
|
2. Preserve an explicitly requested CCR alias as `--model ALIAS`. Do not replace
|
|
9
11
|
it with an upstream model ID or reject it solely because discovery omitted it.
|
|
10
12
|
3. If no alias was chosen, run
|
|
11
|
-
`delegate models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
|
|
13
|
+
`delegate --root ROOT models --provider ccr:print --cwd ABSOLUTE_WORKSPACE --json`.
|
|
12
14
|
Choose a suitable configured alias from the available metadata and report
|
|
13
15
|
the choice. Clarify when the intended model remains ambiguous. If discovery
|
|
14
16
|
is unavailable and no alias is known, report the blocker; do not guess.
|
|
15
|
-
4. Dispatch through Delegate with
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
4. Dispatch through Delegate with the same `--root ROOT`,
|
|
18
|
+
`--provider ccr:print --model ALIAS`, the brief, workspace, permission, finite
|
|
19
|
+
budget, and `--json`. Use the normal status, collect, and continuation procedure
|
|
20
|
+
from the main skill.
|
|
18
21
|
|
|
19
22
|
CCR requires an explicit alias. Unspecified external collaboration still uses
|
|
20
23
|
`dispatch --auto`; do not prefer CCR unless the request calls for it. Multiple
|
|
@@ -22,7 +22,7 @@ The main skill owns [root selection](../SKILL.md#3-prepare-separate-paths-and-a-
|
|
|
22
22
|
| `workspace`, `checkpoint` | [Git resources](workspaces.md) | Helpers, not provider turns |
|
|
23
23
|
| `teams` | [Optional configuration and Member selection](#teams) | None |
|
|
24
24
|
| `schedule` | [Recurring definitions](#schedules), [history and execution evidence](#schedule-history-and-execution) | None |
|
|
25
|
-
| `scheduler run` | [
|
|
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 |
|
|
26
26
|
|
|
27
27
|
Prefix every task command with `delegate --root ROOT`, using the same
|
|
28
28
|
explicit root across invocations.
|
|
@@ -186,9 +186,16 @@ not prove admission, provider readiness or successful publication.
|
|
|
186
186
|
|
|
187
187
|
## Schedules
|
|
188
188
|
|
|
189
|
-
The management commands below save and inspect definitions
|
|
190
|
-
|
|
191
|
-
[
|
|
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).
|
|
192
199
|
|
|
193
200
|
```text
|
|
194
201
|
delegate --root ROOT schedule create --brief FILE --cwd ABS \
|
|
@@ -235,7 +242,9 @@ delegate --root ROOT schedule delete SCHEDULE_ID --json
|
|
|
235
242
|
- Definitions are immutable. Pause blocks future admissions; resume skips the
|
|
236
243
|
interval from the stored cursor through now without catch-up. A clock behind
|
|
237
244
|
the cursor leaves that cursor unchanged. Delete is terminal and retains
|
|
238
|
-
history. Pause/delete do not cancel an active occurrence
|
|
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.
|
|
239
248
|
- Only create initializes absent schedule storage. An absent store lists as
|
|
240
249
|
empty; show/state commands report not found. List defaults to 50 rows, at most
|
|
241
250
|
100, including paused/deleted definitions. Use the returned cursor to page.
|
|
@@ -244,8 +253,11 @@ delegate --root ROOT schedule delete SCHEDULE_ID --json
|
|
|
244
253
|
when output or storage reports uncertainty; inspect it with show rather than
|
|
245
254
|
submitting another create. Reusing an existing ID conflicts.
|
|
246
255
|
|
|
247
|
-
Handler results use exit `0` for
|
|
248
|
-
input/state transitions and `1` for not-found, conflicts or operational
|
|
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).
|
|
249
261
|
`--json` applies to handler responses; argument/usage errors retain the CLI's
|
|
250
262
|
normal stderr behavior. A valid rule with no future occurrence in the supported
|
|
251
263
|
timestamp range has a distinct range error, not a claim of permanent invalidity.
|
|
@@ -282,31 +294,116 @@ for freshness, no-result states, response bounds, exit codes and recovery.
|
|
|
282
294
|
|
|
283
295
|
## Scheduler runtime
|
|
284
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
|
+
|
|
285
302
|
```text
|
|
303
|
+
delegate --root ROOT scheduler serve
|
|
304
|
+
delegate --root ROOT scheduler status
|
|
305
|
+
delegate --root ROOT scheduler stop
|
|
286
306
|
delegate --root ROOT scheduler run [--pueue-config ABS] [--json]
|
|
287
307
|
```
|
|
288
308
|
|
|
289
|
-
|
|
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`
|
|
290
393
|
and `delegate-run` binaries from the same build and omit the advanced `--runner`
|
|
291
394
|
override. An override selects custom ownership even when it names the bundled
|
|
292
|
-
worker
|
|
293
|
-
lease.
|
|
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
|
|
294
399
|
existing compatibility rules. Historical custom-runner claims are not
|
|
295
400
|
automatically repaired or released.
|
|
296
401
|
|
|
297
|
-
This foreground command requires existing schedule storage. One process owns
|
|
298
|
-
each root; a second fails busy. It uses the service launch environment and the
|
|
299
|
-
saved requested provider choices. Saving a definition never starts the service.
|
|
300
|
-
For Team-targeted schedules, new occurrences read the pinned catalog's latest
|
|
301
|
-
Member defaults through normal admission; existing task IDs retain saved settings.
|
|
302
|
-
Use the same intended user configuration context as creation, or a different
|
|
303
|
-
catalog instance fails admission even when Team/Member IDs match.
|
|
304
|
-
See [operator hosting](https://github.com/hishamkaram/delegation-layer/blob/main/docs/cli-reference.md#scheduler-hosting).
|
|
305
|
-
|
|
306
402
|
Startup skips past appointments. Expired, overlapping or capacity-limited
|
|
307
403
|
appointments are skipped with a recorded reason; no catch-up queue or automatic
|
|
308
|
-
retry/continuation is added.
|
|
309
|
-
|
|
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)
|
|
310
407
|
to inspect recorded work, and [result handling](result-handling.md#scheduled-execution-results)
|
|
311
408
|
to collect its answer. Schedule reservation release is separate from result
|
|
312
409
|
publication.
|
|
@@ -317,12 +414,12 @@ Delegate workers keep their own budgets; provider-native in-session subagents do
|
|
|
317
414
|
not acquire independent Delegate lifetimes. The workflow owns saved progress,
|
|
318
415
|
worker IDs and deduplication; unknown acknowledgment is not permission to resend.
|
|
319
416
|
|
|
320
|
-
Interrupting the
|
|
321
|
-
owner lease. Accepted lifecycle calls settle independently of the stop signal;
|
|
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;
|
|
322
419
|
there is no shutdown-time guarantee. Already admitted tasks continue under their
|
|
323
|
-
own supervisors. The
|
|
324
|
-
|
|
325
|
-
|
|
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
|
|
326
423
|
evidence blocks only its schedule until the existing owners can prove closure.
|
|
327
424
|
|
|
328
425
|
## Codex review
|
|
@@ -166,6 +166,66 @@ asking again, but never infer it from a rejection or silently substitute a
|
|
|
166
166
|
destination. Keep the original failed attempt reported as failed; independent
|
|
167
167
|
requests and explicitly allowed recovery paths retain their existing rules.
|
|
168
168
|
|
|
169
|
+
## Schedule definition and host results
|
|
170
|
+
|
|
171
|
+
Use the installed build's help to check `scheduler serve/status/stop` support.
|
|
172
|
+
Keep three facts separate: the definition was
|
|
173
|
+
saved, the host is ready, and an occurrence produced an accepted provider result.
|
|
174
|
+
Neither saving nor host readiness proves that a task ran.
|
|
175
|
+
|
|
176
|
+
Schedule create/resume report confirmed persistence as `schedule.saved: true`;
|
|
177
|
+
keep `schedule.id` even if the command exits nonzero. The separate top-level
|
|
178
|
+
`scheduler` object carries host observation and guidance:
|
|
179
|
+
|
|
180
|
+
| JSON field | Meaning |
|
|
181
|
+
| --- | --- |
|
|
182
|
+
| `scheduler.state` | Observed lifecycle or availability state, including `foreground` for a current raw `scheduler run`. Read it with `ready` and the process exit. |
|
|
183
|
+
| `scheduler.epoch`, `scheduler.attempt` | Owner generation string and numeric child attempt, when known. Omission does not identify an owner. |
|
|
184
|
+
| `scheduler.ready` | Whether this observation confirms host/child readiness; it is not an occurrence result. |
|
|
185
|
+
| `scheduler.fault` | Optional `true` for a permanent fault reported by the host owner. Do not infer it from degraded state or `last_error`; omission is not proof that the whole command is fault-free. |
|
|
186
|
+
| `scheduler.next_retry_at` | Optional next retry timestamp during recovery. Observation does not reset it. |
|
|
187
|
+
| `scheduler.last_error` | Optional bounded host diagnostic. Keep it alongside pending or readiness facts. |
|
|
188
|
+
| `scheduler.next_action` | Caller guidance, such as `start_required`, `inspect_scheduler` or `stop_foreground_runtime`. |
|
|
189
|
+
| `scheduler.serve_command` | Optional exact argv array for an independent user start. Preserve every element and its argument boundary. |
|
|
190
|
+
| `scheduler.stop_accepted` | Optional boolean for acceptance of this stop request. `true` is accepted, `false` is explicitly not accepted, and omission is unknown. Acceptance does not prove shutdown completed. |
|
|
191
|
+
|
|
192
|
+
For `start_required`, both `schedule.next_action` and `scheduler.next_action`
|
|
193
|
+
carry that guidance. `scheduler.serve_command` is JSON argv, including the
|
|
194
|
+
resolved executable and exact root. Human output also prints JSON argv after
|
|
195
|
+
`run independently (argv):`, for example:
|
|
196
|
+
|
|
197
|
+
```text
|
|
198
|
+
run independently (argv): ["/installation with spaces/delegate","--root","/state with spaces","scheduler","serve"]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Forward the array intact. It is not an unquoted shell command: do not join its
|
|
202
|
+
elements with spaces or pass the joined text through a shell. The user starts
|
|
203
|
+
serve independently with those exact argument boundaries; the agent must not
|
|
204
|
+
execute it inside its bounded task. An omitted `schedule.saved` does not confirm
|
|
205
|
+
persistence; preserve any ID and follow the reported storage/error guidance.
|
|
206
|
+
|
|
207
|
+
| Response or observation | Next action |
|
|
208
|
+
| --- | --- |
|
|
209
|
+
| Create/resume saved the definition and confirmed a compatible ready host; exit `0` | Keep its schedule ID/root. The host will handle future due work; use history/execution for actual occurrence evidence. |
|
|
210
|
+
| Create/resume returns exit `3`, `schedule.saved: true` and `scheduler.next_action: start_required` | The definition remains saved. Preserve the returned schedule ID/root and give `scheduler.serve_command` unchanged to the user to run in an independent terminal or tmux pane. Never start it inside the agent's bounded task, detach it in the background, or submit another create. |
|
|
211
|
+
| Create/resume saved the definition but reports starting, backoff or pending readiness; exit `3` | Keep the same ID and report its host state and available retry time. Use passive scheduler status for later observation; do not create another definition, start a competing host or reset cooldown. |
|
|
212
|
+
| Create/resume saved the definition but the host is temporarily unreachable; exit `3`, pending guidance and no top-level `error` | Preserve `schedule.saved: true` and the same ID. Use passive status to observe the uncertainty. A transport failure does not establish owner death or a permanent host fault. |
|
|
213
|
+
| Create/resume saved the definition and the host reports `scheduler.fault: true`; exit `1` | Report the permanent fault and available `scheduler.last_error`; retain `schedule.saved: true` and the ID. For an incompatible saved definition, the before-Ready check stops automatic child restart. Repeated create, serve or status calls are not a repair. |
|
|
214
|
+
| Scheduler status observes starting, ready, backoff, degraded, stopping or stopped; exit `0` | Observation completed. Report the observed state; exit `0` does not mean ready or that an occurrence succeeded. Status does not start, migrate, repair or clean resources. |
|
|
215
|
+
| Scheduler stop confirms completed stop; exit `0` | The exact stopped intent has a validated owner-written closure witness and the exact host is absent. The witness follows joined child shutdown and free execution ownership. Independently admitted tasks keep their existing lifetimes. A later host needs a fresh explicit user-run serve command. |
|
|
216
|
+
| Scheduler stop has `scheduler.stop_accepted: true` but completion is pending; exit `3` | Preserve its acceptance and pending state. The host remains control-responsive while joining its child or waiting for a prior execution owner. Host death before the closure witness does not complete stop. Observe the same generation; do not claim stopped, launch a replacement or repeat schedule creation. An omitted `stop_accepted` is unknown, not false. |
|
|
217
|
+
| Scheduler stop has authenticated `scheduler.stop_accepted: true` and a later readback fault; exit `1` | Preserve the accepted fact and report the concrete fault. Readback failure does not revoke acceptance or establish completed shutdown. |
|
|
218
|
+
| Status reports `scheduler.state: foreground`, or stop returns exit `3` with that state, `stop_accepted: false` and `next_action: stop_foreground_runtime` | The current compatibility `scheduler run` owns this generation; an older managed-host receipt cannot hide it. Public stop does not terminate it. Have the user end that invocation with Ctrl-C in its original pane. Prefer managed `scheduler serve` afterward. |
|
|
219
|
+
| Invalid input/state; exit `2`, or concrete operational/compatibility/cleanup fault; exit `1` | Report the error and retain any saved ID or accepted-control fact. A concrete fault joined to pending work remains a fault; it is not a pending-only result. |
|
|
220
|
+
|
|
221
|
+
If the host dies, its pane closes or the machine reboots, the user must start
|
|
222
|
+
serve again. Child crash recovery applies only while that host remains alive.
|
|
223
|
+
An absent heartbeat or unresponsive endpoint is uncertainty, not permission to
|
|
224
|
+
replace an owner. Do not install a service or invoke a detached bootstrap as a
|
|
225
|
+
recovery step. Pause/delete affect future claims and need no live host; they do
|
|
226
|
+
not cancel already admitted occurrences. [Scheduler runtime](command-reference.md#scheduler-runtime)
|
|
227
|
+
owns launch, backoff and calendar behavior.
|
|
228
|
+
|
|
169
229
|
## Scheduled execution results
|
|
170
230
|
|
|
171
231
|
Use [schedule history and execution](command-reference.md#schedule-history-and-execution)
|