@open-agent-toolkit/cli 0.1.42 → 0.1.43

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.
Files changed (31) hide show
  1. package/assets/agents/oat-phase-implementer.md +11 -7
  2. package/assets/agents/oat-reviewer.md +6 -4
  3. package/assets/docs/cli-utilities/configuration.md +51 -35
  4. package/assets/docs/reference/oat-directory-structure.md +26 -24
  5. package/assets/docs/workflows/projects/dispatch-ceiling.md +128 -85
  6. package/assets/docs/workflows/projects/implementation-execution.md +68 -45
  7. package/assets/docs/workflows/projects/index.md +2 -2
  8. package/assets/docs/workflows/projects/lifecycle.md +17 -2
  9. package/assets/public-package-versions.json +4 -4
  10. package/assets/skills/oat-project-implement/SKILL.md +181 -91
  11. package/assets/skills/oat-project-plan/SKILL.md +60 -29
  12. package/assets/skills/oat-project-plan-writing/SKILL.md +10 -10
  13. package/assets/skills/oat-project-quick-start/SKILL.md +60 -29
  14. package/assets/templates/plan.md +4 -4
  15. package/assets/templates/state.md +7 -3
  16. package/dist/commands/config/index.d.ts.map +1 -1
  17. package/dist/commands/config/index.js +66 -3
  18. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  19. package/dist/commands/project/dispatch-ceiling/index.js +296 -49
  20. package/dist/config/dispatch-ceiling-preset.d.ts +37 -1
  21. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  22. package/dist/config/dispatch-ceiling-preset.js +20 -0
  23. package/dist/config/oat-config.d.ts +10 -1
  24. package/dist/config/oat-config.d.ts.map +1 -1
  25. package/dist/config/oat-config.js +20 -1
  26. package/dist/config/resolve.d.ts.map +1 -1
  27. package/dist/config/resolve.js +4 -0
  28. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  29. package/dist/providers/ceiling/registry.js +6 -1
  30. package/dist/providers/codex/codec/sync-extension.js +1 -1
  31. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-implement
3
- version: 2.0.25
3
+ version: 2.0.27
4
4
  description: Use when plan.md is ready for execution. Dispatches phase-level subagents with bounded fix loops; supports plan-declared parallel phase groups with worktree-isolated execution and ordered fan-in.
5
5
  oat_gateable: true
6
6
  argument-hint: '[--retry-limit <N>] [--dry-run]'
@@ -163,12 +163,14 @@ Forbidden: Selected: Tier 2 — Inline because the user did not separately menti
163
163
 
164
164
  **Legacy state migration:** If `state.md` contains `oat_execution_mode: subagent-driven`, silently ignore it. On the next bookkeeping write, remove that key. Do not redirect to `oat-project-subagent-implement` — that skill is deprecated.
165
165
 
166
- ### Dispatch Ceiling Preflight
166
+ ### Dispatch Policy Preflight
167
167
 
168
- Before any phase work, resolve and print the OAT dispatch ceiling. This is a
168
+ Before any phase work, resolve and print the OAT dispatch policy. This is a
169
169
  preflight gate, not a mid-run question.
170
170
 
171
- Use the CLI resolver as the source of truth:
171
+ Use the CLI resolver as the source of truth. The command name remains
172
+ `dispatch-ceiling` for compatibility, but the returned contract is dispatch
173
+ policy:
172
174
 
173
175
  ```bash
174
176
  oat project dispatch-ceiling resolve --provider <active-provider> --preflight --json
@@ -182,10 +184,12 @@ pnpm run cli -- project dispatch-ceiling resolve --provider <active-provider> --
182
184
 
183
185
  Resolution order:
184
186
 
185
- 1. Config keys `workflow.dispatchCeiling.providers.<provider>` (local > shared > user)
186
- 2. Project `state.md` frontmatter key `oat_dispatch_ceiling`
187
- 3. Interactive implementation preflight prompt (below)
188
- 4. Non-interactive unresolved: block before work starts
187
+ 1. Config keys `workflow.dispatchPolicy.mode` / `workflow.dispatchPolicy.policy` (local > shared > user)
188
+ 2. Compatibility config keys `workflow.dispatchCeiling.providers.<provider>` (local > shared > user)
189
+ 3. Project `state.md` frontmatter key `oat_dispatch_policy`
190
+ 4. Legacy project `state.md` frontmatter key `oat_dispatch_ceiling`
191
+ 5. Interactive implementation preflight prompt (below)
192
+ 6. Non-interactive unresolved: block before work starts
189
193
 
190
194
  **JSON response shape** (from `--json`):
191
195
 
@@ -194,6 +198,8 @@ Resolution order:
194
198
  "status": "resolved",
195
199
  "provider": "codex",
196
200
  "value": "high",
201
+ "policyMode": "managed",
202
+ "policy": "balanced",
197
203
  "source": "project-state",
198
204
  "preset": "balanced",
199
205
  "unresolved": false,
@@ -209,7 +215,10 @@ Resolution order:
209
215
  "role": "implementer",
210
216
  "preferredValue": null,
211
217
  "selectedValue": "high",
212
- "capped": false
218
+ "capped": false,
219
+ "selectionMode": "capped",
220
+ "policyMode": "managed",
221
+ "policy": "balanced"
213
222
  }
214
223
  }
215
224
  }
@@ -220,58 +229,88 @@ Read `providers.<active-provider>` for the concrete dispatch controls. The
220
229
  `dispatchArgs` field carries the provider-specific argument to pass through
221
230
  (Codex: `variant` name; Claude: `model` string). For implementer/fix dispatch,
222
231
  pass `--preferred <preferred-effort>` and use `selection.selectedValue` as the
223
- selected axis value. Never re-derive these from the preset label or a ceiling-only
224
- variant the resolver is the single compilation/join point.
232
+ selected axis value when it is present. Never re-derive these from the policy
233
+ label or a ceiling-only variant - the resolver is the single compilation/join
234
+ point.
225
235
 
226
236
  Print before phase work:
227
237
 
228
238
  ```text
229
- Dispatch ceiling: high (codex, enforced — pinned-variant)
230
- Source: project state | Preset: balanced
239
+ Dispatch policy: balanced (codex, managed capped — pinned-variant)
240
+ Resolved cap: high
241
+ Source: project state
231
242
  Provider default effort: medium
232
- Note: OAT will use pinned subagent variants up to high. Base/unpinned roles resolve through the provider default.
243
+ Note: OAT will use pinned subagent variants up to high. Base/unpinned roles resolve through the provider default only on fallback paths.
233
244
  ```
234
245
 
235
- If no ceiling resolves and the session is interactive, present the preset
236
- prompt once before starting work:
246
+ If no policy resolves and the session is interactive, present the dispatch
247
+ policy prompt once before starting work:
237
248
 
238
249
  ```text
239
- No dispatch ceiling is configured for this project.
250
+ No dispatch policy is configured for this project.
240
251
 
241
- Set the dispatch ceilingthe maximum subagent tier OAT may use.
252
+ Set the dispatch policyhow OAT should choose subagent model/effort controls.
242
253
 
243
- 1. Balanced (recommended) — Codex: high · Claude: sonnet
244
- 2. Maximum — Codex: xhigh · Claude: opus (reviews always run at this tier)
245
- 3. Cost-conscious — Codex: medium · Claude: sonnet
246
- 4. Advanced set per provider
247
- 5. No ceiling
254
+ Managed capped policies:
255
+ 1. Economy — Codex: medium · Claude: sonnet
256
+ 2. Balanced — Codex: high · Claude: sonnet (recommended)
257
+ 3. High Codex: xhigh · Claude: opus
258
+ 4. Frontier — Codex: xhigh · Claude: fable
248
259
 
249
- OAT applies this where the provider exposes a reliable mechanism (Codex: pinned
250
- variants; Claude: Task model parameter). Other providers may treat it as advisory.
260
+ Managed uncapped:
261
+ 5. Uncapped OAT selects the preferred implementer/fix target without a stored maximum cap.
262
+
263
+ Host defaults:
264
+ 6. Inherit Host Defaults — OAT does not select model/effort controls.
265
+
266
+ OAT applies managed policies where the provider exposes a reliable mechanism
267
+ (Codex: pinned variants; Claude: Task model parameter). Other providers may
268
+ treat managed policies as advisory.
251
269
  ```
252
270
 
253
- **Preset selection** persists `preset` + compiled per-provider values. On
254
- selection, print the exact compiled result (e.g., "Ceiling set: balanced
255
- Codex: high · Claude: sonnet") before proceeding.
271
+ **Managed capped policy selection (options 1-4)** persists `mode: managed`,
272
+ `policy`, and the compiled provider targets. On selection, print the exact
273
+ compiled result (e.g., "Dispatch policy set: balanced -> Codex: high · Claude:
274
+ sonnet") before proceeding.
256
275
 
257
- **Advanced (option 4)** prompts for each provider's value individually, then
258
- persists `providers` + `source` only no `preset` key.
276
+ **Uncapped (option 5)** persists explicit managed uncapped state. It does not
277
+ write provider caps, and it must not be represented by leaving dispatch policy
278
+ state absent.
259
279
 
260
- **No ceiling (option 5)** leaves `oat_dispatch_ceiling` unset; implementer
261
- subagents run at provider defaults.
280
+ **Inherit Host Defaults (option 6)** persists explicit inherit/default state.
281
+ Use this only when the user wants OAT to leave implementation, fix, and review
282
+ model/effort controls to the executing host/provider.
262
283
 
263
284
  Persist in project `state.md` frontmatter using the normalized shape:
264
285
 
265
286
  ```yaml
266
- oat_dispatch_ceiling:
267
- preset: balanced # omit when Advanced was chosen
287
+ oat_dispatch_policy:
288
+ mode: managed
289
+ policy: balanced
268
290
  providers:
269
291
  codex: high
270
292
  claude: sonnet
271
293
  source: project-state
272
294
  ```
273
295
 
274
- If no ceiling resolves and `OAT_NON_INTERACTIVE=1` or no user-response channel
296
+ For `Uncapped`:
297
+
298
+ ```yaml
299
+ oat_dispatch_policy:
300
+ mode: managed
301
+ policy: uncapped
302
+ source: project-state
303
+ ```
304
+
305
+ For `Inherit Host Defaults`:
306
+
307
+ ```yaml
308
+ oat_dispatch_policy:
309
+ mode: inherit
310
+ source: project-state
311
+ ```
312
+
313
+ If no policy resolves and `OAT_NON_INTERACTIVE=1` or no user-response channel
275
314
  exists, rerun the resolver with non-interactive behavior and stop before work
276
315
  starts if it blocks:
277
316
 
@@ -280,11 +319,11 @@ oat project dispatch-ceiling resolve --provider <active-provider> --preflight --
280
319
  ```
281
320
 
282
321
  ```text
283
- BLOCKED: Codex dispatch ceiling is unresolved in non-interactive mode.
284
- Set workflow.dispatchCeiling.providers.codex in .oat/config.json or oat_dispatch_ceiling in project state.
322
+ BLOCKED: Codex dispatch policy is unresolved in non-interactive mode.
323
+ Set workflow.dispatchPolicy.mode/workflow.dispatchPolicy.policy, workflow.dispatchCeiling.providers.codex, oat_dispatch_policy, or legacy oat_dispatch_ceiling.
285
324
  ```
286
325
 
287
- Dry-run mode must report the unresolved ceiling and planned behavior without
326
+ Dry-run mode must report the unresolved policy and planned behavior without
288
327
  modifying project state.
289
328
 
290
329
  ### Runtime dispatch selection
@@ -296,7 +335,7 @@ dispatch selection decides model/effort controls for the specific work.
296
335
 
297
336
  Use these inputs:
298
337
 
299
- - resolved dispatch ceiling and source
338
+ - resolved dispatch policy, source, and provider-specific selection
300
339
  - phase ID and phase scope
301
340
  - optional `## Dispatch Profile` row in `plan.md`
302
341
  - host-exposed provider controls, by axis
@@ -317,18 +356,28 @@ Codex rules:
317
356
  - `low`: trivial docs-only, narrow single-file, or mechanical changes
318
357
  - `medium`: normal multi-file implementation and moderate integration risk
319
358
  - `high`: broad architecture, security/auth/redaction boundaries, subtle state behavior, or repeated substantive review failures
320
- - `xhigh`: highest-risk work that requires the configured ceiling to allow xhigh
321
- 3. Selected effort is `min(preferred, resolved_ceiling)` for implementer/fix work.
322
- 4. For implementer/fix dispatch: call `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <preferred-effort>`; read `providers.codex.selection.selectedValue` and `providers.codex.dispatchArgs.variant` for the selected role name (e.g., `oat-phase-implementer-medium`). The resolver caps the preferred effort against the ceiling; never pass a ceiling-only implementer variant when `selection.selectedValue` is lower.
323
- 5. For review dispatch: call `oat project dispatch-ceiling resolve --provider codex --role reviewer`; read `providers.codex.dispatchArgs.variant` for the reviewer role name (e.g., `oat-reviewer-high`). Reviewer always targets the ceiling for deterministic quality gate behavior.
324
- 6. Use base/unpinned Codex roles only as a fallback or explicit provider-default choice. Log `Selected effort: provider-default`, display provider default effort when known, and do not describe this as parent-ceiling inheritance.
325
- 7. Do not use top-level per-call `reasoning_effort` as the standard OAT selected-effort path; dogfooding showed that path can be inconsistent.
359
+ - `xhigh`: highest-risk work that requires a capped policy to allow xhigh or a managed `Uncapped` policy to select it
360
+ 3. For capped managed implementer/fix work, selected effort is `min(preferred, resolved_cap)`.
361
+ 4. For managed `Uncapped` implementer/fix work, selected effort is the preferred effort with no cap.
362
+ 5. For inherit/default mode, the resolver returns no selected dispatch args. Use the base/unpinned Codex role, log `Selected effort: provider-default`, display provider default effort when known, and do not describe this as managed uncapped behavior.
363
+ 6. For implementer/fix dispatch: call `oat project dispatch-ceiling resolve --provider codex --role implementer --preferred <preferred-effort>`; read `providers.codex.selection.selectedValue` and `providers.codex.dispatchArgs.variant` for the selected role name (e.g., `oat-phase-implementer-medium`). Never pass a cap-only implementer variant when `selection.selectedValue` is lower.
364
+ 7. For review dispatch: call `oat project dispatch-ceiling resolve --provider codex --role reviewer`; read `providers.codex.dispatchArgs.variant`.
365
+ - Capped managed policy: reviewer targets the configured cap for deterministic quality gate behavior.
366
+ - Managed `Uncapped`: no reviewer target exists; use base/unpinned reviewer fallback and log `selectionMode=no-review-target`, `selectedValue=null`, and `effort_axis=provider-default`.
367
+ - Inherit/default: no reviewer target exists; use base/unpinned reviewer fallback and log `selectionMode=inherit-default`, `selectedValue=null`, and `effort_axis=provider-default`.
368
+ 8. Codex payload-first assertion applies only when the resolver returns a pinned variant. If `effort_axis=selected:<value>`, the actual `spawn_agent` payload MUST use the matching pinned `agent_type`. If the resolver returns no variant, use the base role and log provider-default.
369
+ 9. Do not use top-level per-call `reasoning_effort` as the standard OAT selected-effort path; dogfooding showed that path can be inconsistent.
326
370
 
327
371
  Claude rules:
328
372
 
329
- - Claude ceiling is model-based: `haiku < sonnet < opus`.
330
- - Implementer/fix dispatch: classify the preferred model (`haiku`, `sonnet`, or `opus`) and pass it to the resolver as `--preferred <preferred-model>`. The resolver selects the lowest sufficient model capped by the resolved Claude ceiling (`min(preferred, ceiling)`).
331
- - Review dispatch: target the resolved Claude ceiling directly.
373
+ - Claude policy selection is model-based: `haiku < sonnet < opus < fable`.
374
+ - Implementer/fix dispatch: classify the preferred model (`haiku`, `sonnet`, `opus`, or `fable`) and pass it to the resolver as `--preferred <preferred-model>`.
375
+ - Capped managed policy: the resolver selects `min(preferred, resolved_cap)`.
376
+ - Managed `Uncapped`: the resolver selects the preferred model with no cap.
377
+ - Inherit/default: the resolver returns no selected model; omit `model` so Claude Code inherits host/default behavior.
378
+ - Review dispatch:
379
+ - Capped managed policy: target the configured policy cap directly.
380
+ - Managed `Uncapped` or inherit/default: no reviewer target exists; omit `model` and log inherited/default model behavior.
332
381
  - For implementer/fix dispatch, call `oat project dispatch-ceiling resolve --provider claude --role implementer --preferred <preferred-model> --orchestrator-tier <current-orchestrator-tier>`; for review dispatch, call the same resolver with `--role reviewer` and no `--preferred`. Read `providers.claude.selection.selectedValue` and `providers.claude.dispatchArgs.model` for the selected model string to pass. Pass `--orchestrator-tier` so the resolver can flag above-orchestrator upgrade requests and set `verifyOnDispatch` correctly.
333
382
  - Pass `model: "<value>"` when `model_axis=selected:<value>` on the Task tool call.
334
383
  - Keep `effort_axis=not-applicable`; Claude Code has no separate per-dispatch effort axis.
@@ -345,14 +394,16 @@ Structured dispatch log:
345
394
  OAT Dispatch: Phase {phase_id} {implementation | fix | review}
346
395
  Host: {Claude Code | Codex | Cursor | other host}
347
396
  Preferred effort: {low | medium | high | xhigh | provider-default | not-applicable}
348
- Dispatch ceiling: {resolved ceiling value}
397
+ Dispatch policy: {economy | balanced | high | frontier | uncapped | inherit host defaults | legacy capped}
398
+ Resolved cap: {resolved cap value | none}
349
399
  Selected effort: {low | medium | high | xhigh | provider-default | not-applicable}
350
- Ceiling source: {repo config | project state | preflight prompt}
400
+ Policy source: {repo config | project state | preflight prompt}
351
401
  Provider default effort: {value | unknown | not-applicable}
402
+ Selection mode: {capped | uncapped | review-target | no-review-target | inherit-default}
352
403
  Model axis: { selected:<value> | inherited | not-applicable | host-auto }
353
404
  Effort axis: { selected:<value> | provider-default | inherited | not-applicable | host-auto }
354
405
  Dispatch target: {host-specific subagent/role/tool target}
355
- Rationale: {short rationale grounded in phase scope and any ceiling cap}
406
+ Rationale: {short rationale grounded in phase scope and any policy cap/uncapped/default behavior}
356
407
  ```
357
408
 
358
409
  Codex capped example:
@@ -361,46 +412,70 @@ Codex capped example:
361
412
  OAT Dispatch: Phase p02 implementation
362
413
  Host: Codex
363
414
  Preferred effort: high
364
- Dispatch ceiling: medium
415
+ Dispatch policy: economy
416
+ Resolved cap: medium
365
417
  Selected effort: medium
366
- Ceiling source: repo config
418
+ Policy source: repo config
367
419
  Provider default effort: high
420
+ Selection mode: capped
368
421
  Model axis: inherited
369
422
  Effort axis: selected:medium
370
423
  Dispatch target: oat-phase-implementer-medium
371
- Rationale: normal multi-file implementation; high preferred due to integration risk, capped by configured ceiling.
424
+ Rationale: normal multi-file implementation; high preferred due to integration risk, capped by configured policy.
372
425
  ```
373
426
 
374
- Codex reviewer example:
427
+ Codex uncapped implementer example:
428
+
429
+ ```text
430
+ OAT Dispatch: Phase p02 implementation
431
+ Host: Codex
432
+ Preferred effort: xhigh
433
+ Dispatch policy: uncapped
434
+ Resolved cap: none
435
+ Selected effort: xhigh
436
+ Policy source: project state
437
+ Provider default effort: medium
438
+ Selection mode: uncapped
439
+ Model axis: inherited
440
+ Effort axis: selected:xhigh
441
+ Dispatch target: oat-phase-implementer-xhigh
442
+ Rationale: high-risk phase; managed uncapped policy allows the preferred pinned variant. Actual host support for upward effort selection must be verified by the dispatching host.
443
+ ```
444
+
445
+ Codex capped reviewer example:
375
446
 
376
447
  ```text
377
448
  OAT Dispatch: Phase p02 review
378
449
  Host: Codex
379
450
  Preferred effort: high
380
- Dispatch ceiling: high
381
- Selected effort: high
382
- Ceiling source: project state
451
+ Dispatch policy: high
452
+ Resolved cap: xhigh
453
+ Selected effort: xhigh
454
+ Policy source: project state
383
455
  Provider default effort: medium
456
+ Selection mode: review-target
384
457
  Model axis: inherited
385
- Effort axis: selected:high
386
- Dispatch target: oat-reviewer-high
387
- Rationale: reviewer runs at the configured ceiling for deterministic quality gate behavior.
458
+ Effort axis: selected:xhigh
459
+ Dispatch target: oat-reviewer-xhigh
460
+ Rationale: reviewer runs at the configured policy cap for deterministic quality gate behavior.
388
461
  ```
389
462
 
390
- Codex base/unpinned fallback example:
463
+ Codex inherit/default fallback example:
391
464
 
392
465
  ```text
393
466
  OAT Dispatch: Phase p02 review
394
467
  Host: Codex
395
468
  Preferred effort: provider-default
396
- Dispatch ceiling: high
469
+ Dispatch policy: inherit host defaults
470
+ Resolved cap: none
397
471
  Selected effort: provider-default
398
- Ceiling source: project state
472
+ Policy source: project state
399
473
  Provider default effort: medium
474
+ Selection mode: inherit-default
400
475
  Model axis: inherited
401
476
  Effort axis: provider-default
402
477
  Dispatch target: oat-reviewer
403
- Rationale: base unpinned role fallback; effective effort follows Codex provider default.
478
+ Rationale: explicit inherit/default policy; base unpinned role follows Codex provider default.
404
479
  ```
405
480
 
406
481
  Generic sidecar/explorer dispatch:
@@ -416,9 +491,10 @@ Codex generic explorer example:
416
491
  OAT Dispatch: p02-t10 sidecar exploration
417
492
  Host: Codex
418
493
  Preferred effort: provider-default
419
- Dispatch ceiling: xhigh
494
+ Dispatch policy: high
495
+ Resolved cap: xhigh
420
496
  Selected effort: provider-default
421
- Ceiling source: project state
497
+ Policy source: project state
422
498
  Provider default effort: xhigh
423
499
  Model axis: inherited
424
500
  Effort axis: provider-default
@@ -435,12 +511,17 @@ effort_axis:
435
511
  selected:<value> | provider-default | inherited | not-applicable | host-auto,
436
512
  }
437
513
  dispatch_ceiling: { resolved ceiling value }
514
+ dispatch_policy:
515
+ {
516
+ economy | balanced | high | frontier | uncapped | inherit host defaults | legacy capped,
517
+ }
438
518
  ceiling_source: { repo config | project state | preflight prompt }
519
+ policy_source: { repo config | project state | preflight prompt }
439
520
  provider_default_effort: { value | unknown | not-applicable }
440
521
  dispatch_rationale: { short rationale }
441
522
  ```
442
523
 
443
- ### Dispatch Ceiling Enforcement Log
524
+ ### Dispatch Policy Enforcement Log
444
525
 
445
526
  After each phase dispatch (implementation, fix, or review), append one enforcement
446
527
  log line. The log reflects the `mode` and `mechanism` returned by
@@ -449,18 +530,20 @@ log line. The log reflects the `mode` and `mechanism` returned by
449
530
  **Three-state log format:**
450
531
 
451
532
  ```text
452
- Dispatch ceiling: {value} ({provider}, {mode} — {mechanism detail})
533
+ Dispatch policy: {policy}; selected={selected value | none}; cap={value | none} ({provider}, {mode} — {mechanism detail})
453
534
  ```
454
535
 
455
536
  **Log examples (matching resolver output):**
456
537
 
457
538
  ```text
