@open-agent-toolkit/cli 0.1.46 → 0.1.48

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 (82) hide show
  1. package/assets/agents/oat-phase-implementer.md +202 -191
  2. package/assets/agents/oat-reviewer.md +11 -1
  3. package/assets/config/dispatch-matrix-recommendation.json +120 -13
  4. package/assets/docs/cli-utilities/configuration.md +172 -113
  5. package/assets/docs/cli-utilities/workflow-gates.md +161 -27
  6. package/assets/docs/contributing/skills.md +14 -8
  7. package/assets/docs/provider-sync/providers.md +41 -7
  8. package/assets/docs/provider-sync/scope-and-surface.md +2 -2
  9. package/assets/docs/reference/cli-reference.md +3 -1
  10. package/assets/docs/reference/oat-directory-structure.md +27 -26
  11. package/assets/docs/workflows/projects/artifacts.md +31 -1
  12. package/assets/docs/workflows/projects/dispatch-ceiling.md +235 -187
  13. package/assets/docs/workflows/projects/implementation-execution.md +283 -260
  14. package/assets/docs/workflows/projects/lifecycle.md +26 -5
  15. package/assets/docs/workflows/projects/reviews.md +27 -2
  16. package/assets/migration/pjm-restructure.md +1 -1
  17. package/assets/public-package-versions.json +4 -4
  18. package/assets/skills/oat-project-implement/SKILL.md +247 -133
  19. package/assets/skills/oat-project-import-plan/SKILL.md +173 -16
  20. package/assets/skills/oat-project-next/SKILL.md +2 -2
  21. package/assets/skills/oat-project-plan/SKILL.md +122 -92
  22. package/assets/skills/oat-project-plan-writing/SKILL.md +246 -15
  23. package/assets/skills/oat-project-quick-start/SKILL.md +157 -107
  24. package/assets/skills/oat-project-review-provide/SKILL.md +94 -22
  25. package/dist/commands/config/index.d.ts.map +1 -1
  26. package/dist/commands/config/index.js +64 -39
  27. package/dist/commands/doctor/index.d.ts.map +1 -1
  28. package/dist/commands/doctor/index.js +21 -6
  29. package/dist/commands/gate/index.d.ts +7 -1
  30. package/dist/commands/gate/index.d.ts.map +1 -1
  31. package/dist/commands/gate/index.js +544 -67
  32. package/dist/commands/gate/review-verdict.d.ts +16 -0
  33. package/dist/commands/gate/review-verdict.d.ts.map +1 -1
  34. package/dist/commands/gate/review-verdict.js +72 -9
  35. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  36. package/dist/commands/project/dispatch-ceiling/index.js +452 -16
  37. package/dist/commands/providers/codex/materialize.d.ts.map +1 -1
  38. package/dist/commands/providers/codex/materialize.js +6 -1
  39. package/dist/commands/shared/frontmatter.d.ts +4 -0
  40. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  41. package/dist/commands/shared/frontmatter.js +23 -0
  42. package/dist/commands/status/index.d.ts +1 -0
  43. package/dist/commands/status/index.d.ts.map +1 -1
  44. package/dist/commands/status/index.js +10 -4
  45. package/dist/commands/sync/index.d.ts.map +1 -1
  46. package/dist/commands/sync/index.js +10 -3
  47. package/dist/commands/sync/sync.types.d.ts +1 -0
  48. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  49. package/dist/config/oat-config.d.ts +19 -2
  50. package/dist/config/oat-config.d.ts.map +1 -1
  51. package/dist/config/oat-config.js +139 -24
  52. package/dist/config/resolve.d.ts +8 -0
  53. package/dist/config/resolve.d.ts.map +1 -1
  54. package/dist/config/resolve.js +66 -2
  55. package/dist/engine/index.d.ts +1 -1
  56. package/dist/engine/index.d.ts.map +1 -1
  57. package/dist/engine/index.js +1 -1
  58. package/dist/engine/scanner.d.ts +1 -0
  59. package/dist/engine/scanner.d.ts.map +1 -1
  60. package/dist/engine/scanner.js +17 -1
  61. package/dist/fs/paths.d.ts +4 -0
  62. package/dist/fs/paths.d.ts.map +1 -1
  63. package/dist/fs/paths.js +18 -1
  64. package/dist/providers/ceiling/registry.d.ts +1 -0
  65. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  66. package/dist/providers/ceiling/registry.js +12 -5
  67. package/dist/providers/codex/codec/catalog.d.ts +14 -0
  68. package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
  69. package/dist/providers/codex/codec/catalog.js +21 -0
  70. package/dist/providers/codex/codec/materialize.d.ts.map +1 -1
  71. package/dist/providers/codex/codec/materialize.js +6 -5
  72. package/dist/providers/codex/codec/shared.d.ts +19 -0
  73. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  74. package/dist/providers/codex/codec/shared.js +98 -5
  75. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  76. package/dist/providers/codex/codec/sync-extension.js +142 -32
  77. package/dist/providers/identity/stamp.d.ts.map +1 -1
  78. package/dist/providers/identity/stamp.js +4 -0
  79. package/dist/shared/types.d.ts +1 -0
  80. package/dist/shared/types.d.ts.map +1 -1
  81. package/dist/shared/types.js +4 -0
  82. package/package.json +2 -2
