@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
@@ -35,14 +35,16 @@ You will be given a "Phase Scope" block including:
35
35
  - **workflow_mode**: `spec-driven` | `quick` | `import` (default `spec-driven`)
36
36
  - **model_axis**: Optional model dispatch state selected by the orchestrator (`selected:<value>`, `inherited`, `not-applicable`, or `host-auto`)
37
37
  - **effort_axis**: Optional effort dispatch state selected by the orchestrator (`selected:<value>`, `provider-default`, `inherited`, `not-applicable`, or `host-auto`)
38
- - **dispatch_ceiling**: Optional resolved provider ceiling that capped/selected this dispatch
39
- - **ceiling_source**: Optional source for the resolved ceiling (`repo config`, `project state`, or `preflight prompt`)
40
- - **provider_default_effort**: Optional Codex provider default effort, used only to explain base/unpinned fallback dispatches
38
+ - **dispatch_policy**: Optional resolved policy label (`economy`, `balanced`, `high`, `frontier`, `uncapped`, `inherit host defaults`, or `legacy capped`)
39
+ - **dispatch_ceiling**: Optional resolved provider cap that may have capped/selected this dispatch; absent or null for `uncapped` and inherit/default modes
40
+ - **policy_source**: Optional source for the resolved policy (`repo config`, `project state`, or `preflight prompt`)
41
+ - **ceiling_source**: Optional compatibility alias for policy source (`repo config`, `project state`, or `preflight prompt`)
42
+ - **provider_default_effort**: Optional Codex provider default effort, used only to explain inherit/default behavior or base/unpinned fallback dispatches
41
43
  - **dispatch_rationale**: Optional short rationale for the model/effort axis choices
42
44
 
43
- The `model_axis`, `effort_axis`, `dispatch_ceiling`, `ceiling_source`, and `provider_default_effort` fields describe dispatch state the orchestrator already chose; they are descriptive context for your report, not actions for you to take. Echo whatever values were provided in your summary. If a field is absent, report it as "not provided."
45
+ The `model_axis`, `effort_axis`, `dispatch_policy`, `dispatch_ceiling`, `policy_source`, `ceiling_source`, and `provider_default_effort` fields describe dispatch state the orchestrator already chose; they are descriptive context for your report, not actions for you to take. Echo whatever values were provided in your summary. If a field is absent, report it as "not provided."
44
46
 
45
- For Codex, `provider-default` means the base/unpinned role follows Codex configured/provider default effort. It does not mean OAT inherited the parent session ceiling.
47
+ For Codex, `provider-default` means explicit inherit/default behavior or a base/unpinned fallback follows Codex configured/provider default effort. It does not mean managed `Uncapped`, and it does not mean OAT inherited the parent session ceiling.
46
48
 
47
49
  If `mode: fix`, the block also includes:
48
50
 
@@ -131,8 +133,9 @@ Report format:
131
133
  **Confidence:** high | medium | low
132
134
  **Model axis:** {model_axis if provided, otherwise "not provided"}
133
135
  **Effort axis:** {effort_axis if provided, otherwise "not provided"}
136
+ **Dispatch policy:** {dispatch_policy if provided, otherwise "not provided"}
134
137
  **Dispatch ceiling:** {dispatch_ceiling if provided, otherwise "not provided"}
135
- **Ceiling source:** {ceiling_source if provided, otherwise "not provided"}
138
+ **Policy source:** {policy_source if provided, otherwise ceiling_source if provided, otherwise "not provided"}
136
139
  **Provider default effort:** {provider_default_effort if provided, otherwise "not provided"}
137
140
 
138
141
  ### Task Outcomes
@@ -200,8 +203,9 @@ If a fix introduces a regression or doesn't address its finding, either re-fix w
200
203
  **Confidence:** high | medium | low
201
204
  **Model axis:** {model_axis if provided, otherwise "not provided"}
202
205
  **Effort axis:** {effort_axis if provided, otherwise "not provided"}
206
+ **Dispatch policy:** {dispatch_policy if provided, otherwise "not provided"}
203
207
  **Dispatch ceiling:** {dispatch_ceiling if provided, otherwise "not provided"}
204
- **Ceiling source:** {ceiling_source if provided, otherwise "not provided"}
208
+ **Policy source:** {policy_source if provided, otherwise ceiling_source if provided, otherwise "not provided"}
205
209
  **Provider default effort:** {provider_default_effort if provided, otherwise "not provided"}
206
210
 
207
211
  ### Fix Outcomes
@@ -57,16 +57,18 @@ You will be given a "Review Scope" block including:
57
57
  - **oat_review_invocation**: Optional provenance selector for artifact-mode reviews. Use `manual`, `auto`, or `gate`; default to `manual` when absent.
58
58
  - **model_axis**: Optional model dispatch state selected by the orchestrator (`selected:<value>`, `inherited`, `not-applicable`, or `host-auto`)
59
59
  - **effort_axis**: Optional effort dispatch state selected by the orchestrator (`selected:<value>`, `provider-default`, `inherited`, `not-applicable`, or `host-auto`)
