@open-agent-toolkit/cli 0.1.45 → 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 (112) hide show
  1. package/assets/agents/oat-phase-implementer.md +202 -191
  2. package/assets/agents/oat-reviewer.md +12 -2
  3. package/assets/config/dispatch-matrix-recommendation.json +120 -13
  4. package/assets/docs/cli-utilities/config-and-local-state.md +7 -0
  5. package/assets/docs/cli-utilities/configuration.md +183 -84
  6. package/assets/docs/cli-utilities/workflow-gates.md +161 -27
  7. package/assets/docs/contributing/skills.md +14 -8
  8. package/assets/docs/provider-sync/config.md +5 -1
  9. package/assets/docs/provider-sync/manifest-and-drift.md +6 -1
  10. package/assets/docs/provider-sync/providers.md +42 -5
  11. package/assets/docs/provider-sync/scope-and-surface.md +3 -2
  12. package/assets/docs/reference/cli-reference.md +3 -1
  13. package/assets/docs/reference/oat-directory-structure.md +27 -26
  14. package/assets/docs/workflows/projects/artifacts.md +31 -1
  15. package/assets/docs/workflows/projects/dispatch-ceiling.md +235 -174
  16. package/assets/docs/workflows/projects/implementation-execution.md +283 -253
  17. package/assets/docs/workflows/projects/lifecycle.md +26 -5
  18. package/assets/docs/workflows/projects/reviews.md +27 -2
  19. package/assets/migration/pjm-restructure.md +1 -1
  20. package/assets/public-package-versions.json +4 -4
  21. package/assets/skills/oat-project-implement/SKILL.md +347 -178
  22. package/assets/skills/oat-project-import-plan/SKILL.md +173 -16
  23. package/assets/skills/oat-project-next/SKILL.md +2 -2
  24. package/assets/skills/oat-project-plan/SKILL.md +122 -92
  25. package/assets/skills/oat-project-plan-writing/SKILL.md +246 -15
  26. package/assets/skills/oat-project-quick-start/SKILL.md +156 -94
  27. package/assets/skills/oat-project-review-provide/SKILL.md +94 -22
  28. package/dist/commands/config/index.d.ts +2 -2
  29. package/dist/commands/config/index.d.ts.map +1 -1
  30. package/dist/commands/config/index.js +129 -53
  31. package/dist/commands/doctor/index.d.ts +2 -2
  32. package/dist/commands/doctor/index.d.ts.map +1 -1
  33. package/dist/commands/doctor/index.js +102 -31
  34. package/dist/commands/gate/index.d.ts +7 -1
  35. package/dist/commands/gate/index.d.ts.map +1 -1
  36. package/dist/commands/gate/index.js +544 -67
  37. package/dist/commands/gate/review-verdict.d.ts +16 -0
  38. package/dist/commands/gate/review-verdict.d.ts.map +1 -1
  39. package/dist/commands/gate/review-verdict.js +72 -9
  40. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  41. package/dist/commands/project/dispatch-ceiling/index.js +586 -23
  42. package/dist/commands/providers/codex/index.d.ts +4 -0
  43. package/dist/commands/providers/codex/index.d.ts.map +1 -0
  44. package/dist/commands/providers/codex/index.js +7 -0
  45. package/dist/commands/providers/codex/materialize.d.ts +5 -0
  46. package/dist/commands/providers/codex/materialize.d.ts.map +1 -0
  47. package/dist/commands/providers/codex/materialize.js +157 -0
  48. package/dist/commands/providers/index.d.ts +2 -2
  49. package/dist/commands/providers/index.d.ts.map +1 -1
  50. package/dist/commands/providers/index.js +4 -2
  51. package/dist/commands/providers/providers.types.d.ts +23 -0
  52. package/dist/commands/providers/providers.types.d.ts.map +1 -1
  53. package/dist/commands/shared/codex-strays.d.ts.map +1 -1
  54. package/dist/commands/shared/codex-strays.js +11 -1
  55. package/dist/commands/shared/frontmatter.d.ts +4 -0
  56. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  57. package/dist/commands/shared/frontmatter.js +23 -0
  58. package/dist/commands/status/index.d.ts +5 -1
  59. package/dist/commands/status/index.d.ts.map +1 -1
  60. package/dist/commands/status/index.js +10 -4
  61. package/dist/commands/sync/index.d.ts.map +1 -1
  62. package/dist/commands/sync/index.js +10 -3
  63. package/dist/commands/sync/sync.types.d.ts +5 -1
  64. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  65. package/dist/config/dispatch-ceiling-preset.d.ts +4 -0
  66. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  67. package/dist/config/dispatch-ceiling-preset.js +3 -0
  68. package/dist/config/dispatch-policy-options.d.ts +20 -0
  69. package/dist/config/dispatch-policy-options.d.ts.map +1 -0
  70. package/dist/config/dispatch-policy-options.js +96 -0
  71. package/dist/config/oat-config.d.ts +25 -2
  72. package/dist/config/oat-config.d.ts.map +1 -1
  73. package/dist/config/oat-config.js +154 -24
  74. package/dist/config/resolve.d.ts +8 -0
  75. package/dist/config/resolve.d.ts.map +1 -1
  76. package/dist/config/resolve.js +66 -2
  77. package/dist/engine/index.d.ts +1 -1
  78. package/dist/engine/index.d.ts.map +1 -1
  79. package/dist/engine/index.js +1 -1
  80. package/dist/engine/scanner.d.ts +1 -0
  81. package/dist/engine/scanner.d.ts.map +1 -1
  82. package/dist/engine/scanner.js +17 -1
  83. package/dist/fs/paths.d.ts +4 -0
  84. package/dist/fs/paths.d.ts.map +1 -1
  85. package/dist/fs/paths.js +18 -1
  86. package/dist/providers/ceiling/registry.d.ts +8 -5
  87. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  88. package/dist/providers/ceiling/registry.js +25 -7
  89. package/dist/providers/codex/codec/catalog.d.ts +14 -0
  90. package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
  91. package/dist/providers/codex/codec/catalog.js +21 -0
  92. package/dist/providers/codex/codec/config-merge.d.ts +6 -0
  93. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  94. package/dist/providers/codex/codec/config-merge.js +7 -0
  95. package/dist/providers/codex/codec/materialize.d.ts +16 -0
  96. package/dist/providers/codex/codec/materialize.d.ts.map +1 -0
  97. package/dist/providers/codex/codec/materialize.js +58 -0
  98. package/dist/providers/codex/codec/shared.d.ts +20 -0
  99. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  100. package/dist/providers/codex/codec/shared.js +107 -6
  101. package/dist/providers/codex/codec/sync-extension.d.ts +7 -1
  102. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  103. package/dist/providers/codex/codec/sync-extension.js +299 -52
  104. package/dist/providers/identity/availability.d.ts +24 -1
  105. package/dist/providers/identity/availability.d.ts.map +1 -1
  106. package/dist/providers/identity/availability.js +253 -19
  107. package/dist/providers/identity/stamp.d.ts.map +1 -1
  108. package/dist/providers/identity/stamp.js +4 -0
  109. package/dist/shared/types.d.ts +1 -0
  110. package/dist/shared/types.d.ts.map +1 -1
  111. package/dist/shared/types.js +4 -0
  112. package/package.json +2 -2