@@ -1,78 +1,153 @@
1
1
  ---
2
2
  title: Dispatch Policy
3
- description: 'How OAT dispatch policy works: managed tiers, dispatch matrix cells, ordered routes, producer provenance, legacy compatibility, and provider-specific enforcement.'
3
+ description: 'How OAT combines owned provider candidate ladders, project and phase named maximum ceilings, exact task dispatch, and provider-specific enforcement.'
4
4
  ---
5
5
 
6
6
  # Dispatch Policy
7
7
 
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:
8
+ OAT dispatch policy separates reusable provider choices from project-specific
9
+ constraints:
11
10
 
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
+ - A **candidate ladder** is an ordered provider column stored in user, shared,
12
+ or repo-local config. Each named tier contains one or more exact candidates.
13
+ - A **named ceiling** is a project or phase maximum such as `balanced` or
14
+ `high`. It is not an enduring model-family or effort preference.
15
+ - A **task target** is one exact configured candidate selected at invocation
16
+ time at or below the named maximum.
15
17
 
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.
18
+ The CLI command remains `oat project dispatch-ceiling resolve` for compatibility.
19
+ Legacy `workflow.dispatchCeiling.*` and `oat_dispatch_ceiling` values remain
20
+ readable, but new projects use ordered candidates plus `oat_dispatch_policy`.
20
21
 
21
- For raw config keys see [Configuration](../../cli-utilities/configuration.md);
22
- for execution-time behavior see [Implementation Execution](implementation-execution.md).
22
+ For raw config keys, see [Configuration](../../cli-utilities/configuration.md).
23
+ For the coordinator and task-worker loop, see
24
+ [Implementation Execution](implementation-execution.md).
23
25
 
24
- Multi-family providers such as Cursor use the same abstract policy names, but
25
- their concrete model values come from a dispatch matrix under
26
- `workflow.dispatchCeiling.providers.*`. A matrix cell can be a single value, a
27
- per-tier value, or an ordered route for escalation.
26
+ ## Named Policy Choices
28
27
 
29
- ## Policy Choices
28
+ | Choice | Mode | Named maximum | Eligible configured tiers |
29
+ | ----------------------- | ------- | ------------- | ---------------------------------------- |
30
+ | `Economy` | managed | `economy` | Economy |
31
+ | `Balanced` | managed | `balanced` | Economy, Balanced |
32
+ | `High` | managed | `high` | Economy, Balanced, High |
33
+ | `Frontier` | managed | `frontier` | Economy, Balanced, High, Frontier |
34
+ | `Uncapped` | managed | none | Any configured candidate OAT can resolve |
35
+ | `Inherit Host Defaults` | inherit | none | OAT does not select provider controls |
30
36
 
31
- | Policy | Mode | Codex cap | Claude target | Meaning |
32
- | ----------------------- | ------- | --------- | ------------- | -------------------------------------------- |
33
- | `Economy` | managed | `medium` | `sonnet` | Lower-cost managed cap |
34
- | `Balanced` | managed | `high` | `sonnet` | Default managed cap |
35
- | `High` | managed | `xhigh` | `opus` | High-capability managed cap |
36
- | `Frontier` | managed | `xhigh` | `fable` | Top managed tier currently exposed by OAT |
37
- | `Uncapped` | managed | none | none | OAT selects preferred controls without a cap |
38
- | `Inherit Host Defaults` | inherit | none | none | OAT does not select model/effort controls |
37
+ A named `High` ceiling therefore keeps configured Economy, Balanced, and High
38
+ candidates eligible and available. It does not pin Sol, `opus`, one Cursor
39
+ string, or one effort value. The task coordinator chooses the lowest exact
40
+ candidate it judges sufficient for each bounded task.
39
41
 