60
- - **dispatch_ceiling**: Optional resolved provider ceiling that capped/selected this review dispatch
61
- - **ceiling_source**: Optional source for the resolved ceiling (`repo config`, `project state`, or `preflight prompt`)
62
- - **provider_default_effort**: Optional Codex provider default effort, used only to explain base/unpinned fallback dispatches
60
+ - **dispatch_policy**: Optional resolved policy label (`economy`, `balanced`, `high`, `frontier`, `uncapped`, `inherit host defaults`, or `legacy capped`)
61
+ - **dispatch_ceiling**: Optional resolved provider cap that may have capped/selected this review dispatch; absent or null for `uncapped` and inherit/default modes
62
+ - **policy_source**: Optional source for the resolved policy (`repo config`, `project state`, or `preflight prompt`)
63
+ - **ceiling_source**: Optional compatibility alias for policy source (`repo config`, `project state`, or `preflight prompt`)
64
+ - **provider_default_effort**: Optional Codex provider default effort, used only to explain inherit/default behavior or base/unpinned fallback dispatches
63
65
  - **dispatch_rationale**: Optional short rationale for the model/effort axis choices
64
66
 
65
67
  ## Dispatch Control
66
68
 
67
69
  The orchestrator owns dispatch control. Do not read `plan.md` Dispatch Profile rows to self-select a tier.
68
70
 
69
- For Codex, normal deterministic review dispatch uses pinned reviewer variants (`oat-reviewer-low`, `oat-reviewer-medium`, `oat-reviewer-high`, or `oat-reviewer-xhigh`) selected by the resolved OAT dispatch ceiling. The base `oat-reviewer` role is a provider-default/unpinned fallback; if you are running as the base role, report any provided `provider_default_effort` as context but do not treat it as an OAT ceiling.
71
+ For Codex, deterministic review dispatch under a capped managed policy uses pinned reviewer variants (`oat-reviewer-low`, `oat-reviewer-medium`, `oat-reviewer-high`, or `oat-reviewer-xhigh`) selected by the resolved OAT dispatch policy cap. Managed `Uncapped` and inherit/default policies have no reviewer target, so the base `oat-reviewer` role is used as a provider-default/unpinned fallback. If you are running as the base role, report any provided `provider_default_effort` as context but do not treat it as managed uncapped selection or an OAT cap.
70
72
 
71
73
  For Claude Code, review dispatch is model-axis based and the effort axis is `not-applicable`.
72
74
 
@@ -168,44 +168,53 @@ oat config get lastPausedProject
168
168
  oat config describe activeIdea
169
169
  ```
170
170
 
171
- ## Dispatch ceiling resolution
171
+ ## Dispatch policy resolution
172
172
 
173
- The dispatch ceiling is set as a **provider-neutral preset** (or per-provider
174
- advanced values) and compiled at write time into concrete per-provider values.
175
- Runtime dispatch reads only the concrete values — never the preset label.
173
+ Dispatch policy is the workflow setting that tells OAT whether to manage
174
+ subagent model/effort selection and, if so, which managed policy to use.
176
175
 
177
- For the full conceptual model presets, the compile/resolve flow, and how
178
- enforcement differs for Codex, Claude, and unsupported providers see
179
- [Dispatch Ceiling](../workflows/projects/dispatch-ceiling.md).
176
+ For the full conceptual model - managed capped tiers, managed `Uncapped`,
177
+ `Inherit Host Defaults`, and provider-specific enforcement - see
178
+ [Dispatch Policy](../workflows/projects/dispatch-ceiling.md).
180
179
 
181
180
  ### Config keys
182
181
 
183
- Three keys control the ceiling, all under `workflow.dispatchCeiling`:
182
+ Preferred keys:
184
183
 
185
- | Key | Values | Purpose |
186
- | ------------------------------------------- | --------------------------------------- | --------------------------------------------------- |
187
- | `workflow.dispatchCeiling.preset` | `balanced`, `maximum`, `cost-conscious` | Convenience preset; compiles to concrete values |
188
- | `workflow.dispatchCeiling.providers.codex` | `low`, `medium`, `high`, `xhigh` | Concrete Codex ceiling (set by preset or Advanced) |
189
- | `workflow.dispatchCeiling.providers.claude` | `haiku`, `sonnet`, `opus` | Concrete Claude ceiling (set by preset or Advanced) |
184
+ | Key | Values | Purpose |
185
+ | -------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------- |
186
+ | `workflow.dispatchPolicy.mode` | `managed`, `inherit` | `managed` lets OAT select controls; `inherit` leaves controls to the host/provider |
187
+ | `workflow.dispatchPolicy.policy` | `economy`, `balanced`, `high`, `frontier`, `uncapped` | Managed policy. Setting this key writes `mode=managed` |
190
188
 
191
- **Presets compile to:**
189
+ Managed policies compile to:
192
190
 
193
- | Preset | Codex | Claude |
194
- | ---------------- | -------- | -------- |
195
- | `balanced` | `high` | `sonnet` |
196
- | `maximum` | `xhigh` | `opus` |
197
- | `cost-conscious` | `medium` | `sonnet` |
191
+ | Policy | Codex | Claude |
192
+ | ---------- | -------- | -------- |
193
+ | `economy` | `medium` | `sonnet` |
194
+ | `balanced` | `high` | `sonnet` |
195
+ | `high` | `xhigh` | `opus` |
196
+ | `frontier` | `xhigh` | `fable` |
197
+ | `uncapped` | none | none |
198
198
 
199
- **Advanced (no preset):** set `providers.codex` and/or `providers.claude`
200
- individually. No `preset` key is stored.
199
+ Legacy compatibility keys remain supported for capped managed behavior:
201
200
 
202
- **No ceiling:** leave `oat_dispatch_ceiling` unset; implementer subagents run at
203
- provider defaults.
201
+ | Key | Values | Purpose |
202
+ | ------------------------------------------- | --------------------------------------- | ---------------------------------------------------------------------------- |
203
+ | `workflow.dispatchCeiling.preset` | `balanced`, `maximum`, `cost-conscious` | Legacy preset alias; `maximum` maps to `high`, `cost-conscious` to `economy` |
204
+ | `workflow.dispatchCeiling.providers.codex` | `low`, `medium`, `high`, `xhigh` | Legacy concrete Codex capped target |
205
+ | `workflow.dispatchCeiling.providers.claude` | `haiku`, `sonnet`, `opus`, `fable` | Legacy concrete Claude capped target |
206
+
207
+ `Uncapped` is explicit managed state. Do not represent it by leaving policy
208
+ state absent. To request no OAT model/effort selection, set:
209
+
210
+ ```bash
211
+ oat config set workflow.dispatchPolicy.mode inherit
212
+ ```
204
213
 
205
214
  ### How enforcement works
206
215
 
207
- OAT applies the ceiling where the provider exposes a reliable mechanism. Other
208
- providers receive it as advisory.
216
+ OAT applies managed policies where the provider exposes a reliable mechanism.
217
+ Other providers receive them as advisory/unsupported.
209
218
 
210
219
  | Provider | Mechanism | Enforcement mode |
211
220
  | -------- | ------------------------- | -------------------------- |
@@ -213,17 +222,22 @@ providers receive it as advisory.
213
222
  | Claude | Task `model` parameter | `enforced` |
214
223
  | Others | None (informational only) | `advisory` / `unsupported` |
215
224
 
225
+ Codex uses effort (`low < medium < high < xhigh`) and pinned OAT role variants.
226
+ Claude uses Task `model` (`haiku < sonnet < opus < fable`) and keeps
227
+ `effort_axis=not-applicable`.
228
+
216
229
  **Verify-on-upgrade:** when the requested tier exceeds the current orchestrator
217
230
  tier (an upgrade request), the resolver sets `verifyOnDispatch: true`. The skill
218
231
  confirms the actual model used after dispatch. If the provider did not honor the
219
232
  upgrade, the enforcement log reads `advisory — provider did not honor upgrade;
