@open-agent-toolkit/cli 0.3.10 → 0.3.11

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 (163) hide show
  1. package/README.md +2 -1
  2. package/assets/bundle-metadata.json +1 -1
  3. package/assets/docs/cli-utilities/meta.json +13 -0
  4. package/assets/docs/cli-utilities/tool-packs.md +8 -2
  5. package/assets/docs/cli-utilities/workflow-gates.md +13 -0
  6. package/assets/docs/contributing/code.md +8 -2
  7. package/assets/docs/contributing/documentation.md +7 -1
  8. package/assets/docs/contributing/meta.json +15 -0
  9. package/assets/docs/docs-tooling/add-docs-to-a-repo.md +14 -5
  10. package/assets/docs/docs-tooling/commands.md +26 -8
  11. package/assets/docs/docs-tooling/meta.json +4 -0
  12. package/assets/docs/docs-tooling/workflows.md +2 -2
  13. package/assets/docs/guide/meta.json +4 -0
  14. package/assets/docs/meta.json +14 -0
  15. package/assets/docs/provider-sync/instruction-sync.md +8 -0
  16. package/assets/docs/provider-sync/meta.json +11 -0
  17. package/assets/docs/provider-sync/scope-and-surface.md +3 -4
  18. package/assets/docs/reference/cli-reference.md +5 -2
  19. package/assets/docs/reference/docs-index-contract.md +22 -6
  20. package/assets/docs/reference/file-locations.md +7 -2
  21. package/assets/docs/reference/index.md +1 -1
  22. package/assets/docs/reference/meta.json +10 -0
  23. package/assets/docs/reference/troubleshooting.md +41 -6
  24. package/assets/docs/workflows/ideas/meta.json +4 -0
  25. package/assets/docs/workflows/meta.json +4 -0
  26. package/assets/docs/workflows/projects/cursor-cloud.md +8 -3
  27. package/assets/docs/workflows/projects/evidence-layers.md +6 -8
  28. package/assets/docs/workflows/projects/implementation-execution.md +30 -4
  29. package/assets/docs/workflows/projects/lifecycle.md +7 -1
  30. package/assets/docs/workflows/projects/meta.json +25 -0
  31. package/assets/docs/workflows/projects/orchestration-model.md +5 -6
  32. package/assets/docs/workflows/skills/meta.json +10 -0
  33. package/assets/docs/workflows/skills/recon.md +28 -3
  34. package/assets/public-package-versions.json +4 -4
  35. package/assets/skills/oat-cursor-cloud-projects/SKILL.md +30 -16
  36. package/assets/skills/oat-dispatch-subagents/SKILL.md +4 -12
  37. package/assets/skills/oat-dispatch-subagents/references/managed-claude-example.json +1 -1
  38. package/assets/skills/oat-dispatch-subagents/references/provider-codex.md +51 -0
  39. package/assets/skills/oat-dispatch-subagents/references/record-schema.md +8 -7
  40. package/assets/skills/oat-docs-analyze/SKILL.md +28 -3
  41. package/assets/skills/oat-docs-apply/SKILL.md +3 -3
  42. package/assets/skills/oat-docs-authoring/SKILL.md +1 -1
  43. package/assets/skills/oat-docs-authoring/references/oat-fumadocs-contract.md +5 -2
  44. package/assets/skills/oat-docs-bootstrap/SKILL.md +4 -3
  45. package/assets/skills/oat-docs-bootstrap/assets/AGENTS.md.template +3 -3
  46. package/assets/skills/oat-pjm-decision/SKILL.md +3 -2
  47. package/assets/skills/oat-project-autonomous/references/gate-inventory.md +4 -4
  48. package/assets/skills/oat-project-complete/SKILL.md +47 -2
  49. package/assets/skills/oat-project-design/SKILL.md +10 -6
  50. package/assets/skills/oat-project-discover/SKILL.md +3 -3
  51. package/assets/skills/oat-project-dispatch-subagents/SKILL.md +3 -10
  52. package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +4 -4
  53. package/assets/skills/oat-project-implement/SKILL.md +1 -1
  54. package/assets/skills/oat-project-implement/references/completion-and-closeout.md +135 -3
  55. package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +7 -9
  56. package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +4 -4
  57. package/assets/skills/oat-project-implement/references/plan-and-resume.md +1 -1
  58. package/assets/skills/oat-project-import-plan/SKILL.md +3 -3
  59. package/assets/skills/oat-project-lite/references/docs/autonomy-contract.md +4 -4
  60. package/assets/skills/oat-project-new/SKILL.md +3 -3
  61. package/assets/skills/oat-project-next/SKILL.md +50 -7
  62. package/assets/skills/oat-project-plan/SKILL.md +4 -4
  63. package/assets/skills/oat-project-plan-writing/SKILL.md +2 -2
  64. package/assets/skills/oat-project-pr-final/SKILL.md +11 -1
  65. package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +4 -4
  66. package/assets/skills/oat-project-promote-spec-driven/SKILL.md +2 -2
  67. package/assets/skills/oat-project-quick-start/SKILL.md +12 -8
  68. package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +4 -4
  69. package/assets/skills/oat-project-retro/SKILL.md +6 -3
  70. package/assets/skills/oat-project-review-provide/SKILL.md +2 -2
  71. package/assets/skills/oat-project-review-provide-remote/SKILL.md +2 -2
  72. package/assets/skills/oat-project-spec/SKILL.md +3 -3
  73. package/assets/skills/oat-project-summary/SKILL.md +22 -3
  74. package/assets/skills/oat-repo-improve/SKILL.md +2 -2
  75. package/assets/skills/recon/SKILL.md +24 -3
  76. package/assets/skills/recon/references/packet-contract.md +36 -6
  77. package/assets/skills/recon/references/profiles.md +3 -0
  78. package/assets/skills/recon/references/worker-contract.md +16 -3
  79. package/assets/skills/recon/scripts/create-review-brief.mjs +17 -86
  80. package/assets/skills/recon/scripts/lib/contracts.mjs +158 -41
  81. package/assets/skills/recon/scripts/lib/review-binding.mjs +123 -0
  82. package/assets/skills/recon/scripts/lib/routing.mjs +5 -2
  83. package/assets/skills/recon/scripts/reconcile-ledger.mjs +18 -7
  84. package/assets/skills/recon/scripts/render-packet.mjs +93 -1
  85. package/assets/skills/recon/scripts/validate-packet.mjs +119 -88
  86. package/assets/templates/state.md +1 -0
  87. package/dist/commands/backlog/new.d.ts +2 -2
  88. package/dist/commands/backlog/new.d.ts.map +1 -1
  89. package/dist/commands/backlog/new.js +2 -2
  90. package/dist/commands/decision/new.d.ts +2 -2
  91. package/dist/commands/decision/new.d.ts.map +1 -1
  92. package/dist/commands/decision/new.js +2 -2
  93. package/dist/commands/docs/nav/contents.d.ts +9 -0
  94. package/dist/commands/docs/nav/contents.d.ts.map +1 -1
  95. package/dist/commands/docs/nav/contents.js +7 -2
  96. package/dist/commands/docs/nav/fumadocs.d.ts +51 -0
  97. package/dist/commands/docs/nav/fumadocs.d.ts.map +1 -0
  98. package/dist/commands/docs/nav/fumadocs.js +301 -0
  99. package/dist/commands/docs/nav/sync.d.ts +31 -1
  100. package/dist/commands/docs/nav/sync.d.ts.map +1 -1
  101. package/dist/commands/docs/nav/sync.js +163 -6
  102. package/dist/commands/index.d.ts.map +1 -1
  103. package/dist/commands/index.js +2 -0
  104. package/dist/commands/instructions/instructions.utils.d.ts +19 -0
  105. package/dist/commands/instructions/instructions.utils.d.ts.map +1 -1
  106. package/dist/commands/instructions/instructions.utils.js +89 -17
  107. package/dist/commands/instructions/sync/sync.d.ts.map +1 -1
  108. package/dist/commands/instructions/sync/sync.js +49 -2
  109. package/dist/commands/pjm/init.d.ts.map +1 -1
  110. package/dist/commands/pjm/init.js +2 -2
  111. package/dist/commands/project/closeout-check/closeout-invariant.d.ts +97 -0
  112. package/dist/commands/project/closeout-check/closeout-invariant.d.ts.map +1 -0
  113. package/dist/commands/project/closeout-check/closeout-invariant.js +301 -0
  114. package/dist/commands/project/closeout-check/index.d.ts +38 -0
  115. package/dist/commands/project/closeout-check/index.d.ts.map +1 -0
  116. package/dist/commands/project/closeout-check/index.js +117 -0
  117. package/dist/commands/project/complete-state/index.d.ts +4 -0
  118. package/dist/commands/project/complete-state/index.d.ts.map +1 -1
  119. package/dist/commands/project/complete-state/index.js +11 -13
  120. package/dist/commands/project/dispatch/index.d.ts.map +1 -1
  121. package/dist/commands/project/dispatch/index.js +6 -30
  122. package/dist/commands/project/dispatch/record.d.ts +9 -18
  123. package/dist/commands/project/dispatch/record.d.ts.map +1 -1
  124. package/dist/commands/project/dispatch/record.js +15 -212
  125. package/dist/commands/project/index.d.ts.map +1 -1
  126. package/dist/commands/project/index.js +2 -0
  127. package/dist/commands/project/new/scaffold.d.ts +0 -1
  128. package/dist/commands/project/new/scaffold.d.ts.map +1 -1
  129. package/dist/commands/project/new/scaffold.js +19 -20
  130. package/dist/commands/project/promote/promote.d.ts +2 -2
  131. package/dist/commands/project/promote/promote.d.ts.map +1 -1
  132. package/dist/commands/project/promote/promote.js +13 -11
  133. package/dist/commands/shared/frontmatter.d.ts +21 -0
  134. package/dist/commands/shared/frontmatter.d.ts.map +1 -1
  135. package/dist/commands/shared/frontmatter.js +70 -4
  136. package/dist/commands/shared/template-source.d.ts +29 -0
  137. package/dist/commands/shared/template-source.d.ts.map +1 -0
  138. package/dist/commands/{pjm → shared}/template-source.js +24 -7
  139. package/dist/commands/state/generate.js +2 -2
  140. package/dist/commands/template/index.d.ts +10 -0
  141. package/dist/commands/template/index.d.ts.map +1 -0
  142. package/dist/commands/template/index.js +87 -0
  143. package/dist/commands/template/resolve.d.ts +31 -0
  144. package/dist/commands/template/resolve.d.ts.map +1 -0
  145. package/dist/commands/template/resolve.js +86 -0
  146. package/dist/fs/io.d.ts +0 -41
  147. package/dist/fs/io.d.ts.map +1 -1
  148. package/dist/fs/io.js +2 -414
  149. package/dist/providers/identity/absolute-paths.d.ts +4 -13
  150. package/dist/providers/identity/absolute-paths.d.ts.map +1 -1
  151. package/dist/providers/identity/absolute-paths.js +4 -17
  152. package/dist/providers/identity/generic-dispatch-record.d.ts +1 -1
  153. package/dist/providers/identity/generic-dispatch-record.js +2 -2
  154. package/dist/providers/identity/oat-dispatch-record.d.ts +4 -357
  155. package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -1
  156. package/dist/providers/identity/oat-dispatch-record.js +4 -236
  157. package/dist/release/public-package-contract.d.ts.map +1 -1
  158. package/dist/release/public-package-contract.js +12 -4
  159. package/dist/validation/skills.d.ts.map +1 -1
  160. package/dist/validation/skills.js +32 -6
  161. package/package.json +2 -2
  162. package/dist/commands/pjm/template-source.d.ts +0 -14
  163. package/dist/commands/pjm/template-source.d.ts.map +0 -1
