@open-agent-toolkit/cli 0.1.46 → 0.1.50

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 (98) 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 +213 -113
  5. package/assets/docs/cli-utilities/workflow-gates.md +178 -27
  6. package/assets/docs/contributing/skills.md +14 -8
  7. package/assets/docs/provider-sync/providers.md +46 -8
  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 +297 -197
  13. package/assets/docs/workflows/projects/implementation-execution.md +306 -249
  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 +290 -149
  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 +110 -22
  25. package/assets/skills/oat-project-review-provide-remote/SKILL.md +28 -1
  26. package/dist/commands/config/index.d.ts +3 -0
  27. package/dist/commands/config/index.d.ts.map +1 -1
  28. package/dist/commands/config/index.js +92 -125
  29. package/dist/commands/doctor/index.d.ts +3 -0
  30. package/dist/commands/doctor/index.d.ts.map +1 -1
  31. package/dist/commands/doctor/index.js +57 -95
  32. package/dist/commands/gate/index.d.ts +7 -1
  33. package/dist/commands/gate/index.d.ts.map +1 -1
  34. package/dist/commands/gate/index.js +615 -67
  35. package/dist/commands/gate/review-verdict.d.ts +16 -0
  36. package/dist/commands/gate/review-verdict.d.ts.map +1 -1
  37. package/dist/commands/gate/review-verdict.js +72 -9
  38. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  39. package/dist/commands/project/dispatch-ceiling/index.js +567 -99
  40. package/dist/commands/providers/codex/materialize.d.ts.map +1 -1
  41. package/dist/commands/providers/codex/materialize.js +6 -1
  42. package/dist/commands/shared/frontmatter.d.ts +4 -0
  43. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  44. package/dist/commands/shared/frontmatter.js +23 -0
  45. package/dist/commands/status/index.d.ts +1 -0
  46. package/dist/commands/status/index.d.ts.map +1 -1
  47. package/dist/commands/status/index.js +10 -4
  48. package/dist/commands/sync/index.d.ts.map +1 -1
  49. package/dist/commands/sync/index.js +10 -3
  50. package/dist/commands/sync/sync.types.d.ts +1 -0
  51. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  52. package/dist/config/dispatch-matrix.d.ts +59 -0
  53. package/dist/config/dispatch-matrix.d.ts.map +1 -0
  54. package/dist/config/dispatch-matrix.js +264 -0
  55. package/dist/config/oat-config.d.ts +9 -18
  56. package/dist/config/oat-config.d.ts.map +1 -1
  57. package/dist/config/oat-config.js +99 -120
  58. package/dist/config/resolve.d.ts +8 -0
  59. package/dist/config/resolve.d.ts.map +1 -1
  60. package/dist/config/resolve.js +66 -1
  61. package/dist/engine/index.d.ts +1 -1
  62. package/dist/engine/index.d.ts.map +1 -1
  63. package/dist/engine/index.js +1 -1
  64. package/dist/engine/scanner.d.ts +1 -0
  65. package/dist/engine/scanner.d.ts.map +1 -1
  66. package/dist/engine/scanner.js +17 -1
  67. package/dist/fs/paths.d.ts +4 -0
  68. package/dist/fs/paths.d.ts.map +1 -1
  69. package/dist/fs/paths.js +18 -1
  70. package/dist/providers/ceiling/registry.d.ts +1 -0
  71. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  72. package/dist/providers/ceiling/registry.js +12 -5
  73. package/dist/providers/codex/codec/catalog.d.ts +14 -0
  74. package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
  75. package/dist/providers/codex/codec/catalog.js +21 -0
  76. package/dist/providers/codex/codec/materialize.d.ts.map +1 -1
  77. package/dist/providers/codex/codec/materialize.js +6 -5
  78. package/dist/providers/codex/codec/shared.d.ts +19 -0
  79. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  80. package/dist/providers/codex/codec/shared.js +98 -5
  81. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  82. package/dist/providers/codex/codec/sync-extension.js +142 -32
  83. package/dist/providers/identity/availability.d.ts +12 -0
  84. package/dist/providers/identity/availability.d.ts.map +1 -1
  85. package/dist/providers/identity/availability.js +72 -29
  86. package/dist/providers/identity/dispatch-report.d.ts +124 -0
  87. package/dist/providers/identity/dispatch-report.d.ts.map +1 -0
  88. package/dist/providers/identity/dispatch-report.js +285 -0
  89. package/dist/providers/identity/dispatch-validation.d.ts +28 -0
  90. package/dist/providers/identity/dispatch-validation.d.ts.map +1 -0
  91. package/dist/providers/identity/dispatch-validation.js +149 -0
  92. package/dist/providers/identity/stamp.d.ts +2 -0
  93. package/dist/providers/identity/stamp.d.ts.map +1 -1
  94. package/dist/providers/identity/stamp.js +7 -1
  95. package/dist/shared/types.d.ts +1 -0
  96. package/dist/shared/types.d.ts.map +1 -1
  97. package/dist/shared/types.js +4 -0
  98. 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,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,205 @@ 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