220
233
  ran <tier>` instead of `enforced`.
221
234
 
222
- ### Clean break
235
+ ### Legacy compatibility
223
236
 
224
- The previous flat keys (`workflow.dispatchCeiling.codex` and
225
- `workflow.dispatchCeiling.claude`) are removed. There is no migration path — set
226
- the new keys.
237
+ The command group and docs path still use `dispatch-ceiling` for compatibility.
238
+ Legacy `workflow.dispatchCeiling.*` config and project `oat_dispatch_ceiling`
239
+ frontmatter remain readable as capped managed policy input. Absent legacy state
240
+ does not mean managed `Uncapped`.
227
241
 
228
242
  ### Using the resolver
229
243
 
@@ -238,9 +252,9 @@ oat project dispatch-ceiling resolve --provider claude --orchestrator-tier sonne
238
252
  ```
239
253
 
240
254
  The resolver checks effective config first, then project `state.md`
241
- `oat_dispatch_ceiling` frontmatter. For Codex it also reports
242
- `providerDefaultEffort`, which is informational for base/unpinned roles and is
243
- not treated as the OAT ceiling.
255
+ `oat_dispatch_policy` frontmatter, then legacy `oat_dispatch_ceiling`.
256
+ For Codex it also reports `providerDefaultEffort`, which is informational only
257
+ for explicit inherit/default behavior or base/unpinned fallback paths.
244
258
 
245
259
  For non-interactive preflight checks, use:
246
260
 
@@ -269,9 +283,11 @@ Workflow preference keys live under the `workflow.*` namespace:
269
283
  - `workflow.autoNarrowReReviewScope` — boolean. Auto-narrow re-review scope to fix-task commits only in `oat-project-review-provide`. When unset, the skill prompts.
270
284
  - `workflow.autoArtifactReview.plan` — boolean, default `true`. Automatically run the bounded artifact-review loop for generated `plan.md` files before implementation handoff. Set to `false` only when you intentionally want to skip the plan artifact review.
271
285
  - `workflow.autoArtifactReview.analysis` — boolean, default `true`. Automatically run the bounded accuracy-review loop for generated docs and agent-instructions analysis artifacts before the matching apply workflow consumes them.
272
- - `workflow.dispatchCeiling.preset` — `balanced`, `maximum`, or `cost-conscious`. Convenience preset that compiles to per-provider values at write time. Setting this key is the recommended way to configure the ceiling.
273
- - `workflow.dispatchCeiling.providers.codex` — `low`, `medium`, `high`, or `xhigh`. Concrete Codex ceiling. Set automatically when a preset is selected; also settable directly for Advanced (no preset) configurations. Provider default effort is informational for base/unpinned roles and is not treated as this ceiling.
274
- - `workflow.dispatchCeiling.providers.claude` — `haiku`, `sonnet`, or `opus`. Concrete Claude ceiling. Set automatically when a preset is selected; also settable directly for Advanced configurations. Claude has no separate per-dispatch effort axis, so the effort axis remains `not-applicable`.
286
+ - `workflow.dispatchPolicy.mode` — `managed` or `inherit`. `managed` means OAT selects model/effort controls from `workflow.dispatchPolicy.policy`; `inherit` means OAT leaves controls to host/provider defaults.
287
+ - `workflow.dispatchPolicy.policy` — `economy`, `balanced`, `high`, `frontier`, or `uncapped`. `economy` through `frontier` are capped managed policies; `uncapped` keeps OAT-managed preferred selection without provider caps.
288
+ - `workflow.dispatchCeiling.preset` — legacy compatibility alias (`balanced`, `maximum`, or `cost-conscious`) for capped managed policy setup.
289
+ - `workflow.dispatchCeiling.providers.codex` — legacy concrete Codex cap (`low`, `medium`, `high`, or `xhigh`).
290
+ - `workflow.dispatchCeiling.providers.claude` — legacy concrete Claude cap (`haiku`, `sonnet`, `opus`, or `fable`). Claude has no separate per-dispatch effort axis, so the effort axis remains `not-applicable`.
275
291
  - `workflow.gates.skills` / `workflow.gates.execTargets` — structured per-skill final gate commands and exec-target registry. Use `oat gate set`, `oat gate target set`, `oat gate review`, and `oat gate cross-provider-exec`; do not use `oat config set` for these objects.
