@open-agent-toolkit/cli 0.1.43 → 0.1.45

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 (47) hide show
  1. package/assets/config/dispatch-matrix-recommendation.json +23 -0
  2. package/assets/docs/cli-utilities/configuration.md +59 -20
  3. package/assets/docs/cli-utilities/workflow-gates.md +79 -16
  4. package/assets/docs/contributing/code.md +10 -4
  5. package/assets/docs/contributing/hooks-and-safety.md +23 -0
  6. package/assets/docs/workflows/projects/dispatch-ceiling.md +80 -10
  7. package/assets/public-package-versions.json +4 -4
  8. package/assets/skills/oat-project-implement/SKILL.md +53 -11
  9. package/assets/skills/oat-project-plan/SKILL.md +22 -3
  10. package/assets/skills/oat-project-quick-start/SKILL.md +22 -3
  11. package/assets/templates/state.md +5 -0
  12. package/dist/commands/config/index.d.ts +6 -0
  13. package/dist/commands/config/index.d.ts.map +1 -1
  14. package/dist/commands/config/index.js +366 -8
  15. package/dist/commands/doctor/index.d.ts +6 -1
  16. package/dist/commands/doctor/index.d.ts.map +1 -1
  17. package/dist/commands/doctor/index.js +138 -4
  18. package/dist/commands/gate/index.d.ts +39 -2
  19. package/dist/commands/gate/index.d.ts.map +1 -1
  20. package/dist/commands/gate/index.js +343 -30
  21. package/dist/commands/internal/cursor-current-target.d.ts +37 -0
  22. package/dist/commands/internal/cursor-current-target.d.ts.map +1 -0
  23. package/dist/commands/internal/cursor-current-target.js +228 -0
  24. package/dist/commands/internal/index.d.ts.map +1 -1
  25. package/dist/commands/internal/index.js +2 -0
  26. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  27. package/dist/commands/project/dispatch-ceiling/index.js +359 -16
  28. package/dist/config/oat-config.d.ts +15 -5
  29. package/dist/config/oat-config.d.ts.map +1 -1
  30. package/dist/config/oat-config.js +103 -10
  31. package/dist/config/resolve.js +12 -0
  32. package/dist/manifest/manifest.types.d.ts +12 -12
  33. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  34. package/dist/providers/ceiling/registry.js +16 -0
  35. package/dist/providers/identity/availability.d.ts +22 -0
  36. package/dist/providers/identity/availability.d.ts.map +1 -0
  37. package/dist/providers/identity/availability.js +119 -0
  38. package/dist/providers/identity/family.d.ts +13 -0
  39. package/dist/providers/identity/family.d.ts.map +1 -0
  40. package/dist/providers/identity/family.js +32 -0
  41. package/dist/providers/identity/provenance.d.ts +21 -0
  42. package/dist/providers/identity/provenance.d.ts.map +1 -0
  43. package/dist/providers/identity/provenance.js +65 -0
  44. package/dist/providers/identity/stamp.d.ts +35 -0
  45. package/dist/providers/identity/stamp.d.ts.map +1 -0
  46. package/dist/providers/identity/stamp.js +171 -0
  47. package/package.json +2 -2
@@ -0,0 +1,23 @@
1
+ {
2
+ "version": "2026-07-07.1",
3
+ "providers": {
4
+ "codex": {
5
+ "economy": "low",
6
+ "balanced": "medium",
7
+ "high": "high",
8
+ "frontier": "xhigh"
9
+ },
10
+ "claude": {
11
+ "economy": "haiku",
12
+ "balanced": "sonnet",
13
+ "high": "opus",
14
+ "frontier": "fable"
15
+ },
16
+ "cursor": {
17
+ "economy": "composer-2.5",
18
+ "balanced": "composer-2.5-fast",
19
+ "high": "gpt-5.5-high",
20
+ "frontier": "fable-5"
21
+ }
22
+ }
23
+ }
@@ -173,8 +173,8 @@ oat config describe activeIdea
173
173
  Dispatch policy is the workflow setting that tells OAT whether to manage
174
174
  subagent model/effort selection and, if so, which managed policy to use.
175
175
 
176
- For the full conceptual model - managed capped tiers, managed `Uncapped`,
177
- `Inherit Host Defaults`, and provider-specific enforcement - see
176
+ For the full conceptual model - managed capped tiers, dispatch matrix cells,
177
+ managed `Uncapped`, `Inherit Host Defaults`, and provider-specific enforcement - see
178
178
  [Dispatch Policy](../workflows/projects/dispatch-ceiling.md).
179
179
 
180
180
  ### Config keys
@@ -196,13 +196,44 @@ Managed policies compile to:
196
196
  | `frontier` | `xhigh` | `fable` |
197
197
  | `uncapped` | none | none |
198
198
 
199
- Legacy compatibility keys remain supported for capped managed behavior:
199
+ Dispatch matrix and legacy compatibility keys:
200
200
 
201
- | Key | Values | Purpose |
202
- | ------------------------------------------- | --------------------------------------- | ---------------------------------------------------------------------------- |
203
- | `workflow.dispatchCeiling.preset` | `balanced`, `maximum`, `cost-conscious` | Legacy preset alias; `maximum` maps to `high`, `cost-conscious` to `economy` |
204
- | `workflow.dispatchCeiling.providers.codex` | `low`, `medium`, `high`, `xhigh` | Legacy concrete Codex capped target |
205
- | `workflow.dispatchCeiling.providers.claude` | `haiku`, `sonnet`, `opus`, `fable` | Legacy concrete Claude capped target |
201
+ | Key | Values | Purpose |
202
+ | ------------------------------------------------------ | --------------------------------------- | -------------------------------------------------------------------------------------- |
203
+ | `workflow.dispatchCeiling.preset` | `balanced`, `maximum`, `cost-conscious` | Legacy preset alias; `maximum` maps to `high`, `cost-conscious` to `economy` |
204
+ | `workflow.dispatchCeiling.providers.<provider>` | bare value or tier map | Provider column; bare Codex/Claude values remain legacy capped targets |
205
+ | `workflow.dispatchCeiling.providers.<provider>.<tier>` | bare value or ordered route | One matrix cell for `economy`, `balanced`, `high`, or `frontier` |
206
+ | `workflow.dispatchCeiling.recommendationVersion` | string | Version stamp written by `oat config adopt dispatch-matrix`; used for drift visibility |
207
+
208
+ Examples:
209
+
210
+ ```bash
211
+ oat config adopt dispatch-matrix --shared
212
+ oat config set workflow.dispatchCeiling.providers.cursor.balanced composer-2.5 --shared
213
+ oat config set workflow.dispatchCeiling.providers.codex high --shared
214
+ oat config set workflow.dispatchCeiling.providers.claude opus --shared
215
+ ```
216
+
217
+ For ordered routes, edit the config JSON so a tier cell is an array. Route
218
+ entries are either bare slugs or objects with `harness`, `model`, and optional
219
+ `effort`:
220
+
221
+ ```json
222
+ {
223
+ "workflow": {
224
+ "dispatchCeiling": {
225
+ "providers": {
226
+ "cursor": {
227
+ "high": [
228
+ "composer-2.5",
229
+ { "harness": "cursor", "model": "gpt-5.5-xhigh" }
230
+ ]
231
+ }
232
+ }
233
+ }
234
+ }
235
+ }
236
+ ```
206
237
 
207
238
  `Uncapped` is explicit managed state. Do not represent it by leaving policy
208
239
  state absent. To request no OAT model/effort selection, set:
@@ -214,17 +245,20 @@ oat config set workflow.dispatchPolicy.mode inherit
214
245
  ### How enforcement works
215
246
 
216
247
  OAT applies managed policies where the provider exposes a reliable mechanism.