- ```
113
-
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
- }
137
- ```
138
-
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:
184
+ Planning and implementation preflight resolve the active policy first:
147
185
 
148
186
  ```bash
149
- oat project dispatch-ceiling resolve --provider <provider> --role <implementer|reviewer> --json
187
+ oat project dispatch-ceiling resolve \
188
+ --provider codex \
189
+ --preflight \
190
+ --json
150
191
  ```
151
192
 
152
- For implementer or fix dispatch, pass the preferred runtime control:
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:
153
197
 
154
198
  ```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
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
158
223
  ```
159
224
 
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.
208
-
209
- ## Producer Provenance
210
-
211
- Dispatch notes use a parseable single-line stamp so later gates can identify
212
- the producer family:
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.
228
+
229
+ Successful JSON reports:
230
+
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`
237
+
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.
242
+
243
+ `--preferred` remains available for legacy scalar ceilings and managed
244
+ `Uncapped` compatibility. It is not the exact managed task-worker selection
245
+ path.
246
+
247
+ ## Provider Enforcement
248
+
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 |
255
+
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.
260
+
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.
265
+
266
+ ### Cursor evidence authority
267
+
268
+ Cursor resolution and runtime evidence answer different questions. Resolution
269
+ proves which opaque candidate OAT requested. A stream-JSON Task start and
270
+ correlated completion prove launcher behavior only when the model argument is
271
+ preserved byte-for-byte. An accepted Task plus the child sentinel establishes
272
+ argument eligibility for that account and client; a structured rejection can
273
+ establish `unknown-value`. Runtime producer identity remains `not-reported`
274
+ unless trusted Cursor telemetry or Cursor support independently confirms it.
275
+
276
+ The [2026-07-11 GPT-5.6 evidence record](https://github.com/voxmedia/open-agent-toolkit/blob/main/.oat/repo/reference/project-summaries/20260711-cursor-gpt-5-6-subagent-verification.md)
277
+ ran positive and negative controls before candidate probes. Neither control
278
+ emitted a Task event, so the harness stopped without probing the 13 recommended
279
+ arguments or exploratory `gpt-5.6-sol-high-fast`. This is a harness/account
280
+ boundary, not model rejection, and it supports no recommendation change.
281
+
282
+ The tracked artifact's structured second-pass block exposes only an allowlisted
283
+ event projection and non-reversible identifier hashes. Exact
284
+ request/session/tool-call IDs and credential-redacted unprojected streams from
285
+ that pass stay in gitignored local project storage for support diagnosis.
286
+
287
+ The same public artifact intentionally preserves the sanitized historical v1
288
+ text-mode record for provenance. That older section includes command arguments
289
+ and prompts, stdout and stderr, exit and duration data, and capture-environment
290
+ details such as user-specific binary paths; it is not limited to the structured
291
+ second-pass projection.
292
+
293
+ ## Coordinator and Worker Layers
294
+
295
+ `oat-phase-implementer` has two explicit modes:
296
+
297
+ 1. **Phase coordinator:** reads phase artifacts once, preserves dependency
298
+ order, selects one exact candidate per task, waits for each worker, verifies
299
+ its result and commit, then performs phase-wide integration review. It does
300
+ not implement ordinary tasks itself.
301
+ 2. **Task worker:** receives exactly one Task Scope with one task ID, file
302
+ boundary, verification commands, commit convention, and exact dispatch
303
+ payload. It implements and commits that task, then stops.
304
+
305
+ Workers run serially in the same worktree. Parallelism remains limited to
306
+ plan-declared phase worktrees. See
307
+ [Implementation Execution](implementation-execution.md) for the full loop.
308
+
309
+ ## Dispatch Report V1 and Producer Provenance
310
+
311
+ Resolver calls that pass `--report-scope` and `--report-action` include a
312
+ `dispatchReport` object in JSON output. Consumers must require
313
+ `dispatchReport.schemaVersion: 1` before dispatch. The report keeps four
314
+ different decisions separate:
315
+
316
+ | Report area | What it means |
317
+ | ------------------------------------------------------------------- | -------------------------------------------------------------------- |
318
+ | `policy` | The resolved managed/inherit policy, its status, name, and source |
319
+ | `selection.ceilingTier` / `selection.ceilingTarget` | The maximum allowed tier and its boundary target |
320
+ | `selection.requestedCandidate` / `candidateTier` / `candidateIndex` | The exact candidate requested for this bounded task and its position |
321
+ | `selection.exactSelectedTarget` / `route.target` | The compiled provider target and actual invocation route |
322
+
323
+ A named policy or ceiling is never a substitute for the requested candidate or
324
+ exact selected target. `requestedControls` records what OAT put into the host
325
+ payload. `configuredDefaults` records fallback configuration and is explicitly
326
+ not a runtime observation.
327
+
328
+ `gateInvocation` is an immutable copy of configured gate controls.
329
+ `runtimeIdentity` is separate and stays `not-reported` until independently
330
+ observed or otherwise supported runtime evidence exists. Requested controls,
331
+ configured defaults, role-name parsing, and reviewer self-identification do not
332
+ become observed runtime identity.
333
+
334
+ Human output comes from `formatDispatchReport(dispatchReport)`. Dispatch notes
335
+ also retain a parseable compatibility stamp for later review gates:
213
336
 
214
337
  ```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
