ace-assign 0.42.4 → 0.55.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.
- checksums.yaml +4 -4
- data/.ace-defaults/assign/catalog/composition-rules.yml +2 -17
- data/.ace-defaults/assign/catalog/steps/create-pr.step.yml +0 -26
- data/.ace-defaults/assign/catalog/steps/create-retro.step.yml +1 -1
- data/.ace-defaults/assign/catalog/steps/mark-task-done.step.yml +1 -2
- data/.ace-defaults/assign/catalog/steps/onboard.step.yml +0 -17
- data/.ace-defaults/assign/catalog/steps/plan-task.step.yml +0 -11
- data/.ace-defaults/assign/catalog/steps/pre-commit-review.step.yml +3 -0
- data/.ace-defaults/assign/catalog/steps/reflect-and-refactor.step.yml +3 -2
- data/.ace-defaults/assign/catalog/steps/review-pr.step.yml +0 -16
- data/.ace-defaults/assign/catalog/steps/split-subtree-root.step.yml +4 -2
- data/.ace-defaults/assign/catalog/steps/task-load.step.yml +1 -1
- data/.ace-defaults/assign/catalog/steps/verify-test-suite.step.yml +7 -34
- data/.ace-defaults/assign/catalog/steps/verify-test.step.yml +7 -4
- data/.ace-defaults/assign/catalog/steps/work-on-task.step.yml +0 -17
- data/.ace-defaults/assign/config.yml +1 -0
- data/.ace-defaults/assign/presets/fix-bug.yml +4 -3
- data/.ace-defaults/assign/presets/quick-implement.yml +1 -1
- data/.ace-defaults/assign/presets/work-on-task.yml +6 -16
- data/CHANGELOG.md +216 -0
- data/README.md +20 -43
- data/docs/demo/canonical-skill-source.gif +0 -0
- data/docs/demo/canonical-skill-source.tape.yml +51 -0
- data/docs/demo/fork-provider.cast +834 -0
- data/docs/demo/fork-provider.gif +0 -0
- data/docs/demo/fork-provider.recording.json +30 -0
- data/docs/demo/fork-provider.tape.yml +77 -20
- data/docs/getting-started.md +5 -2
- data/docs/usage.md +74 -4
- data/handbook/guides/fork-context.g.md +31 -7
- data/handbook/skills/as-assign-drive/SKILL.md +13 -1
- data/handbook/skills/as-create-retro-internal/SKILL.md +29 -0
- data/handbook/skills/as-mark-task-done-internal/SKILL.md +29 -0
- data/handbook/skills/as-reflect-and-refactor-internal/SKILL.md +30 -0
- data/handbook/skills/as-task-load-internal/SKILL.md +28 -0
- data/handbook/workflow-instructions/assign/compose.wf.md +3 -3
- data/handbook/workflow-instructions/assign/create-retro-internal.wf.md +11 -0
- data/handbook/workflow-instructions/assign/create.wf.md +6 -3
- data/handbook/workflow-instructions/assign/drive.wf.md +330 -40
- data/handbook/workflow-instructions/assign/mark-task-done-internal.wf.md +12 -0
- data/handbook/workflow-instructions/assign/prepare.wf.md +10 -5
- data/handbook/workflow-instructions/assign/reflect-and-refactor-internal.wf.md +14 -0
- data/handbook/workflow-instructions/assign/run-in-batches.wf.md +4 -1
- data/handbook/workflow-instructions/assign/start.wf.md +5 -2
- data/handbook/workflow-instructions/assign/task-load-internal.wf.md +12 -0
- data/handbook/workflow-instructions/assign/verify-test-suite.wf.md +36 -0
- data/lib/ace/assign/atoms/catalog_loader.rb +105 -2
- data/lib/ace/assign/atoms/preset_expander.rb +4 -0
- data/lib/ace/assign/atoms/step_file_parser.rb +15 -0
- data/lib/ace/assign/atoms/tree_formatter.rb +2 -2
- data/lib/ace/assign/cli/commands/add.rb +20 -11
- data/lib/ace/assign/cli/commands/assignment_target.rb +87 -3
- data/lib/ace/assign/cli/commands/create.rb +1 -1
- data/lib/ace/assign/cli/commands/fail.rb +1 -1
- data/lib/ace/assign/cli/commands/finish.rb +32 -8
- data/lib/ace/assign/cli/commands/fork_run.rb +58 -16
- data/lib/ace/assign/cli/commands/fork_session.rb +52 -0
- data/lib/ace/assign/cli/commands/list.rb +4 -3
- data/lib/ace/assign/cli/commands/retry_cmd.rb +1 -1
- data/lib/ace/assign/cli/commands/start.rb +9 -3
- data/lib/ace/assign/cli/commands/status.rb +237 -230
- data/lib/ace/assign/cli/commands/step.rb +62 -0
- data/lib/ace/assign/cli.rb +8 -1
- data/lib/ace/assign/models/assignment_info.rb +33 -4
- data/lib/ace/assign/models/queue_state.rb +101 -39
- data/lib/ace/assign/models/step.rb +17 -5
- data/lib/ace/assign/molecules/fork_session_launcher.rb +218 -21
- data/lib/ace/assign/molecules/queue_scanner.rb +1 -0
- data/lib/ace/assign/molecules/skill_assign_source_resolver.rb +223 -47
- data/lib/ace/assign/molecules/step_writer.rb +3 -3
- data/lib/ace/assign/molecules/tmux_control_surface_runner.rb +249 -0
- data/lib/ace/assign/organisms/assignment_executor.rb +355 -106
- data/lib/ace/assign/version.rb +1 -1
- data/lib/ace/assign.rb +1 -0
- metadata +35 -5
- data/.ace-defaults/assign/catalog/steps/verify-e2e.step.yml +0 -42
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
---
|
|
2
|
+
name: assign-drive
|
|
3
|
+
description: Drive an ace-assign assignment until completion or an explicit blocker.
|
|
4
|
+
allowed-tools:
|
|
5
|
+
- Bash(ace-assign:*)
|
|
6
|
+
- Bash(ace-bundle:*)
|
|
7
|
+
- Read
|
|
8
|
+
- Write
|
|
9
|
+
- AskUserQuestion
|
|
10
|
+
- Skill
|
|
2
11
|
doc-type: workflow
|
|
3
12
|
title: Drive Assignment Workflow
|
|
4
13
|
purpose: workflow instruction for driving ace-assign assignment execution
|
|
5
14
|
ace-docs:
|
|
6
|
-
last-updated: 2026-
|
|
7
|
-
last-checked: 2026-
|
|
15
|
+
last-updated: '2026-04-23'
|
|
16
|
+
last-checked: '2026-04-23'
|
|
8
17
|
---
|
|
9
18
|
|
|
10
19
|
# Drive Assignment Workflow
|
|
@@ -16,7 +25,7 @@ Drive agent execution through an active assignment by continuously checking stat
|
|
|
16
25
|
## Prerequisites
|
|
17
26
|
|
|
18
27
|
- An active assignment exists (created via `ace-assign create` or `/as-assign-create`)
|
|
19
|
-
- Assignment has at least one pending or
|
|
28
|
+
- Assignment has at least one pending or active step
|
|
20
29
|
|
|
21
30
|
## Assignment Context Propagation
|
|
22
31
|
|
|
@@ -27,11 +36,11 @@ When working with multiple concurrent assignments, the active assignment is reso
|
|
|
27
36
|
3. `.latest` symlink (auto-updated on any activity)
|
|
28
37
|
4. Scan all assignments (fallback)
|
|
29
38
|
|
|
30
|
-
If this workflow is invoked with an argument (for example `/as-assign-drive abc123@010.01`), treat that value as the initial assignment target. If no argument is provided, resolve one active assignment and pin it for the entire loop.
|
|
39
|
+
If this workflow is invoked with an argument (for example `/as-assign-drive abc123@010.01`), treat that exact value as the initial assignment target. If no argument is provided, resolve one active assignment and pin it for the entire loop.
|
|
31
40
|
|
|
32
41
|
```bash
|
|
33
|
-
# Set once from workflow argument (empty when
|
|
34
|
-
ASSIGNMENT_TARGET="${1:-}"
|
|
42
|
+
# Set once from workflow argument or internal scoped default (empty when neither is provided)
|
|
43
|
+
ASSIGNMENT_TARGET="${1:-${ACE_ASSIGN_DEFAULT_TARGET:-}}"
|
|
35
44
|
|
|
36
45
|
# Resolve and pin assignment identity for the full drive loop
|
|
37
46
|
if [ -n "$ASSIGNMENT_TARGET" ]; then
|
|
@@ -50,6 +59,8 @@ if [ -z "$ASSIGNMENT_TARGET" ]; then
|
|
|
50
59
|
fi
|
|
51
60
|
```
|
|
52
61
|
|
|
62
|
+
`ACE_ASSIGN_DEFAULT_TARGET` is an internal fallback passed by `fork-run` launches. If it is present, use it exactly. Do not widen it back to the parent assignment, do not drop the `@<root>` scope suffix, and do not re-resolve an unscoped assignment target later in the loop.
|
|
63
|
+
|
|
53
64
|
### Explicit Assignment Targeting (Recommended)
|
|
54
65
|
|
|
55
66
|
Use explicit flags to propagate assignment context across subprocesses and tools:
|
|
@@ -72,7 +83,7 @@ ace-assign status --assignment abc123@010.01
|
|
|
72
83
|
ace-assign finish --message done.md --assignment abc123@010.01
|
|
73
84
|
```
|
|
74
85
|
|
|
75
|
-
When an assignment target includes scope (`<id>@<root>`), `ace-assign finish --message`
|
|
86
|
+
When an assignment target includes scope (`<id>@<root>`), `ace-assign finish --message` finishes only within that subtree. Pending descendants remain pending until scoped execution explicitly starts them.
|
|
76
87
|
|
|
77
88
|
Helper command:
|
|
78
89
|
|
|
@@ -104,12 +115,57 @@ ace-assign finish --message done.md --assignment <id>
|
|
|
104
115
|
|
|
105
116
|
Repeat the following cycle until all steps are done or failed:
|
|
106
117
|
|
|
118
|
+
### Run-Until-Blocked Contract
|
|
119
|
+
|
|
120
|
+
Once `ASSIGNMENT_TARGET` is pinned, keep driving that exact target until exactly one of these stop conditions is true:
|
|
121
|
+
|
|
122
|
+
1. `ace-assign status --assignment "$ASSIGNMENT_TARGET"` shows all steps complete
|
|
123
|
+
2. A workflow step explicitly requires HITL or other user judgment before execution can continue
|
|
124
|
+
3. A step reaches an unrecoverable failure path and this workflow instructs you to stop
|
|
125
|
+
4. The user explicitly interrupts or cancels execution
|
|
126
|
+
|
|
127
|
+
Do **not** stop merely because you have useful progress to report.
|
|
128
|
+
|
|
129
|
+
- Intermediate progress belongs in short progress updates, not in a final completion response.
|
|
130
|
+
- `pending` steps with no active step are not a stop condition. They mean the queue must be advanced and the loop must continue.
|
|
131
|
+
- A batch child subtree finishing is not a completion boundary for the parent assignment.
|
|
132
|
+
- If `ASSIGNMENT_TARGET` includes `@<root>`, that scoped subtree is the entire execution boundary.
|
|
133
|
+
- A paused assignment with remaining runnable work is not "done"; treat it as a recoverable scheduler state and resume the loop.
|
|
134
|
+
|
|
135
|
+
### Final Response Gate
|
|
136
|
+
|
|
137
|
+
Before sending any final user-facing completion response, re-run:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
ace-assign status --assignment "$ASSIGNMENT_TARGET" --format json
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
You may only stop and send a final response when one of these is true:
|
|
144
|
+
|
|
145
|
+
- the pinned assignment has no remaining runnable `pending` or `active` work
|
|
146
|
+
- the workflow recorded an explicit blocker or unrecoverable failure stop condition
|
|
147
|
+
- the user explicitly interrupted or canceled execution
|
|
148
|
+
|
|
149
|
+
Do **not** send a final response merely because:
|
|
150
|
+
|
|
151
|
+
- one child subtree completed in the parent assignment
|
|
152
|
+
- useful progress was made
|
|
153
|
+
- a prior terminal session ended
|
|
154
|
+
- the parent assignment surfaced the next pending step after active work finished
|
|
155
|
+
|
|
156
|
+
Concrete example:
|
|
157
|
+
|
|
158
|
+
- `010.01 done` and `010.02.01 active` means continue driving the assignment. It is not a completion boundary.
|
|
159
|
+
- `040.01 done`, `040.02 done`, and `040.03 done` under `/as-assign-drive <id>@040` means stop the scoped worker. Do not inspect parent step `070` from that scoped process.
|
|
160
|
+
|
|
107
161
|
### Step Execution Policy
|
|
108
162
|
|
|
109
163
|
- Planned steps are mandatory work items. Do not skip them by judgment.
|
|
110
164
|
- For each active step, do exactly one of:
|
|
165
|
+
|
|
111
166
|
1. Execute the step and report completion with `ace-assign finish --message`
|
|
112
167
|
2. Attempt execution, capture blocker evidence, and mark failed with `ace-assign fail`
|
|
168
|
+
|
|
113
169
|
- Never use report text to "skip" or synthesize completion for planned steps.
|
|
114
170
|
- **Fork-delegation constraint**: If the active step has `FORK: yes`, the driver MUST delegate via `ace-assign fork-run`. The driver MUST NOT execute fork-marked steps inline, absorb remaining fork children after partial failure, or inject retry steps as top-level siblings. All fork recovery goes through re-fork (see [Fork-Run Crash Recovery](#fork-run-crash-recovery-partial-completion)).
|
|
115
171
|
- **Conditional release in review subtrees**: A `release` step inside a review cycle (e.g., `[review-pr, apply-feedback, release]`) MUST skip the version bump when prior sibling steps produced no code changes. If `apply-feedback` reported no findings or `git diff HEAD~1 --stat` shows only report files, mark release done with "no-op: no changes to release" instead of bumping.
|
|
@@ -119,30 +175,40 @@ Repeat the following cycle until all steps are done or failed:
|
|
|
119
175
|
After completing or failing each step, evaluate whether the assignment needs adaptation:
|
|
120
176
|
|
|
121
177
|
- **Test failures detected** → Consider adding a fix-tests step:
|
|
178
|
+
|
|
122
179
|
```bash
|
|
123
180
|
ace-assign add "fix-tests" --instructions "Fix failing tests identified in step NNN" --assignment "$ASSIGNMENT_TARGET"
|
|
124
181
|
```
|
|
125
182
|
|
|
183
|
+
- **E2E failures detected** (`ace-test-e2e` command, `.ace-local/test-e2e/` evidence, or explicit failing scenario IDs) → add an E2E-specific fix step instead of generic `fix-tests` / `fix-issue`:
|
|
184
|
+
|
|
185
|
+
```bash
|
|
186
|
+
ace-assign add "fix-e2e" --instructions "Use /as-e2e-fix for the failing package and scenario IDs from the recorded evidence. If analysis is missing, let /as-e2e-fix generate it via wfi://e2e/analyze-failures before applying fixes. Re-run the targeted failing scenarios before completing this step." --assignment "$ASSIGNMENT_TARGET"
|
|
187
|
+
```
|
|
188
|
+
|
|
126
189
|
- **Review found critical issues** → Consider adding an apply-critical-fixes step:
|
|
190
|
+
|
|
127
191
|
```bash
|
|
128
192
|
ace-assign add "apply-critical-fixes" --instructions "Address critical review findings before proceeding" --assignment "$ASSIGNMENT_TARGET"
|
|
129
193
|
```
|
|
130
194
|
|
|
131
195
|
- **Missing prerequisite discovered** → Consider adding the prerequisite step:
|
|
196
|
+
|
|
132
197
|
```bash
|
|
133
198
|
ace-assign add "missing-prereq" --instructions "Complete prerequisite work discovered during step NNN" --assignment "$ASSIGNMENT_TARGET"
|
|
134
199
|
```
|
|
135
200
|
|
|
136
|
-
- **Metadata hint**: Step file contains `trigger_on_failure`
|
|
201
|
+
- **Metadata hint**: Step file contains `trigger_on_failure` -- if the step failed, inject the referenced step type
|
|
137
202
|
|
|
138
203
|
Use `decision_notes` from step metadata (if present) as additional guidance for these assessments.
|
|
139
204
|
|
|
140
205
|
- **Review-cycle circuit breaker**: When a review fork subtree fails due to provider unavailability (not code bugs), evaluate whether to attempt the next review cycle:
|
|
206
|
+
|
|
141
207
|
- If the **first** review cycle (valid) failed on providers: skip remaining cycles (fit, shine). Mark them done with "skipped: provider unavailable for prior cycle" reports.
|
|
142
208
|
- If the **second** cycle (fit) failed after valid succeeded: skip shine. Valid already captured correctness issues.
|
|
143
209
|
- **Never retry a provider-failed review cycle more than once.** If the re-fork also fails on providers, mark the cycle done-with-skip and move on.
|
|
144
210
|
|
|
145
|
-
- **Transient network failure retry**: When a fork subtree fails due to a transient network error (connection reset, DNS timeout, socket hangup)
|
|
211
|
+
- **Transient network failure retry**: When a fork subtree fails due to a transient network error (connection reset, DNS timeout, socket hangup) -- as opposed to provider unavailability or auth failure -- wait 30 seconds and re-fork once. If the re-fork also fails on a network error, treat it as a hard failure and apply the circuit breaker rules above. Auth errors (401/403) and not-found errors (404) are never transient -- fail immediately on those.
|
|
146
212
|
|
|
147
213
|
### 1. Check Status
|
|
148
214
|
|
|
@@ -152,14 +218,20 @@ echo "$STATUS_OUTPUT"
|
|
|
152
218
|
```
|
|
153
219
|
|
|
154
220
|
Read the output to identify:
|
|
221
|
+
|
|
155
222
|
- Assignment ID (must remain equal to pinned `ASSIGNMENT_ID`)
|
|
156
|
-
-
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
- Remaining steps in the queue
|
|
223
|
+
- Active step list in scope, or next step when nothing is active
|
|
224
|
+
- Remaining visible steps in the queue preview
|
|
225
|
+
- Hidden-step counts for large queues
|
|
160
226
|
|
|
161
227
|
**Note:** `ace-assign status` is the source of truth for assignment state. The step files in the `steps/` directory are the backing store, but always query status via the command for accurate information.
|
|
162
228
|
|
|
229
|
+
Load instructions separately when needed:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
ace-assign step --assignment "$ASSIGNMENT_TARGET"
|
|
233
|
+
```
|
|
234
|
+
|
|
163
235
|
### 2. Auto-Delegate Fork Subtrees (When Applicable)
|
|
164
236
|
|
|
165
237
|
Before executing the current step inline, check whether the active step is inside a fork-enabled subtree.
|
|
@@ -184,6 +256,20 @@ fi
|
|
|
184
256
|
|
|
185
257
|
This prevents fork agents from stalling on pre-existing unrelated changes. Assignment metadata files (`.ace-local/`, `.ace-tasks/`, `.ace-retros/`) are expected to be dirty during drive execution and are excluded.
|
|
186
258
|
|
|
259
|
+
Dirty-tree classification rule:
|
|
260
|
+
|
|
261
|
+
- Do not auto-commit every unrelated dirty path.
|
|
262
|
+
- First classify the dirty state:
|
|
263
|
+
- **intentional work**: user edits, task implementation, or other meaningful repo changes that must be preserved
|
|
264
|
+
- **generated side effects**: bootstrap/config scaffolding, handbook projection output, caches, or other machine-generated files outside the current task scope
|
|
265
|
+
- If the dirty paths are intentional work, preserve them and either continue with scope awareness or commit them deliberately.
|
|
266
|
+
- If the dirty paths are generated side effects outside the current task scope, clean/reset them before `fork-run` instead of committing them.
|
|
267
|
+
- Only stop for user input when classification remains ambiguous after inspection.
|
|
268
|
+
|
|
269
|
+
Example:
|
|
270
|
+
|
|
271
|
+
- A bulk untracked `.ace/...` tree created by `ace-config sync` is generated side-effect output. Clean it; do not create a "pre-fork" commit for it.
|
|
272
|
+
|
|
187
273
|
#### Delegation Rule
|
|
188
274
|
|
|
189
275
|
**FORK SIGNAL**: If a step row shows `yes` in the `FORK` column, the step itself has `context: fork` and MUST be delegated via `fork-run`.
|
|
@@ -194,6 +280,7 @@ This prevents fork agents from stalling on pre-existing unrelated changes. Assig
|
|
|
194
280
|
| `FORK: ` (empty) | Step is not fork-enabled | Execute inline (or inspect fork-enabled children if batch parent) |
|
|
195
281
|
|
|
196
282
|
**Example status output:**
|
|
283
|
+
|
|
197
284
|
```
|
|
198
285
|
NUMBER STATUS NAME FORK CHILDREN
|
|
199
286
|
------------------------------------------------------------------------------
|
|
@@ -202,6 +289,7 @@ NUMBER STATUS NAME FORK CHILDREN
|
|
|
202
289
|
```
|
|
203
290
|
|
|
204
291
|
Step 020 shows `FORK: yes` → run:
|
|
292
|
+
|
|
205
293
|
```bash
|
|
206
294
|
ace-assign fork-run --assignment <id>@020
|
|
207
295
|
```
|
|
@@ -209,8 +297,15 @@ ace-assign fork-run --assignment <id>@020
|
|
|
209
297
|
**Delegation boundary rule**
|
|
210
298
|
|
|
211
299
|
- Outside a delegated fork scope, do NOT execute fork steps inline.
|
|
212
|
-
-
|
|
213
|
-
- If
|
|
300
|
+
- First decide whether the fork boundary is already entered before issuing `fork-run`.
|
|
301
|
+
- If scoped status for `--assignment <id>@<root>` already resolves work inside `<root>`, the fork boundary is already entered: continue inline and never call `fork-run` again for the same `<root>`.
|
|
302
|
+
- A same-root call to `ace-assign fork-run --assignment <id>@<root>` from inside that exact scoped subtree is invalid and must be treated as an error, not a retry path.
|
|
303
|
+
- If the scoped root itself is active and no child in that subtree is active yet, run:
|
|
304
|
+
|
|
305
|
+
- `ace-assign start --assignment "$ASSIGNMENT_TARGET"`
|
|
306
|
+
|
|
307
|
+
- After a child step inside the scoped subtree becomes active, continue executing that child inline within the same scope.
|
|
308
|
+
- Only if the current step is a top-level step with `FORK: yes` and no matching scope is already active should the driver delegate via `fork-run`.
|
|
214
309
|
|
|
215
310
|
#### Nested Batch Containers (Container → Fork Children)
|
|
216
311
|
|
|
@@ -222,10 +317,12 @@ A batch container (e.g., `010`) may have children but no fork context itself (`F
|
|
|
222
317
|
- `fork_retry_limit: <N>` (default `1`)
|
|
223
318
|
|
|
224
319
|
**How to distinguish:**
|
|
320
|
+
|
|
225
321
|
- **Direct fork target**: `FORK: yes` on the current step → fork-run the current step.
|
|
226
322
|
- **Batch container**: `FORK: ` on parent, but children include `FORK: yes` steps.
|
|
227
323
|
|
|
228
324
|
**Pattern for batch containers:**
|
|
325
|
+
|
|
229
326
|
```bash
|
|
230
327
|
# Read scheduler metadata from parent step 010
|
|
231
328
|
# parallel=false => sequential, still fork every child
|
|
@@ -236,9 +333,11 @@ A batch container (e.g., `010`) may have children but no fork context itself (`F
|
|
|
236
333
|
|
|
237
334
|
- Iterate pending child steps in number order.
|
|
238
335
|
- For each child with `FORK: yes`, run:
|
|
336
|
+
|
|
239
337
|
- `ace-assign fork-run --assignment <id>@<child>`
|
|
338
|
+
|
|
240
339
|
- Re-check status after each child.
|
|
241
|
-
- Do not pause for user input between children
|
|
340
|
+
- Do not pause for user input between children -- treat the batch loop as a single unit (see Batch Continuation Rule below).
|
|
242
341
|
|
|
243
342
|
**Parallel mode (`parallel: true`)**
|
|
244
343
|
|
|
@@ -262,12 +361,19 @@ The driver MUST NOT pause for user input between child fork-runs within a batch
|
|
|
262
361
|
|
|
263
362
|
1. Verify the child's reports (see Subtree Guard below).
|
|
264
363
|
2. If reports indicate successful completion, immediately launch the next pending child.
|
|
265
|
-
3. Treat the entire batch loop as a single unit of execution
|
|
364
|
+
3. Treat the entire batch loop as a single unit of execution -- only pause on quality concerns flagged during report review.
|
|
266
365
|
4. For timeout-constrained environments: launch `fork-run` in background, poll for completion, then loop to the next child without pausing.
|
|
267
366
|
|
|
367
|
+
Conversational boundary rule:
|
|
368
|
+
|
|
369
|
+
- Do not end the turn or emit a final user-facing completion summary after a child subtree unless the entire assignment now satisfies a real stop condition from [Run-Until-Blocked Contract](#run-until-blocked-contract).
|
|
370
|
+
- If child `010.01` completes, reports are clean, and `010.02` is still pending, immediately advance/resume the queue and continue driving.
|
|
371
|
+
- Treat child-subtree completion as progress within the same drive session, not as permission to stop.
|
|
372
|
+
|
|
268
373
|
**Failure policy (retry-then-stop)**
|
|
269
374
|
|
|
270
375
|
- On any child failure:
|
|
376
|
+
|
|
271
377
|
- Pause launching new children immediately.
|
|
272
378
|
- Wait for in-flight children to finish.
|
|
273
379
|
- Retry failed child once (`fork_retry_limit=1` default).
|
|
@@ -279,11 +385,29 @@ The driver MUST NOT pause for user input between child fork-runs within a batch
|
|
|
279
385
|
```bash
|
|
280
386
|
STATUS_JSON=$(ace-assign status --assignment "$ASSIGNMENT_TARGET" --format json)
|
|
281
387
|
ASSIGNMENT_ID=$(echo "$STATUS_JSON" | ruby -rjson -e 'puts JSON.parse(STDIN.read).dig("assignment", "id")')
|
|
388
|
+
SCOPED_ROOT="${ASSIGNMENT_TARGET#*@}"
|
|
389
|
+
ACTIVE_STEP=$(echo "$STATUS_JSON" | ruby -rjson -e '
|
|
390
|
+
scoped_root = ARGV[0].to_s
|
|
391
|
+
active = Array(JSON.parse(STDIN.read)["active_steps"])
|
|
392
|
+
child = active.find { |step| step["number"] != scoped_root && step["number"].start_with?("#{scoped_root}.") }
|
|
393
|
+
puts(child ? child["number"] : active.first&.fetch("number", nil))
|
|
394
|
+
' "$SCOPED_ROOT")
|
|
395
|
+
|
|
396
|
+
if [ -n "$SCOPED_ROOT" ] && [ "$ACTIVE_STEP" = "$SCOPED_ROOT" ]; then
|
|
397
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
398
|
+
continue
|
|
399
|
+
fi
|
|
400
|
+
|
|
282
401
|
FORK_ROOT=$(echo "$STATUS_JSON" | ruby -rjson -e '
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
402
|
+
scoped_root = ARGV[0].to_s
|
|
403
|
+
active = Array(JSON.parse(STDIN.read)["active_steps"])
|
|
404
|
+
next_fork = active.find do |step|
|
|
405
|
+
step["context"] == "fork" &&
|
|
406
|
+
(scoped_root.empty? || (step["number"] != scoped_root && !step["number"].start_with?("#{scoped_root}.")))
|
|
407
|
+
end
|
|
408
|
+
puts next_fork["number"] if next_fork
|
|
409
|
+
' "$SCOPED_ROOT")
|
|
410
|
+
if [ -n "$FORK_ROOT" ] && [ "$FORK_ROOT" != "$SCOPED_ROOT" ]; then
|
|
287
411
|
ace-assign fork-run --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}"
|
|
288
412
|
# Re-check status after subtree delegation completes
|
|
289
413
|
continue
|
|
@@ -292,13 +416,103 @@ fi
|
|
|
292
416
|
|
|
293
417
|
`fork-run` executes the entire subtree in one dedicated process and returns when the subtree is complete or failed.
|
|
294
418
|
|
|
419
|
+
#### Fork Wait Continuation Rule
|
|
420
|
+
|
|
421
|
+
After launching `ace-assign fork-run`, the driver remains inside the same drive session.
|
|
422
|
+
|
|
423
|
+
- If fork session metadata includes `callback_pane`, callback mode is active. In that case:
|
|
424
|
+
|
|
425
|
+
- do not poll the forked subtree on a timer
|
|
426
|
+
- do not run the `sleep 360` loop
|
|
427
|
+
- remain idle after launch and wait for the child forked agent to send a final status message back into the origin pane
|
|
428
|
+
- treat the callback message as the trigger to resume the parent drive loop
|
|
429
|
+
- if the callback never arrives and the session is resumed later, recover from assignment state and scoped status instead of waiting forever
|
|
430
|
+
|
|
431
|
+
- Treat "fork subtree is still running" as an internal progress state, not as a stop condition.
|
|
432
|
+
- Do not end the turn, emit a final user-facing completion summary, or hand control back to the user merely because the driver is waiting on fork completion.
|
|
433
|
+
- Poll the forked subtree every 6 minutes by default. Use two signals on each poll:
|
|
434
|
+
|
|
435
|
+
1. poll the live fork session/process handle
|
|
436
|
+
2. poll scoped assignment status with `ace-assign status --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}"`
|
|
437
|
+
|
|
438
|
+
- Treat scoped assignment status as the source of truth for subtree completion. Terminal PTY output is helpful telemetry, but it is not the canonical completion signal.
|
|
439
|
+
- Continue polling until one of these is true:
|
|
440
|
+
|
|
441
|
+
- the `fork-run` process exits
|
|
442
|
+
- scoped status for the subtree proves every step inside that subtree is terminal (`done` or `failed`)
|
|
443
|
+
- the workflow reaches a documented blocker or failure path
|
|
444
|
+
|
|
445
|
+
- If scoped subtree status is terminal, immediately treat the fork as complete even if the PTY stayed quiet or the original terminal handle has already disappeared.
|
|
446
|
+
- A quiet terminal is not a stall by itself. Only treat the fork as stalled when there is no scoped status movement, no new subtree reports, and no process exit for about 30 minutes.
|
|
447
|
+
- When the wait ends, immediately re-enter the parent drive loop. Do not stop between "fork finished" and "next runnable step started."
|
|
448
|
+
|
|
449
|
+
#### Fork Callback Rule
|
|
450
|
+
|
|
451
|
+
When `ACE_ASSIGN_CALLBACK_PANE` is present in the forked child environment:
|
|
452
|
+
|
|
453
|
+
- before stopping for either success or failure, send one final sentence back to the origin pane with direct `ace-tmux send`
|
|
454
|
+
- use the exact pane target from `ACE_ASSIGN_CALLBACK_PANE`
|
|
455
|
+
- use a success sentence shaped like:
|
|
456
|
+
|
|
457
|
+
```bash
|
|
458
|
+
ace-tmux send --pane "$ACE_ASSIGN_CALLBACK_PANE" --msg "Fork subtree ${FORK_ROOT} for assignment ${ASSIGNMENT_ID} completed. Resume parent assignment drive now." --key Enter
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
- use a failure sentence shaped like:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
ace-tmux send --pane "$ACE_ASSIGN_CALLBACK_PANE" --msg "Fork subtree ${FORK_ROOT} for assignment ${ASSIGNMENT_ID} failed. Resume parent assignment drive and inspect scoped status." --key Enter
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
- do not invent a new skill or wrapper for this callback; use `ace-tmux send` directly
|
|
468
|
+
|
|
469
|
+
#### Post-Fork Resume Checklist
|
|
470
|
+
|
|
471
|
+
Immediately after the fork wait ends, run this checklist in order:
|
|
472
|
+
|
|
473
|
+
1. If `fork-run` exited non-zero, enter [Fork-Run Recovery](#fork-run-recovery).
|
|
474
|
+
2. Read and review subtree reports.
|
|
475
|
+
3. Check for uncommitted changes and commit safety-net leftovers if needed.
|
|
476
|
+
4. Query parent assignment status.
|
|
477
|
+
5. If no active step exists but pending work remains, run:
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
6. If pending or `active` work remains and no blocker was recorded, continue the main loop immediately.
|
|
484
|
+
7. Only stop if the assignment now satisfies a real stop condition from [Run-Until-Blocked Contract](#run-until-blocked-contract).
|
|
485
|
+
|
|
486
|
+
#### Scoped Worker Completion Boundary
|
|
487
|
+
|
|
488
|
+
When `ASSIGNMENT_TARGET` already includes `@<root>`, the current process is the subtree worker, not the parent orchestrator.
|
|
489
|
+
|
|
490
|
+
- After report review, re-check `ace-assign status --assignment "$ASSIGNMENT_TARGET"`.
|
|
491
|
+
- If that scoped status is terminal, stop immediately.
|
|
492
|
+
- Do not query the parent assignment from that scoped worker.
|
|
493
|
+
- Do not widen a scoped target back to parent assignment status.
|
|
494
|
+
- Do not continue into later sibling roots such as `070` from `/as-assign-drive <id>@040`.
|
|
495
|
+
- Parent resume after subtree completion belongs only to the unscoped driver that launched the fork.
|
|
496
|
+
|
|
497
|
+
Detached-resume rule:
|
|
498
|
+
|
|
499
|
+
- If a prior drive session or terminal ended, a new `/as-assign-drive` invocation MUST recover from assignment state, not from the old terminal handle.
|
|
500
|
+
- On re-entry, first inspect parent `ace-assign status --assignment "$ASSIGNMENT_TARGET"` and, when applicable, scoped subtree status for the last in-flight fork root.
|
|
501
|
+
- If the child subtree is already terminal, run the same post-fork checklist immediately and continue the parent queue without waiting for any historical `fork-run` session to be observed again.
|
|
502
|
+
|
|
503
|
+
Concrete example:
|
|
504
|
+
|
|
505
|
+
- Incorrect: launch `fork-run` for `040`, post "waiting on subtree", stop responding, and never resume `070`.
|
|
506
|
+
- Correct: launch `fork-run` for `040`, poll until it finishes, review reports, re-check `ace-assign status --assignment "$ASSIGNMENT_TARGET"`, then advance and launch `070` if it is the next runnable step.
|
|
507
|
+
- Correct after interruption: re-run `/as-assign-drive <assignment-id>`, detect that `040` is already terminal from scoped status/reports, then immediately advance and launch `070`.
|
|
508
|
+
|
|
295
509
|
> **Long-running execution:** `fork-run` typically takes 10-30 minutes depending on subtree complexity. If your environment has bash timeout limits (e.g., Claude Code's 10-minute Bash tool limit), run `fork-run` in background and poll for completion:
|
|
296
510
|
>
|
|
297
511
|
> ```bash
|
|
298
512
|
> # Run fork-run in background (use run_in_background: true in Claude Code)
|
|
299
513
|
> ace-assign fork-run --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}" &
|
|
300
514
|
>
|
|
301
|
-
> # Poll scoped status every
|
|
515
|
+
> # Poll scoped status every 6 minutes until subtree completes
|
|
302
516
|
> while true; do
|
|
303
517
|
> STATUS_JSON=$(ace-assign status --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}" --format json)
|
|
304
518
|
> COMPLETE=$(echo "$STATUS_JSON" | ruby -rjson -e '
|
|
@@ -307,36 +521,41 @@ fi
|
|
|
307
521
|
> puts steps.all? { |step| step["status"] == "done" || step["status"] == "failed" }
|
|
308
522
|
> ')
|
|
309
523
|
> [ "$COMPLETE" = "true" ] && break
|
|
310
|
-
> sleep
|
|
524
|
+
> sleep 360
|
|
311
525
|
> done
|
|
526
|
+
> ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
312
527
|
> ```
|
|
313
528
|
|
|
314
529
|
#### Subtree Completion: Task Status Verification
|
|
315
530
|
|
|
316
531
|
After a fork subtree completes (work-on-task finishes successfully):
|
|
317
532
|
|
|
318
|
-
1. **Verify ace-
|
|
533
|
+
1. **Verify ace-task status matches assignment status.** If the assignment shows `work-on-task` as done but ace-task still shows `in-progress`, status drift has occurred.
|
|
319
534
|
|
|
320
535
|
2. **If mark-task-done step was NOT included in the assignment** (common for ad-hoc assignments):
|
|
536
|
+
|
|
321
537
|
```bash
|
|
322
538
|
# Manually sync status before reporting subtree complete
|
|
323
539
|
ace-task done {taskref}
|
|
324
540
|
ace-task {taskref} # Verify it shows status: done
|
|
325
541
|
```
|
|
326
542
|
|
|
327
|
-
3. **Report the subtree complete only after verification.** This prevents the orchestrator from showing work as done while ace-
|
|
543
|
+
3. **Report the subtree complete only after verification.** This prevents the orchestrator from showing work as done while ace-task shows it as in-progress.
|
|
328
544
|
|
|
329
545
|
#### Subtree Guard: Review Fork Reports Before Continuing
|
|
330
546
|
|
|
331
547
|
After fork-run returns and completion is verified, the driver acts as the **guard** for the subtree. Before continuing to the next step:
|
|
332
548
|
|
|
333
549
|
1. **Read all subtree report files** from `.ace-local/assign/<assignment-id>/reports/`:
|
|
550
|
+
|
|
334
551
|
```bash
|
|
335
552
|
# List and read all reports for the completed subtree
|
|
336
553
|
ls .ace-local/assign/${ASSIGNMENT_ID}/reports/${FORK_ROOT}.*
|
|
337
554
|
# Read each report file to review the forked agent's work
|
|
338
555
|
```
|
|
556
|
+
|
|
339
557
|
2. **Check for uncommitted changes** left by the fork agent:
|
|
558
|
+
|
|
340
559
|
```bash
|
|
341
560
|
DIRTY=$(git status --short)
|
|
342
561
|
if [ -n "$DIRTY" ]; then
|
|
@@ -346,7 +565,8 @@ After fork-run returns and completion is verified, the driver acts as the **guar
|
|
|
346
565
|
ace-git-commit -i "commit changes left by fork subtree ${FORK_ROOT}"
|
|
347
566
|
fi
|
|
348
567
|
```
|
|
349
|
-
|
|
568
|
+
|
|
569
|
+
Fork agents are expected to commit all their work. Uncommitted files indicate incomplete commit discipline -- note this when reviewing reports.
|
|
350
570
|
3. **Verify quality**: Check that reports indicate successful completion, not just step advancement.
|
|
351
571
|
4. **Flag concerns**: If any report indicates partial work, errors, or skipped steps, stop and ask the user before continuing.
|
|
352
572
|
5. **Only then continue** the main drive loop to the next step.
|
|
@@ -357,12 +577,33 @@ After fork-run returns and completion is verified, the driver acts as the **guar
|
|
|
357
577
|
|
|
358
578
|
After all fork subtrees within a batch container complete, the container auto-marks as Done. However, the queue pointer may not automatically advance to the next top-level step.
|
|
359
579
|
|
|
360
|
-
**After verifying all fork subtree reports**, if `ace-assign status` shows no
|
|
580
|
+
**After verifying all fork subtree reports**, if `ace-assign status` shows no active step (all completed steps but no new active step), run:
|
|
581
|
+
|
|
361
582
|
```bash
|
|
362
583
|
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
363
584
|
```
|
|
585
|
+
|
|
364
586
|
This advances the queue to the next pending top-level step.
|
|
365
587
|
|
|
588
|
+
If pending steps still remain after this queue advancement, continue the drive loop immediately. Do not stop after printing a partial progress summary.
|
|
589
|
+
|
|
590
|
+
Concrete example:
|
|
591
|
+
|
|
592
|
+
```text
|
|
593
|
+
010.01 done
|
|
594
|
+
010.02 pending
|
|
595
|
+
010.03 pending
|
|
596
|
+
Current Step: none
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
This state means "resume driving", not "return final status". Run:
|
|
600
|
+
|
|
601
|
+
```bash
|
|
602
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
603
|
+
```
|
|
604
|
+
|
|
605
|
+
then continue the loop from status check.
|
|
606
|
+
|
|
366
607
|
#### Fork-Run Recovery
|
|
367
608
|
|
|
368
609
|
When `fork-run` exits non-zero, invoke the fork recovery workflow:
|
|
@@ -428,9 +669,11 @@ For external-facing steps (for example PR/review/release/push/update lifecycle s
|
|
|
428
669
|
|
|
429
670
|
- Attempt the step command(s) first.
|
|
430
671
|
- If blocked, capture concrete evidence:
|
|
672
|
+
|
|
431
673
|
- command attempted
|
|
432
674
|
- exact error output
|
|
433
675
|
- why the step cannot proceed
|
|
676
|
+
|
|
434
677
|
- Mark step failed with evidence (do not report synthetic completion).
|
|
435
678
|
|
|
436
679
|
```bash
|
|
@@ -449,27 +692,35 @@ Use HITL when:
|
|
|
449
692
|
For a blocked step:
|
|
450
693
|
|
|
451
694
|
1. Create a HITL event with assignment and step context:
|
|
695
|
+
|
|
452
696
|
```bash
|
|
453
697
|
ace-hitl create "Need product decision" --question "Should retries be visible?" --assignment <id> --step <number> --step-name <name> --resume "/as-assign-drive <id>"
|
|
454
698
|
```
|
|
699
|
+
|
|
455
700
|
2. Fail the step using canonical stall format:
|
|
701
|
+
|
|
456
702
|
```bash
|
|
457
703
|
ace-assign fail --message "HITL: <hitl-id> <hitl-path>" --assignment "$ASSIGNMENT_TARGET"
|
|
458
704
|
```
|
|
705
|
+
|
|
459
706
|
3. Human/operator resolves:
|
|
707
|
+
|
|
460
708
|
```bash
|
|
461
709
|
ace-hitl show <hitl-id>
|
|
462
710
|
ace-hitl update <hitl-id> --answer "Yes, show retries in user-facing output."
|
|
463
711
|
ace-hitl wait <hitl-id>
|
|
464
712
|
```
|
|
713
|
+
|
|
465
714
|
4. Discover pending HITL work:
|
|
466
715
|
- Main checkout default (smart local-first): `ace-hitl list`
|
|
467
716
|
- Explicit scope controls: `ace-hitl list --scope current` and `ace-hitl list --scope all`
|
|
468
717
|
5. Polling is default: requesting agent waits on its own HITL id (`ace-hitl wait <hitl-id>`), not global queues.
|
|
469
718
|
6. Resume dispatch is fallback: if waiter is no longer active, run:
|
|
719
|
+
|
|
470
720
|
```bash
|
|
471
721
|
ace-hitl update <hitl-id> --answer "<decision>" --resume
|
|
472
722
|
```
|
|
723
|
+
|
|
473
724
|
7. On retry/resume, read the answer from the HITL event and continue normal fail/retry mechanics. Do not introduce gate phases, assignment-level paused state, or extra resume commands in `ace-assign`.
|
|
474
725
|
|
|
475
726
|
### 5. Write Report (Only After Real Execution)
|
|
@@ -504,6 +755,7 @@ echo "$POST_STATUS"
|
|
|
504
755
|
```
|
|
505
756
|
|
|
506
757
|
Required checks:
|
|
758
|
+
|
|
507
759
|
- If report succeeded: active step advanced consistently with work performed
|
|
508
760
|
- If fail succeeded: assignment is stalled or moved according to retry/add logic
|
|
509
761
|
- If output mismatches expected transition: stop and ask user before continuing
|
|
@@ -533,7 +785,13 @@ Creates a new step linked to the original. Original remains visible as failed.
|
|
|
533
785
|
ace-assign add "fix-issue" --instructions "Fix the failing tests and verify" --assignment "$ASSIGNMENT_TARGET"
|
|
534
786
|
```
|
|
535
787
|
|
|
536
|
-
New step is inserted after the current
|
|
788
|
+
New step is inserted after the current active step.
|
|
789
|
+
|
|
790
|
+
When the failure evidence is E2E-specific (`ace-test-e2e`, scenario IDs, or `.ace-local/test-e2e/` artifacts), prefer:
|
|
791
|
+
|
|
792
|
+
```bash
|
|
793
|
+
ace-assign add "fix-e2e" --instructions "Use /as-e2e-fix for the failing package and scenario IDs from the recorded evidence. If analysis is missing, let /as-e2e-fix generate it via wfi://e2e/analyze-failures before applying fixes. Re-run the targeted failing scenarios before completing this step." --assignment "$ASSIGNMENT_TARGET"
|
|
794
|
+
```
|
|
537
795
|
|
|
538
796
|
#### Option C: Ask the User
|
|
539
797
|
|
|
@@ -542,10 +800,33 @@ If uncertain, ask the user whether to retry, add a fix step, or abort.
|
|
|
542
800
|
### 8. Repeat
|
|
543
801
|
|
|
544
802
|
Check status again:
|
|
803
|
+
|
|
545
804
|
- If there is a next step, continue the loop from step 1
|
|
546
805
|
- If all steps are `done`, proceed to Completion
|
|
547
806
|
- If assignment has failed steps and no fix is planned, report to user
|
|
548
807
|
|
|
808
|
+
### 9. Pre-Exit Verification (Required)
|
|
809
|
+
|
|
810
|
+
Before ending the drive session with a final user-facing response, re-run:
|
|
811
|
+
|
|
812
|
+
```bash
|
|
813
|
+
FINAL_STATUS=$(ace-assign status --assignment "$ASSIGNMENT_TARGET" --format json)
|
|
814
|
+
echo "$FINAL_STATUS"
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
Required checks:
|
|
818
|
+
|
|
819
|
+
- If any steps remain `pending` or `active` and no explicit blocker was recorded, resume the loop instead of stopping.
|
|
820
|
+
- If the assignment is `paused`, `active_steps` is empty, and `next_step` is present, run:
|
|
821
|
+
|
|
822
|
+
```bash
|
|
823
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
824
|
+
```
|
|
825
|
+
|
|
826
|
+
then continue the loop.
|
|
827
|
+
|
|
828
|
+
- Only produce a final completion response when the assignment is actually complete or when this workflow has already reached a documented blocker/failure stop condition.
|
|
829
|
+
|
|
549
830
|
## Completion
|
|
550
831
|
|
|
551
832
|
When `ace-assign status` shows all steps as `done`:
|
|
@@ -555,6 +836,7 @@ ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
|
555
836
|
```
|
|
556
837
|
|
|
557
838
|
Example output:
|
|
839
|
+
|
|
558
840
|
```
|
|
559
841
|
Assignment: work-on-task-123 (8or5kx)
|
|
560
842
|
|
|
@@ -567,6 +849,7 @@ All steps complete!
|
|
|
567
849
|
```
|
|
568
850
|
|
|
569
851
|
Summarize the assignment results to the user:
|
|
852
|
+
|
|
570
853
|
- What was accomplished
|
|
571
854
|
- Any artifacts created (PRs, commits, etc.)
|
|
572
855
|
- Next steps or follow-up actions
|
|
@@ -604,6 +887,7 @@ When executing a step with a `skill:` field:
|
|
|
604
887
|
|----------|--------|
|
|
605
888
|
| No active assignment | Create an assignment first via `/as-assign-create` |
|
|
606
889
|
| All steps done | Report completion to user |
|
|
890
|
+
| Assignment paused with pending work | Run `ace-assign start --assignment "$ASSIGNMENT_TARGET"` and continue driving |
|
|
607
891
|
| Step fails | Attempt first, then use `fail` with command/error evidence; decide retry/add/ask |
|
|
608
892
|
| Skill not found | Execute instructions directly without skill |
|
|
609
893
|
| Unclear instructions | Ask user for clarification |
|
|
@@ -616,7 +900,7 @@ When executing a step with a `skill:` field:
|
|
|
616
900
|
| Status | Meaning | Next Action |
|
|
617
901
|
|--------|---------|-------------|
|
|
618
902
|
| `pending` | Step not started | Cannot execute (wait for queue) |
|
|
619
|
-
| `
|
|
903
|
+
| `active` | Step is active | Execute this step |
|
|
620
904
|
| `done` | Step completed | Move to next step |
|
|
621
905
|
| `failed` | Step failed | Decide: retry, add fix, or abort |
|
|
622
906
|
|
|
@@ -630,11 +914,11 @@ When executing a step with a `skill:` field:
|
|
|
630
914
|
│ ├── assignment.yaml # Assignment metadata
|
|
631
915
|
│ ├── steps/ # Step files (.st.md extension)
|
|
632
916
|
│ │ ├── 010-init.st.md # done
|
|
633
|
-
│ │ ├── 020-implement.st.md #
|
|
917
|
+
│ │ ├── 020-implement.st.md # active
|
|
634
918
|
│ │ └── 030-test.st.md # pending
|
|
635
919
|
│ └── reports/ # Report files (.r.md extension)
|
|
636
920
|
│ ├── 010-init.r.md # completed report
|
|
637
|
-
│ └── 020-implement.r.md #
|
|
921
|
+
│ └── 020-implement.r.md # active-step report
|
|
638
922
|
└── def456/
|
|
639
923
|
├── assignment.yaml
|
|
640
924
|
├── steps/
|
|
@@ -642,6 +926,7 @@ When executing a step with a `skill:` field:
|
|
|
642
926
|
```
|
|
643
927
|
|
|
644
928
|
Each step has:
|
|
929
|
+
|
|
645
930
|
- **Step file** (`steps/NNN-name.st.md`) - Contains step instructions and status
|
|
646
931
|
- **Report file** (`reports/NNN-name.r.md`) - Contains completion report (created when step is done)
|
|
647
932
|
|
|
@@ -680,28 +965,33 @@ $ ASSIGNMENT_TARGET=8or5kx
|
|
|
680
965
|
|
|
681
966
|
# 1. Check status
|
|
682
967
|
$ ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
683
|
-
|
|
968
|
+
Next: 010 onboard
|
|
969
|
+
|
|
970
|
+
# 2. Start the next pending step
|
|
971
|
+
$ ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
972
|
+
[Step 010 becomes active]
|
|
684
973
|
|
|
685
|
-
#
|
|
974
|
+
# 3. Execute step (has skill: onboard)
|
|
686
975
|
$ /as-onboard
|
|
687
976
|
[Onboarding workflow runs...]
|
|
688
977
|
|
|
689
|
-
#
|
|
978
|
+
# 4. Write report
|
|
690
979
|
$ ace-assign finish --message onboard-complete.md --assignment "$ASSIGNMENT_TARGET"
|
|
691
|
-
Step 010 marked done
|
|
980
|
+
[Step 010 marked done]
|
|
692
981
|
|
|
693
|
-
#
|
|
982
|
+
# 5. Check status again
|
|
694
983
|
$ ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
695
|
-
|
|
984
|
+
Next: 020 work-on-task
|
|
696
985
|
|
|
697
|
-
#
|
|
986
|
+
# 6. Start and execute next step (has skill: as-task-work)
|
|
987
|
+
$ ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
698
988
|
$ /as-task-work 148
|
|
699
989
|
[Task workflow runs...]
|
|
700
990
|
|
|
701
|
-
#
|
|
991
|
+
# 7. Report and continue...
|
|
702
992
|
$ ace-assign finish --message task-done.md --assignment "$ASSIGNMENT_TARGET"
|
|
703
993
|
|
|
704
|
-
#
|
|
994
|
+
# 8. Eventually...
|
|
705
995
|
$ ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
706
996
|
All steps complete!
|
|
707
997
|
```
|