@open-agent-toolkit/cli 0.3.37 → 0.3.39

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 (84) hide show
  1. package/README.md +2 -2
  2. package/assets/bundle-metadata.json +1 -1
  3. package/assets/docs/getting-started/bootstrap.md +15 -16
  4. package/assets/docs/getting-started/tool-packs.md +15 -14
  5. package/assets/docs/provider-sync/commands.md +6 -5
  6. package/assets/docs/provider-sync/manifest-and-drift.md +26 -19
  7. package/assets/docs/provider-sync/pilot-with-a-team.md +17 -17
  8. package/assets/docs/provider-sync/providers.md +4 -4
  9. package/assets/docs/provider-sync/scope-and-surface.md +5 -5
  10. package/assets/docs/reference/cli-reference.md +8 -5
  11. package/assets/docs/reference/oat-directory-structure.md +1 -1
  12. package/assets/docs/reference/project-artifacts.md +12 -3
  13. package/assets/docs/reference/troubleshooting.md +4 -5
  14. package/assets/docs/reference/what-oat-writes.md +54 -59
  15. package/assets/docs/skills/repo-improve.md +23 -19
  16. package/assets/docs/workflows/advanced/workflow-gates.md +7 -1
  17. package/assets/docs/workflows/projects/closeout/closeout-skills.md +9 -6
  18. package/assets/docs/workflows/projects/execution/execution-skills.md +1 -2
  19. package/assets/docs/workflows/projects/execution/implementation-execution.md +3 -2
  20. package/assets/docs/workflows/projects/lifecycle.md +3 -1
  21. package/assets/public-package-versions.json +4 -4
  22. package/assets/skills/oat-project-brief/SKILL.md +1 -1
  23. package/assets/skills/oat-project-brief/references/brief-contract.md +32 -9
  24. package/assets/skills/oat-project-complete/SKILL.md +17 -7
  25. package/assets/skills/oat-project-implement/SKILL.md +2 -2
  26. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +14 -4
  27. package/assets/skills/oat-project-pr-final/SKILL.md +2 -2
  28. package/assets/skills/oat-project-pr-progress/SKILL.md +23 -12
  29. package/assets/skills/oat-repo-knowledge-index/SKILL.md +226 -131
  30. package/dist/commands/doctor/index.d.ts.map +1 -1
  31. package/dist/commands/doctor/index.js +5 -2
  32. package/dist/commands/init/index.d.ts.map +1 -1
  33. package/dist/commands/init/index.js +10 -5
  34. package/dist/commands/init/tools/index.d.ts.map +1 -1
  35. package/dist/commands/init/tools/index.js +106 -28
  36. package/dist/commands/init/tools/project-guidance.js +1 -1
  37. package/dist/commands/project/closeout-check/index.d.ts.map +1 -1
  38. package/dist/commands/project/closeout-check/index.js +4 -8
  39. package/dist/commands/project/delivery/check.d.ts.map +1 -1
  40. package/dist/commands/project/delivery/check.js +32 -14
  41. package/dist/commands/project/delivery/evidence.d.ts +39 -0
  42. package/dist/commands/project/delivery/evidence.d.ts.map +1 -1
  43. package/dist/commands/project/delivery/evidence.js +163 -17
  44. package/dist/commands/project/delivery/refresh.d.ts.map +1 -1
  45. package/dist/commands/project/delivery/refresh.js +13 -16
  46. package/dist/commands/project/journal-check/index.d.ts +2 -0
  47. package/dist/commands/project/journal-check/index.d.ts.map +1 -1
  48. package/dist/commands/project/journal-check/index.js +78 -1
  49. package/dist/commands/project/journal-check/types.d.ts +1 -1
  50. package/dist/commands/project/journal-check/types.d.ts.map +1 -1
  51. package/dist/commands/project/new/index.d.ts.map +1 -1
  52. package/dist/commands/project/new/index.js +1 -0
  53. package/dist/commands/project/new/scaffold.d.ts +1 -1
  54. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  55. package/dist/commands/project/new/scaffold.js +1 -1
  56. package/dist/commands/providers/codex/materialize.d.ts +5 -1
  57. package/dist/commands/providers/codex/materialize.d.ts.map +1 -1
  58. package/dist/commands/providers/codex/materialize.js +6 -1
  59. package/dist/commands/shared/exact-path-commit.d.ts.map +1 -1
  60. package/dist/commands/shared/exact-path-commit.js +11 -1
  61. package/dist/commands/shared/scope-option.d.ts +3 -1
  62. package/dist/commands/shared/scope-option.d.ts.map +1 -1
  63. package/dist/commands/shared/scope-option.js +4 -2
  64. package/dist/commands/status/index.d.ts.map +1 -1
  65. package/dist/commands/status/index.js +4 -1
  66. package/dist/commands/tools/install/index.d.ts.map +1 -1
  67. package/dist/commands/tools/install/index.js +1 -1
  68. package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +11 -0
  69. package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -1
  70. package/dist/commands/tools/shared/pack-lifecycle-outcome.js +16 -0
  71. package/dist/config/oat-config.d.ts +6 -1
  72. package/dist/config/oat-config.d.ts.map +1 -1
  73. package/dist/config/oat-config.js +14 -22
  74. package/dist/index.d.ts +6 -0
  75. package/dist/index.d.ts.map +1 -1
  76. package/dist/index.js +16 -0
  77. package/dist/providers/codex/codec/config-merge.d.ts +19 -0
  78. package/dist/providers/codex/codec/config-merge.d.ts.map +1 -1
  79. package/dist/providers/codex/codec/config-merge.js +75 -8
  80. package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
  81. package/dist/providers/codex/codec/sync-extension.js +84 -38
  82. package/dist/providers/cursor/codec/materialize.d.ts.map +1 -1
  83. package/dist/providers/cursor/codec/materialize.js +17 -1
  84. package/package.json +3 -3
package/README.md CHANGED
@@ -20,8 +20,8 @@ npx @open-agent-toolkit/cli --help
20
20
 
21
21
  ```bash
22
22
  oat init --scope project
23
- oat status --scope all
24
- oat sync --scope all
23
+ oat status --scope project
24
+ oat sync --scope project
25
25
  oat config describe
26
26
  ```
27
27
 
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "oatVersion": "0.3.37"
3
+ "oatVersion": "0.3.39"
4
4
  }
@@ -73,9 +73,8 @@ on your `PATH`. OAT adds its lines between `# >>> oat pre-commit hook >>>` and
73
73
 
74
74
  To remove the hook, run `oat init --scope project --no-hook` in the
75
75
  repository. (Without `--scope project`, `oat init` uses scope `all` and also
76
- writes under your home directory.) Although its
77
- help text reads "Skip optional pre-commit hook install", the flag also removes
78
- an OAT hook that is already installed. It deletes only the marked OAT block
76
+ writes under your home directory.) As its help text says, `--no-hook` removes
77
+ an installed optional pre-commit hook and skips installing one. It deletes only the marked OAT block
79
78
  and keeps any other hook content; if the file contained nothing but the OAT
80
79
  block, the file is deleted (or emptied, when it is a symlink). You can also
81
80
  delete the lines between the two markers by hand. To install the hook later
@@ -99,8 +98,7 @@ oat init --scope project
99
98
 
100
99
  ### Where tool packs install
101
100
 
102
- Guided setup uses the same per-pack defaults as `oat tools install`, with one
103
- difference described at the end of this section. The `--scope` option of `oat tools install` and `oat tools remove` lists `all` as
101
+ Guided setup uses the same per-pack defaults as `oat tools install`. The `--scope` option of `oat tools install` and `oat tools remove` lists `all` as
104
102
  its default in `--help`. For `oat tools install`, that default does not mean
105
103
  both scopes:
106
104
 
@@ -114,21 +112,22 @@ both scopes:
114
112
  The `core` pack can only live under your home directory:
115
113
 
116
114
  - `oat tools install --scope project`, with no pack name, installs the other
117
- seven packs in this repository and still installs `core` under your home
118
- directory.
119
- - `oat tools install core --scope project` exits successfully and prints
120
- `Installed core tool pack.`, but it writes nothing, neither in the
121
- repository nor in your home directory.
115
+ seven packs in this repository, skips `core`, and reports that core is
116
+ user-scope only.
117
+ - `oat tools install core --scope project` exits 1 with a message that core is
118
+ user-scope only and writes nothing.
122
119
  - `oat tools remove --all --scope project` fails with
