@open-agent-toolkit/cli 0.1.41 → 0.1.43

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/agents/oat-phase-implementer.md +13 -9
  2. package/assets/agents/oat-reviewer.md +16 -12
  3. package/assets/docs/cli-utilities/configuration.md +51 -35
  4. package/assets/docs/cli-utilities/workflow-gates.md +55 -0
  5. package/assets/docs/reference/cli-reference.md +1 -1
  6. package/assets/docs/reference/oat-directory-structure.md +26 -24
  7. package/assets/docs/workflows/projects/artifacts.md +22 -0
  8. package/assets/docs/workflows/projects/dispatch-ceiling.md +128 -85
  9. package/assets/docs/workflows/projects/hill-checkpoints.md +2 -0
  10. package/assets/docs/workflows/projects/implementation-execution.md +70 -46
  11. package/assets/docs/workflows/projects/index.md +2 -2
  12. package/assets/docs/workflows/projects/lifecycle.md +17 -2
  13. package/assets/docs/workflows/projects/reviews.md +17 -0
  14. package/assets/public-package-versions.json +4 -4
  15. package/assets/skills/oat-project-implement/SKILL.md +256 -95
  16. package/assets/skills/oat-project-plan/SKILL.md +60 -29
  17. package/assets/skills/oat-project-plan-writing/SKILL.md +10 -10
  18. package/assets/skills/oat-project-quick-start/SKILL.md +60 -29
  19. package/assets/skills/oat-project-review-provide/SKILL.md +25 -13
  20. package/assets/skills/oat-project-review-receive/SKILL.md +20 -10
  21. package/assets/skills/oat-review-provide/SKILL.md +14 -12
  22. package/assets/skills/oat-review-provide/references/review-artifact-template.md +1 -1
  23. package/assets/templates/plan.md +4 -4
  24. package/assets/templates/state.md +7 -3
  25. package/dist/commands/config/index.d.ts.map +1 -1
  26. package/dist/commands/config/index.js +66 -3
  27. package/dist/commands/gate/index.d.ts.map +1 -1
  28. package/dist/commands/gate/index.js +15 -3
  29. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  30. package/dist/commands/project/dispatch-ceiling/index.js +296 -49
  31. package/dist/commands/review/latest.d.ts.map +1 -1
  32. package/dist/commands/review/latest.js +5 -2
  33. package/dist/commands/shared/frontmatter.d.ts +11 -0
  34. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  35. package/dist/commands/shared/frontmatter.js +15 -0
  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 +10 -1
  40. package/dist/config/oat-config.d.ts.map +1 -1
  41. package/dist/config/oat-config.js +20 -1
  42. package/dist/config/resolve.d.ts.map +1 -1
  43. package/dist/config/resolve.js +4 -0
  44. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  45. package/dist/providers/ceiling/registry.js +6 -1
  46. package/dist/providers/codex/codec/sync-extension.js +1 -1
  47. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-phase-implementer
3
- version: 1.0.2
3
+ version: 1.0.3
4
4
  description: Implements a single plan phase end-to-end — reads artifacts once, executes tasks sequentially, commits per task, self-reviews, and returns a structured summary. Dispatched by oat-project-implement.
5
5
  tools: Read, Write, Edit, Bash, Grep, Glob
6
6
  color: cyan
@@ -35,18 +35,20 @@ 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
 
49
- - **review_artifact**: Path to the review artifact from the reviewer (e.g., `reviews/p02-review-YYYY-MM-DD.md`)
51
+ - **review_artifact**: Path to the review artifact from the reviewer (e.g., `reviews/p02-review-2026-01-28T140322Z.md`)
50
52
  - **findings**: Critical and Important findings list
51
53
  - **prior_summary**: Your own prior `implement` run summary (what was previously built)
52
54
 
@@ -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
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-reviewer
3
- version: 1.1.3
3
+ version: 1.1.4
4
4
  description: Unified reviewer for OAT projects - mode-aware verification of requirements/design alignment and code quality. Writes a review artifact to disk by default, or returns structured findings in-memory when dispatched in structured-output mode.
5
5
  tools: Read, Bash, Grep, Glob, Write
6
6
  color: yellow
@@ -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
 
@@ -287,19 +289,21 @@ Write the review artifact to the specified path.
287
289
 
288
290
  **File path format:**
289
291
 
