@open-agent-toolkit/cli 0.1.45 → 0.1.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (112) hide show
  1. package/assets/agents/oat-phase-implementer.md +202 -191
  2. package/assets/agents/oat-reviewer.md +12 -2
  3. package/assets/config/dispatch-matrix-recommendation.json +120 -13
  4. package/assets/docs/cli-utilities/config-and-local-state.md +7 -0
  5. package/assets/docs/cli-utilities/configuration.md +183 -84
  6. package/assets/docs/cli-utilities/workflow-gates.md +161 -27
  7. package/assets/docs/contributing/skills.md +14 -8
  8. package/assets/docs/provider-sync/config.md +5 -1
  9. package/assets/docs/provider-sync/manifest-and-drift.md +6 -1
  10. package/assets/docs/provider-sync/providers.md +42 -5
  11. package/assets/docs/provider-sync/scope-and-surface.md +3 -2
  12. package/assets/docs/reference/cli-reference.md +3 -1
  13. package/assets/docs/reference/oat-directory-structure.md +27 -26
  14. package/assets/docs/workflows/projects/artifacts.md +31 -1
  15. package/assets/docs/workflows/projects/dispatch-ceiling.md +235 -174
  16. package/assets/docs/workflows/projects/implementation-execution.md +283 -253
  17. package/assets/docs/workflows/projects/lifecycle.md +26 -5
  18. package/assets/docs/workflows/projects/reviews.md +27 -2
  19. package/assets/migration/pjm-restructure.md +1 -1
  20. package/assets/public-package-versions.json +4 -4
  21. package/assets/skills/oat-project-implement/SKILL.md +347 -178
  22. package/assets/skills/oat-project-import-plan/SKILL.md +173 -16
  23. package/assets/skills/oat-project-next/SKILL.md +2 -2
  24. package/assets/skills/oat-project-plan/SKILL.md +122 -92
  25. package/assets/skills/oat-project-plan-writing/SKILL.md +246 -15
  26. package/assets/skills/oat-project-quick-start/SKILL.md +156 -94
  27. package/assets/skills/oat-project-review-provide/SKILL.md +94 -22
  28. package/dist/commands/config/index.d.ts +2 -2
  29. package/dist/commands/config/index.d.ts.map +1 -1
  30. package/dist/commands/config/index.js +129 -53
  31. package/dist/commands/doctor/index.d.ts +2 -2
  32. package/dist/commands/doctor/index.d.ts.map +1 -1
  33. package/dist/commands/doctor/index.js +102 -31
  34. package/dist/commands/gate/index.d.ts +7 -1
  35. package/dist/commands/gate/index.d.ts.map +1 -1
  36. package/dist/commands/gate/index.js +544 -67
  37. package/dist/commands/gate/review-verdict.d.ts +16 -0
  38. package/dist/commands/gate/review-verdict.d.ts.map +1 -1
  39. package/dist/commands/gate/review-verdict.js +72 -9
  40. package/dist/commands/project/dispatch-ceiling/index.d.ts.map +1 -1
  41. package/dist/commands/project/dispatch-ceiling/index.js +586 -23
  42. package/dist/commands/providers/codex/index.d.ts +4 -0
  43. package/dist/commands/providers/codex/index.d.ts.map +1 -0
  44. package/dist/commands/providers/codex/index.js +7 -0
  45. package/dist/commands/providers/codex/materialize.d.ts +5 -0
  46. package/dist/commands/providers/codex/materialize.d.ts.map +1 -0
  47. package/dist/commands/providers/codex/materialize.js +157 -0
  48. package/dist/commands/providers/index.d.ts +2 -2
  49. package/dist/commands/providers/index.d.ts.map +1 -1
  50. package/dist/commands/providers/index.js +4 -2
  51. package/dist/commands/providers/providers.types.d.ts +23 -0
  52. package/dist/commands/providers/providers.types.d.ts.map +1 -1
  53. package/dist/commands/shared/codex-strays.d.ts.map +1 -1
  54. package/dist/commands/shared/codex-strays.js +11 -1
  55. package/dist/commands/shared/frontmatter.d.ts +4 -0
  56. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  57. package/dist/commands/shared/frontmatter.js +23 -0
  58. package/dist/commands/status/index.d.ts +5 -1
  59. package/dist/commands/status/index.d.ts.map +1 -1
  60. package/dist/commands/status/index.js +10 -4
  61. package/dist/commands/sync/index.d.ts.map +1 -1
  62. package/dist/commands/sync/index.js +10 -3
  63. package/dist/commands/sync/sync.types.d.ts +5 -1
  64. package/dist/commands/sync/sync.types.d.ts.map +1 -1
  65. package/dist/config/dispatch-ceiling-preset.d.ts +4 -0
  66. package/dist/config/dispatch-ceiling-preset.d.ts.map +1 -1
  67. package/dist/config/dispatch-ceiling-preset.js +3 -0
  68. package/dist/config/dispatch-policy-options.d.ts +20 -0
  69. package/dist/config/dispatch-policy-options.d.ts.map +1 -0
  70. package/dist/config/dispatch-policy-options.js +96 -0
  71. package/dist/config/oat-config.d.ts +25 -2
  72. package/dist/config/oat-config.d.ts.map +1 -1
  73. package/dist/config/oat-config.js +154 -24
  74. package/dist/config/resolve.d.ts +8 -0
  75. package/dist/config/resolve.d.ts.map +1 -1
  76. package/dist/config/resolve.js +66 -2
  77. package/dist/engine/index.d.ts +1 -1
  78. package/dist/engine/index.d.ts.map +1 -1
  79. package/dist/engine/index.js +1 -1
  80. package/dist/engine/scanner.d.ts +1 -0
  81. package/dist/engine/scanner.d.ts.map +1 -1
  82. package/dist/engine/scanner.js +17 -1
  83. package/dist/fs/paths.d.ts +4 -0
  84. package/dist/fs/paths.d.ts.map +1 -1
  85. package/dist/fs/paths.js +18 -1
  86. package/dist/providers/ceiling/registry.d.ts +8 -5
  87. package/dist/providers/ceiling/registry.d.ts.map +1 -1
  88. package/dist/providers/ceiling/registry.js +25 -7
  89. package/dist/providers/codex/codec/catalog.d.ts +14 -0
  90. package/dist/providers/codex/codec/catalog.d.ts.map +1 -0
  91. package/dist/providers/codex/codec/catalog.js +21 -0
  92. package/dist/providers/codex/codec/config-merge.d.ts +6 -0
  93. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  94. package/dist/providers/codex/codec/config-merge.js +7 -0
  95. package/dist/providers/codex/codec/materialize.d.ts +16 -0
  96. package/dist/providers/codex/codec/materialize.d.ts.map +1 -0
  97. package/dist/providers/codex/codec/materialize.js +58 -0
  98. package/dist/providers/codex/codec/shared.d.ts +20 -0
  99. package/dist/providers/codex/codec/shared.d.ts.map +1 -1
  100. package/dist/providers/codex/codec/shared.js +107 -6
  101. package/dist/providers/codex/codec/sync-extension.d.ts +7 -1
  102. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  103. package/dist/providers/codex/codec/sync-extension.js +299 -52
  104. package/dist/providers/identity/availability.d.ts +24 -1
  105. package/dist/providers/identity/availability.d.ts.map +1 -1
  106. package/dist/providers/identity/availability.js +253 -19
  107. package/dist/providers/identity/stamp.d.ts.map +1 -1
  108. package/dist/providers/identity/stamp.js +4 -0
  109. package/dist/shared/types.d.ts +1 -0
  110. package/dist/shared/types.d.ts.map +1 -1
  111. package/dist/shared/types.js +4 -0
  112. package/package.json +2 -2
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-import-plan
3
- version: 1.4.2
3
+ version: 1.4.4
4
4
  description: Use when you have an external markdown plan to execute with OAT. Preserves the source plan and normalizes it into canonical plan.md format.