123
120
  `Pack core does not allow project scope`, and so does
124
121
  `oat tools remove --all` with no `--scope`.
125
122
 
126
- The difference: guided setup does not take its pack scope from `--scope`.
127
- `oat init --scope project --setup`, run without an interactive terminal,
128
- installed all eight packs under the home directory. In an interactive
129
- terminal, answer **Yes** to the per-pack scope question to choose project
130
- scope, or install packs afterwards with `oat tools install <pack> --scope project`. See [Where packs install](tool-packs.md#where-packs-install) for
131
- the full rules and how to remove packs.
123
+ Guided setup takes its pack scope from an explicit `--scope`:
124
+ `oat init --scope project --setup` installs the selected packs in this
125
+ repository, skips `core`, and writes nothing under your home directory, and
126
+ `--scope user --setup` installs them at user scope only. Without an
127
+ explicit scope, guided setup keeps the per-pack defaults above. Guided setup
128
+ detects the default branch from `origin/HEAD`, then `main`, and does not run
129
+ `gh`. See [Where packs install](tool-packs.md#where-packs-install) for the full
130
+ rules and how to remove packs.
132
131
 
133
132
  Related commands:
134
133
 
@@ -12,7 +12,7 @@ This page covers CLI commands that manage bundled OAT tool packs and installed O
12
12
  > - A tool pack is a bundle of OAT skills (instructions your coding agent follows), agents, templates and scripts that installs as one unit.
13
13
  > - There are eight packs: `core` (setup diagnostics and a local copy of these docs), `workflows` (tracked projects), `docs` (documentation upkeep), `utility` (reviews and maintenance helpers), `research` (evidence gathering and comparison), `ideas` and `brainstorm` (exploring ideas), and `project-management` (backlog and decisions kept in the repository).
14
14
  > - Install one pack with an explicit scope: `oat tools install research --scope project` puts it in this repository, and `oat tools install research --scope user` puts it in your home directory. Leave out the pack name, as in `oat tools install --scope project`, to install every pack; in an interactive terminal it first asks which packs to include.
15
- > - The `core` pack only ever installs under your home directory, whatever `--scope` you pass. [Where packs install](#where-packs-install) shows what that means for each command.
15
+ > - The `core` pack only ever installs under your home directory; `--scope project` refuses or skips it. [Where packs install](#where-packs-install) shows what that means for each command.
16
16
  > - Installing the `project-management` pack is not the same as adopting project management: the repository's planning files are created only when someone runs `oat pjm init`.
17
17
  > - Read next: [Choosing packs and their ownership](#choosing-packs-and-their-ownership), [Install vs. initialize](#install-vs-initialize), [Upgrading from an earlier CLI](#upgrading-from-an-earlier-cli), and [What OAT Writes](../reference/what-oat-writes.md) for every file each command creates.
18
18
 
@@ -54,18 +54,19 @@ mean both scopes:
54
54
  packs asks where each one should go and suggests the same answer.
55
55
  - With `--scope project`, the pack is installed in this repository
56
56
  (`.agents/` and `.oat/`). With `--scope user`, it is installed under your
57
- home directory.
57
+ home directory. An explicit `--scope project` or `--scope user` writes only
58
+ that scope, with or without a pack name: a copy the pack already has at the
59
+ other scope is left as it is, and the summary names only the scope written.
58
60
  - With `--scope all` given explicitly for one pack, as in
59
61
  `oat tools install docs --scope all`, that pack is installed at both scopes.
60
62
 
61
63
  The `core` pack can only live under your home directory:
62
64
 
63
65
  - `oat tools install --scope project`, with no pack name, installs the other
64
- seven packs in this repository and still installs `core` under your home
65
- directory.
66
- - `oat tools install core --scope project` exits successfully and prints
67
- `Installed core tool pack.`, but it writes nothing, neither in the
68
- repository nor in your home directory. Run `oat tools install core` (or add
66
+ seven packs in this repository, skips `core`, and reports that core is
67
+ user-scope only; nothing is written under your home directory.
68
+ - `oat tools install core --scope project` exits 1 with a message that core is
69
+ user-scope only and writes nothing. Run `oat tools install core` (or add
69
70
  `--scope user`) to install it.
70
71
  - `oat tools remove --all --scope project` fails with
71
72
  `Pack core does not allow project scope`, and so does
@@ -773,7 +774,8 @@ Key behavior:
773
774
  - Installing is **additive**: choosing a scope for a pack never removes it from another scope. A pack installed at user scope plus a project install ends up at `project + user`, not moved
774
775
  - For every pack that allows both scopes (`ideas`, `docs`, `workflows`, `utility`, `project-management`, `research`, `brainstorm`), the interactive flow offers a per-pack end-state selector (`project`, `user`, or `both`) defaulting to the pack's current placement; leaving the default makes no changes for that pack
775
776
  - Fresh installs default to **user scope** for every pack; existing installs keep their current placement. The `--scope` default shown in `--help` is `all`, but with no `--scope` a pack that is not installed yet goes under your home directory; see [Where packs install](#where-packs-install)
776
- - `oat init --setup` uses this same additive scope resolver. In guided setup, choosing to customize scope reaches the per-pack selector; choosing the recommended defaults, or running non-interactively, applies additive per-pack defaults without removals
777
+ - `oat init --setup` uses this same additive scope resolver. In guided setup, choosing to customize scope reaches the per-pack selector; choosing the recommended defaults, or running non-interactively, applies additive per-pack defaults without removals. An explicit `oat init --scope project --setup` or `--scope user --setup` installs the selected packs at that scope only (core is skipped under `--scope project`), and guided setup never runs `gh`: it detects the default branch from `origin/HEAD`, then `main`
778
+ - An explicit `--scope project` or `--scope user` writes only that scope, for one pack or all of them; existing placements at the other scope are neither reconciled nor removed. With no `--scope` or with `--scope all`, the rules above apply
777
779
  - Every pack's fresh-install default is user scope (`defaultScope` in the release manifest); existing installs keep their current placement on re-install, so a re-install never moves a pack between scopes or creates a second copy at the other one. This applies to the per-pack subcommands too: a bare `oat tools install docs` in a repository where `docs` is already at project scope stays at project scope, and only an explicit `--scope` overrides that
778
780
  - Removing a pack from a scope happens only when you explicitly choose a narrower end-state in the interactive flow (e.g. a pack at `both` set to `project` only). All staged removals are shown in a single change summary and applied only after one batch confirmation — declining makes no changes
779
781
  - Non-interactive installs (including `--scope project`, `--scope user`, and the default pack set) are strictly additive and never remove a pack from a scope. Removal is interactive-only
@@ -963,7 +965,7 @@ The `core` pack contains foundational diagnostic and documentation skills:
963
965
 
964
966
  Key behavior:
965
967
 
966
- - Core pack always installs at **user scope** (`~/.agents/skills/`). It is the only pack whose sole allowed scope is `user`. A conflicting explicit `--scope project` is not rejected: `oat tools install core --scope project` (and the legacy `oat init tools core --scope project`) exits successfully and prints `Installed core tool pack.` but writes nothing, while `oat tools install --scope project` with no pack name still installs core under your home directory. To install core, omit `--scope` or pass `--scope user`. Keeping core in your home directory makes its skills available in any directory. See [Where packs install](#where-packs-install).
968
+ - Core pack always installs at **user scope** (`~/.agents/skills/`). It is the only pack whose sole allowed scope is `user`. A conflicting explicit `--scope project` is refused: `oat tools install core --scope project` (and the legacy `oat init tools core --scope project`) exits 1 with a message that core is user-scope only and writes nothing, and `oat tools install --scope project` with no pack name skips core and says so. To install core, omit `--scope` or pass `--scope user`. Keeping core in your home directory makes its skills available in any directory. See [Where packs install](#where-packs-install).
967
969
  - `~/.oat/docs/` is a managed directory asset: its completeness and drift are compared as a whole tree, so a partially deleted docs tree is reported as a partial `core` install rather than passing silently.
968
970
  - Core is checked by default in the `oat init tools` guided setup.
969
971
  - Installation also bundles OAT documentation to `~/.oat/docs/` for the oat-docs skill.
@@ -1277,11 +1279,10 @@ created until someone runs `oat pjm init` (see [Install vs. initialize](#install
1277
1279
  A fresh install goes to user scope, which lets you reuse packs across
1278
1280
  repositories without update churn in each one; a pack that is already installed
1279
1281
  keeps its scope. **`core` is user-only**: `oat tools install --scope project`
1280
- with no pack name still installs it in your home directory, and
1281
- `oat tools install core --scope project` reports success but installs nothing
1282
- (see [Where packs install](#where-packs-install)). `oat init --scope project --setup` does not choose
1283
- project scope for packs; customize each pack's scope at the prompt, or install
1284
- packs explicitly. Installing a pack at a second scope adds a second copy rather
1282
+ with no pack name skips it, and `oat tools install core --scope project` exits
1283
+ 1 without installing anything (see [Where packs install](#where-packs-install)).
1284
+ `oat init --scope project --setup` installs the packs you select at project
1285
+ scope. Installing a pack at a second scope adds a second copy rather
1285
1286
  than moving it, so use `oat tools migrate` to move a pack between scopes.
1286
1287
  Templates that a project-scope install writes belong to the repository after
1287
1288
  that: later pack updates and `oat tools remove` leave them alone.
@@ -206,11 +206,12 @@ Key behavior:
206
206
  project role file; `--scope user` writes only under `~/.codex`
207
207
  - `--agent-path` selects a specific canonical agent and `--role-name` overrides
208
208
  the generated role name
209
- - Managed role registration enables multi-agent support and merges an
210
- `agents.max_depth` floor of `2`
211
- - Project writes preserve a higher existing project depth or inherited user
212
- depth without mutating user configuration; user writes do not inspect or
213
- mutate project configuration
209
+ - Managed role registration adds `[features] multi_agent = true` and
210
+ `agents.max_depth = 2` only when those keys are absent; an explicit value is
211
+ kept, and each `Config:` line names a key added or a conflict
212
+ - A project write that adds `max_depth` uses a higher inherited user depth
213
+ when there is one, without mutating user configuration; user writes do not
214
+ inspect or mutate project configuration
214
215
  - Existing unrelated Codex configuration and custom roles are preserved
215
216
 
216
217
  ## Notes
@@ -54,32 +54,39 @@ Diagram: canonical assets produce provider views and a manifest; status reports
54
54
  - **What re-running `oat sync` does.** It writes unless you pass `--dry-run`.
55
55
  It recreates missing views and rewrites drifted ones from canonical, so an
56
56
  edit made in a provider copy is lost, not merged. A file you placed at a
57
- view's path without OAT is replaced too. When a skill or rule is deleted
58
- from `.agents/`, sync removes its views. When an agent is deleted or
59
- renamed, it does not; see the warning below.
57
+ view's path without OAT is replaced too. When a skill, rule or agent is
58
+ deleted from `.agents/`, sync removes its views; see the note below for
59
+ agents.
60
60
  - **What to do with a stray.** In an interactive `oat status` or `oat init` you
61
61
  can adopt it, which moves or converts it into `.agents/`. For a Cursor or
62
62
  Copilot skill you can keep it in place; OAT records the path under
63
63
  `knownStrays` in `.oat/sync/config.json` and leaves it out of later reports.
64
64
  You can also list a path there by hand.
65
65
 
66
- > [!WARNING]
67
- > Sync does not clean up after a deleted or renamed agent. With Cursor enabled,
68
- > once `.agents/agents/<name>.md` is gone, `oat sync`, `oat sync --dry-run` and
69
- > `oat status` exit 1 with
70
- > `Cursor agent definition is a symbolic link at .cursor/agents/<name>.md whose target escapes the sync scope.`
71
- > With Codex enabled, the agent's generated files stay behind. After deleting
72
- > or renaming an agent, clean up by hand:
66
+ > [!NOTE]
67
+ > From 0.3.39, sync cleans up after a deleted or renamed agent. Once
68
+ > `.agents/agents/<name>.md` is gone, `oat status` reports the pending change,
69
+ > `oat sync --dry-run` lists the removals and writes nothing, and
70
+ > `oat sync --scope project` removes the agent's `.claude/agents/`,
71
+ > `.cursor/agents/` and `.github/agents/` views, its
72
+ > `.codex/agents/<name>.toml` with any generated model variants, and its
73
+ > `[agents.<name>]` tables in `.codex/config.toml`. A rename also creates the
74
+ > new name's views. User-authored `[agents.*]` tables stay. A dangling link
75
+ > left in `.cursor/agents/`, `.claude/agents/` or `.codex/agents/` no longer
76
+ > stops sync with an `escapes the sync scope` error. At an agent view path,
77
+ > such as `.cursor/agents/<name>.md`, sync restores the managed link. Sync
78
+ > cannot write a generated file through a dangling link: at the path of a
79
+ > generated Cursor model variant, such as
80
+ > `.cursor/agents/oat-reviewer-<model>-<effort>.md`, it reports a failed
81
+ > materialization, and at a Codex role path, such as
82
+ > `.codex/agents/<name>.toml` or one of its model variants, it reports the
83
+ > role as `missing`. Either way sync exits 1; delete the link and rerun sync.
84
+ > A link whose existing target lies outside the sync scope is still refused.
73
85
  >
74
- > 1. Delete the link `.cursor/agents/<name>.md`.
75
- > 2. Delete the link `.claude/agents/<name>.md`; until it is gone, the same
76
- > error names that path instead.
77
- > 3. Delete `.codex/agents/<name>.toml`.
78
- > 4. In `.codex/config.toml`, delete the `[agents.<name>]` table.
79
- > 5. Run `oat sync --scope project`; it should now succeed.
80
- >
81
- > Skills and rules are not affected: sync removes their views when the
82
- > canonical file is deleted.
86
+ > Codex roles written by versions before 0.3.39 carry no owner header until
87
+ > the next sync rewrites them. If such an agent was deleted before you first
88
+ > synced with 0.3.39, delete its `.codex/agents/<name>.toml` and its
89
+ > `[agents.<name>]` table by hand once.
83
90
 
84
91
  ## Manifest locations
85
92
 
@@ -144,23 +144,23 @@ checkouts handle committed links was not tested.
144
144
 
145
145
  Run `oat sync --scope project`, and commit its output in the same change, when
146
146
  you add, rename, or delete a skill, agent, or rule, or change an agent or rule.
147
- Deleting or renaming an agent also needs the manual cleanup described below.
148
147
  Rules, Codex agent files and Cursor's per-model agent variants are generated
149
148
  copies, so they only change when sync runs. An edit inside an existing linked
150
149
  skill reaches Claude Code at once, because the view is a link.
151
150
 
152
151
  Make every change in `.agents/`, never in the provider folders. Re-running sync
153
152
  overwrites edits made to generated copies, replaces an untracked file sitting
154
- at a view path, and removes the view of a deleted skill or rule. Editing
155
- through a link changes the canonical file itself, which is easy to miss in
156
- review.
157
-
158
- Agents are the exception. After you delete or rename an agent, delete its old
159
- links in `.cursor/agents/` and `.claude/agents/` yourself: with Cursor enabled,
160
- `oat sync` and `oat status` stop with an error saying the link's target
161
- `escapes the sync scope` until both links are gone. Also delete its
162
- `.codex/agents/<name>.toml` file and the `[agents.<name>]` table in
163
- `.codex/config.toml`, which sync leaves behind.
153
+ at a view path, and removes the views of a deleted skill, rule, or agent.
154
+ Editing through a link changes the canonical file itself, which is easy to miss
155
+ in review.
156
+
157
+ From 0.3.39, deleting or renaming an agent needs no manual cleanup: sync
158
+ removes its old links in `.cursor/agents/`, `.claude/agents/` and
159
+ `.github/agents/`, its `.codex/agents/<name>.toml` file and its
160
+ `[agents.<name>]` table in `.codex/config.toml`. A Codex role that a version
161
+ before 0.3.39 generated for an agent deleted before the upgrade has no owner
162
+ header, so delete that file and its table by hand once (see
163
+ [Manifest and Drift](manifest-and-drift.md#quick-look)).
164
164
 
165
165
  Before committing, run `oat status --scope project`. It exits 1 when any view
166
166
  is missing or drifted, or when a stray file sits in a provider folder. For a
@@ -177,12 +177,12 @@ inside the working tree. Remove it with `oat init --scope project --no-hook`.
177
177
 
178
178
  ## Mixed tools
179
179
 
180
- | Provider | What OAT generates in the repository | What the team should know |
181
- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
182
- | Claude Code | A relative link per skill in `.claude/skills/` and per agent in `.claude/agents/`; rules as generated copies in `.claude/rules/` | The only provider with skill views, so a new skill reaches Claude Code only after sync |
183
- | Cursor | No skill files: it reads `.agents/skills`. A link per agent in `.cursor/agents/`; rules as `.cursor/rules/*.mdc` files | Its `.cursor/skills/` folder is not managed; skills found there are reported as strays |
184
- | Codex | No skill files: it reads `.agents/skills`. A generated `.codex/agents/<name>.toml` per agent, registered in `.codex/config.toml` | Sync merges into an existing `.codex/config.toml`: it adds OAT's tables, turns on `multi_agent` and raises `max_depth` to at least 2, and keeps your other settings and comments |
185
- | Gemini | Nothing; it reads skills and agents from `.agents/` directly | Nothing to commit |
180
+ | Provider | What OAT generates in the repository | What the team should know |
181
+ | ----------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
182
+ | Claude Code | A relative link per skill in `.claude/skills/` and per agent in `.claude/agents/`; rules as generated copies in `.claude/rules/` | The only provider with skill views, so a new skill reaches Claude Code only after sync |
183
+ | Cursor | No skill files: it reads `.agents/skills`. A link per agent in `.cursor/agents/`; rules as `.cursor/rules/*.mdc` files | Its `.cursor/skills/` folder is not managed; skills found there are reported as strays |
184
+ | Codex | No skill files: it reads `.agents/skills`. A generated `.codex/agents/<name>.toml` per agent, registered in `.codex/config.toml` | Sync merges into an existing `.codex/config.toml`: it adds OAT's tables, adds `multi_agent` and `max_depth` only when they are missing, keeps the values you set (reporting a conflict when OAT needs another), and keeps your other settings and comments |
185
+ | Gemini | Nothing; it reads skills and agents from `.agents/` directly | Nothing to commit |
186
186
 
187
187
  If OAT's own implementer and reviewer agents are installed in the repository,
188
188
  sync also generates one file per supported model for each of them, in
@@ -57,13 +57,13 @@ description: 'Provider-specific path mappings for Claude, Cursor, Copilot, Gemin
57
57
  - Agents are native-read from `.agents/agents` for canonical source-of-truth workflows
58
58
  - Canonical markdown agents in `.agents/agents/*.md` are exported to Codex runtime roles:
59
59
  - `.codex/agents/<role>.toml`
60
- - `.codex/config.toml` (`[features] multi_agent = true`, `[agents.<role>]` upserts)
61
- - Sync and direct materialization edit `config.toml` in place. They change only `features.multi_agent`, `agents.max_depth`, and the `description` and `config_file` keys of managed `[agents.<role>]` tables, and remove stale managed role tables. Comments (including other tools' ownership markers), blank lines, table order, and other keys stay byte for byte, and the file is not rewritten when nothing managed changed. Removing a stale role deletes its whole table, including comments inside it; comments above or after the table stay. Dotted keys and inline tables are edited where they are defined. New keys and tables are never added between another tool's `# BEGIN <label>` and `# END <label>` comments: a key goes before the block, and a table that cannot sit next to its related tables outside the block goes at the end of the file. If `features`, `agents`, or a managed role is not a table, or a key can only be added inside such a block, sync stops with an error instead of rewriting the file.
60
+ - `.codex/config.toml` (`[features] multi_agent = true` when absent, `[agents.<role>]` upserts)
61
+ - Sync and direct materialization edit `config.toml` in place. They change only the `description` and `config_file` keys of managed `[agents.<role>]` tables, add `features.multi_agent` and `agents.max_depth` only when those keys are absent, and remove stale managed role tables. An explicit `multi_agent` or `max_depth` value is never rewritten. The output (human and `--json`, including when nothing else changes) names each key added, reports a conflict for `multi_agent` other than `true` or a `max_depth` below `1`, and notes that `max_depth = 1` disables only optional nested work. Comments (including other tools' ownership markers), blank lines, table order, and other keys stay byte for byte, and the file is not rewritten when nothing managed changed. Removing a stale role deletes its whole table, including comments inside it; comments above or after the table stay. Dotted keys and inline tables are edited where they are defined. New keys and tables are never added between another tool's `# BEGIN <label>` and `# END <label>` comments: a key goes before the block, and a table that cannot sit next to its related tables outside the block goes at the end of the file. If `features`, `agents`, or a managed role is not a table, or a key can only be added inside such a block, sync stops with an error instead of rewriting the file.
62
62
  - Codex role files include OAT managed provenance headers and are regenerated by `oat sync --scope project|user|all`
63
63
  - Project sync writes and maintains the version-controlled supported catalogue: GPT-6.1 Sol and GPT-6 Luna, Sol, and Astra at `low`, `medium`, `high`, `xhigh`, and `max`; GPT-5.6 Luna and Terra through `xhigh`; and GPT-5.6 Sol through `max`. Both `oat-phase-implementer` and `oat-reviewer` receive each supported pair (66 pinned variants). Sync writes files; it does not create a Git commit.
64
64
  - Custom targets follow configuration provenance: user-config targets write only under `~/.codex`; shared, repo-local, and active-project targets write under the project's tracked `.codex` view.
65
65
  - User sync loads only the bundled canonical `oat-phase-implementer` and `oat-reviewer` definitions needed to expand user-config targets. It does not enable general user-agent mirroring, and it refuses stale user-role cleanup if either managed definition is unavailable.
66
- - Generated variants carry `supported-catalogue`, `user-config`, or `project-config` ownership. Cleanup removes stale entries only for the owner being reconciled and preserves other scopes plus unrelated Codex entries.
66
+ - Generated variants carry `supported-catalogue`, `user-config`, or `project-config` ownership, and from 0.3.39 each canonical agent's base role carries the scope's owner (`project-config` or `user-config`). Cleanup removes stale entries only for the owner being reconciled (`supported-catalogue` and `project-config` at project scope, `user-config` at user scope) and preserves other scopes plus unrelated Codex entries. A deleted or renamed agent's role files, variants, and tables are removed by full sync and by pack removal. Roles an older CLI wrote without an owner header are left in place. A stale `[agents.<role>]` table is removed only while its `config_file` still names the stale OAT-owned role file; a table you re-pointed at another file stays, and only the leftover OAT file is removed. Cleanup never deletes a role file whose real path, after resolving symlinks (including a symlinked `.codex/agents` directory), is outside the sync scope.
67
67
  - All project-generated Codex variants and config registrations are repository-owned, version-controlled output and are never auto-ignored by OAT. User-config output remains under `~/.codex`.
68
68
  - A single role can be materialized directly with `oat providers codex materialize <agent-name> --model <model-id> --effort <reasoning-effort>`; `--agent-path` selects a specific canonical markdown agent, `--role-name` overrides the generated role name, and `--scope user` writes a user-config-owned role.
69
69
  - Aggregate Codex config drift metadata (`aggregateConfigHash`) is emitted in sync/status codex extension output and intentionally not stored as a separate manifest row
@@ -71,7 +71,7 @@ description: 'Provider-specific path mappings for Claude, Cursor, Copilot, Gemin
71
71
  - Codex `max` is a first-class dispatch effort. It is supported for GPT-6.1 Sol, GPT-6 Luna, Sol, and Astra, plus GPT-5.6 Sol, for both implementer and reviewer roles.
72
72
  - Codex multi-agent dispatch uses config-defined roles (`[agents.<name>]`) and `agent_type`
73
73
  - Codex subagent workflows require `[features] multi_agent = true` in active Codex config layers
74
- - 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.
74
+ - Default managed Codex execution requires root (depth 0) → phase implementer (depth 1). `agents.max_depth >= 2` enables optional nested phase-agent work; when the key is absent, sync and direct materialization add `2` (or a higher inherited value), and they never change an explicit value.
75
75
  - 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.
76
76
  - 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.
77
77
  - 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.
@@ -25,7 +25,7 @@ Rules are currently project-scoped canonical content. Unlike skills and agents,
25
25
 
26
26
  - Mutate by default; `--dry-run` to preview
27
27
  - Explicit `--dry-run` for safe preview of mutations
28
- - Deletions are limited to manifest-tracked entries: sync removes a skill or rule view only when the manifest records it and its canonical source is gone. Deleted agents are not cleaned up this way: with Cursor enabled, sync and status stop with an `escapes the sync scope` error until you delete the agent's dangling links in `.cursor/agents/` and `.claude/agents/`, and Codex's `.codex/agents/<name>.toml` and `[agents.<name>]` table are never removed (see [Manifest and Drift](manifest-and-drift.md#quick-look)). A provider file with no canonical source and no manifest entry is reported as a stray by `oat status`, not deleted. Writing a view is not limited this way: sync replaces whatever sits at a view's expected path, including an untracked file (see the warning under [Choosing sync scope](#choosing-sync-scope))
28
+ - Deletions are limited to managed entries: sync removes a skill, rule or agent view only when the manifest records it and its canonical source is gone. A deleted or renamed agent's generated Codex role and `[agents.<name>]` table are removed through their owner header instead (0.3.39 and later; see [Manifest and Drift](manifest-and-drift.md#quick-look)). A provider file with no canonical source and no manifest entry is reported as a stray by `oat status`, not deleted. Writing a view is not limited this way: sync replaces whatever sits at a view's expected path, including an untracked file (see the warning under [Choosing sync scope](#choosing-sync-scope))
29
29
  - Cross-provider compatibility via adapters
30
30
  - Native-read assets stay canonical while provider-local adoption sources remain discoverable independently
31
31
  - Obsolete managed mappings are deleted only when their provider paths are verified clean; changed or unverified paths are preserved and detached from manifest ownership
@@ -64,7 +64,7 @@ Rules are currently project-scoped canonical content. Unlike skills and agents,
64
64
  - Cursor provider enablement still controls agents, rules, migration discovery, and legacy cleanup even though Cursor reads canonical skills without a generated skill view.
65
65
  - Copilot provider enablement still controls agents, project rules, migration discovery, and legacy cleanup even though Copilot reads canonical skills without a generated skill view.
66
66
  - 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.
67
- - 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.
67
+ - Default Codex execution requires `root (0) → phase implementer (1)`. When `agents.max_depth` is absent, sync and direct materialization add `2` (or a higher inherited value) as optional nested-work capability; they keep an explicit value and report it as a conflict when it is below `1`. 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.
68
68
  - 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.
69
69
  - Codex aggregate config drift is reported via sync/status extension metadata (`aggregateConfigHash`); it is not persisted as a separate manifest schema entry.
70
70
  - 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.
@@ -154,9 +154,9 @@ the provider views, because sync overwrites changes made in the views.
154
154
  > A bare `oat sync` uses scope `all`, so it also writes under your home
155
155
  > directory. Every sync also overwrites edits made directly in provider folders,
156
156
  > replaces an untracked file sitting at a view path, and removes the view of a
157
- > deleted skill or rule. It does not clean up after a deleted or renamed agent;
158
- > see [Manifest and Drift](manifest-and-drift.md#quick-look) for the manual
159
- > steps. Pass `--scope` explicitly, and preview with `--dry-run` when you are
157
+ > deleted skill or rule. From 0.3.39 it also removes a deleted or renamed
158
+ > agent's views, Codex role and `[agents.<name>]` table; see
159
+ > [Manifest and Drift](manifest-and-drift.md#quick-look). Pass `--scope` explicitly, and preview with `--dry-run` when you are
160
160
  > unsure.
161
161
 
162
162
  - If the run is in CI or a script, always pass `--scope project`, and preview
@@ -41,8 +41,11 @@ The first practical expansion path is to keep improving the existing owners: [Do
41
41
 
42
42
  `oat internal commit-paths --identity <operation> --message <message> -- <files...>`
43
43
  commits an explicit list of owned files with enabled Git hooks. Include tracked
44
- removals and both names of a rename. Directories, untracked missing paths,
45
- unmerged entries and paths outside the repository are rejected; the command
44
+ removals and both names of a rename. A file `HEAD` already tracks is
45
+ committed even when an ignore rule matches it or its directory (for example
46
+ `packages/cli/assets/templates/` under `packages/cli/assets/*`); an untracked
47
+ path that an ignore rule matches is rejected. Directories, untracked missing
48
+ paths, unmerged entries and paths outside the repository are rejected; the command
46
49
  does not discover ownership or expand directory/glob pathspecs. Unrelated staged
47
50
  entries and worktree bytes remain preserved, including partially staged files.
48
51
  On success, owned index/worktree bytes match the hook-final commit.
@@ -205,8 +208,8 @@ Notable commands introduced in the current CLI surface:
205
208
  - `oat review latest --json` - find the newest review artifact by `oat_generated_at`, scanning the active or specified project's `reviews/` and `reviews/archived/` directories plus ad-hoc review locations. Same-time candidates use target priority, then lifecycle recency (`final` > higher phase/task > lower phase/task). The JSON contract returns `path`, `scope`, `generatedAt`, `kind` (`project` or `adhoc`), `archived`, and `actionable`, with `null` values when no review exists. Archived project reviews remain discoverable as history but return `actionable: false`.
206
209
  - `oat project list --json` - summary state for tracked projects under the configured projects root
207
210
  - `oat project closeout-check <project-path> [--autonomous] [--json]` - read-only check of the closeout invariant: a closeout that must snapshot its post-implementation sequence cannot reach terminal completion until its `oat_post_implement_sequence` snapshot exists, every stored step is recorded complete, approval is recorded, and the snapshot reached `status: complete`. A snapshot is required when the effective layered `workflow.postImplementSequence` is configured, when the closeout is autonomous (`--autonomous`, or `OAT_AUTONOMOUS=1` in the environment even without the flag), or when `oat_workflow_mode` is `lite`. Once a snapshot exists its recorded state is authoritative and current configuration is not consulted. JSON output reports `status` (`complete`, `not_required`, or `incomplete`), the missing `invariant` (`snapshot_missing`, `snapshot_malformed`, `sequence_failed`, `pre_approval_step_pending`, `approval_pending`, `post_approval_step_pending`, or `sequence_not_complete`), `route` (`oat-project-implement` when incomplete), `nextOwner` (the next stored step and its skill, or the approval), and the evaluated `inputs`. An incomplete or malformed result exits 1. For a goal project (`oat_workflow_mode: goal`) the goal boundary is checked first and read-only: it requires `oat_goal_status: declared_met`, a valid exhaustive `oat_goal_outcome_audit`, resolved extractions, a successful `gh pr view` observation of every terminal delivery member, and delivery coverage of every accepted phase (each in a terminal delivery's effective scope with a passed, fresh integrated review and its persisted `exit_gate`); refusals report `goal_inputs_unreadable`, `goal_not_declared`, `goal_audit_invalid`, `goal_extraction_unresolved`, `goal_observation_failed`, or `goal_coverage_incomplete`, and `nextOwner` is `{ kind: "goal", skill, reasons }`, where each reason is `{ code, message, subject? }` and `skill` is the owner of the first reason: for example `not-declared` and `audit-invalid` route to `oat-project-goal`, `review-not-fresh` to `oat-project-review-provide`, `exit-carrier-not-fresh` to `oat-project-implement`, delivery and endpoint reasons such as `endpoint-unmet` to `oat-project-pr-progress`, and `phase-uncovered` to `oat-project-pr-final`. A goal snapshot may record its `pr` step as satisfied by delivery coverage (`satisfied_by: { pr: delivery-coverage }`) only once `pr` is in the completed prefix.
208
- - `oat project delivery refresh --project <path> [--json]` - goal only. Observes every registered delivery member with `gh pr view <url> --json state,headRefOid,baseRefOid` and persists, in `state.md`, only the observations (`observed_head`, `observed_base`, member `status`), the delivery `status` (`open` or `at_endpoint`), the first observed `endpoint_attainment`, and derived staleness (`integrated_review.disposition: stale`, the milestone exit carrier's `freshness: stale` with `freshness_reason`). It never rewrites a reviewed revision, a member base, or the first endpoint attainment, never writes `oat_milestone_status` or `oat_goal_recovery`, and never manufactures a passed review or a fresh carrier. `oat-project-pr-progress` and `oat-project-goal` run it before registration and re-alignment.
209
- - `oat project delivery check --project <path> --subject <mNN|dNN> [--json]` - goal only, read-only. Reports whether a milestone (before registration, against the branch head) or a registered delivery (against its observed member revisions) is deliverable: a passed integrated review that is still fresh under the bookkeeping-successor rule and an allowed, fresh milestone exit carrier (reported as `exit.source: milestone-carrier`; the closeout boundary judges each delivery's persisted `exit_gate` instead). Evidence reviewed at R covers a later head only when every intervening commit changes permitted bookkeeping in this project's tracking files (`state.md`, `plan.md`, `implementation.md`, `project-log.md`, `summary.md`) and review artifacts (including those of deliveries sharing the same member pull request); any change to `summary.md` is bookkeeping because it is derived memory, never the authority for the brief's content; code changes, edits to approved brief content, and a substantive change followed by its revert fail. JSON output carries `status` (`ok` or `undeliverable`), the subject, its ordered `scope`, `publishedHeads`, `review`, `exit`, and `deliverable`; an undeliverable subject exits 1 with the full report. A stale `review` or `exit` result carries a `reason` that starts with a code, such as `review-missing`, `review-scope-narrow`, `member-unobserved`, `base-changed`, `bound-revision-mismatch` (a bound revision differs from its member's set-once `reviewed_head`), `subject-changed`, `configuration-changed`, or a bookkeeping-successor failure: `missing-revision`, `missing-object`, `not-ancestor`, `inspection-failed`, `disallowed-path`, or `substantive-change`.
211
+ - `oat project delivery refresh --project <path> [--json]` - goal only. Observes every registered delivery member with `gh pr view <url> --json state,headRefOid,baseRefOid` and persists, in `state.md`, only the observations (`observed_head`, `observed_base`, member `status`), the delivery `status` (`open` or `at_endpoint`), the first observed `endpoint_attainment`, and derived staleness (`integrated_review.disposition: stale`, the milestone exit carrier's `freshness: stale` with `freshness_reason`). It never rewrites a reviewed revision, a member base, or the first endpoint attainment, never writes `oat_milestone_status` or `oat_goal_recovery`, and never manufactures a passed review or a fresh carrier. For `kind: stack`, members are ordered base to tip. A configured code carrier bound to a reviewed head is judged at the tip, and each lower observed head must be an ancestor of the tip; null carriers are skipped, and unreviewed-resolution carriers (`no_gate`, `project_disabled`) are evaluated exactly as for `kind: pr`. `oat-project-pr-progress` and `oat-project-goal` run it before registration and re-alignment.
212
+ - `oat project delivery check --project <path> --subject <mNN|dNN> [--json]` - goal only, read-only. Reports whether a milestone (before registration, against the branch head) or a registered delivery (against its observed member revisions) is deliverable: a passed integrated review that is still fresh under the bookkeeping-successor rule and an allowed, fresh milestone exit carrier (reported as `exit.source: milestone-carrier`; the closeout boundary judges each delivery's persisted `exit_gate` instead). For `kind: stack`, `publishedHeads` still reports every member head. For a registered delivery subject (`--subject dNN`), a configured code carrier bound to a reviewed head is judged against the tip after verifying each lower head is its ancestor (`stack-order` otherwise); null carriers and unreviewed-resolution carriers (`no_gate`, `project_disabled`) are evaluated exactly as for `kind: pr`. A milestone subject (`--subject mNN`) keeps branch-head carrier evaluation. Evidence reviewed at R covers a later head only when every intervening commit changes permitted bookkeeping in this project's tracking files (`state.md`, `plan.md`, `implementation.md`, `project-log.md`, `summary.md`) and review artifacts (including those of deliveries sharing the same member pull request). A gate-produced code-review artifact under `reviews/` also counts as permitted bookkeeping when its Reviews row has Invocation `gate` and Reviewed Head equal to the carrier's `reviewed_head`; it remains shared evidence, never integrated-review evidence or a delivery's own evidence. Any change to `summary.md` is bookkeeping because it is derived memory, never the authority for the brief's content; code changes, edits to approved brief content, and a substantive change followed by its revert fail. JSON output carries `status` (`ok` or `undeliverable`), the subject, its ordered `scope`, `publishedHeads`, `review`, `exit`, and `deliverable`; an undeliverable subject exits 1 with the full report. A stale `review` or `exit` result carries a `reason` that starts with a code, such as `review-missing`, `review-scope-narrow`, `member-unobserved`, `base-changed`, `bound-revision-mismatch` (a bound revision differs from its member's set-once `reviewed_head`), `subject-changed`, `configuration-changed`, `stack-order`, or a bookkeeping-successor failure: `missing-revision`, `missing-object`, `not-ancestor`, `inspection-failed`, `disallowed-path`, or `substantive-change`.
210
213
  - `oat project complete-state <project-path> [--archived] [--autonomous]` - apply the canonical completed-state mutation to a project's `state.md`; used by `oat-project-complete` during lifecycle closeout. It first evaluates the same closeout invariant as `oat project closeout-check` and refuses, with the same message and without writing, a configured, autonomous, or lite closeout whose snapshot is absent, malformed, or incomplete. A project whose implementation finished before closeout snapshots existed recovers by running `oat-project-implement`, which persists the snapshot (`completion-and-closeout.md` Step 15) and completes its stored steps; there is no override flag. An unconfigured, interactive, non-lite closeout without a snapshot completes as before. A goal project is also refused, without writing, by the goal boundary that `closeout-check` describes. When the project has an `implementation.md`, `complete-state` then runs the final journal evaluator (`oat project journal check --at completion`) on the same bytes immediately before its write, and refuses with the evaluator's reasons, writing nothing, when the journal does not hold its terminal shape; an override line covers only its eligible gap and never the closeout invariant. A project with a `plan.md` but no `implementation.md` is refused with `journal-missing`; only a plan-less project completes on the closeout invariant alone.
211
214
  - `oat project archive [project-path] [--project-recap-run <project-relative-path>] [--no-commit] [--new-generation <reason>]` - archive a tracked project through the same local move, summary export, and configured S3 upload path used by completion. When omitted, the project path falls back to the active project. The optional recap path must identify a `project-recap` run inside the project's `explainers/` directory. Archive verifies the complete selected package and every immutable file byte, then atomically exports one self-contained `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>.html` page before deleting the active project. The full original package remains in the archived project. JSON `projectRecapExport` identifies `runId`, `page.sourceRelativePath`, `page.originalSha256`, `page.exportedSha256`, `verifiedArtifactCount`, and the flat `exportRoot`. No tracked sidecar is created. Matching dated pages are adopted on retry; conflicting destinations, incomplete inventory coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project. Summary and PR links point to the tracked page. For synced projects, a configured S3 upload must succeed before terminal cleanup. Successful closeout makes `refs/oat/completed/<project>` authoritative, deletes the tracked JSON record and nested checkout, and leaves archive metadata sufficient for an idempotent recordless retry. With `--json`, the terminal receipt reports `completedRef`, `verifiedSourceSha`, whether `activeAliasDisposition` was `retained` or `removed`, whether `recordRetired` completed, and the parent `lifecycleCommit`. `--no-commit` is a manual/library-only option: for a synced project it still removes the checkout but deliberately leaves `lifecycleCommit` null. Never pass it through `oat-project-complete`, which requires that receipt. Retry identity: one read-only evaluator, shared by apply and `--dry-run`, resolves the archive before any write. An identical retry (the project's retained-artifact manifest matches exactly one same-scope archive) reuses that snapshot's local path, dated export identity (summary export file and S3 key) and receipt on any later date, and a source-absent retry resumes the single same-scope archive; changed content, several matching archives, or an unverifiable non-empty directory at the archive path refuse before export, copy, overwrite or S3 upload, with follow-up-project guidance. The dry-run reports the identity the apply would use. `.oat-archive-source.json` records `manifestHash` and `generation` beside the project name, scope, snapshot and synced source SHA. The exported summary rewrites `oat-project:<project>#<entry-id>` locators to `oat-archive:<snapshot>#<entry-id>` and turns relative `project-log.md` or `oat-execution-learnings.md` links into plain text; see [Archive identity](project-artifacts.md#archive-identity). `--new-generation <reason>` archives reopened work of a shared or local project as the next generation instead of refusing it: it requires a non-empty single-line reason and exactly one latest generation of the same project and scope as predecessor (otherwise it refuses), never overwrites that predecessor, and persists the new generation (`<project>-gN` locally, `<YYYYMMDD>-<project>-gN` as export identity; when the same project's archive from another scope already holds that path or identity, both carry the scope: `<project>-gN-<scope>` and `<YYYYMMDD>-<project>-gN-<scope>`) with its predecessor, reason and `generationRequest` id before any export, copy or S3 side effect, so a retry reuses it. Replaying the same predecessor and content resolves to the same generation; synced projects refuse the option. JSON adds `generation` and `predecessorSnapshot`, and `--dry-run` reports the proposed generation without writing it.
212
215
  - `oat repo archive sync [project-name]` - hydrate archived project snapshots from the configured repo-scoped S3 archive into `.oat/projects/archived/`. A name resolves as an exact snapshot, then a full generation name such as `demo-g2`, then the project (or `<project>-<scope>` family), restoring its latest generation and then its latest date; see [Project Artifacts](project-artifacts.md) for the `<project>[-gN][-<scope>]` naming contract. The old `oat project archive sync` path remains as a deprecated shim.
@@ -214,7 +217,7 @@ Notable commands introduced in the current CLI surface:
214
217
  - `oat project dispatch record --event-file <json-file-or-dash> --format line [--dispatch-stamp <line>]` - print the one-line journal run record for the same validated, redacted record and event (projection `run/v1`), and write nothing; standard input still works. The line is `run/v1` followed by named fields in a fixed order, joined by a space-padded `·`: `request`, `scope`, `action`, `role`, configured `target`, `model` and `effort`, `stamp` (the formal `Dispatch:` stamp passed verbatim through `--dispatch-stamp`; a stamp without the canonical prefix is refused), `launch` (`planned`, `accepted`, or `blocked-before-start`), the raw child `outcome`, `terminal` (`yes` or `no`) and its `class` (`completed`, `terminal-stop`, `blocked-before-start`, `live`, or `unrecognized`), `continuation` references, and the optional `observed` identity with its `match`, which never replaces the configured fields. Inside a value, `\\` is a literal backslash and `\·`, `\~`, `\n`, and `\r` escape the delimiter, a tilde, a newline, and a carriage return; a bare `~` is null. Terminality comes from one producer-to-outcome mapping: a successful completion (`completed`, `DONE`, `DONE_WITH_CONCERNS`), a terminal stop (`BLOCKED`, `failed`, `cancelled`, `INVALID_RUN_ABORT`) and `blocked-before-start` are terminal; `planned`, `running`, `pending`, and `NEEDS_CONTEXT` with its handle still open are not, and an outcome outside the mapping is `unrecognized`, never success. The owning skill writes one line per request id under `## Orchestration Runs` and updates it in place. `--json` keeps `status: validated-only`, the record and `runtimeIdentity`, and adds `runLine` (`version`, `line`, `fields`, `classification`, `terminal`).
215
218
  - `oat project dispatch canonical-role --role <name> --request-id <id> --skill-dir <dir> [--json]` - resolve a canonical role through the loaded, user (`$HOME/.agents`), and project (`<repo>/.agents`) tiers and print the `canonical-role-resolution` event that `oat project dispatch record` accepts unchanged: redacted `canonicalPath` and `selectedPath` in the form `<loaded|user|project>/agents/<name>.md`, the role's `contentDigest`, and `candidateMisses`. `--skill-dir` is required because the loaded tier is derived from the loaded skill's directory; a missing or invalid directory exits 1 with a redacted error. An unknown role prints `missing` evidence with its recovery commands. Read-only; the dependency is the `workflows` pack.
216
219
  - `oat project validate-plan --project-path <path>` - validates `oat_plan_parallel_groups` metadata in `plan.md`; exits non-zero on invalid. Lite plans must contain exactly one phase, declare no parallel groups, and give every Validation Criteria bullet either a backticked command or a `manual:` instruction. Brief plans (`oat_workflow_mode: brief`) are validated with the brief profile: phases need non-empty `**Intent:**` and `**Exit evidence:**`, a `**Provisional:**` value of `yes` or `no`, unique IDs, and a concrete first phase; `### Task` headings in a brief are reported as a warning, and taskless parallel groups are valid. Goal plans add the goal profile: `oat_plan_source: goal`, a valid `## Milestones` table (`goal-milestones-missing`, `goal-milestones-malformed`, `goal-duplicate-milestone`, `goal-milestone-empty`, `goal-milestone-unknown-phase`, `goal-phase-in-multiple-milestones`, `goal-phase-without-milestone`), no parallel group spanning milestones (`goal-group-crosses-milestone`), canonical persisted phase IDs (`goal-noncanonical-phase-id`), and no change to a shipped milestone or a registered delivery's frozen scope (`goal-shipped-milestone-changed`, `goal-delivered-scope-changed`); phases the journal marks `extracted` need no milestone. See [Implementation Execution](../workflows/projects/execution/implementation-execution.md#parallel-phase-groups).
217
- - `oat project journal check --at <implement-preflight|review|completion> [--project <path>] [--scope pNN[,pNN]] [--json]` - read-only journal evaluator: it reads `plan.md`, `implementation.md`, and `state.md` and writes nothing. `implement-preflight` is implement's call before its Step 16: it validates the accepted task and phase evidence while the terminal headers and pointers Step 16 owns may still be unwritten. `review` requires an explicit `--scope` of phases the plan declares and ignores future phases; a live run line warns there instead of refusing. `completion` (oat-project-complete, before roll-up, seal, or any lifecycle write) also requires the terminal journal shape: journal `oat_status: complete` and a cleared `oat_current_task_id`, `state.md` `oat_phase_status` `complete` or `pr_open` and a cleared `oat_current_task`. Task modes read journal records through the shared heading-only reader (fenced and indented code excluded, a block ends at the next heading of equal or higher level): every plan task heading is unique and sits under its own phase (`plan-task-duplicate`, `plan-task-misplaced`, routed to the plan owner and never override-eligible), and every plan task has exactly one journal block in its phase with exactly one owned `**Status:** completed` and one owned `**Commit:**` SHA; tables and checklists are never completion evidence, and overview totals must match. Brief and goal read phase units: an accepted phase carries its `**Head:**`, execution records close as `completed` with a commit or as `failed`, `cancelled`, or `no-change` without one, an extracted goal phase and a phase the goal outcome audit defers or retires stay valid and incomplete. Everywhere: `## References` is last, review receipts sit in their phase or `## Reviews and Gates`, deferrals in `## Deferred Findings`, dispatch payloads are refused unless marked `quoted-evidence`, every run line parses as `run/v1` under `## Orchestration Runs`, carries a valid `request` identifier, and is terminal at implement-preflight and completion, and no template placeholder survives, including one left in an inline-code slot such as ``- `{path}` - …`` unless the line is marked `quoted-evidence`. An override is one line under `## Deviations from Plan / Design`: `**Override:** <scope-disposition-approved|evidence-lost|operator-accepted-gap> · **Authorized by:** <decision id> · **Scope:** <pNN-tNN|pNN> · <reason>`; it covers only a missing task block, an incomplete task, missing commit evidence, or (for `scope-disposition-approved`) an unaccepted phase within its scope, and a malformed or misplaced override is refused. Output is `{ status: ok | refused, reasons: [{ code, path, line, owner, message }], warnings, overrides }`; a refusal exits 1. Delivery coverage and the post-implementation sequence stay with `closeout-check`.
220
+ - `oat project journal check --at <implement-preflight|review|completion> [--project <path>] [--scope pNN[,pNN]] [--json]` - read-only journal evaluator: it reads `plan.md`, `implementation.md`, and `state.md` and writes nothing. `implement-preflight` is implement's call before its Step 16: it validates the accepted task and phase evidence while the terminal headers and pointers Step 16 owns may still be unwritten. `review` requires an explicit `--scope` of phases the plan declares and ignores future phases; a live run line warns there instead of refusing. In goal projects, those two boundaries also compare working `implementation.md` with its committed `HEAD` version and refuse each removed or rewritten recorded line as `journal-line-rewritten`; append-only additions, mutable progress fields, and new extraction markers do not trigger that reason. The comparison base is `HEAD`, so a rewrite that is already committed is left to `delivery check`. Unparseable committed journal frontmatter refuses as `journal-frontmatter-malformed` and must be repaired and committed before re-running. An untracked journal or unborn `HEAD` has no committed version to compare, while other Git inspection failures are command errors. `completion` does not run this comparison and instead requires the terminal journal shape: journal `oat_status: complete` and a cleared `oat_current_task_id`, `state.md` `oat_phase_status` `complete` or `pr_open` and a cleared `oat_current_task`. Task modes read journal records through the shared heading-only reader (fenced and indented code excluded, a block ends at the next heading of equal or higher level): every plan task heading is unique and sits under its own phase (`plan-task-duplicate`, `plan-task-misplaced`, routed to the plan owner and never override-eligible), and every plan task has exactly one journal block in its phase with exactly one owned `**Status:** completed` and one owned `**Commit:**` SHA; tables and checklists are never completion evidence, and overview totals must match. Brief and goal read phase units: an accepted phase carries its `**Head:**`, execution records close as `completed` with a commit or as `failed`, `cancelled`, or `no-change` without one, an extracted goal phase and a phase the goal outcome audit defers or retires stay valid and incomplete. Everywhere: `## References` is last, review receipts sit in their phase or `## Reviews and Gates`, deferrals in `## Deferred Findings`, dispatch payloads are refused unless marked `quoted-evidence`, every run line parses as `run/v1` under `## Orchestration Runs`, carries a valid `request` identifier, and is terminal at implement-preflight and completion, and no template placeholder survives, including one left in an inline-code slot such as ``- `{path}` - …`` unless the line is marked `quoted-evidence`. An override is one line under `## Deviations from Plan / Design`: `**Override:** <scope-disposition-approved|evidence-lost|operator-accepted-gap> · **Authorized by:** <decision id> · **Scope:** <pNN-tNN|pNN> · <reason>`; it covers only a missing task block, an incomplete task, missing commit evidence, or (for `scope-disposition-approved`) an unaccepted phase within its scope, and a malformed or misplaced override is refused. Output is `{ status: ok | refused, reasons: [{ code, path, line, owner, message }], warnings, overrides }`; a refusal exits 1. Delivery coverage and the post-implementation sequence stay with `closeout-check`.
218
221
  - `oat project log append|check|synthesize|rollup` - manage the optional append-only project observation log: append validated judgment or structural entries, inspect grammar and synthesis status, complete end-of-run synthesis, and roll observations into `summary.md` plus the configured repository ledger. See [Project Log](../workflows/projects/execution/project-log.md).
219
222
  - `oat project log append --category <category> --source <id> [--origin <producer>]` - record a learning on a judgment entry. The category is one of `gotcha`, `efficiency`, `documentation-gap`, `candidate-skill-content`, `decision`, or `environment-limited`; any other value, `--category` without `--source`, a `--source` containing whitespace, and these flags on a `--structural` entry are refused. The flags write a `**Category:**`, `**Source:**`, `**Origin:**`, `**Recorded:**` body head above the body; the heading grammar is unchanged and an entry without them is stored as before. Passing the source id as `--idempotency-key` makes a retry report `already-appended` and write nothing.
220
223
  - `oat project log check` - JSON adds `learnings`: `legacy` when the project still has `oat-execution-learnings.md`, which summary and retro read after the log, and `none` otherwise, in every status.
@@ -127,7 +127,7 @@ Current schema keys:
127
127
  | `documentation.nonReaderPaths` | `string[]` | - | Shared-only content-root-relative bounded globs omitted from nav inventory/Contents/check/manifest and, with OAT source config, Fumadocs rendering. MkDocs 1.4.2 still renders routes. See [Non-reader paths](#non-reader-paths). |
128
128
  | `documentation.excludes` | `string[]` | - | Globs, relative to the docs directory, that `oat docs generate-index` leaves out of the generated index. See [Excluding pages from the generated index](#excluding-pages-from-the-generated-index). |
129
129
  | `documentation.requireForProjectCompletion` | `boolean` | `false` | When `true`, OAT project completion gates require documentation to be updated |
130
- | `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`. |
130
+ | `git.defaultBranch` | `string` | `"main"` | Default branch for PR creation. Auto-detected during `oat init --setup` from `origin/HEAD`, falling back to `main`. Used by `oat-project-pr-final`, `oat-project-pr-progress`, and `oat-project-complete`. |
131
131
  | `instructions.claude.shims` | `string` | `"none"` | CLAUDE.md shim strategy for `oat instructions sync`/`validate`: `none` (no shims; sync removes OAT-managed ones, all or nothing: none while any `CLAUDE.md` has content; see [All or nothing](../provider-sync/instruction-sync.md#all-or-nothing)), `pointer`, `symlink`, or `copy`. `--strategy` overrides it for one run; any other value is rejected with exit code `2`. See [Instruction Sync](../provider-sync/instruction-sync.md#choosing-a-strategy). |
132
132
  | `instructions.claude.excludes` | `string[]` | - | Repo-relative directories `oat instructions sync`/`validate` must not treat as pointer sites, additive to the documentation content root they skip by default. Normalized and de-duplicated; a malformed value (non-array, or an empty or non-string entry) is rejected with exit code `2`. Set as one comma-separated value with `oat config set`; absolute paths and paths escaping the repository are refused. See [Instruction Sync](../provider-sync/instruction-sync.md#documentation-trees). |
133
133
  | `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. |
@@ -112,19 +112,28 @@ goal fields:
112
112
  its milestone, frozen phase scope, agreed endpoint, status, member pull
113
113
  requests and their observed revisions, the integrated review it was
114
114
  delivered on, its exit-gate binding and the first observed endpoint
115
- attainment. A delivery's `status` is `registering`, `open`, `at_endpoint`,
115
+ attainment. A delivery's `kind` is `pr` for one pull request or `stack` for
116
+ an existing gh-stack, whose members are recorded base to tip; a stack's
117
+ configured code exit carrier is judged at the tip member, and every lower
118
+ member's observed head must be an ancestor of the tip (`stack-order`
119
+ otherwise). A delivery's `status` is `registering`, `open`, `at_endpoint`,
116
120
  or `superseded`, and its agreed `endpoint` is `open` or `merged`. A
117
121
  replacement delivery names its one direct predecessor in `covers_scope_of`,
118
122
  and the predecessor's `superseded_by` points back; only a delivery that never
119
123
  reached its agreed endpoint may be replaced. A correction of a delivery that
120
124
  did reach it is additive (`corrects_delivery_id`, new phase IDs, no inherited
121
125
  coverage). `oat_pr_status` and `oat_pr_url` project the latest member pull
122
- request.
126
+ request, which is the tip member for a stack.
123
127
 
124
128
  Delivery evidence stays fresh across later commits that change only bookkeeping:
125
129
  `state.md`, `plan.md` (outside its approved content), `implementation.md`,
126
130
  `project-log.md` appends, `summary.md`, and the review artifacts of the
127
- delivery and of any delivery sharing its pull request.
131
+ delivery and of any delivery sharing its pull request. In evidence scopes built
132
+ for an exit carrier, the gate's own artifact also counts as bookkeeping if its
133
+ `## Reviews` row has Type `code`, Invocation `gate` and a non-placeholder
134
+ Reviewed Head equal to the carrier's `reviewed_head`, and the artifact is under `reviews/`
135
+ (including `reviews/archived/`). That artifact is never integrated-review
136
+ evidence and never one of a delivery's own review artifacts.
128
137
 
129
138
  A delivery's evidence identity is set once: its `exit_gate`, its
130
139
  `integrated_review` identity (`artifact`, `scope`, `bound_revisions`), and each
@@ -95,9 +95,8 @@ link or copy that OAT creates in the tool's own folder, such as
95
95
  - If you are working in the OAT source repository: run
96
96
  `pnpm run worktree:init`. This command copies local-only files from the main
97
97
  worktree, installs dependencies, configures Git hooks, builds the workspace,
98
- and runs `oat sync` with no scope flag. A bare `oat sync` uses
99
- `--scope all`, so it refreshes user-scope provider views in your home
100
- directory as well as the project's.
98
+ and runs `oat sync --scope project`, which refreshes only the project's
99
+ provider views and leaves user-scope views in your home directory alone.
101
100
 
102
101
  ## Codex appears detected but no skill sync actions are listed
103
102
 
@@ -328,8 +327,8 @@ npm install --global @open-agent-toolkit/cli
328
327
  oat status # or: oat doctor
329
328
  ```
330
329
 
331
- The diagnostic's own recovery line says to run `pnpm build`. That applies only
332
- when you run the CLI from a checkout of the OAT source repository.
330
+ The diagnostic's own recovery line names the same two remedies and mentions
331
+ `pnpm build` only for a checkout of the OAT source repository.
333
332
 
334
333
  If you are working in the OAT source repository: rebuild the CLI workspace,
335
334
  then rerun the command named in the diagnostic: