ace-assign 0.42.4 → 0.53.4
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/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/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 +3 -16
- data/CHANGELOG.md +201 -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 +957 -0
- data/docs/demo/fork-provider.gif +0 -0
- data/docs/demo/fork-provider.recording.json +32 -0
- data/docs/demo/fork-provider.tape.yml +65 -20
- data/docs/getting-started.md +5 -2
- data/docs/usage.md +47 -0
- data/handbook/guides/fork-context.g.md +2 -2
- 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 +231 -14
- data/handbook/workflow-instructions/assign/mark-task-done-internal.wf.md +12 -0
- data/handbook/workflow-instructions/assign/prepare.wf.md +5 -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/step_file_parser.rb +15 -0
- data/lib/ace/assign/cli/commands/assignment_target.rb +53 -0
- data/lib/ace/assign/cli/commands/finish.rb +7 -4
- data/lib/ace/assign/cli/commands/fork_run.rb +4 -1
- data/lib/ace/assign/cli/commands/fork_session.rb +52 -0
- data/lib/ace/assign/cli/commands/start.rb +9 -3
- data/lib/ace/assign/cli/commands/status.rb +208 -227
- data/lib/ace/assign/cli/commands/step.rb +62 -0
- data/lib/ace/assign/cli.rb +8 -1
- data/lib/ace/assign/models/step.rb +4 -2
- data/lib/ace/assign/molecules/fork_session_launcher.rb +189 -8
- 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/tmux_fork_runner.rb +191 -0
- data/lib/ace/assign/organisms/assignment_executor.rb +223 -24
- data/lib/ace/assign/version.rb +1 -1
- metadata +21 -5
- data/.ace-defaults/assign/catalog/steps/verify-e2e.step.yml +0 -42
|
@@ -1,9 +1,18 @@
|
|
|
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-
|
|
15
|
+
last-updated: 2026-04-12
|
|
7
16
|
last-checked: 2026-03-21
|
|
8
17
|
---
|
|
9
18
|
|
|
@@ -104,12 +113,55 @@ ace-assign finish --message done.md --assignment <id>
|
|
|
104
113
|
|
|
105
114
|
Repeat the following cycle until all steps are done or failed:
|
|
106
115
|
|
|
116
|
+
### Run-Until-Blocked Contract
|
|
117
|
+
|
|
118
|
+
Once `ASSIGNMENT_TARGET` is pinned, keep driving the same assignment until exactly one of these stop conditions is true:
|
|
119
|
+
|
|
120
|
+
1. `ace-assign status --assignment "$ASSIGNMENT_TARGET"` shows all steps complete
|
|
121
|
+
2. A workflow step explicitly requires HITL or other user judgment before execution can continue
|
|
122
|
+
3. A step reaches an unrecoverable failure path and this workflow instructs you to stop
|
|
123
|
+
4. The user explicitly interrupts or cancels execution
|
|
124
|
+
|
|
125
|
+
Do **not** stop merely because you have useful progress to report.
|
|
126
|
+
|
|
127
|
+
- Intermediate progress belongs in short progress updates, not in a final completion response.
|
|
128
|
+
- `pending` steps with no active step are not a stop condition. They mean the queue must be advanced and the loop must continue.
|
|
129
|
+
- A batch child subtree finishing is not a completion boundary for the parent assignment.
|
|
130
|
+
- A paused assignment with remaining runnable work is not "done"; treat it as a recoverable scheduler state and resume the loop.
|
|
131
|
+
|
|
132
|
+
### Final Response Gate
|
|
133
|
+
|
|
134
|
+
Before sending any final user-facing completion response, re-run:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
ace-assign status --assignment "$ASSIGNMENT_TARGET" --format json
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
You may only stop and send a final response when one of these is true:
|
|
141
|
+
|
|
142
|
+
- the pinned assignment has no remaining runnable `pending` or `in_progress` work
|
|
143
|
+
- the workflow recorded an explicit blocker or unrecoverable failure stop condition
|
|
144
|
+
- the user explicitly interrupted or canceled execution
|
|
145
|
+
|
|
146
|
+
Do **not** send a final response merely because:
|
|
147
|
+
|
|
148
|
+
- one child subtree completed
|
|
149
|
+
- useful progress was made
|
|
150
|
+
- a prior terminal session ended
|
|
151
|
+
- the parent assignment auto-advanced to the next active step
|
|
152
|
+
|
|
153
|
+
Concrete example:
|
|
154
|
+
|
|
155
|
+
- `010.01 done` and `010.02.01 in_progress` means continue driving the assignment. It is not a completion boundary.
|
|
156
|
+
|
|
107
157
|
### Step Execution Policy
|
|
108
158
|
|
|
109
159
|
- Planned steps are mandatory work items. Do not skip them by judgment.
|
|
110
160
|
- For each active step, do exactly one of:
|
|
161
|
+
|
|
111
162
|
1. Execute the step and report completion with `ace-assign finish --message`
|
|
112
163
|
2. Attempt execution, capture blocker evidence, and mark failed with `ace-assign fail`
|
|
164
|
+
|
|
113
165
|
- Never use report text to "skip" or synthesize completion for planned steps.
|
|
114
166
|
- **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
167
|
- **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 +171,40 @@ Repeat the following cycle until all steps are done or failed:
|
|
|
119
171
|
After completing or failing each step, evaluate whether the assignment needs adaptation:
|
|
120
172
|
|
|
121
173
|
- **Test failures detected** → Consider adding a fix-tests step:
|
|
174
|
+
|
|
122
175
|
```bash
|
|
123
176
|
ace-assign add "fix-tests" --instructions "Fix failing tests identified in step NNN" --assignment "$ASSIGNMENT_TARGET"
|
|
124
177
|
```
|
|
125
178
|
|
|
179
|
+
- **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`:
|
|
180
|
+
|
|
181
|
+
```bash
|
|
182
|
+
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"
|
|
183
|
+
```
|
|
184
|
+
|
|
126
185
|
- **Review found critical issues** → Consider adding an apply-critical-fixes step:
|
|
186
|
+
|
|
127
187
|
```bash
|
|
128
188
|
ace-assign add "apply-critical-fixes" --instructions "Address critical review findings before proceeding" --assignment "$ASSIGNMENT_TARGET"
|
|
129
189
|
```
|
|
130
190
|
|
|
131
191
|
- **Missing prerequisite discovered** → Consider adding the prerequisite step:
|
|
192
|
+
|
|
132
193
|
```bash
|
|
133
194
|
ace-assign add "missing-prereq" --instructions "Complete prerequisite work discovered during step NNN" --assignment "$ASSIGNMENT_TARGET"
|
|
134
195
|
```
|
|
135
196
|
|
|
136
|
-
- **Metadata hint**: Step file contains `trigger_on_failure`
|
|
197
|
+
- **Metadata hint**: Step file contains `trigger_on_failure` -- if the step failed, inject the referenced step type
|
|
137
198
|
|
|
138
199
|
Use `decision_notes` from step metadata (if present) as additional guidance for these assessments.
|
|
139
200
|
|
|
140
201
|
- **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:
|
|
202
|
+
|
|
141
203
|
- 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
204
|
- If the **second** cycle (fit) failed after valid succeeded: skip shine. Valid already captured correctness issues.
|
|
143
205
|
- **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
206
|
|
|
145
|
-
- **Transient network failure retry**: When a fork subtree fails due to a transient network error (connection reset, DNS timeout, socket hangup)
|
|
207
|
+
- **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
208
|
|
|
147
209
|
### 1. Check Status
|
|
148
210
|
|
|
@@ -152,14 +214,20 @@ echo "$STATUS_OUTPUT"
|
|
|
152
214
|
```
|
|
153
215
|
|
|
154
216
|
Read the output to identify:
|
|
217
|
+
|
|
155
218
|
- Assignment ID (must remain equal to pinned `ASSIGNMENT_ID`)
|
|
156
219
|
- Current step number, name, and status
|
|
157
|
-
-
|
|
158
|
-
-
|
|
159
|
-
- Remaining steps in the queue
|
|
220
|
+
- Remaining visible steps in the queue preview
|
|
221
|
+
- Hidden-step counts for large queues
|
|
160
222
|
|
|
161
223
|
**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
224
|
|
|
225
|
+
Load instructions separately when needed:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
ace-assign step --assignment "$ASSIGNMENT_TARGET"
|
|
229
|
+
```
|
|
230
|
+
|
|
163
231
|
### 2. Auto-Delegate Fork Subtrees (When Applicable)
|
|
164
232
|
|
|
165
233
|
Before executing the current step inline, check whether the active step is inside a fork-enabled subtree.
|
|
@@ -184,6 +252,20 @@ fi
|
|
|
184
252
|
|
|
185
253
|
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
254
|
|
|
255
|
+
Dirty-tree classification rule:
|
|
256
|
+
|
|
257
|
+
- Do not auto-commit every unrelated dirty path.
|
|
258
|
+
- First classify the dirty state:
|
|
259
|
+
- **intentional work**: user edits, task implementation, or other meaningful repo changes that must be preserved
|
|
260
|
+
- **generated side effects**: bootstrap/config scaffolding, handbook projection output, caches, or other machine-generated files outside the current task scope
|
|
261
|
+
- If the dirty paths are intentional work, preserve them and either continue with scope awareness or commit them deliberately.
|
|
262
|
+
- If the dirty paths are generated side effects outside the current task scope, clean/reset them before `fork-run` instead of committing them.
|
|
263
|
+
- Only stop for user input when classification remains ambiguous after inspection.
|
|
264
|
+
|
|
265
|
+
Example:
|
|
266
|
+
|
|
267
|
+
- A bulk untracked `.ace/...` tree created by `ace-config init` is generated side-effect output. Clean it; do not create a "pre-fork" commit for it.
|
|
268
|
+
|
|
187
269
|
#### Delegation Rule
|
|
188
270
|
|
|
189
271
|
**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 +276,7 @@ This prevents fork agents from stalling on pre-existing unrelated changes. Assig
|
|
|
194
276
|
| `FORK: ` (empty) | Step is not fork-enabled | Execute inline (or inspect fork-enabled children if batch parent) |
|
|
195
277
|
|
|
196
278
|
**Example status output:**
|
|
279
|
+
|
|
197
280
|
```
|
|
198
281
|
NUMBER STATUS NAME FORK CHILDREN
|
|
199
282
|
------------------------------------------------------------------------------
|
|
@@ -202,6 +285,7 @@ NUMBER STATUS NAME FORK CHILDREN
|
|
|
202
285
|
```
|
|
203
286
|
|
|
204
287
|
Step 020 shows `FORK: yes` → run:
|
|
288
|
+
|
|
205
289
|
```bash
|
|
206
290
|
ace-assign fork-run --assignment <id>@020
|
|
207
291
|
```
|
|
@@ -209,7 +293,7 @@ ace-assign fork-run --assignment <id>@020
|
|
|
209
293
|
**Delegation boundary rule**
|
|
210
294
|
|
|
211
295
|
- Outside a delegated fork scope, do NOT execute fork steps inline.
|
|
212
|
-
- If
|
|
296
|
+
- 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>`.
|
|
213
297
|
- If the current step is a top-level step with `FORK: yes` and no matching scope is active, delegate immediately.
|
|
214
298
|
|
|
215
299
|
#### Nested Batch Containers (Container → Fork Children)
|
|
@@ -222,10 +306,12 @@ A batch container (e.g., `010`) may have children but no fork context itself (`F
|
|
|
222
306
|
- `fork_retry_limit: <N>` (default `1`)
|
|
223
307
|
|
|
224
308
|
**How to distinguish:**
|
|
309
|
+
|
|
225
310
|
- **Direct fork target**: `FORK: yes` on the current step → fork-run the current step.
|
|
226
311
|
- **Batch container**: `FORK: ` on parent, but children include `FORK: yes` steps.
|
|
227
312
|
|
|
228
313
|
**Pattern for batch containers:**
|
|
314
|
+
|
|
229
315
|
```bash
|
|
230
316
|
# Read scheduler metadata from parent step 010
|
|
231
317
|
# parallel=false => sequential, still fork every child
|
|
@@ -236,9 +322,11 @@ A batch container (e.g., `010`) may have children but no fork context itself (`F
|
|
|
236
322
|
|
|
237
323
|
- Iterate pending child steps in number order.
|
|
238
324
|
- For each child with `FORK: yes`, run:
|
|
325
|
+
|
|
239
326
|
- `ace-assign fork-run --assignment <id>@<child>`
|
|
327
|
+
|
|
240
328
|
- Re-check status after each child.
|
|
241
|
-
- Do not pause for user input between children
|
|
329
|
+
- Do not pause for user input between children -- treat the batch loop as a single unit (see Batch Continuation Rule below).
|
|
242
330
|
|
|
243
331
|
**Parallel mode (`parallel: true`)**
|
|
244
332
|
|
|
@@ -262,12 +350,19 @@ The driver MUST NOT pause for user input between child fork-runs within a batch
|
|
|
262
350
|
|
|
263
351
|
1. Verify the child's reports (see Subtree Guard below).
|
|
264
352
|
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
|
|
353
|
+
3. Treat the entire batch loop as a single unit of execution -- only pause on quality concerns flagged during report review.
|
|
266
354
|
4. For timeout-constrained environments: launch `fork-run` in background, poll for completion, then loop to the next child without pausing.
|
|
267
355
|
|
|
356
|
+
Conversational boundary rule:
|
|
357
|
+
|
|
358
|
+
- 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).
|
|
359
|
+
- If child `010.01` completes, reports are clean, and `010.02` is still pending, immediately advance/resume the queue and continue driving.
|
|
360
|
+
- Treat child-subtree completion as progress within the same drive session, not as permission to stop.
|
|
361
|
+
|
|
268
362
|
**Failure policy (retry-then-stop)**
|
|
269
363
|
|
|
270
364
|
- On any child failure:
|
|
365
|
+
|
|
271
366
|
- Pause launching new children immediately.
|
|
272
367
|
- Wait for in-flight children to finish.
|
|
273
368
|
- Retry failed child once (`fork_retry_limit=1` default).
|
|
@@ -292,13 +387,64 @@ fi
|
|
|
292
387
|
|
|
293
388
|
`fork-run` executes the entire subtree in one dedicated process and returns when the subtree is complete or failed.
|
|
294
389
|
|
|
390
|
+
#### Fork Wait Continuation Rule
|
|
391
|
+
|
|
392
|
+
After launching `ace-assign fork-run`, the driver remains inside the same drive session.
|
|
393
|
+
|
|
394
|
+
- Treat "fork subtree is still running" as an internal progress state, not as a stop condition.
|
|
395
|
+
- 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.
|
|
396
|
+
- Poll the forked subtree every 6 minutes by default. Use two signals on each poll:
|
|
397
|
+
|
|
398
|
+
1. poll the live fork session/process handle
|
|
399
|
+
2. poll scoped assignment status with `ace-assign status --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}"`
|
|
400
|
+
|
|
401
|
+
- 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.
|
|
402
|
+
- Continue polling until one of these is true:
|
|
403
|
+
|
|
404
|
+
- the `fork-run` process exits
|
|
405
|
+
- scoped status for the subtree proves every step inside that subtree is terminal (`done` or `failed`)
|
|
406
|
+
- the workflow reaches a documented blocker or failure path
|
|
407
|
+
|
|
408
|
+
- 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.
|
|
409
|
+
- 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.
|
|
410
|
+
- When the wait ends, immediately re-enter the parent drive loop. Do not stop between "fork finished" and "next runnable step started."
|
|
411
|
+
|
|
412
|
+
#### Post-Fork Resume Checklist
|
|
413
|
+
|
|
414
|
+
Immediately after the fork wait ends, run this checklist in order:
|
|
415
|
+
|
|
416
|
+
1. If `fork-run` exited non-zero, enter [Fork-Run Recovery](#fork-run-recovery).
|
|
417
|
+
2. Read and review subtree reports.
|
|
418
|
+
3. Check for uncommitted changes and commit safety-net leftovers if needed.
|
|
419
|
+
4. Query parent assignment status.
|
|
420
|
+
5. If no active step exists but pending work remains, run:
|
|
421
|
+
|
|
422
|
+
```bash
|
|
423
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
6. If pending or `in_progress` work remains and no blocker was recorded, continue the main loop immediately.
|
|
427
|
+
7. Only stop if the assignment now satisfies a real stop condition from [Run-Until-Blocked Contract](#run-until-blocked-contract).
|
|
428
|
+
|
|
429
|
+
Detached-resume rule:
|
|
430
|
+
|
|
431
|
+
- 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.
|
|
432
|
+
- 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.
|
|
433
|
+
- 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.
|
|
434
|
+
|
|
435
|
+
Concrete example:
|
|
436
|
+
|
|
437
|
+
- Incorrect: launch `fork-run` for `040`, post "waiting on subtree", stop responding, and never resume `070`.
|
|
438
|
+
- 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.
|
|
439
|
+
- 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`.
|
|
440
|
+
|
|
295
441
|
> **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
442
|
>
|
|
297
443
|
> ```bash
|
|
298
444
|
> # Run fork-run in background (use run_in_background: true in Claude Code)
|
|
299
445
|
> ace-assign fork-run --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}" &
|
|
300
446
|
>
|
|
301
|
-
> # Poll scoped status every
|
|
447
|
+
> # Poll scoped status every 6 minutes until subtree completes
|
|
302
448
|
> while true; do
|
|
303
449
|
> STATUS_JSON=$(ace-assign status --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}" --format json)
|
|
304
450
|
> COMPLETE=$(echo "$STATUS_JSON" | ruby -rjson -e '
|
|
@@ -307,36 +453,41 @@ fi
|
|
|
307
453
|
> puts steps.all? { |step| step["status"] == "done" || step["status"] == "failed" }
|
|
308
454
|
> ')
|
|
309
455
|
> [ "$COMPLETE" = "true" ] && break
|
|
310
|
-
> sleep
|
|
456
|
+
> sleep 360
|
|
311
457
|
> done
|
|
458
|
+
> ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
312
459
|
> ```
|
|
313
460
|
|
|
314
461
|
#### Subtree Completion: Task Status Verification
|
|
315
462
|
|
|
316
463
|
After a fork subtree completes (work-on-task finishes successfully):
|
|
317
464
|
|
|
318
|
-
1. **Verify ace-
|
|
465
|
+
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
466
|
|
|
320
467
|
2. **If mark-task-done step was NOT included in the assignment** (common for ad-hoc assignments):
|
|
468
|
+
|
|
321
469
|
```bash
|
|
322
470
|
# Manually sync status before reporting subtree complete
|
|
323
471
|
ace-task done {taskref}
|
|
324
472
|
ace-task {taskref} # Verify it shows status: done
|
|
325
473
|
```
|
|
326
474
|
|
|
327
|
-
3. **Report the subtree complete only after verification.** This prevents the orchestrator from showing work as done while ace-
|
|
475
|
+
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
476
|
|
|
329
477
|
#### Subtree Guard: Review Fork Reports Before Continuing
|
|
330
478
|
|
|
331
479
|
After fork-run returns and completion is verified, the driver acts as the **guard** for the subtree. Before continuing to the next step:
|
|
332
480
|
|
|
333
481
|
1. **Read all subtree report files** from `.ace-local/assign/<assignment-id>/reports/`:
|
|
482
|
+
|
|
334
483
|
```bash
|
|
335
484
|
# List and read all reports for the completed subtree
|
|
336
485
|
ls .ace-local/assign/${ASSIGNMENT_ID}/reports/${FORK_ROOT}.*
|
|
337
486
|
# Read each report file to review the forked agent's work
|
|
338
487
|
```
|
|
488
|
+
|
|
339
489
|
2. **Check for uncommitted changes** left by the fork agent:
|
|
490
|
+
|
|
340
491
|
```bash
|
|
341
492
|
DIRTY=$(git status --short)
|
|
342
493
|
if [ -n "$DIRTY" ]; then
|
|
@@ -346,7 +497,8 @@ After fork-run returns and completion is verified, the driver acts as the **guar
|
|
|
346
497
|
ace-git-commit -i "commit changes left by fork subtree ${FORK_ROOT}"
|
|
347
498
|
fi
|
|
348
499
|
```
|
|
349
|
-
|
|
500
|
+
|
|
501
|
+
Fork agents are expected to commit all their work. Uncommitted files indicate incomplete commit discipline -- note this when reviewing reports.
|
|
350
502
|
3. **Verify quality**: Check that reports indicate successful completion, not just step advancement.
|
|
351
503
|
4. **Flag concerns**: If any report indicates partial work, errors, or skipped steps, stop and ask the user before continuing.
|
|
352
504
|
5. **Only then continue** the main drive loop to the next step.
|
|
@@ -358,11 +510,32 @@ After fork-run returns and completion is verified, the driver acts as the **guar
|
|
|
358
510
|
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
511
|
|
|
360
512
|
**After verifying all fork subtree reports**, if `ace-assign status` shows no Active step (all completed steps but no new in-progress step), run:
|
|
513
|
+
|
|
361
514
|
```bash
|
|
362
515
|
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
363
516
|
```
|
|
517
|
+
|
|
364
518
|
This advances the queue to the next pending top-level step.
|
|
365
519
|
|
|
520
|
+
If pending steps still remain after this queue advancement, continue the drive loop immediately. Do not stop after printing a partial progress summary.
|
|
521
|
+
|
|
522
|
+
Concrete example:
|
|
523
|
+
|
|
524
|
+
```text
|
|
525
|
+
010.01 done
|
|
526
|
+
010.02 pending
|
|
527
|
+
010.03 pending
|
|
528
|
+
Current Step: none
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
This state means "resume driving", not "return final status". Run:
|
|
532
|
+
|
|
533
|
+
```bash
|
|
534
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
then continue the loop from status check.
|
|
538
|
+
|
|
366
539
|
#### Fork-Run Recovery
|
|
367
540
|
|
|
368
541
|
When `fork-run` exits non-zero, invoke the fork recovery workflow:
|
|
@@ -428,9 +601,11 @@ For external-facing steps (for example PR/review/release/push/update lifecycle s
|
|
|
428
601
|
|
|
429
602
|
- Attempt the step command(s) first.
|
|
430
603
|
- If blocked, capture concrete evidence:
|
|
604
|
+
|
|
431
605
|
- command attempted
|
|
432
606
|
- exact error output
|
|
433
607
|
- why the step cannot proceed
|
|
608
|
+
|
|
434
609
|
- Mark step failed with evidence (do not report synthetic completion).
|
|
435
610
|
|
|
436
611
|
```bash
|
|
@@ -449,27 +624,35 @@ Use HITL when:
|
|
|
449
624
|
For a blocked step:
|
|
450
625
|
|
|
451
626
|
1. Create a HITL event with assignment and step context:
|
|
627
|
+
|
|
452
628
|
```bash
|
|
453
629
|
ace-hitl create "Need product decision" --question "Should retries be visible?" --assignment <id> --step <number> --step-name <name> --resume "/as-assign-drive <id>"
|
|
454
630
|
```
|
|
631
|
+
|
|
455
632
|
2. Fail the step using canonical stall format:
|
|
633
|
+
|
|
456
634
|
```bash
|
|
457
635
|
ace-assign fail --message "HITL: <hitl-id> <hitl-path>" --assignment "$ASSIGNMENT_TARGET"
|
|
458
636
|
```
|
|
637
|
+
|
|
459
638
|
3. Human/operator resolves:
|
|
639
|
+
|
|
460
640
|
```bash
|
|
461
641
|
ace-hitl show <hitl-id>
|
|
462
642
|
ace-hitl update <hitl-id> --answer "Yes, show retries in user-facing output."
|
|
463
643
|
ace-hitl wait <hitl-id>
|
|
464
644
|
```
|
|
645
|
+
|
|
465
646
|
4. Discover pending HITL work:
|
|
466
647
|
- Main checkout default (smart local-first): `ace-hitl list`
|
|
467
648
|
- Explicit scope controls: `ace-hitl list --scope current` and `ace-hitl list --scope all`
|
|
468
649
|
5. Polling is default: requesting agent waits on its own HITL id (`ace-hitl wait <hitl-id>`), not global queues.
|
|
469
650
|
6. Resume dispatch is fallback: if waiter is no longer active, run:
|
|
651
|
+
|
|
470
652
|
```bash
|
|
471
653
|
ace-hitl update <hitl-id> --answer "<decision>" --resume
|
|
472
654
|
```
|
|
655
|
+
|
|
473
656
|
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
657
|
|
|
475
658
|
### 5. Write Report (Only After Real Execution)
|
|
@@ -504,6 +687,7 @@ echo "$POST_STATUS"
|
|
|
504
687
|
```
|
|
505
688
|
|
|
506
689
|
Required checks:
|
|
690
|
+
|
|
507
691
|
- If report succeeded: active step advanced consistently with work performed
|
|
508
692
|
- If fail succeeded: assignment is stalled or moved according to retry/add logic
|
|
509
693
|
- If output mismatches expected transition: stop and ask user before continuing
|
|
@@ -535,6 +719,12 @@ ace-assign add "fix-issue" --instructions "Fix the failing tests and verify" --a
|
|
|
535
719
|
|
|
536
720
|
New step is inserted after the current in-progress step.
|
|
537
721
|
|
|
722
|
+
When the failure evidence is E2E-specific (`ace-test-e2e`, scenario IDs, or `.ace-local/test-e2e/` artifacts), prefer:
|
|
723
|
+
|
|
724
|
+
```bash
|
|
725
|
+
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"
|
|
726
|
+
```
|
|
727
|
+
|
|
538
728
|
#### Option C: Ask the User
|
|
539
729
|
|
|
540
730
|
If uncertain, ask the user whether to retry, add a fix step, or abort.
|
|
@@ -542,10 +732,33 @@ If uncertain, ask the user whether to retry, add a fix step, or abort.
|
|
|
542
732
|
### 8. Repeat
|
|
543
733
|
|
|
544
734
|
Check status again:
|
|
735
|
+
|
|
545
736
|
- If there is a next step, continue the loop from step 1
|
|
546
737
|
- If all steps are `done`, proceed to Completion
|
|
547
738
|
- If assignment has failed steps and no fix is planned, report to user
|
|
548
739
|
|
|
740
|
+
### 9. Pre-Exit Verification (Required)
|
|
741
|
+
|
|
742
|
+
Before ending the drive session with a final user-facing response, re-run:
|
|
743
|
+
|
|
744
|
+
```bash
|
|
745
|
+
FINAL_STATUS=$(ace-assign status --assignment "$ASSIGNMENT_TARGET" --format json)
|
|
746
|
+
echo "$FINAL_STATUS"
|
|
747
|
+
```
|
|
748
|
+
|
|
749
|
+
Required checks:
|
|
750
|
+
|
|
751
|
+
- If any steps remain `pending` or `in_progress` and no explicit blocker was recorded, resume the loop instead of stopping.
|
|
752
|
+
- If the assignment is `paused`, `current_step` is `null`, and pending steps remain, run:
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
ace-assign start --assignment "$ASSIGNMENT_TARGET"
|
|
756
|
+
```
|
|
757
|
+
|
|
758
|
+
then continue the loop.
|
|
759
|
+
|
|
760
|
+
- 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.
|
|
761
|
+
|
|
549
762
|
## Completion
|
|
550
763
|
|
|
551
764
|
When `ace-assign status` shows all steps as `done`:
|
|
@@ -555,6 +768,7 @@ ace-assign status --assignment "$ASSIGNMENT_TARGET"
|
|
|
555
768
|
```
|
|
556
769
|
|
|
557
770
|
Example output:
|
|
771
|
+
|
|
558
772
|
```
|
|
559
773
|
Assignment: work-on-task-123 (8or5kx)
|
|
560
774
|
|
|
@@ -567,6 +781,7 @@ All steps complete!
|
|
|
567
781
|
```
|
|
568
782
|
|
|
569
783
|
Summarize the assignment results to the user:
|
|
784
|
+
|
|
570
785
|
- What was accomplished
|
|
571
786
|
- Any artifacts created (PRs, commits, etc.)
|
|
572
787
|
- Next steps or follow-up actions
|
|
@@ -604,6 +819,7 @@ When executing a step with a `skill:` field:
|
|
|
604
819
|
|----------|--------|
|
|
605
820
|
| No active assignment | Create an assignment first via `/as-assign-create` |
|
|
606
821
|
| All steps done | Report completion to user |
|
|
822
|
+
| Assignment paused with pending work | Run `ace-assign start --assignment "$ASSIGNMENT_TARGET"` and continue driving |
|
|
607
823
|
| Step fails | Attempt first, then use `fail` with command/error evidence; decide retry/add/ask |
|
|
608
824
|
| Skill not found | Execute instructions directly without skill |
|
|
609
825
|
| Unclear instructions | Ask user for clarification |
|
|
@@ -642,6 +858,7 @@ When executing a step with a `skill:` field:
|
|
|
642
858
|
```
|
|
643
859
|
|
|
644
860
|
Each step has:
|
|
861
|
+
|
|
645
862
|
- **Step file** (`steps/NNN-name.st.md`) - Contains step instructions and status
|
|
646
863
|
- **Report file** (`reports/NNN-name.r.md`) - Contains completion report (created when step is done)
|
|
647
864
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# mark-task-done-internal
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Mark a task as done and verify the state transition persisted.
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. Run `ace-task update <taskref> --set status=done --move-to archive --git-commit`.
|
|
10
|
+
2. Verify with `ace-task show <taskref>` and confirm `status: done`.
|
|
11
|
+
3. If the task has a parent, check whether siblings are all done; when true, mark the parent done and verify.
|
|
12
|
+
4. Repeat upward only while all siblings remain done.
|
|
@@ -336,7 +336,7 @@ session:
|
|
|
336
336
|
|
|
337
337
|
steps:
|
|
338
338
|
- name: <step-name>
|
|
339
|
-
|
|
339
|
+
source: <source-reference> # Canonical: skill://... or wfi://...
|
|
340
340
|
instructions:
|
|
341
341
|
- <resolved instruction line>
|
|
342
342
|
# ... more steps
|
|
@@ -344,7 +344,7 @@ steps:
|
|
|
344
344
|
|
|
345
345
|
### 8. Output Result
|
|
346
346
|
|
|
347
|
-
Default output: `<task>/jobs/<timestamp>-job.yml` (e.g., `.ace-
|
|
347
|
+
Default output: `<task>/jobs/<timestamp>-job.yml` (e.g., `.ace-task/v.0.9.0/tasks/229-xxx/jobs/k5abc123-job.yml`)
|
|
348
348
|
|
|
349
349
|
Custom output: Use `--output path/to/custom.yaml`
|
|
350
350
|
|
|
@@ -379,19 +379,19 @@ session:
|
|
|
379
379
|
|
|
380
380
|
steps:
|
|
381
381
|
- name: onboard
|
|
382
|
-
|
|
382
|
+
source: skill://as-onboard
|
|
383
383
|
instructions:
|
|
384
384
|
- Onboard yourself to the codebase.
|
|
385
385
|
- Load context and understand the project structure.
|
|
386
386
|
|
|
387
387
|
- name: work-on-task
|
|
388
|
-
|
|
388
|
+
source: skill://as-task-work
|
|
389
389
|
instructions:
|
|
390
390
|
- Work on task 123.
|
|
391
391
|
- Implement the required changes following project conventions.
|
|
392
392
|
|
|
393
393
|
- name: create-pr
|
|
394
|
-
|
|
394
|
+
source: skill://as-github-pr-create
|
|
395
395
|
instructions:
|
|
396
396
|
- Create a pull request for the changes.
|
|
397
397
|
- Capture the PR number for subsequent review steps.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# reflect-and-refactor-internal
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Run architecture reflection and bounded refactoring before release/closeout.
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. Validate implementation/demo state.
|
|
10
|
+
2. Run architecture-focused review on the active diff.
|
|
11
|
+
3. Categorize findings (refactor/accept/skip).
|
|
12
|
+
4. Execute bounded refactoring for selected findings only.
|
|
13
|
+
5. Commit refactor changes separately.
|
|
14
|
+
6. If a replan trigger is hit, inject follow-up implementation steps and rerun once.
|
|
@@ -3,7 +3,7 @@ doc-type: workflow
|
|
|
3
3
|
title: Run In Batches Workflow
|
|
4
4
|
purpose: workflow instruction for reusable repeated-item orchestration with deterministic assignment creation
|
|
5
5
|
ace-docs:
|
|
6
|
-
last-updated: 2026-
|
|
6
|
+
last-updated: 2026-04-07
|
|
7
7
|
last-checked: 2026-03-21
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -163,6 +163,8 @@ If `--run` is present:
|
|
|
163
163
|
/as-assign-drive <assignment-id>
|
|
164
164
|
```
|
|
165
165
|
|
|
166
|
+
This handoff must continue through the full batch execution, including all child fork subtrees, until the assignment is complete or an explicit blocker/failure stop condition is reached. Child completion is not a valid stop boundary.
|
|
167
|
+
|
|
166
168
|
If no workable step is available, keep creation successful and report why drive did not continue.
|
|
167
169
|
|
|
168
170
|
### 7. Report Result
|
|
@@ -203,6 +205,7 @@ Show:
|
|
|
203
205
|
- Parent/child metadata reflects scheduler intent (`parallel`, `max_parallel`, `fork_retry_limit`)
|
|
204
206
|
- `{{item}}` substitution and `Target item:` fallback are deterministic
|
|
205
207
|
- Optional `--run` handoff delegates to `/as-assign-drive`
|
|
208
|
+
- Optional `--run` handoff preserves drive's run-until-complete-or-blocked semantics across the whole batch
|
|
206
209
|
|
|
207
210
|
## Verification
|
|
208
211
|
|
|
@@ -3,7 +3,7 @@ doc-type: workflow
|
|
|
3
3
|
title: Start Assignment Workflow (Legacy Compatibility)
|
|
4
4
|
purpose: preserve compatibility for as-assign-start while routing to public assign/create + assign/drive flow
|
|
5
5
|
ace-docs:
|
|
6
|
-
last-updated: 2026-
|
|
6
|
+
last-updated: 2026-04-07
|
|
7
7
|
last-checked: 2026-03-21
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -39,8 +39,11 @@ Primary public UX remains:
|
|
|
39
39
|
/as-assign-drive <assignment-id>
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
+
When this handoff occurs, `/as-assign-drive` must continue until the assignment is complete or explicitly blocked. It is not a single-step progress probe.
|
|
43
|
+
|
|
42
44
|
## Success Criteria
|
|
43
45
|
|
|
44
46
|
- Preserves compatibility entrypoint for orchestration examples.
|
|
45
47
|
- Delegates behavior to `assign/create` and `assign/drive`.
|
|
46
|
-
- Does not redefine the public assignment flow.
|
|
48
|
+
- Does not redefine the public assignment flow.
|
|
49
|
+
- Preserves drive's run-until-complete-or-blocked semantics.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# task-load-internal
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
Load task behavioral specification and dependency context for assignment execution.
|
|
6
|
+
|
|
7
|
+
## Steps
|
|
8
|
+
|
|
9
|
+
1. Run `ace-bundle task://<taskref>` for the target task reference.
|
|
10
|
+
2. If task dependencies are declared, run `ace-bundle task://<dep-ref>` for each dependency.
|
|
11
|
+
3. Review relevant dependency reports under `.ace-local/assign/` so the plan/work steps build on prior implementation.
|
|
12
|
+
4. Confirm context is loaded before proceeding.
|