@@ -31,6 +31,28 @@ Mode-sensitive notes:
31
31
  - `references/imported-plan.md`: preserved source plan for import mode
32
32
  - `references/split-plan.json`: persisted split plan for a coordination parent, used as the durable resume source when `oat-project-split` is interrupted
33
33
 
34
+ ### Gate review frontmatter
35
+
36
+ Review artifacts produced by `oat gate review` use the normal review fields plus
37
+ an exact copy of the gate-owned configured invocation:
38
+
39
+ ```yaml
40
+ oat_review_invocation: gate
41
+ oat_project: .oat/projects/shared/example
42
+ oat_gate_run_id: 00000000-0000-0000-0000-000000000000
43
+ oat_gate_target: codex-sol-max
44
+ oat_gate_runtime: codex
45
+ oat_invocation_model: gpt-5.6-sol
46
+ oat_invocation_reasoning_effort: max
47
+ oat_invocation_source: exec-target-config
48
+ ```
49
+
50
+ `oat_invocation_model` and `oat_invocation_reasoning_effort` may be
51
+ `provider-default` when OAT deliberately leaves a control to the provider, or
52
+ `unknown` when the target does not declare it. These fields are configured
53
+ invocation metadata, not runtime-confirmed or self-reported model identity.
54
+ Manual and auto review artifacts do not require the gate-only fields.
55
+
34
56
  ## Contract
