ace-assign 0.37.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 +7 -0
- data/.ace-defaults/assign/catalog/composition-rules.yml +211 -0
- data/.ace-defaults/assign/catalog/recipes/batch-tasks.recipe.yml +44 -0
- data/.ace-defaults/assign/catalog/recipes/documentation.recipe.yml +35 -0
- data/.ace-defaults/assign/catalog/recipes/fix-and-review.recipe.yml +32 -0
- data/.ace-defaults/assign/catalog/recipes/implement-simple.recipe.yml +29 -0
- data/.ace-defaults/assign/catalog/recipes/implement-with-pr.recipe.yml +48 -0
- data/.ace-defaults/assign/catalog/recipes/release-only.recipe.yml +34 -0
- data/.ace-defaults/assign/catalog/steps/apply-feedback.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/commit.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/create-pr.step.yml +28 -0
- data/.ace-defaults/assign/catalog/steps/create-retro.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/fix-tests.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/lint.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/mark-task-done.step.yml +57 -0
- data/.ace-defaults/assign/catalog/steps/onboard-base.step.yml +19 -0
- data/.ace-defaults/assign/catalog/steps/onboard.step.yml +19 -0
- data/.ace-defaults/assign/catalog/steps/plan-task.step.yml +17 -0
- data/.ace-defaults/assign/catalog/steps/pre-commit-review.step.yml +34 -0
- data/.ace-defaults/assign/catalog/steps/push-to-remote.step.yml +28 -0
- data/.ace-defaults/assign/catalog/steps/rebase-with-main.step.yml +28 -0
- data/.ace-defaults/assign/catalog/steps/reflect-and-refactor.step.yml +57 -0
- data/.ace-defaults/assign/catalog/steps/release-minor.step.yml +23 -0
- data/.ace-defaults/assign/catalog/steps/release.step.yml +23 -0
- data/.ace-defaults/assign/catalog/steps/reorganize-commits.step.yml +28 -0
- data/.ace-defaults/assign/catalog/steps/research.step.yml +19 -0
- data/.ace-defaults/assign/catalog/steps/review-pr.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/security-audit.step.yml +22 -0
- data/.ace-defaults/assign/catalog/steps/split-subtree-root.step.yml +25 -0
- data/.ace-defaults/assign/catalog/steps/squash-changelog.step.yml +28 -0
- data/.ace-defaults/assign/catalog/steps/task-load.step.yml +29 -0
- data/.ace-defaults/assign/catalog/steps/update-docs.step.yml +38 -0
- data/.ace-defaults/assign/catalog/steps/update-pr-desc.step.yml +28 -0
- data/.ace-defaults/assign/catalog/steps/verify-e2e.step.yml +42 -0
- data/.ace-defaults/assign/catalog/steps/verify-test-suite.step.yml +48 -0
- data/.ace-defaults/assign/catalog/steps/verify-test.step.yml +36 -0
- data/.ace-defaults/assign/catalog/steps/work-on-task.step.yml +23 -0
- data/.ace-defaults/assign/config.yml +48 -0
- data/.ace-defaults/assign/presets/fix-bug.yml +65 -0
- data/.ace-defaults/assign/presets/quick-implement.yml +41 -0
- data/.ace-defaults/assign/presets/release-only.yml +35 -0
- data/.ace-defaults/assign/presets/work-on-docs.yml +41 -0
- data/.ace-defaults/assign/presets/work-on-task.yml +179 -0
- data/.ace-defaults/nav/protocols/skill-sources/ace-assign.yml +19 -0
- data/.ace-defaults/nav/protocols/wfi-sources/ace-assign.yml +19 -0
- data/CHANGELOG.md +1415 -0
- data/README.md +87 -0
- data/Rakefile +16 -0
- data/docs/exit-codes.md +61 -0
- data/docs/getting-started.md +121 -0
- data/docs/handbook.md +40 -0
- data/docs/usage.md +224 -0
- data/exe/ace-assign +16 -0
- data/handbook/guides/fork-context.g.md +231 -0
- data/handbook/skills/as-assign-compose/SKILL.md +24 -0
- data/handbook/skills/as-assign-create/SKILL.md +23 -0
- data/handbook/skills/as-assign-drive/SKILL.md +24 -0
- data/handbook/skills/as-assign-prepare/SKILL.md +23 -0
- data/handbook/skills/as-assign-recover-fork/SKILL.md +22 -0
- data/handbook/skills/as-assign-run-in-batches/SKILL.md +23 -0
- data/handbook/skills/as-assign-start/SKILL.md +25 -0
- data/handbook/workflow-instructions/assign/compose.wf.md +256 -0
- data/handbook/workflow-instructions/assign/create.wf.md +215 -0
- data/handbook/workflow-instructions/assign/drive.wf.md +666 -0
- data/handbook/workflow-instructions/assign/prepare.wf.md +469 -0
- data/handbook/workflow-instructions/assign/recover-fork.wf.md +233 -0
- data/handbook/workflow-instructions/assign/run-in-batches.wf.md +212 -0
- data/handbook/workflow-instructions/assign/start.wf.md +46 -0
- data/lib/ace/assign/atoms/assign_frontmatter_parser.rb +173 -0
- data/lib/ace/assign/atoms/catalog_loader.rb +101 -0
- data/lib/ace/assign/atoms/composition_rules.rb +219 -0
- data/lib/ace/assign/atoms/number_generator.rb +110 -0
- data/lib/ace/assign/atoms/preset_expander.rb +277 -0
- data/lib/ace/assign/atoms/step_file_parser.rb +207 -0
- data/lib/ace/assign/atoms/step_numbering.rb +227 -0
- data/lib/ace/assign/atoms/step_sorter.rb +66 -0
- data/lib/ace/assign/atoms/tree_formatter.rb +106 -0
- data/lib/ace/assign/cli/commands/add.rb +102 -0
- data/lib/ace/assign/cli/commands/assignment_target.rb +55 -0
- data/lib/ace/assign/cli/commands/create.rb +63 -0
- data/lib/ace/assign/cli/commands/fail.rb +43 -0
- data/lib/ace/assign/cli/commands/finish.rb +88 -0
- data/lib/ace/assign/cli/commands/fork_run.rb +229 -0
- data/lib/ace/assign/cli/commands/list.rb +166 -0
- data/lib/ace/assign/cli/commands/retry_cmd.rb +42 -0
- data/lib/ace/assign/cli/commands/select.rb +45 -0
- data/lib/ace/assign/cli/commands/start.rb +40 -0
- data/lib/ace/assign/cli/commands/status.rb +407 -0
- data/lib/ace/assign/cli.rb +144 -0
- data/lib/ace/assign/models/assignment.rb +107 -0
- data/lib/ace/assign/models/assignment_info.rb +66 -0
- data/lib/ace/assign/models/queue_state.rb +326 -0
- data/lib/ace/assign/models/step.rb +197 -0
- data/lib/ace/assign/molecules/assignment_discoverer.rb +57 -0
- data/lib/ace/assign/molecules/assignment_manager.rb +276 -0
- data/lib/ace/assign/molecules/fork_session_launcher.rb +102 -0
- data/lib/ace/assign/molecules/queue_scanner.rb +130 -0
- data/lib/ace/assign/molecules/skill_assign_source_resolver.rb +376 -0
- data/lib/ace/assign/molecules/step_renumberer.rb +227 -0
- data/lib/ace/assign/molecules/step_writer.rb +246 -0
- data/lib/ace/assign/organisms/assignment_executor.rb +1299 -0
- data/lib/ace/assign/version.rb +7 -0
- data/lib/ace/assign.rb +141 -0
- metadata +289 -0
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: workflow
|
|
3
|
+
title: Prepare Assignment Workflow
|
|
4
|
+
purpose: workflow instruction for preparing ace-assign job configurations
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-03-18
|
|
7
|
+
last-checked: 2026-03-21
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Prepare Assignment Workflow
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Transform informal instructions OR preset names into a structured job.yaml file that can be used with `ace-assign create job.yaml`. This workflow bridges the gap between high-level intent and the structured work queue format.
|
|
15
|
+
|
|
16
|
+
## Input Formats
|
|
17
|
+
|
|
18
|
+
The workflow accepts three input types:
|
|
19
|
+
|
|
20
|
+
### 1. Preset Name Only
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
/as-assign-prepare work-on-task --taskref 123
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Loads the preset and injects parameter values.
|
|
27
|
+
|
|
28
|
+
### 2. Informal Instructions Only
|
|
29
|
+
|
|
30
|
+
```
|
|
31
|
+
/as-assign-prepare "Work on task 123, create a PR, do 2 review cycles"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Transforms prose into structured steps.
|
|
35
|
+
|
|
36
|
+
### 3. Preset + Customization
|
|
37
|
+
|
|
38
|
+
```
|
|
39
|
+
/as-assign-prepare work-on-task --taskref 123 "skip onboarding, add security review"
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Loads preset then applies modifications.
|
|
43
|
+
|
|
44
|
+
## Available Presets
|
|
45
|
+
|
|
46
|
+
Presets are stored in `ace-assign/.ace-defaults/assign/presets/`:
|
|
47
|
+
|
|
48
|
+
| Preset | Description |
|
|
49
|
+
|--------|-------------|
|
|
50
|
+
| `work-on-task` | Unified preset for single-task (`--taskref`) and batch (`--taskrefs`) execution |
|
|
51
|
+
|
|
52
|
+
List available presets:
|
|
53
|
+
```bash
|
|
54
|
+
ls ace-assign/.ace-defaults/assign/presets/
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Preset File Format
|
|
58
|
+
|
|
59
|
+
### Basic Preset
|
|
60
|
+
|
|
61
|
+
```yaml
|
|
62
|
+
name: preset-name
|
|
63
|
+
description: What this preset does
|
|
64
|
+
|
|
65
|
+
parameters:
|
|
66
|
+
taskref:
|
|
67
|
+
required: true
|
|
68
|
+
description: Task reference (e.g., task-123 or 123)
|
|
69
|
+
pr_number:
|
|
70
|
+
required: false
|
|
71
|
+
description: Optional PR number for review steps
|
|
72
|
+
|
|
73
|
+
steps:
|
|
74
|
+
- name: step-name
|
|
75
|
+
skill: ace_skill_name # Optional skill reference
|
|
76
|
+
instructions:
|
|
77
|
+
- Step instruction line one.
|
|
78
|
+
- "Step instruction with {{parameter}} placeholder."
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
### Preset with Expansion Directives
|
|
82
|
+
|
|
83
|
+
For multi-task presets, use the `expansion` section to generate hierarchical steps:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
name: work-on-task
|
|
87
|
+
description: Work on multiple tasks with consolidated review
|
|
88
|
+
|
|
89
|
+
parameters:
|
|
90
|
+
taskrefs:
|
|
91
|
+
required: true
|
|
92
|
+
type: array # Accepts comma-separated, range, or pattern
|
|
93
|
+
description: Task references (e.g., "148,149,150" or "148-152")
|
|
94
|
+
|
|
95
|
+
expansion:
|
|
96
|
+
batch-parent:
|
|
97
|
+
name: batch-tasks
|
|
98
|
+
number: "010"
|
|
99
|
+
instructions: |
|
|
100
|
+
Batch container - auto-completes when children done.
|
|
101
|
+
Tasks: {{taskrefs}}
|
|
102
|
+
|
|
103
|
+
foreach: taskrefs # Parameter name to iterate over
|
|
104
|
+
child-template:
|
|
105
|
+
name: "work-on-{{item}}" # {{item}} is current iteration value
|
|
106
|
+
parent: "010"
|
|
107
|
+
context: fork # Parent split step can be forked (children stay non-fork)
|
|
108
|
+
instructions: |
|
|
109
|
+
Implement task {{item}} per specification.
|
|
110
|
+
|
|
111
|
+
steps:
|
|
112
|
+
# Steps after expansion are appended with their own numbers
|
|
113
|
+
- name: consolidated-review
|
|
114
|
+
number: "020"
|
|
115
|
+
instructions: Review all batch changes.
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
#### Array Parameter Syntax
|
|
119
|
+
|
|
120
|
+
The `--taskrefs` parameter accepts multiple formats:
|
|
121
|
+
|
|
122
|
+
| Format | Example | Result |
|
|
123
|
+
|--------|---------|--------|
|
|
124
|
+
| Comma-separated | `148,149,150` | Tasks 148, 149, 150 |
|
|
125
|
+
| Range | `148-152` | Tasks 148, 149, 150, 151, 152 |
|
|
126
|
+
| Pattern | `240.*` | All subtasks of 240 |
|
|
127
|
+
|
|
128
|
+
#### Generated Job Structure
|
|
129
|
+
|
|
130
|
+
For `--taskrefs 148,149,150`, expansion generates:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
010 batch-tasks (parent, auto-completes)
|
|
134
|
+
├── 010.01 work-on-148 (fork context on split parent)
|
|
135
|
+
│ ├── 010.01.01 onboard (no fork marker)
|
|
136
|
+
│ ├── 010.01.02 plan-task (no fork marker)
|
|
137
|
+
│ └── 010.01.03 work-on-task (no fork marker)
|
|
138
|
+
├── 010.02 work-on-149 (fork context on split parent)
|
|
139
|
+
└── 010.03 work-on-150 (fork context on split parent)
|
|
140
|
+
020 consolidated-review
|
|
141
|
+
030 finalize
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
The hierarchical numbering enables:
|
|
145
|
+
- Parent auto-completion when all children are done
|
|
146
|
+
- Parent-only fork markers for subtree delegation
|
|
147
|
+
- Progress tracking per-task
|
|
148
|
+
|
|
149
|
+
## Parameter Placeholders
|
|
150
|
+
|
|
151
|
+
Use `{{parameter}}` syntax in preset instructions:
|
|
152
|
+
- `{{taskrefs}}` - Task references (single-item or multi-item list)
|
|
153
|
+
- `{{pr_number}}` - PR number (when available)
|
|
154
|
+
|
|
155
|
+
Parameters are injected when preparing the job.yaml.
|
|
156
|
+
|
|
157
|
+
## Transformation Rules
|
|
158
|
+
|
|
159
|
+
### From Informal Instructions
|
|
160
|
+
|
|
161
|
+
When parsing informal instructions, identify:
|
|
162
|
+
|
|
163
|
+
1. **Task References**: "task 123", "task-123", "#123"
|
|
164
|
+
2. **Skill Keywords**: Map to known skills
|
|
165
|
+
- "work on task" → `ace:task-work`
|
|
166
|
+
- "create pr", "make pr" → `ace:github-pr-create`
|
|
167
|
+
- "review", "review pr" → `ace:review-pr`
|
|
168
|
+
- "commit" → `ace:git-commit`
|
|
169
|
+
- "onboard" → `onboard`
|
|
170
|
+
3. **Loop Indicators**: "2 cycles", "3 iterations", "twice"
|
|
171
|
+
4. **Sequence Markers**: "then", "after that", "finally"
|
|
172
|
+
|
|
173
|
+
### Loop Expansion
|
|
174
|
+
|
|
175
|
+
Review loops expand into forked cycle parent steps with standard child sub-steps:
|
|
176
|
+
|
|
177
|
+
```yaml
|
|
178
|
+
# "do 3 review cycles" becomes:
|
|
179
|
+
- name: review-valid-1
|
|
180
|
+
context: fork
|
|
181
|
+
sub_steps: [review-pr, apply-feedback, release]
|
|
182
|
+
instructions:
|
|
183
|
+
- "Child review-pr: use preset code-valid."
|
|
184
|
+
- "Focus: correctness — bugs, logic errors, missing functionality, broken contracts."
|
|
185
|
+
|
|
186
|
+
- name: review-fit-1
|
|
187
|
+
context: fork
|
|
188
|
+
sub_steps: [review-pr, apply-feedback, release]
|
|
189
|
+
instructions:
|
|
190
|
+
- "Child review-pr: use preset code-fit."
|
|
191
|
+
- "Focus: quality — performance, architecture, standards, test coverage."
|
|
192
|
+
|
|
193
|
+
- name: review-shine-1
|
|
194
|
+
context: fork
|
|
195
|
+
sub_steps: [review-pr, apply-feedback, release]
|
|
196
|
+
instructions:
|
|
197
|
+
- "Child review-pr: use preset code-shine."
|
|
198
|
+
- "Focus: polish — simplification, naming, documentation (non-blocking suggestions)."
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
## Process Steps
|
|
202
|
+
|
|
203
|
+
### 1. Parse Input
|
|
204
|
+
|
|
205
|
+
Determine input type:
|
|
206
|
+
- If starts with known preset name → load preset
|
|
207
|
+
- If contains `--taskref` or similar flags → extract parameters
|
|
208
|
+
- If quoted string or prose → parse as informal instructions
|
|
209
|
+
|
|
210
|
+
### 2. Load Preset (if applicable)
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
# Read preset file
|
|
214
|
+
cat ace-assign/.ace-defaults/assign/presets/<preset-name>.yml
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 3. Extract Parameters
|
|
218
|
+
|
|
219
|
+
From command-line flags:
|
|
220
|
+
- `--taskref 123` → normalize to `taskrefs: ["123"]` (single task shorthand)
|
|
221
|
+
- `--taskrefs 148,149,150` → `taskrefs: ["148", "149", "150"]` (multi-task)
|
|
222
|
+
- `--taskrefs 148-152` → `taskrefs: ["148", "149", "150", "151", "152"]` (range)
|
|
223
|
+
- `--output custom-job.yaml` → output path
|
|
224
|
+
|
|
225
|
+
From informal instructions:
|
|
226
|
+
- "task 123" → `taskrefs: ["123"]`
|
|
227
|
+
- "tasks 148, 149, 150" → `taskrefs: ["148", "149", "150"]`
|
|
228
|
+
- "PR 45" → `pr_number: "45"`
|
|
229
|
+
|
|
230
|
+
### 4. Apply Customizations (if prose provided)
|
|
231
|
+
|
|
232
|
+
Parse modifications:
|
|
233
|
+
- "skip onboarding" → remove onboard step
|
|
234
|
+
- "add security review" → insert security review step
|
|
235
|
+
- "only 2 cycles" → adjust loop count
|
|
236
|
+
|
|
237
|
+
### 5. Expand and Inject Parameters
|
|
238
|
+
|
|
239
|
+
For presets with `expansion` section, use `Ace::Assign::Atoms::PresetExpander.expand()`:
|
|
240
|
+
|
|
241
|
+
```ruby
|
|
242
|
+
require "ace/assign"
|
|
243
|
+
|
|
244
|
+
preset = YAML.load_file("work-on-task.yml")
|
|
245
|
+
params = { "taskrefs" => ["148", "149", "150"], "review_preset" => "batch" }
|
|
246
|
+
steps = Ace::Assign::Atoms::PresetExpander.expand(preset, params)
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
### 5.1 Resolve Skill `assign.source` Metadata (Deterministic Runtime Expansion)
|
|
250
|
+
|
|
251
|
+
After preset expansion, each step with a `skill:` field may declare assignment source metadata via the skill frontmatter:
|
|
252
|
+
|
|
253
|
+
```yaml
|
|
254
|
+
assign:
|
|
255
|
+
source: wfi://task/work
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
Resolution flow:
|
|
259
|
+
1. Find `SKILL.md` by step `skill` name (e.g., `ace:task-work`)
|
|
260
|
+
2. Read `assign.source` from skill frontmatter
|
|
261
|
+
3. Resolve `wfi://...` to workflow file
|
|
262
|
+
4. Parse workflow frontmatter `assign.sub-steps`
|
|
263
|
+
5. Materialize those sub-steps into the concrete job steps
|
|
264
|
+
|
|
265
|
+
This keeps lifecycle ownership in workflow files while prepare/create remain deterministic.
|
|
266
|
+
Compose intentionally does not perform this metadata scan.
|
|
267
|
+
|
|
268
|
+
This generates hierarchical steps with:
|
|
269
|
+
- Pre-assigned numbers (010, 010.01, 010.02, etc.)
|
|
270
|
+
- Parent-child relationships
|
|
271
|
+
- All `{{placeholder}}` tokens resolved
|
|
272
|
+
|
|
273
|
+
For standard presets (no expansion), replace `{{parameter}}` placeholders:
|
|
274
|
+
|
|
275
|
+
```yaml
|
|
276
|
+
# Before
|
|
277
|
+
instructions:
|
|
278
|
+
- "Work on task {{taskref}}."
|
|
279
|
+
|
|
280
|
+
# After (with taskref=123)
|
|
281
|
+
instructions:
|
|
282
|
+
- Work on task 123.
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
### 6. Validate Job Configuration
|
|
286
|
+
|
|
287
|
+
Check:
|
|
288
|
+
- [ ] Session name is set
|
|
289
|
+
- [ ] All required parameters have values
|
|
290
|
+
- [ ] No unresolved `{{placeholder}}` tokens remain
|
|
291
|
+
- [ ] Steps have names and instructions
|
|
292
|
+
- [ ] Skill references are valid (if present)
|
|
293
|
+
|
|
294
|
+
### 7. Generate job.yaml
|
|
295
|
+
|
|
296
|
+
Write the final configuration:
|
|
297
|
+
|
|
298
|
+
```yaml
|
|
299
|
+
session:
|
|
300
|
+
name: <preset-name>-<taskref>
|
|
301
|
+
description: <preset description with context>
|
|
302
|
+
|
|
303
|
+
steps:
|
|
304
|
+
- name: <step-name>
|
|
305
|
+
skill: <skill-reference> # If present in preset
|
|
306
|
+
instructions:
|
|
307
|
+
- <resolved instruction line>
|
|
308
|
+
# ... more steps
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### 8. Output Result
|
|
312
|
+
|
|
313
|
+
Default output: `<task>/jobs/<timestamp>-job.yml` (e.g., `.ace-taskflow/v.0.9.0/tasks/229-xxx/jobs/k5abc123-job.yml`)
|
|
314
|
+
|
|
315
|
+
Custom output: Use `--output path/to/custom.yaml`
|
|
316
|
+
|
|
317
|
+
Report:
|
|
318
|
+
```
|
|
319
|
+
Job configuration created: job.yaml
|
|
320
|
+
|
|
321
|
+
Session: work-on-task-123
|
|
322
|
+
Steps: 10 total
|
|
323
|
+
- onboard
|
|
324
|
+
- work-on-task
|
|
325
|
+
- create-pr
|
|
326
|
+
- review-cycle-1
|
|
327
|
+
- apply-feedback-1
|
|
328
|
+
- review-cycle-2
|
|
329
|
+
- apply-feedback-2
|
|
330
|
+
- review-cycle-3
|
|
331
|
+
- apply-feedback-3
|
|
332
|
+
- finalize
|
|
333
|
+
|
|
334
|
+
Start assignment with: ace-assign create job.yaml
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
## Output Format
|
|
338
|
+
|
|
339
|
+
### job.yaml Structure
|
|
340
|
+
|
|
341
|
+
```yaml
|
|
342
|
+
session:
|
|
343
|
+
name: work-on-task-123
|
|
344
|
+
description: Work on task 123 with PR and review cycles
|
|
345
|
+
|
|
346
|
+
steps:
|
|
347
|
+
- name: onboard
|
|
348
|
+
skill: as-onboard
|
|
349
|
+
instructions:
|
|
350
|
+
- Onboard yourself to the codebase.
|
|
351
|
+
- Load context and understand the project structure.
|
|
352
|
+
|
|
353
|
+
- name: work-on-task
|
|
354
|
+
skill: as-task-work
|
|
355
|
+
instructions:
|
|
356
|
+
- Work on task 123.
|
|
357
|
+
- Implement the required changes following project conventions.
|
|
358
|
+
|
|
359
|
+
- name: create-pr
|
|
360
|
+
skill: as-github-pr-create
|
|
361
|
+
instructions:
|
|
362
|
+
- Create a pull request for the changes.
|
|
363
|
+
- Capture the PR number for subsequent review steps.
|
|
364
|
+
- Update the next steps with the PR number.
|
|
365
|
+
|
|
366
|
+
# ... more steps
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
## Error Handling
|
|
370
|
+
|
|
371
|
+
| Scenario | Action |
|
|
372
|
+
|----------|--------|
|
|
373
|
+
| Unknown preset | List available presets, ask for selection |
|
|
374
|
+
| Missing required parameter | Prompt for value |
|
|
375
|
+
| Invalid task reference | Show expected formats |
|
|
376
|
+
| Unresolved placeholders | Report which parameters need values |
|
|
377
|
+
|
|
378
|
+
## Examples
|
|
379
|
+
|
|
380
|
+
### Example 1: Full Workflow Preset
|
|
381
|
+
|
|
382
|
+
```
|
|
383
|
+
/as-assign-prepare work-on-task --taskref 148
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
Creates job with 13 steps: onboard, work-on-task, release, create-pr, 2 review cycles (review + apply-feedback + release each), reorganize-commits, push-to-remote, update-pr-desc.
|
|
387
|
+
|
|
388
|
+
### Example 2: Informal Instructions
|
|
389
|
+
|
|
390
|
+
```
|
|
391
|
+
/as-assign-prepare "implement task 148, create pr, review twice"
|
|
392
|
+
```
|
|
393
|
+
|
|
394
|
+
Parses instructions and creates job with:
|
|
395
|
+
- onboard
|
|
396
|
+
- work-on-task (148)
|
|
397
|
+
- create-pr
|
|
398
|
+
- review-valid-1 (fork subtree: review-pr → apply-feedback → release)
|
|
399
|
+
- review-fit-1 (fork subtree: review-pr → apply-feedback → release)
|
|
400
|
+
- finalize
|
|
401
|
+
|
|
402
|
+
### Example 3: Custom Output Path
|
|
403
|
+
|
|
404
|
+
```
|
|
405
|
+
/as-assign-prepare work-on-task --taskref 148 --output .cache/my-job.yaml
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Writes configuration to specified path.
|
|
409
|
+
|
|
410
|
+
### Example 4: Multi-Task Batch (Comma-Separated)
|
|
411
|
+
|
|
412
|
+
```
|
|
413
|
+
/as-assign-prepare work-on-task --taskrefs 148,149,150
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
Creates job with hierarchical structure:
|
|
417
|
+
- batch-tasks (010) - parent container
|
|
418
|
+
- work-on-148 (010.01) - fork context
|
|
419
|
+
- work-on-149 (010.02) - fork context
|
|
420
|
+
- work-on-150 (010.03) - fork context
|
|
421
|
+
- consolidated-review (020)
|
|
422
|
+
- finalize (030)
|
|
423
|
+
|
|
424
|
+
### Example 5: Multi-Task Batch (Range)
|
|
425
|
+
|
|
426
|
+
```
|
|
427
|
+
/as-assign-prepare work-on-task --taskrefs 148-152
|
|
428
|
+
```
|
|
429
|
+
|
|
430
|
+
Expands range to tasks 148, 149, 150, 151, 152.
|
|
431
|
+
|
|
432
|
+
### Example 6: Multi-Task Batch (Pattern)
|
|
433
|
+
|
|
434
|
+
```
|
|
435
|
+
/as-assign-prepare work-on-task --taskrefs "240.*"
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
Expands pattern to match subtasks (requires resolution at prepare time).
|
|
439
|
+
|
|
440
|
+
## Success Criteria
|
|
441
|
+
|
|
442
|
+
- [ ] Input correctly parsed (preset, parameters, or prose)
|
|
443
|
+
- [ ] Preset loaded and parameters injected
|
|
444
|
+
- [ ] Expansion directives processed (if present)
|
|
445
|
+
- [ ] Hierarchical steps numbered correctly
|
|
446
|
+
- [ ] Loops expanded into separate steps
|
|
447
|
+
- [ ] All placeholders resolved
|
|
448
|
+
- [ ] Valid job.yaml generated
|
|
449
|
+
- [ ] Clear summary provided to user
|
|
450
|
+
|
|
451
|
+
## Next Steps
|
|
452
|
+
|
|
453
|
+
After job.yaml is created:
|
|
454
|
+
|
|
455
|
+
```bash
|
|
456
|
+
# Start the assignment
|
|
457
|
+
/as-assign-create job.yaml
|
|
458
|
+
|
|
459
|
+
# Or directly:
|
|
460
|
+
ace-assign create job.yaml
|
|
461
|
+
|
|
462
|
+
# Check status
|
|
463
|
+
ace-assign status
|
|
464
|
+
|
|
465
|
+
# Drive execution through the workflow
|
|
466
|
+
/as-assign-drive
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
**Note:** Job files created in `<task>/jobs/` stay in place when `ace-assign create` runs. Files created elsewhere are moved to `<task>/jobs/<session_id>-job.yml` for provenance. Always use `ace-assign status` to query the current assignment state.
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
---
|
|
2
|
+
doc-type: workflow
|
|
3
|
+
title: Fork Recovery Workflow
|
|
4
|
+
purpose: Recover from fork-run failures — crash with partial completion, provider unavailability, or mixed subtree state
|
|
5
|
+
ace-docs:
|
|
6
|
+
last-updated: 2026-03-22
|
|
7
|
+
last-checked: 2026-03-22
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Fork Recovery Workflow
|
|
11
|
+
|
|
12
|
+
## Purpose
|
|
13
|
+
|
|
14
|
+
Recover from `fork-run` failures during assignment execution. This workflow is invoked by the driver when a fork subtree exits non-zero. It covers three scenarios: crash with partial progress, provider unavailability, and mixed subtree state after provider failure.
|
|
15
|
+
|
|
16
|
+
## Prerequisites
|
|
17
|
+
|
|
18
|
+
- A fork subtree that exited non-zero (`fork-run` failed)
|
|
19
|
+
- The driver has the `ASSIGNMENT_ID` and `FORK_ROOT` pinned
|
|
20
|
+
- The driver has NOT started executing fork work inline (fork boundary intact)
|
|
21
|
+
|
|
22
|
+
## Variables
|
|
23
|
+
|
|
24
|
+
- `$ASSIGNMENT_ID`: The pinned assignment identifier
|
|
25
|
+
- `$FORK_ROOT`: The root step number of the failed fork subtree (e.g., `020`)
|
|
26
|
+
- `$failed_step`: The specific step that was active when the fork crashed
|
|
27
|
+
|
|
28
|
+
## Detection: When to Use This Workflow
|
|
29
|
+
|
|
30
|
+
Invoke this workflow when `fork-run` exits non-zero. Determine the scenario:
|
|
31
|
+
|
|
32
|
+
| Signal | Scenario | Go to |
|
|
33
|
+
|--------|----------|-------|
|
|
34
|
+
| `exit != 0` AND (`git status --short` shows changes OR mixed step status) | Crash with partial progress | Scenario 1 |
|
|
35
|
+
| `exit != 0` AND error indicates timeout/hang/empty response (no stack trace, no test failure) | Provider unavailability | Scenario 2 |
|
|
36
|
+
| `exit != 0` AND subtree has mix of done + failed + pending children after provider failure | Mixed state after provider failure | Scenario 3 |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Scenario 1: Crash with Partial Completion
|
|
41
|
+
|
|
42
|
+
The fork crashed due to a code issue, environment error, or timeout — but made partial progress.
|
|
43
|
+
|
|
44
|
+
### Step 1: Commit Partial Work
|
|
45
|
+
|
|
46
|
+
Stage and commit any uncommitted changes from the crashed fork:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
git add -A
|
|
50
|
+
ace-git-commit -i "partial: save fork progress for ${FORK_ROOT}"
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Step 2: Write Progress Report for the Active Step
|
|
54
|
+
|
|
55
|
+
Document what was accomplished and what remains:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
cat > /tmp/partial-report.md << 'EOF'
|
|
59
|
+
## Partial Completion (fork crashed)
|
|
60
|
+
|
|
61
|
+
### Completed
|
|
62
|
+
- [list of files created/modified]
|
|
63
|
+
- [tests passing: X tests, Y assertions]
|
|
64
|
+
|
|
65
|
+
### Remaining
|
|
66
|
+
- [list of components not yet implemented]
|
|
67
|
+
- [tests not yet written]
|
|
68
|
+
EOF
|
|
69
|
+
ace-assign finish --message /tmp/partial-report.md --assignment ${ASSIGNMENT_ID}@${failed_step}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Step 3: Inject Recovery Steps
|
|
73
|
+
|
|
74
|
+
Add two child steps inside the failed step's subtree. **Never inject as top-level siblings.**
|
|
75
|
+
|
|
76
|
+
#### Recovery Step Construction Rules
|
|
77
|
+
|
|
78
|
+
**recovery-onboard** — Must enumerate all completed subtree report paths explicitly:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# 1. List all completed reports in the subtree
|
|
82
|
+
REPORT_DIR=".ace-local/assign/${ASSIGNMENT_ID}/reports"
|
|
83
|
+
REPORT_LIST=$(ls ${REPORT_DIR}/${FORK_ROOT}.* 2>/dev/null | sort)
|
|
84
|
+
|
|
85
|
+
# 2. Build the instruction with explicit file paths
|
|
86
|
+
RECOVERY_INSTRUCTIONS="Read these reports to understand completed work before continuing:
|
|
87
|
+
$(echo "$REPORT_LIST" | sed 's/^/- /')
|
|
88
|
+
Also read the failure evidence from the failed step."
|
|
89
|
+
|
|
90
|
+
# 3. Inject the step
|
|
91
|
+
ace-assign add "recovery-onboard" --after ${failed_step} --child \
|
|
92
|
+
--assignment ${ASSIGNMENT_ID}@${FORK_ROOT} \
|
|
93
|
+
-i "$RECOVERY_INSTRUCTIONS"
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
The recovery-onboard instructions MUST list every report file path — not semantic references like "read the plan-task report". A forked recovery agent starts with zero context and cannot infer the directory structure.
|
|
97
|
+
|
|
98
|
+
**continue-work** — Must be a verbatim copy of the original failed step's instructions:
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# 1. Read the original failed step file
|
|
102
|
+
STEP_FILE=$(ls .ace-local/assign/${ASSIGNMENT_ID}/steps/${failed_step}-*.st.md)
|
|
103
|
+
|
|
104
|
+
# 2. Extract the instruction body (everything after YAML frontmatter)
|
|
105
|
+
ORIGINAL_INSTRUCTIONS=$(sed '1,/^---$/{ /^---$/!d; /^---$/d }' "$STEP_FILE" | sed '1,/^---$/d')
|
|
106
|
+
|
|
107
|
+
# 3. Inject continue-work with the SAME instructions
|
|
108
|
+
ace-assign add "continue-work" --after recovery-onboard --child \
|
|
109
|
+
--assignment ${ASSIGNMENT_ID}@${FORK_ROOT} \
|
|
110
|
+
-i "$ORIGINAL_INSTRUCTIONS"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The continue-work step IS the restart of the same work — it needs the same execution rules, principles, conventions, and done criteria that the original agent had. Do NOT compress or summarize the instructions. Only the recovery-onboard step gets special "catch up" instructions.
|
|
114
|
+
|
|
115
|
+
### Step 4: Reset Downstream Steps
|
|
116
|
+
|
|
117
|
+
If any steps after the failed step were completed during a prior (incorrect) recovery attempt, reset them:
|
|
118
|
+
|
|
119
|
+
- Set their status back to `pending` in the step file frontmatter
|
|
120
|
+
- Delete their report files from `.ace-local/assign/${ASSIGNMENT_ID}/reports/`
|
|
121
|
+
|
|
122
|
+
### Step 5: Re-Fork
|
|
123
|
+
|
|
124
|
+
The injected recovery steps are pending, so `fork-run` will pick them up:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
ace-assign fork-run --assignment ${ASSIGNMENT_ID}@${FORK_ROOT}
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## Scenario 2: Provider Unavailability
|
|
133
|
+
|
|
134
|
+
The fork failed because the LLM provider timed out, hung, or returned no output — not because of a code bug. Re-forking would crash the same way.
|
|
135
|
+
|
|
136
|
+
### Step 1: Confirm Provider Failure
|
|
137
|
+
|
|
138
|
+
Read the fork's last message and failed step error. Look for:
|
|
139
|
+
- Model timeout or API unavailability
|
|
140
|
+
- Empty or truncated response
|
|
141
|
+
- Connection reset or socket hangup
|
|
142
|
+
- Tool hang with no output
|
|
143
|
+
|
|
144
|
+
NOT provider failure: stack traces, test failures, syntax errors — those are code bugs (use Scenario 1).
|
|
145
|
+
|
|
146
|
+
### Step 2: Classify the Failed Step
|
|
147
|
+
|
|
148
|
+
| Step Type | Description | Example Steps |
|
|
149
|
+
|-----------|-------------|---------------|
|
|
150
|
+
| **LLM-tool step** | Invokes an LLM-backed tool as its primary action | `ace-review`, `ace-lint`, audit, summarize |
|
|
151
|
+
| **Code step** | Produces or modifies source code | implement, fix, refactor, work-on-task |
|
|
152
|
+
|
|
153
|
+
### Step 3: Fork-Side Action (if still inside fork)
|
|
154
|
+
|
|
155
|
+
The fork MUST only fail and exit. It must NEVER inject steps:
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
# Mark the crashed step as failed with evidence, then exit
|
|
159
|
+
ace-assign fail --message "Provider unavailable: <error details>" \
|
|
160
|
+
--assignment ${ASSIGNMENT_ID}@${failed_step}
|
|
161
|
+
# EXIT — do not add steps, do not retry, do not modify the assignment tree
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
**Forks NEVER inject steps outside their subtree scope. Recovery decisions belong to the driver.**
|
|
165
|
+
|
|
166
|
+
### Step 4: Driver-Side Recovery
|
|
167
|
+
|
|
168
|
+
After detecting the fork failure, the driver classifies and recovers:
|
|
169
|
+
|
|
170
|
+
**LLM-tool steps** → execute equivalent work inline at driver level:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
# Option A: Execute inline (for LLM-tool steps only)
|
|
174
|
+
# Read changed files, analyze each, write review report directly
|
|
175
|
+
|
|
176
|
+
# Option B: Add retry as a child of the failed step's parent
|
|
177
|
+
ace-assign add "retry-<step-name>" --after <failed_step> --child \
|
|
178
|
+
--assignment ${ASSIGNMENT_ID}@${FORK_ROOT} \
|
|
179
|
+
-i "Provider was unavailable for forked <step-name>. Execute equivalent work inline: <specific instructions>"
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
**Code steps** → do NOT execute inline. Wait for provider recovery or escalate:
|
|
183
|
+
|
|
184
|
+
```bash
|
|
185
|
+
# Ask user whether to wait and retry later
|
|
186
|
+
# Do NOT attempt the code work inline — context isolation is required
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Inline execution constraint**: Only LLM-tool steps may go inline during provider unavailability. Code-producing steps always require a fork for context isolation — wait for recovery or ask the user.
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## Scenario 3: Re-Fork After Partial Provider Failure
|
|
194
|
+
|
|
195
|
+
The fork subtree has a mix of done, failed, and pending children after a provider failure. The driver recovers by re-forking — not by absorbing remaining work inline.
|
|
196
|
+
|
|
197
|
+
### Protocol
|
|
198
|
+
|
|
199
|
+
1. **Inject retry as a child** of the failed step's parent subtree (never as a top-level sibling):
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
ace-assign add "retry-<step-name>" --after ${failed_child} --child \
|
|
203
|
+
--assignment ${ASSIGNMENT_ID}@${FORK_ROOT} \
|
|
204
|
+
-i "Retry <step-name> after provider recovery."
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
2. **Re-fork the subtree** — fork-run re-enters and picks up pending/retry children:
|
|
208
|
+
|
|
209
|
+
```bash
|
|
210
|
+
ace-assign fork-run --assignment "${ASSIGNMENT_ID}@${FORK_ROOT}"
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
3. **Do NOT inject steps as top-level siblings** — retry steps must be children of the original subtree root, never top-level steps like `101` or `121`.
|
|
214
|
+
|
|
215
|
+
**Anti-pattern**: Driver sees subtree 110 with 110.01 failed, 110.02 and 110.03 pending. Driver executes 110.02 and 110.03 inline. This defeats context isolation and violates the fork-delegation constraint.
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## Key Principles
|
|
220
|
+
|
|
221
|
+
1. **Never execute fork work inline** — except for LLM-tool steps during provider unavailability. The fork boundary exists for context isolation.
|
|
222
|
+
2. **Recovery steps are always children, never top-level siblings** — injecting at the top level breaks subtree scope and causes downstream steps to run without prerequisite work.
|
|
223
|
+
3. **Recovery-onboard lists explicit file paths** — never semantic references. The recovery agent has zero context.
|
|
224
|
+
4. **Continue-work copies original instructions verbatim** — the restart needs the same rules as the original. Only recovery-onboard gets special instructions.
|
|
225
|
+
5. **Reset downstream steps after incorrect recovery** — if steps ran without their prerequisite work, they must be reset to pending with their reports deleted.
|
|
226
|
+
|
|
227
|
+
## Success Criteria
|
|
228
|
+
|
|
229
|
+
- Failed fork subtree is recovered without breaking fork isolation
|
|
230
|
+
- Recovery children are injected inside the correct subtree scope
|
|
231
|
+
- Recovery agent receives explicit report paths and complete original instructions
|
|
232
|
+
- Re-fork picks up pending recovery steps and completes the subtree
|
|
233
|
+
- No fork work is absorbed into the driver (except LLM-tool inline during provider unavailability)
|