40
- `Uncapped` is explicit managed state. It is not represented by omitting policy
41
- state. Existing projects with absent legacy ceiling state remain unresolved or
42
- legacy-compatible; they do not silently become managed `Uncapped`. `Unresolved`
43
- is a deferral state for planning/preflight only. Implementation preflight must
44
- resolve a managed policy or inherit/default mode before work starts.
42
+ `Uncapped` is explicit managed state. It is not represented by omitted policy
43
+ state. `Unresolved` is a planning or preflight deferral and cannot begin
44
+ implementation.
45
45
 
46
- ## Config Shapes
46
+ ## Ownership and Adoption
47
47
 
48
- Preferred managed policy config:
48
+ Adopt the complete bundled recommendation into one explicit owning scope:
49
49
 
50
50
  ```bash
51
- oat config set workflow.dispatchPolicy.policy balanced --shared
52
- oat config set workflow.dispatchPolicy.policy frontier --shared
53
- oat config set workflow.dispatchPolicy.policy uncapped --shared
51
+ # Team-owned, tracked repo configuration
52
+ oat config adopt dispatch-matrix --shared
53
+
54
+ # Checkout-specific repo configuration
55
+ oat config adopt dispatch-matrix --local
56
+
57
+ # Personal defaults across repositories
58
+ oat config adopt dispatch-matrix --user
54
59
  ```
55
60
 
56
- `workflow.dispatchPolicy.policy` writes `workflow.dispatchPolicy.mode=managed`.
57
- To request host defaults:
61
+ Adoption fills missing provider/tier cells and records
62
+ `workflow.dispatchCeiling.recommendationVersion`; it does not replace explicit
63
+ existing cells. Planning shows the complete recommendation before asking which
64
+ scope should own it. If the resulting ladder is still missing or incomplete,
65
+ planning remains blocked rather than replacing the user's explicit values.
58
66
 
59
- ```bash
60
- oat config set workflow.dispatchPolicy.mode inherit --shared
67
+ The ownership boundary is deliberate:
68
+
69
+ | Source | Config location | Codex materialization output |
70
+ | ------------------------------------------ | ------------------------------ | ------------------------------------- |
71
+ | Shared or repo-local project configuration | `.oat/config*.json` | Tracked project `.codex` view |
72
+ | Active-project sparse override | Project `state.md` | Tracked project `.codex` view |
73
+ | User configuration | `~/.oat/config.json` | User `~/.codex` view |
74
+ | Supported OAT catalogue | Bundled recommendation/catalog | Tracked project `.codex` view on sync |
75
+
76
+ Project-generated roles remain visible to version control. OAT does not
77
+ auto-ignore them. User-generated roles remain outside the repository under the
78
+ user home directory.
79
+
80
+ The reusable ladder and active project ceiling have separate ownership. A
81
+ project-specific policy or ceiling belongs in that project's `state.md`; do not
82
+ write it into user `~/.oat/config.json` merely because the reusable ladder is
83
+ user-owned.
84
+
85
+ ## Config Shapes
86
+
87
+ An ordered candidate cell uses `candidates`:
88
+
89
+ ```json
90
+ {
91
+ "workflow": {
92
+ "dispatchCeiling": {
93
+ "providers": {
94
+ "codex": {
95
+ "balanced": {
96
+ "candidates": [
97
+ {
98
+ "harness": "codex",
99
+ "model": "gpt-5.6-terra",
100
+ "effort": "low"
101
+ },
102
+ {
103
+ "harness": "codex",
104
+ "model": "gpt-5.6-terra",
105
+ "effort": "medium"
106
+ },
107
+ {
108
+ "harness": "codex",
109
+ "model": "gpt-5.6-terra",
110
+ "effort": "high"
111
+ }
112
+ ]
113
+ }
114
+ },
115
+ "claude": {
116
+ "balanced": { "candidates": ["sonnet"] }
117
+ },
118
+ "cursor": {
119
+ "balanced": {
120
+ "candidates": [
121
+ "gpt-5.6-terra-low",
122
+ "gpt-5.6-terra-medium",
123
+ "gpt-5.6-terra-high"
124
+ ]
125
+ }
126
+ }
127
+ }
128
+ }
129
+ }
130
+ }
61
131
  ```
62
132
 
63
- Project state uses the same shape:
133
+ Each candidate can also be a fallback route. Route entries are attempted only
134
+ through the resolver's bounded escalation level; a route does not change the
135
+ named maximum.
136
+
137
+ Project state records only the active named maximum:
64
138
 
65
139
  ```yaml