35
57
 
36
58
  Artifacts are the project system of record; automation and routing should derive from these files, not memory.
@@ -75,7 +97,7 @@ Each inner array is a group of phases that execute concurrently in their own wor
75
97
  - Each group must contain **2 or more** phases — singleton groups are rejected.
76
98
  - Every phase ID must exist in the plan body.
77
99
  - No phase may appear in more than one group.
78
- - Parallelism is only honored at Tier 1 (native subagents). Tier 2 degrades parallel groups to sequential inline execution.
100
+ - Parallelism is only honored at Tier 1 (native subagents). Tier 2 degrades parallel groups to sequential target-preserving execution, not unconditional inline review. Concrete managed Claude and Cursor reviewers retain the exact resolver-returned `dispatchArgs.model` in the actual invocation and every retry; Codex retains its exact role or pinned child. Inline review requires verified equivalent host controls or an explicit inherit/default or managed-uncapped base-role exception, and otherwise blocks.
79
101
 
80
102
  **Authoring responsibility:**
81
103
 
@@ -90,6 +112,14 @@ Before dispatching, `oat-project-implement` invokes `oat project validate-plan -
90
112
 
91
113
  Enable an optional, non-pausing external review gate that runs after each selected phase's standard reviewer passes and its bookkeeping is committed:
92
114
 
115
+ Planning offers this setting after stable phase IDs exist and before the plan
116
+ artifact review. The read-only target probe qualifies only an explicitly
117
+ configured, enabled, and available target, then offers all phases, selected
118
+ phases, or disabled. An explicit `oat_phase_review_gate` value from a resumed or
119
+ imported plan is preserved unchanged without re-prompting. If the probe fails,
120
+ no target qualifies, the run is non-interactive, or the user declines, planning
121
+ leaves phase review disabled.
122
+
93
123
  ```yaml
94
124
  oat_phase_review_gate:
95
125
  enabled: true
@@ -1,76 +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 target | 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`.
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.
43
45
 
44
- ## Config Shapes
46
+ ## Ownership and Adoption
45
47
 
46
- Preferred managed policy config:
48
+ Adopt the complete bundled recommendation into one explicit owning scope:
47
49
 
48
50
  ```bash
49
- oat config set workflow.dispatchPolicy.policy balanced --shared
50
- oat config set workflow.dispatchPolicy.policy frontier --shared
51
- 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
52
59
  ```
53
60
 
54
- `workflow.dispatchPolicy.policy` writes `workflow.dispatchPolicy.mode=managed`.
55
- 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.
56
66
 
57
- ```bash
58
- 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
+ }
59
131
  ```
60
132
 
61
- 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:
62
138
 
63
139
  ```yaml
64
140
  oat_dispatch_policy:
65
141
  mode: managed
66
- policy: balanced
67
- providers:
68
- codex: high
69
- claude: sonnet
142
+ policy: high
70
143
  source: project-state
71
144
  ```
72
145
 
73
- 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:
74
151
 
75
152
  ```yaml
76
153
  oat_dispatch_policy:
@@ -79,169 +156,153 @@ oat_dispatch_policy:
79
156
  source: project-state
80
157
  ```
81
158
 
82
- For host defaults:
83
-
84
159
  ```yaml
85
160
  oat_dispatch_policy:
86
161
  mode: inherit
87
162
  source: project-state
