@open-agent-toolkit/cli 0.2.27 → 0.2.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/agents/oat-phase-implementer.md +312 -7
- package/assets/bundle-metadata.json +4 -0
- package/assets/docs/workflows/projects/autonomy.md +25 -0
- package/assets/docs/workflows/projects/implementation-execution.md +151 -1
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +16 -3
- package/assets/skills/oat-project-autonomous/SKILL.md +17 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +5 -5
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +5 -5
- package/assets/skills/oat-project-implement/SKILL.md +5 -4
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +21 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +5 -5
- package/assets/skills/oat-project-implement/references/phase-execution.md +359 -12
- package/assets/skills/oat-project-import-plan/SKILL.md +7 -3
- package/assets/skills/oat-project-plan/SKILL.md +6 -3
- package/assets/skills/oat-project-plan-writing/SKILL.md +32 -5
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +5 -5
- package/assets/skills/oat-project-quick-start/SKILL.md +7 -3
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +5 -5
- package/assets/templates/state.md +7 -0
- package/dist/fs/assets.d.ts +1 -0
- package/dist/fs/assets.d.ts.map +1 -1
- package/dist/fs/assets.js +36 -1
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +1 -0
- package/package.json +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-phase-implementer
|
|
3
|
-
version: 1.0.
|
|
3
|
+
version: 1.0.11
|
|
4
4
|
description: Implements one plan phase end-to-end, commits each task separately, self-checks between tasks, and handles bounded review fixes when resumed by oat-project-implement.
|
|
5
5
|
tools: Read, Write, Edit, Bash, Grep, Glob, Task
|
|
6
6
|
color: cyan
|
|
@@ -26,7 +26,7 @@ The root supplies:
|
|
|
26
26
|
|
|
27
27
|
- `project`: active OAT project path;
|
|
28
28
|
- `phase`: one phase ID;
|
|
29
|
-
- `mode`: `implement` or `
|
|
29
|
+
- `mode`: `implement`, `fix`, or `recover`;
|
|
30
30
|
- `artifact_paths`: available plan, design, spec, discovery, implementation,
|
|
31
31
|
and imported-plan paths;
|
|
32
32
|
- `workflow_mode`: `spec-driven`, `quick`, or `import`;
|
|
@@ -35,6 +35,8 @@ The root supplies:
|
|
|
35
35
|
- `worktree`: assigned phase worktree or orchestration checkout;
|
|
36
36
|
- launcher-owned dispatch policy, target, arguments, axes, selection reason,
|
|
37
37
|
candidates, and formal dispatch stamp;
|
|
38
|
+
- `phase_recovery_limit`, `phase_recovery_attempts_used`,
|
|
39
|
+
`original_request_id`, and the root-resolved recovery authorization source;
|
|
38
40
|
- optional `parallel_group`, `expected_base_sha`, and smoke run metadata.
|
|
39
41
|
|
|
40
42
|
Fix mode also supplies:
|
|
@@ -45,8 +47,21 @@ Fix mode also supplies:
|
|
|
45
47
|
- `original_request_id`: original phase dispatch request;
|
|
46
48
|
- `continuation_event`: resume linkage for this fix attempt.
|
|
47
49
|
|
|
50
|
+
Recover mode also supplies:
|
|
51
|
+
|
|
52
|
+
- `original_request_id` and `continuation_event`;
|
|
53
|
+
- `recovery_base_head`, `original_task_id`, and immutable `original_commit`;
|
|
54
|
+
- `defect_class`, `discovered_by`, `bounded_correction_scope`, and
|
|
55
|
+
`bounded_files`;
|
|
56
|
+
- `phase_recovery_limit`, `phase_recovery_attempts_used`, and the authoritative
|
|
57
|
+
`pending_attempt` ledger entry;
|
|
58
|
+
- `focused_verification` and `phase_verification`; and
|
|
59
|
+
- the exact original `dispatch_target` plus launcher-owned axes and stamp.
|
|
60
|
+
|
|
48
61
|
Reject a missing/unknown phase, an unrecognized mode, a base mismatch, or a
|
|
49
|
-
fix request without bounded findings.
|
|
62
|
+
fix request without bounded findings. Reject recover mode when any recover input
|
|
63
|
+
is absent, the continuation does not link to the original request, or the
|
|
64
|
+
pending attempt cannot be reconciled.
|
|
50
65
|
|
|
51
66
|
## Shared Dispatch Contract
|
|
52
67
|
|
|
@@ -101,6 +116,195 @@ After formatting, run the repository's applicable gate set over the produced
|
|
|
101
116
|
diff, explicitly including artifact writes. This supplements rather than
|
|
102
117
|
replaces every task and phase verification command below.
|
|
103
118
|
|
|
119
|
+
## Prevention and Post-Commit Recovery
|
|
120
|
+
|
|
121
|
+
Prevention is the first recovery control. Before every planned task commit:
|
|
122
|
+
|
|
123
|
+
1. format every changed file;
|
|
124
|
+
2. run the declared task verification;
|
|
125
|
+
3. run every repository-discovered cheap check applicable to the changed
|
|
126
|
+
surface when it is discoverable and proportionate; and
|
|
127
|
+
4. when a task changes emitted output, build/test configuration, packaging, or
|
|
128
|
+
equivalent behavior, run the discoverable scoped build or test before
|
|
129
|
+
commit when its cost is proportionate.
|
|
130
|
+
|
|
131
|
+
Run those checks in that order before commit. Broad repository tests or builds
|
|
132
|
+
may remain phase-level when running them per task is disproportionate.
|
|
133
|
+
Corrections completed before the planned task commit are prevention and do not
|
|
134
|
+
consume a phase recovery attempt.
|
|
135
|
+
|
|
136
|
+
When a task-transition or phase check discovers a post-commit failure, classify
|
|
137
|
+
it before editing. Automatic recovery is allowed only when all conditions hold:
|
|
138
|
+
|
|
139
|
+
- the failure is an obvious in-scope lint, type, test, build, or composition
|
|
140
|
+
defect discovered by declared task, transition, or phase verification;
|
|
141
|
+
- the correction is mechanically bounded and unambiguous, remains within phase
|
|
142
|
+
intent and public requirements, and any file-boundary expansion is
|
|
143
|
+
mechanically derived and in-phase;
|
|
144
|
+
- architecture, security, product scope, requirements, and public behavior do
|
|
145
|
+
not change;
|
|
146
|
+
- the work is non-destructive, reversible, and does not cross credential,
|
|
147
|
+
protected-branch, or other consequential boundaries;
|
|
148
|
+
- the exact target remains unchanged and bindable regardless of handle state
|
|
149
|
+
and stays equal to the launcher-owned dispatch target;
|
|
150
|
+
- handle continuity follows one of the authorized alternatives below;
|
|
151
|
+
- attempt accounting follows one of the authorized alternatives below; and
|
|
152
|
+
- focused plus relevant phase verification can establish correctness.
|
|
153
|
+
|
|
154
|
+
Handle and exact-target continuity use these mutually compatible branches:
|
|
155
|
+
|
|
156
|
+
1. When the accepted handle is available or resumable, use same-handle
|
|
157
|
+
continuation.
|
|
158
|
+
2. When the accepted handle is unavailable or unresumable, an unchanged,
|
|
159
|
+
bindable exact target plus a lifecycle-authorized recover scope, a reconciled
|
|
160
|
+
pending attempt, and continuation linkage authorizes fresh `mode: recover`.
|
|
161
|
+
3. A lost or unbindable exact target requires a direction-required stop with no
|
|
162
|
+
fallback.
|
|
163
|
+
|
|
164
|
+
Handle unavailability alone does not make automatic recovery ineligible or
|
|
165
|
+
stop it. It selects the second branch only when all its conditions hold.
|
|
166
|
+
|
|
167
|
+
Attempt accounting uses exactly one of these alternatives:
|
|
168
|
+
|
|
169
|
+
1. **Pending completion:** a matching `pending_attempt` may continue only after
|
|
170
|
+
complete reconciliation of the authoritative ledger, original request,
|
|
171
|
+
immutable original commit at the same history position, bounded worktree
|
|
172
|
+
diff, and unchanged exact target. Continue and finish that same reserved
|
|
173
|
+
attempt without incrementing `used_attempts` or creating another
|
|
174
|
+
reservation, even when the existing count equals the limit.
|
|
175
|
+
2. **New reservation:** when no `pending_attempt` exists,
|
|
176
|
+
`phase_recovery_attempts_used < phase_recovery_limit` is mandatory. Atomically
|
|
177
|
+
increment usage and write the new reservation before editing.
|
|
178
|
+
|
|
179
|
+
For the final-attempt boundary, `limit=1`, `used=1`, and a fully reconciled
|
|
180
|
+
matching `pending_attempt` continue and finish the same reserved attempt
|
|
181
|
+
without incrementing usage. With `limit=1`, `used=1`, and no `pending_attempt`,
|
|
182
|
+
stop direction-required before edit with no new reservation and no fallback.
|
|
183
|
+
|
|
184
|
+
Record the eligibility evidence before editing. A new reservation consumes one
|
|
185
|
+
attempt before editing; continuation of a reconciled pending attempt does not
|
|
186
|
+
consume another. Apply the bounded correction and run the focused and phase
|
|
187
|
+
checks before creating a candidate commit. If either check fails, restore the
|
|
188
|
+
bounded files to their original committed content without rewriting history,
|
|
189
|
+
atomically mark the reservation `failed`, durably commit only that ledger
|
|
190
|
+
transition, and stop. When both checks pass, atomically mark the reservation
|
|
191
|
+
`completed` and create one append-only candidate recovery commit containing the
|
|
192
|
+
bounded correction plus that transition.
|
|
193
|
+
|
|
194
|
+
Immediately rerun the focused and phase checks against the committed HEAD.
|
|
195
|
+
These post-commit reruns are the authoritative recovery result. On pass, the
|
|
196
|
+
candidate is the successful recovery commit. On failure, atomically replace the
|
|
197
|
+
`completed` marker with `failed`, durably commit that ledger-only transition,
|
|
198
|
+
preserve the candidate commit as immutable, claim no successful recovery
|
|
199
|
+
commit, and stop. Any failed edit, commit, or re-verification leaves the attempt
|
|
200
|
+
consumed. Preserve the accepted task commit at the same history position; never
|
|
201
|
+
amend, reset, rebase, squash, replace its task ID, or conceal it. Mechanically
|
|
202
|
+
related failures from the same verification command may use one atomic attempt
|
|
203
|
+
and successful recovery commit. Independent failures require separate attempts.
|
|
204
|
+
At three recovery events, report an elevated recovery-volume warning but
|
|
205
|
+
continue while the predicate and budget remain valid.
|
|
206
|
+
|
|
207
|
+
A suspected infrastructure or flake failure permits one no-edit rerun without
|
|
208
|
+
attempt consumption. If the repeated unexplained failure remains ambiguous,
|
|
209
|
+
stop without editing. Never turn contradictory evidence into a speculative
|
|
210
|
+
repair.
|
|
211
|
+
|
|
212
|
+
Stop with `DONE_WITH_CONCERNS` or `BLOCKED`, do not edit, and request direction
|
|
213
|
+
for any ambiguous or contradictory case; architecture, security, product, or
|
|
214
|
+
requirements decision; non-mechanical boundary widening; destructive,
|
|
215
|
+
irreversible, credential-bearing, or protected-branch work; retry exhaustion;
|
|
216
|
+
dirty worktree or dirty history; inability to establish correctness; missing
|
|
217
|
+
original-request or missing exact-target provenance; unverifiable commit range;
|
|
218
|
+
malformed recovery event; exact-target loss; or governance cap. No stop
|
|
219
|
+
condition authorizes fallback or another model, provider, route, or worker.
|
|
220
|
+
|
|
221
|
+
Every post-commit disposition returns exactly one canonical recovery event,
|
|
222
|
+
including recovered, direction-required, and failed-attempt outcomes. The event
|
|
223
|
+
must preserve original request, original commit, defect class, discovering
|
|
224
|
+
check, disposition, authorization, attempt/budget, dispatch target, recovery
|
|
225
|
+
commit when one exists, verification outcome, and reason. This allows defect
|
|
226
|
+
count, prompt count, and successful repair count to remain independently
|
|
227
|
+
measurable.
|
|
228
|
+
|
|
229
|
+
A `direction-required` disposition reached before any reservation leaves
|
|
230
|
+
`pending_attempt: null`, does not increment `used_attempts`, and performs no
|
|
231
|
+
edit or recovery commit. Its event carries the stop-boundary evidence so root
|
|
232
|
+
can validate and record the terminal stop without expecting a `completed` or
|
|
233
|
+
`failed` marker.
|
|
234
|
+
|
|
235
|
+
### Authoritative Attempt Ledger
|
|
236
|
+
|
|
237
|
+
The active project's
|
|
238
|
+
`oat_phase_recovery_policy.phase_attempt_usage.<pNN>` entry in `state.md` is the
|
|
239
|
+
one authoritative durable per-phase attempt ledger. The phase implementer has a
|
|
240
|
+
narrow exception to root-owned bookkeeping: while it owns the worktree, it may
|
|
241
|
+
atomically replace only that ledger entry. It must not alter any other project
|
|
242
|
+
tracking field.
|
|
243
|
+
|
|
244
|
+
Before the first code edit for a new recovery attempt, atomically increment
|
|
245
|
+
`used_attempts` and write `pending_attempt` with the attempt number, event ID,
|
|
246
|
+
original request, original task/commit, discovering check, exact target, and
|
|
247
|
+
reservation HEAD. This reservation happens before editing and survives
|
|
248
|
+
interruption. Never decrement or reset `used_attempts`.
|
|
249
|
+
|
|
250
|
+
On same-handle resume or recover mode, reconcile the supplied nonzero
|
|
251
|
+
`used_attempts` and `pending_attempt` against `state.md`, Git history, and the
|
|
252
|
+
bounded worktree diff. Complete reconciliation includes the ledger identities,
|
|
253
|
+
original request, immutable original commit at the same history position,
|
|
254
|
+
bounded diff, and unchanged exact target. Continue the same attempt without
|
|
255
|
+
consuming another attempt. Reject an unreconciled resume before further
|
|
256
|
+
editing. A new attempt is exhausted when `used_attempts` is equal to or greater
|
|
257
|
+
than `phase_recovery_limit`; an already-pending matching attempt may only finish
|
|
258
|
+
or fail and does not receive another reservation.
|
|
259
|
+
|
|
260
|
+
Run focused and phase checks before a candidate commit. A pre-commit failure
|
|
261
|
+
restores the bounded files and commits only the `failed` transition. A
|
|
262
|
+
pre-commit pass atomically marks the pending entry `completed` and creates the
|
|
263
|
+
candidate recovery commit with the bounded code change plus that transition.
|
|
264
|
+
Immediately rerun both checks against committed HEAD. Those reruns are
|
|
265
|
+
authoritative: a pass leaves the committed `completed` marker for root
|
|
266
|
+
validation, while a failure atomically replaces it with `failed` in a separate
|
|
267
|
+
ledger-only evidence commit and claims no successful recovery commit. If any
|
|
268
|
+
required terminal marker cannot be committed, preserve the working tree and
|
|
269
|
+
report the attempt as unreconciled; root must fail closed without bookkeeping.
|
|
270
|
+
|
|
271
|
+
The final matching committed `completed` or `failed` marker is the committed
|
|
272
|
+
pre-bookkeeping terminal handoff for an attempted recovery. A report of
|
|
273
|
+
`recovered` or `failed-attempt` returns with that marker still present. A
|
|
274
|
+
pre-attempt `direction-required` report instead returns with
|
|
275
|
+
`pending_attempt: null`, unchanged usage, and evidence of no reservation, edit,
|
|
276
|
+
or recovery commit. An active, mismatched, prematurely cleared, unreconciled,
|
|
277
|
+
or contradictory attempted-recovery marker must fail closed before root
|
|
278
|
+
bookkeeping. Root clears an attempted-recovery marker only after validating the
|
|
279
|
+
report, immutable original history, exact target and axes, canonical event,
|
|
280
|
+
attempt count, recovery commit when successful, and authoritative focused plus
|
|
281
|
+
phase verification. Root records a valid pre-attempt `direction-required`
|
|
282
|
+
event without clearing a marker. Clearing always retains monotonic
|
|
283
|
+
`used_attempts`; failed attempts also preserve their terminal-stop disposition.
|
|
284
|
+
Only the post-bookkeeping null state is settled for an attempted recovery.
|
|
285
|
+
|
|
286
|
+
### Canonical Recovery Event
|
|
287
|
+
|
|
288
|
+
Emit this exact heading, label order, and enum vocabulary for every post-commit
|
|
289
|
+
disposition:
|
|
290
|
+
|
|
291
|
+
```markdown
|
|
292
|
+
### Recovery Event {event-id}
|
|
293
|
+
|
|
294
|
+
- Phase/task: {phase and originating task when known}
|
|
295
|
+
- Original request: {original_request_id}
|
|
296
|
+
- Original commit: {immutable task commit}
|
|
297
|
+
- Defect class: lint | type | test | build | composition | other
|
|
298
|
+
- Discovered by: {exact verification command or transition check}
|
|
299
|
+
- Disposition: recovered | direction-required | failed-attempt
|
|
300
|
+
- Authorization: phase-standing | operator-extension | operator-scope
|
|
301
|
+
- Attempt: {used}/{phase_recovery_limit}
|
|
302
|
+
- Dispatch target: {exact launcher-owned implementation target}
|
|
303
|
+
- Recovery commit: {sha or -}
|
|
304
|
+
- Verification: {focused and relevant phase result}
|
|
305
|
+
- Reason: {eligibility or stop-boundary evidence}
|
|
306
|
+
```
|
|
307
|
+
|
|
104
308
|
## Mode: Implement
|
|
105
309
|
|
|
106
310
|
### 1. Verify Phase Base
|
|
@@ -125,7 +329,12 @@ For every task:
|
|
|
125
329
|
3. Follow RED/GREEN/refactor ordering when specified.
|
|
126
330
|
4. Implement only that task. Optional nested help does not transfer task
|
|
127
331
|
ownership or commit authority.
|
|
128
|
-
5.
|
|
332
|
+
5. Apply the Prevention and Post-Commit Recovery ordering: format, run every
|
|
333
|
+
declared task verification, run applicable discoverable proportionate cheap
|
|
334
|
+
checks, and, for emitted output or build/test configuration changes, run a
|
|
335
|
+
scoped build/test before commit. Broad repository tests and builds may stay at
|
|
336
|
+
the phase boundary when per-task execution is disproportionate. This
|
|
337
|
+
prevention does not consume a recovery attempt.
|
|
129
338
|
6. Self-review requirements, behavioral tests, scope, and accidental changes.
|
|
130
339
|
7. Fix any issue before committing.
|
|
131
340
|
8. Create exactly one task commit using `commit_convention`.
|
|
@@ -139,8 +348,9 @@ For every task:
|
|
|
139
348
|
- every task verification passed; and
|
|
140
349
|
- the worktree is clean.
|
|
141
350
|
10. Perform a brief between-task transition check before starting the next
|
|
142
|
-
task. If the committed task is defective,
|
|
143
|
-
|
|
351
|
+
task. If the committed task is defective, apply the post-commit eligibility,
|
|
352
|
+
accounting, append-only recovery, event, and stop contract above. Never
|
|
353
|
+
amend or conceal the task commit.
|
|
144
354
|
|
|
145
355
|
Do not skip, reorder, combine, or split planned task commits.
|
|
146
356
|
|
|
@@ -149,6 +359,8 @@ Do not skip, reorder, combine, or split planned task commits.
|
|
|
149
359
|
After all task commits:
|
|
150
360
|
|
|
151
361
|
- run phase-wide verification;
|
|
362
|
+
- apply the same post-commit recovery contract to an eligible phase-level
|
|
363
|
+
composition failure;
|
|
152
364
|
- verify task outputs compose correctly;
|
|
153
365
|
- compare the phase result with design/spec/discovery;
|
|
154
366
|
- confirm no task boundary or dependency was missed; and
|
|
@@ -166,10 +378,12 @@ report.
|
|
|
166
378
|
**Phase:** {phase-id}
|
|
167
379
|
**Tasks executed:** {N} of {N}
|
|
168
380
|
**Phase base:** {sha}
|
|
381
|
+
**Final head:** {sha}
|
|
169
382
|
**Commits:** {first sha}..{last sha}
|
|
383
|
+
**Recovery attempts:** {used}/{phase_recovery_limit}
|
|
170
384
|
**Phase verification:** pass | fail
|
|
171
385
|
**Confidence:** high | medium | low
|
|
172
|
-
**Request ID:** {
|
|
386
|
+
**Request ID:** {original_request_id}
|
|
173
387
|
**Dispatch target:** {launcher-owned target}
|
|
174
388
|
**Dispatch stamp:** {formal Dispatch: line}
|
|
175
389
|
|
|
@@ -179,6 +393,10 @@ report.
|
|
|
179
393
|
| ------- | ------ | ------ | ------------ | --------------- |
|
|
180
394
|
| pNN-tNN | done | {sha} | pass | {bounded files} |
|
|
181
395
|
|
|
396
|
+
### Recovery Events
|
|
397
|
+
|
|
398
|
+
- {None, or exactly one canonical event per recovered, direction-required, or failed-attempt disposition}
|
|
399
|
+
|
|
182
400
|
### Optional Nested Dispatches
|
|
183
401
|
|
|
184
402
|
- {None, or request ID / bounded purpose / exact target / terminal outcome}
|
|
@@ -192,6 +410,93 @@ report.
|
|
|
192
410
|
- {None or concise reason/evidence}
|
|
193
411
|
```
|
|
194
412
|
|
|
413
|
+
## Mode: Recover
|
|
414
|
+
|
|
415
|
+
Recover mode is a continuation of a post-commit recovery attempt already
|
|
416
|
+
authorized when the original accepted handle cannot resume. It is not phase
|
|
417
|
+
implementation, review-fix mode, fallback, or replay.
|
|
418
|
+
|
|
419
|
+
Require this self-contained Recover Scope:
|
|
420
|
+
|
|
421
|
+
```yaml
|
|
422
|
+
mode: recover
|
|
423
|
+
original_request_id: { original phase request }
|
|
424
|
+
continuation_event: { generic continuation_events identifier }
|
|
425
|
+
recovery_base_head: { current immutable Git HEAD }
|
|
426
|
+
original_task_id: { originating planned task }
|
|
427
|
+
original_commit: { immutable task commit }
|
|
428
|
+
defect_class: { lint|type|test|build|composition|other }
|
|
429
|
+
discovered_by: { exact command or transition check }
|
|
430
|
+
bounded_correction_scope: { mechanical correction only }
|
|
431
|
+
bounded_files: { declared or mechanically derived in-phase files }
|
|
432
|
+
phase_recovery_limit: { resolved total limit }
|
|
433
|
+
phase_recovery_attempts_used: { authoritative nonzero used count }
|
|
434
|
+
pending_attempt: { matching authoritative ledger entry }
|
|
435
|
+
focused_verification: { exact failing check }
|
|
436
|
+
phase_verification: { relevant phase command }
|
|
437
|
+
dispatch_target: { exact original launcher-owned target }
|
|
438
|
+
dispatch_axes: { unchanged original launcher-owned axes }
|
|
439
|
+
dispatch_stamp: { original formal Dispatch line }
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
1. Validate every recover input. Confirm the exact launcher-owned target equals
|
|
443
|
+
the original target and the generic `continuation_events` record links
|
|
444
|
+
`continuation_event` to `original_request_id`.
|
|
445
|
+
2. Confirm HEAD exactly equals `recovery_base_head`; the `original_commit`
|
|
446
|
+
remains immutable at the same history position; and the worktree contains
|
|
447
|
+
only the reconciled pending ledger reservation plus an optional mechanically
|
|
448
|
+
bounded diff inside `bounded_files`. Any other dirt or history change
|
|
449
|
+
blocks.
|
|
450
|
+
3. Reconcile the authoritative `pending_attempt` and nonzero
|
|
451
|
+
`phase_recovery_attempts_used` with `state.md`. Recover mode continues that
|
|
452
|
+
same consumed attempt and must not increment usage again. Missing,
|
|
453
|
+
contradictory, or unreconciled state blocks before editing.
|
|
454
|
+
4. Apply or complete only `bounded_correction_scope`. Recover mode must not
|
|
455
|
+
replay planned tasks and must not require, fabricate, or consume a review
|
|
456
|
+
artifact.
|
|
457
|
+
5. Apply the bounded correction, then run `focused_verification` and
|
|
458
|
+
`phase_verification` before creating a candidate commit. If either check
|
|
459
|
+
fails, restore `bounded_files` to their original committed content,
|
|
460
|
+
atomically mark the pending entry `failed`, durably commit only that
|
|
461
|
+
ledger transition, emit one `failed-attempt` event, and stop.
|
|
462
|
+
6. When both pre-commit checks pass, atomically mark the pending entry
|
|
463
|
+
`completed` and create one append-only candidate recovery commit containing
|
|
464
|
+
only `bounded_files` plus that ledger transition.
|
|
465
|
+
7. Immediately rerun `focused_verification` and `phase_verification` against the
|
|
466
|
+
committed HEAD; these reruns are authoritative. On pass, emit one `recovered`
|
|
467
|
+
event and report the candidate as the successful recovery commit. On
|
|
468
|
+
failure, atomically replace `completed` with `failed`, durably commit that
|
|
469
|
+
ledger-only transition, emit one `failed-attempt` event, preserve the
|
|
470
|
+
consumed attempt and immutable candidate, and claim no successful recovery
|
|
471
|
+
commit. If terminal evidence cannot be committed, report an unreconciled
|
|
472
|
+
block that root must reject before bookkeeping. Never amend history or
|
|
473
|
+
launch fallback.
|
|
474
|
+
8. Return the report below. `DONE` is accepted success;
|
|
475
|
+
`DONE_WITH_CONCERNS` and `BLOCKED` may be accepted terminal stops and must
|
|
476
|
+
still report provenance, accounting, immutable history, and the event.
|
|
477
|
+
|
|
478
|
+
```markdown
|
|
479
|
+
## Phase Recovery Continuation Report
|
|
480
|
+
|
|
481
|
+
**Status:** DONE | DONE_WITH_CONCERNS | BLOCKED
|
|
482
|
+
**Phase:** {phase-id}
|
|
483
|
+
**Original request ID:** {original_request_id}
|
|
484
|
+
**Continuation event:** {continuation_event}
|
|
485
|
+
**Recovery base:** {recovery_base_head}
|
|
486
|
+
**Original task/commit:** {original_task_id} / {original_commit}
|
|
487
|
+
**Attempt:** {phase_recovery_attempts_used}/{phase_recovery_limit}
|
|
488
|
+
**Dispatch target:** {same exact launcher-owned target}
|
|
489
|
+
**Dispatch stamp:** {original formal Dispatch line}
|
|
490
|
+
**Pending handoff:** {completed|failed}
|
|
491
|
+
**Recovery commit:** {sha or -}
|
|
492
|
+
**Verification:** {focused result}; {phase result}
|
|
493
|
+
**Recovery event:** {event-id}
|
|
494
|
+
|
|
495
|
+
### Concerns or Block
|
|
496
|
+
|
|
497
|
+
- {None or bounded terminal-stop evidence}
|
|
498
|
+
```
|
|
499
|
+
|
|
195
500
|
## Mode: Fix
|
|
196
501
|
|
|
197
502
|
Fix mode is a continuation of a successfully completed phase, not a replay.
|
|
@@ -66,6 +66,31 @@ The canonical autonomy contract and exhaustive gate inventory
|
|
|
66
66
|
`references/docs/autonomy-contract.md`) map each prompt to its autonomous
|
|
67
67
|
resolution and provenance.
|
|
68
68
|
|
|
69
|
+
### Dispatch-ladder scope selection
|
|
70
|
+
|
|
71
|
+
An incomplete reusable dispatch ladder is auto-resolvable when an authorized
|
|
72
|
+
adoption-compatible config scope is available. Autonomous planning checks
|
|
73
|
+
config-file existence in this fixed order without prompting or reordering from
|
|
74
|
+
effective value or matrix-cell provenance:
|
|
75
|
+
|
|
76
|
+
1. user config (`~/.oat/config.json`);
|
|
77
|
+
2. repo-local config (`.oat/config.local.json`);
|
|
78
|
+
3. shared config (`.oat/config.json`), only when repository policy already
|
|
79
|
+
authorizes that write.
|
|
80
|
+
|
|
81
|
+
Before writing, planning rejects a candidate that would preserve a
|
|
82
|
+
provider-level scalar in that scope or remain shadowed by one at higher
|
|
83
|
+
precedence. It always tries the next authorized compatible candidate and stops
|
|
84
|
+
without mutation only when none remains.
|
|
85
|
+
|
|
86
|
+
The planner runs exactly one matching `oat config adopt dispatch-matrix`
|
|
87
|
+
command, records file-existence and compatibility evidence plus the selected
|
|
88
|
+
scope, and re-runs dispatch preflight. Existing explicit cells remain unchanged;
|
|
89
|
+
their provenance does not select the persistence scope. No authorized
|
|
90
|
+
compatible scope, or a ladder that remains incomplete after adoption, is still
|
|
91
|
+
a repository-policy boundary. `OAT_NON_INTERACTIVE=1` without
|
|
92
|
+
`OAT_AUTONOMOUS=1` does not select a scope and continues to fail closed.
|
|
93
|
+
|
|
69
94
|
## Review contract
|
|
70
95
|
|
|
71
96
|
Autonomous execution preserves independent review:
|
|
@@ -16,6 +16,10 @@ and updates project state.
|
|
|
16
16
|
in dependency order.
|
|
17
17
|
- **Task boundary:** each task still produces exactly one bounded, verified
|
|
18
18
|
commit.
|
|
19
|
+
- **Prevention boundary:** formatting, declared task verification, and
|
|
20
|
+
applicable cheap checks run before the task commit.
|
|
21
|
+
- **Recovery boundary:** an eligible post-commit defect may produce a separate
|
|
22
|
+
same-target recovery commit under the phase's bounded recovery authority.
|
|
19
23
|
- **Review boundary:** the root dispatches one independent reviewer after the
|
|
20
24
|
phase report.
|
|
21
25
|
- **Fix boundary:** blocking findings return to the original phase handle when
|
|
@@ -78,7 +82,138 @@ once, and directly executes each task in plan order. For every task it:
|
|
|
78
82
|
6. verifies the commit, file boundary, tests, and clean worktree.
|
|
79
83
|
|
|
80
84
|
After all tasks, it runs phase-wide verification and returns a compact report.
|
|
81
|
-
It does not dispatch the phase reviewer or mutate project bookkeeping.
|
|
85
|
+
It does not dispatch the phase reviewer or mutate general project bookkeeping.
|
|
86
|
+
While it owns the worktree, it may atomically update only the active phase's
|
|
87
|
+
authoritative `oat_phase_recovery_policy.phase_attempt_usage.<pNN>` entry. The
|
|
88
|
+
phase returns with a matching committed `completed` or `failed` terminal marker
|
|
89
|
+
still present. The root validates that marker against the report, recovery
|
|
90
|
+
event, immutable history, attempt accounting, exact target, and verification
|
|
91
|
+
before clearing it. Only the post-validation null marker is the settled ledger
|
|
92
|
+
state; a premature clear or contradictory marker fails closed.
|
|
93
|
+
|
|
94
|
+
## Prevent Defects Before Commit
|
|
95
|
+
|
|
96
|
+
Prevention is the first recovery control. Before each planned task commit, the
|
|
97
|
+
phase implementer runs checks in this order:
|
|
98
|
+
|
|
99
|
+
1. format every changed file;
|
|
100
|
+
2. run the task's declared verification;
|
|
101
|
+
3. run every repository-discovered cheap check that applies to the changed
|
|
102
|
+
surface and is proportionate to the task; and
|
|
103
|
+
4. run a discoverable scoped build or test when the task changes emitted
|
|
104
|
+
output, build or test configuration, packaging, or equivalent behavior.
|
|
105
|
+
|
|
106
|
+
Broad repository tests and builds may remain phase-level when running them for
|
|
107
|
+
every task would be disproportionate. These broader checks verify that the
|
|
108
|
+
phase's task outputs compose correctly. A correction made before the planned
|
|
109
|
+
task commit is prevention and does not consume a recovery attempt.
|
|
110
|
+
|
|
111
|
+
## Recover After Commit
|
|
112
|
+
|
|
113
|
+
When declared task, transition, or phase verification finds a post-commit
|
|
114
|
+
defect, OAT classifies it before editing. Automatic recovery proceeds only when
|
|
115
|
+
the correction is mechanically bounded, unambiguous, in phase, non-destructive,
|
|
116
|
+
and verifiable, and when the exact launcher-owned implementation target and
|
|
117
|
+
original-request provenance remain intact. Architecture, security, product,
|
|
118
|
+
requirements, public-behavior, credential, protected-branch, destructive, or
|
|
119
|
+
non-mechanical scope changes require operator direction.
|
|
120
|
+
|
|
121
|
+
The accepted task commit remains immutable. For an eligible defect, the phase
|
|
122
|
+
implementer reserves an attempt in the authoritative phase ledger, applies the
|
|
123
|
+
bounded correction, and runs focused and phase checks before a candidate commit.
|
|
124
|
+
After those checks pass, the implementer commits the correction with a
|
|
125
|
+
`completed` pre-bookkeeping marker and immediately reruns both checks against
|
|
126
|
+
the committed HEAD. Those post-commit reruns are authoritative. A pass makes
|
|
127
|
+
the candidate the successful recovery commit; a failure durably transitions the
|
|
128
|
+
marker to `failed` in ledger-only terminal evidence and stops without claiming
|
|
129
|
+
a successful recovery. Mechanically related failures from one verification
|
|
130
|
+
command may share one atomic attempt and successful commit; independent defects
|
|
131
|
+
require separate attempts.
|
|
132
|
+
|
|
133
|
+
Append-only history protects accepted work by requiring a new, auditable commit;
|
|
134
|
+
it does not require repeated approval for a mechanical repair already covered
|
|
135
|
+
by the phase's standing authority. The important distinctions are:
|
|
136
|
+
|
|
137
|
+
- a **defect** is a post-commit failure discovered by declared verification;
|
|
138
|
+
- an **authorization prompt** is required only at a direction-required
|
|
139
|
+
boundary, not for every eligible defect;
|
|
140
|
+
- a **continuation** preserves the original request and exact target, either in
|
|
141
|
+
the accepted handle or through an explicitly linked fresh same-target
|
|
142
|
+
recovery launch; and
|
|
143
|
+
- a **successful repair** produces one immutable append-only recovery commit.
|
|
144
|
+
|
|
145
|
+
This recovery is not accepted-launch fallback. After a launch is accepted,
|
|
146
|
+
completion, failure, timeout, interruption, `BLOCKED`, or contract refusal never
|
|
147
|
+
makes another model, provider, route, or worker eligible. A fresh launch is
|
|
148
|
+
permitted only when the caller-specific lifecycle contract already authorized
|
|
149
|
+
bounded recovery, the accepted handle cannot resume, the exact original target
|
|
150
|
+
remains bindable, a pending attempt is reconciled, and the existing
|
|
151
|
+
`continuation_events` record links it to the original request.
|
|
152
|
+
|
|
153
|
+
### Recovery Budget
|
|
154
|
+
|
|
155
|
+
`oat_phase_recovery_policy` is dedicated to implementation recovery and is
|
|
156
|
+
independent of `oat_orchestration_retry_limit`, which continues to govern
|
|
157
|
+
review-fix and gate loops. The project default is `10` attempts per phase.
|
|
158
|
+
Project defaults and phase-specific overrides accept integers from `0` through
|
|
159
|
+
`20`; `0` disables automatic post-commit repair for that scope.
|
|
160
|
+
|
|
161
|
+
Attempt usage is monotonic and durable per phase. A new attempt is consumed
|
|
162
|
+
before the bounded edit begins, so a failed edit, commit, or re-verification
|
|
163
|
+
cannot retry for free. An already-reconciled pending attempt may finish without
|
|
164
|
+
another reservation, even when usage equals the limit. Evidence of an
|
|
165
|
+
infrastructure or flaky failure permits one no-edit rerun without consuming an
|
|
166
|
+
attempt; a repeated unexplained failure is ambiguous and stops without editing.
|
|
167
|
+
A direction-required boundary reached before reservation leaves the pending
|
|
168
|
+
marker null and usage unchanged, emits its required event, and records no edit
|
|
169
|
+
or recovery commit.
|
|
170
|
+
|
|
171
|
+
At three recovery events, the phase report warns about elevated recovery volume
|
|
172
|
+
but may continue while every eligibility condition and the budget remain valid.
|
|
173
|
+
At exhaustion, OAT stops for one explicit operator outcome:
|
|
174
|
+
|
|
175
|
+
1. **Add N attempts:** set that phase's total limit to `used_attempts + N`,
|
|
176
|
+
capped at `20`, without resetting prior usage.
|
|
177
|
+
2. **Authorize changed scope:** record a separate consequential or
|
|
178
|
+
scope-expanding action outside automatic recovery.
|
|
179
|
+
3. **Stop:** preserve the worktree, immutable history, and evidence.
|
|
180
|
+
|
|
181
|
+
### Recovery Event
|
|
182
|
+
|
|
183
|
+
Every recovered, direction-required, or failed-attempt disposition emits
|
|
184
|
+
exactly one event with this heading, label order, and vocabulary:
|
|
185
|
+
|
|
186
|
+
```markdown
|
|
187
|
+
### Recovery Event {event-id}
|
|
188
|
+
|
|
189
|
+
- Phase/task: {phase and originating task when known}
|
|
190
|
+
- Original request: {original_request_id}
|
|
191
|
+
- Original commit: {immutable task commit}
|
|
192
|
+
- Defect class: lint | type | test | build | composition | other
|
|
193
|
+
- Discovered by: {exact verification command or transition check}
|
|
194
|
+
- Disposition: recovered | direction-required | failed-attempt
|
|
195
|
+
- Authorization: phase-standing | operator-extension | operator-scope
|
|
196
|
+
- Attempt: {used}/{phase_recovery_limit}
|
|
197
|
+
- Dispatch target: {exact launcher-owned implementation target}
|
|
198
|
+
- Recovery commit: {sha or -}
|
|
199
|
+
- Verification: {focused and relevant phase result}
|
|
200
|
+
- Reason: {eligibility or stop-boundary evidence}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
The event ledger keeps defect volume, authorization-prompt volume, continuation
|
|
204
|
+
volume, and successful repair commits measurable as separate facts. A failed
|
|
205
|
+
attempt still produces one event even when it produces no recovery commit.
|
|
206
|
+
|
|
207
|
+
### Pre-Change Baseline
|
|
208
|
+
|
|
209
|
+
The recorded pre-change baseline is nine recovery events plus two
|
|
210
|
+
operator-recovery continuations. Known failures included lint, composition, and
|
|
211
|
+
test-fixture defects; exact per-class counts are unavailable. The repeated
|
|
212
|
+
prompts exposed a latent policy under integration-heavy verification rather
|
|
213
|
+
than a recent regression. In particular, PR #176 changed phase-base anchoring
|
|
214
|
+
and is explicitly excluded from causation: the root still captures a fresh
|
|
215
|
+
phase base immediately before each launch, so earlier recovery commits are
|
|
216
|
+
already part of the next phase's base.
|
|
82
217
|
|
|
83
218
|
### Phase reviewer
|
|
84
219
|
|
|
@@ -155,6 +290,21 @@ Only an allowed and fresh gate disposition can enter the pre-approval sequence,
|
|
|
155
290
|
cross final HiLL, run the post-approval sequence, mark implementation complete,
|
|
156
291
|
or emit success.
|
|
157
292
|
|
|
293
|
+
## Update Installed Recovery Contracts
|
|
294
|
+
|
|
295
|
+
Bounded phase recovery ships in OAT `0.2.28`. After upgrading to that release or
|
|
296
|
+
later, update the installed OAT tools and then regenerate provider views from
|
|
297
|
+
the canonical contracts:
|
|
298
|
+
|
|
299
|
+
```bash
|
|
300
|
+
oat tools update
|
|
301
|
+
oat sync --scope all
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
Run the commands in that order before expecting global Claude, Codex, or Cursor
|
|
305
|
+
phase agents to use the new contract. Provider assets are generated views, not
|
|
306
|
+
independently maintained policy forks.
|
|
307
|
+
|
|
158
308
|
## Phase Scope
|
|
159
309
|
|
|
160
310
|
The root supplies one scope for the whole phase:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: oat-dispatch-subagents
|
|
3
|
-
version: 1.2.
|
|
3
|
+
version: 1.2.2
|
|
4
4
|
description: Use when an OAT skill or workflow needs provider-neutral selection, launch, recovery, or evidence for bounded subagent work without project lifecycle policy.
|
|
5
5
|
disable-model-invocation: true
|
|
6
6
|
user-invocable: false
|
|
@@ -385,18 +385,31 @@ a declared class floor.
|
|
|
385
385
|
- An accepted launch is terminal for automatic replacement eligibility.
|
|
386
386
|
- Completion, failure, timeout, interruption, `BLOCKED`, and contract refusal
|
|
387
387
|
are post-acceptance outcomes; none makes another route eligible.
|
|
388
|
+
- Automatic route, model, provider, or worker replacement after acceptance is
|
|
389
|
+
forbidden fallback. No post-acceptance outcome makes another route eligible.
|
|
388
390
|
- A wrapper failure or payload rejection before child start is a pre-start
|
|
389
391
|
rejection. A new recorded selection is allowed only within caller retry
|
|
390
392
|
policy.
|
|
391
393
|
- Continuing the same accepted child through its valid handle is allowed.
|
|
392
394
|
Record continuation separately and preserve selectors and route.
|
|
395
|
+
- Same-target bounded recovery is a continuation rather than fallback only when
|
|
396
|
+
a caller-specific lifecycle contract explicitly authorizes it. That contract
|
|
397
|
+
must supply the bounded scope, exact target, numeric budget, canonical
|
|
398
|
+
recording, and stop conditions before launch. It may allow either
|
|
399
|
+
continuation through the accepted handle or an explicitly linked fresh
|
|
400
|
+
same-target launch when the original handle cannot be resumed.
|
|
401
|
+
- Standing recovery authority is default-deny. `oat-project-implement` may
|
|
402
|
+
establish it through its complete caller-specific lifecycle contract; wave
|
|
403
|
+
execution, autonomous projects, cloud-project orchestration, reviewers, and
|
|
404
|
+
every other consumer remain outside that grant unless their own future
|
|
405
|
+
contract independently defines the complete boundary.
|
|
406
|
+
- Scope-expanding or consequential recovery requires new operator direction.
|
|
407
|
+
The same applies to ambiguous, destructive, or retry-exhausted work.
|
|
393
408
|
- A caller may cancel accepted handles only after it proves that the enclosing
|
|
394
409
|
run itself is invalid under caller-owned containment or integrity policy.
|
|
395
410
|
Record `invalid-run-abort` and the invalidating evidence. Cancellation never
|
|
396
411
|
makes another route eligible and never authorizes replacement, fallback, or
|
|
397
412
|
a successful child outcome.
|
|
398
|
-
- Operator-authorized recovery is a new explicit action, never automatic
|
|
399
|
-
fallback.
|
|
400
413
|
- Runtime identity is optional corroboration. Missing runtime identity does not
|
|
401
414
|
invalidate launcher-owned configured invocation evidence.
|
|
402
415
|
|