217
- Other providers receive them as advisory/unsupported.
248
+ Providers without an adapter receive them as advisory/unsupported.
218
249
 
219
- | Provider | Mechanism | Enforcement mode |
220
- | -------- | ------------------------- | -------------------------- |
221
- | Codex | Pinned role variants | `enforced` |
222
- | Claude | Task `model` parameter | `enforced` |
223
- | Others | None (informational only) | `advisory` / `unsupported` |
250
+ | Provider | Mechanism | Enforcement mode |
251
+ | -------- | ------------------------- | ------------------------------- |
252
+ | Codex | Pinned role variants | `enforced` |
253
+ | Claude | Task `model` parameter | `enforced` |
254
+ | Cursor | `--model` argument | `enforced` when a cell resolves |
255
+ | Others | None (informational only) | `advisory` / `unsupported` |
224
256
 
225
257
  Codex uses effort (`low < medium < high < xhigh`) and pinned OAT role variants.
226
258
  Claude uses Task `model` (`haiku < sonnet < opus < fable`) and keeps
227
- `effort_axis=not-applicable`.
259
+ `effort_axis=not-applicable`. Cursor and other model-arg providers use opaque
260
+ matrix slugs; OAT validates availability when a provider oracle is available,
261
+ but the configured matrix owns tier meaning.
228
262
 
229
263
  **Verify-on-upgrade:** when the requested tier exceeds the current orchestrator
230
264
  tier (an upgrade request), the resolver sets `verifyOnDispatch: true`. The skill
@@ -249,12 +283,14 @@ oat project dispatch-ceiling resolve --provider codex --json
249
283
  oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
250
284
  oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --orchestrator-tier sonnet --json
251
285
  oat project dispatch-ceiling resolve --provider claude --orchestrator-tier sonnet --json
286
+ oat project dispatch-ceiling resolve --provider cursor --role implementer --preferred high --escalation-level 0 --json
252
287
  ```
253
288
 
254
289
  The resolver checks effective config first, then project `state.md`
255
- `oat_dispatch_policy` frontmatter, then legacy `oat_dispatch_ceiling`.
256
- For Codex it also reports `providerDefaultEffort`, which is informational only
257
- for explicit inherit/default behavior or base/unpinned fallback paths.
290
+ `oat_dispatch_policy` frontmatter, including sparse `matrix` overrides, then
291
+ legacy `oat_dispatch_ceiling`. For Codex it also reports
292
+ `providerDefaultEffort`, which is informational only for explicit
293
+ inherit/default behavior or base/unpinned fallback paths.
258
294
 
259
295
  For non-interactive preflight checks, use:
260
296
 
@@ -286,8 +322,9 @@ Workflow preference keys live under the `workflow.*` namespace:
286
322
  - `workflow.dispatchPolicy.mode` — `managed` or `inherit`. `managed` means OAT selects model/effort controls from `workflow.dispatchPolicy.policy`; `inherit` means OAT leaves controls to host/provider defaults.
287
323
  - `workflow.dispatchPolicy.policy` — `economy`, `balanced`, `high`, `frontier`, or `uncapped`. `economy` through `frontier` are capped managed policies; `uncapped` keeps OAT-managed preferred selection without provider caps.
288
324
  - `workflow.dispatchCeiling.preset` — legacy compatibility alias (`balanced`, `maximum`, or `cost-conscious`) for capped managed policy setup.
289
- - `workflow.dispatchCeiling.providers.codex`legacy concrete Codex cap (`low`, `medium`, `high`, or `xhigh`).
290
- - `workflow.dispatchCeiling.providers.claude`legacy concrete Claude cap (`haiku`, `sonnet`, `opus`, or `fable`). Claude has no separate per-dispatch effort axis, so the effort axis remains `not-applicable`.
325
+ - `workflow.dispatchCeiling.providers.<provider>`dispatch matrix provider column or legacy bare provider target.
326
+ - `workflow.dispatchCeiling.providers.<provider>.<tier>`one matrix cell for `economy`, `balanced`, `high`, or `frontier`.
327
+ - `workflow.dispatchCeiling.recommendationVersion` — version of the adopted recommended matrix.
291
328
  - `workflow.gates.skills` / `workflow.gates.execTargets` — structured per-skill final gate commands and exec-target registry. Use `oat gate set`, `oat gate target set`, `oat gate review`, and `oat gate cross-provider-exec`; do not use `oat config set` for these objects.
292
329
 
293
330
  ### Auto artifact-review preferences
@@ -324,6 +361,7 @@ oat config set workflow.autoReviewAtHillCheckpoints true --user
324
361
  oat config set workflow.autoNarrowReReviewScope true --user
325
362
  oat config set workflow.designMode selective --user
326
363
  oat config set workflow.dispatchCeiling.preset balanced --user
364
+ oat config adopt dispatch-matrix --user
327
365
  oat config set workflow.autoArtifactReview.plan true --user
328
366
  oat config set workflow.autoArtifactReview.analysis true --user
329
367
 
@@ -331,6 +369,7 @@ oat config set workflow.autoArtifactReview.analysis true --user
331
369
  oat config set workflow.createPrOnComplete false --shared
332
370
  oat config set workflow.designMode collaborative --shared
333
371
  oat config set workflow.dispatchCeiling.preset balanced --shared
372
+ oat config set workflow.dispatchCeiling.providers.cursor.high composer-2.5 --shared
334
373
  oat config set workflow.autoArtifactReview.plan false --shared
335
374
 
336
375
  # Repo-local: personal override for this repo (default when no flag)
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Workflow Gates
3
- description: Configure per-skill final commands and cross-runtime review dispatch with oat gate.
3
+ description: Configure per-skill final commands and family-aware review dispatch with oat gate.
4
4
  ---
5
5
 
6
6
  # Workflow Gates
@@ -16,6 +16,13 @@ selects an exec target, runs the prompt, and exits with the child process
16
16
  status. Use `oat gate review` when the command is specifically an OAT review
17
17
  gate that should inspect the produced review artifact.
18
18
 
19
+ :::note Release note: default avoidance changed
20
+ Gate dispatch now defaults to `--avoid same-family`, not `same-runtime`.
21
+ For multi-family providers such as Cursor, this prevents a gate from reviewing
22
+ with the same model family that produced the work. Use `--avoid none` only when
23
+ you intentionally allow same-family review.
24
+ :::
25
+
19
26
  ## Gate config
20
27
 
21
28
  Gate config lives under `workflow.gates.skills` and is keyed by skill name.
@@ -129,9 +136,9 @@ contract.
129
136
  ## Exec targets
130
137
 
131
138
  `oat gate cross-provider-exec` chooses from `workflow.gates.execTargets`.
132
- Targets are keyed by opaque id. OAT uses only the declared runtime, commands,
133
- and priority; it does not parse model names or infer provider semantics from the
134
- id.
139
+ Targets are keyed by opaque id. OAT uses the declared runtime, commands,
140
+ priority, optional `models` list, and any pinned `--model` already present in
141
+ the command. It does not infer provider semantics from the target id.
135
142
 
136
143
  Built-in targets:
137
144
 
@@ -162,6 +169,34 @@ oat gate target set claude-opus \
162
169
  JSON argv is intentional: provider commands often contain flags such as `-p` or
163
170
  `--model`, which would be ambiguous as variadic CLI options.
164
171
 
172
+ Targets may also define a `models` list directly in config. During selection,
173
+ OAT expands that target into `(target, model)` candidates, preserves the target
174
+ priority and model list order, and appends `--model <winner>` to the command.
175
+ A long-form target that already pins `--model` in `baseCommand` is treated as
176
+ that candidate's model and is not double-pinned.
177
+
178
+ ```json
179
+ {
180
+ "workflow": {
181
+ "gates": {
182
+ "execTargets": {
183
+ "cursor-family-gate": {
184
+ "runtime": "cursor",
185
+ "baseCommand": ["cursor-agent", "-p", "--force"],
186
+ "models": ["composer-2.5", "gpt-5.5-xhigh", "claude-opus-4-8"],
187
+ "availabilityCommand": [
188
+ "sh",
189
+ "-c",
190
+ "command -v cursor-agent || command -v agent"
191
+ ],
192
+ "priority": 95
193
+ }
194
+ }
195
+ }
196
+ }
197
+ }
198
+ ```
199
+
165
200
  ### Trusted target examples
166
201
 
167
202
  Use these examples only in trusted environments where the provider process may
@@ -275,12 +310,15 @@ oat gate cross-provider-exec "Use oat-project-review-provide to review the curre
275
310
  By default the dispatcher:
276
311
 
277
312
  1. Resolves built-in and configured exec targets.
278
- 2. Detects the current runtime with host detection commands.
279
- 3. Applies `--avoid same-runtime`.
280
- 4. Checks candidate availability in descending priority order, with target id as
313
+ 2. Expands target `models` into candidate `(target, model)` pairs.
314
+ 3. Detects the current runtime with host detection commands.
315
+ 4. Resolves producer identity from `--producer-identity` or dispatch stamps when
316
+ available.
317
+ 5. Applies `--avoid same-family`.
318
+ 6. Checks candidate availability in descending priority order, with target id as
281
319
  the tie-breaker.
282
- 5. Runs the chosen `baseCommand` with the prompt appended.
283
- 6. Exits with the child process status.
320
+ 7. Runs the chosen `baseCommand` with the selected model and prompt appended.
321
+ 8. Exits with the child process status.
284
322
 
285
323
  Use `--target <id>` to pin one target and skip detection/avoidance:
286
324
 
@@ -289,12 +327,32 @@ oat gate cross-provider-exec --target claude-opus "Review the current project"
289
327
  ```
290
328
 
291
329
  Use `--avoid none` only when you intentionally allow the current runtime to be
292
- selected:
330
+ selected or same-family review to run:
293
331
 
294
332
  ```bash
295
333
  oat gate cross-provider-exec --avoid none "Run this gate on any available target"
296
334
  ```
297
335
 
336
+ Use `--producer-identity <value>:<provenance>` to route manually from a known
337
+ producer when no project dispatch stamp exists:
338
+
339
+ ```bash
340
+ oat gate review \
341
+ --producer-identity gpt-5.5-xhigh:declared \
342
+ --review-type code \
343
+ --review-scope final \
344
+ "Use oat-project-review-provide code final to review the current project"
345
+ ```
346
+
347
+ Gate JSON output includes `diversity` metadata with the requested avoid mode,
348
+ producer identity/provenance/confidence, reviewer target/model/family, and the
349
+ achieved level:
350
+
351
+ - `different-family`
352
+ - `degraded-to-different-slug`
353
+ - `same-family - no diverse target available`
354
+ - `unknown-producer`
355
+
298
356
  ## Failure behavior
299
357
 
300
358
  Gate failure behavior is owned by the gate-aware skill:
@@ -309,11 +367,16 @@ Gate failure behavior is owned by the gate-aware skill:
309
367
  available target. Once a target actually runs, its exit code is the gate result;
310
368
  OAT does not try another target after a failed review.
311
369
 
370
+ Gate target execution has a child-process timeout (default 10 minutes, override
371
+ with `OAT_GATE_EXEC_TIMEOUT_MS`). When a review target times out, JSON output
372
+ reports `status: review_failed`, `outcome: review_did_not_complete`,
373
+ `timedOut: true`, and the timeout value so automation can distinguish a hung
374
+ provider prompt from a completed review with findings.
375
+
312
376
  ## Current limits
313
377
 