66
140
  oat_dispatch_policy:
67
141
  mode: managed
68
- policy: balanced
69
- providers:
70
- codex: high
71
- claude: sonnet
142
+ policy: high
72
143
  source: project-state
73
144
  ```
74
145
 
75
- For `Uncapped`, omit provider caps:
146
+ Do not copy compiled `providers` targets into this shape. An optional plan
147
+ `## Dispatch Profile` row may narrow one phase to another named maximum at or
148
+ below the project maximum. Blank or `auto` uses the project value.
149
+
150
+ Managed uncapped and inherit/default shapes are explicit:
76
151
 
77
152
  ```yaml
78
153
  oat_dispatch_policy:
@@ -81,180 +156,153 @@ oat_dispatch_policy:
81
156
  source: project-state
82
157
  ```
83
158
 
84
- For host defaults:
85
-
86
159
  ```yaml
87
160
  oat_dispatch_policy:
88
161
  mode: inherit
89
162
  source: project-state
90
163
  ```
91
164
 
92
- Legacy compatibility keys remain readable:
165
+ ## Complete Bundled Recommendation
93
166
 
94
- - `workflow.dispatchCeiling.preset`
95
- - `workflow.dispatchCeiling.providers.<provider>`
96
- - `workflow.dispatchCeiling.providers.<provider>.<tier>`
97
- - `oat_dispatch_ceiling`
167
+ The bundled ladder contains every supported candidate, not only the final
168
+ candidate in each tier:
98
169
 
99
- Legacy preset names map into the managed ladder: `cost-conscious` maps to
100
- `Economy`, `balanced` maps to `Balanced`, and `maximum` maps to `High`.
170
+ - **Codex:** Luna at `low`, `medium`, `high`, and `xhigh`; Terra at `low`,
171
+ `medium`, `high`, and `xhigh`; Sol at `low`, `medium`, `high`, `xhigh`, and
172
+ `max`.
173
+ - **Claude:** `haiku`, `sonnet`, `opus`, and `fable` across the ordered named
174
+ tiers.
175
+ - **Cursor:** opaque strings corresponding to the same 13 configured positions.
176
+ OAT does not parse those strings to infer family, effort, cost, or capability.
101
177
 
102
- ## Dispatch Matrix
178
+ The final candidate in a named tier defines that tier's reviewer ceiling. Lower
179
+ reviewer selection requires a separate reviewed contract; a normal reviewer
180
+ does not use task candidate flags.
103
181
 
104
- The dispatch matrix maps the abstract policy rung (`economy`, `balanced`,
105
- `high`, `frontier`) to concrete provider controls. Existing bare Codex and
106
- Claude values remain valid, and multi-family providers can use tier cells:
182
+ ## Exact Task Resolution
107
183
 
108
- ```bash
109
- oat config adopt dispatch-matrix --shared
110
- oat config set workflow.dispatchCeiling.providers.cursor.balanced composer-2.5 --shared
111
- oat config set workflow.dispatchCeiling.providers.cursor.high gpt-5.5-xhigh --shared
112
- ```
184
+ Planning and implementation preflight resolve the active policy first:
113
185
 
