@open-agent-toolkit/cli 0.3.7 → 0.3.9

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 (147) hide show
  1. package/README.md +3 -3
  2. package/assets/agents/oat-codebase-mapper.md +3 -2
  3. package/assets/agents/oat-reviewer.md +5 -13
  4. package/assets/agents/skeptical-evaluator.md +6 -2
  5. package/assets/bundle-metadata.json +1 -1
  6. package/assets/docs/cli-utilities/backlog-lifecycle.md +3 -2
  7. package/assets/docs/cli-utilities/bootstrap.md +5 -2
  8. package/assets/docs/cli-utilities/config-and-local-state.md +13 -6
  9. package/assets/docs/cli-utilities/configuration.md +25 -10
  10. package/assets/docs/cli-utilities/tool-packs.md +60 -10
  11. package/assets/docs/cli-utilities/workflow-gates.md +37 -0
  12. package/assets/docs/contributing/code.md +9 -5
  13. package/assets/docs/provider-sync/commands.md +17 -8
  14. package/assets/docs/provider-sync/instruction-sync.md +241 -39
  15. package/assets/docs/provider-sync/providers.md +20 -0
  16. package/assets/docs/provider-sync/scope-and-surface.md +3 -1
  17. package/assets/docs/reference/cli-reference.md +4 -1
  18. package/assets/docs/reference/oat-directory-structure.md +12 -11
  19. package/assets/docs/reference/troubleshooting.md +19 -4
  20. package/assets/docs/workflows/projects/evidence-layers.md +5 -1
  21. package/assets/docs/workflows/projects/implementation-execution.md +22 -8
  22. package/assets/docs/workflows/projects/lifecycle.md +4 -6
  23. package/assets/docs/workflows/projects/retro.md +7 -0
  24. package/assets/public-package-versions.json +4 -4
  25. package/assets/skills/oat-agent-instructions-analyze/SKILL.md +4 -4
  26. package/assets/skills/oat-agent-instructions-analyze/references/analysis-artifact-template.md +5 -5
  27. package/assets/skills/oat-agent-instructions-analyze/references/docs/rules-files.md +14 -11
  28. package/assets/skills/oat-agent-instructions-analyze/references/quality-checklist.md +2 -2
  29. package/assets/skills/oat-agent-instructions-analyze/scripts/resolve-instruction-files.sh +4 -3
  30. package/assets/skills/oat-agent-instructions-analyze/scripts/resolve-providers.sh +17 -6
  31. package/assets/skills/oat-agent-instructions-apply/SKILL.md +3 -3
  32. package/assets/skills/oat-agent-instructions-apply/references/docs/rules-files.md +14 -11
  33. package/assets/skills/oat-dispatch-subagents/SKILL.md +1 -1
  34. package/assets/skills/oat-dispatch-subagents/references/managed-claude-example.json +387 -0
  35. package/assets/skills/oat-dispatch-subagents/references/record-schema.md +75 -0
  36. package/assets/skills/oat-doctor/SKILL.md +17 -13
  37. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +1 -1
  38. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +1 -1
  39. package/assets/skills/oat-project-implement/SKILL.md +2 -2
  40. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +33 -11
  41. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +24 -22
  42. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +1 -1
  43. package/assets/skills/oat-project-implement/references/phase-execution.md +109 -8
  44. package/assets/skills/oat-project-lite/SKILL.md +23 -1
  45. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +1 -1
  46. package/assets/skills/oat-project-next/SKILL.md +3 -3
  47. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +1 -1
  48. package/assets/skills/oat-project-progress/SKILL.md +2 -2
  49. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +1 -1
  50. package/assets/skills/oat-project-retro/SKILL.md +70 -6
  51. package/assets/skills/oat-project-review-provide/SKILL.md +3 -1
  52. package/assets/skills/oat-project-review-provide-remote/SKILL.md +3 -1
  53. package/assets/templates/docs-app-mkdocs/docs/contributing.md +1 -3
  54. package/assets/templates/pjm-agents.md +7 -3
  55. package/assets/templates/state.md +2 -2
  56. package/dist/agents/canonical/resolve.d.ts +6 -4
  57. package/dist/agents/canonical/resolve.d.ts.map +1 -1
  58. package/dist/agents/canonical/resolve.js +6 -4
  59. package/dist/commands/backlog/archive.d.ts +10 -2
  60. package/dist/commands/backlog/archive.d.ts.map +1 -1
  61. package/dist/commands/backlog/archive.js +22 -6
  62. package/dist/commands/backlog/index.d.ts.map +1 -1
  63. package/dist/commands/backlog/index.js +5 -1
  64. package/dist/commands/backlog/rewrite-references.d.ts +41 -0
  65. package/dist/commands/backlog/rewrite-references.d.ts.map +1 -0
  66. package/dist/commands/backlog/rewrite-references.js +516 -0
  67. package/dist/commands/config/index.d.ts +1 -0
  68. package/dist/commands/config/index.d.ts.map +1 -1
  69. package/dist/commands/config/index.js +69 -34
  70. package/dist/commands/gate/index.d.ts.map +1 -1
  71. package/dist/commands/gate/index.js +51 -2
  72. package/dist/commands/gate/review-verdict.d.ts +22 -0
  73. package/dist/commands/gate/review-verdict.d.ts.map +1 -1
  74. package/dist/commands/gate/review-verdict.js +111 -0
  75. package/dist/commands/init/index.d.ts +6 -0
  76. package/dist/commands/init/index.d.ts.map +1 -1
  77. package/dist/commands/init/index.js +27 -4
  78. package/dist/commands/init/tools/index.d.ts +18 -1
  79. package/dist/commands/init/tools/index.d.ts.map +1 -1
  80. package/dist/commands/init/tools/index.js +84 -17
  81. package/dist/commands/init/tools/project-guidance.d.ts +19 -4
  82. package/dist/commands/init/tools/project-guidance.d.ts.map +1 -1
  83. package/dist/commands/init/tools/project-guidance.js +58 -15
  84. package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
  85. package/dist/commands/init/tools/workflows/index.js +5 -1
  86. package/dist/commands/instructions/instructions.types.d.ts +105 -4
  87. package/dist/commands/instructions/instructions.types.d.ts.map +1 -1
  88. package/dist/commands/instructions/instructions.types.js +4 -5
  89. package/dist/commands/instructions/instructions.utils.d.ts +161 -6
  90. package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
  91. package/dist/commands/instructions/instructions.utils.js +650 -12
  92. package/dist/commands/instructions/sync/sync.d.ts.map +1 -1
  93. package/dist/commands/instructions/sync/sync.js +256 -18
  94. package/dist/commands/instructions/validate/validate.d.ts.map +1 -1
  95. package/dist/commands/instructions/validate/validate.js +36 -8
  96. package/dist/commands/pjm/index.d.ts.map +1 -1
  97. package/dist/commands/pjm/index.js +19 -4
  98. package/dist/commands/pjm/init.d.ts +3 -0
  99. package/dist/commands/pjm/init.d.ts.map +1 -1
  100. package/dist/commands/pjm/init.js +23 -5
  101. package/dist/commands/project/dispatch/canonical-role.d.ts +33 -0
  102. package/dist/commands/project/dispatch/canonical-role.d.ts.map +1 -0
  103. package/dist/commands/project/dispatch/canonical-role.js +114 -0
  104. package/dist/commands/project/dispatch/index.d.ts.map +1 -1
  105. package/dist/commands/project/dispatch/index.js +3 -1
  106. package/dist/commands/project/dispatch/record.d.ts.map +1 -1
  107. package/dist/commands/project/dispatch/record.js +146 -4
  108. package/dist/commands/shared/agents-md.d.ts +26 -5
  109. package/dist/commands/shared/agents-md.d.ts.map +1 -1
  110. package/dist/commands/shared/agents-md.js +182 -3
  111. package/dist/commands/sync/apply.d.ts.map +1 -1
  112. package/dist/commands/sync/apply.js +28 -21
  113. package/dist/commands/tools/guidance/index.d.ts +15 -0
  114. package/dist/commands/tools/guidance/index.d.ts.map +1 -0
  115. package/dist/commands/tools/guidance/index.js +81 -0
  116. package/dist/commands/tools/index.d.ts.map +1 -1
  117. package/dist/commands/tools/index.js +2 -0
  118. package/dist/commands/tools/shared/sync-evidence.d.ts.map +1 -1
  119. package/dist/commands/tools/shared/sync-evidence.js +32 -5
  120. package/dist/config/oat-config.d.ts +57 -3
  121. package/dist/config/oat-config.d.ts.map +1 -1
  122. package/dist/config/oat-config.js +223 -15
  123. package/dist/config/resolve.d.ts.map +1 -1
  124. package/dist/config/resolve.js +12 -2
  125. package/dist/engine/compute-plan.d.ts.map +1 -1
  126. package/dist/engine/compute-plan.js +31 -3
  127. package/dist/providers/claude/dispatch-envelope.d.ts +53 -0
  128. package/dist/providers/claude/dispatch-envelope.d.ts.map +1 -1
  129. package/dist/providers/claude/dispatch-envelope.js +324 -48
  130. package/dist/providers/claude/rule-transform.js +1 -1
  131. package/dist/providers/copilot/rule-transform.js +1 -1
  132. package/dist/providers/cursor/rule-transform.js +1 -1
  133. package/dist/providers/identity/absolute-paths.d.ts +13 -0
  134. package/dist/providers/identity/absolute-paths.d.ts.map +1 -1
  135. package/dist/providers/identity/absolute-paths.js +27 -14
  136. package/dist/providers/identity/generic-dispatch-record.d.ts +212 -0
  137. package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -1
  138. package/dist/providers/identity/generic-dispatch-record.js +78 -19
  139. package/dist/providers/identity/oat-dispatch-record.d.ts +5 -0
  140. package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -1
  141. package/dist/providers/identity/oat-dispatch-record.js +11 -2
  142. package/dist/providers/shared/registry.d.ts +6 -0
  143. package/dist/providers/shared/registry.d.ts.map +1 -1
  144. package/dist/providers/shared/registry.js +30 -0
  145. package/dist/rules/canonical/parse.d.ts.map +1 -1
  146. package/dist/rules/canonical/parse.js +38 -3
  147. package/package.json +2 -2