5
5
  argument-hint: '<path-to-plan.md> [--provider codex|cursor|claude] [--project <name>]'
6
6
  oat_gateable: true
@@ -13,6 +13,13 @@ allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
13
13
 
14
14
  Import a markdown plan from an external coding provider and normalize it into OAT project artifacts.
15
15
 
16
+ Provider native plan mode uses this same path: provider-plan-via-import
17
+ preserves the provider plan first, and provider plan dispatch readiness
18
+ inherits the same import workflow contract below, including complete ladder
19
+ adoption, the project named ceiling, the `Shared Phase-Review Setup Contract`,
20
+ and the rule that readiness and completion follow only after a durable review
21
+ disposition. It does not add a separate provider-plan prompt.
22
+
16
23
  ## Prerequisites
17
24
 
18
25
  - External plan exists as a local markdown file.
@@ -154,10 +161,41 @@ If already present, write timestamped copy:
154
161
 
155
162
  - `references/imported-plan-YYYY-MM-DD-HHMM.md`
156
163
 
164
+ ### Step 2.5: Snapshot Explicit Phase-Review Setting Before Plan Normalization
165
+
166
+ Before any template-based create, update, replacement, or normalization of
167
+ `"$PROJECT_PATH/plan.md"`, inspect these sources in precedence order:
168
+
169
+ 1. Existing destination `plan.md`, when it contains a resumed explicit value.
170
+ 2. The preserved imported source, when it contains an imported explicit value
171
+ and the destination did not contain the key.
172
+
173
+ Snapshot the key presence of `oat_phase_review_gate` as a separate boolean;
174
+ presence is not truthiness and is authoritative regardless of validity. When
175
+ present, snapshot the complete explicit value as the exact YAML frontmatter
176
+ entry, including its full nested mapping or scalar form. Preserve enabled,
177
+ disabled, selected-phase, `null`, and malformed-for-contract values verbatim;
178
+ do not normalize, validate, or reconstruct the value while taking the snapshot.
179
+
180
+ If both sources contain the key, the resumed destination value wins so an
181
+ import cannot silently replace a project-level choice. Resumed and imported
182
+ settings therefore preserve their complete explicit value across
183
+ normalization. Explicit presence must not trigger a target probe or re-prompt,
184
+ even when the preserved value is `null` or malformed for the phase-review
185
+ contract.
186
+
157
187
  ### Step 3: Normalize Into Canonical OAT plan.md
158
188
 
159
189
  Create/update `"$PROJECT_PATH/plan.md"` using `.oat/templates/plan.md` and map imported content into the canonical structure. Apply `oat-project-plan-writing` invariants after mapping:
160
190
 
191
+ Restore the exact snapshot into the resulting `plan.md` frontmatter as part of
192
+ the first normalized plan write, before any later frontmatter rewrite and
193
+ before Step 4.25 invokes the shared setup contract. Carry the snapshot
194
+ losslessly through every subsequent plan update. When the key was explicitly
195
+ present, its complete value must still be present exactly as captured; do not
196
+ probe, re-prompt, validate, or replace it here. When the key was absent, do not
197
+ invent one before the shared setup contract runs.
198
+
161
199
  - `## Phase N`
162
200
  - `### Task pNN-tNN` (stable task IDs)