114
- For ordered escalation, write a route in config JSON. The resolver selects the
115
- floor entry at escalation level `0` and advances by route entry when the
116
- implementation/fix loop escalates:
117
-
118
- ```json
119
- {
120
- "workflow": {
121
- "dispatchCeiling": {
122
- "providers": {
123
- "cursor": {
124
- "high": [
125
- "composer-2.5",
126
- { "harness": "cursor", "model": "gpt-5.5-xhigh" }
127
- ],
128
- "frontier": [
129
- { "harness": "cursor", "model": "gpt-5.5-xhigh" },
130
- { "harness": "cursor", "model": "fable-5" }
131
- ]
132
- }
133
- }
134
- }
135
- }
136
- }
186
+ ```bash
187
+ oat project dispatch-ceiling resolve \
188
+ --provider codex \
189
+ --preflight \
190
+ --json
137
191
  ```
138
192
 
139
- Project `state.md` may carry only sparse project-specific matrix overrides
140
- under `oat_dispatch_policy.matrix`. The full reusable matrix belongs in user,
141
- shared, or local config so switching harnesses mid-project re-resolves the same
142
- abstract policy through the active provider column.
143
-
144
- ## How Resolution Works
145
-
146
- Before dispatching a subagent, the orchestrator calls:
193
+ Before each managed capped implementation or fix task, the phase coordinator
194
+ classifies the bounded task and requests one exact configured candidate. It
195
+ passes the recorded project or narrower phase maximum through the
196
+ invocation-only `--ceiling-tier` option:
147
197
 
148
198
  ```bash