290
- - Phase review: `{project}/reviews/pNN-review-YYYY-MM-DD.md`
291
- - Final review: `{project}/reviews/final-review-YYYY-MM-DD.md`
292
- - Task review: `{project}/reviews/pNN-tNN-review-YYYY-MM-DD.md`
293
- - Range review: `{project}/reviews/range-review-YYYY-MM-DD.md`
292
+ Use a seconds-precision **UTC** timestamp token (`YYYY-MM-DDTHHMMSSZ`, from `date -u +%Y-%m-%dT%H%M%SZ` — the `-u` and the trailing `Z` are mandatory) so same-scope, same-day re-reviews never collide and always sort by recency. Never emit a local-time or `Z`-less timestamp: a timezone-less datetime mis-orders artifacts written by agents in different timezones.
294
293
 
295
- **If file already exists for today:** add `-v2`, `-v3`, etc.
294
+ - Phase review: `{project}/reviews/pNN-review-YYYY-MM-DDTHHMMSSZ.md`
295
+ - Final review: `{project}/reviews/final-review-YYYY-MM-DDTHHMMSSZ.md`
296
+ - Task review: `{project}/reviews/pNN-tNN-review-YYYY-MM-DDTHHMMSSZ.md`
297
+ - Range review: `{project}/reviews/range-review-YYYY-MM-DDTHHMMSSZ.md`
298
+
299
+ The timestamp token must match the `oat_generated_at` frontmatter for the same run. In the unlikely event a file with that exact second already exists, append `-v2`, `-v3`, etc.
296
300
 
297
301
  **Review artifact template:**
298
302
 
299
303
  ````markdown
300
304
  ---
301
305
  oat_generated: true
302
- oat_generated_at: YYYY-MM-DD
306
+ oat_generated_at: YYYY-MM-DDTHH:MM:SSZ
303
307
  oat_review_scope: { scope }
304
308
  oat_review_type: { code|artifact|analysis }
305
309
  oat_review_invocation: { manual|auto|gate }
@@ -308,7 +312,7 @@ oat_project: { project-path }
308
312
 
309
313
  # {Code|Artifact|Analysis} Review: {scope}
310
314
 
311
- **Reviewed:** YYYY-MM-DD
315
+ **Reviewed:** YYYY-MM-DDTHH:MM:SSZ
312
316
  **Scope:** {scope description}
313
317
  **Files reviewed:** {N}
314
318
  **Commits:** {range or count}
@@ -168,44 +168,53 @@ 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, managed `Uncapped`,
177
+ `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
+ Legacy compatibility keys remain supported for capped managed behavior:
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.codex` | `low`, `medium`, `high`, `xhigh` | Legacy concrete Codex capped target |
205
+ | `workflow.dispatchCeiling.providers.claude` | `haiku`, `sonnet`, `opus`, `fable` | Legacy concrete Claude capped target |
206
+
207
+ `Uncapped` is explicit managed state. Do not represent it by leaving policy
208
+ state absent. To request no OAT model/effort selection, set:
209
+
210
+ ```bash
211
+ oat config set workflow.dispatchPolicy.mode inherit
212
+ ```
204
213
 
205
214
  ### How enforcement works
206
215
 
207
- OAT applies the ceiling where the provider exposes a reliable mechanism. Other
208
- providers receive it as advisory.
216
+ OAT applies managed policies where the provider exposes a reliable mechanism.
217
+ Other providers receive them as advisory/unsupported.
209
218
 
210
219
  | Provider | Mechanism | Enforcement mode |
211
220
  | -------- | ------------------------- | -------------------------- |
@@ -213,17 +222,22 @@ providers receive it as advisory.
213
222
  | Claude | Task `model` parameter | `enforced` |
214
223
  | Others | None (informational only) | `advisory` / `unsupported` |
215
224
 
225
+ Codex uses effort (`low < medium < high < xhigh`) and pinned OAT role variants.
226
+ Claude uses Task `model` (`haiku < sonnet < opus < fable`) and keeps
227
+ `effort_axis=not-applicable`.
228
+
216
229
  **Verify-on-upgrade:** when the requested tier exceeds the current orchestrator
217
230
  tier (an upgrade request), the resolver sets `verifyOnDispatch: true`. The skill
218
231
  confirms the actual model used after dispatch. If the provider did not honor the
219
232
  upgrade, the enforcement log reads `advisory — provider did not honor upgrade;
220
233
  ran <tier>` instead of `enforced`.
221
234
 