163
201
  - Step structure (RED/GREEN/Refactor/Verify/Commit)
@@ -173,26 +211,105 @@ Normalization rules:
173
211
 
174
212
  Dispatch Profile import handling:
175
213
 
176
- - Preserve recognizable OAT-format `## Dispatch Profile` rows as user-authored constraints or preferences.
177
- - Treat foreign model or effort hints as dispatch constraints only when the source clearly presents them as explicit requirements or preferences.
178
- - Otherwise preserve model or effort hints as rationale/context in the relevant task or phase text and let runtime selection decide.
214
+ - Preserve recognizable OAT-format `## Dispatch Profile` rows only when
215
+ they use phase named ceilings at or below the project ceiling.
216
+ - Preserve foreign model or effort hints as rationale/context in the relevant
217
+ task or phase text. Do not turn them into enduring exact model-family or
218
+ effort preferences.
179
219
  - Do not generate Dispatch Profile recommendation rows during import.
180
220
 
181
221
  ### Step 4: Update Plan Metadata
182
222
 
183
223
  Set frontmatter in `"$PROJECT_PATH/plan.md"`:
184
224
 
185
- - `oat_status: complete`
186
- - `oat_ready_for: null` (Step 4.5 sets this after the import-aware plan review)
225
+ - `oat_status: in_progress`
226
+ - `oat_ready_for: null`
187
227
  - `oat_phase: plan`
188
- - `oat_phase_status: complete`
228
+ - `oat_phase_status: in_progress`
189
229
  - `oat_plan_source: imported`
190
230
  - `oat_import_reference: references/imported-plan.md`
191
231
  - `oat_import_source_path: {source-path}`
192
232
  - `oat_import_provider: {codex|cursor|claude|null}`
233
+ - `oat_template: true`
234
+
235
+ These values are the interruption-safe pre-review state. Here,
236
+ `oat_template: true` keeps the normalized plan owned by the current import
237
+ workflow until its review disposition is durable. If the skill pauses, is
238
+ interrupted, or cannot resolve dispatch before Step 4.6, persist and commit this
239
+ state. `oat-project-next` must route it back to the same planning workflow and
240
+ cannot advance it to implementation.
241
+
242
+ ### Step 4.1: Adopt Complete Ladders and Record the Named Ceiling
243
+
244
+ Invoke the `Complete Dispatch Ladder Adoption Contract` from
245
+ `oat-project-plan-writing`. If the effective ladder is missing or incomplete,
246
+ show the complete bundled recommendation and ask for its owning scope before
247
+ running exactly one of:
248
+
249
+ ```bash
250
+ oat config adopt dispatch-matrix --shared
251
+ oat config adopt dispatch-matrix --local
252
+ oat config adopt dispatch-matrix --user
253
+ ```
254
+
255
+ Adoption preserves explicit cells. Re-run the resolver and completeness check.
256
+ An incomplete or missing ladder after adoption blocks readiness; do not
257
+ overwrite explicit cells or infer provider defaults. Non-interactive import
258
+ also blocks on a missing or incomplete ladder.
259
+
260
+ The selected scope owns only reusable ladders. A project-specific active policy
261
+ or ceiling must not be written to user `~/.oat/config.json`. Resolve or ask
262
+ for the project named ceiling, then persist only the maximum constraint in
263
+ `"$PROJECT_PATH/state.md"`:
264
+
265
+ ```yaml
266
+ oat_dispatch_policy:
267
+ mode: managed
268
+ policy: high
269
+ source: project-state
270
+ ```
271
+
272
+ The named `High` tier is a maximum, not an exact family preference:
273
+ configured `Economy`, `Balanced`, and `High` candidates remain
274
+ available at or below it. An optional phase Dispatch Profile may narrow the
275
+ maximum. Use the canonical
276
+ `oat project dispatch-ceiling choices --format markdown` prompt when no
277
+ project ceiling resolves. `Uncapped` and `Inherit Host Defaults` remain
278
+ explicit modes; `Leave Unresolved` is not implementation-ready.
279
+
280
+ ### Step 4.25: Configure Optional Phase Review
281
+
282
+ After normalization has produced stable phase IDs and before Step 4.5 starts
283
+ the import-aware plan artifact review, invoke the `Shared Phase-Review Setup
284
+ Contract` from `oat-project-plan-writing`. Provider native plan mode uses this
285
+ same import step and inherits its result.
286
+
287
+ If `plan.md` already contains an explicit `oat_phase_review_gate`, preserve it
288
+ through the shared contract without probing, prompting, or mutation. Resumed or
289
+ imported explicit values remain authoritative without re-prompting. Otherwise
290
+ let the contract probe qualifying targets and offer all phases, selected
291
+ phases, or disabled. If the probe fails, no target qualifies, or the user
292
+ declines, leave phase review disabled and continue with the contract's concise
293
+ status output.
294
+
295
+ This phase-review setup is independent from HiLL checkpoints. Do not read or
296
+ change HiLL fields here, and do not add a provider/model `--target` to any
297
+ lifecycle command.
193
298
 
194
299
  ### Step 4.5: Run Import-Aware Plan Artifact Review Loop
195
300
 
301
+ Before dispatching the artifact reviewer, invoke the `Managed Dispatch
302
+ Readiness and Review Contract` from `oat-project-plan-writing`:
303
+
304
+ ```bash
305
+ oat project dispatch-ceiling resolve --provider "$ACTIVE_PROVIDER" --role reviewer --preflight --json
306
+ ```
307
+
308
+ If managed resolution or the complete ladder is unresolved, return to Step
309
+ 4.1, adopt the recommendation in the selected ownership scope, and re-run the
310
+ resolver. Do not set `oat_ready_for: oat-project-implement` while either
311
+ contract is unresolved.
312
+
196
313
  Invoke the shared `Auto Artifact-Review Loop` from `oat-project-plan-writing` with target `plan` before advancing project state or handing off to implementation.