149
- oat project dispatch-ceiling resolve --provider <provider> --role <implementer|reviewer> --json
199
+ # Codex: exact model plus effort
200
+ oat project dispatch-ceiling resolve \
201
+ --provider codex \
202
+ --role implementer \
203
+ --ceiling-tier high \
204
+ --candidate-model gpt-5.6-terra \
205
+ --candidate-effort medium \
206
+ --json
207
+
208
+ # Claude: exact model argument
209
+ oat project dispatch-ceiling resolve \
210
+ --provider claude \
211
+ --role implementer \
212
+ --ceiling-tier high \
213
+ --candidate-model sonnet \
214
+ --json
215
+
216
+ # Cursor: exact opaque configured string
217
+ oat project dispatch-ceiling resolve \
218
+ --provider cursor \
219
+ --role implementer \
220
+ --ceiling-tier high \
221
+ --candidate-model 'opaque:model/balanced [v2]' \
222
+ --json
150
223
  ```
151
224
 
152
- For implementer or fix dispatch, pass the preferred runtime control:
225
+ `--ceiling-tier` accepts `economy`, `balanced`, `high`, or `frontier`. It
226
+ overrides a layered active-policy ceiling for that resolver invocation only. It
227
+ does not modify user, shared, local, or project configuration.
153
228
 
154
- ```bash
155
- oat project dispatch-ceiling resolve --provider codex --role implementer --preferred high --json
156
- oat project dispatch-ceiling resolve --provider claude --role implementer --preferred opus --json
157
- oat project dispatch-ceiling resolve --provider cursor --role implementer --preferred high --escalation-level 0 --json
158
- ```
229
+ Successful JSON reports:
159
230
 
160
- The resolver returns the resolved policy, optional cap, source, provider default
161
- effort where applicable, and provider-specific `dispatchArgs`.
162
-
163
- Selection modes:
164
-
165
- - `capped` - implementer/fix dispatch selects `min(preferred, cap)`.
166
- - `uncapped` - implementer/fix dispatch selects the preferred value.
167
- - `matrix-pinned` - a matrix cell supplied the selected provider value.
168
- - `prompt-persisted` - an interactive prompt filled a missing cell and persisted it.
169
- - `escalation-target` - an ordered route entry supplied the selected target.
170
- - `review-target` - reviewer dispatch targets a configured cap when one exists.
171
- - `no-review-target` - managed uncapped reviewer dispatch has no configured
172
- target and falls back to the base/unpinned reviewer.
173
- - `inherit-default` - OAT returns no dispatch args and leaves controls to the host.
174
- - `unresolved` - non-interactive implementation blocks before work starts.
175
-
176
- ## Provider Behavior
177
-
178
- | | Codex | Claude Code | Cursor / model-arg providers | Unsupported provider |
179
- | ----------------- | ----------------------------------------------------- | --------------------------------------- | ---------------------------- | -------------------- |
180
- | Managed mechanism | Materialized roles with explicit `model` and `effort` | Task `model` argument | Task/CLI `model` argument | None |
181
- | Axis | model plus effort (`low < medium < high < xhigh`) | model (`haiku < sonnet < opus < fable`) | opaque model slug | None |
182
- | Capped policy | materialized target selected up to cap | selected Task model up to cap | selected matrix cell | advisory/unsupported |
183
- | Uncapped | preferred materialized target, no cap | preferred Task model, no cap | preferred matrix cell | advisory/unsupported |
184
- | Inherit/default | base/unpinned role follows provider default | omit `model` | omit model selection | normal behavior |
185
-
186
- Codex uses materialized roles because per-call model/effort controls were
187
- unreliable in dogfooding. The resolver compiles an explicit model+effort target
188
- into a role name such as `oat-phase-implementer-gpt-5-6-terra-xhigh`, and the
189
- Codex spawn payload uses that role as `agent_type`. For managed `Uncapped`, OAT
190
- still selects the preferred materialized target. If the Codex preferred value is
191
- an effort rather than a matrix tier, OAT looks up the highest managed tier that
192
- compiles to that effort before resolving the matrix target; for example,
193
- `--preferred xhigh` resolves through the `frontier` matrix cell. The dispatching
194
- host should verify whether upward effort selection is actually honored in the
195
- current session. The old effort-only Codex pins are not the managed dispatch
196
- contract for new projects.
197
-
198
- Claude Code uses the per-call Task `model` argument. It has no OAT-managed
199
- per-dispatch effort axis, so dispatch logs use `effort_axis=not-applicable`.
200
- `Frontier` maps to Claude `fable`.
201
-
202
- Cursor and other model-arg providers use matrix values as opaque slugs. OAT
203
- validates availability with provider oracles when possible, but tier semantics
204
- come from the configured matrix, not from a built-in model catalog. For Cursor,
205
- that validation checks subagent Task eligibility, not just broad catalog
206
- visibility, because a slug can appear in `cursor-agent models` and still be
207
- rejected for subagent dispatch.
231
+ - top-level `source: invocation` for the ephemeral maximum
232
+ - `providers.<provider>.cellSource` for the config layer that owns the selected
233
+ candidate definition
234
+ - `selection.ceilingTier`, `selection.candidateTier`, and
235
+ `selection.requestedCandidate`
236
+ - the exact provider-specific `dispatchArgs`
208
237
 
209
- ## Producer Provenance
238
+ The resolver rejects a missing candidate, an above-ceiling candidate, an
239
+ ambiguous route, malformed ordering, a reviewer candidate request, or controls
240
+ that cannot compile exactly. The coordinator blocks instead of reusing its own
241
+ target, a base role, or a provider default.
210
242
 
211
- Dispatch notes use a parseable single-line stamp so later gates can identify
212
- the producer family:
243
+ `--preferred` remains available for legacy scalar ceilings and managed
244
+ `Uncapped` compatibility. It is not the exact managed task-worker selection
245
+ path.
213
246
 
214
- ```text
215
- Dispatch: scope=p06 action=implementation role=implementer producer=gpt-5.5-xhigh provenance=declared model_axis=selected:gpt-5.5-xhigh effort_axis=not-applicable dispatch_policy=high dispatch_ceiling=xhigh target=cursor
216
- ```
247
+ ## Provider Enforcement
217
248
 
218
- `producer` is the resolved model slug when OAT knows it, otherwise `unknown`.
219
- `provenance` is one of `declared`, `observed`, `inferred`, or `unknown`.
220
- Concrete same-harness model arguments can be declared. Codex materialized
221
- model+effort roles declare `model_axis=selected:<model>` and
222
- `effort_axis=selected:<effort>` from resolver output, but producer identity
223
- remains `unknown` unless an observed or inferred model identity is available.
249
+ | Provider | Exact task invocation | Failure behavior |
250
+ | -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
251
+ | Codex | Use `providers.codex.dispatchArgs.variant` as `agent_type`; otherwise launch a fresh child pinned to the returned model and effort | Block if neither exact route is usable |
252
+ | Claude | Pass `providers.claude.dispatchArgs.model` as the actual Task `model` | Block if the model cannot be applied |
253
+ | Cursor | Pass `providers.cursor.dispatchArgs.model` byte-for-byte as the actual invocation model; treat it as opaque | Block rather than normalize or substitute |
254
+ | Other | Use a registered provider adapter when it can compile exact controls | Unsupported providers remain advisory |
224
255
 
225
- ## Implementer, Fix, and Reviewer Behavior
256
+ Materialized Codex roles exist before task dispatch after project/user sync.
257
+ The supported catalogue is committed project output; custom Codex candidates
258
+ materialize according to config ownership. Workflow correctness still keeps a
259
+ fresh pinned-child fallback and does not require provider restart or hot reload.
226
260
 
227
- For implementer and fix dispatches:
261
+ Reviewers use the final candidate at the configured review ceiling. Managed
262
+ `Uncapped` and explicit inherit/default behavior retain their documented base
263
+ reviewer behavior. A timeout retry preserves the same exact role or complete
264
+ Claude/Cursor model payload.
228
265
 
229
- - Capped managed policies select `min(preferred, cap)`.
230
- - Managed `Uncapped` selects the preferred value without a cap.
231
- - Inherit/default mode returns no model/effort dispatch args.
266
+ ## Coordinator and Worker Layers
232
267
 
233
- For reviewer dispatches:
268
+ `oat-phase-implementer` has two explicit modes:
234
269
 
235
- - Capped managed policies target the configured cap for deterministic review
236
- quality gates.
237
- - Managed `Uncapped` has no reviewer cap, so OAT uses the base/unpinned reviewer
238
- fallback and logs provider-default behavior.
239
- - Inherit/default mode also uses the base/unpinned reviewer fallback.
270
+ 1. **Phase coordinator:** reads phase artifacts once, preserves dependency
271
+ order, selects one exact candidate per task, waits for each worker, verifies
272
+ its result and commit, then performs phase-wide integration review. It does
273
+ not implement ordinary tasks itself.
274
+ 2. **Task worker:** receives exactly one Task Scope with one task ID, file
275
+ boundary, verification commands, commit convention, and exact dispatch
276
+ payload. It implements and commits that task, then stops.
240
277
 
241
- Generic sidecars such as `explorer` are outside the implementer/reviewer/fix
242
- contract. If their payload does not pin a reliable provider control, logs should
243
- say `provider-default`.
278
+ Workers run serially in the same worktree. Parallelism remains limited to
279
+ plan-declared phase worktrees. See
280
+ [Implementation Execution](implementation-execution.md) for the full loop.
244
281
 
245
- ## Dispatch Logs
282
+ ## Producer Provenance
246
283
 
247
- Examples:
284
+ Dispatch notes retain a parseable stamp for later review gates:
248
285
 
249
286
  ```text