222
- ### Clean break
235
+ ### Legacy compatibility
223
236
 
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.
237
+ The command group and docs path still use `dispatch-ceiling` for compatibility.
238
+ Legacy `workflow.dispatchCeiling.*` config and project `oat_dispatch_ceiling`
239
+ frontmatter remain readable as capped managed policy input. Absent legacy state
240
+ does not mean managed `Uncapped`.
227
241
 
228
242
  ### Using the resolver
229
243
 
@@ -238,9 +252,9 @@ oat project dispatch-ceiling resolve --provider claude --orchestrator-tier sonne
238
252
  ```
239
253
 
240
254
  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.
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.
244
258
 
245
259
  For non-interactive preflight checks, use:
246
260
 
@@ -269,9 +283,11 @@ Workflow preference keys live under the `workflow.*` namespace:
269
283
  - `workflow.autoNarrowReReviewScope` — boolean. Auto-narrow re-review scope to fix-task commits only in `oat-project-review-provide`. When unset, the skill prompts.
270
284
  - `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
285
  - `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`.
286
+ - `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
+ - `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
+ - `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`.
275
291
  - `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
292
 
277
293
  ### Auto artifact-review preferences
@@ -71,6 +71,61 @@ status when the configured threshold is met. `cross-provider-exec` does not do
71
71
  that interpretation; for generic prompts it still returns only the child process
72
72
  status.
73
73
 
74
+ `oat-project-implement` uses `oat gate review` per phase when a project opts in
75
+ via the `oat_phase_review_gate` plan frontmatter — a non-pausing gate that runs
76
+ after each selected phase's standard reviewer passes. See
77
+ [Reviews → Phase review gate](../workflows/projects/reviews.md#phase-review-gate)
78
+ for the frontmatter contract and how passing versus blocking gates are
79
+ dispositioned.
80
+
81
+ ### Gate completion signal
82
+
83
+ The canonical "how do I know the gate finished" signal is the structured result
84
+ `oat --json gate review` writes to stdout on exit, together with the process
85
+ exit code. Orchestrators should run the gate synchronously and read that
86
+ envelope — do **not** poll the `reviews/` directory for a file to appear or
87
+ watch the provider process's log for liveness. Filesystem and log-liveness
88
+ heuristics are unreliable: a re-gate can momentarily surface a prior round's
89
+ artifact, and a lingering provider side-process says nothing about whether the
90
+ review committed.
91
+
92
+ Every terminal envelope carries a `runId` (unique per gate invocation) and,
93
+ once an artifact exists, its `generatedAt` (the artifact's seconds-precision
94
+ `oat_generated_at`), so a caller can correlate the result to the exact artifact
95
+ and disambiguate re-gate rounds:
96
+
97
+ | `status` | Exit | Meaning |
98
+ | ---------------------------- | ---- | --------------------------------------------------------- |
99
+ | `ok` | 0 | Review completed; gate passed at the threshold. |
100
+ | `blocked` | 1 | Review completed; findings at/above the threshold. |
101
+ | `review_failed` | ≠0 | The provider target exited non-zero; no verdict. |
102
+ | `artifact_validation_failed` | 1 | Provider ran but the review artifact could not be parsed. |
103
+
104
+ `ok` and `blocked` also include `outcome`, `artifactPath`, `counts`, `scope`,
105
+ and `handoff`. Treat any status other than `ok`/`blocked` as an operational
106
+ failure, not a passing gate.
107
+
108
+ **Drive gates through `oat gate review`, not raw provider invocation.** An
109
+ orchestrator that hand-rolls the review (for example, calling
110
+ `codex exec … oat-project-review-provide <scope>` directly) and then watches
111
+ `reviews/` for a file is reimplementing — less reliably — what the CLI already
112
+ does: `oat gate review` snapshots the reviews directory, dispatches the
113
+ provider, and attributes the produced artifact by content hash, so it is immune
114
+ to a stale file lingering from a prior round. It works standalone, not only
115
+ inside the `oat-project-implement` auto-loop — a one-off final review is just:
116
+
117
+ ```bash
118
+ oat --json gate review \
119
+ --project "$PROJECT_PATH" \
120
+ --review-type code \
121
+ --review-scope final \
122
+ --exit-nonzero-on important \
123
+ 'Use oat-project-review-provide code final to review the current project'
124
+ ```
125
+
126
+ Read the resulting envelope and exit code; that is the whole completion
127
+ contract.
128
+
74
129
  ## Exec targets
75
130
 
76
131
  `oat gate cross-provider-exec` chooses from `workflow.gates.execTargets`.
@@ -68,7 +68,7 @@ Notable commands introduced in the current CLI surface:
68
68
  - `oat repo archive sync [project-name]` - hydrate archived project snapshots from the configured repo-scoped S3 archive into `.oat/projects/archived/`. The old `oat project archive sync` path remains as a deprecated shim.
69
69
  - `oat project validate-plan --project-path <path>` - validates `oat_plan_parallel_groups` metadata in `plan.md`; exits non-zero on invalid. See [Implementation Execution](../workflows/projects/implementation-execution.md#validating-plan-metadata).
70
70
  - `oat project set-mode` — deprecated no-op. Execution mode is no longer user-selectable; emits a deprecation warning and preserves the `--json` contract.
71
- - `oat gate review <prompt...>` - run a stateful OAT review through the target registry, parse the produced review artifact, and exit nonzero for configured blocking findings; produced gate reviews use `oat_review_invocation: gate` and still require `oat-project-review-receive` handoff before they are dispositioned.
71
+ - `oat gate review <prompt...>` - run a stateful OAT review through the target registry, parse the produced review artifact, and exit nonzero for configured blocking findings; produced gate reviews use `oat_review_invocation: gate` and still require `oat-project-review-receive` handoff before they are dispositioned. With `--json`, the result envelope on exit is the canonical completion signal — `status` (`ok` | `blocked` | `review_failed` | `artifact_validation_failed`), `runId`, `generatedAt`, `artifactPath` — so orchestrators should read it rather than poll the filesystem. Runs standalone (e.g. `--review-scope final`), not only inside `oat-project-implement`. See [Workflow Gates → Gate completion signal](../cli-utilities/workflow-gates.md#gate-completion-signal).
72
72
  - `oat gate cross-provider-exec <prompt...>` - choose an available exec target while avoiding the current runtime by default, then run the prompt with the chosen target's configured base command and exit with the child status.
73
73
 
74
74
  ## `oat config` surface flags
@@ -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>`.
@@ -57,6 +57,7 @@ See [Project Splitting](splitting.md) for the full parent/child model.
57
57
 