@@ -1,19 +1,22 @@
1
1
  ---
2
2
  title: Instruction Sync
3
- description: Project-scoped AGENTS.md and CLAUDE.md validation, repair strategies, and Claude-only adoption.
3
+ description: Project-scoped AGENTS.md and CLAUDE.md validation, the no-shim default, opt-in shim strategies, and Claude-only adoption.
4
4
  ---
5
5
 
6
6
  # Instruction Sync
7
7
 
8
- `oat instructions ...` is the project-scoped lane for keeping canonical `AGENTS.md` files aligned with sibling `CLAUDE.md` files throughout a repository tree.
8
+ `oat instructions ...` is the project-scoped lane for keeping canonical `AGENTS.md` files and any sibling `CLAUDE.md` files consistent throughout a repository tree.
9
+
10
+ By default OAT keeps **no** `CLAUDE.md` shims: Claude Code reads `AGENTS.md` itself (see [Claude Code and AGENTS.md](#claude-code-and-agentsmd)). A repository opts back into shims with `instructions.claude.shims`.
9
11
 
10
12
  Use it when you want OAT to:
11
13
 
12
- - validate nested `AGENTS.md` / `CLAUDE.md` pairs
13
- - repair missing or drifted `CLAUDE.md` files with a chosen strategy
14
+ - validate nested `AGENTS.md` files, and their `CLAUDE.md` shims when a shim strategy is configured
15
+ - remove the `CLAUDE.md` shims OAT created, under the default, once no `CLAUDE.md` with its own content remains, and warn about any `CLAUDE.md` that would hide `AGENTS.md` from Claude Code
16
+ - create or repair `CLAUDE.md` shims with a chosen strategy, when you opt in
14
17
  - adopt Claude-only directories back into canonical `AGENTS.md`
15
18
 
16
- This command group is intentionally separate from manifest-backed provider sync. It operates on repo-local instruction files, not provider view manifests.
19
+ This command group is intentionally separate from manifest-backed provider sync. It operates on repo-local instruction files, not provider view manifests. The shim setting affects only `oat instructions`: `oat sync` writes the same rules (including `.claude/rules`), skills, and agents under every strategy and never creates or removes a `CLAUDE.md`, and `oat instructions sync` leaves synced `.claude/rules` files alone.
17
20
 
18
21
  ## Scope
19
22
 
@@ -22,8 +25,9 @@ Instruction sync is currently project-only.
22
25
  - It scans the current repository recursively.
23
26
  - It supports nested directories all the way down the tree.
24
27
  - It skips provider-irrelevant or local-only roots such as `.git`, `.oat`, `.worktrees`, and `node_modules`.
25
- - Exception: `.oat/repo/**` is scanned even though the rest of `.oat/` is skipped, so the curated `AGENTS.md` files there (repo root guidance, `pjm/`, `reference/`) get their sibling `CLAUDE.md` shims managed and validated like any other directory. The rest of `.oat/` (`templates/`, `projects/`, `sync/`) stays excluded.
26
- - It skips the documentation content tree by default, and any path you add to `documentation.instructionPointerExcludes`. See [Documentation trees](#documentation-trees) below.
28
+ - It stops at nested git checkouts: any directory below the root that holds its own `.git` (a directory, or the gitdir file of a submodule or linked worktree such as `.claude/worktrees/<name>`) is a separate repository that its own `oat instructions` run owns. Nothing inside it is scanned, removed, or warned about.
29
+ - Exception: `.oat/repo/**` is scanned even though the rest of `.oat/` is skipped, so the curated `AGENTS.md` files there (repo root guidance, `pjm/`, `reference/`) are managed and validated like any other directory. The rest of `.oat/` (`templates/`, `projects/`, `sync/`) stays excluded.
30
+ - It skips the documentation content tree by default, and any path you add to `instructions.claude.excludes`. See [Documentation trees](#documentation-trees) below.
27
31
  - It does not scan user-level provider roots such as `~/.claude` in this release.
28
32
 
29
33
  ## Documentation Trees
@@ -49,20 +53,25 @@ only; it does not change what instruction sync excludes.)
49
53
  canonically names the docs _app_ root, and a file like
50
54
  `apps/oat-docs/AGENTS.md` is instructions for working on the docs app rather
51
55
  than a documentation page. When the app root has a `docs` child, only that
52
- child is skipped, and the app root keeps receiving its `CLAUDE.md` pointer. Opt
53
- the app root out explicitly if you do not want it synced.
56
+ child is skipped, and the app root is still synced (under a shim strategy it
57
+ keeps receiving its `CLAUDE.md` pointer). Opt the app root out explicitly if
58
+ you do not want it synced.
54
59
 
55
- Add further paths with `documentation.instructionPointerExcludes`, a list of
60
+ Add further paths with `instructions.claude.excludes`, a list of
56
61
  repository-relative directories. Set it with
57
- `oat config set documentation.instructionPointerExcludes "vendor,third_party/docs"`
62
+ `oat config set instructions.claude.excludes "vendor,third_party/docs"`
58
63
  (an empty value clears it, and `oat config unset` removes it), or write it
59
64
  directly:
60
65
 
61
66
  ```json
62
67
  {
63
68
  "documentation": {
64
- "root": "apps/oat-docs",
65
- "instructionPointerExcludes": ["vendor", "third_party/docs"]
69
+ "root": "apps/oat-docs"
70
+ },
71
+ "instructions": {
72
+ "claude": {
73
+ "excludes": ["vendor", "third_party/docs"]
74
+ }
66
75
  }
67
76
  }
68
77
  ```
@@ -115,8 +124,11 @@ leaves the content root underived, and no default exclusion applies).
115
124
 
116
125
  Exclusion only stops a directory from being scanned. Nothing is deleted: a
117
126
  `CLAUDE.md` that already exists inside an excluded tree is left exactly as it
118
- is. When any exclusion is configured, `--json` output carries three additional
119
- fields.
127
+ is, even under the default `none` strategy, which removes managed shims
128
+ everywhere else. Exclusion does not silence the
129
+ [leftover `CLAUDE.md` warning](#leftover-claudemd-warnings), because Claude
130
+ Code does not honor OAT's exclusions. When any exclusion is configured,
131
+ `--json` output carries three additional fields.
120
132
 
121
133
  - `excludedPaths` lists the configured exclusions — a statement of intent, not
122
134
  a per-directory skip log, so `.oat` appearing there does not contradict
@@ -135,8 +147,8 @@ dropped before `excludedPaths` is built, so it appears only here.
135
147
  ## Canonical Model
136
148
 
137
149
  - `AGENTS.md` is canonical.
138
- - `CLAUDE.md` is derived from the sibling `AGENTS.md`.
139
- - If a directory contains only `CLAUDE.md`, OAT can adopt that file by writing canonical `AGENTS.md` content first and then regenerating `CLAUDE.md`.
150
+ - A `CLAUDE.md` beside it is either absent (the default, strategy `none`) or a shim derived from the sibling `AGENTS.md` (strategies `pointer`, `symlink`, and `copy`).
151
+ - If a directory contains only `CLAUDE.md`, OAT can adopt that file by writing canonical `AGENTS.md` content first. Under a shim strategy it then regenerates `CLAUDE.md`; under `none` it removes it.
140
152
 
141
153
  ## Commands
142
154
 
@@ -146,40 +158,177 @@ Read-only validation for instruction integrity.
146
158
 
147
159
  - Resolves the project root automatically.
148
160
  - Scans nested directories for instruction pairs and Claude-only strays.
149
- - Returns exit code `0` when everything is valid and `1` when drift is detected.
150
- - Suggests the matching repair command, including `--strategy` when you validated with a non-default mode.
161
+ - Returns exit code `0` when everything is valid and `1` when drift is detected. Leftover-`CLAUDE.md` warnings never change the exit code.
162
+ - Suggests the matching repair command, including `--strategy` when you validated with an explicit `--strategy`.
151
163
 
152
164
  ### `oat instructions sync`
153
165
 
154
166
  Repair and adoption command for instruction drift.
155
167
 
156
168
  - Mutates by default.
157
- - Use `--dry-run` to preview planned actions.
158
- - Use `--force` to overwrite mismatched `CLAUDE.md` files.
159
- - Reuses the selected strategy when creating or repairing `CLAUDE.md`.
169
+ - Use `--dry-run` to preview planned actions, including every planned removal.
170
+ - Under a shim strategy, use `--force` to overwrite mismatched `CLAUDE.md` files. Under `none`, `--force` has no effect: sync never deletes anything that is not an exact managed shim.
171
+ - Applies the effective strategy when creating, repairing, or removing `CLAUDE.md`.
160
172
 
161
- ## Supported Strategies
173
+ Both commands report the effective strategy as `strategy:` in human output and as the `strategy` field under `--json`.
162
174
 
163
- `CLAUDE.md` can be generated or validated in one of three modes:
175
+ ## Supported Strategies
164
176
 
165
- | Strategy | Expected `CLAUDE.md` shape | Notes |
166
- | --------- | -------------------------------- | --------------------------------------- |
167
- | `pointer` | file content `@AGENTS.md` | Default mode. Lightweight and explicit. |
168
- | `symlink` | file symlink to `AGENTS.md` | Uses a same-directory relative symlink. |
169
- | `copy` | hard copy of `AGENTS.md` content | Useful when symlinks are undesirable. |
177
+ | Strategy | Expected `CLAUDE.md` shape | Notes |
178
+ | --------- | -------------------------------- | --------------------------------------------------------------------------------------------------- |
179
+ | `none` | no `CLAUDE.md` | Default. Sync removes the shims OAT created (all or nothing) and warns about any other `CLAUDE.md`. |
180
+ | `pointer` | file content `@AGENTS.md` | Lightweight and explicit. The default before shims became opt-in. |
181
+ | `symlink` | file symlink to `AGENTS.md` | Uses a same-directory relative symlink. |
182
+ | `copy` | hard copy of `AGENTS.md` content | Useful when symlinks are undesirable. |
170
183
 
171
184
  Validation treats the selected file shape as part of correctness. For example, `copy` mode rejects a symlink even if the symlink resolves to identical content.
172
185
 
186
+ ### Choosing a strategy
187
+
188
+ The effective strategy for a run is resolved in this order:
189
+
190
+ 1. the `--strategy` flag, which overrides for that one run and never changes config;
191
+ 2. `instructions.claude.shims` in `.oat/config.json`;
192
+ 3. the built-in default, `none`.
193
+
194
+ Persist a shim strategy for the repository with:
195
+
196
+ ```bash
197
+ oat config set instructions.claude.shims pointer
198
+ oat instructions sync
199
+ ```
200
+
201
+ `oat config unset instructions.claude.shims` returns to the default. A value outside `none`, `pointer`, `symlink`, and `copy` is rejected with exit code `2` instead of silently falling back to the default, and `oat config set` can still repair it.
202
+
173
203
  ## Reported States
174
204
 
175
205
  `oat instructions validate` and `oat instructions sync --dry-run` work from the same scan model.
176
206
 
177
- | State | Meaning |
178
- | ------------------ | ------------------------------------------------------------------------------------------------ |
179
- | `ok` | The discovered instruction pair matches the selected strategy. |
180
- | `missing` | `AGENTS.md` exists but sibling `CLAUDE.md` is missing. |
181
- | `content_mismatch` | `CLAUDE.md` exists but has the wrong shape/content, or an instruction file is unreadable/broken. |
182
- | `stray` | `CLAUDE.md` exists without sibling `AGENTS.md` and the Claude file is readable enough to adopt. |
207
+ | State | Meaning |
208
+ | ------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
209
+ | `ok` | The directory matches the effective strategy (under `none`: no `CLAUDE.md` beside `AGENTS.md`). |
210
+ | `missing` | Shim strategies only: `AGENTS.md` exists but sibling `CLAUDE.md` is missing. Under `none` a missing `CLAUDE.md` is correct, never drift. |
211
+ | `content_mismatch` | `CLAUDE.md` exists but has the wrong shape/content, or an instruction file is unreadable/broken. |
212
+ | `stray` | `CLAUDE.md` exists without sibling `AGENTS.md` and the Claude file is readable enough to adopt. |
213
+ | `managed_shim` | `none` only: a `CLAUDE.md` in an exact shape OAT writes. Drift; sync removes it unless [a `CLAUDE.md` with content blocks removal](#all-or-nothing). |
214
+ | `unmanaged` | `none` only: a `CLAUDE.md` that is not an exact managed shape (hand-written, modified, or a symlink elsewhere). Reported and kept, never deleted, and not drift. |
215
+
216
+ ## Removing OAT-Managed Shims
217
+
218
+ Under `none`, a non-dry-run sync removes the `CLAUDE.md` files OAT created, so
219
+ the repository never sits with shims in some directories and not others (see
220
+ [Claude Code and AGENTS.md](#claude-code-and-agentsmd) for why that state is
221
+ worse than either extreme). `--dry-run` lists each planned `remove` action and
222
+ changes nothing.
223
+
224
+ Removal is deliberately narrow. It only ever targets a file named `CLAUDE.md`
225
+ whose sibling is `AGENTS.md`, inside the tree the scan walks, in one of these
226
+ exact shapes:
227
+
228
+ - the pointer `@AGENTS.md` followed by a newline (LF or CRLF), and nothing else;
229
+ - a symlink whose target names the sibling `AGENTS.md`;
230
+ - a byte-identical copy of the sibling `AGENTS.md`.
231
+
232
+ Everything else is kept and reported as `unmanaged`: a hand-written or edited
233
+ `CLAUDE.md`, a pointer with extra lines or trailing spaces, a symlink to any
234
+ other file, `.claude/CLAUDE.md`, and any `CLAUDE.md` that a scanned instruction
235
+ file in another directory links to (`pkg/AGENTS.md -> ../CLAUDE.md`), which
236
+ is neither removed nor adopted because that would leave the link dangling; the
237
+ entry names the links. A `CLAUDE.md` that the sibling
238
+ `AGENTS.md` resolves to (the Claude-first `ln -s CLAUDE.md AGENTS.md` layout,
239
+ or a hard link) holds the only copy of the instructions, so it is never
240
+ treated as a shim of any shape; and a copy is only ever recognized against a
241
+ distinct regular `AGENTS.md`. `CLAUDE.local.md` is never touched and never
242
+ scanned as a shim; it is reported only through the
243
+ [leftover warning](#leftover-claudemd-warnings). A `CLAUDE.md` inside the
244
+ documentation content tree, an excluded directory, or a nested git checkout is
245
+ never touched.
246
+
247
+ ### All or nothing
248
+
249
+ A file with content never leaves a mix behind. If any `CLAUDE.md`,
250
+ `.claude/CLAUDE.md`, or `CLAUDE.local.md` in the repository is not one of the
251
+ exact shapes above — it has content of its own — sync removes **nothing**, not
252
+ even the managed shims.
253
+ A partial removal would strand directories: while that file exists, Claude
254
+ Code ignores `AGENTS.md` for the sessions it covers, and the removed shims were
255
+ what carried those directories' instructions. The check covers the whole
256
+ repository, including excluded and documentation trees, because Claude Code's
257
+ walk does not honor OAT's exclusions. A lone `CLAUDE.md` that sync will adopt
258
+ (no sibling `AGENTS.md`) is not counted: its content moves into a new
259
+ `AGENTS.md`. While another file blocks removal, that stray is still adopted
260
+ into `AGENTS.md`, but its `CLAUDE.md` is kept.
261
+
262
+ Exact shims do not block. An exact shim inside an `instructions.claude.excludes`
263
+ directory or the documentation content tree is never touched, so sync removes
264
+ the other shims and reports that one as a
265
+ [leftover](#leftover-claudemd-warnings); sessions started in its directory
266
+ still ignore `AGENTS.md` until you remove it.
267
+
268
+ When removal is blocked, sync reports every removal it held back as a skipped
269
+ action and exits `1`, and sync, `oat instructions validate`, and `oat-doctor`
270
+ report one finding (`code: "claude_md_blocks_shim_removal"` under `--json`,
271
+ with `paths` naming the files with content, `wouldRemove` naming the
272
+ `CLAUDE.md` files kept, and `linkedBy` mapping each file in `paths` to the
273
+ `AGENTS.md` links that reach it). The finding names the `CLAUDE.md` files the
274
+ configuration would remove, says none were removed and why, links to
275
+ [Claude Code and AGENTS.md](#claude-code-and-agentsmd), and names what to do
276
+ next:
277
+
278
+ - remove each named file, or move its content into an `AGENTS.md`, and rerun
279
+ `oat instructions sync`; for a file an `AGENTS.md` links to (the Claude-first
280
+ layout), replace each link with the file's content first, then remove the
281
+ file, because it holds the only copy of those instructions; or
282
+ - set `instructions.claude.shims` to a shim strategy (`pointer`, `symlink`, or
283
+ `copy`) to keep `CLAUDE.md` files.
284
+
285
+ While removal is blocked, the files in `wouldRemove` get no
286
+ [leftover warning](#leftover-claudemd-warnings) of their own: the finding
287
+ already names them, and removing one by hand would recreate the mix.
288
+
289
+ Removal also fails closed at apply time. Immediately before deleting, sync
290
+ re-checks the file: it must still be the same file the scan saw (same device
291
+ and inode, and the same symlink target), still an exact managed shape, and not
292
+ the target of a link from any scanned instruction file. If it was edited or
293
+ replaced, or a link to it appeared, in between, it is kept, byte for byte, and reported
294
+ as `CLAUDE.md changed since planning (...); kept`, and the command exits `1`
295
+ so you can rerun it.
296
+
297
+ ## Leftover `CLAUDE.md` Warnings
298
+
299
+ Under `none`, after sync (and on every `validate`) OAT reports each remaining
300
+ `CLAUDE.md`, `.claude/CLAUDE.md`, and `CLAUDE.local.md` anywhere in the
301
+ repository with a warning: while that file exists, Claude Code's default
302
+ `agents-md` mode ignores every `AGENTS.md` in the project. For a file at the
303
+ root (including `.claude/CLAUDE.md` and `CLAUDE.local.md` there) that holds for
304
+ every session; for a file in a subdirectory it holds for sessions started in
305
+ that directory or below, and the warning says so. The warning names exactly
306
+ two ways out:
307
+
308
+ - remove the file — or, when an `AGENTS.md` links to it (the warning's
309
+ `linkedBy`), first replace each linking `AGENTS.md` with the file's content,
310
+ because the file holds the only copy of those instructions; or
311
+ - set `instructions.claude.shims` in `.oat/config.json` to a shim
312
+ strategy (`pointer`, `symlink`, or `copy`) and rerun `oat instructions sync`
313
+ to add shims back everywhere.
314
+
315
+ This check is a separate, read-only walk of the whole repository. It
316
+ deliberately ignores `documentation.root` and
317
+ `instructions.claude.excludes`, which only limit what OAT may
318
+ change, because Claude Code's own walk does not honor them. Only `.git`,
319
+ `node_modules`, the root `.worktrees`, and nested git checkouts are skipped.
320
+
321
+ Warnings go to stderr in human mode and to the `warnings` array under `--json`
322
+ (each item has `code: "claude_md_hides_agents_md"`, a repository-relative
323
+ `path`, `linkedBy` — the repository-relative `AGENTS.md` paths whose symlink
324
+ chain reaches the file, empty when there are none — and the `message`).
325
+ Names are matched exactly: a case variant such as `claude.md` is neither
326
+ reported nor ever removed, because such names are common for ordinary
327
+ documents (a provider page named `claude.md`, for example). On a
328
+ case-insensitive filesystem, rename a case-variant file yourself if Claude Code
329
+ treats it as `CLAUDE.md`. They never change the exit code, a dry run leaves
330
+ out files it is about to remove, a repository with no remaining `CLAUDE.md`
331
+ prints nothing, and no warning is emitted under a shim strategy.
183
332
 
184
333
  ## Claude-Only Adoption
185
334
 
@@ -187,15 +336,59 @@ When a directory contains `CLAUDE.md` but no `AGENTS.md`, sync can adopt it:
187
336
 
188
337
  1. Read the existing `CLAUDE.md`
189
338
  2. Write canonical `AGENTS.md` with that content
190
- 3. Regenerate `CLAUDE.md` using the selected strategy
339
+ 3. Under a shim strategy, regenerate `CLAUDE.md` using that strategy. Under
340
+ `none`, remove the `CLAUDE.md`, so adoption never leaves a file that makes
341
+ Claude Code ignore `AGENTS.md` — unless another `CLAUDE.md` with content
342
+ [blocks removal](#all-or-nothing), in which case the adopted `CLAUDE.md` is
343
+ kept.
344
+
345
+ This means the original Claude instructions become canonical before the derived file is rewritten or removed.
191
346
 
192
- This means the original Claude instructions become canonical before the derived file is rewritten.
347
+ Under `none` the removal is re-verified like any other: the `CLAUDE.md` must
348
+ still be the same file and now byte-identical to the new `AGENTS.md`. If it
349
+ changed during adoption, it is kept and reported as
350
+ `CLAUDE.md kept after adoption into AGENTS.md (...)`, and it is also named in a
351
+ leftover warning.
193
352
 
194
353
  Readable Claude-only files are adoptable. Unreadable Claude-only files are not.
354
+ `.claude/CLAUDE.md` is Claude Code's own alternate project file, not a stray,
355
+ so under `none` it is never adopted.
356
+
357
+ ## Claude Code and AGENTS.md
358
+
359
+ Claude Code reads `AGENTS.md` natively through its built-in `agents-md` plugin
360
+ (`anthropics/claude-code`, `mods/agents-md`, as of v2.1.278). Its
361
+ `instructionFiles` option defaults to `claude-md-or-agents-md`:
362
+
363
+ - In that default mode the plugin stands down for the **whole project** when
364
+ any `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` exists in any
365
+ directory from the project root down to the working directory; Claude Code
366
+ then loads only `CLAUDE.md` files. A single root `CLAUDE.md` or a personal
367
+ `CLAUDE.local.md` is enough to make it ignore every `AGENTS.md`, and a
368
+ repository with shims in some directories but not others loses every
369
+ `AGENTS.md` that has no shim. This is why the default removes managed shims
370
+ and warns about the rest.
371
+ - In `claude-md-and-agents-md` mode, an `AGENTS.md` that a `CLAUDE.md` already
372
+ imports or links is not loaded twice, so shims are harmless there.
373
+ - The option can be set only in user settings (`~/.claude/settings.json`),
374
+ with `--settings`, or in managed settings. A project's
375
+ `.claude/settings.json` cannot set it, so a repository cannot choose the mode
376
+ for its contributors.
377
+
378
+ Opt into a shim strategy when your contributors need `CLAUDE.md`:
379
+
380
+ - they run Claude Code releases from before the built-in `agents-md` plugin;
381
+ - they set `instructionFiles` to `claude-md`, which loads no `AGENTS.md`;
382
+ - the plugin's documented gaps matter to you: nested `AGENTS.md` files attach
383
+ only on a text file `Read` (not on `@`-mentions, IDE selections, or
384
+ notebook, image, or PDF reads), and `--add-dir` directories contribute no
385
+ `AGENTS.md`, where Claude Code's own `CLAUDE.md` loading covers those cases
386
+ (for `--add-dir`, only when `CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1`
387
+ is set).
195
388
 
196
389
  ## When `--force` Is Required
197
390
 
198
- `oat instructions sync` does not overwrite a mismatched `CLAUDE.md` unless you pass `--force`.
391
+ Under a shim strategy, `oat instructions sync` does not overwrite a mismatched `CLAUDE.md` unless you pass `--force`.
199
392
 
200
393
  Typical pattern:
201
394
 
@@ -223,9 +416,18 @@ In these cases, sync reports a manual-repair skip instead of guessing at destruc
223
416
 
224
417
  ## Example Workflow
225
418
 
226
- Preview and adopt nested Claude-only strays as pointer files:
419
+ Preview and apply the default: remove OAT-managed shims and adopt Claude-only
420
+ strays into `AGENTS.md`:
421
+
422
+ ```bash
423
+ oat instructions sync --dry-run
424
+ oat instructions sync
425
+ ```
426
+
427
+ Opt the repository into pointer shims:
227
428
 
228
429
  ```bash
430
+ oat config set instructions.claude.shims pointer
229
431
  oat instructions sync --dry-run
230
432
  oat instructions sync
231
433
  ```
@@ -186,6 +186,26 @@ current-session catalog probe is still not proof of provider visibility.
186
186
  - Codex user-scope sync materializes user-config custom roles under `~/.codex`; project-config and supported-catalogue output remains project-scoped and version controlled
187
187
  - Cursor user-scope sync materializes user-config variants under `~/.cursor/agents`; project-config and supported-catalogue output remains project-scoped and version controlled
188
188
 
189
+ ## Canonical rule frontmatter
190
+
191
+ Canonical rules in `.agents/rules/*.md` declare `activation` as one of
192
+ `always`, `glob`, `agent-requested`, or `manual`; `globs` is valid only with
193
+ `activation: glob`.
194
+
195
+ Third-party installers sometimes write Cursor-style rules straight into
196
+ `.agents/rules/` (for example `argent init`, reported in GitHub issue #316).
197
+ OAT accepts that shape through one narrow alias:
198
+
199
+ - `alwaysApply: true` with no `activation` is read as `activation: always`.
200
+ - Under that alias a null or empty `globs` value is ignored, and a non-empty
201
+ `globs` value is an error naming the file, because canonical rules keep globs
202
+ only for `activation: glob`.
203
+ - An explicit `activation` always wins over `alwaysApply`.
204
+ - `alwaysApply: false`, or any value other than `true`, without `activation`
205
+ stays an activation error that names the file.
206
+
207
+ Every canonical rule parse error names the repository-relative rule file.
208
+
189
209
  ## Adoption model
190
210
 
191
211
  - Stray adoption is available in `oat init` and `oat status`.
@@ -45,6 +45,8 @@ Rules are currently project-scoped canonical content. Unlike skills and agents,
45
45
  - `oat providers codex materialize`
46
46
  - `oat project dispatch record` (project-aware dispatch evidence only; never a
47
47
  provider launcher)
48
+ - `oat project dispatch canonical-role` (read-only; prints the
49
+ canonical-role-resolution event that `oat project dispatch record` accepts)
48
50
 
49
51
  ## Adjacent CLI commands (commonly used with provider interop)
50
52
 
@@ -121,7 +123,7 @@ runtime mismatch, malformed output, and missing telemetry never authorize it.
121
123
  ## Non-interop namespaces in the same CLI
122
124
 
123
125
  - `oat project new <name>` (workflow/project scaffolding)
124
- - `oat instructions validate` / `oat instructions sync` (AGENTS.md/CLAUDE.md pointer, symlink, or copy integrity plus Claude-only adoption)
126
+ - `oat instructions validate` / `oat instructions sync` (AGENTS.md integrity with no CLAUDE.md shims by default, opt-in pointer, symlink, or copy shims, plus Claude-only adoption)
125
127
  - `oat internal validate-oat-skills` (internal maintenance)
126
128
 
127
129
  ## Reference artifacts
@@ -134,6 +134,7 @@ Notable commands introduced in the current CLI surface:
134
134
  `refs/oat/completed/<project>` result counts as absence. Transport,
135
135
  authentication, and other lookup failures fail the command closed; they are
136
136
  never converted into a `recorded-absent` row or pull guidance.
137
+ - `oat tools guidance` - print the managed `OAT tools` `AGENTS.md` block for the currently installed packs without installing, upgrading, or writing anything; `--json` returns `status`, `sectionKey`, `target`, `packs`, `otherProjectSkills`, and `managedBlock`. See [Tool Packs](../cli-utilities/tool-packs.md#oat-tools-guidance).
137
138
  - `oat tools migrate --pack <pack> --from <scope> --to <scope>` - move one installed pack between project and user scope. Always previews first, installs and re-inventories the destination before touching the source, and offers source removal only after the destination is verified complete. Declining or running non-interactively leaves the pack installed at both scopes rather than failing. `--dry-run` stops after the preview; there is no force flag. See [Tool Packs](../cli-utilities/tool-packs.md#oat-tools-migrate).
138
139
  - `oat pjm doctor --json` - read-only repository PJM diagnostics whose result carries an additive `adoption` object (`state` of `declared` | `inferred-legacy` | `partial-initialization` | `none`, `repoRoot`, and `recovery`). This, not `oat tools has project-management`, is the check that answers whether _this repository_ adopted PJM.
139
140
  - `oat pjm remote ... --json` - operate one explicit provider-neutral binding.
@@ -153,7 +154,8 @@ Notable commands introduced in the current CLI surface:
153
154
  - `oat project complete-state <project-path>` - apply the canonical completed-state mutation to a project's `state.md`; used by `oat-project-complete` during lifecycle closeout
154
155
  - `oat project archive [project-path] [--project-recap-run <project-relative-path>] [--no-commit]` - 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 stages the selected complete package into `.oat/repo/reference/project-recaps/<YYYYMMDD-project-slug>/`, verifies every manifest-declared file byte, then atomically installs the export before deleting the active project. Existing destinations, incomplete inventory coverage, stale bytes, path escapes, and recipe mismatches fail without removing the active project. 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.
155
156
  - `oat repo archive sync [project-name]` - hydrate archived project snapshots from the configured repo-scoped S3 archive into `.oat/projects/archived/`. The old `oat project archive sync` path remains as a deprecated shim.
156
- - `oat project dispatch record --event-file <json-file-or-dash> [--project <project-path>]` - validate one generic dispatch record plus its namespaced OAT evidence event, and persist it into the project's append-only `dispatch/` journal (optional; no lifecycle skill requires persistence). Omit `--project` to validate without persisting. Managed, effort-pinned Claude launches use the validation-only form before launch: the input carries `claudeLaunch` with the real resolver result, generated definition, and proposed payload, plus `recordBase` and `event`. The command validates their agreement and derives the configured invocation fields; callers cannot copy those fields into `recordBase`. Revision 1 is `dispatch/<request-id>.json` and every later revision is `dispatch/<request-id>@<NNNN>.json`; superseded revisions are never replaced or removed. The command validates and records evidence only — it never launches a provider. A `runtime-observation` event may carry either a finished `observation` or the provider `metadata` envelope (`provider`, `observedAt`, `entries`) to normalize, but not both. `entries` may be raw provider output: they are projected through the owning parser's allowlist, are never persisted, and both forms have their `match` derived from the record's configured invocation rather than trusted from the caller, with the observation's `provider` bound to the record's. With `--json`, the result adds `runtimeIdentity` with separate `configured` and `observed` objects plus a `match` of `matching`, `mismatching`, `not-comparable`, or `null`; observation is corroboration only and never overrides configured invocation. Error output is redacted on a best-effort basis; absolute paths in identity fields are rejected outright, while some prose forms (colon-prefixed, URL routes) can survive. See [Evidence Layers](../workflows/projects/evidence-layers.md).
157
+ - `oat project dispatch record --event-file <json-file-or-dash> [--project <project-path>]` - validate one generic dispatch record plus its namespaced OAT evidence event, and persist it into the project's append-only `dispatch/` journal (optional; no lifecycle skill requires persistence). Omit `--project` to validate without persisting. Managed, effort-pinned Claude launches use the validation-only form before launch: the input carries `claudeLaunch` with the real resolver result, generated definition, and proposed payload, plus `recordBase` and `event`. The command validates their agreement and derives the configured invocation fields; callers cannot copy those fields into `recordBase`. One validation run reports every violation across `claudeLaunch`, `recordBase`, and `event` in a single error message, one `stage path: message` line each; the `recordBase` cross-field rules run even when a required field is missing, checks that need a value that failed to parse are skipped and named on a final line, secret-shaped values and absolute paths are scrubbed from the message, and the exit code stays 1. A validated input per role is published at `.agents/skills/oat-dispatch-subagents/references/managed-claude-example.json`. Revision 1 is `dispatch/<request-id>.json` and every later revision is `dispatch/<request-id>@<NNNN>.json`; superseded revisions are never replaced or removed. The command validates and records evidence only — it never launches a provider. A `runtime-observation` event may carry either a finished `observation` or the provider `metadata` envelope (`provider`, `observedAt`, `entries`) to normalize, but not both. `entries` may be raw provider output: they are projected through the owning parser's allowlist, are never persisted, and both forms have their `match` derived from the record's configured invocation rather than trusted from the caller, with the observation's `provider` bound to the record's. With `--json`, the result adds `runtimeIdentity` with separate `configured` and `observed` objects plus a `match` of `matching`, `mismatching`, `not-comparable`, or `null`; observation is corroboration only and never overrides configured invocation. Error output is redacted on a best-effort basis; absolute paths in identity fields are rejected outright, while some prose forms (colon-prefixed, URL routes) can survive. See [Evidence Layers](../workflows/projects/evidence-layers.md).
158
+ - `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.
157
159
  - `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. See [Implementation Execution](../workflows/projects/implementation-execution.md#parallel-phase-groups).
158
160
  - `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](../cli-utilities/project-log.md).
159
161
  - `oat project set-mode` — deprecated no-op. Execution mode is no longer user-selectable; emits a deprecation warning and preserves the `--json` contract.
@@ -164,6 +166,7 @@ Notable commands introduced in the current CLI surface:
164
166
  - `oat gate target set <id> --timeout-ms <milliseconds>` - persist a validated per-target gate budget.
165
167
  - `oat gate target list --json` - inspect resolved gate targets without selecting or executing a reviewer. Each entry reports its config origin, whether it is explicitly configured and enabled, current availability, and normalized configured invocation values (`unknown` when omitted).
166
168
  - `oat gate cross-provider-exec <prompt...>` - choose an available exec target while avoiding the current runtime by default, then run the prompt with the chosen target's configured base command and exit with the child status.
169
+ - `oat instructions sync [--dry-run] [--strategy none|pointer|symlink|copy]` - apply the effective `CLAUDE.md` strategy (`--strategy`, else `instructions.claude.shims`, else `none`). Under the default `none` it removes the `CLAUDE.md` shims OAT created — none at all while any `CLAUDE.md` has content of its own — keeps and reports every other `CLAUDE.md`, and warns about any `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` that would make Claude Code ignore `AGENTS.md`. `oat instructions validate` checks the same strategy read-only. See [Instruction Sync](../provider-sync/instruction-sync.md).
167
170
 
168
171
  ## `oat config` surface flags
169
172
 
@@ -48,16 +48,16 @@ Project scope is used for project workflows and repo-local sync state. User scop
48
48
 
49
49
  ## Top-level entries
50
50
 
51
- | Path | Purpose | Notes |
52
- | ------------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
53
- | `.oat/config.json` | Shared repo runtime config for non-sync settings | Includes `worktrees.root`, `projects.root`, `git.defaultBranch`, `archive.*`, `documentation.*`, and `pjm.remote.*` |
54
- | `.oat/config.local.json` | Local per-developer runtime state | Gitignored; includes `activeProject`, `lastPausedProject`, `activeIdea` |
55
- | `.oat/state.md` | Generated repo state dashboard | Gitignored; rebuilt with `oat state refresh` from config, project artifacts, and knowledge metadata |
56
- | `.oat/projects/` | OAT project artifacts | `shared`, `synced`, `local`, and lifecycle `archived` locations |
57
- | `.oat/ideas/` | Project-level ideas store | Often gitignored |
58
- | `.oat/sync/` | Interop sync state/config | See details below |
59
- | `.oat/templates/` | Artifact templates used by OAT skills | Source for scaffolding. Includes `docs-app-fuma/` (Fumadocs) and `docs-app-mkdocs/` (MkDocs) templates. |
60
- | `.oat/repo/` | Repo-level PJM/knowledge/reference/review artifacts | Active PJM state under `pjm/`; durable references (including decisions) under `reference/` |
51
+ | Path | Purpose | Notes |
52
+ | ------------------------ | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
53
+ | `.oat/config.json` | Shared repo runtime config for non-sync settings | Includes `worktrees.root`, `projects.root`, `git.defaultBranch`, `archive.*`, `documentation.*`, `instructions.*`, and `pjm.remote.*` |
54
+ | `.oat/config.local.json` | Local per-developer runtime state | Gitignored; includes `activeProject`, `lastPausedProject`, `activeIdea` |
55
+ | `.oat/state.md` | Generated repo state dashboard | Gitignored; rebuilt with `oat state refresh` from config, project artifacts, and knowledge metadata |
56
+ | `.oat/projects/` | OAT project artifacts | `shared`, `synced`, `local`, and lifecycle `archived` locations |
57
+ | `.oat/ideas/` | Project-level ideas store | Often gitignored |
58
+ | `.oat/sync/` | Interop sync state/config | See details below |
59
+ | `.oat/templates/` | Artifact templates used by OAT skills | Source for scaffolding. Includes `docs-app-fuma/` (Fumadocs) and `docs-app-mkdocs/` (MkDocs) templates. |
60
+ | `.oat/repo/` | Repo-level PJM/knowledge/reference/review artifacts | Active PJM state under `pjm/`; durable references (including decisions) under `reference/` |
61
61
 
62
62
  ## `.oat/sync/` details
63
63
 
@@ -125,9 +125,10 @@ Current schema keys:
125
125
  | `documentation.config` | `string` | - | Path to the documentation framework config file (e.g., `mkdocs.yml`, `next.config.js`) |
126
126
  | `documentation.index` | `string` | - | Path to the docs surface entry point: the generated app-root manifest `<root>/index.md` for Fumadocs, `mkdocs.yml` for MkDocs. Set by `oat docs init`. `oat docs generate-index` writes it only for the Fumadocs manifest transition and never for MkDocs. |
127
127
  | `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). |
128
- | `documentation.instructionPointerExcludes` | `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). |
129
128
  | `documentation.requireForProjectCompletion` | `boolean` | `false` | When `true`, OAT project completion gates require documentation to be updated |
130
129
  | `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
+ | `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). |
131
+ | `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). |
131
132
  | `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. |
132
133
  | `workflow.dispatchPolicy.mode` | `string` | unset | Dispatch policy mode: `managed` lets OAT select model/effort controls; `inherit` leaves controls to the host/provider defaults. |
133
134
  | `workflow.dispatchPolicy.policy` | `string` | unset | Managed dispatch policy: `economy`, `balanced`, `high`, `frontier`, or `uncapped`. Capped policies compile to provider targets; `uncapped` keeps OAT-managed preferred selection without provider caps. `inherit` mode is separate and leaves controls to the host/provider. |
@@ -56,12 +56,27 @@ when a same-name canonical skill exists; rename one package before retrying.
56
56
  - `oat providers set --scope project --enabled <providers> --disabled <providers>`
57
57
  - Re-run `oat sync --scope project` after updating config.
58
58
 
59
- ## `instructions validate` reports `missing`, `content_mismatch`, or `stray`
59
+ ## `instructions validate` reports `missing`, `content_mismatch`, `stray`, or `managed_shim`
60
60
 
61
+ - Check the effective strategy (`strategy:` in the output). The default is `none`, which expects no `CLAUDE.md`; `missing` is only reported under a configured shim strategy.
61
62
  - Run `oat instructions sync --dry-run` to preview changes.
62
- - Run `oat instructions sync --strategy pointer|symlink|copy` to apply the expected `CLAUDE.md` shape.
63
- - If mismatched `CLAUDE.md` files should be overwritten, run `oat instructions sync --force` (or combine it with `--strategy` if needed).
64
- - If `stray` is reported, `oat instructions sync` will adopt the Claude-only file into `AGENTS.md` and then regenerate `CLAUDE.md`.
63
+ - Under `none`, `managed_shim` entries are `CLAUDE.md` files OAT created; `oat instructions sync` removes them, unless a `CLAUDE.md` with its own content blocks removal (see below).
64
+ - To keep shims instead, run `oat config set instructions.claude.shims pointer` (or `symlink` / `copy`) and then `oat instructions sync`.
65
+ - Under a shim strategy, if mismatched `CLAUDE.md` files should be overwritten, run `oat instructions sync --force`.
66
+ - If `stray` is reported, `oat instructions sync` will adopt the Claude-only file into `AGENTS.md`, then regenerate `CLAUDE.md` under a shim strategy or remove it under `none`.
67
+
68
+ ## `instructions sync` removed no shims because a `CLAUDE.md` has content
69
+
70
+ - Under `none`, removal is all or nothing: while any `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` has content of its own, sync removes no `CLAUDE.md` at all, reports each held-back removal as skipped, and exits `1`. The finding (`claude_md_blocks_shim_removal` under `--json`) names the files with content (`paths`) and the `CLAUDE.md` files kept (`wouldRemove`); `linkedBy` names any `AGENTS.md` link to a file with content, which you replace with that file's content before removing it. `oat instructions validate` reports the same finding.
71
+ - Either remove each named file or move its content into an `AGENTS.md`, then rerun `oat instructions sync`; or set `instructions.claude.shims` to `pointer`, `symlink`, or `copy` to keep `CLAUDE.md` files.
72
+ - See [Instruction Sync](../provider-sync/instruction-sync.md#all-or-nothing).
73
+
74
+ ## `instructions sync` warns that a `CLAUDE.md` makes Claude Code ignore every `AGENTS.md`
75
+
76
+ - Under the default `none` strategy, a remaining `CLAUDE.md`, `.claude/CLAUDE.md`, or `CLAUDE.local.md` makes Claude Code's `agents-md` plugin stand down: for every session when the file is at the repository root, and for sessions started in its directory or below when it is in a subdirectory.
77
+ - Either remove the named file, or set `instructions.claude.shims` to a shim strategy and rerun `oat instructions sync` to add shims everywhere.
78
+ - If the warning names an `AGENTS.md` that links to the file (`linkedBy` under `--json`), that file holds the only copy of those instructions: replace each linking `AGENTS.md` with the file's content first, then remove the file.
79
+ - Sync never deletes a hand-written or modified `CLAUDE.md` itself; see [Instruction Sync](../provider-sync/instruction-sync.md#leftover-claudemd-warnings).
65
80
  - If a broken or unreadable instruction path is reported, fix the underlying file or symlink target first; sync will intentionally skip manual-repair cases instead of forcing recovery.
66
81
  - If a directory you expected to see is missing from the scan, confirm it is not under `.git`, `.oat`, `.worktrees`, or `node_modules`.
67
82
  - Re-run `oat instructions validate` and confirm status is `ok`.
@@ -86,7 +86,11 @@ before launch. That validation-only call derives the configured invocation and
86
86
  does not persist a journal file. When a host opts in, the generic snake-case
87
87
  fields remain authoritative. A namespaced `oat` block adds
88
88
  only canonical-role identity, proven pre-start rejection, fallback linkage,
89
- and optional runtime observation. `DispatchReportV1` and the parseable
89
+ and optional runtime observation. `oat project dispatch canonical-role`
90
+ prints the canonical-role-resolution event read-only, so callers do not
91
+ hand-author it; a validated managed Claude input per role is published at
92
+ `.agents/skills/oat-dispatch-subagents/references/managed-claude-example.json`.
93
+ `DispatchReportV1` and the parseable
90
94
  `Dispatch:` compatibility stamp keep their existing byte shape.
91
95
 
92
96
  The launcher constructs and redacts the complete payload before calling the