@open-agent-toolkit/cli 0.1.42 → 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 (60) hide show
  1. package/assets/agents/oat-phase-implementer.md +11 -7
  2. package/assets/agents/oat-reviewer.md +6 -4
  3. package/assets/config/dispatch-matrix-recommendation.json +23 -0
  4. package/assets/docs/cli-utilities/configuration.md +95 -40
  5. package/assets/docs/cli-utilities/workflow-gates.md +79 -16
  6. package/assets/docs/contributing/code.md +10 -4
  7. package/assets/docs/contributing/hooks-and-safety.md +23 -0
  8. package/assets/docs/reference/oat-directory-structure.md +26 -24
  9. package/assets/docs/workflows/projects/dispatch-ceiling.md +193 -80
  10. package/assets/docs/workflows/projects/implementation-execution.md +68 -45
  11. package/assets/docs/workflows/projects/index.md +2 -2
  12. package/assets/docs/workflows/projects/lifecycle.md +17 -2
  13. package/assets/public-package-versions.json +4 -4
  14. package/assets/skills/oat-project-implement/SKILL.md +232 -100
  15. package/assets/skills/oat-project-plan/SKILL.md +80 -30
  16. package/assets/skills/oat-project-plan-writing/SKILL.md +10 -10
  17. package/assets/skills/oat-project-quick-start/SKILL.md +80 -30
  18. package/assets/templates/plan.md +4 -4
  19. package/assets/templates/state.md +12 -3
  20. package/dist/commands/config/index.d.ts +6 -0
  21. package/dist/commands/config/index.d.ts.map +1 -1
  22. package/dist/commands/config/index.js +432 -11
  23. package/dist/commands/doctor/index.d.ts +6 -1
  24. package/dist/commands/doctor/index.d.ts.map +1 -1
  25. package/dist/commands/doctor/index.js +138 -4
  26. package/dist/commands/gate/index.d.ts +39 -2
  27. package/dist/commands/gate/index.d.ts.map +1 -1
  28. package/dist/commands/gate/index.js +343 -30
  29. package/dist/commands/internal/cursor-current-target.d.ts +37 -0
  30. package/dist/commands/internal/cursor-current-target.d.ts.map +1 -0
  31. package/dist/commands/internal/cursor-current-target.js +228 -0
  32. package/dist/commands/internal/index.d.ts.map +1 -1
  33. package/dist/commands/internal/index.js +2 -0
  34. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  35. package/dist/commands/project/dispatch-ceiling/index.js +646 -56
  36. package/dist/config/dispatch-ceiling-preset.d.ts +37 -1
  37. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  38. package/dist/config/dispatch-ceiling-preset.js +20 -0
  39. package/dist/config/oat-config.d.ts +25 -6
  40. package/dist/config/oat-config.d.ts.map +1 -1
  41. package/dist/config/oat-config.js +123 -11
  42. package/dist/config/resolve.d.ts.map +1 -1
  43. package/dist/config/resolve.js +16 -0
  44. package/dist/manifest/manifest.types.d.ts +12 -12
  45. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  46. package/dist/providers/ceiling/registry.js +22 -1
  47. package/dist/providers/codex/codec/sync-extension.js +1 -1
  48. package/dist/providers/identity/availability.d.ts +22 -0
  49. package/dist/providers/identity/availability.d.ts.map +1 -0
  50. package/dist/providers/identity/availability.js +119 -0
  51. package/dist/providers/identity/family.d.ts +13 -0
  52. package/dist/providers/identity/family.d.ts.map +1 -0
  53. package/dist/providers/identity/family.js +32 -0
  54. package/dist/providers/identity/provenance.d.ts +21 -0
  55. package/dist/providers/identity/provenance.d.ts.map +1 -0
  56. package/dist/providers/identity/provenance.js +65 -0
  57. package/dist/providers/identity/stamp.d.ts +35 -0
  58. package/dist/providers/identity/stamp.d.ts.map +1 -0
  59. package/dist/providers/identity/stamp.js +171 -0
  60. package/package.json +2 -2
@@ -35,14 +35,16 @@ You will be given a "Phase Scope" block including:
35
35
  - **workflow_mode**: `spec-driven` | `quick` | `import` (default `spec-driven`)
36
36
  - **model_axis**: Optional model dispatch state selected by the orchestrator (`selected:<value>`, `inherited`, `not-applicable`, or `host-auto`)
37
37
  - **effort_axis**: Optional effort dispatch state selected by the orchestrator (`selected:<value>`, `provider-default`, `inherited`, `not-applicable`, or `host-auto`)
38
- - **dispatch_ceiling**: Optional resolved provider ceiling that capped/selected this dispatch
39
- - **ceiling_source**: Optional source for the resolved ceiling (`repo config`, `project state`, or `preflight prompt`)
40
- - **provider_default_effort**: Optional Codex provider default effort, used only to explain base/unpinned fallback dispatches
38
+ - **dispatch_policy**: Optional resolved policy label (`economy`, `balanced`, `high`, `frontier`, `uncapped`, `inherit host defaults`, or `legacy capped`)
39
+ - **dispatch_ceiling**: Optional resolved provider cap that may have capped/selected this dispatch; absent or null for `uncapped` and inherit/default modes
40
+ - **policy_source**: Optional source for the resolved policy (`repo config`, `project state`, or `preflight prompt`)
41
+ - **ceiling_source**: Optional compatibility alias for policy source (`repo config`, `project state`, or `preflight prompt`)
42
+ - **provider_default_effort**: Optional Codex provider default effort, used only to explain inherit/default behavior or base/unpinned fallback dispatches
41
43
  - **dispatch_rationale**: Optional short rationale for the model/effort axis choices
42
44
 
43
- The `model_axis`, `effort_axis`, `dispatch_ceiling`, `ceiling_source`, and `provider_default_effort` fields describe dispatch state the orchestrator already chose; they are descriptive context for your report, not actions for you to take. Echo whatever values were provided in your summary. If a field is absent, report it as "not provided."
45
+ The `model_axis`, `effort_axis`, `dispatch_policy`, `dispatch_ceiling`, `policy_source`, `ceiling_source`, and `provider_default_effort` fields describe dispatch state the orchestrator already chose; they are descriptive context for your report, not actions for you to take. Echo whatever values were provided in your summary. If a field is absent, report it as "not provided."
44
46
 
45
- For Codex, `provider-default` means the base/unpinned role follows Codex configured/provider default effort. It does not mean OAT inherited the parent session ceiling.
47
+ For Codex, `provider-default` means explicit inherit/default behavior or a base/unpinned fallback follows Codex configured/provider default effort. It does not mean managed `Uncapped`, and it does not mean OAT inherited the parent session ceiling.
46
48
 
47
49
  If `mode: fix`, the block also includes:
48
50
 
@@ -131,8 +133,9 @@ Report format:
131
133
  **Confidence:** high | medium | low
132
134
  **Model axis:** {model_axis if provided, otherwise "not provided"}
133
135
  **Effort axis:** {effort_axis if provided, otherwise "not provided"}
136
+ **Dispatch policy:** {dispatch_policy if provided, otherwise "not provided"}
134
137
  **Dispatch ceiling:** {dispatch_ceiling if provided, otherwise "not provided"}
135
- **Ceiling source:** {ceiling_source if provided, otherwise "not provided"}
138
+ **Policy source:** {policy_source if provided, otherwise ceiling_source if provided, otherwise "not provided"}
136
139
  **Provider default effort:** {provider_default_effort if provided, otherwise "not provided"}
137
140
 
138
141
  ### Task Outcomes
@@ -200,8 +203,9 @@ If a fix introduces a regression or doesn't address its finding, either re-fix w
200
203
  **Confidence:** high | medium | low
201
204
  **Model axis:** {model_axis if provided, otherwise "not provided"}
202
205
  **Effort axis:** {effort_axis if provided, otherwise "not provided"}
206
+ **Dispatch policy:** {dispatch_policy if provided, otherwise "not provided"}
203
207
  **Dispatch ceiling:** {dispatch_ceiling if provided, otherwise "not provided"}
204
- **Ceiling source:** {ceiling_source if provided, otherwise "not provided"}
208
+ **Policy source:** {policy_source if provided, otherwise ceiling_source if provided, otherwise "not provided"}
205
209
  **Provider default effort:** {provider_default_effort if provided, otherwise "not provided"}
206
210
 
207
211
  ### Fix Outcomes
@@ -57,16 +57,18 @@ You will be given a "Review Scope" block including:
57
57
  - **oat_review_invocation**: Optional provenance selector for artifact-mode reviews. Use `manual`, `auto`, or `gate`; default to `manual` when absent.
58
58
  - **model_axis**: Optional model dispatch state selected by the orchestrator (`selected:<value>`, `inherited`, `not-applicable`, or `host-auto`)
59
59
  - **effort_axis**: Optional effort dispatch state selected by the orchestrator (`selected:<value>`, `provider-default`, `inherited`, `not-applicable`, or `host-auto`)
60
- - **dispatch_ceiling**: Optional resolved provider ceiling that capped/selected this review dispatch
61
- - **ceiling_source**: Optional source for the resolved ceiling (`repo config`, `project state`, or `preflight prompt`)
62
- - **provider_default_effort**: Optional Codex provider default effort, used only to explain base/unpinned fallback dispatches
60
+ - **dispatch_policy**: Optional resolved policy label (`economy`, `balanced`, `high`, `frontier`, `uncapped`, `inherit host defaults`, or `legacy capped`)
61
+ - **dispatch_ceiling**: Optional resolved provider cap that may have capped/selected this review dispatch; absent or null for `uncapped` and inherit/default modes
62
+ - **policy_source**: Optional source for the resolved policy (`repo config`, `project state`, or `preflight prompt`)
63
+ - **ceiling_source**: Optional compatibility alias for policy source (`repo config`, `project state`, or `preflight prompt`)
64
+ - **provider_default_effort**: Optional Codex provider default effort, used only to explain inherit/default behavior or base/unpinned fallback dispatches
63
65
  - **dispatch_rationale**: Optional short rationale for the model/effort axis choices
64
66
 
65
67
  ## Dispatch Control
66
68
 
67
69
  The orchestrator owns dispatch control. Do not read `plan.md` Dispatch Profile rows to self-select a tier.
68
70
 
69
- For Codex, normal deterministic review dispatch uses pinned reviewer variants (`oat-reviewer-low`, `oat-reviewer-medium`, `oat-reviewer-high`, or `oat-reviewer-xhigh`) selected by the resolved OAT dispatch ceiling. The base `oat-reviewer` role is a provider-default/unpinned fallback; if you are running as the base role, report any provided `provider_default_effort` as context but do not treat it as an OAT ceiling.
71
+ For Codex, deterministic review dispatch under a capped managed policy uses pinned reviewer variants (`oat-reviewer-low`, `oat-reviewer-medium`, `oat-reviewer-high`, or `oat-reviewer-xhigh`) selected by the resolved OAT dispatch policy cap. Managed `Uncapped` and inherit/default policies have no reviewer target, so the base `oat-reviewer` role is used as a provider-default/unpinned fallback. If you are running as the base role, report any provided `provider_default_effort` as context but do not treat it as managed uncapped selection or an OAT cap.
70
72
 
71
73
  For Claude Code, review dispatch is model-axis based and the effort axis is `not-applicable`.
72
74
 
@@ -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
+ }
@@ -168,50 +168,97 @@ oat config get lastPausedProject
168
168
  oat config describe activeIdea
169
169
  ```
170
170
 
171
- ## Dispatch ceiling resolution
171
+ ## Dispatch policy resolution
172
172
 
173
- The dispatch ceiling is set as a **provider-neutral preset** (or per-provider
174
- advanced values) and compiled at write time into concrete per-provider values.
175
- Runtime dispatch reads only the concrete values — never the preset label.
173
+ Dispatch policy is the workflow setting that tells OAT whether to manage
174
+ subagent model/effort selection and, if so, which managed policy to use.
176
175
 
177
- For the full conceptual model presets, the compile/resolve flow, and how
178
- enforcement differs for Codex, Claude, and unsupported providers see
179
- [Dispatch Ceiling](../workflows/projects/dispatch-ceiling.md).
176
+ For the full conceptual model - managed capped tiers, dispatch matrix cells,
177
+ managed `Uncapped`, `Inherit Host Defaults`, and provider-specific enforcement - see
178
+ [Dispatch Policy](../workflows/projects/dispatch-ceiling.md).
180
179
 
181
180
  ### Config keys
182
181
 
183
- Three keys control the ceiling, all under `workflow.dispatchCeiling`:
182
+ Preferred keys:
184
183
 
185
- | Key | Values | Purpose |
186
- | ------------------------------------------- | --------------------------------------- | --------------------------------------------------- |
187
- | `workflow.dispatchCeiling.preset` | `balanced`, `maximum`, `cost-conscious` | Convenience preset; compiles to concrete values |
188
- | `workflow.dispatchCeiling.providers.codex` | `low`, `medium`, `high`, `xhigh` | Concrete Codex ceiling (set by preset or Advanced) |
189
- | `workflow.dispatchCeiling.providers.claude` | `haiku`, `sonnet`, `opus` | Concrete Claude ceiling (set by preset or Advanced) |
184
+ | Key | Values | Purpose |
185
+ | -------------------------------- | ----------------------------------------------------- | ---------------------------------------------------------------------------------- |
186
+ | `workflow.dispatchPolicy.mode` | `managed`, `inherit` | `managed` lets OAT select controls; `inherit` leaves controls to the host/provider |
187
+ | `workflow.dispatchPolicy.policy` | `economy`, `balanced`, `high`, `frontier`, `uncapped` | Managed policy. Setting this key writes `mode=managed` |
190
188
 
191
- **Presets compile to:**
189
+ Managed policies compile to:
192
190
 
193
- | Preset | Codex | Claude |
194
- | ---------------- | -------- | -------- |
195
- | `balanced` | `high` | `sonnet` |
196
- | `maximum` | `xhigh` | `opus` |
197
- | `cost-conscious` | `medium` | `sonnet` |
191
+ | Policy | Codex | Claude |
192
+ | ---------- | -------- | -------- |
193
+ | `economy` | `medium` | `sonnet` |
194
+ | `balanced` | `high` | `sonnet` |
195
+ | `high` | `xhigh` | `opus` |
196
+ | `frontier` | `xhigh` | `fable` |
197
+ | `uncapped` | none | none |
198
198
 
199
- **Advanced (no preset):** set `providers.codex` and/or `providers.claude`
200
- individually. No `preset` key is stored.
199
+ Dispatch matrix and legacy compatibility keys:
201
200
 
202
- **No ceiling:** leave `oat_dispatch_ceiling` unset; implementer subagents run at
203
- provider defaults.
201
+ | Key | Values | Purpose |
202
+ | ------------------------------------------------------ | --------------------------------------- | -------------------------------------------------------------------------------------- |
203
+ | `workflow.dispatchCeiling.preset` | `balanced`, `maximum`, `cost-conscious` | Legacy preset alias; `maximum` maps to `high`, `cost-conscious` to `economy` |
204
+ | `workflow.dispatchCeiling.providers.<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
+ ```
237
+
238
+ `Uncapped` is explicit managed state. Do not represent it by leaving policy
239
+ state absent. To request no OAT model/effort selection, set:
240
+
241
+ ```bash
242
+ oat config set workflow.dispatchPolicy.mode inherit
243
+ ```
204
244
 
205
245
  ### How enforcement works
206
246
 
207
- OAT applies the ceiling where the provider exposes a reliable mechanism. Other
208
- providers receive it as advisory.
247
+ OAT applies managed policies where the provider exposes a reliable mechanism.
248
+ Providers without an adapter receive them as advisory/unsupported.
249
+
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` |
209
256
 