458
- Dispatch ceiling: high (codex, enforced — variant oat-phase-implementer-high)
459
- Dispatch ceiling: high (codex, enforced — variant oat-reviewer-high)
460
- Dispatch ceiling: sonnet (claude, enforced — Task model arg)
461
- Dispatch ceiling: opus (claude, enforcedTask model arg)
462
- Dispatch ceiling: high (cursor, unsupportedno adapter; informational)
463
- Dispatch ceiling: unresolved (codex, advisoryceiling set but no value resolved)
539
+ Dispatch policy: balanced; selected=high; cap=high (codex, enforced — variant oat-phase-implementer-high)
540
+ Dispatch policy: high; selected=xhigh; cap=xhigh (codex, enforced — variant oat-reviewer-xhigh)
541
+ Dispatch policy: uncapped; selected=xhigh; cap=none (codex, enforced — variant oat-phase-implementer-xhigh)
542
+ Dispatch policy: inherit host defaults; selected=none; cap=none (codex, advisorybase role follows provider default)
543
+ Dispatch policy: balanced; selected=sonnet; cap=sonnet (claude, enforcedTask model arg)
544
+ Dispatch policy: frontier; selected=fable; cap=fable (claude, enforcedTask model arg)
545
+ Dispatch policy: high; selected=none; cap=high (cursor, unsupported — no adapter; informational)
546
+ Dispatch policy: unresolved; selected=none; cap=none (codex, advisory — policy set but no value resolved)
464
547
  ```
465
548
 
466
549
  **Verify-on-upgrade (`verifyOnDispatch: true`):**
@@ -471,16 +554,18 @@ logging `enforced`, confirm the actual model/tier used by the dispatched agent.
471
554
  If the provider honored the request, log `enforced`. If it did not:
472
555
 
473
556
  ```text
474
- Dispatch ceiling: opus (claude, advisory — provider did not honor upgrade; ran sonnet)
557
+ Dispatch policy: high; selected=opus; cap=opus (claude, advisory — provider did not honor upgrade; ran sonnet)
475
558
  ```
476
559
 
477
560
  **`enforced`** — the adapter compiled concrete dispatch args and the provider
478
561
  accepted them. Log value + provider + mechanism detail (variant name or "Task
479
562
  model arg").
480
563
 
481
- **`advisory`** — the adapter supports the ceiling but no concrete value resolved,
482
- or the provider is known but could not be verified. Log with note "ceiling set
483
- but no value resolved" or "provider did not honor upgrade; ran \<tier\>".
564
+ **`advisory`** — the adapter supports the policy but no concrete value resolved,
565
+ the policy intentionally inherits provider defaults, or the provider is known
566
+ but could not be verified. Log with note "policy set but no value resolved",
567
+ "base role follows provider default", or "provider did not honor upgrade; ran
568
+ \<tier\>".
484
569
 
485
570
  **`unsupported`** — the provider has no registered adapter. Log with note "no
486
571
  adapter; informational". Never block on unsupported — dispatch follows provider
@@ -796,8 +881,10 @@ For each phase `pNN` in the plan (or each phase in the current parallel group),
796
881
  workflow_mode: {from state.md or plan.md frontmatter}
797
882
  model_axis: {selected:<value> | inherited | not-applicable | host-auto; omit if unknown}
798
883
  effort_axis: {selected:<value> | provider-default | inherited | not-applicable | host-auto; omit if unknown}
799
- dispatch_ceiling: {resolved ceiling value; omit if unknown}
800
- ceiling_source: {repo config | project state | preflight prompt; omit if unknown}
884
+ dispatch_policy: {economy | balanced | high | frontier | uncapped | inherit host defaults | legacy capped; omit if unknown}
885
+ dispatch_ceiling: {resolved cap value; omit if none or unknown}
886
+ policy_source: {repo config | project state | preflight prompt; omit if unknown}
887
+ ceiling_source: {repo config | project state | preflight prompt; omit if unknown; compatibility alias for policy_source}
801
888
  provider_default_effort: {value | unknown | not-applicable; omit if unknown}
802
889
  dispatch_rationale: {short rationale; omit if unknown}
803
890
  ```
@@ -848,8 +935,8 @@ Escalate the runtime dispatch control when there is evidence that the current co
848
935
  When escalation is needed:
849
936
 
850
937
  1. If a stronger available control exists, re-dispatch at the next stronger control and include the reason in the scope packet. The escalation ladder is provider-specific:
851
- - **Codex:** `selected:low -> selected:medium -> selected:high -> selected:xhigh`, capped by the resolved Codex dispatch ceiling.
852
- - **Claude Code:** `selected:haiku -> selected:sonnet -> selected:opus`, capped by the resolved Claude dispatch ceiling.
938
+ - **Codex:** `selected:low -> selected:medium -> selected:high -> selected:xhigh`, capped by the resolved managed cap when one exists; managed `Uncapped` may select up to the preferred value; inherit/default mode has no OAT escalation control.
939
+ - **Claude Code:** `selected:haiku -> selected:sonnet -> selected:opus -> selected:fable`, capped by the resolved managed cap when one exists; managed `Uncapped` may select up to the preferred model; inherit/default mode has no OAT escalation control.
853
940
  2. Count the escalation redispatch against the existing bounded retry budget. Escalation changes the control; it does not create extra retry attempts.
854
941
  3. Record a compact note in `implementation.md` when practical:
855
942
  - `Dispatch: p03 escalated to model_axis=selected:opus, effort_axis=not-applicable after repeated review failures.` (Claude Code)