197
314
 
198
315
  Required payload:
@@ -209,14 +326,43 @@ Apply the shared loop exactly:
209
326
 
210
327
  - Resolve `workflow.autoArtifactReview.plan`; only an explicit `false` skips the loop.
211
328
  - Resolve `oat_orchestration_retry_limit` from project state, defaulting to `2`.
212
- - Dispatch `oat-reviewer` in structured mode using Tier 1 subagent when available and Tier 2 inline fallback otherwise.
329
+ - For a concrete managed target, dispatch the exact registered reviewer role. If the host cannot select it, launch a fresh Codex child pinned to the resolved model and reasoning effort with the canonical reviewer instructions.
330
+ - For Claude or Cursor, pass the exact resolver-returned
331
+ `providers.<provider>.dispatchArgs.model` as the actual invocation's model
332
+ argument. Preserve the same complete payload on timeout and retry; Cursor
333
+ strings remain opaque.
334
+ - Run inline only with verified equivalent current-host model and effort controls, or for explicit inherit/default behavior or the managed-uncapped reviewer exception. If none applies, fail closed before artifact review.
335
+ - If the reviewer times out or does not conclude, poll and nudge once, then retry the same exact role or pinned child within the retry bound. If that target-preserving retry still fails, fail closed; never downgrade the review to inline.
213
336
  - Apply Critical and Important artifact-local fixes when unambiguous and limited to canonical conformance/completeness; offer Medium and Minor fixes instead of silently applying them.
214
337
  - Re-dispatch after rewrites until clean or the retry bound is exhausted.
215
338
  - Update the `plan` artifact row in the `## Reviews` table to `passed` when clean. If residual findings remain, preserve the row and surface the residual findings before downstream handoff.
216
339
 
217
- After the loop completes or is explicitly skipped, set `"$PROJECT_PATH/plan.md"` frontmatter:
340
+ ### Step 4.6: Record Review Disposition and Mark Plan Complete
341
+
342
+ Before changing readiness, durably record the review outcome in `plan.md`:
343
+
344
+ - When review ran, update the `plan` review row in the `## Reviews` section to
345
+ the outcome reached by Step 4.5. Use `passed` only for a clean result. If
346
+ residual findings remain, retain their actual non-passed status and add a
347
+ concise residual-finding disposition in the same section.
348
+ - When `workflow.autoArtifactReview.plan` is explicitly `false`, record the
349
+ explicit skip in the `## Reviews` section as
350
+ `Plan artifact review: skipped (workflow.autoArtifactReview.plan=false)`.
351
+ Do not claim that the plan passed review.
352
+
353
+ The review row or explicit skip must be written to `plan.md`; chat or status
354
+ output alone is not durable. Only after that write succeeds, atomically update
355
+ the plan frontmatter:
218
356
 
357
+ - `oat_status: complete`
219
358
  - `oat_ready_for: oat-project-implement`
359
+ - `oat_phase_status: complete`
360
+ - `oat_template: false`
361
+
362
+ If dispatch remains unresolved, review execution fails closed, or the outcome
363
+ cannot be recorded, leave the Step 4 pre-review values unchanged and commit
364
+ them before stopping. Never expose a partially reviewed imported plan to
365
+ `oat-project-implement`. Provider-plan-via-import inherits this exact boundary.
220
366
 
221
367
  ### Step 5: Update Project State
222
368
 
@@ -284,18 +430,29 @@ Before reporting this skill as complete, run the configured gate as the final st
284
430
 
285
431
  If the command returns JSON `null`, no gate is configured; the skill is complete.
286
432
 
287
- 2. If a gate config is returned, run its `command` exactly as configured. Capture stdout, stderr, and the exit code. A zero exit code means the gate passed and the skill is complete.
433
+ 2. Export the resolved project path into the command shell:
434
+
435
+ ```bash
436
+ export PROJECT_PATH
437
+ ```
438
+
439
+ If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"` and must not include `--target <id>`. A valid reusable shape is `oat gate review --project "$PROJECT_PATH" ...`. If the declaration is missing, stop and migrate the stored gate command; do not inject or append arguments at execution time.
440
+
441
+ 3. Execute the resolved command exactly as configured. Capture stdout, stderr, the exit code, and the structured JSON result. A zero exit code means the review passed its threshold, but it does not by itself authorize artifact receipt or complete the handoff.
288
442
 
289
- 3. Review-artifact handoff:
290
- - If the gate reports a produced review artifact, the host must run `oat-project-review-receive` to receive and disposition that artifact before treating the review as consumed.
291
- - This applies to `oat gate review ...` outputs regardless of whether the gate ultimately exits zero or nonzero; the command output owns the exact artifact path, and receive-review owns disposition and archival.
443
+ 4. Review-artifact handoff:
444
+ - Parse the structured gate result. An exit code or artifact path alone never authorizes `oat-project-review-receive`.
445
+ - Invoke receive only when all three conditions hold: `status` is `ok` or `blocked`, the envelope explicitly sets `receiveEligible: true`, and a non-null `handoff` confirms the artifact was corroborated.
446
+ - `receiveEligible: false` is a hard stop even when `artifactPath` is present. Never receive `targeting_correlation_failed`; correct the project/run routing and run a new gate.
447
+ - Keep `artifact_validation_failed` outside receive until the artifact is corrected and the gate successfully revalidates it. Treat `review_failed`, unknown statuses, null handoffs, and contradictory eligibility fields as operational failures.
448
+ - `blocked` exits nonzero but is receive-eligible; `ok` exits zero and still requires durable receive disposition. Route by structured status and eligibility, not by exit code.
292
449
 
