delegation-layer 0.1.32 → 0.1.37
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 +8 -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/SKILL.md +12 -3
- package/plugins/delegation-layer/skills/agent-integration/examples/json-results.md +42 -0
- package/plugins/delegation-layer/skills/agent-integration/examples/managed-workspace.md +61 -0
- package/plugins/delegation-layer/skills/agent-integration/references/collaboration.md +16 -0
- package/plugins/delegation-layer/skills/agent-integration/references/command-reference.md +23 -1
- package/plugins/delegation-layer/skills/agent-integration/references/continuation.md +36 -0
- package/plugins/delegation-layer/skills/agent-integration/references/result-handling.md +53 -1
- package/plugins/delegation-layer/skills/agent-integration/references/workspaces.md +93 -1
- package/skills/agent-integration/SKILL.md +12 -3
- package/skills/agent-integration/examples/json-results.md +42 -0
- package/skills/agent-integration/examples/managed-workspace.md +61 -0
- package/skills/agent-integration/references/collaboration.md +16 -0
- package/skills/agent-integration/references/command-reference.md +23 -1
- package/skills/agent-integration/references/continuation.md +36 -0
- package/skills/agent-integration/references/result-handling.md +53 -1
- package/skills/agent-integration/references/workspaces.md +93 -1
package/README.md
CHANGED
|
@@ -301,6 +301,14 @@ reference](skills/agent-integration/references/workspaces.md) for attachment,
|
|
|
301
301
|
continuation, verification, review scope, release, and forgetting. This
|
|
302
302
|
feature does not automatically apply, commit, branch, or merge worker changes.
|
|
303
303
|
|
|
304
|
+
To fork a worker from current uncommitted work, first record a Git checkpoint
|
|
305
|
+
with `delegate checkpoint create --cwd ABS` (or `--workspace ID`). It stores a
|
|
306
|
+
synthetic commit under a Delegate-owned ref without moving `HEAD` or touching
|
|
307
|
+
the real index. After `checkpoint status` reports it `checkpointed` and
|
|
308
|
+
`usable`, pass its commit to `dispatch --isolation git-worktree --base`.
|
|
309
|
+
Checkpoints stay until `checkpoint remove`; see the [checkpoint
|
|
310
|
+
guidance](skills/agent-integration/references/workspaces.md#git-checkpoints).
|
|
311
|
+
|
|
304
312
|
## Documentation
|
|
305
313
|
|
|
306
314
|
- [Getting started](docs/getting-started.md) — install and run a first task.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "delegation-layer",
|
|
3
3
|
"displayName": "Delegation Layer",
|
|
4
|
-
"version": "0.1.
|
|
4
|
+
"version": "0.1.37",
|
|
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.1.
|
|
3
|
+
"version": "0.1.37",
|
|
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",
|
|
@@ -133,7 +133,12 @@ tasks may proceed; the failed attempt must remain reported as failed or blocked.
|
|
|
133
133
|
or provider comparison. For independent parallel writes, choose
|
|
134
134
|
`--isolation git-worktree` automatically unless the user explicitly chooses
|
|
135
135
|
shared coordination; the model chooses fan-out and task scope. A read-only
|
|
136
|
-
review may attach a retained workspace with `--workspace ID`.
|
|
136
|
+
review may attach a retained workspace with `--workspace ID`. To fork a
|
|
137
|
+
worker from current uncommitted content, follow
|
|
138
|
+
[checkpoint before fork](references/workspaces.md#checkpoint-before-fork):
|
|
139
|
+
fork only from a `checkpointed`, `usable` checkpoint commit. If your own
|
|
140
|
+
turn holds the workspace, do not wait or retry through `--cwd`; report so
|
|
141
|
+
the Lead checkpoints after your turn closes.
|
|
137
142
|
|
|
138
143
|
For an explicit Codex code review, use the discoverable `codex:review` profile
|
|
139
144
|
with one persisted target: `--review-target uncommitted`,
|
|
@@ -352,7 +357,9 @@ cancellation or `stop_and_report` applies, a `timed_out` task with
|
|
|
352
357
|
otherwise report it. When continuing, use the original state root and a finite
|
|
353
358
|
budget, then observe the returned successor ID. Do not
|
|
354
359
|
wait indefinitely for pending publication or restart the task as an unrelated
|
|
355
|
-
dispatch. If continuation is unavailable, report its reason
|
|
360
|
+
dispatch. If continuation is unavailable, report its reason, except the busy
|
|
361
|
+
managed-workspace case in [continuation and timeout
|
|
362
|
+
recovery](references/continuation.md). Apply the same
|
|
356
363
|
`failure` and `task_record` decisions as for dispatch; never repeat an uncertain
|
|
357
364
|
successor creation.
|
|
358
365
|
|
|
@@ -377,7 +384,9 @@ recruit more agents unless that is explicitly part of the task.
|
|
|
377
384
|
- Read [continuation](references/continuation.md) for timeout or interruption
|
|
378
385
|
recovery or an exact-session follow-up.
|
|
379
386
|
- Read [managed workspaces](references/workspaces.md) for optional Git
|
|
380
|
-
worktrees, capture, review scope, release, and forgetting
|
|
387
|
+
worktrees, capture, review scope, release, and forgetting, and
|
|
388
|
+
[Git checkpoints](references/workspaces.md#git-checkpoints) before creating,
|
|
389
|
+
observing, forking from, or removing a checkpoint.
|
|
381
390
|
- Use [read-only example](examples/read-only-task.md),
|
|
382
391
|
[write example](examples/workspace-write-task.md),
|
|
383
392
|
[JSON examples](examples/json-results.md), and
|
|
@@ -11,3 +11,45 @@ own the decision order for task creation, failures, timeout continuation,
|
|
|
11
11
|
terminal outcomes, pending interaction, and bounded collection. Read them
|
|
12
12
|
before interpreting these commands; pending publication alone is not a reason
|
|
13
13
|
to wait when the task needs an answer or timeout recovery.
|
|
14
|
+
|
|
15
|
+
## Checkpoint responses
|
|
16
|
+
|
|
17
|
+
These abbreviated shapes use the delivered field names; `…` marks omitted
|
|
18
|
+
values. Apply [checkpoint results](../references/result-handling.md#checkpoint-results)
|
|
19
|
+
to the whole response and its exit code.
|
|
20
|
+
|
|
21
|
+
Accepted creation, exit `3`:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{"schema_version":1,"command":"checkpoint","root_id":"…","admission":"unknown","liveness":"undetermined","publication":"unknown",
|
|
25
|
+
"checkpoint":{"id":"CHECKPOINT_ID","next_action":"watch_checkpoint"}}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Busy refusal, exit `3`, with no accepted ID:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{"checkpoint":{"reason_code":"requested_action_not_authorized","next_action":"retry_create"}}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Qualified checkpoint from `status`, exit `0`; only this state may be forked:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{"checkpoint":{"id":"CHECKPOINT_ID","current":{"id":"CHECKPOINT_ID","selection":"ordinary","cwd":"/abs/source",
|
|
38
|
+
"state":"checkpointed","snapshot_ref":"refs/delegate/ROOT_ID/checkpoints/CHECKPOINT_ID","commit_oid":"…","usable":true}}}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Exact removal attempt from `status CHECKPOINT_ID --operation OPERATION_ID`,
|
|
42
|
+
exit `0`. Creation history stays `checkpointed`, but `usable` is now `false`:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{"checkpoint":{"id":"CHECKPOINT_ID","operation_id":"OPERATION_ID",
|
|
46
|
+
"current":{"id":"CHECKPOINT_ID","selection":"ordinary","state":"checkpointed","usable":false,
|
|
47
|
+
"removal":{"operation_id":"OPERATION_ID","attempts":1,"state":"removed"}},
|
|
48
|
+
"operation":{"operation_id":"OPERATION_ID","attempts":1,"state":"removed"}}}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
An empty `list` page, exit `0`, still has the array:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{"schema_version":1,"command":"checkpoint","root_id":"…","admission":"unknown","liveness":"undetermined","publication":"unknown","checkpoints":[]}
|
|
55
|
+
```
|
|
@@ -66,3 +66,64 @@ Save each response and exit code once. A created task is observed with
|
|
|
66
66
|
success; continue observing the same task. The Lead reviews the capture and
|
|
67
67
|
owns landing any changes. `workspace release` is explicit; no automatic
|
|
68
68
|
apply, commit, branch merge, TTL eviction, or provider-CLI fallback occurs.
|
|
69
|
+
|
|
70
|
+
## Fork from a checkpoint
|
|
71
|
+
|
|
72
|
+
Use this sequence when the worker must start from current uncommitted content
|
|
73
|
+
instead of a committed base. Run it from the Lead, not from inside a worker
|
|
74
|
+
that uses the same workspace. The [checkpoint guidance](../references/workspaces.md#checkpoint-before-fork)
|
|
75
|
+
owns the rules; [checkpoint results](../references/result-handling.md#checkpoint-results)
|
|
76
|
+
owns every response decision.
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
SOURCE="$PWD"
|
|
80
|
+
RESPONSE="$(mktemp)"
|
|
81
|
+
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint create \
|
|
82
|
+
--cwd "$SOURCE" --budget 5m --json >"$RESPONSE.checkpoint"; then
|
|
83
|
+
checkpoint_exit=0
|
|
84
|
+
else
|
|
85
|
+
checkpoint_exit=$?
|
|
86
|
+
fi
|
|
87
|
+
printf '%s\n' "$checkpoint_exit" >"$RESPONSE.checkpoint.exit"
|
|
88
|
+
cat "$RESPONSE.checkpoint"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Exit `3` with `checkpoint.id` and `next_action: "watch_checkpoint"` means the
|
|
92
|
+
request was accepted, not captured. Use that `checkpoint.id` as
|
|
93
|
+
`CHECKPOINT_ID`. Do not run `create` again.
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint status CHECKPOINT_ID \
|
|
97
|
+
--watch 30s --json >"$RESPONSE.checkpoint.status"; then
|
|
98
|
+
checkpoint_status_exit=0
|
|
99
|
+
else
|
|
100
|
+
checkpoint_status_exit=$?
|
|
101
|
+
fi
|
|
102
|
+
printf '%s\n' "$checkpoint_status_exit" >"$RESPONSE.checkpoint.status.exit"
|
|
103
|
+
cat "$RESPONSE.checkpoint.status"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Repeat that status command while it exits `3`. Fork only when it exits `0`,
|
|
107
|
+
`checkpoint.current.state` is `checkpointed`, and `checkpoint.current.usable`
|
|
108
|
+
is `true`. Use `checkpoint.current.commit_oid` as `COMMIT_OID` in the first
|
|
109
|
+
dispatch example, replacing `--base HEAD` with `--base COMMIT_OID`. Report a
|
|
110
|
+
`stop_and_report` result instead of forking.
|
|
111
|
+
|
|
112
|
+
When the Lead no longer needs the checkpoint, remove it explicitly:
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint remove CHECKPOINT_ID \
|
|
116
|
+
--budget 5m --json >"$RESPONSE.checkpoint.remove"; then
|
|
117
|
+
checkpoint_remove_exit=0
|
|
118
|
+
else
|
|
119
|
+
checkpoint_remove_exit=$?
|
|
120
|
+
fi
|
|
121
|
+
printf '%s\n' "$checkpoint_remove_exit" >"$RESPONSE.checkpoint.remove.exit"
|
|
122
|
+
cat "$RESPONSE.checkpoint.remove"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Exit `3` with `checkpoint.operation_id` and `watch_checkpoint` means removal
|
|
126
|
+
attempt `OPERATION_ID` was accepted. Observe that exact attempt with
|
|
127
|
+
`checkpoint status CHECKPOINT_ID --operation OPERATION_ID --watch 30s --json`,
|
|
128
|
+
saving its response and exit the same way. A `retry_remove` response has no
|
|
129
|
+
`operation_id` and accepted nothing.
|
|
@@ -8,6 +8,22 @@ cap or TTL eviction. A read-only review may attach a retained workspace with
|
|
|
8
8
|
release rules live in [managed workspace guidance](workspaces.md); do not
|
|
9
9
|
restate them in each collaboration brief.
|
|
10
10
|
|
|
11
|
+
Give each participant a bounded deliverable, explicit write ownership, and the
|
|
12
|
+
inputs it depends on. Run independent assignments in parallel; dependent work
|
|
13
|
+
begins only after the required results are collected and any prerequisite
|
|
14
|
+
changes are applied and verified in the consuming worker's workspace, without
|
|
15
|
+
requiring a merge. Combine the relevant completed results in the verification
|
|
16
|
+
workspace before running checks that depend on their interaction. A worker's
|
|
17
|
+
terminal outcome establishes that assignment's result, not completion of the
|
|
18
|
+
user's full objective; keep remaining integration, verification and unresolved
|
|
19
|
+
work explicit.
|
|
20
|
+
|
|
21
|
+
When a participant must start from the Lead's current uncommitted work, the
|
|
22
|
+
Lead checkpoints that content first and forks each worker from the qualified
|
|
23
|
+
checkpoint commit with `--base`. Follow
|
|
24
|
+
[checkpoint before fork](workspaces.md#checkpoint-before-fork); a worker never
|
|
25
|
+
checkpoints a workspace its own turn is using.
|
|
26
|
+
|
|
11
27
|
## Keep each request identifiable
|
|
12
28
|
|
|
13
29
|
Choose the fan-out needed for the user's task. Each participant needs its own
|
|
@@ -6,7 +6,8 @@ All paths passed to `--root`, `--cwd`, and `--brief` must be absolute. Add
|
|
|
6
6
|
Pass the intended workspace directly. Delegate handles provider launch options;
|
|
7
7
|
do not initialize Git, change trust settings, or call a provider CLI as a
|
|
8
8
|
workspace workaround. Ordinary tasks support non-Git directories. Git is
|
|
9
|
-
required for managed worktree creation/attachment
|
|
9
|
+
required for managed worktree creation/attachment and checkpoint creation or
|
|
10
|
+
removal only; native review retains
|
|
10
11
|
its separate explicit review-target contract. See [managed workspace guidance](workspaces.md)
|
|
11
12
|
for the policy owner.
|
|
12
13
|
|
|
@@ -101,6 +102,27 @@ Continuation flags:
|
|
|
101
102
|
- `--budget DURATION`, `--model MODEL`, and `--effort VALUE`: optional overrides;
|
|
102
103
|
- `--interactive`: enable interaction when supported; already-interactive predecessors keep it.
|
|
103
104
|
|
|
105
|
+
## Checkpoint commands
|
|
106
|
+
|
|
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.
|
|
112
|
+
|
|
113
|
+
```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
|
|
119
|
+
```
|
|
120
|
+
|
|
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`.
|
|
125
|
+
|
|
104
126
|
## Choosing models and effort
|
|
105
127
|
|
|
106
128
|
Pass an explicitly supplied model ID and effort unchanged, even if discovery
|
|
@@ -53,6 +53,42 @@ Then retry the exact `continue --task PREDECESSOR_ID` after it becomes retained.
|
|
|
53
53
|
Keep the original predecessor, brief, and budget; do not replace continuation
|
|
54
54
|
with a fresh dispatch. A created successor is only observed.
|
|
55
55
|
|
|
56
|
+
**Busy managed workspace after a timeout.** This is the only case where an
|
|
57
|
+
unavailable continuation may be waited for instead of reported. It applies
|
|
58
|
+
only when a `timed_out` task reports all of `continuation.resumable: false`,
|
|
59
|
+
`continuation.reason` exactly `"managed workspace is busy"`,
|
|
60
|
+
`workspace.state: "busy"`, and `workspace.next_action: "watch_workspace"`.
|
|
61
|
+
Another reservation may still hold the workspace; do not infer which use. Wait
|
|
62
|
+
only when further work needs to continue this task, and return a committed
|
|
63
|
+
result normally. Do not wait when a cancellation (`failure.code:
|
|
64
|
+
"task_cancelled"`), a concrete fault, or `stop_and_report` applies to the task
|
|
65
|
+
or the workspace. If a successor from this predecessor was already created,
|
|
66
|
+
observe that successor instead; if its creation is uncertain, follow the
|
|
67
|
+
`task_record` stop rule in [result handling](result-handling.md).
|
|
68
|
+
|
|
69
|
+
1. Watch the workspace with the same root and a finite duration, using
|
|
70
|
+
`workspace.id` from the task response; never guess an ID or path:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" workspace status \
|
|
74
|
+
WORKSPACE_ID --watch 30s --json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Repeat the watch only while it reports `state: "busy"`.
|
|
78
|
+
2. When it reports `state: "retained"`, run a fresh `status` for the same
|
|
79
|
+
predecessor task ID.
|
|
80
|
+
3. Only if that status now reports `continuation.resumable: true` and the task
|
|
81
|
+
rules above still permit it, run the exact `continue --task PREDECESSOR_ID`
|
|
82
|
+
once. Otherwise report its reason and stop.
|
|
83
|
+
|
|
84
|
+
Never run `continue` while `resumable` is `false`. Report any other reason,
|
|
85
|
+
workspace state, or fault under the existing guidance; do not reactivate a
|
|
86
|
+
`released` or `forgotten` workspace. An `undetermined` workspace view is
|
|
87
|
+
unobserved and follows [managed workspace results](result-handling.md#managed-workspace-results);
|
|
88
|
+
it is neither a terminal failure nor permission to continue. Do not dispatch,
|
|
89
|
+
fall back to another provider, repair the environment, or mutate the workspace
|
|
90
|
+
to free it. Availability is not guaranteed; do not wait indefinitely.
|
|
91
|
+
|
|
56
92
|
`mode` describes the provider contract:
|
|
57
93
|
|
|
58
94
|
- `native` uses the provider’s exact persisted conversation/session ID;
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
Use the response fields independently. A successful control command is not
|
|
4
4
|
the same as a successful provider result.
|
|
5
5
|
|
|
6
|
-
1. Save `task_id` immediately after dispatch or continue.
|
|
6
|
+
1. Save `task_id` immediately after dispatch or continue. It is the durable
|
|
7
|
+
Delegate identity. `supervisor.numeric_task_id` and a stop's
|
|
8
|
+
`numeric_task_id` are private, ephemeral queue addresses. The queue can
|
|
9
|
+
reuse a number for a later task, so a repeated number is not a binding
|
|
10
|
+
error; never use it as a task handle.
|
|
7
11
|
2. For a dispatch or continue error, inspect `task_record` first. When it is
|
|
8
12
|
`created`, observe the returned ID with `status`. Before applying the generic
|
|
9
13
|
`not_created` stop rule, handle the sole migration exception: when
|
|
@@ -91,6 +95,18 @@ The provider outcome is immutable and the workspace `CaptureReceipt` is a
|
|
|
91
95
|
separate immutable fact; a failed or unavailable capture must not be reported
|
|
92
96
|
as a provider failure when native closure is already proven.
|
|
93
97
|
|
|
98
|
+
In task `status` or `collect`, a workspace with `state: "undetermined"`,
|
|
99
|
+
`evidence_state: "unknown"`, and `next_action: "watch_workspace"` means that
|
|
100
|
+
observer's bounded view expired before it read the workspace. It is an
|
|
101
|
+
unobserved view only. It does not imply corruption, change the task fields, or
|
|
102
|
+
revoke an eligible continuation, and it does not turn a committed task into a
|
|
103
|
+
failure. Follow the task fields above: return a committed result, handle a
|
|
104
|
+
rejection using its reported guidance, and keep observing only while the task
|
|
105
|
+
fields are pending. When useful, watch the same workspace with the same root.
|
|
106
|
+
Do not dispatch again, retry the provider, fall back to another integration,
|
|
107
|
+
or repair the environment because of it. A workspace view with `stop_and_report` remains a
|
|
108
|
+
concrete failure to report.
|
|
109
|
+
|
|
94
110
|
Before a task record exists, a pending workspace provision returns
|
|
95
111
|
`task_record: "not_created"` with
|
|
96
112
|
`failure.code: "workspace_provision_pending"` and
|
|
@@ -124,6 +140,42 @@ Lead has terminal task/capture evidence and explicitly releases it. Read
|
|
|
124
140
|
[managed workspace guidance](workspaces.md) for the exact command surface and
|
|
125
141
|
review/capture/forgetting boundaries.
|
|
126
142
|
|
|
143
|
+
## Checkpoint results
|
|
144
|
+
|
|
145
|
+
A `checkpoint` response has `command: "checkpoint"` and no `task_id` or
|
|
146
|
+
`outcome`. A checkpoint receipt is Git-content evidence; it never replaces a
|
|
147
|
+
provider outcome, and a provider outcome never proves a checkpoint. Read
|
|
148
|
+
`checkpoint.id`, `checkpoint.operation_id`, `checkpoint.current`,
|
|
149
|
+
`checkpoint.operation`, `checkpoint.reason_code`, `checkpoint.next_action`, and
|
|
150
|
+
`error` separately, together with the exit code. Exit `0` alone is not enough.
|
|
151
|
+
|
|
152
|
+
| Command and response | Meaning and next action |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `create`: exit `3`, `id` C, `next_action: "watch_checkpoint"` | Accepted, not yet captured. Watch `status C`; never repeat `create`. |
|
|
155
|
+
| `create`: exit `3`, `requested_action_not_authorized`, `retry_create`, no `id` | Busy refusal; nothing was accepted. Apply the [busy rule](workspaces.md#checkpoint-before-fork). Never wait for your own turn or switch to `--cwd`. |
|
|
156
|
+
| `remove C`: exit `3`, `id` C, `operation_id` R, `watch_checkpoint` | Removal attempt R is accepted. Watch `status C --operation R`; never repeat `remove` to observe it. |
|
|
157
|
+
| `remove C`: exit `3`, `requested_action_not_authorized`, `retry_remove`, no `operation_id` | Not accepted, usually because creation is still pending. The `id` in your command is not a removal ID. Watch `status C` until it settles, then retry `remove C` once. |
|
|
158
|
+
| `remove C`: exit `0` with `operation_id` R | R already succeeded. No new attempt was registered. |
|
|
159
|
+
| `status C`: exit `0` | Successful observation. Fork only when `current.state` is `checkpointed` and `current.usable` is `true`. With `next_action: "stop_and_report"`, report the unavailable creation or latest removal; do not fork. |
|
|
160
|
+
| `status C`: exit `3`, `watch_checkpoint` | Creation or latest removal is still pending. Keep watching the same C. |
|
|
161
|
+
| `status C --operation R`: exit `0`, `1`, or `3` | R's own result: `removed` or `nothing_to_remove` is `0`; `unavailable` is `1` with `stop_and_report`; pending is `3`. A newer attempt in `current.removal` never replaces R's outcome. Keep watching R, not the newer head. |
|
|
162
|
+
| `list`: exit `0` | One metadata page. Entries may be pending, unavailable, or removed. Run `status C` for a reconciled verdict. |
|
|
163
|
+
| Exit `1` with `stop_and_report` | Concrete failure. Report `error` and every ID already returned; do not repeat the mutation. |
|
|
164
|
+
| Exit `2` | Invalid request. Parse errors print usage on stderr without guaranteed JSON; correct the request. |
|
|
165
|
+
|
|
166
|
+
Take `C` only from `checkpoint.id` and `R` only from `checkpoint.operation_id`
|
|
167
|
+
of a response that returned them. Never invent an operation ID or reuse a
|
|
168
|
+
creation ID as `--operation`. Returned IDs stay valid after a later read
|
|
169
|
+
fault; an unreadable `current` or `operation` is omitted rather than shown as
|
|
170
|
+
empty availability.
|
|
171
|
+
|
|
172
|
+
`status --watch` repeats the same observation of the same IDs until a settled
|
|
173
|
+
or failed result or the bound ends. It never begins another action, renews a
|
|
174
|
+
helper deadline, or cancels accepted work. The latest observation chooses the
|
|
175
|
+
exit. A watch that ends at exit `3` means keep observing; it is not a failure.
|
|
176
|
+
If writing the response itself fails (exit `1`), accepted work stays accepted;
|
|
177
|
+
observe it with `status` instead of repeating the mutation.
|
|
178
|
+
|
|
127
179
|
## Offline recovery
|
|
128
180
|
|
|
129
181
|
When Delegate returns `failure.next_action: "recheck"`, use the same root and
|
|
@@ -4,7 +4,7 @@ Managed workspaces are an optional Delegate feature for tasks that need a
|
|
|
4
4
|
retained Git worktree. Ordinary delegation, including ordinary work in a
|
|
5
5
|
non-Git directory, is unchanged. Git is required only when a request creates
|
|
6
6
|
or attaches to a managed workspace (`--isolation git-worktree` or
|
|
7
|
-
`--workspace ID`).
|
|
7
|
+
`--workspace ID`), or creates or removes a [Git checkpoint](#git-checkpoints).
|
|
8
8
|
|
|
9
9
|
This reference is self-contained guidance for using managed workspaces.
|
|
10
10
|
|
|
@@ -169,6 +169,98 @@ expired provider scope is never renewed or reused. If capture
|
|
|
169
169
|
is unavailable after closure, the closure evidence can still preserve a valid
|
|
170
170
|
continuation decision; it does not rewrite the provider outcome.
|
|
171
171
|
|
|
172
|
+
## Git checkpoints
|
|
173
|
+
|
|
174
|
+
A checkpoint records the current Git content of one checkout as a synthetic
|
|
175
|
+
commit pinned by the owned ref `refs/delegate/ROOT_ID/checkpoints/CHECKPOINT_ID`.
|
|
176
|
+
It does not move `HEAD`, create or switch a branch, or change the real index.
|
|
177
|
+
The commit's tree is the full current Git-content view, built through a private
|
|
178
|
+
index with the capture algorithm above, so the same exclusions apply. Its single
|
|
179
|
+
parent is the `HEAD` the helper observed. Author, committer, and timestamp are
|
|
180
|
+
fixed Delegate values; trailers carry the checkpoint ID and request digest.
|
|
181
|
+
This is unrelated to a provider continuation `mode: "checkpoint"`.
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
delegate --root ROOT checkpoint create --cwd ABS [--budget DURATION] --json
|
|
185
|
+
delegate --root ROOT checkpoint create --workspace ID [--budget DURATION] --json
|
|
186
|
+
delegate --root ROOT checkpoint status CHECKPOINT_ID [--operation OP] [--watch DURATION] --json
|
|
187
|
+
delegate --root ROOT checkpoint list [--after CHECKPOINT_ID] [--limit 1..50] --json
|
|
188
|
+
delegate --root ROOT checkpoint remove CHECKPOINT_ID [--budget DURATION] --json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- `create` names exactly one target: `--cwd` for an absolute ordinary Git
|
|
192
|
+
checkout directory, or `--workspace` for a managed workspace ID. Nothing is
|
|
193
|
+
inferred from the current directory. Select a managed checkout only by
|
|
194
|
+
`--workspace ID`; never pass its path as `--cwd`.
|
|
195
|
+
- `status` and `remove` take the checkpoint ID `C` from the create response.
|
|
196
|
+
`list` takes no target and runs no Git command.
|
|
197
|
+
- Only `create --cwd` may initialize a new state root. Every other checkpoint
|
|
198
|
+
command needs the existing root and fails with exit `1` without creating it.
|
|
199
|
+
Use one state root for every command about the same checkpoint.
|
|
200
|
+
- `--budget` is the finite helper budget (default 5m). It is persisted with the
|
|
201
|
+
operation and does not renew any provider task budget. `--watch` exists only
|
|
202
|
+
on `status`.
|
|
203
|
+
|
|
204
|
+
A managed checkpoint is a workspace use. It needs the workspace's use owner and
|
|
205
|
+
holds that workspace's usage reservation while its helper runs, so a concurrent
|
|
206
|
+
turn or `workspace exec` on that workspace gets the normal busy response. It
|
|
207
|
+
closes without content capture. Create it while the workspace is retained.
|
|
208
|
+
|
|
209
|
+
Delegate does not restore, apply, merge, or land a checkpoint into any checkout.
|
|
210
|
+
It does not control nested delegation budgets or lifetimes either. A fork from
|
|
211
|
+
a checkpoint is an ordinary new managed dispatch with its own task budget.
|
|
212
|
+
|
|
213
|
+
### Checkpoint before fork
|
|
214
|
+
|
|
215
|
+
Use this sequence to start an isolated worker from current uncommitted work.
|
|
216
|
+
Save every response and exit code once; follow
|
|
217
|
+
[checkpoint results](result-handling.md#checkpoint-results) for each one.
|
|
218
|
+
|
|
219
|
+
1. Run `checkpoint create` with one target. Exit `3` with `checkpoint.id` and
|
|
220
|
+
`next_action: "watch_checkpoint"` means the request was accepted. It does
|
|
221
|
+
not mean the content was captured. Save that exact ID as `C`.
|
|
222
|
+
2. Run `checkpoint status C --watch 30s --json` until the exit is not `3`.
|
|
223
|
+
Never repeat `create` to observe it.
|
|
224
|
+
3. Fork only when `status` exits `0` and `checkpoint.current.state` is
|
|
225
|
+
`checkpointed` and `checkpoint.current.usable` is `true`. A `commit_oid` or
|
|
226
|
+
`snapshot_ref` alone is not proof: an unavailable creation can still name a
|
|
227
|
+
retained candidate.
|
|
228
|
+
4. Dispatch the worker with the qualified `checkpoint.current.commit_oid` as
|
|
229
|
+
the existing `--base` of a new managed workspace. Use an ordinary checkout of
|
|
230
|
+
the same repository as `--cwd`, normally the source the Lead already uses:
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
delegate --root ROOT dispatch --auto --brief ABS_BRIEF --cwd ABS_SOURCE \
|
|
234
|
+
--isolation git-worktree --base COMMIT_OID \
|
|
235
|
+
--permission workspace-write --budget 30m --json
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
5. Remove the checkpoint explicitly when the Lead no longer needs it.
|
|
239
|
+
|
|
240
|
+
`status` exit `0` means a successful metadata observation, not an available
|
|
241
|
+
checkpoint. `usable` is `true` only for a `checkpointed` creation with no
|
|
242
|
+
registered removal attempt, including a failed one. It is derived from
|
|
243
|
+
Delegate's records; it is not proof that an external Git command left the ref
|
|
244
|
+
in place.
|
|
245
|
+
|
|
246
|
+
If `checkpoint create --workspace ID` returns exit `3` with
|
|
247
|
+
`reason_code: "requested_action_not_authorized"` and `retry_create`, no
|
|
248
|
+
checkpoint was accepted and no ID was assigned. When that workspace is in use
|
|
249
|
+
by the turn you are running in, do not wait for yourself, retry in a loop, or
|
|
250
|
+
retry through `--cwd`. Finish and report; the Lead creates the checkpoint after
|
|
251
|
+
your turn closes. When another use holds it, the Lead observes that workspace
|
|
252
|
+
until it is retained again, then retries the same create once.
|
|
253
|
+
|
|
254
|
+
Checkpoint refs outlive `workspace release` and `workspace forget`: the forget
|
|
255
|
+
inventory covers only the workspace's own base, capture, and baseline refs.
|
|
256
|
+
`checkpoint remove C` is the only command that removes a checkpoint ref.
|
|
257
|
+
Removal needs only the shared Git common directory, so it works after the
|
|
258
|
+
source checkout or managed checkout is gone. A missing or replaced common
|
|
259
|
+
directory makes that removal attempt `unavailable`, never `removed`. Creation
|
|
260
|
+
history stays observable after removal: `current.state` keeps the creation
|
|
261
|
+
disposition, while `current.usable` becomes `false` and `current.removal`
|
|
262
|
+
shows the latest attempt.
|
|
263
|
+
|
|
172
264
|
## Retention and forgetting
|
|
173
265
|
|
|
174
266
|
A created managed checkout is retained for every outcome, including no-op and
|
|
@@ -133,7 +133,12 @@ tasks may proceed; the failed attempt must remain reported as failed or blocked.
|
|
|
133
133
|
or provider comparison. For independent parallel writes, choose
|
|
134
134
|
`--isolation git-worktree` automatically unless the user explicitly chooses
|
|
135
135
|
shared coordination; the model chooses fan-out and task scope. A read-only
|
|
136
|
-
review may attach a retained workspace with `--workspace ID`.
|
|
136
|
+
review may attach a retained workspace with `--workspace ID`. To fork a
|
|
137
|
+
worker from current uncommitted content, follow
|
|
138
|
+
[checkpoint before fork](references/workspaces.md#checkpoint-before-fork):
|
|
139
|
+
fork only from a `checkpointed`, `usable` checkpoint commit. If your own
|
|
140
|
+
turn holds the workspace, do not wait or retry through `--cwd`; report so
|
|
141
|
+
the Lead checkpoints after your turn closes.
|
|
137
142
|
|
|
138
143
|
For an explicit Codex code review, use the discoverable `codex:review` profile
|
|
139
144
|
with one persisted target: `--review-target uncommitted`,
|
|
@@ -352,7 +357,9 @@ cancellation or `stop_and_report` applies, a `timed_out` task with
|
|
|
352
357
|
otherwise report it. When continuing, use the original state root and a finite
|
|
353
358
|
budget, then observe the returned successor ID. Do not
|
|
354
359
|
wait indefinitely for pending publication or restart the task as an unrelated
|
|
355
|
-
dispatch. If continuation is unavailable, report its reason
|
|
360
|
+
dispatch. If continuation is unavailable, report its reason, except the busy
|
|
361
|
+
managed-workspace case in [continuation and timeout
|
|
362
|
+
recovery](references/continuation.md). Apply the same
|
|
356
363
|
`failure` and `task_record` decisions as for dispatch; never repeat an uncertain
|
|
357
364
|
successor creation.
|
|
358
365
|
|
|
@@ -377,7 +384,9 @@ recruit more agents unless that is explicitly part of the task.
|
|
|
377
384
|
- Read [continuation](references/continuation.md) for timeout or interruption
|
|
378
385
|
recovery or an exact-session follow-up.
|
|
379
386
|
- Read [managed workspaces](references/workspaces.md) for optional Git
|
|
380
|
-
worktrees, capture, review scope, release, and forgetting
|
|
387
|
+
worktrees, capture, review scope, release, and forgetting, and
|
|
388
|
+
[Git checkpoints](references/workspaces.md#git-checkpoints) before creating,
|
|
389
|
+
observing, forking from, or removing a checkpoint.
|
|
381
390
|
- Use [read-only example](examples/read-only-task.md),
|
|
382
391
|
[write example](examples/workspace-write-task.md),
|
|
383
392
|
[JSON examples](examples/json-results.md), and
|
|
@@ -11,3 +11,45 @@ own the decision order for task creation, failures, timeout continuation,
|
|
|
11
11
|
terminal outcomes, pending interaction, and bounded collection. Read them
|
|
12
12
|
before interpreting these commands; pending publication alone is not a reason
|
|
13
13
|
to wait when the task needs an answer or timeout recovery.
|
|
14
|
+
|
|
15
|
+
## Checkpoint responses
|
|
16
|
+
|
|
17
|
+
These abbreviated shapes use the delivered field names; `…` marks omitted
|
|
18
|
+
values. Apply [checkpoint results](../references/result-handling.md#checkpoint-results)
|
|
19
|
+
to the whole response and its exit code.
|
|
20
|
+
|
|
21
|
+
Accepted creation, exit `3`:
|
|
22
|
+
|
|
23
|
+
```json
|
|
24
|
+
{"schema_version":1,"command":"checkpoint","root_id":"…","admission":"unknown","liveness":"undetermined","publication":"unknown",
|
|
25
|
+
"checkpoint":{"id":"CHECKPOINT_ID","next_action":"watch_checkpoint"}}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Busy refusal, exit `3`, with no accepted ID:
|
|
29
|
+
|
|
30
|
+
```json
|
|
31
|
+
{"checkpoint":{"reason_code":"requested_action_not_authorized","next_action":"retry_create"}}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Qualified checkpoint from `status`, exit `0`; only this state may be forked:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
{"checkpoint":{"id":"CHECKPOINT_ID","current":{"id":"CHECKPOINT_ID","selection":"ordinary","cwd":"/abs/source",
|
|
38
|
+
"state":"checkpointed","snapshot_ref":"refs/delegate/ROOT_ID/checkpoints/CHECKPOINT_ID","commit_oid":"…","usable":true}}}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Exact removal attempt from `status CHECKPOINT_ID --operation OPERATION_ID`,
|
|
42
|
+
exit `0`. Creation history stays `checkpointed`, but `usable` is now `false`:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{"checkpoint":{"id":"CHECKPOINT_ID","operation_id":"OPERATION_ID",
|
|
46
|
+
"current":{"id":"CHECKPOINT_ID","selection":"ordinary","state":"checkpointed","usable":false,
|
|
47
|
+
"removal":{"operation_id":"OPERATION_ID","attempts":1,"state":"removed"}},
|
|
48
|
+
"operation":{"operation_id":"OPERATION_ID","attempts":1,"state":"removed"}}}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
An empty `list` page, exit `0`, still has the array:
|
|
52
|
+
|
|
53
|
+
```json
|
|
54
|
+
{"schema_version":1,"command":"checkpoint","root_id":"…","admission":"unknown","liveness":"undetermined","publication":"unknown","checkpoints":[]}
|
|
55
|
+
```
|
|
@@ -66,3 +66,64 @@ Save each response and exit code once. A created task is observed with
|
|
|
66
66
|
success; continue observing the same task. The Lead reviews the capture and
|
|
67
67
|
owns landing any changes. `workspace release` is explicit; no automatic
|
|
68
68
|
apply, commit, branch merge, TTL eviction, or provider-CLI fallback occurs.
|
|
69
|
+
|
|
70
|
+
## Fork from a checkpoint
|
|
71
|
+
|
|
72
|
+
Use this sequence when the worker must start from current uncommitted content
|
|
73
|
+
instead of a committed base. Run it from the Lead, not from inside a worker
|
|
74
|
+
that uses the same workspace. The [checkpoint guidance](../references/workspaces.md#checkpoint-before-fork)
|
|
75
|
+
owns the rules; [checkpoint results](../references/result-handling.md#checkpoint-results)
|
|
76
|
+
owns every response decision.
|
|
77
|
+
|
|
78
|
+
```sh
|
|
79
|
+
SOURCE="$PWD"
|
|
80
|
+
RESPONSE="$(mktemp)"
|
|
81
|
+
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint create \
|
|
82
|
+
--cwd "$SOURCE" --budget 5m --json >"$RESPONSE.checkpoint"; then
|
|
83
|
+
checkpoint_exit=0
|
|
84
|
+
else
|
|
85
|
+
checkpoint_exit=$?
|
|
86
|
+
fi
|
|
87
|
+
printf '%s\n' "$checkpoint_exit" >"$RESPONSE.checkpoint.exit"
|
|
88
|
+
cat "$RESPONSE.checkpoint"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Exit `3` with `checkpoint.id` and `next_action: "watch_checkpoint"` means the
|
|
92
|
+
request was accepted, not captured. Use that `checkpoint.id` as
|
|
93
|
+
`CHECKPOINT_ID`. Do not run `create` again.
|
|
94
|
+
|
|
95
|
+
```sh
|
|
96
|
+
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint status CHECKPOINT_ID \
|
|
97
|
+
--watch 30s --json >"$RESPONSE.checkpoint.status"; then
|
|
98
|
+
checkpoint_status_exit=0
|
|
99
|
+
else
|
|
100
|
+
checkpoint_status_exit=$?
|
|
101
|
+
fi
|
|
102
|
+
printf '%s\n' "$checkpoint_status_exit" >"$RESPONSE.checkpoint.status.exit"
|
|
103
|
+
cat "$RESPONSE.checkpoint.status"
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Repeat that status command while it exits `3`. Fork only when it exits `0`,
|
|
107
|
+
`checkpoint.current.state` is `checkpointed`, and `checkpoint.current.usable`
|
|
108
|
+
is `true`. Use `checkpoint.current.commit_oid` as `COMMIT_OID` in the first
|
|
109
|
+
dispatch example, replacing `--base HEAD` with `--base COMMIT_OID`. Report a
|
|
110
|
+
`stop_and_report` result instead of forking.
|
|
111
|
+
|
|
112
|
+
When the Lead no longer needs the checkpoint, remove it explicitly:
|
|
113
|
+
|
|
114
|
+
```sh
|
|
115
|
+
if delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" checkpoint remove CHECKPOINT_ID \
|
|
116
|
+
--budget 5m --json >"$RESPONSE.checkpoint.remove"; then
|
|
117
|
+
checkpoint_remove_exit=0
|
|
118
|
+
else
|
|
119
|
+
checkpoint_remove_exit=$?
|
|
120
|
+
fi
|
|
121
|
+
printf '%s\n' "$checkpoint_remove_exit" >"$RESPONSE.checkpoint.remove.exit"
|
|
122
|
+
cat "$RESPONSE.checkpoint.remove"
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Exit `3` with `checkpoint.operation_id` and `watch_checkpoint` means removal
|
|
126
|
+
attempt `OPERATION_ID` was accepted. Observe that exact attempt with
|
|
127
|
+
`checkpoint status CHECKPOINT_ID --operation OPERATION_ID --watch 30s --json`,
|
|
128
|
+
saving its response and exit the same way. A `retry_remove` response has no
|
|
129
|
+
`operation_id` and accepted nothing.
|
|
@@ -8,6 +8,22 @@ cap or TTL eviction. A read-only review may attach a retained workspace with
|
|
|
8
8
|
release rules live in [managed workspace guidance](workspaces.md); do not
|
|
9
9
|
restate them in each collaboration brief.
|
|
10
10
|
|
|
11
|
+
Give each participant a bounded deliverable, explicit write ownership, and the
|
|
12
|
+
inputs it depends on. Run independent assignments in parallel; dependent work
|
|
13
|
+
begins only after the required results are collected and any prerequisite
|
|
14
|
+
changes are applied and verified in the consuming worker's workspace, without
|
|
15
|
+
requiring a merge. Combine the relevant completed results in the verification
|
|
16
|
+
workspace before running checks that depend on their interaction. A worker's
|
|
17
|
+
terminal outcome establishes that assignment's result, not completion of the
|
|
18
|
+
user's full objective; keep remaining integration, verification and unresolved
|
|
19
|
+
work explicit.
|
|
20
|
+
|
|
21
|
+
When a participant must start from the Lead's current uncommitted work, the
|
|
22
|
+
Lead checkpoints that content first and forks each worker from the qualified
|
|
23
|
+
checkpoint commit with `--base`. Follow
|
|
24
|
+
[checkpoint before fork](workspaces.md#checkpoint-before-fork); a worker never
|
|
25
|
+
checkpoints a workspace its own turn is using.
|
|
26
|
+
|
|
11
27
|
## Keep each request identifiable
|
|
12
28
|
|
|
13
29
|
Choose the fan-out needed for the user's task. Each participant needs its own
|
|
@@ -6,7 +6,8 @@ All paths passed to `--root`, `--cwd`, and `--brief` must be absolute. Add
|
|
|
6
6
|
Pass the intended workspace directly. Delegate handles provider launch options;
|
|
7
7
|
do not initialize Git, change trust settings, or call a provider CLI as a
|
|
8
8
|
workspace workaround. Ordinary tasks support non-Git directories. Git is
|
|
9
|
-
required for managed worktree creation/attachment
|
|
9
|
+
required for managed worktree creation/attachment and checkpoint creation or
|
|
10
|
+
removal only; native review retains
|
|
10
11
|
its separate explicit review-target contract. See [managed workspace guidance](workspaces.md)
|
|
11
12
|
for the policy owner.
|
|
12
13
|
|
|
@@ -101,6 +102,27 @@ Continuation flags:
|
|
|
101
102
|
- `--budget DURATION`, `--model MODEL`, and `--effort VALUE`: optional overrides;
|
|
102
103
|
- `--interactive`: enable interaction when supported; already-interactive predecessors keep it.
|
|
103
104
|
|
|
105
|
+
## Checkpoint commands
|
|
106
|
+
|
|
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.
|
|
112
|
+
|
|
113
|
+
```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
|
|
119
|
+
```
|
|
120
|
+
|
|
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`.
|
|
125
|
+
|
|
104
126
|
## Choosing models and effort
|
|
105
127
|
|
|
106
128
|
Pass an explicitly supplied model ID and effort unchanged, even if discovery
|
|
@@ -53,6 +53,42 @@ Then retry the exact `continue --task PREDECESSOR_ID` after it becomes retained.
|
|
|
53
53
|
Keep the original predecessor, brief, and budget; do not replace continuation
|
|
54
54
|
with a fresh dispatch. A created successor is only observed.
|
|
55
55
|
|
|
56
|
+
**Busy managed workspace after a timeout.** This is the only case where an
|
|
57
|
+
unavailable continuation may be waited for instead of reported. It applies
|
|
58
|
+
only when a `timed_out` task reports all of `continuation.resumable: false`,
|
|
59
|
+
`continuation.reason` exactly `"managed workspace is busy"`,
|
|
60
|
+
`workspace.state: "busy"`, and `workspace.next_action: "watch_workspace"`.
|
|
61
|
+
Another reservation may still hold the workspace; do not infer which use. Wait
|
|
62
|
+
only when further work needs to continue this task, and return a committed
|
|
63
|
+
result normally. Do not wait when a cancellation (`failure.code:
|
|
64
|
+
"task_cancelled"`), a concrete fault, or `stop_and_report` applies to the task
|
|
65
|
+
or the workspace. If a successor from this predecessor was already created,
|
|
66
|
+
observe that successor instead; if its creation is uncertain, follow the
|
|
67
|
+
`task_record` stop rule in [result handling](result-handling.md).
|
|
68
|
+
|
|
69
|
+
1. Watch the workspace with the same root and a finite duration, using
|
|
70
|
+
`workspace.id` from the task response; never guess an ID or path:
|
|
71
|
+
|
|
72
|
+
```sh
|
|
73
|
+
delegate --root "${DELEGATE_ROOT:-$HOME/delegation-state}" workspace status \
|
|
74
|
+
WORKSPACE_ID --watch 30s --json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Repeat the watch only while it reports `state: "busy"`.
|
|
78
|
+
2. When it reports `state: "retained"`, run a fresh `status` for the same
|
|
79
|
+
predecessor task ID.
|
|
80
|
+
3. Only if that status now reports `continuation.resumable: true` and the task
|
|
81
|
+
rules above still permit it, run the exact `continue --task PREDECESSOR_ID`
|
|
82
|
+
once. Otherwise report its reason and stop.
|
|
83
|
+
|
|
84
|
+
Never run `continue` while `resumable` is `false`. Report any other reason,
|
|
85
|
+
workspace state, or fault under the existing guidance; do not reactivate a
|
|
86
|
+
`released` or `forgotten` workspace. An `undetermined` workspace view is
|
|
87
|
+
unobserved and follows [managed workspace results](result-handling.md#managed-workspace-results);
|
|
88
|
+
it is neither a terminal failure nor permission to continue. Do not dispatch,
|
|
89
|
+
fall back to another provider, repair the environment, or mutate the workspace
|
|
90
|
+
to free it. Availability is not guaranteed; do not wait indefinitely.
|
|
91
|
+
|
|
56
92
|
`mode` describes the provider contract:
|
|
57
93
|
|
|
58
94
|
- `native` uses the provider’s exact persisted conversation/session ID;
|
|
@@ -3,7 +3,11 @@
|
|
|
3
3
|
Use the response fields independently. A successful control command is not
|
|
4
4
|
the same as a successful provider result.
|
|
5
5
|
|
|
6
|
-
1. Save `task_id` immediately after dispatch or continue.
|
|
6
|
+
1. Save `task_id` immediately after dispatch or continue. It is the durable
|
|
7
|
+
Delegate identity. `supervisor.numeric_task_id` and a stop's
|
|
8
|
+
`numeric_task_id` are private, ephemeral queue addresses. The queue can
|
|
9
|
+
reuse a number for a later task, so a repeated number is not a binding
|
|
10
|
+
error; never use it as a task handle.
|
|
7
11
|
2. For a dispatch or continue error, inspect `task_record` first. When it is
|
|
8
12
|
`created`, observe the returned ID with `status`. Before applying the generic
|
|
9
13
|
`not_created` stop rule, handle the sole migration exception: when
|
|
@@ -91,6 +95,18 @@ The provider outcome is immutable and the workspace `CaptureReceipt` is a
|
|
|
91
95
|
separate immutable fact; a failed or unavailable capture must not be reported
|
|
92
96
|
as a provider failure when native closure is already proven.
|
|
93
97
|
|
|
98
|
+
In task `status` or `collect`, a workspace with `state: "undetermined"`,
|
|
99
|
+
`evidence_state: "unknown"`, and `next_action: "watch_workspace"` means that
|
|
100
|
+
observer's bounded view expired before it read the workspace. It is an
|
|
101
|
+
unobserved view only. It does not imply corruption, change the task fields, or
|
|
102
|
+
revoke an eligible continuation, and it does not turn a committed task into a
|
|
103
|
+
failure. Follow the task fields above: return a committed result, handle a
|
|
104
|
+
rejection using its reported guidance, and keep observing only while the task
|
|
105
|
+
fields are pending. When useful, watch the same workspace with the same root.
|
|
106
|
+
Do not dispatch again, retry the provider, fall back to another integration,
|
|
107
|
+
or repair the environment because of it. A workspace view with `stop_and_report` remains a
|
|
108
|
+
concrete failure to report.
|
|
109
|
+
|
|
94
110
|
Before a task record exists, a pending workspace provision returns
|
|
95
111
|
`task_record: "not_created"` with
|
|
96
112
|
`failure.code: "workspace_provision_pending"` and
|
|
@@ -124,6 +140,42 @@ Lead has terminal task/capture evidence and explicitly releases it. Read
|
|
|
124
140
|
[managed workspace guidance](workspaces.md) for the exact command surface and
|
|
125
141
|
review/capture/forgetting boundaries.
|
|
126
142
|
|
|
143
|
+
## Checkpoint results
|
|
144
|
+
|
|
145
|
+
A `checkpoint` response has `command: "checkpoint"` and no `task_id` or
|
|
146
|
+
`outcome`. A checkpoint receipt is Git-content evidence; it never replaces a
|
|
147
|
+
provider outcome, and a provider outcome never proves a checkpoint. Read
|
|
148
|
+
`checkpoint.id`, `checkpoint.operation_id`, `checkpoint.current`,
|
|
149
|
+
`checkpoint.operation`, `checkpoint.reason_code`, `checkpoint.next_action`, and
|
|
150
|
+
`error` separately, together with the exit code. Exit `0` alone is not enough.
|
|
151
|
+
|
|
152
|
+
| Command and response | Meaning and next action |
|
|
153
|
+
| --- | --- |
|
|
154
|
+
| `create`: exit `3`, `id` C, `next_action: "watch_checkpoint"` | Accepted, not yet captured. Watch `status C`; never repeat `create`. |
|
|
155
|
+
| `create`: exit `3`, `requested_action_not_authorized`, `retry_create`, no `id` | Busy refusal; nothing was accepted. Apply the [busy rule](workspaces.md#checkpoint-before-fork). Never wait for your own turn or switch to `--cwd`. |
|
|
156
|
+
| `remove C`: exit `3`, `id` C, `operation_id` R, `watch_checkpoint` | Removal attempt R is accepted. Watch `status C --operation R`; never repeat `remove` to observe it. |
|
|
157
|
+
| `remove C`: exit `3`, `requested_action_not_authorized`, `retry_remove`, no `operation_id` | Not accepted, usually because creation is still pending. The `id` in your command is not a removal ID. Watch `status C` until it settles, then retry `remove C` once. |
|
|
158
|
+
| `remove C`: exit `0` with `operation_id` R | R already succeeded. No new attempt was registered. |
|
|
159
|
+
| `status C`: exit `0` | Successful observation. Fork only when `current.state` is `checkpointed` and `current.usable` is `true`. With `next_action: "stop_and_report"`, report the unavailable creation or latest removal; do not fork. |
|
|
160
|
+
| `status C`: exit `3`, `watch_checkpoint` | Creation or latest removal is still pending. Keep watching the same C. |
|
|
161
|
+
| `status C --operation R`: exit `0`, `1`, or `3` | R's own result: `removed` or `nothing_to_remove` is `0`; `unavailable` is `1` with `stop_and_report`; pending is `3`. A newer attempt in `current.removal` never replaces R's outcome. Keep watching R, not the newer head. |
|
|
162
|
+
| `list`: exit `0` | One metadata page. Entries may be pending, unavailable, or removed. Run `status C` for a reconciled verdict. |
|
|
163
|
+
| Exit `1` with `stop_and_report` | Concrete failure. Report `error` and every ID already returned; do not repeat the mutation. |
|
|
164
|
+
| Exit `2` | Invalid request. Parse errors print usage on stderr without guaranteed JSON; correct the request. |
|
|
165
|
+
|
|
166
|
+
Take `C` only from `checkpoint.id` and `R` only from `checkpoint.operation_id`
|
|
167
|
+
of a response that returned them. Never invent an operation ID or reuse a
|
|
168
|
+
creation ID as `--operation`. Returned IDs stay valid after a later read
|
|
169
|
+
fault; an unreadable `current` or `operation` is omitted rather than shown as
|
|
170
|
+
empty availability.
|
|
171
|
+
|
|
172
|
+
`status --watch` repeats the same observation of the same IDs until a settled
|
|
173
|
+
or failed result or the bound ends. It never begins another action, renews a
|
|
174
|
+
helper deadline, or cancels accepted work. The latest observation chooses the
|
|
175
|
+
exit. A watch that ends at exit `3` means keep observing; it is not a failure.
|
|
176
|
+
If writing the response itself fails (exit `1`), accepted work stays accepted;
|
|
177
|
+
observe it with `status` instead of repeating the mutation.
|
|
178
|
+
|
|
127
179
|
## Offline recovery
|
|
128
180
|
|
|
129
181
|
When Delegate returns `failure.next_action: "recheck"`, use the same root and
|
|
@@ -4,7 +4,7 @@ Managed workspaces are an optional Delegate feature for tasks that need a
|
|
|
4
4
|
retained Git worktree. Ordinary delegation, including ordinary work in a
|
|
5
5
|
non-Git directory, is unchanged. Git is required only when a request creates
|
|
6
6
|
or attaches to a managed workspace (`--isolation git-worktree` or
|
|
7
|
-
`--workspace ID`).
|
|
7
|
+
`--workspace ID`), or creates or removes a [Git checkpoint](#git-checkpoints).
|
|
8
8
|
|
|
9
9
|
This reference is self-contained guidance for using managed workspaces.
|
|
10
10
|
|
|
@@ -169,6 +169,98 @@ expired provider scope is never renewed or reused. If capture
|
|
|
169
169
|
is unavailable after closure, the closure evidence can still preserve a valid
|
|
170
170
|
continuation decision; it does not rewrite the provider outcome.
|
|
171
171
|
|
|
172
|
+
## Git checkpoints
|
|
173
|
+
|
|
174
|
+
A checkpoint records the current Git content of one checkout as a synthetic
|
|
175
|
+
commit pinned by the owned ref `refs/delegate/ROOT_ID/checkpoints/CHECKPOINT_ID`.
|
|
176
|
+
It does not move `HEAD`, create or switch a branch, or change the real index.
|
|
177
|
+
The commit's tree is the full current Git-content view, built through a private
|
|
178
|
+
index with the capture algorithm above, so the same exclusions apply. Its single
|
|
179
|
+
parent is the `HEAD` the helper observed. Author, committer, and timestamp are
|
|
180
|
+
fixed Delegate values; trailers carry the checkpoint ID and request digest.
|
|
181
|
+
This is unrelated to a provider continuation `mode: "checkpoint"`.
|
|
182
|
+
|
|
183
|
+
```text
|
|
184
|
+
delegate --root ROOT checkpoint create --cwd ABS [--budget DURATION] --json
|
|
185
|
+
delegate --root ROOT checkpoint create --workspace ID [--budget DURATION] --json
|
|
186
|
+
delegate --root ROOT checkpoint status CHECKPOINT_ID [--operation OP] [--watch DURATION] --json
|
|
187
|
+
delegate --root ROOT checkpoint list [--after CHECKPOINT_ID] [--limit 1..50] --json
|
|
188
|
+
delegate --root ROOT checkpoint remove CHECKPOINT_ID [--budget DURATION] --json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
- `create` names exactly one target: `--cwd` for an absolute ordinary Git
|
|
192
|
+
checkout directory, or `--workspace` for a managed workspace ID. Nothing is
|
|
193
|
+
inferred from the current directory. Select a managed checkout only by
|
|
194
|
+
`--workspace ID`; never pass its path as `--cwd`.
|
|
195
|
+
- `status` and `remove` take the checkpoint ID `C` from the create response.
|
|
196
|
+
`list` takes no target and runs no Git command.
|
|
197
|
+
- Only `create --cwd` may initialize a new state root. Every other checkpoint
|
|
198
|
+
command needs the existing root and fails with exit `1` without creating it.
|
|
199
|
+
Use one state root for every command about the same checkpoint.
|
|
200
|
+
- `--budget` is the finite helper budget (default 5m). It is persisted with the
|
|
201
|
+
operation and does not renew any provider task budget. `--watch` exists only
|
|
202
|
+
on `status`.
|
|
203
|
+
|
|
204
|
+
A managed checkpoint is a workspace use. It needs the workspace's use owner and
|
|
205
|
+
holds that workspace's usage reservation while its helper runs, so a concurrent
|
|
206
|
+
turn or `workspace exec` on that workspace gets the normal busy response. It
|
|
207
|
+
closes without content capture. Create it while the workspace is retained.
|
|
208
|
+
|
|
209
|
+
Delegate does not restore, apply, merge, or land a checkpoint into any checkout.
|
|
210
|
+
It does not control nested delegation budgets or lifetimes either. A fork from
|
|
211
|
+
a checkpoint is an ordinary new managed dispatch with its own task budget.
|
|
212
|
+
|
|
213
|
+
### Checkpoint before fork
|
|
214
|
+
|
|
215
|
+
Use this sequence to start an isolated worker from current uncommitted work.
|
|
216
|
+
Save every response and exit code once; follow
|
|
217
|
+
[checkpoint results](result-handling.md#checkpoint-results) for each one.
|
|
218
|
+
|
|
219
|
+
1. Run `checkpoint create` with one target. Exit `3` with `checkpoint.id` and
|
|
220
|
+
`next_action: "watch_checkpoint"` means the request was accepted. It does
|
|
221
|
+
not mean the content was captured. Save that exact ID as `C`.
|
|
222
|
+
2. Run `checkpoint status C --watch 30s --json` until the exit is not `3`.
|
|
223
|
+
Never repeat `create` to observe it.
|
|
224
|
+
3. Fork only when `status` exits `0` and `checkpoint.current.state` is
|
|
225
|
+
`checkpointed` and `checkpoint.current.usable` is `true`. A `commit_oid` or
|
|
226
|
+
`snapshot_ref` alone is not proof: an unavailable creation can still name a
|
|
227
|
+
retained candidate.
|
|
228
|
+
4. Dispatch the worker with the qualified `checkpoint.current.commit_oid` as
|
|
229
|
+
the existing `--base` of a new managed workspace. Use an ordinary checkout of
|
|
230
|
+
the same repository as `--cwd`, normally the source the Lead already uses:
|
|
231
|
+
|
|
232
|
+
```text
|
|
233
|
+
delegate --root ROOT dispatch --auto --brief ABS_BRIEF --cwd ABS_SOURCE \
|
|
234
|
+
--isolation git-worktree --base COMMIT_OID \
|
|
235
|
+
--permission workspace-write --budget 30m --json
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
5. Remove the checkpoint explicitly when the Lead no longer needs it.
|
|
239
|
+
|
|
240
|
+
`status` exit `0` means a successful metadata observation, not an available
|
|
241
|
+
checkpoint. `usable` is `true` only for a `checkpointed` creation with no
|
|
242
|
+
registered removal attempt, including a failed one. It is derived from
|
|
243
|
+
Delegate's records; it is not proof that an external Git command left the ref
|
|
244
|
+
in place.
|
|
245
|
+
|
|
246
|
+
If `checkpoint create --workspace ID` returns exit `3` with
|
|
247
|
+
`reason_code: "requested_action_not_authorized"` and `retry_create`, no
|
|
248
|
+
checkpoint was accepted and no ID was assigned. When that workspace is in use
|
|
249
|
+
by the turn you are running in, do not wait for yourself, retry in a loop, or
|
|
250
|
+
retry through `--cwd`. Finish and report; the Lead creates the checkpoint after
|
|
251
|
+
your turn closes. When another use holds it, the Lead observes that workspace
|
|
252
|
+
until it is retained again, then retries the same create once.
|
|
253
|
+
|
|
254
|
+
Checkpoint refs outlive `workspace release` and `workspace forget`: the forget
|
|
255
|
+
inventory covers only the workspace's own base, capture, and baseline refs.
|
|
256
|
+
`checkpoint remove C` is the only command that removes a checkpoint ref.
|
|
257
|
+
Removal needs only the shared Git common directory, so it works after the
|
|
258
|
+
source checkout or managed checkout is gone. A missing or replaced common
|
|
259
|
+
directory makes that removal attempt `unavailable`, never `removed`. Creation
|
|
260
|
+
history stays observable after removal: `current.state` keeps the creation
|
|
261
|
+
disposition, while `current.usable` becomes `false` and `current.removal`
|
|
262
|
+
shows the latest attempt.
|
|
263
|
+
|
|
172
264
|
## Retention and forgetting
|
|
173
265
|
|
|
174
266
|
A created managed checkout is retained for every outcome, including no-op and
|