88
163
  ```
89
164
 
90
- Legacy compatibility keys remain readable:
165
+ ## Complete Bundled Recommendation
91
166
 
92
- - `workflow.dispatchCeiling.preset`
93
- - `workflow.dispatchCeiling.providers.<provider>`
94
- - `workflow.dispatchCeiling.providers.<provider>.<tier>`
95
- - `oat_dispatch_ceiling`
167
+ The bundled ladder contains every supported candidate, not only the final
168
+ candidate in each tier:
96
169
 
97
- Legacy preset names map into the managed ladder: `cost-conscious` maps to
98
- `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.
99
177
 
100
- ## 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.
101
181
 
102
- The dispatch matrix maps the abstract policy rung (`economy`, `balanced`,
103
- `high`, `frontier`) to concrete provider controls. Existing bare Codex and
104
- Claude values remain valid, and multi-family providers can use tier cells:
182
+ ## Exact Task Resolution
105
183
 
106
- ```bash
107
- oat config adopt dispatch-matrix --shared
108
- oat config set workflow.dispatchCeiling.providers.cursor.balanced composer-2.5 --shared
109
- oat config set workflow.dispatchCeiling.providers.cursor.high gpt-5.5-xhigh --shared
110
- ```
184
+ Planning and implementation preflight resolve the active policy first:
111
185
 
112
- For ordered escalation, write a route in config JSON. The resolver selects the
113
- floor entry at escalation level `0` and advances by route entry when the
114
- implementation/fix loop escalates:
115
-
116
- ```json
117
- {
118
- "workflow": {
119
- "dispatchCeiling": {
120
- "providers": {
121
- "cursor": {
122
- "high": [
123
- "composer-2.5",
124
- { "harness": "cursor", "model": "gpt-5.5-xhigh" }
125
- ],
126
- "frontier": [
127
- { "harness": "cursor", "model": "gpt-5.5-xhigh" },
128
- { "harness": "cursor", "model": "fable-5" }
129
- ]
130
- }
131
- }
132
- }
133
- }
134
- }
186
+ ```bash
187
+ oat project dispatch-ceiling resolve \
188
+ --provider codex \
189
+ --preflight \
190
+ --json
135
191
  ```
136
192
 
137
- Project `state.md` may carry only sparse project-specific matrix overrides
138
- under `oat_dispatch_policy.matrix`. The full reusable matrix belongs in user,
139
- shared, or local config so switching harnesses mid-project re-resolves the same
140
- abstract policy through the active provider column.
141
-
142
- ## How Resolution Works
143
-
144
- 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:
145
197
 
146
198
  ```bash