250
- Dispatch policy: balanced; selected=high; cap=high (codex, enforced — variant oat-phase-implementer-gpt-5-6-terra-high)
251
- Dispatch policy: high; selected=xhigh; cap=xhigh (codex, enforced — variant oat-reviewer-gpt-5-6-terra-xhigh)
252
- Dispatch policy: uncapped; selected=xhigh; cap=none (codex, enforced — variant oat-phase-implementer-gpt-5-6-sol-xhigh)
253
- Dispatch policy: inherit host defaults; selected=none; cap=none (codex, advisory — base role follows provider default)
254
- Dispatch policy: frontier; selected=fable; cap=fable (claude, enforced — Task model arg)
287
+ Dispatch: scope=p06-t03 action=implementation role=implementer producer=gpt-5.6-sol provenance=declared model_axis=selected:gpt-5.6-sol effort_axis=selected:high dispatch_policy=high dispatch_ceiling=high target=oat-phase-implementer-gpt-5-6-sol-high
255
288
  ```
256
289
 
257
- OAT logs `enforced` only when the provider accepted the requested control.
258
- Above-orchestrator Claude upgrade requests may require post-dispatch
259
- verification. Unsupported providers do not block; OAT records the policy as
260
- advisory/unsupported and dispatch follows provider behavior.
290
+ `producer` is the resolved model slug when OAT can establish it; otherwise it is
291
+ `unknown`. `provenance` is `declared`, `observed`, `inferred`, or `unknown`.
292
+ Concrete Claude/Cursor model arguments can declare identity. Codex roles retain
293
+ exact model and effort axes from resolver output even when producer identity is
294
+ not independently observable.
295
+
296
+ ## Legacy Compatibility
297
+
298
+ The following remain readable during migration:
299
+
300
+ - `workflow.dispatchCeiling.preset`
301
+ - bare `workflow.dispatchCeiling.providers.<provider>` values
302
+ - project `oat_dispatch_ceiling`
303
+ - `--preferred` resolver selection
304
+
305
+ Legacy preset names map to managed named tiers: `cost-conscious` to Economy,
306
+ `balanced` to Balanced, and `maximum` to High. Legacy values are migration
307
+ inputs, not evidence that a new project should persist exact provider-family
308
+ pins.