314
- V1 gates avoid the current runtime, not the current model or effort setting.
315
- Same-runtime but different-target dispatch, such as using Cursor again with a
316
- different model slug, is future work. Until that exists, reusable lifecycle
317
- gates should rely on default `same-runtime` avoidance for cross-runtime review;
318
- manual and local overrides can pin an explicit reviewer target with
319
- `--target <id>`.
378
+ Family diversity is selected before dispatch. If the selected provider command
379
+ starts and then fails, OAT does not try another target after dispatch. If no
380
+ different-family target is available, OAT warns, records the degraded achieved
381
+ level, and runs the best available target rather than pretending diversity was
382
+ achieved.
@@ -12,15 +12,21 @@ Use this page when you are changing the OAT codebase itself rather than only edi
12
12
  Install and verify the workspace from the repo root:
13
13
 
14
14
  ```bash
15
- pnpm install
16
- pnpm build
17
- pnpm run cli -- help
15
+ nvm use
16
+ corepack pnpm install
17
+ corepack pnpm build
18
+ corepack pnpm run cli -- help
18
19
  ```
19
20
 
21
+ The repo pins Node in `.nvmrc` and the package manager in `package.json`
22
+ (`packageManager`). If your machine has multiple Node or pnpm installs, prefer
23
+ Corepack from the active `.nvmrc` Node so workspace commands use the same pnpm
24
+ version as the hooks and CI.
25
+
20
26
  For worktree-based implementation, initialize the worktree before starting the CLI workflow:
21
27
 
22
28
  ```bash
23
- pnpm run worktree:init
29
+ corepack pnpm run worktree:init
24
30
  ```
25
31
 
26
32
  ## Monorepo Structure
@@ -20,6 +20,29 @@ The hook is non-blocking: it never fails the commit, even when managed drift is
20
20
 
21
21
  OAT installs the hook into Git's currently active hook directory. When a consumer repo keeps hooks in a repo-managed folder such as `.githooks/`, Git must be configured to use that path before install, or OAT must configure it during the hook prompt flow.
22
22
 
23
+ ## OAT repo developer hooks
24
+
25
+ The `open-agent-toolkit` repository also ships its own managed hook scripts under
26
+ `tools/git-hooks/`. These are contributor hooks for this repo, separate from the
27
+ consumer hook snippet that `oat init` installs into other repositories.
28
+
29
+ The repo hooks source `tools/git-hooks/repo-toolchain.sh` before running pnpm
30
+ commands. The helper changes to the repo root, loads `.nvmrc` through nvm when
31
+ available, and then prefers Corepack pnpm. This keeps `commit-msg`,
32
+ `pre-commit`, `pre-push`, and `post-checkout` on the same Node/pnpm toolchain
33
+ even when a developer shell has multiple versions installed.
34
+
35
+ The repo's `pre-commit` OAT status check uses the repo-local source CLI when the
36
+ OAT source tree is present:
37
+
38
+ ```bash
39
+ corepack pnpm run --silent cli:source -- status --scope project --hook
40
+ ```
41
+
42
+ That avoids false sync drift from a stale globally installed `oat` while still
43
+ leaving the consumer-repo hook contract unchanged: generated hooks in other
44
+ repos continue to call `oat status --scope project --hook`.
45
+
23
46
  ## Safety contracts
24
47
 
25
48
  - `sync` mutates by default; use `--dry-run` to preview.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  title: Dispatch Policy
3
- description: 'How OAT dispatch policy works: managed capped tiers, managed Uncapped, Inherit Host Defaults, legacy dispatch-ceiling compatibility, and provider-specific enforcement.'
3
+ description: 'How OAT dispatch policy works: managed tiers, dispatch matrix cells, ordered routes, producer provenance, legacy compatibility, and provider-specific enforcement.'
4
4
  ---
5
5
 
6
6
  # Dispatch Policy
@@ -21,6 +21,11 @@ dispatch policy terminology.
21
21
  For raw config keys see [Configuration](../../cli-utilities/configuration.md);