147
- 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
148
223
  ```
149
224
 
150
- 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.
151
228
 
152
- ```bash
153
- oat project dispatch-ceiling resolve --provider codex --role implementer --preferred high --json
154
- oat project dispatch-ceiling resolve --provider claude --role implementer --preferred opus --json
155
- oat project dispatch-ceiling resolve --provider cursor --role implementer --preferred high --escalation-level 0 --json
156
- ```
229
+ Successful JSON reports:
157
230
 
158
- The resolver returns the resolved policy, optional cap, source, provider default
159
- effort where applicable, and provider-specific `dispatchArgs`.
160
-
161
- Selection modes:
162
-
163
- - `capped` - implementer/fix dispatch selects `min(preferred, cap)`.
164
- - `uncapped` - implementer/fix dispatch selects the preferred value.
165
- - `matrix-pinned` - a matrix cell supplied the selected provider value.
166
- - `prompt-persisted` - an interactive prompt filled a missing cell and persisted it.
167
- - `escalation-target` - an ordered route entry supplied the selected target.
168
- - `review-target` - reviewer dispatch targets a configured cap when one exists.
169
- - `no-review-target` - managed uncapped reviewer dispatch has no configured
170
- target and falls back to the base/unpinned reviewer.
171
- - `inherit-default` - OAT returns no dispatch args and leaves controls to the host.
172
- - `unresolved` - non-interactive implementation blocks before work starts.
173
-
174
- ## Provider Behavior
175
-
176
- | | Codex | Claude Code | Cursor / model-arg providers | Unsupported provider |
177
- | ----------------- | ------------------------------------------- | --------------------------------------- | ---------------------------- | -------------------- |
178
- | Managed mechanism | Pinned role variants | Task `model` argument | `--model` argument | None |
179
- | Axis | effort (`low < medium < high < xhigh`) | model (`haiku < sonnet < opus < fable`) | opaque model slug | None |
180
- | Capped policy | selected pinned variant up to cap | selected Task model up to cap | selected matrix cell | advisory/unsupported |
181
- | Uncapped | preferred pinned variant, no cap | preferred Task model, no cap | preferred matrix cell | advisory/unsupported |
182
- | Inherit/default | base/unpinned role follows provider default | omit `model` | omit `--model` | normal behavior |
183
-
184
- Codex uses pinned variants because per-call effort controls were unreliable in
185
- dogfooding. For managed `Uncapped`, OAT still selects the preferred pinned
186
- variant; the dispatching host should verify whether upward effort selection is
187
- actually honored in the current session.
188
-
189
- Claude Code uses the per-call Task `model` argument. It has no OAT-managed
190
- per-dispatch effort axis, so dispatch logs use `effort_axis=not-applicable`.
191
- `Frontier` maps to Claude `fable`.
192
-
193
- Cursor and other model-arg providers use matrix values as opaque slugs. OAT
194
- validates availability with provider oracles when possible, but tier semantics
195
- come from the configured matrix, not from a built-in model catalog.
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`
196
237
 
197
- ## 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.
198
242
 
199
- Dispatch notes use a parseable single-line stamp so later gates can identify
200
- 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.
201
246
 
202
- ```text
203
- 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
204
- ```
247
+ ## Provider Enforcement
205
248
 
206
- `producer` is the resolved model slug when OAT knows it, otherwise `unknown`.
207
- `provenance` is one of `declared`, `observed`, `inferred`, or `unknown`.
208
- Concrete same-harness model arguments can be declared. Codex pinned effort
209
- variants declare effort, not concrete producer identity, unless an observed or
210
- inferred model 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 |
211
255
 
212
- ## 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.
213
260
 
214
- 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.
215
265
 
216
- - Capped managed policies select `min(preferred, cap)`.
217
- - Managed `Uncapped` selects the preferred value without a cap.
218
- - Inherit/default mode returns no model/effort dispatch args.
266
+ ## Coordinator and Worker Layers
219
267
 
220
- For reviewer dispatches:
268
+ `oat-phase-implementer` has two explicit modes:
221
269
 
222
- - Capped managed policies target the configured cap for deterministic review
223
- quality gates.
224
- - Managed `Uncapped` has no reviewer cap, so OAT uses the base/unpinned reviewer
225
- fallback and logs provider-default behavior.
226
- - 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.
227
277
 
228
- Generic sidecars such as `explorer` are outside the implementer/reviewer/fix
229
- contract. If their payload does not pin a reliable provider control, logs should
230
- 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.
231
281
 
232
- ## Dispatch Logs
282
+ ## Producer Provenance
233
283
 
234
- Examples:
284
+ Dispatch notes retain a parseable stamp for later review gates:
235
285
 
236
286
  ```text
237
- Dispatch policy: balanced; selected=high; cap=high (codex, enforced — variant oat-phase-implementer-high)
238
- Dispatch policy: high; selected=xhigh; cap=xhigh (codex, enforced — variant oat-reviewer-xhigh)
239
- Dispatch policy: uncapped; selected=xhigh; cap=none (codex, enforced — variant oat-phase-implementer-xhigh)
240
- Dispatch policy: inherit host defaults; selected=none; cap=none (codex, advisory — base role follows provider default)
241
- 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
242
288
  ```
243
289
 
244
- OAT logs `enforced` only when the provider accepted the requested control.
245
- Above-orchestrator Claude upgrade requests may require post-dispatch
246
- verification. Unsupported providers do not block; OAT records the policy as
247
- 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.