@open-agent-toolkit/cli 0.1.54 → 0.1.59
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.
- package/assets/agents/oat-phase-implementer.md +195 -238
- package/assets/docs/cli-utilities/configuration.md +7 -6
- package/assets/docs/contributing/index.md +1 -0
- package/assets/docs/contributing/smoke-testing.md +284 -0
- package/assets/docs/provider-sync/providers.md +11 -11
- package/assets/docs/provider-sync/scope-and-surface.md +2 -2
- package/assets/docs/workflows/projects/dispatch-ceiling.md +29 -26
- package/assets/docs/workflows/projects/evidence-layers.md +123 -0
- package/assets/docs/workflows/projects/implementation-execution.md +160 -406
- package/assets/docs/workflows/projects/index.md +8 -0
- package/assets/docs/workflows/projects/orchestration-model.md +190 -0
- package/assets/docs/workflows/projects/programmatic-execution.md +137 -0
- package/assets/docs/workflows/projects/review-flavors.md +129 -0
- package/assets/docs/workflows/skills/repo-improve.md +14 -0
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-agent-instructions-analyze/references/docs/provider-reference.md +5 -4
- package/assets/skills/oat-agent-instructions-apply/references/docs/provider-reference.md +5 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +6 -1
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +5 -0
- package/assets/skills/oat-project-dispatch-subagents/SKILL.md +37 -15
- package/assets/skills/oat-project-implement/SKILL.md +63 -1904
- package/assets/skills/oat-project-implement/references/completion-and-closeout.md +431 -0
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +715 -0
- package/assets/skills/oat-project-implement/references/phase-execution.md +270 -0
- package/assets/skills/oat-project-implement/references/plan-and-resume.md +279 -0
- package/assets/skills/oat-project-import-plan/SKILL.md +16 -8
- package/assets/skills/oat-project-plan/SKILL.md +15 -7
- package/assets/skills/oat-project-plan-writing/SKILL.md +74 -40
- package/assets/skills/oat-project-quick-start/SKILL.md +16 -8
- package/assets/skills/oat-project-review-provide/SKILL.md +8 -5
- package/assets/skills/oat-repo-improve/SKILL.md +17 -2
- package/assets/skills/oat-repo-improve/references/audit-playbook.md +6 -0
- package/assets/skills/oat-worktree-bootstrap/SKILL.md +22 -12
- package/assets/skills/oat-worktree-bootstrap/references/worktree-conventions.md +8 -8
- package/assets/skills/oat-worktree-bootstrap-auto/SKILL.md +233 -44
- package/dist/commands/docs/index-generate/index.d.ts.map +1 -1
- package/dist/commands/docs/index-generate/index.js +10 -5
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +7 -4
- package/dist/commands/gate/index.d.ts +9 -1
- package/dist/commands/gate/index.d.ts.map +1 -1
- package/dist/commands/gate/index.js +62 -2
- package/dist/commands/project/dispatch-ceiling/index.js +2 -2
- package/package.json +4 -4
- package/assets/skills/oat-worktree-bootstrap-auto/scripts/bootstrap.sh +0 -236
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Smoke Testing
|
|
3
|
+
description: 'Runbook for the OAT live workflow smoke runner: preflight, scenarios, evidence, cleanup, and fixture maintenance.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Smoke Testing
|
|
7
|
+
|
|
8
|
+
The smoke runner (`tools/smoke/`) drives the real OAT orchestration workflows end
|
|
9
|
+
to end against a self-contained fixture project. It provisions a disposable Git
|
|
10
|
+
worktree, hands that worktree to a live provider harness, collects durable
|
|
11
|
+
evidence of what actually happened, verifies the evidence against per-scenario
|
|
12
|
+
assertion profiles, and then removes everything it created.
|
|
13
|
+
|
|
14
|
+
Run it manually as release validation and after any change that could alter
|
|
15
|
+
orchestration behavior — dispatch, parallel phase topology, review gating, state
|
|
16
|
+
transitions, or the fixture contract itself. It is deliberately **not** part of
|
|
17
|
+
the default CI path: each run launches real provider processes and external
|
|
18
|
+
review gates, so it is operator-initiated rather than automatic.
|
|
19
|
+
|
|
20
|
+
This page describes the machinery and the process. It does not report the
|
|
21
|
+
outcome of any particular run.
|
|
22
|
+
|
|
23
|
+
## Data flow
|
|
24
|
+
|
|
25
|
+
```mermaid
|
|
26
|
+
flowchart TD
|
|
27
|
+
F["Fixture template\ntools/smoke/fixture/"] --> PRE["Preflight\ninstall + auth + fixture + local oat"]
|
|
28
|
+
PRE -->|blocked| STOP["Exit before provisioning"]
|
|
29
|
+
PRE -->|ready| PREP["Prepare / provision\ndisposable worktree + isolated config + manifest"]
|
|
30
|
+
PREP --> DRIVE["Drive\nper-harness protocol"]
|
|
31
|
+
DRIVE --> AUTO["Automated: runner launches provider"]
|
|
32
|
+
DRIVE --> OP["Operator: printed command + prompt"]
|
|
33
|
+
AUTO --> COLLECT["Collect\nevidence bundle + report"]
|
|
34
|
+
OP --> COLLECT
|
|
35
|
+
COLLECT --> CLEAN["Cleanup\nmanifest-scoped"]
|
|
36
|
+
COLLECT -.->|--keep| SKIP["Cleanup skipped"]
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Collection runs even when the drive stage fails, so a broken run still produces
|
|
40
|
+
an evidence bundle before cleanup reclaims its resources.
|
|
41
|
+
|
|
42
|
+
## Prerequisites
|
|
43
|
+
|
|
44
|
+
Preflight (`tools/smoke/runner/preflight.mjs`) derives the required runtime set
|
|
45
|
+
from both the selected drive harness and its independent gate runtime. Every
|
|
46
|
+
distinct required runtime must be installed and authenticated before
|
|
47
|
+
provisioning. Preflight also runs `oat gate target list --json` and requires the
|
|
48
|
+
configured target to report available without launching a review.
|
|
49
|
+
|
|
50
|
+
| Harness | Runtime probe | Authentication probe |
|
|
51
|
+
| ------------ | ------------------------ | --------------------- |
|
|
52
|
+
| `codex` | `codex --version` | `codex login status` |
|
|
53
|
+
| `claude` | `claude --version` | `claude auth status` |
|
|
54
|
+
| `cursor-ide` | `cursor --version` | `cursor agent status` |
|
|
55
|
+
| `cursor-cli` | `cursor-agent --version` | `cursor-agent status` |
|
|
56
|
+
|
|
57
|
+
Additional readiness requirements before a run can start:
|
|
58
|
+
|
|
59
|
+
- **`CURSOR_API_KEY` presence.** Required when the harness is `cursor-cli` or
|
|
60
|
+
`cursor-ide`, or when the selected gate runtime is Cursor (this is the case
|
|
61
|
+
for the Codex harness, whose review gate is cross-runtime). Preflight checks
|
|
62
|
+
only for a non-empty value; the key is never printed, logged, or written into
|
|
63
|
+
config, manifests, prompts, or evidence.
|
|
64
|
+
- **Local build.** Preflight requires the CLI to resolve to the freshly built
|
|
65
|
+
local dist entrypoint (`packages/cli/dist/index.js`) through the committed
|
|
66
|
+
`tools/smoke/bin/oat` shim, with a version matching source. Build the CLI
|
|
67
|
+
first (for example, `pnpm build`) so the disposable worktree does not fall
|
|
68
|
+
through to a global `oat`.
|
|
69
|
+
- **Fixture integrity.** Preflight runs the fixture validators and checks the
|
|
70
|
+
required project artifacts, presets, and seed logs before provisioning.
|
|
71
|
+
|
|
72
|
+
If any required check fails, preflight raises `PreflightError` and no
|
|
73
|
+
provisioning is started.
|
|
74
|
+
|
|
75
|
+
## Scenario selection
|
|
76
|
+
|
|
77
|
+
Select the scenario with `--scenario`. The manifest's applied scenario is the
|
|
78
|
+
authoritative selector for which assertion profile the evidence is checked
|
|
79
|
+
against.
|
|
80
|
+
|
|
81
|
+
- **`plan-review`** — proves the plan-review lifecycle: the substantive plan
|
|
82
|
+
(task IDs and parallel groups) is stable across resume, the plan gate review
|
|
83
|
+
is corroborated against gate-owned invocation evidence, and state advances
|
|
84
|
+
atomically from pre-review through reviewed to implementation-ready.
|
|
85
|
+
- **`implement`** — proves execution: one accepted, completed phase implementer
|
|
86
|
+
and one direct-root phase reviewer for each of `p01`, `p02`, and `p03`;
|
|
87
|
+
exactly five fixture markers and five bounded task commits; exact
|
|
88
|
+
at-or-below-ceiling target selection; isolated flat parallel branches with
|
|
89
|
+
fan-in after all declared dependencies; phase-review row and artifact
|
|
90
|
+
binding; explicit runtime identity status; and exactly one final code gate
|
|
91
|
+
after `p03`.
|
|
92
|
+
- **`full`** — unions the plan-review and implement profiles. It runs exactly
|
|
93
|
+
two external gates: one plan-review gate before implementation and one final
|
|
94
|
+
code gate after `p03`.
|
|
95
|
+
|
|
96
|
+
## Running
|
|
97
|
+
|
|
98
|
+
The runner entrypoint is `tools/smoke/runner/run-smoke.mjs`. `--harness` and
|
|
99
|
+
`--scenario` are always required. Drive mode defaults to `automated` and all
|
|
100
|
+
stages (`prepare`, `drive`, `collect`) run by default.
|
|
101
|
+
|
|
102
|
+
### Automated full run
|
|
103
|
+
|
|
104
|
+
Automated drive supports `codex`, `claude`, and `cursor-cli`. The runner
|
|
105
|
+
launches the provider itself and runs all three stages:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
node tools/smoke/runner/run-smoke.mjs --harness codex --scenario full
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Operator prepare/collect split
|
|
112
|
+
|
|
113
|
+
Operator mode splits the lifecycle so a noninteractive command cannot drive by
|
|
114
|
+
accident. Passing `--drive-mode operator` without `--stage` defaults to
|
|
115
|
+
`prepare` only, so you run prepare and collect as separate commands:
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
node tools/smoke/runner/run-smoke.mjs \
|
|
119
|
+
--harness claude --scenario full --drive-mode operator --stage prepare
|
|
120
|
+
# Run the printed command and paste the printed prompt in an interactive TTY.
|
|
121
|
+
node tools/smoke/runner/run-smoke.mjs \
|
|
122
|
+
--harness claude --scenario full --drive-mode operator --stage collect
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Prepare prints the disposable worktree path, the interactive provider command,
|
|
126
|
+
and the canned root prompt. Complete the driven session before running collect.
|
|
127
|
+
|
|
128
|
+
### Manual Cursor IDE flow
|
|
129
|
+
|
|
130
|
+
`cursor-ide` is operator-driven by definition, so it always uses the
|
|
131
|
+
prepare/collect shape and never substitutes a headless CLI drive. Do not pass
|
|
132
|
+
`--drive-mode operator`; its canonical report root omits the `operator/`
|
|
133
|
+
segment.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
node tools/smoke/runner/run-smoke.mjs --harness cursor-ide --scenario full --stage prepare
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Then, following `tools/smoke/protocols/cursor-ide.md`:
|
|
140
|
+
|
|
141
|
+
1. Open the printed disposable worktree in Cursor.
|
|
142
|
+
2. Start a new Agent session in that worktree.
|
|
143
|
+
3. Paste the canned root prompt printed by prepare and let the session finish.
|
|
144
|
+
4. Run the matching collect stage:
|
|
145
|
+
|
|
146
|
+
```bash
|
|
147
|
+
node tools/smoke/runner/run-smoke.mjs --harness cursor-ide --scenario full --stage collect
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
For each required review gate, the canned prompt invokes `oat gate review`
|
|
151
|
+
exactly once with the harness's fixed `--target`. Listing targets with
|
|
152
|
+
`oat gate target list` is a valid probe; invoking a gate as a probe is not,
|
|
153
|
+
because an accepted gate launch is terminal even when it fails.
|
|
154
|
+
|
|
155
|
+
### Dry run and keep
|
|
156
|
+
|
|
157
|
+
- `--dry-run` stubs the install and authentication probes and produces a drive
|
|
158
|
+
stub instead of launching a provider, letting you exercise the
|
|
159
|
+
provisioning and cleanup wiring. The fixture and local-CLI checks still run
|
|
160
|
+
for real.
|
|
161
|
+
- `--keep` short-circuits cleanup so the worktree, branches, and manifest remain
|
|
162
|
+
on disk for inspection.
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
node tools/smoke/runner/run-smoke.mjs --harness cursor-cli --scenario plan-review --dry-run --keep
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Negative controls
|
|
169
|
+
|
|
170
|
+
Negative controls prove the runner refuses to do the wrong thing.
|
|
171
|
+
|
|
172
|
+
**Unavailable target.** Set `OAT_SMOKE_FORCE_UNAVAILABLE=<harness>` to force that
|
|
173
|
+
harness's runtime probe to report unavailable. Preflight then blocks before any
|
|
174
|
+
provisioning, and the control asserts that no manifests, branches, or worktrees
|
|
175
|
+
were created. Capture the failed runner output, then normalize it:
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
OAT_SMOKE_FORCE_UNAVAILABLE=codex \
|
|
179
|
+
node tools/smoke/runner/run-smoke.mjs --harness codex --scenario plan-review \
|
|
180
|
+
> preflight-capture.txt 2>&1
|
|
181
|
+
node tools/smoke/evidence/negative.mjs \
|
|
182
|
+
--harness codex \
|
|
183
|
+
--preflight preflight-capture.txt \
|
|
184
|
+
--repository "$(pwd)" \
|
|
185
|
+
--runs-dir "$(pwd)/tools/smoke/.runs" \
|
|
186
|
+
--out tools/smoke/reports/negative-controls/codex
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
**Post-acceptance failure.** Once a child launch is accepted and then fails, that
|
|
190
|
+
outcome is terminal: any launch after an accepted failure is a Critical
|
|
191
|
+
violation. Explicit pre-start rejections before the accepted launch remain
|
|
192
|
+
valid. This control is verified through the `post-acceptance-failure` profile
|
|
193
|
+
(see below).
|
|
194
|
+
|
|
195
|
+
## Interpreting evidence reports
|
|
196
|
+
|
|
197
|
+
Reports are written outside the disposable worktree, under
|
|
198
|
+
`tools/smoke/reports/<harness>/<scenario>/` for automated runs and
|
|
199
|
+
`tools/smoke/reports/<harness>/operator/<scenario>/` for operator runs
|
|
200
|
+
(`cursor-ide` always uses the operator-free `tools/smoke/reports/cursor-ide/<scenario>/`
|
|
201
|
+
path).
|
|
202
|
+
|
|
203
|
+
The collect stage runs the collector and report generator automatically. To
|
|
204
|
+
regenerate or re-verify a report by hand:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
node tools/smoke/evidence/report.mjs --bundle <out>/bundle.json --out <out>
|
|
208
|
+
node tools/smoke/evidence/report.mjs --check <out>/report.json \
|
|
209
|
+
--expect-profile <plan-review|implement|full|unavailable-target|post-acceptance-failure>
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Reading the output:
|
|
213
|
+
|
|
214
|
+
- **`report.json` is authoritative.** It records the SHA-256 digest and sibling
|
|
215
|
+
path of the `bundle.json` it was generated from. The `report.md` table
|
|
216
|
+
(columns Assertion, Severity, Status, Description) is a derived, human-readable
|
|
217
|
+
view.
|
|
218
|
+
- **`--check` re-verification** rereads the bound bundle, validates its digest,
|
|
219
|
+
recomputes the scenario profile, and requires the caller's explicit expected
|
|
220
|
+
profile plus byte-equivalent results. It does not trust the report's stated
|
|
221
|
+
status, assertion IDs, severities, summary counts, or the bundle's own
|
|
222
|
+
scenario as the caller's intent.
|
|
223
|
+
|
|
224
|
+
The evidence is organized as three layers — launcher-owned production records,
|
|
225
|
+
independent durable corroboration from Git and the fixture, and the normalized
|
|
226
|
+
bundle and assertion report. See
|
|
227
|
+
[Evidence Layers](../workflows/projects/evidence-layers.md) for the model.
|
|
228
|
+
|
|
229
|
+
## Cleanup and recovery
|
|
230
|
+
|
|
231
|
+
Cleanup (`tools/smoke/runner/cleanup.mjs`) is manifest-scoped: it only removes
|
|
232
|
+
resources the run journaled. It runs automatically when the run errored, when a
|
|
233
|
+
full `prepare` → `drive` → `collect` lifecycle completed, or when a
|
|
234
|
+
collection-only invocation ran. `--keep` short-circuits it entirely. An operator
|
|
235
|
+
`prepare` stage therefore intentionally leaves its worktree in place for you to
|
|
236
|
+
drive.
|
|
237
|
+
|
|
238
|
+
After an interrupted run you may find:
|
|
239
|
+
|
|
240
|
+
- `tools/smoke/.runs/smoke-<branch>/` containing the `provisioning-manifest.json`
|
|
241
|
+
and the disposable `worktree/`.
|
|
242
|
+
- The outer `smoke-*` branch and any journaled child branches created for
|
|
243
|
+
parallel phases.
|
|
244
|
+
|
|
245
|
+
Recovery validates the tracked smoke marker at each ownership baseline, refuses
|
|
246
|
+
divergent branch tips, mismatched shared Git directories, missing baseline
|
|
247
|
+
markers, and any run-descendant worktree or branch absent from the journal. A
|
|
248
|
+
journaled worktree that is already gone from disk is still recoverable; a
|
|
249
|
+
contradictory or unjournaled resource fails closed with a refusal rather than
|
|
250
|
+
guessing.
|
|
251
|
+
|
|
252
|
+
To finish a stalled run, re-run the matching `--stage collect` (collection-only
|
|
253
|
+
triggers cleanup) or start a fresh run; the runner reconciles journaled
|
|
254
|
+
resources on the next errored or collection-bearing invocation. If cleanup fails
|
|
255
|
+
closed on unjournaled state, resolve that state manually before retrying.
|
|
256
|
+
|
|
257
|
+
## Updating the fixture as workflows change
|
|
258
|
+
|
|
259
|
+
When a workflow or skill contract changes shape, the fixture and its checks must
|
|
260
|
+
change with it, and a passing smoke run on the updated fixture is the acceptance
|
|
261
|
+
bar. Typical touch points:
|
|
262
|
+
|
|
263
|
+
- **Fixture plan** (`tools/smoke/fixture/project/plan.md`) — task IDs, the
|
|
264
|
+
parallel-groups declaration, each task's write target, and the expected commit
|
|
265
|
+
subject. Preflight enforces the task count, groups, and per-task integrity.
|
|
266
|
+
- **Lifecycle presets** (`tools/smoke/fixture/presets/`) — the `pre-review` and
|
|
267
|
+
`implementation-ready` frontmatter fingerprints that transition assertions
|
|
268
|
+
parse.
|
|
269
|
+
- **Protocols** (`tools/smoke/protocols/*.md`) — the canned prompts, fixed gate
|
|
270
|
+
counts, and expected per-harness topology.
|
|
271
|
+
- **Assertion profiles** (`tools/smoke/evidence/assertions.mjs`) — the expected
|
|
272
|
+
task IDs and the plan-review, implement, and full profiles.
|
|
273
|
+
- **Format contract tests** (`tools/smoke/fixture/fixture-format-contract.test.mjs`,
|
|
274
|
+
`fixture-integrity.test.mjs`, and `presets/apply-preset.test.mjs`) — run by
|
|
275
|
+
preflight and updated alongside any contract change.
|
|
276
|
+
|
|
277
|
+
Change these together, then run the affected scenario end to end. If the updated
|
|
278
|
+
fixture does not pass, the workflow change is not accepted.
|
|
279
|
+
|
|
280
|
+
## Related
|
|
281
|
+
|
|
282
|
+
- [Contributing Code](code.md)
|
|
283
|
+
- [Implementation Execution](../workflows/projects/implementation-execution.md)
|
|
284
|
+
- [Dispatch Ceiling](../workflows/projects/dispatch-ceiling.md)
|
|
@@ -12,7 +12,7 @@ description: 'Provider-specific path mappings for Claude, Cursor, Copilot, Gemin
|
|
|
12
12
|
- Project: `.agents/skills` -> `.claude/skills`, `.agents/agents` -> `.claude/agents`, `.agents/rules` -> `.claude/rules`
|
|
13
13
|
- User: `~/.agents/skills` -> `~/.claude/skills`, `~/.agents/agents` -> `~/.claude/agents`
|
|
14
14
|
- Rule files stay `.md` and are rendered with Claude-compatible frontmatter when needed
|
|
15
|
-
- Managed
|
|
15
|
+
- Managed phase implementers and optional nested workers use the exact configured candidate returned as `providers.claude.dispatchArgs.model`; OAT passes that value as the actual Agent `model`
|
|
16
16
|
|
|
17
17
|
=== "Cursor"
|
|
18
18
|
|
|
@@ -61,10 +61,10 @@ description: 'Provider-specific path mappings for Claude, Cursor, Copilot, Gemin
|
|
|
61
61
|
- Codex `max` is a first-class dispatch effort. It is present only for the Sol family in the committed supported catalogue, for both implementer and reviewer roles.
|
|
62
62
|
- Codex multi-agent dispatch uses config-defined roles (`[agents.<name>]`) and `agent_type`
|
|
63
63
|
- Codex subagent workflows require `[features] multi_agent = true` in active Codex config layers
|
|
64
|
-
-
|
|
64
|
+
- Default managed Codex execution requires root (depth 0) → phase implementer (depth 1). `agents.max_depth >= 2` enables optional nested phase-agent work; sync and direct materialization still merge that capability floor without lowering a higher target value.
|
|
65
65
|
- Project sync or materialization writes only the project's `.codex/config.toml`; explicit user-scope materialization writes only `~/.codex/config.toml`. Project scope may read the lower-precedence user depth, but never mutates user configuration.
|
|
66
|
-
-
|
|
67
|
-
-
|
|
66
|
+
- Missing depth and explicit depth `1` are sufficient for default phase execution. Invalid values or values below `1` block managed implementation preflight. `oat doctor` explains when depth `2` optional nesting is available.
|
|
67
|
+
- The phase implementer directly executes its planned tasks from one Phase Scope, preserves one bounded commit per task, and returns phase-wide verification. It does not dispatch the phase reviewer.
|
|
68
68
|
|
|
69
69
|
## Managed dispatch views
|
|
70
70
|
|
|
@@ -85,17 +85,17 @@ project `.codex` view. User-config candidates materialize under `~/.codex`.
|
|
|
85
85
|
OAT does not auto-ignore project output or create its Git commit; the team owns
|
|
86
86
|
that repository change.
|
|
87
87
|
|
|
88
|
-
At implementation time, the
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
88
|
+
At implementation time, the root passes the recorded named maximum through
|
|
89
|
+
invocation-only `--ceiling-tier`, resolves one exact candidate per phase, and
|
|
90
|
+
dispatches one phase implementer. Codex first attempts the resolver-returned
|
|
91
|
+
materialized role as the native `agent_type`. The launcher records the target,
|
|
92
|
+
model axis, and effort axis from that resolved payload; child self-report is not
|
|
93
|
+
provenance and cannot replace those values.
|
|
94
94
|
Only an explicit pre-start native role-selection rejection permits a fresh
|
|
95
95
|
pinned-child fallback. An accepted child, including one that later returns
|
|
96
96
|
`BLOCKED` or lacks telemetry, is a task outcome rather than a fallback signal.
|
|
97
97
|
Claude and Cursor bind the exact model arguments described above. A missing or
|
|
98
|
-
unselectable managed target blocks rather than falling back to the
|
|
98
|
+
unselectable managed target blocks rather than falling back to the root target
|
|
99
99
|
or a base role.
|
|
100
100
|
|
|
101
101
|
## Scope rules
|
|
@@ -48,8 +48,8 @@ Rules are currently project-scoped canonical content. Unlike skills and agents,
|
|
|
48
48
|
- `oat init --scope project` (interactive) prompts for supported providers and persists explicit true/false values.
|
|
49
49
|
- `oat sync --scope project` uses config-aware provider activation and can prompt to remediate detected mismatches.
|
|
50
50
|
- Codex project-scope subagent sync writes `.codex/config.toml` and `.codex/agents/*.toml` at command layer after path-mapping sync. Every generated project Codex variant and registration is repository-owned, version-controlled provider output. OAT provides no automatic ignore mechanism for this project output; collaborators review and commit it like other project configuration.
|
|
51
|
-
-
|
|
52
|
-
-
|
|
51
|
+
- Default Codex execution requires `root (0) → phase implementer (1)`. Sync and direct materialization continue to apply an `agents.max_depth` floor of `2` as optional nested-work capability without lowering a higher target value. A project write may read a higher lower-precedence user value and preserves it in project configuration; it writes only project `.codex/config.toml`. User scope writes only `~/.codex/config.toml` and does not read or change project configuration.
|
|
52
|
+
- Missing depth or depth `1` does not block default phase execution. Invalid values or explicit values below `1` fail managed implementation preflight. `oat doctor` reports whether optional depth-two nesting is available and gives a scope-specific repair when the configured value is unusable.
|
|
53
53
|
- Codex aggregate config drift is reported via sync/status extension metadata (`aggregateConfigHash`); it is not persisted as a separate manifest schema entry.
|
|
54
54
|
- Codex user-config materialization writes user-owned implementer and reviewer roles under the user provider directory, `~/.codex`; it does not write those roles into the repository.
|
|
55
55
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Dispatch Policy
|
|
3
|
-
description: 'How OAT combines
|
|
3
|
+
description: 'How OAT combines provider candidate ladders, project and phase named ceilings, exact phase-agent dispatch, and provider-specific enforcement.'
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Dispatch Policy
|
|
@@ -12,15 +12,15 @@ constraints:
|
|
|
12
12
|
or repo-local config. Each named tier contains one or more exact candidates.
|
|
13
13
|
- A **named ceiling** is a project or phase maximum such as `balanced` or
|
|
14
14
|
`high`. It is not an enduring model-family or effort preference.
|
|
15
|
-
- A **
|
|
16
|
-
time at or below the named maximum.
|
|
15
|
+
- A **phase target** is one exact configured candidate selected at invocation
|
|
16
|
+
time at or below the named maximum. Optional nested work resolves separately.
|
|
17
17
|
|
|
18
18
|
The CLI command remains `oat project dispatch-ceiling resolve` for compatibility.
|
|
19
19
|
Legacy `workflow.dispatchCeiling.*` and `oat_dispatch_ceiling` values remain
|
|
20
20
|
readable, but new projects use ordered candidates plus `oat_dispatch_policy`.
|
|
21
21
|
|
|
22
22
|
For raw config keys, see [Configuration](../../cli-utilities/configuration.md).
|
|
23
|
-
For the
|
|
23
|
+
For the root-owned phase-agent loop, see
|
|
24
24
|
[Implementation Execution](implementation-execution.md).
|
|
25
25
|
|
|
26
26
|
## Named Policy Choices
|
|
@@ -36,8 +36,8 @@ For the coordinator and task-worker loop, see
|
|
|
36
36
|
|
|
37
37
|
A named `High` ceiling therefore keeps configured Economy, Balanced, and High
|
|
38
38
|
candidates eligible and available. It does not pin Sol, `opus`, one Cursor
|
|
39
|
-
string, or one effort value. The
|
|
40
|
-
|
|
39
|
+
string, or one effort value. The project root chooses one exact candidate it
|
|
40
|
+
judges sufficient for the phase.
|
|
41
41
|
|
|
42
42
|
`Uncapped` is explicit managed state. It is not represented by omitted policy
|
|
43
43
|
state. `Unresolved` is a planning or preflight deferral and cannot begin
|
|
@@ -179,7 +179,7 @@ The final candidate in a named tier defines that tier's reviewer ceiling. Lower
|
|
|
179
179
|
reviewer selection requires a separate reviewed contract; a normal reviewer
|
|
180
180
|
does not use task candidate flags.
|
|
181
181
|
|
|
182
|
-
## Exact
|
|
182
|
+
## Exact Phase Resolution
|
|
183
183
|
|
|
184
184
|
Planning and implementation preflight resolve the active policy first:
|
|
185
185
|
|
|
@@ -190,9 +190,9 @@ oat project dispatch-ceiling resolve \
|
|
|
190
190
|
--json
|
|
191
191
|
```
|
|
192
192
|
|
|
193
|
-
Before each managed capped
|
|
194
|
-
|
|
195
|
-
|
|
193
|
+
Before each managed capped phase or bounded fix continuation, the root requests
|
|
194
|
+
one exact configured candidate. It passes the recorded project or narrower
|
|
195
|
+
phase maximum through the
|
|
196
196
|
invocation-only `--ceiling-tier` option:
|
|
197
197
|
|
|
198
198
|
```bash
|
|
@@ -237,23 +237,23 @@ Successful JSON reports:
|
|
|
237
237
|
|
|
238
238
|
The resolver rejects a missing candidate, an above-ceiling candidate, an
|
|
239
239
|
ambiguous route, malformed ordering, a reviewer candidate request, or controls
|
|
240
|
-
that cannot compile exactly. The
|
|
241
|
-
|
|
240
|
+
that cannot compile exactly. The root blocks instead of reusing its own target,
|
|
241
|
+
a base role, or a provider default.
|
|
242
242
|
|
|
243
243
|
`--preferred` remains available for legacy scalar ceilings and managed
|
|
244
|
-
`Uncapped` compatibility. It is not the exact managed
|
|
244
|
+
`Uncapped` compatibility. It is not the exact managed phase-agent selection
|
|
245
245
|
path.
|
|
246
246
|
|
|
247
247
|
## Provider Enforcement
|
|
248
248
|
|
|
249
|
-
| Provider | Exact
|
|
249
|
+
| Provider | Exact phase-agent or optional-child invocation | Failure behavior |
|
|
250
250
|
| -------- | ---------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- |
|
|
251
251
|
| Codex | Use `providers.codex.dispatchArgs.variant` as `agent_type`; otherwise launch a fresh child pinned to the returned model and effort | Block if neither exact route is usable |
|
|
252
252
|
| Claude | Pass `providers.claude.dispatchArgs.model` as the actual Task `model` | Block if the model cannot be applied |
|
|
253
253
|
| Cursor | Pass `providers.cursor.dispatchArgs.model` byte-for-byte as the actual invocation model; treat it as opaque | Block rather than normalize or substitute |
|
|
254
254
|
| Other | Use a registered provider adapter when it can compile exact controls | Unsupported providers remain advisory |
|
|
255
255
|
|
|
256
|
-
Materialized Codex roles exist before
|
|
256
|
+
Materialized Codex roles exist before phase dispatch after project/user sync.
|
|
257
257
|
The supported catalogue is committed project output; custom Codex candidates
|
|
258
258
|
materialize according to config ownership. Workflow correctness still keeps a
|
|
259
259
|
fresh pinned-child fallback and does not require provider restart or hot reload.
|
|
@@ -290,20 +290,23 @@ and prompts, stdout and stderr, exit and duration data, and capture-environment
|
|
|
290
290
|
details such as user-specific binary paths; it is not limited to the structured
|
|
291
291
|
second-pass projection.
|
|
292
292
|
|
|
293
|
-
##
|
|
293
|
+
## Phase and Optional-Worker Layers
|
|
294
294
|
|
|
295
|
-
|
|
295
|
+
The phase implementer directly implements the phase tasks from one Phase Scope
|
|
296
|
+
and:
|
|
296
297
|
|
|
297
|
-
1.
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
2. **Task worker:** receives exactly one Task Scope with one task ID, file
|
|
302
|
-
boundary, verification commands, commit convention, and exact dispatch
|
|
303
|
-
payload. It implements and commits that task, then stops.
|
|
298
|
+
1. reads phase artifacts once and preserves dependency order;
|
|
299
|
+
2. directly implements each planned task;
|
|
300
|
+
3. creates and verifies one bounded commit per task; and
|
|
301
|
+
4. runs phase-wide verification before returning to the root.
|
|
304
302
|
|
|
305
|
-
|
|
306
|
-
|
|
303
|
+
Optional nested workers or recon agents resolve their own exact candidates only
|
|
304
|
+
when they provide a concrete benefit. They are not required for ordinary plan
|
|
305
|
+
tasks and do not own phase commits or review dispatch.
|
|
306
|
+
|
|
307
|
+
Tasks run serially in the same worktree. Parallelism remains limited to
|
|
308
|
+
plan-declared phase worktrees unless optional work has explicitly isolated
|
|
309
|
+
write authority. See
|
|
307
310
|
[Implementation Execution](implementation-execution.md) for the full loop.
|
|
308
311
|
|
|
309
312
|
## Dispatch Report V1 and Producer Provenance
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Evidence Layers
|
|
3
|
+
description: 'The three-layer dispatch evidence model — policy resolution, launcher-owned configured invocation, and optional runtime-observed identity — used across dispatch records and smoke verification.'
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Evidence Layers
|
|
7
|
+
|
|
8
|
+
OAT dispatch evidence is layered so that trust flows from what OAT can prove
|
|
9
|
+
toward what it can only observe. The launcher always knows which policy it
|
|
10
|
+
resolved and which exact route it configured and launched, so that evidence is
|
|
11
|
+
authoritative. A child's self-report of its own model is corroboration, not
|
|
12
|
+
ground truth — it may be missing, delayed, or untrusted without ever
|
|
13
|
+
invalidating the configured-invocation record.
|
|
14
|
+
|
|
15
|
+
The model has **three layers**. The first two are what OAT decided and did; the
|
|
16
|
+
third is what a runtime happened to say about itself. Assertions target the
|
|
17
|
+
first two layers. The third is recorded as `reported` or `not-reported` and
|
|
18
|
+
never gates a conclusion on its own.
|
|
19
|
+
|
|
20
|
+
## Layer map
|
|
21
|
+
|
|
22
|
+
```mermaid
|
|
23
|
+
flowchart TD
|
|
24
|
+
L1["Layer 1 — Policy resolution\nnamed ceiling · candidates · capped/uncapped mode"]
|
|
25
|
+
L2["Layer 2 — Launcher-owned configured invocation\nroute · target/model/effort axes · selection reason ·\ncandidates considered · launch acceptance"]
|
|
26
|
+
L3["Layer 3 — Runtime-observed identity (optional)\nproducer + model, only under trusted provenance"]
|
|
27
|
+
|
|
28
|
+
L1 --> L2 --> L3
|
|
29
|
+
|
|
30
|
+
A["Assertions"] -->|assert on| L1
|
|
31
|
+
A -->|assert on| L2
|
|
32
|
+
A -.->|record only| L3
|
|
33
|
+
|
|
34
|
+
L3 --> R["reported\n(both present + trusted provenance)"]
|
|
35
|
+
L3 --> NR["not-reported\n(anything else normalizes here)"]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Assertions bind to Layers 1 and 2. Layer 3 is recorded as `reported` or
|
|
39
|
+
`not-reported`; its absence never invalidates Layer 2.
|
|
40
|
+
|
|
41
|
+
## Layer 1 — Policy resolution
|
|
42
|
+
|
|
43
|
+
Layer 1 is the output of the dispatch-ceiling / policy resolver: the named
|
|
44
|
+
ceiling in effect, the eligible candidates under that ceiling, and whether the
|
|
45
|
+
policy is capped (a named maximum such as `balanced` or `high`), uncapped
|
|
46
|
+
(explicit managed state), or inherit/default. It answers _what was allowed_
|
|
47
|
+
before any single task chose a target.
|
|
48
|
+
|
|
49
|
+
This layer is a maximum and a candidate set, not a selection. A named `high`
|
|
50
|
+
ceiling keeps lower configured tiers eligible; it does not pin one family or
|
|
51
|
+
effort. See [Dispatch Policy](dispatch-ceiling.md) for named policy choices,
|
|
52
|
+
candidate ladders, and the resolver contract.
|
|
53
|
+
|
|
54
|
+
## Layer 2 — Launcher-owned configured invocation
|
|
55
|
+
|
|
56
|
+
Layer 2 is the dispatch record the launcher writes when it selects and launches
|
|
57
|
+
a route. It is the **authoritative evidence of what was configured and
|
|
58
|
+
launched**, and it records:
|
|
59
|
+
|
|
60
|
+
- the selected route and the exact target, model axis, and effort axis;
|
|
61
|
+
- the `selection.reason`, drawn from the stable shared values `native-catalog`,
|
|
62
|
+
`native-catalog-unsatisfying`, `pre-start-rejection`, `inherit`, and
|
|
63
|
+
`gate-target` (adapters may add a more specific diagnostic but never replace
|
|
64
|
+
or rename these);
|
|
65
|
+
- the ordered `candidates_considered` before launch (never sorted);
|
|
66
|
+
- launch acceptance status (`accepted` or `pre-start-rejected`) and mechanism.
|
|
67
|
+
|
|
68
|
+
Because the launcher constructs the invocation payload itself, this layer does
|
|
69
|
+
not depend on any child cooperation. A launch is judged consistent only when its
|
|
70
|
+
candidate tier, selected model/effort axes, ceiling model/effort axes, policy,
|
|
71
|
+
and exact target all agree. The `atOrBelowCeiling` boolean the launcher provides
|
|
72
|
+
is retained as source evidence but is **not trusted** by assertions — they
|
|
73
|
+
recompute eligibility from the configured candidates and named ceiling instead.
|
|
74
|
+
This layer maps to Dispatch Report V1 and its provenance record; see the
|
|
75
|
+
[Dispatch Report V1 / producer provenance](dispatch-ceiling.md#dispatch-report-v1-and-producer-provenance)
|
|
76
|
+
section.
|
|
77
|
+
|
|
78
|
+
## Layer 3 — Runtime-observed identity (optional corroboration)
|
|
79
|
+
|
|
80
|
+
Layer 3 is the only layer that reflects what a runtime said about itself, and it
|
|
81
|
+
is optional corroboration. It is normalized to `reported` **only** when both the
|
|
82
|
+
`producer` and `model` are present _and_ provenance is one of
|
|
83
|
+
`runtime-observed`, `provider-output`, or `gate-corroborated`. Anything else —
|
|
84
|
+
missing producer, missing model, or a non-trusted provenance value — normalizes
|
|
85
|
+
to `not-reported`.
|
|
86
|
+
|
|
87
|
+
Requested controls, configured defaults, role-name parsing, and reviewer
|
|
88
|
+
self-identification do not become observed runtime identity. Crucially, a
|
|
89
|
+
missing or `not-reported` runtime identity **never invalidates** the
|
|
90
|
+
launcher-owned configured-invocation evidence in Layer 2. Selected model and
|
|
91
|
+
effort axes stay exact even when runtime producer identity is not reported.
|
|
92
|
+
|
|
93
|
+
## How the smoke runner consumes these layers
|
|
94
|
+
|
|
95
|
+
The smoke runner's evidence pipeline reads all three layers and asserts only on
|
|
96
|
+
the trustworthy ones. Launcher-owned records (`dispatch/<scope>-<attempt>.json`),
|
|
97
|
+
orchestration state-transition records, and gate JSON are written before
|
|
98
|
+
collection. The collector then flows the evidence through three stages:
|
|
99
|
+
|
|
100
|
+
1. **Bundle** — collect the immutable dispatch, orchestration, and gate records
|
|
101
|
+
into a normalized evidence bundle, preserving structured candidates and
|
|
102
|
+
recomputing eligible candidates through the named ceiling. Runtime identity
|
|
103
|
+
is normalized here to `reported` / `not-reported`.
|
|
104
|
+
2. **Assertion profiles** — apply the profiles that assert on Layers 1 and 2
|
|
105
|
+
(policy resolution and configured invocation), while recording Layer 3 as
|
|
106
|
+
corroboration only.
|
|
107
|
+
3. **Report** — emit the evidence report from launcher-owned records and gate
|
|
108
|
+
artifacts, carrying `reported` / `not-reported` runtime status without
|
|
109
|
+
letting a missing Layer 3 fail a Layer 2 assertion.
|
|
110
|
+
|
|
111
|
+
For how to run this end to end and when to refresh the fixture, see
|
|
112
|
+
[Smoke testing](../../contributing/smoke-testing.md).
|
|
113
|
+
|
|
114
|
+
## Related
|
|
115
|
+
|
|
116
|
+
- [Dispatch Policy](dispatch-ceiling.md) — Dispatch Report V1 and the
|
|
117
|
+
producer-provenance record that back Layers 1 and 2.
|
|
118
|
+
- [Orchestration Model](orchestration-model.md) — the dispatch topology that
|
|
119
|
+
produces these records.
|
|
120
|
+
- [Review Flavors](review-flavors.md) — how the four review flavors are recorded
|
|
121
|
+
through the same launcher-owned evidence.
|
|
122
|
+
- [Smoke testing](../../contributing/smoke-testing.md) — operating the evidence
|
|
123
|
+
pipeline against real providers.
|