210
- | Provider | Mechanism | Enforcement mode |
211
- | -------- | ------------------------- | -------------------------- |
212
- | Codex | Pinned role variants | `enforced` |
213
- | Claude | Task `model` parameter | `enforced` |
214
- | Others | None (informational only) | `advisory` / `unsupported` |
257
+ Codex uses effort (`low < medium < high < xhigh`) and pinned OAT role variants.
258
+ Claude uses Task `model` (`haiku < sonnet < opus < fable`) and keeps
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.
215
262
 
216
263
  **Verify-on-upgrade:** when the requested tier exceeds the current orchestrator
217
264
  tier (an upgrade request), the resolver sets `verifyOnDispatch: true`. The skill
@@ -219,11 +266,12 @@ confirms the actual model used after dispatch. If the provider did not honor the
219
266
  upgrade, the enforcement log reads `advisory — provider did not honor upgrade;
220
267
  ran <tier>` instead of `enforced`.
221
268
 
222
- ### Clean break
269
+ ### Legacy compatibility
223
270
 
224
- The previous flat keys (`workflow.dispatchCeiling.codex` and
225
- `workflow.dispatchCeiling.claude`) are removed. There is no migration path — set
226
- the new keys.
271
+ The command group and docs path still use `dispatch-ceiling` for compatibility.
272
+ Legacy `workflow.dispatchCeiling.*` config and project `oat_dispatch_ceiling`
273
+ frontmatter remain readable as capped managed policy input. Absent legacy state
274
+ does not mean managed `Uncapped`.
227
275
 
228
276
  ### Using the resolver
229
277
 
@@ -235,12 +283,14 @@ oat project dispatch-ceiling resolve --provider codex --json
235
283
  oat project dispatch-ceiling resolve --provider codex --role implementer --preferred medium --json
236
284
  oat project dispatch-ceiling resolve --provider claude --role implementer --preferred sonnet --orchestrator-tier sonnet --json