293
- 4. If the command exits nonzero, use `description` to orient the next steps and handle `onFailure`:
450
+ 5. If the command exits nonzero, use `description` to orient the next steps and handle `onFailure`:
294
451
  - `block`: read gate feedback, remediate, and re-run the gate up to `maxAttempts` attempts (default `2`). If attempts are exhausted, escalate to the human with accumulated feedback and append that feedback to `implementation.md`. Treat a launch failure, missing CLI, or no eligible runtime as escalation-biased and do not spend it as a remediation attempt.
295
452
  - `prompt`: surface the gate failure and ask the human how to proceed.
296
453
  - `warn`: record the gate failure and continue.
297
454
 
298
- 5. Runtime selection note (V1): the step runs the gate `command` as-is and reads no OAT runtime env var. By default, `oat gate review` and `oat gate cross-provider-exec` resolve the current host from built-in `hostDetectionCommand`s and avoid the same runtime when no exact target is supplied. Reusable lifecycle skill-gate commands should normally omit `--target <id>` so independent review stays provider-neutral. Use explicit targets only for manual/debug commands or deliberate local/user-specific overrides; do not hardcode provider/model targets in bundled skill guidance or shared lifecycle gate examples.
455
+ 6. Runtime selection note (V1): the step runs the gate `command` as-is and reads no OAT runtime env var. By default, `oat gate review` and `oat gate cross-provider-exec` resolve the current host from built-in `hostDetectionCommand`s and avoid the same runtime when no exact target is supplied. Reusable lifecycle skill-gate commands must not include `--target <id>` so independent review stays provider-neutral. Use explicit targets only for manual/debug commands or deliberate local/user-specific overrides; do not hardcode provider/model targets in bundled skill guidance or shared lifecycle gate examples.
299
456
 
300
457
  ### Step 7: Output Next Action
301
458
 
@@ -323,4 +480,4 @@ Report:
323
480
  - ✅ `activeProject` in `.oat/config.local.json` points to the imported project.
324
481
  - ✅ `.oat/state.md` has been refreshed locally after pointer update; it is not staged or committed.
325
482
  - ✅ Changed import artifacts are committed before handoff or pause.
326
- - ✅ Configured gate has run, and any produced review artifact has been handed off to `oat-project-review-receive` before it is treated as consumed.
483
+ - ✅ Configured gate has run, and only a corroborated, receive-eligible artifact has been handed off to `oat-project-review-receive` before it is treated as consumed.
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-next
3
- version: 1.0.5
3
+ version: 1.0.6
4
4
  description: Use when continuing work on the active OAT project. Reads project state, determines the next lifecycle action, and invokes the appropriate skill automatically.
5
5
  disable-model-invocation: true
6
6
  user-invocable: true
@@ -218,7 +218,7 @@ Otherwise, look up the target skill from the routing table for the current `oat_
218
218
  | discovery | in_progress | tier 3 | `oat-project-discover` |
219
219
  | discovery | in_progress | tier 2 | `oat-project-plan` |
220
220
  | discovery | complete | tier 1 | `oat-project-plan` |
221
- | plan | in_progress | tier 3 | `oat-project-plan` |
221
+ | plan | in_progress | tier 3 | `oat-project-quick-start` |
222
222
  | plan | in_progress | tier 2 | `oat-project-implement` \* |
223
223
  | plan | complete | tier 1 | `oat-project-implement` \* |
224
224
  | implement | in_progress | — | `oat-project-implement` \* |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: oat-project-plan
3
- version: 1.3.10
3
+ version: 1.3.12
4
4
  description: Use when design.md is complete and executable implementation tasks are needed. Breaks design into bite-sized TDD tasks in canonical plan.md format.
5
5
  oat_gateable: true
6
6
  disable-model-invocation: true
@@ -155,6 +155,20 @@ Read for implementation context:
155
155
  - `.oat/repo/knowledge/testing.md` - Testing patterns
156
156
  - `.oat/repo/knowledge/stack.md` - Available tools and dependencies
157
157
 
158
+ ### Step 4.9: Snapshot Explicit Phase-Review Setting Before Plan Overwrite
159
+
160
+ Before Step 5 can replace an existing `plan.md`, inspect the source text and
161
+ snapshot both the key presence and the complete explicit value of
162
+ `oat_phase_review_gate`. Presence is authoritative regardless of validity; it
163
+ is not a truthiness check and must distinguish a missing key from an explicit
164
+ `null` value.
165
+
166
+ Preserve the complete raw YAML entry exactly as written, including its nested
167
+ block when present. The snapshot must survive enabled, disabled,
168
+ selected-phase, `null`, and malformed values without normalizing, repairing, or
169
+ discarding them. Explicit presence remains authoritative and must not trigger a
170
+ target probe or re-prompt later in this workflow.
171
+
158
172
  ### Step 5: Initialize Plan Document
159
173
 
160
174
  Check whether a plan already exists at `"$PROJECT_PATH/plan.md"`.
@@ -165,7 +179,7 @@ Check whether a plan already exists at `"$PROJECT_PATH/plan.md"`.
165
179
  - Ask the user:
166
180
  - **Resume** (default): continue editing the existing plan in place
167
181
  - **View**: show the existing plan and stop
168
- - **Overwrite**: replace with a fresh copy of the template (warn about losing draft edits)
182
+ - **Overwrite**: replace with a fresh copy of the template (warn about losing draft edits). Restore the exact snapshot into the resulting `plan.md` frontmatter immediately after the template replacement and before any other plan write. Preserve the raw `oat_phase_review_gate` entry byte-for-byte; do not parse or normalize it.
169
183
  - If resuming: ensure the document contains the required sections from the template (at minimum: `## Reviews`, `## Implementation Complete`, `## References`). If any are missing, add them using the template headings (do not delete existing content).