@@ -77,14 +77,12 @@ section.
77
77
 
78
78
  For project-aware work, the calling workflow records each launch in its run
79
79
  record in `implementation.md` (request ID, `Dispatch:` stamp, launch status,
80
- terminal outcome). Persisting one generic record per request under the
81
- project's `dispatch/` directory with `oat project dispatch record` is optional
82
- and off by default; no lifecycle skill or command consumes those files. Managed
83
- effort-pinned Claude launches still pass the real resolver result, generated
84
- definition, and proposed payload through the command without `--project`
85
- before launch. That validation-only call derives the configured invocation and
86
- does not persist a journal file. When a host opts in, the generic snake-case
87
- fields remain authoritative. A namespaced `oat` block adds
80
+ terminal outcome); that run record is the only launch record.
81
+ `oat project dispatch record` validates a generic record and writes nothing.
82
+ Managed effort-pinned Claude launches pass the real resolver result, generated
83
+ definition, and proposed payload through it before launch, and that
84
+ validation-only call derives the configured invocation. In a validated record
85
+ the generic snake-case fields remain authoritative. A namespaced `oat` block adds
88
86
  only canonical-role identity, proven pre-start rejection, fallback linkage,
89
87
  and optional runtime observation. `oat project dispatch canonical-role`
90
88
  prints the canonical-role-resolution event read-only, so callers do not
@@ -76,10 +76,10 @@ that scope.
76
76
  Before a native launch, the root constructs and redacts the complete generic
77
77
  dispatch record and OAT role event. When the host returns, it writes the
78
78
  request ID, the `Dispatch:` stamp, and the accepted or `blocked-before-start`
79
- result into the run record in `implementation.md`; persisting a per-dispatch
80
- file with `oat project dispatch record` is optional and off by default. Before
81
- an effort-pinned managed Claude launch, the root must still run that command
82
- without `--project` as a validation-only boundary. It supplies the real
79
+ result into the run record in `implementation.md`, the only launch record.
80
+ Before an effort-pinned managed Claude launch, the root must run
81
+ `oat project dispatch record`, which writes nothing, as a validation-only
82
+ boundary. It supplies the real
83
83
  resolver result, generated definition, and proposed launch payload, and launches
84
84
  only the payload returned by the accepted envelope. An accepted launch closes
85
85
  replacement. Only an explicit rejection proving no child started permits one
@@ -319,6 +319,32 @@ and start a new gate generation. Beyond the version's own exclusion set, no
319
319
  implementation or closeout output path is excluded from the comparison. Legacy unqualified fingerprints retain the older
320
320
  fail-closed descendant-path behavior and are not migrated in place.
321
321
 