237
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
238
287
  ```
239
288
 
240
289
  The resolver checks effective config first, then project `state.md`
241
- `oat_dispatch_ceiling` frontmatter. For Codex it also reports
242
- `providerDefaultEffort`, which is informational for base/unpinned roles and is
243
- not treated as the OAT ceiling.
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.
244
294
 
245
295
  For non-interactive preflight checks, use:
246
296
 
@@ -269,9 +319,12 @@ Workflow preference keys live under the `workflow.*` namespace:
269
319
  - `workflow.autoNarrowReReviewScope` — boolean. Auto-narrow re-review scope to fix-task commits only in `oat-project-review-provide`. When unset, the skill prompts.
270
320
  - `workflow.autoArtifactReview.plan` — boolean, default `true`. Automatically run the bounded artifact-review loop for generated `plan.md` files before implementation handoff. Set to `false` only when you intentionally want to skip the plan artifact review.
271
321
  - `workflow.autoArtifactReview.analysis` — boolean, default `true`. Automatically run the bounded accuracy-review loop for generated docs and agent-instructions analysis artifacts before the matching apply workflow consumes them.
272
- - `workflow.dispatchCeiling.preset` — `balanced`, `maximum`, or `cost-conscious`. Convenience preset that compiles to per-provider values at write time. Setting this key is the recommended way to configure the ceiling.
273
- - `workflow.dispatchCeiling.providers.codex` — `low`, `medium`, `high`, or `xhigh`. Concrete Codex ceiling. Set automatically when a preset is selected; also settable directly for Advanced (no preset) configurations. Provider default effort is informational for base/unpinned roles and is not treated as this ceiling.
274
- - `workflow.dispatchCeiling.providers.claude` — `haiku`, `sonnet`, or `opus`. Concrete Claude ceiling. Set automatically when a preset is selected; also settable directly for Advanced configurations. Claude has no separate per-dispatch effort axis, so the effort axis remains `not-applicable`.
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.
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.
324
+ - `workflow.dispatchCeiling.preset` — legacy compatibility alias (`balanced`, `maximum`, or `cost-conscious`) for capped managed policy setup.
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.
275
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.
276
329
 
277
330
  ### Auto artifact-review preferences
@@ -308,6 +361,7 @@ oat config set workflow.autoReviewAtHillCheckpoints true --user
308
361
  oat config set workflow.autoNarrowReReviewScope true --user
309
362
  oat config set workflow.designMode selective --user
310
363
  oat config set workflow.dispatchCeiling.preset balanced --user
364
+ oat config adopt dispatch-matrix --user
311
365
  oat config set workflow.autoArtifactReview.plan true --user
312
366
  oat config set workflow.autoArtifactReview.analysis true --user
313
367
 
@@ -315,6 +369,7 @@ oat config set workflow.autoArtifactReview.analysis true --user
315
369
  oat config set workflow.createPrOnComplete false --shared
316
370
  oat config set workflow.designMode collaborative --shared
317
371
  oat config set workflow.dispatchCeiling.preset balanced --shared
372
+ oat config set workflow.dispatchCeiling.providers.cursor.high composer-2.5 --shared
318
373
  oat config set workflow.autoArtifactReview.plan false --shared
319
374
 
320
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.
@@ -93,30 +93,32 @@ Legacy `.oat/active-project` / `.oat/projects-root` / `.oat/active-idea` files m
93
93
 
94
94
  Current schema keys:
95
95
 
96
- | Key | Type | Default | Description |
97
- | ------------------------------------------- | ---------- | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
- | `version` | `number` | `1` | Schema version |
99
- | `worktrees.root` | `string` | `".worktrees"` | Root directory for git worktrees (repo-relative or absolute) |
100
- | `projects.root` | `string` | `".oat/projects/shared"` | Default root directory for OAT projects |
101
- | `localPaths` | `string[]` | - | Gitignored directories to sync between main repo and worktrees. Supports glob patterns. Managed via `oat local add/remove`. |
102
- | `documentation.root` | `string` | - | Root directory containing documentation source files (e.g., `apps/docs/docs`) |
103
- | `documentation.tooling` | `string` | - | Documentation framework identifier (`mkdocs` or `fumadocs`) |
104
- | `documentation.config` | `string` | - | Path to the documentation framework config file (e.g., `mkdocs.yml`, `next.config.js`) |
105
- | `documentation.index` | `string` | - | Path to the docs surface entry point (e.g., `index.md` for Fumadocs, `mkdocs.yml` for MkDocs). Set by `oat docs init` and updated by `oat docs generate-index`. |
106
- | `documentation.requireForProjectCompletion` | `boolean` | `false` | When `true`, OAT project completion gates require documentation to be updated |
107
- | `git.defaultBranch` | `string` | `"main"` | Default branch for PR creation. Auto-detected during `oat init` via `gh repo view` or `origin/HEAD`. Used by `oat-project-pr-final` and `oat-project-pr-progress`. |
108
- | `workflow.autoReviewAtHillCheckpoints` | `boolean` | unset | When `true`, completing a HiLL checkpoint automatically runs the extra lifecycle review. Does not control Tier 1 per-phase `oat-reviewer` gates. Can be overridden per-project via `oat_auto_review_at_hill_checkpoints` in `plan.md` frontmatter. Legacy `autoReviewAtCheckpoints` remains a fallback. |
109
- | `workflow.dispatchCeiling.preset` | `string` | unset | Convenience preset compiled at write time to concrete per-provider ceilings (`balanced` = codex `high` / claude `sonnet`; `maximum` = codex `xhigh` / claude `opus`; `cost-conscious` = codex `medium` / claude `sonnet`). Stored only when a preset is chosen; runtime reads compiled `providers.*`, never the preset label. |
110
- | `workflow.dispatchCeiling.providers.codex` | `string` | unset | Maximum Codex reasoning effort OAT may select through deterministic pinned implementer/reviewer variants (`low`, `medium`, `high`, or `xhigh`). Codex provider default effort is informational for base/unpinned roles and is not treated as this ceiling. |
111
- | `workflow.dispatchCeiling.providers.claude` | `string` | unset | Maximum Claude model tier OAT may select for provider-native subagent dispatch (`haiku`, `sonnet`, or `opus`). Claude has no separate per-dispatch effort axis. The flat keys `workflow.dispatchCeiling.codex` and `workflow.dispatchCeiling.claude` were removed (no migration). |
112
- | `workflow.gates.skills` | `object` | unset | Per-skill final gate config keyed by skill name. Managed with `oat gate set/unset`; gate-aware skills declare `oat_gateable: true`. |
113
- | `workflow.gates.execTargets` | `object` | built-ins | Cross-runtime exec target registry keyed by opaque target id. Managed with `oat gate target set/unset`; built-ins cover Codex, Claude, and Cursor defaults. |
114
- | `archive.s3Uri` | `string` | - | Base S3 URI for repo-scoped archived project sync, for example `s3://bucket/oat-archive` |
115
- | `archive.s3SyncOnComplete` | `boolean` | `false` | When `true`, `oat-project-complete` uploads the archived project to the configured S3 archive after local archive succeeds |
116
- | `archive.summaryExportPath` | `string` | - | Repo-relative directory where completion exports `summary.md` as a dated snapshot like `20260401-<project-name>.md` for durable tracked reference |
117
- | `archive.wrapUpExportPath` | `string` | - | Repo-relative directory where `oat-wrap-up` writes dated reports like `20260413-wrap-up-past-week.md`; when unset, the skill falls back to `.oat/repo/reference/wrap-ups/` |
118
- | `archive.awsProfile` | `string` | - | Optional AWS named profile forwarded as `AWS_PROFILE` to every `aws` invocation in archive flows (`oat-project-complete` S3 sync, `oat repo archive sync`). Overrides ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` when set. |
119
- | `archive.awsRegion` | `string` | - | Optional AWS region forwarded as `AWS_REGION` to every `aws` invocation in archive flows. Overrides ambient shell `AWS_REGION` / `AWS_DEFAULT_REGION` when set. |
96
+ | Key | Type | Default | Description |
97
+ | ------------------------------------------- | ---------- | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
98
+ | `version` | `number` | `1` | Schema version |
99
+ | `worktrees.root` | `string` | `".worktrees"` | Root directory for git worktrees (repo-relative or absolute) |
100
+ | `projects.root` | `string` | `".oat/projects/shared"` | Default root directory for OAT projects |
101
+ | `localPaths` | `string[]` | - | Gitignored directories to sync between main repo and worktrees. Supports glob patterns. Managed via `oat local add/remove`. |
102
+ | `documentation.root` | `string` | - | Root directory containing documentation source files (e.g., `apps/docs/docs`) |
103
+ | `documentation.tooling` | `string` | - | Documentation framework identifier (`mkdocs` or `fumadocs`) |
104
+ | `documentation.config` | `string` | - | Path to the documentation framework config file (e.g., `mkdocs.yml`, `next.config.js`) |
105
+ | `documentation.index` | `string` | - | Path to the docs surface entry point (e.g., `index.md` for Fumadocs, `mkdocs.yml` for MkDocs). Set by `oat docs init` and updated by `oat docs generate-index`. |
106
+ | `documentation.requireForProjectCompletion` | `boolean` | `false` | When `true`, OAT project completion gates require documentation to be updated |
107
+ | `git.defaultBranch` | `string` | `"main"` | Default branch for PR creation. Auto-detected during `oat init` via `gh repo view` or `origin/HEAD`. Used by `oat-project-pr-final` and `oat-project-pr-progress`. |
108
+ | `workflow.autoReviewAtHillCheckpoints` | `boolean` | unset | When `true`, completing a HiLL checkpoint automatically runs the extra lifecycle review. Does not control Tier 1 per-phase `oat-reviewer` gates. Can be overridden per-project via `oat_auto_review_at_hill_checkpoints` in `plan.md` frontmatter. Legacy `autoReviewAtCheckpoints` remains a fallback. |
109
+ | `workflow.dispatchPolicy.mode` | `string` | unset | Dispatch policy mode: `managed` lets OAT select model/effort controls; `inherit` leaves controls to the host/provider defaults. |
110
+ | `workflow.dispatchPolicy.policy` | `string` | unset | Managed dispatch policy: `economy`, `balanced`, `high`, `frontier`, or `uncapped`. Capped policies compile to provider targets; `uncapped` keeps OAT-managed preferred selection without provider caps. |
111
+ | `workflow.dispatchCeiling.preset` | `string` | unset | Legacy compatibility preset for capped managed policy setup (`balanced`, `maximum`, `cost-conscious`). `maximum` maps to `high`; `cost-conscious` maps to `economy`. |
112
+ | `workflow.dispatchCeiling.providers.codex` | `string` | unset | Legacy concrete Codex capped target (`low`, `medium`, `high`, or `xhigh`). Codex provider default effort is informational only for explicit inherit/default behavior or base/unpinned fallback paths. |
113
+ | `workflow.dispatchCeiling.providers.claude` | `string` | unset | Legacy concrete Claude capped target (`haiku`, `sonnet`, `opus`, or `fable`). Claude has no separate per-dispatch effort axis. The flat keys `workflow.dispatchCeiling.codex` and `workflow.dispatchCeiling.claude` were removed (no migration). |
114
+ | `workflow.gates.skills` | `object` | unset | Per-skill final gate config keyed by skill name. Managed with `oat gate set/unset`; gate-aware skills declare `oat_gateable: true`. |
115
+ | `workflow.gates.execTargets` | `object` | built-ins | Cross-runtime exec target registry keyed by opaque target id. Managed with `oat gate target set/unset`; built-ins cover Codex, Claude, and Cursor defaults. |
116
+ | `archive.s3Uri` | `string` | - | Base S3 URI for repo-scoped archived project sync, for example `s3://bucket/oat-archive` |
117
+ | `archive.s3SyncOnComplete` | `boolean` | `false` | When `true`, `oat-project-complete` uploads the archived project to the configured S3 archive after local archive succeeds |
118
+ | `archive.summaryExportPath` | `string` | - | Repo-relative directory where completion exports `summary.md` as a dated snapshot like `20260401-<project-name>.md` for durable tracked reference |
119
+ | `archive.wrapUpExportPath` | `string` | - | Repo-relative directory where `oat-wrap-up` writes dated reports like `20260413-wrap-up-past-week.md`; when unset, the skill falls back to `.oat/repo/reference/wrap-ups/` |
120
+ | `archive.awsProfile` | `string` | - | Optional AWS named profile forwarded as `AWS_PROFILE` to every `aws` invocation in archive flows (`oat-project-complete` S3 sync, `oat repo archive sync`). Overrides ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` when set. |
121
+ | `archive.awsRegion` | `string` | - | Optional AWS region forwarded as `AWS_REGION` to every `aws` invocation in archive flows. Overrides ambient shell `AWS_REGION` / `AWS_DEFAULT_REGION` when set. |
120
122
 
121
123
  All `documentation.*` keys are managed via `oat config get/set` and are set automatically by `oat docs init`.
122
124
  The `git.defaultBranch` key is auto-detected during `oat init` and can be overridden via `oat config set git.defaultBranch <branch>`.