170
184
 
171
185
  **If `"$PROJECT_PATH/plan.md"` does not exist:**
@@ -187,6 +201,13 @@ oat_template: false
187
201
  ---
188
202
  ```
189
203
 
204
+ When Overwrite restored an explicit phase-review snapshot, keep that exact
205
+ entry in this first rewritten frontmatter. Do not let the generic frontmatter
206
+ update remove or replace it. The shared phase-review setup in Step 12.25 must
207
+ observe the restored key and preserve it without probing, prompting, or
208
+ mutation. When the key was absent from the overwritten plan, do not invent it
209
+ before the shared setup contract runs.
210
+
190
211
  ### Step 6: Define Phases
191
212
 
192
213
  Break design implementation phases into plan phases.
@@ -316,109 +337,72 @@ If `## Planning Checklist` is missing (older plans), add it before finalizing wi
316
337
 
317
338
  ### Step 11.5: Resolve Dispatch Policy Before Implementation Readiness
318
339
 
319
- Before marking the plan ready for implementation, resolve the dispatch policy.
340
+ Before marking the plan ready for implementation, invoke the
341
+ `Complete Dispatch Ladder Adoption Contract` from
342
+ `oat-project-plan-writing` and then resolve the project named ceiling.
320
343
 
321
- Resolution order:
344
+ #### A. Ensure a complete owned ladder
322
345
 
323
- 1. Config keys `workflow.dispatchPolicy.mode` / `workflow.dispatchPolicy.policy` via the resolver CLI
324
- 2. Layered dispatch matrix / compatibility config under `workflow.dispatchCeiling.providers.<provider>` and `workflow.dispatchCeiling.providers.<provider>.<tier>`
325
- 3. Project `state.md` frontmatter key `oat_dispatch_policy`
326
- 4. Legacy project `state.md` frontmatter key `oat_dispatch_ceiling`
327
- 5. Interactive planning prompt (below)
328
- 6. Leave unresolved for implementation preflight when non-interactive
329
-
330
- If no policy resolves and the session is interactive, present the dispatch
331
- policy prompt once before final plan review:
332
-
333
- ```text
334
- Set the dispatch policy — how OAT should choose subagent model/effort controls.
335
-
336
- Managed capped policies:
337
- 1. Economy — Codex: medium · Claude: sonnet
338
- 2. Balanced — Codex: high · Claude: sonnet (recommended)
339
- 3. High — Codex: xhigh · Claude: opus
340
- 4. Frontier — Codex: xhigh · Claude: fable
341
-
342
- Managed uncapped:
343
- 5. Uncapped — OAT selects the preferred implementer/fix target without a stored maximum cap.
344
-
345
- Host defaults:
346
- 6. Inherit Host Defaults — OAT does not select model/effort controls.
347
-
348
- OAT applies managed policies where the provider exposes a reliable mechanism
349
- (Codex: pinned variants; Claude: Task model parameter). Other providers may
350
- treat managed policies as advisory until their provider column has a resolvable
351
- matrix cell.
352
-
353
- For multi-family providers such as Cursor, these options choose the abstract
354
- policy rung; concrete model values live in the dispatch matrix under
355
- `workflow.dispatchCeiling.providers.*`. If the user wants OAT's recommended
356
- starting matrix, offer `oat config adopt dispatch-matrix` for the chosen config
357
- layer before finalizing the plan.
346
+ Inspect the effective candidate ladders and compare them with the complete
347
+ bundled recommendation. If the ladder is missing or incomplete, show that full
348
+ recommendation and ask the user to choose the owning scope before running
349
+ exactly one of:
350
+
351
+ ```bash
352
+ oat config adopt dispatch-matrix --shared
353
+ oat config adopt dispatch-matrix --local
354
+ oat config adopt dispatch-matrix --user
358
355
  ```
359
356
 
360
- **Managed capped policy selection (options 1-4)** persists `mode: managed`,
361
- `policy`, and the compiled provider targets. On selection, print the exact
362
- compiled result (e.g., "Dispatch policy set: balanced Codex: high · Claude:
363
- sonnet") before proceeding.
357
+ Adoption fills missing cells but preserves explicit values. Re-run the resolver
358
+ and the completeness check. An incomplete or missing ladder after adoption
359
+ blocks readiness; do not overwrite explicit cells, infer a fallback, or mark
360
+ the plan ready. Non-interactive setup also blocks on a missing or incomplete
361
+ ladder.
364
362
 
365
- If the resolver reports that the selected policy has a missing matrix cell for
366
- the active provider/tier, run prompt-and-persist once before final review:
363
+ The owning scope stores only the reusable ladders. A project-specific active
364
+ policy or ceiling must not be written to user `~/.oat/config.json`.
367
365
 
368
- 1. Ask for the exact provider value for the missing cell, using the provider's
369
- native vocabulary (for example, `composer-2.5`, `gpt-5.5-xhigh`, `opus`, or
370
- `xhigh`), or an ordered route when escalation needs multiple targets.
371
- 2. Persist the answer to the selected config layer with
372
- `workflow.dispatchCeiling.providers.<provider>.<tier>`. Use project
373
- `state.md` only for sparse project-specific matrix overrides.
374
- 3. Re-run the resolver. Do not silently treat a missing cell as uncapped,
375
- inherited, or provider-default behavior.
366
+ #### B. Record the project named ceiling
376
367
 
377
- **Uncapped (option 5)** persists explicit managed uncapped state. It does not
378
- write provider caps, and it must not be represented by leaving dispatch policy
379
- state absent.
368
+ Resolution order:
380
369
 
381
- **Inherit Host Defaults (option 6)** persists explicit inherit/default state.
382
- Use this only when the user wants OAT to leave implementation, fix, and review
383
- model/effort controls to the executing host/provider.
370
+ 1. Project `state.md` frontmatter key `oat_dispatch_policy`
371
+ 2. Legacy project `state.md` frontmatter key `oat_dispatch_ceiling`
372
+ 3. Config defaults `workflow.dispatchPolicy.mode` /
373
+ `workflow.dispatchPolicy.policy` as a proposed starting value
374
+ 4. Interactive planning prompt
375
+ 5. Unresolved non-interactive state blocks implementation readiness
384
376
 
385
- Persist the answer in `"$PROJECT_PATH/state.md"` frontmatter using the
386
- normalized shape:
377
+ Generate the canonical choice text with:
387
378
 
388
- ```yaml
389
- oat_dispatch_policy:
390
- mode: managed
391
- policy: balanced
392
- providers:
393
- codex: high
394
- claude: sonnet
395
- source: project-state
379
+ ```bash
380
+ oat project dispatch-ceiling choices --format markdown
396
381
  ```