322
+ There is no automatic test-only freshness exception. An operator can instead
323
+ waive named stale-making descendants of an `effective-delta-v1` or
324
+ `effective-delta-v2` generation (`DR-260927-operator-waiver-for-test-only`).
325
+ Each waiver is appended to `oat_implement_exit_gate.waivers` with who waived,
326
+ the reason, the covered `from_commit..to_commit` range, the effective-delta
327
+ fingerprint at the range end (in the generation's own version), and a UTC
328
+ timestamp. A waiver never rewrites `reviewed_head`, the implementation
329
+ fingerprint, `freshness_head`, or the freshness fingerprint, and an earlier
330
+ waiver is never edited. Agents write a waiver only on an explicit operator
331
+ instruction. Under `OAT_AUTONOMOUS=1` an attempted waiver write is refused,
332
+ and a run that finds a stale generation persists `stale` and starts a new gate
333
+ run instead of pausing. A waived generation stays fresh only while nothing
334
+ substantive lands after the covered range, under both versions; a malformed or
335
+ unverifiable waiver fails closed as stale. The project summary and the final PR
336
+ description's Verification section list every waiver.
337
+
338
+ The waiver is offered where staleness is found. Before an interactive
339
+ `oat-project-implement` run persists an allowed generation as `stale` because
340
+ of descendant commits no waiver covers, it lists those commits and asks the
341
+ operator to waive that range or start a new gate run; it persists `stale` only
342
+ when the operator declines. An autonomous run never offers a waiver and starts
343
+ a new gate run. An operator may also record a waiver before resuming
344
+ implementation, for example after `oat-project-next` reports stale state, by
345
+ giving the range, name, and reason in the instruction that resumes
346
+ `oat-project-implement`.
347
+
322
348
  This narrow merge-only exemption relies on fresh repository CI, automated
323
349
  review such as Bugbot, and lifecycle self-review to cover integration risk.
324
350
  Those checks do not substitute for the semantic gate on the full
@@ -65,6 +65,12 @@ allowed and fresh disposition before pre-approval work starts. A
65
65
  not inferred from missing state, and a null, missing, or unrecognized resolver
66
66
  result fails closed as unresolved instead.
67
67
 
68
+ A later substantive change makes an allowed result stale, test-only changes
69
+ included. Only an operator can keep it fresh, by recording an append-only
70
+ exit-gate waiver for the exact commits; agents never issue one. An autonomous
71
+ run that finds a stale result persists `stale` and starts a new gate run; it
72
+ refuses only an attempted waiver write. The summary and PR description list every waiver.
73
+
68
74
  After implementation closeout finishes:
69
75
 
70
76
  1. **Summary** (`oat-project-summary`) — generates `summary.md` as institutional memory from project artifacts; PR-final and completion will auto-refresh it if you have not already run it or if it is stale
@@ -75,7 +81,7 @@ After implementation closeout finishes:
75
81
  - GitHub PR feedback delegates to `oat-project-review-receive-remote`
76
82
  - Review artifacts delegate to `oat-project-review-receive`
77
83
  - After revision tasks complete, state returns to `pr_open`
78
- 5. **Complete** (`oat-project-complete`) — accepts any phase status (`pr_open`, `complete`, `in_progress`), auto-refreshes `summary.md` before closeout when needed, and archives when selected by the workflow preference or completion prompt
84
+ 5. **Complete** (`oat-project-complete`) — accepts any phase status (`pr_open`, `complete`, `in_progress`), auto-refreshes `summary.md` before closeout when needed, and archives when selected by the workflow preference or completion prompt. Before any completion write it runs the read-only `oat project closeout-check`: a configured, autonomous, or lite closeout whose `oat_post_implement_sequence` snapshot is missing, malformed, or incomplete stops and routes back to `oat-project-implement`, and `oat project complete-state` refuses the same state. There is no override; see the [CLI reference](../../reference/cli-reference.md).
79
85
 
80
86
  ### Project-recap gate (non-lite)
81
87
 
@@ -0,0 +1,25 @@
1
+ {
2
+ "title": "Workflow & Projects",
3
+ "pages": [
4
+ "lifecycle",
5
+ "retro",
6
+ "autonomy",
7
+ "cursor-cloud",
8
+ "design-modes",
9
+ "hill-checkpoints",
10
+ "dispatch-ceiling",
11
+ "orchestration-model",
12
+ "review-flavors",
13
+ "evidence-layers",
14
+ "programmatic-execution",
15
+ "artifacts",
16
+ "implementation-execution",
17
+ "reviewing-oat-prs",
18
+ "picking-up-projects",
19
+ "splitting",
20
+ "state-machine",
21
+ "reviews",
22
+ "pr-flow",
23
+ "repo-analysis"
24
+ ]
25
+ }
@@ -76,14 +76,14 @@ sequenceDiagram
76
76
  participant Root as Project root
77
77
  participant Adapter as Project adapter
78
78
  participant Engine as Dispatch engine
79
- participant Journal as Project dispatch journal
79
+ participant Record as Run record in implementation.md
80
80
  participant Phase as Phase implementer
81
81
 
82
82
  Root->>Adapter: Phase + lifecycle authority
83
83
  Adapter->>Engine: Provider-neutral dispatch request
84
84
  Engine-->>Root: Exact route + request ID
85
85
  Root->>Phase: Phase Scope
86
- Root->>Journal: Accepted or blocked-before-start record
86
+ Root->>Record: Accepted or blocked-before-start result
87
87
  Phase-->>Root: Phase report + commits
88
88
  ```
89
89
 
@@ -125,10 +125,9 @@ launch.
125
125
  The launcher constructs and redacts the complete generic record plus the
126
126
  namespaced OAT role event before it calls the native host. When the host
127
127
  returns, the calling workflow writes the accepted or `blocked-before-start`
128
- state into its run record in `implementation.md`. Persisting a per-dispatch
129
- file with `oat project dispatch record` is optional and off by default; the
130
- command is a recorder only and never launches a provider or changes selection
131
- authority.
128
+ state into its run record in `implementation.md`, the only launch record.
129
+ `oat project dispatch record` validates a record and writes nothing; it never
130
+ launches a provider or changes selection authority.
132
131
 
133
132
  An accepted handle owns the scope and closes replacement. One fresh fallback
134
133
  record is legal only when the native wrapper proves no child started, links the
@@ -0,0 +1,10 @@
1
+ {
2
+ "title": "Skills",
3
+ "pages": [
4
+ "[Writing Skills](/contributing/skills)",
5
+ "[Docs Workflows](/docs-tooling/workflows)",
6
+ "explainer-kit",
7
+ "repo-improve",
8
+ "recon"
9
+ ]
10
+ }
@@ -275,6 +275,12 @@ them. Adversarial reviewers receive the declared scope, questions, and
275
275
  provisional statements. Neither pass receives gatherer reasoning, synthesis
276
276
  prose, dossier paths, or earlier review conclusions.
277
277
 
278
+ Review briefs come only from the production brief generator. The packet
279
+ validator rebuilds every brief from the prior claim ledger and manifest with
280
+ that same generator and rejects any difference with `REVIEW_BRIEF_MISMATCH`, so
281
+ a brief carrying an injected claim, note, or source fails publication. A
282
+ review's dispositions must also be unique members of its brief's claims.
283
+
278
284
  Each lane receives one explicit authority envelope and one unique output path.
279
285
  Its enforcement is recorded as:
280
286
 
@@ -293,8 +299,17 @@ operation.
293
299
  A structurally valid run can publish an honest `partial` packet. The manifest
294
300
  and `packet.md` then identify the requested and achieved profiles, failed or
295
301
  omitted passes, material gaps, affected claims, and required assurance
296
- downgrades. A run may be partial even when it achieved the requested profile if
297
- a material evidence gap remains. The achieved profile is derived from the
302
+ downgrades. Every claim a review kept below `verified` (an unresolved issue
303
+ scoped to it or global to its review, a coverage finding that names it, or a
304
+ non-affirming disposition) is listed under Review Downgrades with the review's
305
+ own text, even when it is not a key claim, so a `complete` packet cannot hide a
306
+ downgraded claim. A claim that a required review left without a disposition stays
307
+ `unresolved` and is listed there as not reviewed. A review's
308
+ `unresolvedIssues` entry may name the claim IDs it affects or apply to the
309
+ whole review; a legacy plain-string entry is read as review-wide. A material
310
+ coverage gap does not fail publication by itself: the claims it affects stay
311
+ below `verified` and the run publishes as an honest `partial`. A run may be partial even when it achieved the requested
312
+ profile if a material evidence gap remains. The achieved profile is derived from the
298
313
  complete typed artifacts in the packet; each required pass without a complete
299
314
  result needs a material `PASS_FAILED` or `PASS_OMITTED` gap. Each approved lane
300
315
  must likewise have a complete artifact or a material outcome gap carrying its
@@ -310,7 +325,17 @@ honest `partial` packet at that achieved profile.
310
325
 
311
326
  Status updates and the final handoff label each failure as `worker`,
312
327
  `provider/dispatch`, `contract validation`, or `source availability`, and
313
- say whether every accepted lane reached a terminal result. Workers that
328
+ say whether every accepted lane reached a terminal result.
329
+
330
+ A launch the provider rejects before any child is accepted, such as a Codex
331
+ agent-limit rejection, is a `provider/dispatch` failure, never a worker
332
+ failure, and every accepted artifact is kept. The approved `retryLimit` counts
333
+ these pre-acceptance admission retries per lane, and the controller makes at
334
+ most one per lane, so the approval preview's worst case is two attempts per
335
+ lane. The default of 0 allows none. If admission still fails, recon uses an
336
+ alternate route only when it was already approved; otherwise it stops with a
337
+ partial run and asks for a continuation amendment. An accepted lane is never
338
+ rerun to free capacity. Workers that
314
339
  completed are never reported as failed because the controller could not
315
340
  publish.
316
341
 
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.3.10",
3
- "docs-config": "0.3.10",
4
- "docs-theme": "0.3.10",
5
- "docs-transforms": "0.3.10"
2
+ "cli": "0.3.11",
3
+ "docs-config": "0.3.11",
4
+ "docs-theme": "0.3.11",
5
+ "docs-transforms": "0.3.11"
6
6
  }
@@ -5,7 +5,7 @@ disable-model-invocation: false
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Write, Bash, Glob, Grep
7
7
  metadata:
8
- version: 1.1.2
8
+ version: 1.1.3
9
9
  ---
10
10
 
11
11
  # OAT in Cursor Cloud
@@ -183,7 +183,7 @@ commands from the target repository or pass their supported project path.
183
183
 
184
184
  ### Step 3: Resolve Assets with User Scope First
185
185
 
186
- Apply one source order independently to every asset file:
186
+ Apply one source order independently to every skill and script file:
187
187
 
188
188
  1. user scope;
189
189
  2. target-repository scope when the user asset is absent;
@@ -191,18 +191,30 @@ Apply one source order independently to every asset file:
191
191
 
192
192
  User locations:
193
193
 
194
- | Asset | User source |
195
- | -------- | --------------------------- |
196
- | Skill | `~/.agents/skills/<skill>/` |
197
- | Template | `~/.oat/templates/<file>` |
198
- | Script | `~/.oat/scripts/<file>` |
194
+ | Asset | User source |
195
+ | ------ | --------------------------- |
196
+ | Skill | `~/.agents/skills/<skill>/` |
197
+ | Script | `~/.oat/scripts/<file>` |
199
198
 
200
- Repository locations are `.agents/skills/`, `.oat/templates/`, and
201
- `.oat/scripts/` within the target repository.
199
+ Repository locations are `.agents/skills/` and `.oat/scripts/` within the
200
+ target repository.
202
201
 
203
- The user tier is provisioned from `@latest` at environment boot and is the
204
- canonical execution tier. Repository copies in this fleet are not customized;
205
- a difference indicates staleness, not a local override.
202
+ For skills and scripts, the user tier is provisioned from `@latest` at
203
+ environment boot and is the canonical execution tier. Repository copies of
204
+ skills and scripts in this fleet are not customized; a difference indicates
205
+ staleness, not a local override.
206
+
207
+ Templates are the exception. They resolve repository, then user, then bundled,
208
+ the same order every lifecycle skill uses, because a repository template is an
209
+ owner override. Resolve them only through the CLI, run from the target
210
+ repository:
211
+
212
+ ```bash
213
+ oat template resolve <name> --json # report the tier
214
+ oat template resolve <name> --output "<destination>" # copy the template
215
+ ```
216
+
217
+ Do not read `~/.oat/templates/` directly or choose a template tier by hand.
206
218
 
207
219
  #### Absolute-path loading contract
208
220
 
@@ -213,7 +225,6 @@ Therefore, resolve and read the selected user asset by absolute path as the
213
225
 
214
226
  ```bash
215
227
  USER_SKILLS_ROOT="${HOME}/.agents/skills"
216
- USER_TEMPLATES_ROOT="${HOME}/.oat/templates"
217
228
  USER_SCRIPTS_ROOT="${HOME}/.oat/scripts"
218
229
  ```
219
230
 
@@ -238,8 +249,9 @@ It never chooses the source:
238
249
  - if freshness is safety-critical, refresh and re-verify before continuing;
239
250
  stop if the user tier cannot be refreshed safely.
240
251
 
241
- Never silently switch to the repo copy. Apply per-file precedence to templates
242
- and scripts without using skill semver as their arbitration mechanism.
252
+ Never silently switch to the repo copy. Apply per-file precedence to scripts
253
+ without using skill semver as their arbitration mechanism; templates follow
254
+ `oat template resolve`.
243
255
 
244
256
  ### Step 4: Load Cursor Dispatch Context When Needed
245
257
 
@@ -328,7 +340,9 @@ separate dispatch surface and snapshot its current catalog. See
328
340
  - ✅ `oat` was verified before project artifact work.
329
341
  - ✅ The project home is anchored inside the target repository in both single-
330
342
  and multi-repo environments.
331
- - ✅ Existing user assets won independently for skills, templates, and scripts.
343
+ - ✅ Existing user assets won independently for skills and scripts.
344
+ - ✅ Templates were resolved through `oat template resolve` (repository, user,
345
+ then bundled).
332
346
  - ✅ Skill version comparison verified freshness without changing source.
333
347
  - ✅ User assets were read by absolute path as the primary mechanism.
334
348
  - ✅ Cursor dispatch mechanics remained delegated to the canonical provider
@@ -5,7 +5,7 @@ disable-model-invocation: true
5
5
  user-invocable: false
6
6
  allowed-tools: Read
7
7
  metadata:
8
- version: 1.2.11
8
+ version: 1.2.12
9
9
  ---
10
10
 
11
11
  # Dispatching OAT Subagents
@@ -176,17 +176,9 @@ terminal outcome, not a pre-start rejection, and must be recorded through
176
176
  `provesNoChildStarted: true`, and no fallback is authorized.
177
177
 
178
178
  The calling workflow records each launch in its own run record (request ID,
179
- `Dispatch:` stamp, launch status, terminal outcome). Writing a per-dispatch file with `oat project dispatch record` is optional and off by default: no lifecycle skill or command consumes those files, so do not write them unless the host has explicitly opted in. A host that has opted
180
- in passes the validated record and event on standard input:
181
-
182
- ```bash
183
- oat project dispatch record \
184
- --project "$PROJECT_PATH" \
185
- --event-file - \
186
- --json
187
- ```
188
-
189
- The command validates and persists evidence only. It never launches a provider.
179
+ `Dispatch:` stamp, launch status, terminal outcome); that run record is the
180
+ only launch record. `oat project dispatch record --event-file - --json`
181
+ validates a record and event and writes nothing. It never launches a provider.
190
182
 
191
183
  ## Capability and Authorization
192
184
 
@@ -1,5 +1,5 @@
1
1
  {
2
- "description": "Managed Claude validation-only inputs for `oat project dispatch record --event-file <file> --json` (no --project). Each role key is one complete input. claudeLaunch.resolution is `oat project dispatch-ceiling resolve --provider claude --role <role> --json` output verbatim; claudeLaunch.definition is the generated Claude agent file content; claudeLaunch.payload is the exact launch payload; event is `oat project dispatch canonical-role --json` output. Built from fixture agents, so the definition body, role version, and content digest are illustrative. See record-schema.md, Managed Claude Validation Input.",
2
+ "description": "Managed Claude validation-only inputs for `oat project dispatch record --event-file <file> --json`. Each role key is one complete input. claudeLaunch.resolution is `oat project dispatch-ceiling resolve --provider claude --role <role> --json` output verbatim; claudeLaunch.definition is the generated Claude agent file content; claudeLaunch.payload is the exact launch payload; event is `oat project dispatch canonical-role --json` output. Built from fixture agents, so the definition body, role version, and content digest are illustrative. See record-schema.md, Managed Claude Validation Input.",
3
3
  "implementer": {
4
4
  "claudeLaunch": {
5
5
  "resolution": {
@@ -110,3 +110,54 @@ Add a service tier or reasoning mode only through controls shown by the current
110
110
  CLI/schema. Honor the caller's authorization boundary. Record every selector
111
111
  as configured invocation evidence; do not infer runtime identity from process
112
112
  success alone.
113
+
114
+ ## Agent-Limit Rejections and v2 Residency
115
+
116
+ A native spawn rejected with `agent thread limit reached`
117
+ (`AgentLimitReached`) before any child is accepted is a pre-start
118
+ provider/dispatch outcome, not a worker failure, and not by itself evidence of
119
+ cumulative or lifetime thread exhaustion. The v2 lifecycle facts below are
120
+ cited from the openai/codex `rust-v0.159.2` tag; re-check them when the
121
+ installed Codex version changes.
122
+
123
+ - Before returning `AgentLimitReached`, v2 admission tries to unload an eligible
124
+ resident. A resident is eligible only when it is completed, errored, or
125
+ interrupted, has no active turn, has no pending mailbox items, and holds no
126
+ residency lock
127
+ ([`residency.rs` L99-L120](https://github.com/openai/codex/blob/rust-v0.159.2/codex-rs/core/src/agent/control/residency.rs#L99-L120),
128
+ [eligibility L266-L272](https://github.com/openai/codex/blob/rust-v0.159.2/codex-rs/core/src/agent/control/residency.rs#L266-L272)).
129
+ A visible completed status does not prove eligibility: status does not
130
+ expose mailbox state, active-turn cleanup, or residency locks.
131
+ - The v2 toolset exposes `interrupt_agent`, which interrupts work but does not
132
+ unregister the agent. Older toolsets expose `close_agent`
133
+ ([`spec_plan.rs`](https://github.com/openai/codex/blob/rust-v0.159.2/codex-rs/core/src/tools/spec_plan.rs)).
134
+ Never present `interrupt_agent` as a close or release.
135
+ - A queue-only message to a completed v2 agent can pin it by leaving a pending
136
+ mailbox item
137
+ ([openai/codex#32353](https://github.com/openai/codex/issues/32353)). Do not
138
+ message completed agents to clean them up.
139
+ - Reports of completed residents blocking replacement are nondeterministic
140
+ ([openai/codex#44351](https://github.com/openai/codex/issues/44351)), and
141
+ older open-thread quota behavior
142
+ ([openai/codex#22779](https://github.com/openai/codex/issues/22779)) is a
143
+ different mechanism. Do not conflate either with v2 residency eviction.
144
+
145
+ On a pre-acceptance agent-limit rejection:
146
+
147
+ 1. Keep every accepted artifact and record the exact rejection as a
148
+ provider/dispatch outcome.
149
+ 2. Inspect the available lifecycle tools and statuses. Release only completed
150
+ agents whose output is already retained, and only through a close or release
151
+ tool the live toolset supports; never close the root or an active required
152
+ lane.
153
+ 3. Do not archive or delete sessions to free capacity. Archive availability
154
+ does not prove that it releases a v2 residency slot.
155
+ 4. Make at most one admission retry, only when the caller's approved dispatch
156
+ envelope allows retries and after the eligibility check above. A wait result
157
+ or a completed status alone does not justify another attempt.
158
+ 5. If admission still fails, use an alternate route only when the caller
159
+ already approved it; otherwise stop and return the partial result for a
160
+ concrete continuation amendment.
161
+
162
+ No retry or route changes model, effort, role behavior, data authority, output
163
+ limits, or reviewer blindness. Never rerun an accepted lane to free capacity.
@@ -212,7 +212,7 @@ selection source.
212
212
 
213
213
  Before every managed, effort-pinned Claude implementer or reviewer launch,
214
214
  `oat-project-implement` runs `oat project dispatch record --event-file <file>
215
- --json` without `--project` and requires `status: validated-only`. That input
215
+ --json` and requires `status: validated-only`. That input
216
216
  replaces `record` with three top-level keys:
217
217
 
218
218
  - `claudeLaunch`, an object with three keys of its own:
@@ -361,10 +361,10 @@ be traded against another:
361
361
  strings; and
362
362
  - at most 16 KiB serialized per field.
363
363
 
364
- The whole record is additionally capped at 64 KiB, measured as the **published**
365
- bytes — the pretty-printed JSON plus trailing newline that is actually written
366
- to the journal, not compact `JSON.stringify` output. The two differ by roughly a
367
- tenth on a nested record, so size against the published form. Per-field
364
+ The whole record is additionally capped at 64 KiB, measured as the **serialized**
365
+ document — the pretty-printed JSON plus trailing newline, not compact
366
+ `JSON.stringify` output. The two differ by roughly a tenth on a nested record,
367
+ so size against the serialized form. Per-field
368
368
  projection limits above remain compact measurements, because they bound the
369
369
  shape of a field rather than the size of a file. A realistically rich record
370
370
  measures a few kilobytes, so these limits bind prompt bodies, transcripts, and
@@ -376,8 +376,9 @@ cannot fully account for is treated as sensitive rather than classified on a
376
376
  partial token. Store references, identifiers, and digests; never role content, message bodies,
377
377
  or credentials.
378
378
 
379
- Absolute filesystem paths are handled by field class, because the journal is
380
- committed and a home path in it is permanent:
379
+ Absolute filesystem paths are handled by field class, because the validated
380
+ record is printed verbatim and a caller may copy it into a committed artifact,
381
+ where a home path is permanent:
381
382
 
382
383
  - **Identity and control fields reject them.** `caller`, `scope`, every
383
384
  selector, `selected_route`, the `guidance_*` fields, `authority`,
@@ -3,9 +3,9 @@ name: oat-docs-analyze
3
3
  description: Run when you need to evaluate documentation structure, navigation, and coverage against the OAT docs app contract. Produces a severity-rated analysis artifact for oat-docs-apply.
4
4
  disable-model-invocation: true
5
5
  user-invocable: true
6
- allowed-tools: Read, Write, Bash(git:*), Glob, Grep, AskUserQuestion, Task
6
+ allowed-tools: Read, Write, Bash(git:*), Bash(oat docs nav sync --check:*), Glob, Grep, AskUserQuestion, Task
7
7
  metadata:
8
- version: 1.5.2
8
+ version: 1.6.0
9
9
  ---
10
10
 
11
11
  # Docs Analysis
@@ -386,6 +386,31 @@ If a generated root index or manifest exists:
386
386
  files, and representative links for each finding.
387
387
  5. Prefer source-of-truth fixes over generated-file edits.
388
388
 
389
+ If the app is Fumadocs (a `source.config.ts` beside `docs/`), its sidebar comes from
390
+ `docs/**/meta.json` files that `oat docs nav sync` generates from `## Contents`:
391
+
392
+ 1. Flag a docs directory with an `index.md` but no `meta.json` as a missing
393
+ generated artifact.
394
+ 2. Flag a `meta.json` whose `pages` order or entries differ from that directory's
395
+ `## Contents` (immediate pages and child folders by name, `index` first in the
396
+ docs root and in any `root: true` folder, other targets as `[Title](url)` link
397
+ entries) as stale; the fix is to rerun `oat docs nav sync`.
398
+ 3. Flag a `"..."` or `"z...a"` rest entry as a hand edit; nav sync output is strict.
399
+ 4. Flag pages that no `## Contents` map lists: under strict `meta.json` they are
400
+ hidden from the sidebar. Recommend listing them, not adding a rest entry.
401
+ 5. During analysis, run only the read-only check, with `--check` first and
402
+ `--target-dir` set to the resolved docs app directory (the directory that
403
+ holds `source.config.ts` and `docs/`, such as `apps/oat-docs`, not its `docs/`
404
+ content root):
405
+
406
+ ```bash
407
+ oat docs nav sync --check --target-dir <docs-app-dir>
408
+ ```
409
+
410
+ It writes nothing, names stale `meta.json` files and unlisted pages, and exits
411
+ 1 when either exists. The skill grants only this `--check` form; plain
412
+ `oat docs nav sync` writes files and is not part of analysis.
413
+
389
414
  If `mkdocs.yml` exists:
390
415
 
391
416
  1. Compare nav entries with the docs tree.
@@ -394,7 +419,7 @@ If `mkdocs.yml` exists:
394
419
  4. Flag directories whose `index.md` `## Contents` section appears inconsistent with nav structure.
395
420
  5. Flag docs guidance that claims structure, plugin support, or workflow rules not backed by current repo evidence.
396
421
 
397
- If no `mkdocs.yml` exists, record whether the repo should be migrated to an OAT docs app.
422
+ If neither `mkdocs.yml` nor a Fumadocs app exists, record whether the repo should be migrated to an OAT docs app.
398
423
 
399
424
  ### Step 7: Severity-Rate Findings
400
425
 
@@ -5,7 +5,7 @@ disable-model-invocation: true
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Write, Edit, Bash(git:*), Bash(gh:*), Glob, Grep, AskUserQuestion
7
7
  metadata:
8
- version: 1.3.1
8
+ version: 1.3.2
9
9
  ---
10
10
 
11
11
  # Docs Apply
@@ -34,7 +34,7 @@ Generate or update documentation files from a docs analysis artifact, with expli
34
34
  **ALLOWED Activities:**
35
35
 
36
36
  - Reading analysis artifacts and the current docs surface.
37
- - Creating or updating docs files and `mkdocs.yml` when approved.
37
+ - Creating or updating docs files and `mkdocs.yml` when approved. Fumadocs `meta.json` files change only through `oat docs nav sync`.
38
38
  - Running `oat docs nav sync` after approved structural changes.
39
39
  - Creating branches, commits, and optional PRs.
40
40
 
@@ -203,7 +203,7 @@ For each approved recommendation:
203
203
  When approved actions involve docs app creation or nav updates:
204
204
 
205
205
  - Use `oat docs init` for scaffolding when appropriate.
206
- - Use `oat docs nav sync` instead of manually editing nav when the CLI helper can generate it.
206
+ - Use `oat docs nav sync` instead of manually editing nav when the CLI helper can generate it. In Fumadocs apps it writes strict `meta.json` files and reports pages no `## Contents` map lists (`unlisted` in `--json`); resolve a reported page through an approved `## Contents` change, never by hand-editing `meta.json`.
207
207
 
208
208
  Negative rules:
209
209
 
@@ -6,7 +6,7 @@ disable-model-invocation: false
6
6
  allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
7
7
  user-invocable: true
8
8
  metadata:
9
- version: 1.0.1
9
+ version: 1.0.2
10
10
  ---
11
11
 
12
12
  # OAT Docs Authoring
@@ -60,8 +60,11 @@ authored docs tree. Treat it as generated output.
60
60
  - Asset-only directories do not need `index.md` unless local guidance says so.
61
61
  - Build output, hidden tool directories, and generated artifacts are not content
62
62
  directories.
63
- - Optional Fumadocs metadata files, such as `meta.json`, may refine sidebar
64
- presentation when local style uses them. They do not replace `## Contents`.
63
+ - Fumadocs `meta.json` files are generated by `oat docs nav sync` from each
64
+ directory's `## Contents`, not hand-authored. After structural changes, rerun
65
+ nav sync and commit the result; it never adds a `"..."` rest entry, so list a
66
+ page in `## Contents` to show it in the sidebar. Keys nav sync does not own,
67
+ such as `icon` or `defaultOpen`, may be added by hand and are preserved.
65
68
  - Preserve local audience routers, ownership notes, and app-shell
66
69
  customizations.
67
70
 
@@ -6,7 +6,7 @@ disable-model-invocation: true
6
6
  user-invocable: true
7
7
  allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
8
8
  metadata:
9
- version: 1.2.1
9
+ version: 1.2.2
10
10
  ---
11
11
 
12
12
  # Docs Bootstrap
@@ -930,10 +930,11 @@ Narrate:
930
930
 
931
931
  - **The authored source** at `<appRoot>/docs/index.md`. This is the file the user edits. It has frontmatter (`title`, `description`) and a `## Contents` section listing direct children of the docs root. It is the top of a fractal: every directory has its own `index.md`, each with its own `## Contents`.
932
932
  - **The Fumadocs generated map** at `<appRoot>/index.md`. Regenerated on every `predev` / `prebuild` by the `oat docs generate-index` command. Machine-shaped: inventories Markdown files with titles and descriptions so tools have a single searchable map. **Hand-edits are silently clobbered.**
933
+ - **The Fumadocs sidebar navigation** in `<appRoot>/docs/**/meta.json`. `oat docs nav sync` writes one per docs directory from that directory's `## Contents` order, and the files are committed. Navigation is strict: a page no `## Contents` map lists stays out of the sidebar and the command reports it, so the fix is to list the page, never to edit `meta.json` by hand.
933
934
  - **The MkDocs derived nav** in `mkdocs.yml` `nav:`. MkDocs does not use a Fumadocs-style generated app-root manifest; its generated/derived navigation boundary is the YAML nav block.
934
935
  - **How to tell them apart when opening a file.** If the file sits inside `docs/`, it's authored. If it sits at `<appRoot>/index.md` (outside `docs/`), it's the Fumadocs generated manifest — and when the CLI wrote the warning correctly, the first line is `<!-- AUTOGENERATED by \`oat docs generate-index\`... -->`.
935
936
 
936
- End with: "Always edit `docs/index.md` and the `## Contents` sections. In Fumadocs, never edit the root-level `index.md` — your edits will disappear next build. In MkDocs, treat `mkdocs.yml` `nav:` as derived from authored Contents unless the local workflow says otherwise."
937
+ End with: "Always edit `docs/index.md` and the `## Contents` sections. In Fumadocs, never edit the root-level `index.md` — your edits will disappear next build — and regenerate `meta.json` with `oat docs nav sync` instead of editing it. In MkDocs, treat `mkdocs.yml` `nav:` as derived from authored Contents unless the local workflow says otherwise."
937
938
 
938
939
  #### Section C (both frameworks) — The `## Contents` contract
939
940
 
@@ -944,7 +945,7 @@ Narrate:
944
945
  - **Every directory under `docs/` has an `index.md`.** No exceptions, no `overview.md`, no README-as-index. Missing `index.md`s are the first thing `oat-docs-analyze` flags.
945
946
  - **Every `index.md` has a `## Contents` section.** The section is a plain Markdown bulleted list of links to the direct children of that directory — both subdirectory `index.md`s and leaf pages.
946
947
  - **Link targets use `.md` extensions.** Leaf pages link as `[Title](page.md)`; subdirectories link as `[Section](subdir/index.md)`. The `@open-agent-toolkit/docs-transforms` remark-links plugin normalizes these at build time for Fumadocs routing (`.md` stripped; `dir/index.md` collapsed to `dir`). `.md`-suffixed authored links render correctly **and** let agents follow each link to the target file without path inference — the best of both worlds.
947
- - **The `## Contents` section is the machine-readable local map.** For Fumadocs, it remains the authored navigation intent that agents maintain and compare against the generated app-root manifest. For MkDocs, `oat docs nav sync` reads it to update `mkdocs.yml` `nav:`. `oat-docs-analyze` reads the same authored source to find orphaned pages and stale generated artifacts.
948
+ - **The `## Contents` section is the machine-readable local map.** For Fumadocs, `oat docs nav sync` reads it to write the committed `meta.json` sidebar files, and agents compare it against the generated app-root manifest. For MkDocs, `oat docs nav sync` reads it to update `mkdocs.yml` `nav:`. `oat-docs-analyze` reads the same authored source to find orphaned pages and stale generated artifacts.
948
949
  - **Anything not listed in `## Contents` is invisible to the tooling.** Adding a Markdown file is not enough — it must also appear under the parent `index.md`'s `## Contents`.
949
950
 
950
951
  Show the user their own `docs/index.md` `## Contents` as a concrete example (read the file and paste the relevant 5–15 lines). If `patchesApplied` includes an `FP-16` entry with `status: 'applied'`, mention it — the skill rewrote the scaffold's extension-less links to `.md`-suffixed form so agents can follow them. Then note: "That's the pattern. Every directory you create from now on follows the same shape — `.md`-suffixed links, bulleted list, dash-separated summary per entry."
@@ -12,13 +12,13 @@ This file tells agents how to work inside `{{APP_DIR}}`, the documentation app f
12
12
  2. Add frontmatter with at minimum `title:` and `description:`. The title drives nav display and page `<title>`; the description drives search previews, social cards, and sibling summaries. Empty descriptions hurt all three.
13
13
  3. Update the nearest `index.md`'s `## Contents` section to include a link to the new page. Use `.md`-suffixed relative links: `[Title](page.md)` for leaf pages, `[Section](subdir/index.md)` for subdirectories. The `@open-agent-toolkit/docs-transforms` remark-links plugin normalizes these for Fumadocs routing at build time (strips `.md`, collapses `dir/index.md` → `dir`), so the suffixed form renders correctly **and** lets agents follow links to the target file without path inference. The `## Contents` section is the machine-readable local map — anything not listed there is effectively invisible to the navigation tooling.
14
14
  4. If the new page introduces a new subdirectory, create an `index.md` in that subdirectory with its own `## Contents` section. Every content directory must have an `index.md`.
15
- 5. Regenerate the derived navigation artifact for this framework. For Fumadocs, run the generated-index command (`{{GENERATE_INDEX_CMD}}`) so the app-root `index.md` manifest reflects the current Markdown file tree. For MkDocs, run `oat docs nav sync` or the local equivalent so `mkdocs.yml` `nav:` reflects authored `## Contents`. Derived artifacts never replace the authored `## Contents`; keep authored maps current and compare generated output against them when checking freshness.
15
+ 5. Regenerate the derived navigation artifacts for this framework. For Fumadocs, run `oat docs nav sync` (from the app directory, or with `--target-dir <app-dir>`) so the committed `docs/**/meta.json` sidebar files follow authored `## Contents`, and run the generated-index command (`{{GENERATE_INDEX_CMD}}`) so the app-root `index.md` manifest reflects the current Markdown file tree. Fumadocs nav sync is strict: a page no `## Contents` map lists stays out of the sidebar and is reported, so list the new page rather than editing `meta.json`. For MkDocs, run `oat docs nav sync` or the local equivalent so `mkdocs.yml` `nav:` reflects authored `## Contents`. Derived artifacts never replace the authored `## Contents`; keep authored maps current and compare generated output against them when checking freshness.
16
16
 
17
17
  ## When you need to restructure navigation
18
18
 
19
19
  1. Make changes in the authored `## Contents` sections of each affected `index.md`. That is the authoritative local map.
20
- 2. Do **not** hand-edit generated navigation artifacts. The Fumadocs app-root `index.md` manifest, `mkdocs.yml` `nav:` (for MkDocs), and any other derived nav file is rewritten by the local generation workflow.
21
- 3. After editing `## Contents`, run the framework's generation command to refresh derived artifacts.
20
+ 2. Do **not** hand-edit generated navigation artifacts. The Fumadocs app-root `index.md` manifest, Fumadocs `meta.json` files, `mkdocs.yml` `nav:` (for MkDocs), and any other derived nav file is rewritten by the local generation workflow.
21
+ 3. After editing `## Contents`, run `oat docs nav sync` and the framework's generation command to refresh derived artifacts.
22
22
  4. If you're moving pages between directories, update both source and destination `index.md` `## Contents` entries in the same commit so the site isn't broken mid-way through history.
23
23
  5. If you're reparenting an entire subtree, consider whether the moved directory's own `index.md` needs a revised "scope" paragraph.
24
24