338
+ 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
216
339
  ```
217
340
 
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.
224
-
225
- ## Implementer, Fix, and Reviewer Behavior
226
-
227
- For implementer and fix dispatches:
228
-
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.
341
+ The stamp must be derived through `toDispatchStampRecord(dispatchReport)` and
342
+ `formatDispatchStamp`; callers must not reconstruct it from policy labels, role
343
+ names, candidate strings, or target names. `producer` is the runtime model slug
344
+ when OAT can establish it; otherwise it is `unknown`. `provenance` is
345
+ `declared`, `observed`, `inferred`, or `unknown`. Selected model and effort axes
346
+ can remain exact even when runtime producer identity is not reported.
232
347
 
233
- For reviewer dispatches:
348
+ ## Legacy Compatibility
234
349
 
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.
350
+ The following remain readable during migration:
240
351
 
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`.
244
-
245
- ## Dispatch Logs
246
-
247
- Examples:
248
-
249
- ```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)
255
- ```
256
-
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.
352
+ - `workflow.dispatchCeiling.preset`
353
+ - bare `workflow.dispatchCeiling.providers.<provider>` values
354
+ - project `oat_dispatch_ceiling`
355
+ - `--preferred` resolver selection
356
+
357
+ Legacy preset names map to managed named tiers: `cost-conscious` to Economy,
358
+ `balanced` to Balanced, and `maximum` to High. Legacy values are migration
359
+ inputs, not evidence that a new project should persist exact provider-family
360
+ pins.