22
22
  for execution-time behavior see [Implementation Execution](implementation-execution.md).
23
23
 
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.
28
+
24
29
  ## Policy Choices
25
30
 
26
31
  | Policy | Mode | Codex target | Claude target | Meaning |
@@ -85,13 +90,55 @@ oat_dispatch_policy:
85
90
  Legacy compatibility keys remain readable:
86
91
 
87
92
  - `workflow.dispatchCeiling.preset`
88
- - `workflow.dispatchCeiling.providers.codex`
89
- - `workflow.dispatchCeiling.providers.claude`
93
+ - `workflow.dispatchCeiling.providers.<provider>`
94
+ - `workflow.dispatchCeiling.providers.<provider>.<tier>`
90
95
  - `oat_dispatch_ceiling`
91
96
 
92
97
  Legacy preset names map into the managed ladder: `cost-conscious` maps to
93
98
  `Economy`, `balanced` maps to `Balanced`, and `maximum` maps to `High`.
94
99
 
100
+ ## Dispatch Matrix
101
+
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:
105
+
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
+ ```
111
+
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
+ }
135
+ ```
136
+
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
+
95
142
  ## How Resolution Works
96
143
 
97
144
  Before dispatching a subagent, the orchestrator calls:
@@ -105,6 +152,7 @@ For implementer or fix dispatch, pass the preferred runtime control:
105
152
  ```bash
106
153
  oat project dispatch-ceiling resolve --provider codex --role implementer --preferred high --json
107
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
108
156
  ```
109
157
 
110
158
  The resolver returns the resolved policy, optional cap, source, provider default
@@ -114,6 +162,9 @@ Selection modes:
114
162
 
115
163
  - `capped` - implementer/fix dispatch selects `min(preferred, cap)`.
116
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.
117
168
  - `review-target` - reviewer dispatch targets a configured cap when one exists.
118
169
  - `no-review-target` - managed uncapped reviewer dispatch has no configured
119
170
  target and falls back to the base/unpinned reviewer.
@@ -122,13 +173,13 @@ Selection modes:
122
173
 
123
174
  ## Provider Behavior
124
175
 
125
- | | Codex | Claude Code | Unsupported provider |
126
- | ----------------- | ------------------------------------------- | --------------------------------------- | -------------------- |
127
- | Managed mechanism | Pinned role variants | Task `model` argument | None |
128
- | Axis | effort (`low < medium < high < xhigh`) | model (`haiku < sonnet < opus < fable`) | None |
129
- | Capped policy | selected pinned variant up to cap | selected Task model up to cap | advisory/unsupported |
130
- | Uncapped | preferred pinned variant, no cap | preferred Task model, no cap | advisory/unsupported |
131
- | Inherit/default | base/unpinned role follows provider default | omit `model` | normal behavior |
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 |
132
183
 
133
184
  Codex uses pinned variants because per-call effort controls were unreliable in
134
185
  dogfooding. For managed `Uncapped`, OAT still selects the preferred pinned
@@ -139,6 +190,25 @@ Claude Code uses the per-call Task `model` argument. It has no OAT-managed
139
190
  per-dispatch effort axis, so dispatch logs use `effort_axis=not-applicable`.
140
191
  `Frontier` maps to Claude `fable`.
141
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.
196
+
197
+ ## Producer Provenance
198
+
199
+ Dispatch notes use a parseable single-line stamp so later gates can identify
200
+ the producer family:
201
+
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
+ ```
205
+
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.
211
+
142
212
  ## Implementer, Fix, and Reviewer Behavior
143
213
 
144
214
  For implementer and fix dispatches:
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.1.43",
3
- "docs-config": "0.1.43",
4
- "docs-theme": "0.1.43",
5
- "docs-transforms": "0.1.43"
2
+ "cli": "0.1.45",
3
+ "docs-config": "0.1.45",
4
+ "docs-theme": "0.1.45",
5
+ "docs-transforms": "0.1.45"
6
6
  }