276
292
 
277
293
  ### Auto artifact-review preferences
@@ -93,30 +93,32 @@ Legacy `.oat/active-project` / `.oat/projects-root` / `.oat/active-idea` files m
93
93
 
94
94
  Current schema keys:
95
95
 
96
- | Key | Type | Default | Description |
97
- | ------------------------------------------- | ---------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
- | `version` | `number` | `1` | Schema version |
99
- | `worktrees.root` | `string` | `".worktrees"` | Root directory for git worktrees (repo-relative or absolute) |
100
- | `projects.root` | `string` | `".oat/projects/shared"` | Default root directory for OAT projects |
101
- | `localPaths` | `string[]` | - | Gitignored directories to sync between main repo and worktrees. Supports glob patterns. Managed via `oat local add/remove`. |
102
- | `documentation.root` | `string` | - | Root directory containing documentation source files (e.g., `apps/docs/docs`) |
103
- | `documentation.tooling` | `string` | - | Documentation framework identifier (`mkdocs` or `fumadocs`) |
104
- | `documentation.config` | `string` | - | Path to the documentation framework config file (e.g., `mkdocs.yml`, `next.config.js`) |
105
- | `documentation.index` | `string` | - | Path to the docs surface entry point (e.g., `index.md` for Fumadocs, `mkdocs.yml` for MkDocs). Set by `oat docs init` and updated by `oat docs generate-index`. |
106
- | `documentation.requireForProjectCompletion` | `boolean` | `false` | When `true`, OAT project completion gates require documentation to be updated |
107
- | `git.defaultBranch` | `string` | `"main"` | Default branch for PR creation. Auto-detected during `oat init` via `gh repo view` or `origin/HEAD`. Used by `oat-project-pr-final` and `oat-project-pr-progress`. |
108
- | `workflow.autoReviewAtHillCheckpoints` | `boolean` | unset | When `true`, completing a HiLL checkpoint automatically runs the extra lifecycle review. Does not control Tier 1 per-phase `oat-reviewer` gates. Can be overridden per-project via `oat_auto_review_at_hill_checkpoints` in `plan.md` frontmatter. Legacy `autoReviewAtCheckpoints` remains a fallback. |
109
- | `workflow.dispatchCeiling.preset` | `string` | unset | Convenience preset compiled at write time to concrete per-provider ceilings (`balanced` = codex `high` / claude `sonnet`; `maximum` = codex `xhigh` / claude `opus`; `cost-conscious` = codex `medium` / claude `sonnet`). Stored only when a preset is chosen; runtime reads compiled `providers.*`, never the preset label. |
110
- | `workflow.dispatchCeiling.providers.codex` | `string` | unset | Maximum Codex reasoning effort OAT may select through deterministic pinned implementer/reviewer variants (`low`, `medium`, `high`, or `xhigh`). Codex provider default effort is informational for base/unpinned roles and is not treated as this ceiling. |
111
- | `workflow.dispatchCeiling.providers.claude` | `string` | unset | Maximum Claude model tier OAT may select for provider-native subagent dispatch (`haiku`, `sonnet`, or `opus`). Claude has no separate per-dispatch effort axis. The flat keys `workflow.dispatchCeiling.codex` and `workflow.dispatchCeiling.claude` were removed (no migration). |
112
- | `workflow.gates.skills` | `object` | unset | Per-skill final gate config keyed by skill name. Managed with `oat gate set/unset`; gate-aware skills declare `oat_gateable: true`. |
113
- | `workflow.gates.execTargets` | `object` | built-ins | Cross-runtime exec target registry keyed by opaque target id. Managed with `oat gate target set/unset`; built-ins cover Codex, Claude, and Cursor defaults. |
114
- | `archive.s3Uri` | `string` | - | Base S3 URI for repo-scoped archived project sync, for example `s3://bucket/oat-archive` |
115
- | `archive.s3SyncOnComplete` | `boolean` | `false` | When `true`, `oat-project-complete` uploads the archived project to the configured S3 archive after local archive succeeds |
116
- | `archive.summaryExportPath` | `string` | - | Repo-relative directory where completion exports `summary.md` as a dated snapshot like `20260401-<project-name>.md` for durable tracked reference |
117
- | `archive.wrapUpExportPath` | `string` | - | Repo-relative directory where `oat-wrap-up` writes dated reports like `20260413-wrap-up-past-week.md`; when unset, the skill falls back to `.oat/repo/reference/wrap-ups/` |
118
- | `archive.awsProfile` | `string` | - | Optional AWS named profile forwarded as `AWS_PROFILE` to every `aws` invocation in archive flows (`oat-project-complete` S3 sync, `oat repo archive sync`). Overrides ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` when set. |
119
- | `archive.awsRegion` | `string` | - | Optional AWS region forwarded as `AWS_REGION` to every `aws` invocation in archive flows. Overrides ambient shell `AWS_REGION` / `AWS_DEFAULT_REGION` when set. |
96
+ | Key | Type | Default | Description |
97
+ | ------------------------------------------- | ---------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
+ | `version` | `number` | `1` | Schema version |
99
+ | `worktrees.root` | `string` | `".worktrees"` | Root directory for git worktrees (repo-relative or absolute) |
100
+ | `projects.root` | `string` | `".oat/projects/shared"` | Default root directory for OAT projects |
101
+ | `localPaths` | `string[]` | - | Gitignored directories to sync between main repo and worktrees. Supports glob patterns. Managed via `oat local add/remove`. |
102
+ | `documentation.root` | `string` | - | Root directory containing documentation source files (e.g., `apps/docs/docs`) |
103
+ | `documentation.tooling` | `string` | - | Documentation framework identifier (`mkdocs` or `fumadocs`) |
104
+ | `documentation.config` | `string` | - | Path to the documentation framework config file (e.g., `mkdocs.yml`, `next.config.js`) |
105
+ | `documentation.index` | `string` | - | Path to the docs surface entry point (e.g., `index.md` for Fumadocs, `mkdocs.yml` for MkDocs). Set by `oat docs init` and updated by `oat docs generate-index`. |
106
+ | `documentation.requireForProjectCompletion` | `boolean` | `false` | When `true`, OAT project completion gates require documentation to be updated |
107
+ | `git.defaultBranch` | `string` | `"main"` | Default branch for PR creation. Auto-detected during `oat init` via `gh repo view` or `origin/HEAD`. Used by `oat-project-pr-final` and `oat-project-pr-progress`. |
108
+ | `workflow.autoReviewAtHillCheckpoints` | `boolean` | unset | When `true`, completing a HiLL checkpoint automatically runs the extra lifecycle review. Does not control Tier 1 per-phase `oat-reviewer` gates. Can be overridden per-project via `oat_auto_review_at_hill_checkpoints` in `plan.md` frontmatter. Legacy `autoReviewAtCheckpoints` remains a fallback. |
109
+ | `workflow.dispatchPolicy.mode` | `string` | unset | Dispatch policy mode: `managed` lets OAT select model/effort controls; `inherit` leaves controls to the host/provider defaults. |
110
+ | `workflow.dispatchPolicy.policy` | `string` | unset | Managed dispatch policy: `economy`, `balanced`, `high`, `frontier`, or `uncapped`. Capped policies compile to provider targets; `uncapped` keeps OAT-managed preferred selection without provider caps. |
111
+ | `workflow.dispatchCeiling.preset` | `string` | unset | Legacy compatibility preset for capped managed policy setup (`balanced`, `maximum`, `cost-conscious`). `maximum` maps to `high`; `cost-conscious` maps to `economy`. |
112
+ | `workflow.dispatchCeiling.providers.codex` | `string` | unset | Legacy concrete Codex capped target (`low`, `medium`, `high`, or `xhigh`). Codex provider default effort is informational only for explicit inherit/default behavior or base/unpinned fallback paths. |
113
+ | `workflow.dispatchCeiling.providers.claude` | `string` | unset | Legacy concrete Claude capped target (`haiku`, `sonnet`, `opus`, or `fable`). Claude has no separate per-dispatch effort axis. The flat keys `workflow.dispatchCeiling.codex` and `workflow.dispatchCeiling.claude` were removed (no migration). |
114
+ | `workflow.gates.skills` | `object` | unset | Per-skill final gate config keyed by skill name. Managed with `oat gate set/unset`; gate-aware skills declare `oat_gateable: true`. |
115
+ | `workflow.gates.execTargets` | `object` | built-ins | Cross-runtime exec target registry keyed by opaque target id. Managed with `oat gate target set/unset`; built-ins cover Codex, Claude, and Cursor defaults. |
116
+ | `archive.s3Uri` | `string` | - | Base S3 URI for repo-scoped archived project sync, for example `s3://bucket/oat-archive` |
117
+ | `archive.s3SyncOnComplete` | `boolean` | `false` | When `true`, `oat-project-complete` uploads the archived project to the configured S3 archive after local archive succeeds |
118
+ | `archive.summaryExportPath` | `string` | - | Repo-relative directory where completion exports `summary.md` as a dated snapshot like `20260401-<project-name>.md` for durable tracked reference |
119
+ | `archive.wrapUpExportPath` | `string` | - | Repo-relative directory where `oat-wrap-up` writes dated reports like `20260413-wrap-up-past-week.md`; when unset, the skill falls back to `.oat/repo/reference/wrap-ups/` |
120
+ | `archive.awsProfile` | `string` | - | Optional AWS named profile forwarded as `AWS_PROFILE` to every `aws` invocation in archive flows (`oat-project-complete` S3 sync, `oat repo archive sync`). Overrides ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` when set. |
121
+ | `archive.awsRegion` | `string` | - | Optional AWS region forwarded as `AWS_REGION` to every `aws` invocation in archive flows. Overrides ambient shell `AWS_REGION` / `AWS_DEFAULT_REGION` when set. |
120
122
 
121
123
  All `documentation.*` keys are managed via `oat config get/set` and are set automatically by `oat docs init`.
122
124
  The `git.defaultBranch` key is auto-detected during `oat init` and can be overridden via `oat config set git.defaultBranch <branch>`.
@@ -1,134 +1,177 @@
1
1
  ---
2
- title: Dispatch Ceiling
3
- description: "How OAT's provider-neutral dispatch ceiling works presets, the compile/resolve flow, and how enforcement differs for Codex, Claude, and unsupported providers."
2
+ title: Dispatch Policy
3
+ description: 'How OAT dispatch policy works: managed capped tiers, managed Uncapped, Inherit Host Defaults, legacy dispatch-ceiling compatibility, and provider-specific enforcement.'
4
4
  ---
5
5
 
6
- # Dispatch Ceiling
6
+ # Dispatch Policy
7
7
 
8
- The **dispatch ceiling** is the most capable tier OAT is allowed to use when it dispatches subagents (phase implementers and reviewers) during `oat-project-implement`. It is a **provider-neutral OAT intent** — your declaration of "don't go above this," decoupled from which provider you happen to be running. OAT then applies that intent through whatever mechanism each provider actually exposes.
8
+ OAT dispatch policy controls how `oat-project-implement` selects model or
9
+ effort controls for phase implementers, fix loops, and reviewers. The current
10
+ contract separates two ideas that used to be conflated:
9
11
 
10
- This page explains the model, the why, and — most importantly — how enforcement differs across providers. For the raw config keys see [Configuration](../../cli-utilities/configuration.md); for how dispatch runs at execution time see [Implementation Execution](implementation-execution.md).
12
+ - **Managed policies** keep OAT responsible for selecting model/effort controls.
13
+ - **Inherit Host Defaults** tells OAT not to select model/effort controls and to
14
+ let the executing host/provider decide.
11
15
 
12
- ## Two principles
16
+ The CLI command is still named `oat project dispatch-ceiling resolve` for
17
+ compatibility, and legacy `workflow.dispatchCeiling.*` / `oat_dispatch_ceiling`
18
+ state is still readable as capped managed input. New configuration should use
19
+ dispatch policy terminology.
13
20
 
14
- 1. **Presets are convenience only — they compile to concrete values at _write_ time.** A fuzzy label like `balanced` is never read at dispatch; it is expanded into concrete per-provider values the moment you set it.
15
- 2. **Enforcement capability is computed at dispatch, never stored.** Whether a ceiling is _enforced_, _advisory_, or _unsupported_ is a property of the provider × runtime, so OAT recomputes it on every run rather than persisting a value that would go stale.
21
+ For raw config keys see [Configuration](../../cli-utilities/configuration.md);
22
+ for execution-time behavior see [Implementation Execution](implementation-execution.md).
16
23
 
17
- ## Setting a ceiling
24
+ ## Policy Choices
18
25
 
19
- Set it via `oat config set` (repo / user / local) or answer the planning/implementation preflight prompt. Three shapes:
26
+ | Policy | Mode | Codex target | Claude target | Meaning |
27
+ | ----------------------- | ------- | ------------ | ------------- | -------------------------------------------- |
28
+ | `Economy` | managed | `medium` | `sonnet` | Lower-cost managed cap |
29
+ | `Balanced` | managed | `high` | `sonnet` | Default managed cap |
30
+ | `High` | managed | `xhigh` | `opus` | High-capability managed cap |
31
+ | `Frontier` | managed | `xhigh` | `fable` | Top managed tier currently exposed by OAT |
32
+ | `Uncapped` | managed | none | none | OAT selects preferred controls without a cap |
33
+ | `Inherit Host Defaults` | inherit | none | none | OAT does not select model/effort controls |
20
34
 
21
- | Choice | What gets written |
22
- | ------------------------------------------------------ | ---------------------------------------------------------------------- |
23
- | **Preset** `balanced` / `maximum` / `cost-conscious` | The preset label (provenance) **and** the compiled per-provider values |
24
- | **Advanced** — set providers directly | `providers.*` only (no `preset` key) |
25
- | **No ceiling** | Nothing — each provider runs at its normal/inherited behavior |
35
+ `Uncapped` is explicit managed state. It is not represented by omitting policy
36
+ state. Existing projects with absent legacy ceiling state remain unresolved or
37
+ legacy-compatible; they do not silently become managed `Uncapped`.
26
38
 
27
- The fixed preset table:
39
+ ## Config Shapes
28
40
 
29
- | Preset | Codex | Claude |
30
- | -------------- | -------- | -------- |
31
- | Balanced | `high` | `sonnet` |
32
- | Maximum | `xhigh` | `opus` |
33
- | Cost-conscious | `medium` | `sonnet` |
41
+ Preferred managed policy config:
34
42
 
35
- `cost-conscious` deliberately keeps Claude at `sonnet` (no `haiku` reviewers by default) so review quality stays trustworthy.
43
+ ```bash
44
+ oat config set workflow.dispatchPolicy.policy balanced --shared
45
+ oat config set workflow.dispatchPolicy.policy frontier --shared
46
+ oat config set workflow.dispatchPolicy.policy uncapped --shared
47
+ ```
36
48
 
37
- Config keys:
38
-
39
- - `workflow.dispatchCeiling.preset`
40
- - `workflow.dispatchCeiling.providers.codex` (`low` \| `medium` \| `high` \| `xhigh`)
41
- - `workflow.dispatchCeiling.providers.claude` (`haiku` \| `sonnet` \| `opus`)
49
+ `workflow.dispatchPolicy.policy` writes `workflow.dispatchPolicy.mode=managed`.
50
+ To request host defaults:
42
51
 
43
52
  ```bash
44
- # A preset compiles immediately to concrete per-provider values:
45
- oat config set workflow.dispatchCeiling.preset balanced --shared
46
- # → stores preset: balanced AND providers: { codex: high, claude: sonnet }
53
+ oat config set workflow.dispatchPolicy.mode inherit --shared
54
+ ```
47
55
 
48
- # Or set providers directly (advanced — no preset key stored):
49
- oat config set workflow.dispatchCeiling.providers.codex high --shared
56
+ Project state uses the same shape:
57
+
58
+ ```yaml
59
+ oat_dispatch_policy:
60
+ mode: managed
61
+ policy: balanced
62
+ providers:
63
+ codex: high
64
+ claude: sonnet
65
+ source: project-state
50
66
  ```
51
67
 
52
- Project state can persist the compiled answer as `oat_dispatch_ceiling` (`preset?` + `providers` + `source`) so a planning/preflight choice carries into implementation.
68
+ For `Uncapped`, omit provider caps:
69
+
70
+ ```yaml
71
+ oat_dispatch_policy:
72
+ mode: managed
73
+ policy: uncapped
74
+ source: project-state
75
+ ```
53
76
 
54
- > The earlier flat `workflow.dispatchCeiling.codex` / `.claude` keys were removed. This was a clean break with no migration — set the new keys above.
77
+ For host defaults:
78
+
79
+ ```yaml
80
+ oat_dispatch_policy:
81
+ mode: inherit
82
+ source: project-state
83
+ ```
55
84
 
56
- ## How it resolves at dispatch
85
+ Legacy compatibility keys remain readable:
86
+
87
+ - `workflow.dispatchCeiling.preset`
88
+ - `workflow.dispatchCeiling.providers.codex`
89
+ - `workflow.dispatchCeiling.providers.claude`
90
+ - `oat_dispatch_ceiling`
91
+
92
+ Legacy preset names map into the managed ladder: `cost-conscious` maps to
93
+ `Economy`, `balanced` maps to `Balanced`, and `maximum` maps to `High`.
94
+
95
+ ## How Resolution Works
57
96
 
58
97
  Before dispatching a subagent, the orchestrator calls:
59
98
 
60
99
  ```bash
61
- oat project dispatch-ceiling resolve --provider <provider> --role <implementer|reviewer> --preflight --json
100
+ oat project dispatch-ceiling resolve --provider <provider> --role <implementer|reviewer> --json
62
101
  ```
63
102
 
64
- For implementer or fix dispatch, pass the runtime classification too. In Codex
65
- this is the preferred effort; in Claude it is the preferred model tier:
103
+ For implementer or fix dispatch, pass the preferred runtime control:
66
104
 
67
105
  ```bash
68
- oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
69
- oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --json
106
+ oat project dispatch-ceiling resolve --provider codex --role implementer --preferred high --json
107
+ oat project dispatch-ceiling resolve --provider claude --role implementer --preferred opus --json
70
108
  ```
71
109
 
72
- The resolver:
73
-
74
- 1. reads the concrete `providers.<provider>` value (config precedence, then project state) — **never the preset label**;
75
- 2. looks up that provider's **adapter** in the provider ceiling registry;
76
- 3. applies `--preferred` for implementer/fix dispatch, capping it against the ceiling;
77
- 4. returns a per-provider result: `{ value, mode, mechanism, dispatchArgs, selection }`.
110
+ The resolver returns the resolved policy, optional cap, source, provider default
111
+ effort where applicable, and provider-specific `dispatchArgs`.
78
112
 
79
- `mode` is the honest enforcement status, computed right there and never persisted:
113
+ Selection modes:
80
114
 
81
- - **enforced** the provider has a real mechanism and OAT dispatched the requested control.
82
- - **advisory** the ceiling is recorded as intent, but the provider can't deterministically enforce it (or an above-orchestrator request couldn't be honored).
83
- - **unsupported** no adapter mechanism exists for that provider.
115
+ - `capped` - implementer/fix dispatch selects `min(preferred, cap)`.
116
+ - `uncapped` - implementer/fix dispatch selects the preferred value.
117
+ - `review-target` - reviewer dispatch targets a configured cap when one exists.
118
+ - `no-review-target` - managed uncapped reviewer dispatch has no configured
119
+ target and falls back to the base/unpinned reviewer.
120
+ - `inherit-default` - OAT returns no dispatch args and leaves controls to the host.
121
+ - `unresolved` - non-interactive implementation blocks before work starts.
84
122
 
85
- ## Per-provider behavior
123
+ ## Provider Behavior
86
124
 
87
- The same ceiling intent produces different — but honest — behavior per provider, because each adapter declares its own mechanism.
125
+ | | Codex | Claude Code | Unsupported provider |
126
+ | ----------------- | ------------------------------------------- | --------------------------------------- | -------------------- |
127
+ | Managed mechanism | Pinned role variants | Task `model` argument | None |
128
+ | Axis | effort (`low < medium < high < xhigh`) | model (`haiku < sonnet < opus < fable`) | None |
129
+ | Capped policy | selected pinned variant up to cap | selected Task model up to cap | advisory/unsupported |
130
+ | Uncapped | preferred pinned variant, no cap | preferred Task model, no cap | advisory/unsupported |
131
+ | Inherit/default | base/unpinned role follows provider default | omit `model` | normal behavior |
88
132
 
89
- | | **Codex** | **Claude** | **Unsupported provider** |
90
- | ----------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------- | -------------------------- |
91
- | Can OAT enforce? | Yes | Yes | No (no adapter yet) |
92
- | Mechanism | Pinned variant files | Per-call Task `model` argument | None |
93
- | Where it lives | Sync-time committed `.codex` role variants (`oat-phase-implementer-high`, `oat-reviewer-high`, …) | Passed at dispatch time — **no files** | — |
94
- | Axis | effort (`low < medium < high < xhigh`) | model tier (`haiku < sonnet < opus`) | — |
95
- | `dispatchArgs` | `{ variant: "oat-reviewer-high" }` | `{ model: "sonnet" }` | `null` |
96
- | `mode` | `enforced` | `enforced` | `advisory` / `unsupported` |
97
- | If no ceiling set | base/unpinned role (provider default) | inherits the orchestrator's model | normal behavior |
133
+ Codex uses pinned variants because per-call effort controls were unreliable in
134
+ dogfooding. For managed `Uncapped`, OAT still selects the preferred pinned
135
+ variant; the dispatching host should verify whether upward effort selection is
136
+ actually honored in the current session.
98
137
 
99
- ### Why the mechanisms differ
138
+ Claude Code uses the per-call Task `model` argument. It has no OAT-managed
139
+ per-dispatch effort axis, so dispatch logs use `effort_axis=not-applicable`.
140
+ `Frontier` maps to Claude `fable`.
100
141
 
101
- - **Codex** dispatches through **pinned, sync-time role variants**. Per-call reasoning-effort proved unreliable in practice, so OAT generates committed `oat-phase-implementer-{low..xhigh}` / `oat-reviewer-{low..xhigh}` role files. Implementer/fix dispatch passes `--preferred` so `dispatchArgs.variant` matches the selected capped effort; reviewer dispatch uses the variant matching the resolved ceiling.
102
- - **Claude** uses the **per-call Task `model` parameter**, which is reliable and bidirectional (a Sonnet orchestrator can dispatch an Opus subagent and vice-versa) and overrides agent frontmatter. Implementer/fix dispatch passes `--preferred` as the preferred model tier and receives the capped selected `model`; reviewer dispatch uses the ceiling model. OAT needs no variant files.
103
- - **Unsupported providers** (any without a registered adapter) resolve to `unsupported` with `dispatchArgs: null`. The resolve command **returns cleanly and never blocks** — the ceiling is recorded as intent and applied if/when an adapter ships, while the provider runs at its own capabilities.
142
+ ## Implementer, Fix, and Reviewer Behavior
104
143
 
105
- A **provider adapter registry** is what lets these genuinely different mechanisms sit behind one resolver, so the lifecycle skills consume `dispatchArgs` without ever branching on provider.
144
+ For implementer and fix dispatches:
106
145
 
107
- ## Cap vs target: implementer vs reviewer
146
+ - Capped managed policies select `min(preferred, cap)`.
147
+ - Managed `Uncapped` selects the preferred value without a cap.
148
+ - Inherit/default mode returns no model/effort dispatch args.
108
149
 
109
- The ceiling means slightly different things for the two dispatch roles:
150
+ For reviewer dispatches:
110
151
 
111
- - **Implementer** runs at `min(preferred, ceiling)` — the ceiling is a **cap**. A simple phase may run below it.
112
- - **Reviewer** runs **at** the ceiling — a **target** — so quality gates are deterministic.
152
+ - Capped managed policies target the configured cap for deterministic review
153
+ quality gates.
154
+ - Managed `Uncapped` has no reviewer cap, so OAT uses the base/unpinned reviewer
155
+ fallback and logs provider-default behavior.
156
+ - Inherit/default mode also uses the base/unpinned reviewer fallback.
113
157
 
114
- Both providers honor this distinction (Codex selects the matching variant; Claude passes the matching model).
158
+ Generic sidecars such as `explorer` are outside the implementer/reviewer/fix
159
+ contract. If their payload does not pin a reliable provider control, logs should
160
+ say `provider-default`.
115
161
 
116
- Generic sidecars such as built-in `explorer` are outside this implementer/reviewer/fix contract. They may run at provider default when they are read-only advisory helpers. In that case, dispatch logs should say `Preferred effort: provider-default`, `Selected effort: provider-default`, and `Effort axis: provider-default`; only log a concrete selected effort when the actual sidecar payload pins a reliable provider control.
162
+ ## Dispatch Logs
117
163
 
118
- ## Verify-on-upgrade
119
-
120
- Only a request for a tier **above** the orchestrator's current tier risks a silent plan/entitlement fallback. So the adapter verifies the actually-dispatched model **only** on that upgrade path; capping down or staying lateral needs no check. OAT never logs `enforced` unless the requested control was actually honored.
121
-
122
- ## Dispatch logs
123
-
124
- OAT logs the honest enforcement state per dispatch, for example:
164
+ Examples:
125
165
 
126
166
  ```text