@@ -868,8 +955,9 @@ After the implementer returns DONE (or DONE_WITH_CONCERNS without correctness co
868
955
  **Dispatch:**
869
956
 
870
957
  - Use the same tier that was selected at start.
871
- - For Codex, dispatch the reviewer variant matching the resolved ceiling (`oat-reviewer-low|medium|high|xhigh`) for deterministic quality gates.
872
- - For Claude Code, cap any selected review model by the resolved Claude ceiling and keep `effort_axis=not-applicable`.
958
+ - For Codex with a capped managed policy, dispatch the reviewer variant matching the resolved cap (`oat-reviewer-low|medium|high|xhigh`) for deterministic quality gates.
959
+ - For Codex with managed `Uncapped` or inherit/default mode, no reviewer target exists; use base `oat-reviewer`, log `effort_axis=provider-default`, and explain that the base role follows the provider default.
960
+ - For Claude Code with a capped managed policy, pass the resolved cap as the review `model`; managed `Uncapped` or inherit/default mode omits `model` because no reviewer target exists. Always keep `effort_axis=not-applicable`.
873
961
  - Tier 1: dispatch the selected reviewer target via provider-native subagent mechanism with Review Scope:
874
962
 
875
963
  ```
@@ -881,16 +969,18 @@ After the implementer returns DONE (or DONE_WITH_CONCERNS without correctness co
881
969
  workflow_mode: {from state.md}
882
970
  artifact_paths: {same as Phase Scope}
883
971
  tasks_in_scope: {list of pNN-tNN IDs in the phase}
884
- dispatch_ceiling: {resolved ceiling value}
885
- ceiling_source: {repo config | project state | preflight prompt}
972
+ dispatch_policy: {economy | balanced | high | frontier | uncapped | inherit host defaults | legacy capped}
973
+ dispatch_ceiling: {resolved cap value | null}
974
+ policy_source: {repo config | project state | preflight prompt}
975
+ ceiling_source: {repo config | project state | preflight prompt} # compatibility alias for policy_source
886
976
  provider_default_effort: {value | unknown | not-applicable}
887
- model_axis: inherited
888
- effort_axis: selected:{resolved Codex ceiling} # on Codex; use not-applicable on Claude Code
889
- dispatch_rationale: reviewer runs at the configured ceiling for deterministic quality gate behavior
977
+ model_axis: {inherited | selected:<Claude model>}
978
+ effort_axis: {selected:<Codex value> | provider-default | not-applicable}
979
+ dispatch_rationale: {capped reviewer target | uncapped/inherit reviewer fallback}
890
980
  ```
891
981
 
892
982
  - For Codex Tier 1 dispatches, send the Review Scope block as a self-contained packet and keep fresh context (`fork_context: false`). The reviewer is expected to reconstruct context from git state and the OAT artifacts listed above.
893
- - For Codex Tier 1 review dispatches, use `agent_type: "oat-reviewer-low|medium|high|xhigh"` matching the resolved ceiling. Use base `oat-reviewer` only as a provider-default fallback and log `effort_axis=provider-default`. For Claude Code review dispatches, do not pass a per-review effort override because the effort axis is not applicable; if selecting a model, cap it by the resolved Claude ceiling.
983
+ - For Codex Tier 1 review dispatches, use `agent_type: "oat-reviewer-low|medium|high|xhigh"` only when the resolver returns a pinned reviewer variant for a capped managed policy. Use base `oat-reviewer` for managed `Uncapped`, inherit/default mode, or provider-default fallback, and log `effort_axis=provider-default`. For Claude Code review dispatches, do not pass a per-review effort override because the effort axis is not applicable; pass `model` only when the resolver returns a selected review model.
894
984
  - Treat the commit range as authoritative for review scope. `files_changed` is optional orientation metadata only.
895
985
  - If a Codex reviewer does not return a terminal result on the first wait, poll once more. If it still has not concluded, send one concise nudge to return immediately with current findings. If the reviewer still does not conclude, treat the Tier 1 review dispatch as failed for this phase and perform the review inline instead of waiting indefinitely.
896
986
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-plan
3
- version: 1.3.8
3
+ version: 1.3.9
4
4
  description: Use when design.md is complete and executable implementation tasks are needed. Breaks design into bite-sized TDD tasks in canonical plan.md format.
5
5
  oat_gateable: true
6
6
  disable-model-invocation: true
@@ -314,61 +314,92 @@ Unless the source artifact or user already supplied a confirmed `oat_plan_hill_p
314
314
 
315
315
  If `## Planning Checklist` is missing (older plans), add it before finalizing with the items above.
316
316
 
317
- ### Step 11.5: Resolve Dispatch Ceiling Before Implementation Readiness
317
+ ### Step 11.5: Resolve Dispatch Policy Before Implementation Readiness
318
318
 
319
- Before marking the plan ready for implementation, resolve the dispatch ceiling.
319
+ Before marking the plan ready for implementation, resolve the dispatch policy.
320
320
 
321
321
  Resolution order:
322
322
 
323
- 1. Config keys `workflow.dispatchCeiling.providers.<provider>` via the resolver CLI
324
- 2. Project `state.md` frontmatter key `oat_dispatch_ceiling`
325
- 3. Interactive planning prompt (below)
326
- 4. Leave unresolved for implementation preflight when non-interactive
323
+ 1. Config keys `workflow.dispatchPolicy.mode` / `workflow.dispatchPolicy.policy` via the resolver CLI
324
+ 2. Compatibility config keys `workflow.dispatchCeiling.providers.<provider>`
325
+ 3. Project `state.md` frontmatter key `oat_dispatch_policy`
326
+ 4. Legacy project `state.md` frontmatter key `oat_dispatch_ceiling`
327
+ 5. Interactive planning prompt (below)
328
+ 6. Leave unresolved for implementation preflight when non-interactive
327
329
 
328
- If no ceiling resolves and the session is interactive, present the preset
329
- prompt once before final plan review:
330
+ If no policy resolves and the session is interactive, present the dispatch
331
+ policy prompt once before final plan review:
330
332
 
331
333
  ```text
332
- Set the dispatch ceilingthe maximum subagent tier OAT may use.
334
+ Set the dispatch policyhow OAT should choose subagent model/effort controls.
333
335
 
334
- 1. Balanced (recommended) — Codex: high · Claude: sonnet
335
- 2. Maximum — Codex: xhigh · Claude: opus (reviews always run at this tier)
336
- 3. Cost-conscious — Codex: medium · Claude: sonnet
337
- 4. Advanced set per provider
338
- 5. No ceiling
336
+ Managed capped policies:
337
+ 1. Economy — Codex: medium · Claude: sonnet
338
+ 2. Balanced — Codex: high · Claude: sonnet (recommended)
339
+ 3. High Codex: xhigh · Claude: opus
340
+ 4. Frontier — Codex: xhigh · Claude: fable
339
341
 
340
- OAT applies this where the provider exposes a reliable mechanism (Codex: pinned
341
- variants; Claude: Task model parameter). Other providers may treat it as advisory.
342
+ Managed uncapped:
343
+ 5. Uncapped OAT selects the preferred implementer/fix target without a stored maximum cap.
344
+
345
+ Host defaults:
346
+ 6. Inherit Host Defaults — OAT does not select model/effort controls.
347
+
348
+ OAT applies managed policies where the provider exposes a reliable mechanism
349
+ (Codex: pinned variants; Claude: Task model parameter). Other providers may
350
+ treat managed policies as advisory.
342
351
  ```
343
352
 
344
- **Preset selection** persists `preset` + compiled per-provider values. On
345
- selection, print the exact compiled result (e.g., "Ceiling set: balanced
346
- Codex: high · Claude: sonnet") before proceeding.
353
+ **Managed capped policy selection (options 1-4)** persists `mode: managed`,
354
+ `policy`, and the compiled provider targets. On selection, print the exact
355
+ compiled result (e.g., "Dispatch policy set: balanced → Codex: high · Claude:
356
+ sonnet") before proceeding.
347
357
 
348
- **Advanced (option 4)** prompts for each provider's value individually, then
349
- persists `providers` + `source` only no `preset` key.
358
+ **Uncapped (option 5)** persists explicit managed uncapped state. It does not
359
+ write provider caps, and it must not be represented by leaving dispatch policy
360
+ state absent.
350
361
 
351
- **No ceiling (option 5)** leaves `oat_dispatch_ceiling` unset; implementer
352
- subagents run at provider defaults.
362
+ **Inherit Host Defaults (option 6)** persists explicit inherit/default state.
363
+ Use this only when the user wants OAT to leave implementation, fix, and review
364
+ model/effort controls to the executing host/provider.
353
365
 
354
366
  Persist the answer in `"$PROJECT_PATH/state.md"` frontmatter using the
355
367
  normalized shape:
356
368
 
357
369
  ```yaml
358
- oat_dispatch_ceiling:
359
- preset: balanced # omit when Advanced was chosen
370
+ oat_dispatch_policy:
371
+ mode: managed
372
+ policy: balanced
360
373
  providers:
361
374
  codex: high
362
375
  claude: sonnet
363
376
  source: project-state
364
377
  ```
365
378
 
379
+ For `Uncapped`:
380
+
381
+ ```yaml
382
+ oat_dispatch_policy:
383
+ mode: managed
384
+ policy: uncapped
385
+ source: project-state
386
+ ```
387
+
388
+ For `Inherit Host Defaults`:
389
+
390
+ ```yaml
391
+ oat_dispatch_policy:
392
+ mode: inherit
393
+ source: project-state
394
+ ```
395
+
366
396
  Do not prompt when `OAT_NON_INTERACTIVE=1` or when no user-response channel
367
397
  exists. In that case, leave the value unresolved. `oat-project-implement`
368
- must block before work starts if it still cannot resolve a ceiling.
398
+ must block before work starts if it still cannot resolve a policy.
369
399
 
370
- Do not treat provider default effort as the OAT dispatch ceiling. Provider
371
- default is informational for base/unpinned roles only.
400
+ Do not treat provider default effort as the OAT dispatch policy. Provider
401
+ defaults apply only for explicit inherit/default behavior or base/unpinned
402
+ fallback paths.
372
403
 
373
404
  ### Step 12: Review Plan with User
374
405