58
58
  - `oat_plan_hill_phases` — list of phase IDs to pause at for HiLL checkpoints.
59
59
  - `oat_plan_parallel_groups` — declares which phases may execute concurrently in worktrees. See below.
60
+ - `oat_phase_review_gate` — opt-in non-pausing external review gate that runs after a phase's standard reviewer passes. See below.
60
61
 
61
62
  #### oat_plan_parallel_groups
62
63
 
@@ -85,6 +86,27 @@ Each inner array is a group of phases that execute concurrently in their own wor
85
86
 
86
87
  Before dispatching, `oat-project-implement` invokes `oat project validate-plan --project-path "${PROJECT_PATH}"`. Non-zero exit blocks the run. See [CLI Reference](../../reference/cli-reference.md) and [Implementation Execution](implementation-execution.md) for details.
87
88
 
89
+ #### oat_phase_review_gate
90
+
91
+ Enable an optional, non-pausing external review gate that runs after each selected phase's standard reviewer passes and its bookkeeping is committed:
92
+
93
+ ```yaml
94
+ oat_phase_review_gate:
95
+ enabled: true
96
+ phases: [] # empty or omitted = every implementation phase
97
+ review_type: code
98
+ exit_nonzero_on: important
99
+ ```
100
+
101
+ **Semantics:**
102
+
103
+ - Missing, `null`, or `enabled: false` → disabled (default). `enabled: true` activates the gate.
104
+ - `phases` → optional. Empty or missing runs the gate after every implementation phase; a populated list restricts it to those phase IDs, each of which must exist in the plan body.
105
+ - `review_type` → optional, defaults to `code`. Only `code` is supported for phase gates.
106
+ - `exit_nonzero_on` → optional, defaults to `important`. One of `critical`, `important`, `medium`, `minor`. This is the blocking threshold: findings at or above it stop the phase; sub-threshold findings are dispositioned by the judgment sweep rather than ignored.
107
+
108
+ A malformed gate stops the run before task execution rather than being silently disabled. The gate is independent of HiLL checkpoints and reuses the existing `oat gate review` target config — it does not hardcode a `--target`. See [Reviews → Phase review gate](reviews.md#phase-review-gate) for the runtime behavior and disposition rules.
109
+
88
110
  ## Reference artifacts
89
111
 
90
112
  - `.oat/templates/*.md`