127
- Dispatch ceiling: high (codex, enforced — variant oat-reviewer-high)
128
- Dispatch ceiling: sonnet (claude, enforced — Task model arg)
129
- Dispatch ceiling: balanced (cursor, unsupportedno adapter; informational)
167
+ Dispatch policy: balanced; selected=high; cap=high (codex, enforced — variant oat-phase-implementer-high)
168
+ Dispatch policy: high; selected=xhigh; cap=xhigh (codex, enforced — variant oat-reviewer-xhigh)
169
+ Dispatch policy: uncapped; selected=xhigh; cap=none (codex, enforcedvariant oat-phase-implementer-xhigh)
170
+ Dispatch policy: inherit host defaults; selected=none; cap=none (codex, advisory — base role follows provider default)
171
+ Dispatch policy: frontier; selected=fable; cap=fable (claude, enforced — Task model arg)
130
172
  ```
131
173
 
132
- ## Summary
133
-
134
- You declare intent once (a preset, explicit per-provider values, or nothing). Under Codex it becomes deterministic pinned variants; under Claude it becomes a per-call Task `model` argument; under any other provider it is recorded as advisory and that provider runs normally. The logs tell you honestly whether the ceiling was `enforced`, `advisory`, or `unsupported` — one provider-neutral knob that enforces where it can and degrades gracefully where it can't.
174
+ OAT logs `enforced` only when the provider accepted the requested control.
175
+ Above-orchestrator Claude upgrade requests may require post-dispatch
176
+ verification. Unsupported providers do not block; OAT records the policy as
177
+ advisory/unsupported and dispatch follows provider behavior.