397
382
 
398
- For `Uncapped`:
383
+ Do not abbreviate the menu. Include every managed named tier plus `Uncapped`,
384
+ `Inherit Host Defaults`, and `Leave Unresolved`. A managed named tier
385
+ is a maximum candidate tier, not an enduring exact model-family or effort
386
+ preference. For example, a named `High` ceiling leaves configured candidates
387
+ from `Economy`, `Balanced`, and `High` available at or below the
388
+ maximum. An optional phase `## Dispatch Profile` row may narrow that maximum.
399
389
 
400
390
  ```yaml
401
391
  oat_dispatch_policy:
402
392
  mode: managed
403
- policy: uncapped
393
+ policy: high
404
394
  source: project-state
405
395
  ```
406
396
 
407
- For `Inherit Host Defaults`:
397
+ Persist this normalized shape only in `"$PROJECT_PATH/state.md"`. Never copy
398
+ compiled provider targets into project state, and do not persist the active
399
+ project ceiling to user config.
408
400
 
409
- ```yaml
410
- oat_dispatch_policy:
411
- mode: inherit
412
- source: project-state
413
- ```
414
-
415
- Do not prompt when `OAT_NON_INTERACTIVE=1` or when no user-response channel
416
- exists. In that case, leave the value unresolved. `oat-project-implement`
417
- must block before work starts if it still cannot resolve a policy.
418
-
419
- Do not treat provider default effort as the OAT dispatch policy. Provider
420
- defaults apply only for explicit inherit/default behavior or base/unpinned
421
- fallback paths.
401
+ `Uncapped` persists explicit managed uncapped state. `Inherit Host
402
+ Defaults` persists explicit inherit/default state. `Leave Unresolved` is
403
+ a planning deferral and is not implementation-ready. Do not prompt when
404
+ `OAT_NON_INTERACTIVE=1` or no response channel exists; leave the ceiling
405
+ unresolved and block readiness.
422
406
 
423
407
  ### Step 12: Review Plan with User
424
408
 
@@ -433,8 +417,37 @@ Ask: "Does this breakdown make sense? Any tasks missing?"
433
417
 
434
418
  Iterate until user confirms.
435
419
 
420
+ ### Step 12.25: Configure Optional Phase Review
421
+
422
+ After the confirmed plan has stable phase IDs and before Step 12.5 starts the
423
+ plan artifact review, invoke the `Shared Phase-Review Setup Contract` from
424
+ `oat-project-plan-writing`.
425
+
426
+ If `plan.md` already contains an explicit `oat_phase_review_gate`, preserve it
427
+ through the shared contract without probing, prompting, or mutation. Otherwise
428
+ let the contract probe qualifying targets and offer all phases, selected
429
+ phases, or disabled. If the probe fails, no target qualifies, or the user
430
+ declines, leave phase review disabled and continue with the contract's concise
431
+ status output.
432
+
433
+ This phase-review setup is independent from HiLL checkpoints. Do not read or
434
+ change HiLL fields here, and do not add a provider/model `--target` to any
435
+ lifecycle command.
436
+
436
437
  ### Step 12.5: Run Plan Artifact Review Loop
437
438
 
439
+ Before dispatching the artifact reviewer, invoke the `Managed Dispatch
440
+ Readiness and Review Contract` from `oat-project-plan-writing`:
441
+
442
+ ```bash
443
+ oat project dispatch-ceiling resolve --provider "$ACTIVE_PROVIDER" --role reviewer --preflight --json
444
+ ```
445
+
446
+ If managed resolution or the complete ladder is unresolved, return to Step
447
+ 11.5, adopt the recommendation in the selected ownership scope, and re-run the
448
+ resolver. Do not mark the spec-driven plan ready while either contract is
449
+ unresolved.
450
+
438
451
  Invoke the shared `Auto Artifact-Review Loop` from `oat-project-plan-writing` with target `plan` before setting `plan.md` to implementation-ready.
439
452
 
440
453
  Required payload:
@@ -449,7 +462,13 @@ Apply the shared loop exactly:
449
462
 
450
463
  - Resolve `workflow.autoArtifactReview.plan`; only an explicit `false` skips the loop.
451
464
  - Resolve `oat_orchestration_retry_limit` from project state, defaulting to `2`.
452
- - Dispatch `oat-reviewer` in structured mode using Tier 1 subagent when available and Tier 2 inline fallback otherwise.
465
+ - For a concrete managed target, dispatch the exact registered reviewer role. If the host cannot select it, launch a fresh Codex child pinned to the resolved model and reasoning effort with the canonical reviewer instructions.
466
+ - For Claude or Cursor, pass the exact resolver-returned
467
+ `providers.<provider>.dispatchArgs.model` value as the actual invocation's
468
+ model argument. Preserve that same complete payload on timeout and retry;
469
+ Cursor strings remain opaque.
470
+ - Run inline only with verified equivalent current-host model and effort controls, or for explicit inherit/default behavior or the managed-uncapped reviewer exception. If none applies, fail closed before artifact review.
471
+ - If the reviewer times out or does not conclude, poll and nudge once, then retry the same exact role or pinned child within the retry bound. If that target-preserving retry still fails, fail closed; never downgrade the review to inline.
453
472
  - Apply Critical and Important artifact-local fixes when unambiguous; offer Medium and Minor fixes instead of silently applying them.
454
473
  - Re-dispatch after rewrites until clean or the retry bound is exhausted.
455
474
  - Update the `plan` artifact row in the `## Reviews` table to `passed` when clean. If residual findings remain, preserve the row and surface the residual findings before downstream handoff.
@@ -564,18 +583,29 @@ Before reporting this skill as complete, run the configured gate as the final st
564
583
 
565
584
  If the command returns JSON `null`, no gate is configured; the skill is complete.
566
585
 
567
- 2. If a gate config is returned, run its `command` exactly as configured. Capture stdout, stderr, and the exit code. A zero exit code means the gate passed and the skill is complete.
586
+ 2. Export the resolved project path into the command shell:
587
+
588
+ ```bash
589
+ export PROJECT_PATH
590
+ ```
591
+
592
+ If the resolved command invokes `oat gate review`, the configured review command must already include `--project "$PROJECT_PATH"` and must not include `--target <id>`. A valid reusable shape is `oat gate review --project "$PROJECT_PATH" ...`. If the declaration is missing, stop and migrate the stored gate command; do not inject or append arguments at execution time.
593
+
594
+ 3. Execute the resolved command exactly as configured. Capture stdout, stderr, the exit code, and the structured JSON result. A zero exit code means the review passed its threshold, but it does not by itself authorize artifact receipt or complete the handoff.
568
595
 
569
- 3. Review-artifact handoff:
570
- - If the gate reports a produced review artifact, the host must run `oat-project-review-receive` to receive and disposition that artifact before treating the review as consumed.
571
- - This applies to `oat gate review ...` outputs regardless of whether the gate ultimately exits zero or nonzero; the command output owns the exact artifact path, and receive-review owns disposition and archival.
596
+ 4. Review-artifact handoff:
597
+ - Parse the structured gate result. An exit code or artifact path alone never authorizes `oat-project-review-receive`.
598
+ - Invoke receive only when all three conditions hold: `status` is `ok` or `blocked`, the envelope explicitly sets `receiveEligible: true`, and a non-null `handoff` confirms the artifact was corroborated.
599
+ - `receiveEligible: false` is a hard stop even when `artifactPath` is present. Never receive `targeting_correlation_failed`; correct the project/run routing and run a new gate.
600
+ - Keep `artifact_validation_failed` outside receive until the artifact is corrected and the gate successfully revalidates it. Treat `review_failed`, unknown statuses, null handoffs, and contradictory eligibility fields as operational failures.
601
+ - `blocked` exits nonzero but is receive-eligible; `ok` exits zero and still requires durable receive disposition. Route by structured status and eligibility, not by exit code.
572
602
 
573
- 4. If the command exits nonzero, use `description` to orient the next steps and handle `onFailure`:
603
+ 5. If the command exits nonzero, use `description` to orient the next steps and handle `onFailure`:
574
604
  - `block`: read gate feedback, remediate, and re-run the gate up to `maxAttempts` attempts (default `2`). If attempts are exhausted, escalate to the human with accumulated feedback and append that feedback to `implementation.md`. Treat a launch failure, missing CLI, or no eligible runtime as escalation-biased and do not spend it as a remediation attempt.
575
605
  - `prompt`: surface the gate failure and ask the human how to proceed.
576
606
  - `warn`: record the gate failure and continue.
577
607
 
578
- 5. Runtime selection note (V1): the step runs the gate `command` as-is and reads no OAT runtime env var. By default, `oat gate review` and `oat gate cross-provider-exec` resolve the current host from built-in `hostDetectionCommand`s and avoid the same runtime when no exact target is supplied. Reusable lifecycle skill-gate commands should normally omit `--target <id>` so independent review stays provider-neutral. Use explicit targets only for manual/debug commands or deliberate local/user-specific overrides; do not hardcode provider/model targets in bundled skill guidance or shared lifecycle gate examples.
608
+ 6. Runtime selection note (V1): the step runs the gate `command` as-is and reads no OAT runtime env var. By default, `oat gate review` and `oat gate cross-provider-exec` resolve the current host from built-in `hostDetectionCommand`s and avoid the same runtime when no exact target is supplied. Reusable lifecycle skill-gate commands must not include `--target <id>` so independent review stays provider-neutral. Use explicit targets only for manual/debug commands or deliberate local/user-specific overrides; do not hardcode provider/model targets in bundled skill guidance or shared lifecycle gate examples.
579
609
 
580
610
  ## Success Criteria
581
611