@open-agent-toolkit/cli 0.3.31 → 0.3.33

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 (58) hide show
  1. package/assets/bundle-metadata.json +1 -1
  2. package/assets/docs/docs-tooling/check.md +54 -30
  3. package/assets/docs/docs-tooling/commands.md +21 -2
  4. package/assets/docs/docs-tooling/workflows.md +14 -6
  5. package/assets/docs/reference/cli-reference.md +2 -2
  6. package/assets/docs/reference/config-and-local-state.md +1 -1
  7. package/assets/docs/reference/configuration.md +2 -2
  8. package/assets/docs/reference/docs-index-contract.md +3 -2
  9. package/assets/docs/reference/oat-directory-structure.md +1 -1
  10. package/assets/public-package-versions.json +4 -4
  11. package/assets/skills/oat-agent-instructions-analyze/SKILL.md +2 -2
  12. package/assets/skills/oat-docs-analyze/SKILL.md +63 -25
  13. package/assets/skills/oat-docs-analyze/references/analysis-artifact-template.md +9 -6
  14. package/assets/skills/oat-docs-analyze/references/quality-checklist.md +2 -2
  15. package/assets/skills/oat-docs-analyze/scripts/package-drift.mjs +358 -40
  16. package/assets/skills/oat-docs-apply/SKILL.md +22 -12
  17. package/assets/skills/oat-docs-apply/references/apply-plan-template.md +3 -2
  18. package/dist/commands/config/index.d.ts.map +1 -1
  19. package/dist/commands/config/index.js +47 -9
  20. package/dist/commands/docs/check/check.d.ts.map +1 -1
  21. package/dist/commands/docs/check/check.js +1 -0
  22. package/dist/commands/docs/check/checker.d.ts +2 -0
  23. package/dist/commands/docs/check/checker.d.ts.map +1 -1
  24. package/dist/commands/docs/check/checker.js +2 -0
  25. package/dist/commands/docs/check/commands.d.ts.map +1 -1
  26. package/dist/commands/docs/check/commands.js +74 -30
  27. package/dist/commands/docs/check/files.d.ts +2 -0
  28. package/dist/commands/docs/check/files.d.ts.map +1 -1
  29. package/dist/commands/docs/check/files.js +16 -0
  30. package/dist/commands/docs/check/navigation.d.ts +7 -1
  31. package/dist/commands/docs/check/navigation.d.ts.map +1 -1
  32. package/dist/commands/docs/check/navigation.js +19 -68
  33. package/dist/commands/docs/check/reader-rules.d.ts.map +1 -1
  34. package/dist/commands/docs/check/reader-rules.js +8 -3
  35. package/dist/commands/docs/index-generate/generator.d.ts +9 -1
  36. package/dist/commands/docs/index-generate/generator.d.ts.map +1 -1
  37. package/dist/commands/docs/index-generate/generator.js +17 -6
  38. package/dist/commands/docs/index-generate/index.d.ts +1 -1
  39. package/dist/commands/docs/index-generate/index.d.ts.map +1 -1
  40. package/dist/commands/docs/index-generate/index.js +24 -12
  41. package/dist/commands/docs/init/content.d.ts +2 -3
  42. package/dist/commands/docs/init/content.d.ts.map +1 -1
  43. package/dist/commands/docs/init/content.js +3 -10
  44. package/dist/commands/docs/nav/fumadocs.d.ts +29 -0
  45. package/dist/commands/docs/nav/fumadocs.d.ts.map +1 -1
  46. package/dist/commands/docs/nav/fumadocs.js +8 -5
  47. package/dist/commands/docs/nav/membership.d.ts +37 -0
  48. package/dist/commands/docs/nav/membership.d.ts.map +1 -0
  49. package/dist/commands/docs/nav/membership.js +475 -0
  50. package/dist/commands/docs/nav/sync.d.ts +26 -2
  51. package/dist/commands/docs/nav/sync.d.ts.map +1 -1
  52. package/dist/commands/docs/nav/sync.js +160 -43
  53. package/dist/config/documentation-ia.d.ts +19 -0
  54. package/dist/config/documentation-ia.d.ts.map +1 -0
  55. package/dist/config/documentation-ia.js +42 -0
  56. package/dist/config/oat-config.d.ts.map +1 -1
  57. package/dist/config/oat-config.js +5 -1
  58. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
- "oatVersion": "0.3.31"
3
+ "oatVersion": "0.3.33"
4
4
  }
@@ -17,7 +17,13 @@ oat docs check --rule description h1 --rule links --json
17
17
 
18
18
  Omitted targets use `documentation.root`, then the existing `docs` fallback.
19
19
  Framework app roots resolve to their content directory. A literal Markdown root
20
- stays literal even with a child named `docs`. Paths in findings are deterministic,
20
+ stays literal even with a child named `docs`. The checker never reads
21
+ `node_modules` or hidden directories such as `.git` and `.oat`. An explicit
22
+ target other than the configured root is checked without the configured policy;
23
+ the text output prints a notice that says so and names the mode. Targeting a
24
+ configured framework app's `docs/` content directory checks it as Markdown and
25
+ skips navigation, so the notice suggests the app root instead. Notices never
26
+ appear in `--json` output. Paths in findings are deterministic,
21
27
  content-root-relative POSIX paths; physical line locations are included when
22
28
  available, including nested supported tabs. No sidebar or default manifest is
23
29
  required for Markdown.
@@ -47,9 +53,23 @@ Fix the authored page, its local Contents map and inbound links together. For
47
53
  owned generated navigation, run `oat docs nav sync`, then rerun the checker.
48
54
  Hand-authored or undeclared navigation is compared for membership/order without
49
55
  requiring generated display labels, title fields or YAML formatting; do not
50
- silently regenerate it. Missing optional Fumadocs metadata, metadata objects without
51
- `pages`, and absent MkDocs `nav` skip comparison. Present `pages` must be an array;
52
- explicit entries still compare membership/order. Implicit Fumadocs order is not
56
+ silently regenerate it. A page listed in Contents must be reachable from some
57
+ sidebar entry: its own folder's `pages`, a rest entry, a borrow from another
58
+ folder such as `"../install"`, a root-relative link item to its URL, or the
59
+ folder's `pagesIndex` (a page path, or a link to the folder's own URL). The
60
+ docs root never shows its own index in the sidebar, so a root `pagesIndex` does
61
+ not count; list `index` or link to `/`. Folders with `root` set get no implicit
62
+ index either. Only
63
+ folders the sidebar attaches from the docs root count: a link to a folder's URL
64
+ reaches its landing page, not its other pages. A `"...name"` extraction inlines a folder's
65
+ index and pages and never names a page. Every
66
+ `pages` or `nav` entry must name an existing page or folder, and listed pages keep
67
+ their Contents order. Separators and their labels, MkDocs section labels and
68
+ nesting, link items, rest entries and borrowed pages are presentation and are
69
+ not compared. Messages name the mismatch: a missing reader page or folder, a
70
+ missing target, or an order difference with both orders. Missing optional
71
+ Fumadocs metadata, metadata objects without `pages`, and absent MkDocs `nav`
72
+ skip comparison. Present `pages` must be an array of strings. Implicit Fumadocs order is not
53
73
  compared. Nav-sync ownership retains its existing strict read-only freshness check. Generated inventories are separate: regenerate configured output
54
74
  and check its Git diff after the build. A build that rewrites the inventory does
55
75
  not prove the committed copy was fresh.
@@ -69,30 +89,30 @@ fenced examples do not become headings, links, groups or diagrams. YAML
69
89
  frontmatter, GFM/reference links, explicit heading IDs, static HTML and supported
70
90
  recursive tabs participate.
71
91
 
72
- | Rule ID | Default behavior |
73
- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
74
- | `directory-index` | Error for a reader-bearing directory without `index.md` and a nonempty dash-bullet Contents map, invalid map grammar or unresolved strict Contents target. Ancestors of reader pages participate. |
75
- | `root-width` | Flat root Contents links warn above `rootWarn: 10`, error above `rootError: 14`. Real groups exempt the width. |
76
- | `contents-width` | Ungrouped Contents links warn above `contentsWarn: 10`, error above `contentsError: 15`. `catalog: true` or the recognized OAT generated-index marker exempts only this width rule. |
77
- | `leaf-size` | Direct reader pages include index. A leaf has no reader-bearing child directory: index-only errors; two total pages warn. |
78
- | `folder-size` | Direct reader pages including index warn above `folderWarn: 12`, error above `folderError: 20`, unless the index has real groups. |
79
- | `depth` | Content root is depth 0; warn at `depthWarn: 4`, error at `depthError: 5`. |
80
- | `page-length` | Warn above `pageLines: 500` physical source lines. Explicit `type: reference` or `reference`/`references` path segments use `referenceLines: 1000` and warn above `referenceH3: 40` real H3 headings. No default length error limit. |
81
- | `frontmatter` | Unreadable source, invalid YAML or a non-mapping frontmatter document errors. Read failures use relative paths and safe error codes; invalid metadata skips description validation while independent body checks continue at physical positions. |
82
- | `description` | Missing/empty frontmatter description errors; character lengths below `descriptionMin: 40` or above `descriptionMax: 160` warn. |
83
- | `h1` | Error unless each page has exactly one real H1. |
84
- | `links` | Error for unresolved in-root source links/anchors. No network checking. Ordinary escaping links are provenance warnings and their targets are not read. Contents links retain stricter local-map rules. |
85
- | `contents-description` | Error for descriptions ending in an ellipsis/truncation. |
86
- | `overview` | Warn below `overviewWords: 10` before Contents. |
87
- | `contents-separator` | Warn when Contents descriptions mix separators in a tree. |
88
- | `navigation` | Error for explicit navigation drift using declared ownership semantics; hand-authored/undeclared absent optional meta/pages/nav skips comparison. Nav-sync freshness stays strict; Markdown skips it. |
89
- | `commands` | Error for missing literal contributor scripts; implicit pnpm shorthand also accepts installed package/workspace `.bin` entries. Explicit pnpm run/npm run stays script-only; unresolved context errors; echo scripts warn. |
90
- | `mermaid` | Parse every real Mermaid fence using the pinned Mermaid parser. Invalid syntax errors. |
91
- | `diagram-pairs` | Diagram light/dark SVG siblings and both page references are required. Conventional diagram paths and explicit paired references participate; ordinary logos are not diagrams. |
92
- | `diagram-accessibility` | Mermaid missing `accTitle`/`accDescr` warns. SVGs require `role="img"`, nonempty title/desc. Rendered diagrams without page-visible explanatory text or an associated long description warn. |
93
- | `diagram-freshness` | Warn when changed Mermaid lacks both associated SVG changes; association follows the actual section/tab group. Missing usable Git comparison is explicitly unverified. |
94
- | `image-alt` | Warn for empty, filename/slug-like or longer than `altMax: 155` image alt text. |
95
- | `provenance` | Warn for planning/backlog/home paths, configured ticket/milestone patterns and ordinary links escaping the root. Legitimate reader docs remain visible. |
92
+ | Rule ID | Default behavior |
93
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
94
+ | `directory-index` | Error for a reader-bearing directory without `index.md` and a nonempty dash-bullet Contents map, invalid map grammar or unresolved strict Contents target. Ancestors of reader pages participate. |
95
+ | `root-width` | Flat root Contents links warn above `rootWarn: 10`, error above `rootError: 14`. Real groups exempt the width. |
96
+ | `contents-width` | Ungrouped Contents links warn above `contentsWarn: 10`, error above `contentsError: 15`. `catalog: true` or the recognized OAT generated-index marker exempts only this width rule. |
97
+ | `leaf-size` | Direct reader pages include index. A leaf has no reader-bearing child directory: index-only errors; two total pages warn. |
98
+ | `folder-size` | Direct reader pages including index warn above `folderWarn: 12`, error above `folderError: 20`, unless the index has real groups. |
99
+ | `depth` | Content root is depth 0; warn at `depthWarn: 4`, error at `depthError: 5`. |
100
+ | `page-length` | Warn above `pageLines: 500` physical source lines. Explicit `type: reference` or `reference`/`references` path segments use `referenceLines: 1000` and warn above `referenceH3: 40` real H3 headings. No default length error limit. `line` is the first physical line past the line limit, or the first H3 past the heading limit. |
101
+ | `frontmatter` | Unreadable source, invalid YAML or a non-mapping frontmatter document errors. Read failures use relative paths and safe error codes; invalid metadata skips description validation while independent body checks continue at physical positions. |
102
+ | `description` | Missing/empty frontmatter description errors; character lengths below `descriptionMin: 40` or above `descriptionMax: 160` warn. |
103
+ | `h1` | Error unless each page has exactly one real H1. |
104
+ | `links` | Error for unresolved in-root source links/anchors. No network checking. Ordinary escaping links are provenance warnings and their targets are not read. Contents links retain stricter local-map rules. |
105
+ | `contents-description` | Error for descriptions ending in an ellipsis/truncation. |
106
+ | `overview` | Warn below `overviewWords: 10` before Contents. |
107
+ | `contents-separator` | Warn when Contents descriptions mix separators in a tree. |
108
+ | `navigation` | Error for explicit navigation drift. Nav-sync freshness stays strict; hand-authored/undeclared compare membership and order only (separators, labels, links and borrows are not compared), and absent optional meta/pages/nav skips comparison. Markdown skips it. |
109
+ | `commands` | Error for missing literal contributor scripts; framework app targets try the app package first, then the repository root. Implicit pnpm shorthand also accepts installed package/workspace `.bin` entries. Explicit pnpm run/npm run stays script-only; unresolved context errors; echo scripts warn. |
110
+ | `mermaid` | Parse every real Mermaid fence using the pinned Mermaid parser. Invalid syntax errors. |
111
+ | `diagram-pairs` | Diagram light/dark SVG siblings and both page references are required. Conventional diagram paths and explicit paired references participate; ordinary logos are not diagrams. |
112
+ | `diagram-accessibility` | Mermaid missing `accTitle`/`accDescr` warns. SVGs require `role="img"`, nonempty title/desc. Rendered diagrams without page-visible explanatory text or an associated long description warn. |
113
+ | `diagram-freshness` | Warn when changed Mermaid lacks both associated SVG changes; association follows the actual section/tab group. Missing usable Git comparison is explicitly unverified. |
114
+ | `image-alt` | Warn for empty, filename/slug-like or longer than `altMax: 155` image alt text. |
115
+ | `provenance` | Warn for planning/backlog/home paths, configured ticket/milestone patterns and ordinary links escaping the root. Legitimate reader docs remain visible. |
96
116
 
97
117
  These are lint limits, distinct from authoring targets for concise pages and
98
118
  focused maps. `documentation.nonReaderPaths` uses the existing
@@ -103,8 +123,12 @@ focused maps. `documentation.nonReaderPaths` uses the existing
103
123
 
104
124
  Literal pnpm script and npm run examples in `contributing.md`/`.mdx` and
105
125
  `contributing/**` are checked against package manifests. Each code block starts
106
- at the repository root. Use executable `cd`, `-w`/`--workspace-root`, `--dir` or
107
- literal `--filter` selection to establish another context. Prose such as “from
126
+ at the repository root. For a framework app target with its own `package.json`,
127
+ it also starts at the app root, which is tried first: a script defined by the app
128
+ resolves there, a script only the repository root defines still resolves, and a
129
+ missing script names both manifests. Markdown targets use the repository root
130
+ only. Use executable `cd`, `-w`/`--workspace-root`, `--dir` or literal `--filter`
131
+ selection to establish another context. Prose such as “from
108
132
  the app directory” alone does not change it. Built-in package-manager commands
109
133
  and illustrative placeholders are recognized; commands are never run.
110
134
 
@@ -226,6 +226,7 @@ Key behavior:
226
226
  - refuses a symlink chain that exceeds its own 32-hop cap, naming the path you supplied or the CLI derived rather than an intermediate link, and addressing the flag that owns it: an unusable **output** chain names `--output` and exits `1`; an unusable **docs directory** chain names `--docs-dir` and, when the directory was derived from `documentation.root` rather than passed explicitly, also names the `oat config set documentation.root <path>` repair and exits `2` as unusable path configuration. That cap governs the dangling links the command walks itself; a chain the operating system refuses first surfaces as its own `ELOOP` error with exit `1`, which is what a too-deep chain reports on a platform whose own limit is 32 or lower
227
227
  - writes configuration only for the Fumadocs manifest transition — recording the manifest it just wrote inside `documentation.root` in `documentation.index`, when `documentation.tooling` is `fumadocs` or the config declares neither `tooling` nor `config`. Markdown and MkDocs configurations are never written, and `documentation.root` and `documentation.config` are never modified
228
228
  - prepends an `AUTOGENERATED` warning comment to the output and rewrites the file on every run; do not hand-edit the generated `index.md`
229
+ - writes each link relative to the output file, so links resolve from where the manifest sits: a Fumadocs app-root `index.md` links `docs/guide.md` and `docs/index.md`, never itself. Whitespace, `#`, `?`, `%`, `&`, backslashes, parentheses and angle brackets in link paths are percent-encoded (UTF-8). Starting in 0.3.32; earlier manifests used docs-directory-relative links
229
230
  - should be freshness-checked against authored `docs/**/index.md` `## Contents` maps before treating it as navigation evidence
230
231
  - ordering: authored local Contents orders surviving direct entries in the hierarchical inventory; cross-directory links order the containing entry without duplicates. Child directory titles use index frontmatter, then H1, then slug. Remaining entries use index/directories/files/lexical fallback and are flagged `[unlisted in Contents]` when Contents exists. Missing Contents keeps fallback; malformed present Contents is an error
231
232
  - reports the derived docs directory in human output and as `docsDir` / `docsDirSource` under `--json`, alongside `excludes` — the effective exclusion list, `documentation.excludes`, applicable `documentation.nonReaderPaths`, then the `--exclude` flags, exactly as handed to the generator
@@ -296,10 +297,28 @@ site nav generation. Framework apps generate navigation as follows:
296
297
  generated `meta.json` files.
297
298
 
298
299
  Use `--check` in builds and CI. It computes the same navigation, writes
299
- nothing, and exits 1 when any generated file would change or, for Fumadocs,
300
- any page or folder is unlisted, naming each one (`stale` and `unlisted` in
300
+ nothing, and exits 1 when any generated file is missing or would change or, for
301
+ Fumadocs, any page or folder is unlisted. It names each one and separates
302
+ missing files from differing ones (`stale`, `missing` and `unlisted` in
301
303
  `--json`). Fresh Fumadocs `prebuild` and MkDocs `docs:build` scripts run it with explicit app selection, preserving external `oat` versus source-workspace CLI commands and quoting paths with spaces. This repository's `apps/oat-docs` `prebuild` also runs it, so `pnpm build:docs` fails on stale navigation.
302
304
 
305
+ Without `--target-dir`, the command uses the configured `documentation.root`,
306
+ like `oat docs check`, and falls back to the current directory only when no root
307
+ is configured. With `documentation.tooling: markdown` it exits 1 and says nav
308
+ sync does not apply: Markdown Contents maps are the navigation, so validate
309
+ them with `oat docs check`.
310
+
311
+ The command reads `documentation.navOwner` when the target is the configured root:
312
+
313
+ | Owner | Writing run | `--check` |
314
+ | --------------- | ----------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
315
+ | `nav-sync` | Regenerates navigation. | Strict: generated files must match. |
316
+ | `hand-authored` | Refuses with exit 1 and writes nothing. Edit the navigation directly or change the owner. | Membership and order only, as in [`oat docs check`](check.md#results-and-repair): every Contents page reachable, no entry naming a missing page, listed pages in Contents order. |
317
+ | undeclared | Regenerates navigation and warns you to declare an owner. | Strict, with the same warning. |
318
+
319
+ Fresh `oat docs init` framework scaffolds declare `nav-sync` and run their first
320
+ sync directly, so they are unaffected.
321
+
303
322
  Shared `documentation.nonReaderPaths` uses the exclusion grammar above, relative to the configured content root. Navigation inventory, explicit Contents links, `--check` and manifests omit matches; excluded metadata is never cleaned or rewritten. An unrelated explicit target does not inherit the setting. `documentation.excludes` stays manifest-only. OAT Fumadocs source collections omit non-readers from rendering too; pinned MkDocs 1.4.2 omits them from nav/manifest but still renders their routes (no rendering-exclusion support).
304
323
 
305
324
  Fumadocs apps also regenerate the root markdown manifest with
@@ -495,7 +495,7 @@ work.
495
495
  ## Approval, IA records and restructuring
496
496
 
497
497
  Every analyze recommendation has a stable ID and `approval: explicit | default`.
498
- `apply all` covers only non-blocked default content repairs. Docs-package updates,
498
+ `apply all` covers only non-blocked default content repairs. Docs tooling updates,
499
499
  restructure blocks and work outside Markdown scope require individual approval
500
500
  by ID; unattended runs skip explicit items even when their IDs were supplied,
501
501
  with reason `explicit_requires_interactive_approval`. Kickoff consent is not
@@ -538,18 +538,26 @@ canonical-source judgment; not-found is initially unverified. It cannot prove
538
538
  runtime behavior, registry membership or scenario correctness. Accepted IA,
539
539
  source citations and existing recommendation approval classes still govern.
540
540
 
541
- For framework apps, offline drift compares installed `@open-agent-toolkit/docs-*` packages to the
541
+ For framework apps, offline drift compares installed `@open-agent-toolkit/docs-*` packages, and
542
+ the app's own `@open-agent-toolkit/cli` when the app declares it, to the
542
543
  running CLI's bundled `public-package-versions.json`, never registry latest.
544
+ The app-local CLI matters because its `oat docs generate-index` runs in
545
+ `predev`/`prebuild`: a stale local CLI writes a different manifest than yours, so
546
+ its drift joins the docs-package drift in the same tooling update.
543
547
  Older installed packages produce an explicit drift recommendation with the
544
548
  exact upgrade command. Equal versions are current. Newer packages are `ahead`: select
545
549
  or update the intended CLI installation before re-analysis, without a package
546
550
  downgrade command. Missing installations or bundle metadata and non-orderable
547
551
  versions are `unverified` and require manual verification; hoisted-only packages
548
552
  also remain unverified. Neither ahead nor unverified supplies a package-update
549
- command or authorizes an upgrade. Individual tooling approval permits only docs-app `@open-agent-toolkit/docs-*`
550
- dependency bumps (and resulting lockfile), the admonition/frontmatter conversions
551
- already supported by `oat docs migrate`, and build verification. App config,
552
- routes and package scripts remain manual required changes.
553
+ command or authorizes an upgrade. Individual tooling approval permits only
554
+ docs-app `@open-agent-toolkit/docs-*` dependency bumps, a bump of the app's own
555
+ `@open-agent-toolkit/cli` in the dependency section it already uses (with the
556
+ resulting lockfile), regenerating the app's generated manifest with that upgraded
557
+ CLI, the admonition/frontmatter conversions already supported by
558
+ `oat docs migrate`, and build verification. Other application dependencies,
559
+ framework upgrades, app config, routes and package scripts remain manual
560
+ required changes.
553
561
 
554
562
  ## Related docs
555
563
 
@@ -237,7 +237,7 @@ Notable commands introduced in the current CLI surface:
237
237
  - `--local` — write to or remove from `.oat/config.local.json` (per-developer repo state, gitignored)
238
238
  - `--user` — write to or remove from `~/.oat/config.json` (user-level fallback, applies across all repos)
239
239
 
240
- When no flag is passed, the CLI picks a sensible default per key type: structural keys (`projects.root`, `documentation.*`, etc.) go to shared, state keys (`activeProject`, etc.) go to local, workflow preferences (`workflow.*`) go to local. Pass at most one flag — the command rejects multiple surface flags. `documentation.guidance` is shared by default and also accepts `--user`; use a path/URL string or a JSON string array, not a comma-separated list. `documentation.ia` accepts the [recorded IA JSON shape](configuration.md#shared-repo-config-you-will-touch-most-often) and `documentation.navOwner` accepts `nav-sync` or `hand-authored`; both are shared-only. Unset owner means undeclared, and Markdown ignores it. IA is an atomic value in get/dump, not a set of separately configurable child keys. `documentation.nonReaderPaths` is also shared-only and uses a comma-separated glob list on `set`, stored as an array; empty clears it. It omits matching reader paths from nav/check/manifest and supported Fumadocs collections, while `documentation.excludes` remains manifest-only. See [non-reader configuration](configuration.md#shared-repo-config-you-will-touch-most-often).
240
+ When no flag is passed, the CLI picks a sensible default per key type: structural keys (`projects.root`, `documentation.*`, etc.) go to shared, state keys (`activeProject`, etc.) go to local, workflow preferences (`workflow.*`) go to local. Pass at most one flag — the command rejects multiple surface flags. `documentation.guidance` is shared by default and also accepts `--user`; use a path/URL string or a JSON string array, not a comma-separated list. `documentation.ia` accepts the [recorded IA JSON shape](configuration.md#shared-repo-config-you-will-touch-most-often) and `documentation.navOwner` accepts `nav-sync` or `hand-authored`; both are shared-only. Unset owner means undeclared, and Markdown ignores it. IA is an atomic value in get/dump, not a set of separately configurable child keys. `documentation.nonReaderPaths` is also shared-only and takes a comma-separated glob list or a JSON string array on `set` (other input starting with `[` or `{` is rejected), stored as an array; empty clears it. `documentation.excludes` accepts the same two forms. It omits matching reader paths from nav/check/manifest and supported Fumadocs collections, while `documentation.excludes` remains manifest-only. See [non-reader configuration](configuration.md#shared-repo-config-you-will-touch-most-often).
241
241
 
242
242
  Per-key restrictions apply identically to `set` and `unset`: structural keys can only be written at shared scope, most state keys can only be written at local scope (`activeIdea` is the exception — it accepts both local and user), and workflow preference keys accept any non-auto surface. Legacy `autoReviewAtCheckpoints` remains shared-only; prefer `workflow.autoReviewAtHillCheckpoints`.
243
243
 
@@ -247,7 +247,7 @@ Remote settings under `pjm.remote.*` remain shared-only. Removing a mutable leaf
247
247
 
248
248
  `unset` refuses six classes of key, each with exit code 1:
249
249
 
250
- - **Unknown keys**, including keys OAT reads but does not expose in the `oat config` catalog (`documentation.index`). These are not removable by any `oat config` command.
250
+ - **Unknown keys**, meaning keys outside the `oat config` catalog. These are not removable by any `oat config` command.
251
251
  - **Lifecycle state** (`activeProject`, `lastPausedProject`) — cleared with `oat config set <key> ''` instead.
252
252
  - **Pack intent** (`tools.*`) — removed with `oat tools remove --pack <pack> --scope project`, which also removes the installed pack files. Clearing the intent alone would leave them behind.
253
253
  - **Aggregate read views** (`workflow.dispatchCeiling`, `workflow.dispatchCeiling.providers`) — these are assembled for `get` from the leaf keys and are not stored as such. Unset `workflow.dispatchCeiling.preset` or `workflow.dispatchCeiling.providers.<provider>` instead.
@@ -131,7 +131,7 @@ Use `oat config` for repo runtime config inspection and supported key mutation.
131
131
 
132
132
  - `oat config get <key>` - read one resolved config value
133
133
  - `oat config set <key> <value>` - update a supported shared, repo-local, or user key according to per-key restrictions
134
- - `oat config unset <key>` - remove a supported key from one surface, with the same `--shared`/`--local`/`--user` flags and per-key restrictions as `set`. Pruning removes any parent object the removal empties, and the resolved value falls back to the next surface or the built-in default. A key the surface does not hold reports an already-unset outcome and exits 0; `--json` adds a `removed` boolean that distinguishes that no-op from a real removal. Five classes are refused with exit 1: unknown keys (including the uncatalogued `documentation.index`), lifecycle state (`activeProject`, `lastPausedProject`, cleared with `oat config set <key> ''`), pack intent (`tools.*`, removed with `oat tools remove --pack <pack> --scope project`), the aggregate read views `workflow.dispatchCeiling` and `workflow.dispatchCeiling.providers`, and environment-shadowed keys with nothing stored on the target surface. See [CLI Reference](cli-reference.md#oat-config-surface-flags) for the full contract
134
+ - `oat config unset <key>` - remove a supported key from one surface, with the same `--shared`/`--local`/`--user` flags and per-key restrictions as `set`. Pruning removes any parent object the removal empties, and the resolved value falls back to the next surface or the built-in default. A key the surface does not hold reports an already-unset outcome and exits 0; `--json` adds a `removed` boolean that distinguishes that no-op from a real removal. Five classes are refused with exit 1: unknown keys, lifecycle state (`activeProject`, `lastPausedProject`, cleared with `oat config set <key> ''`), pack intent (`tools.*`, removed with `oat tools remove --pack <pack> --scope project`), the aggregate read views `workflow.dispatchCeiling` and `workflow.dispatchCeiling.providers`, and environment-shadowed keys with nothing stored on the target surface. See [CLI Reference](cli-reference.md#oat-config-surface-flags) for the full contract
135
135
  - `oat config list` - show the resolved command-surface values with source information
136
136
  - `oat config dump --json` - emit the full merged config payload with per-key source attribution, suitable for automation and debugging
137
137
  - `oat config describe` - list supported config surfaces and keys across shared repo, repo-local, user, and sync/provider config
@@ -94,10 +94,10 @@ Common keys in `.oat/config.json`:
94
94
  - `worktrees.root` — where OAT-managed worktrees live
95
95
  - `git.defaultBranch` — base branch fallback for PR workflows
96
96
  - `documentation.root`, `documentation.tooling`, `documentation.config` — docs-surface ownership. With tooling `markdown`, root is the literal content directory (including nested `docs`) and `documentation.index` is authored `<root>/index.md`; Markdown adds no framework config. Framework roots retain app/source semantics. Use `oat docs init --framework markdown` or explicit `--adopt` for setup; optional manifests need external output and never change the authored index. See [Documentation path resolution](oat-directory-structure.md#documentation-path-resolution)
97
- - `documentation.ia` — shared repository-only mirror of the accepted authored IA. Set JSON with required `preset` and repo-relative `decision`, optional `tracks: [{path, principle}]`, and optional `verification: "triad" | "agent-only" | "none"`. The decision record plus Information architecture section in framework docs-app `AGENTS.md` or Markdown contributing page remain authoritative. Use `oat config set documentation.ia '{"preset":"Flat Small","decision":".oat/repo/reference/decisions/DR-example.md","verification":"none"}'`; unset removes the mirror only. Invalid shapes/paths are rejected; neither `--user` nor `--local` is supported.
97
+ - `documentation.ia` — shared repository-only mirror of the accepted authored IA. Set JSON with required `preset` (one of the `oat docs init --ia-preset` IDs: `product-engineering-qa`, `consumer-maintainer`, `domain-engineering`, `task-type`, `toolkit-cli` or `flat-small`; the matching approved label, such as `Flat Small`, is accepted as an exact alias) and repo-relative `decision`, optional `tracks: [{path, principle}]`, and optional `verification: "triad" | "agent-only" | "none"`. The decision record plus Information architecture section in framework docs-app `AGENTS.md` or Markdown contributing page remain authoritative. Use `oat config set documentation.ia '{"preset":"flat-small","decision":".oat/repo/reference/decisions/DR-example.md","verification":"none"}'`; unset removes the mirror only. Invalid shapes, unknown presets and absolute, URL or `..` paths are rejected, both when set and when stored config is read: from 0.3.32 a stored unknown preset makes config-reading commands fail until repaired with `oat config set documentation.ia '<JSON>'` or `oat config unset documentation.ia --shared`; the CLI does not check that the decision file exists, and analyze reports a missing record as `ask_user`; neither `--user` nor `--local` is supported.
98
98
  - `documentation.navOwner` — shared `nav-sync | hand-authored`, independent of recorded IA, for Fumadocs/MkDocs only. Set with `oat config set documentation.navOwner hand-authored`. Absent is undeclared (`get --json` reports null/default), never implied nav-sync; analyze asks the operator and no automatic regeneration is authorized. Markdown ignores this field. Fresh Fumadocs/MkDocs init explicitly seeds nav-sync and generates navigation after scaffold/config succeeds. Existing apps are not regenerated through bootstrap; explicit nav-sync commands retain their behavior.
99
99
  - `documentation.guidance` — advisory Markdown IA source paths/URLs, as a string or ordered non-empty string array. Repo config overrides user config; explicit skill input overrides both. Absent values use the installed `authoring-docs` IA reference. Use `oat config set documentation.guidance ./docs/ia/index.md` or `oat config set documentation.guidance '["~/guidance/index.md","https://example.com/docs/index.md"]' --user`. Arrays retain order; commas in paths are literal. `--local` is unsupported. `get --json` reports `shared`, `user`, or `default` provenance; `unset` reveals the next tier. Only locators are stored, with unrelated config fields preserved. Sources stay read-only, external packs have `index.md` and `## Contents`, and local AGENTS/contributing rules remain authoritative. Conflicts become `ask_user`. See [IA selection](../docs-tooling/workflows.md#ia-selection-and-guidance).
100
- - `documentation.nonReaderPaths` — shared repository-only array of content-root-relative globs for drafts/templates. Set with `oat config set documentation.nonReaderPaths 'templates/,drafts/**'`; empty value clears and `unset` removes it. Entries are trimmed/de-duplicated; non-arrays, empty or non-string entries are rejected. Local/user writes are refused. The [bounded grammar](../docs-tooling/commands.md#exclusion-patterns) matches nav inventory, explicit Contents targets, nav checks and manifests only for the configured app/content root; excluded metadata is not rewritten. Fumadocs source collections also exclude rendering when wired through OAT source config. Pinned MkDocs 1.4.2 still renders excluded pages as routes; only nav/manifest exclusion is supported.
100
+ - `documentation.nonReaderPaths` — shared repository-only array of content-root-relative globs for drafts/templates. Set with `oat config set documentation.nonReaderPaths 'templates/,drafts/**'` or a JSON string array such as `'["**/AGENTS.md"]'`; other JSON-looking input is rejected; empty value clears and `unset` removes it. Entries are trimmed/de-duplicated; non-arrays, empty or non-string entries are rejected. Local/user writes are refused. The [bounded grammar](../docs-tooling/commands.md#exclusion-patterns) matches nav inventory, explicit Contents targets, nav checks and manifests only for the configured app/content root; excluded metadata is not rewritten. Fumadocs source collections also exclude rendering when wired through OAT source config. Pinned MkDocs 1.4.2 still renders excluded pages as routes; only nav/manifest exclusion is supported.
101
101
  - `documentation.excludes` — a JSON array of globs, relative to the docs directory, that `oat docs generate-index` leaves out of the generated index. `oat config set` takes the list as one comma-separated value (`"a/**,b.md"`) and stores it as an array; repeated `--exclude` flags extend it, and an empty value clears the key
102
102
  - `documentation.check` — shared checker policy: stable rule severities, named numeric thresholds, reason-bearing bounded path/rule exceptions, ticket/milestone regex patterns and optional diagram base ref. Set/get/dump/unset preserve and validate the object. See [Check Documentation](../docs-tooling/check.md#configure-narrow-policy) for exact fields/defaults and repair commands.
103
103
  - `documentation.requireForProjectCompletion` — whether docs sync is a completion gate
@@ -73,6 +73,7 @@ Fumadocs generated behavior:
73
73
  - The inventory stays hierarchical. Each local Contents orders its surviving direct entries; a cross-directory link orders its containing direct entry without duplicating the page. Child directory titles come from their index frontmatter title, then H1, then slug, independently of nav labels.
74
74
  - Remaining entries use deterministic index/directories/files/lexical fallback and carry `[unlisted in Contents]` when a Contents map exists. With no Contents map the inventory keeps its fallback order; malformed present Contents reports the shared grammar errors.
75
75
  - Generated manifests should carry an autogen warning and are rewritten by `predev` / `prebuild`.
76
+ - Manifest links are relative to the manifest file, so the app-root `index.md` links docs pages as `docs/<path>.md`.
76
77
 
77
78
  ## Fumadocs Nav Sync
78
79
 
@@ -89,7 +90,7 @@ Fumadocs generated behavior:
89
90
  - Existing files are compared by meaning, not bytes, so a second run with no docs changes writes nothing, even after a formatter rewrites the files.
90
91
  - `.md` and `.mdx` pages can both be listed; each appears in `pages` by its file name without the extension.
91
92
 
92
- `oat docs nav sync --check` computes the same result and writes nothing. It exits 1 when a `meta.json` file would change or a page or folder is unlisted, and names each one. In this app, `prebuild` runs it, so `pnpm build:docs` fails until the `## Contents` maps and the committed `meta.json` files agree.
93
+ `oat docs nav sync --check` computes the same result and writes nothing. It exits 1 when a `meta.json` file is missing or would change, or a page or folder is unlisted, and names each one, listing missing files separately. In this app, `prebuild` runs it, so `pnpm build:docs` fails until the `## Contents` maps and the committed `meta.json` files agree.
93
94
 
94
95
  ## MkDocs Nav Sync
95
96
 
@@ -108,7 +109,7 @@ Shared `documentation.nonReaderPaths` declares drafts/templates outside the read
108
109
 
109
110
  Fumadocs collections also omit matching pages and metadata when `defineDocs` uses OAT's `docs` and `meta` source options with an explicit repository config path. The pinned MkDocs 1.4.2 has no configurable rendering exclusion: these pages leave navigation and manifests but still render as routes. This setting is not a way to keep private content out of a MkDocs site.
110
111
 
111
- Fresh Fumadocs/MkDocs init explicitly writes `documentation.navOwner: nav-sync` and generates navigation after scaffold/config succeeds. Their generated `prebuild` / `docs:build` scripts run `nav sync --check`. Existing hand-authored or undeclared surfaces are preserved through bootstrap and use analyze/apply to choose ownership; absence never implies permission to regenerate. Markdown has no sidebar or nav sync.
112
+ Fresh Fumadocs/MkDocs init explicitly writes `documentation.navOwner: nav-sync` and generates navigation after scaffold/config succeeds. Their generated `prebuild` / `docs:build` scripts run `nav sync --check`. Existing hand-authored or undeclared surfaces are preserved through bootstrap and use analyze/apply to choose ownership; absence never implies permission to regenerate. With `hand-authored`, the writing `oat docs nav sync` refuses and `--check` compares membership and order only; an undeclared owner gets a warning to declare one. Markdown has no sidebar or nav sync.
112
113
 
113
114
  ## Generated-file boundaries
114
115
 
@@ -146,7 +146,7 @@ Current schema keys:
146
146
  | `archive.awsProfile` | `string` | - | Optional AWS named profile forwarded as `AWS_PROFILE` to every `aws` invocation in archive flows (`oat-project-complete` S3 sync, `oat repo archive sync`). Overrides ambient shell `AWS_PROFILE` / `AWS_DEFAULT_PROFILE` when set. |
147
147
  | `archive.awsRegion` | `string` | - | Optional AWS region forwarded as `AWS_REGION` to every `aws` invocation in archive flows. Overrides ambient shell `AWS_REGION` / `AWS_DEFAULT_REGION` when set. |
148
148
 
149
- Most `documentation.*` keys are managed via `oat config get/set` and are set automatically by `oat docs init`. One has no `oat config set` entry and is edited directly in `.oat/config.json`: `documentation.index`, which `oat docs init` still seeds for you.
149
+ `documentation.*` keys are managed via `oat config get/set` and are set automatically by `oat docs init`, including `documentation.index`, which `oat docs generate-index` also updates for the Fumadocs manifest transition.
150
150
  The `git.defaultBranch` key is auto-detected during `oat init` and can be overridden via `oat config set git.defaultBranch <branch>`.
151
151
  Archive settings are managed via `oat config get/set`, and `oat config describe archive.s3Uri` (or the other archive keys) shows the lifecycle and ownership details from the CLI.
152
152
  Workflow gate objects are structured config and are managed with `oat gate`, not the scalar `oat config set` surface. See [Workflow Gates](../workflows/advanced/workflow-gates.md).
@@ -1,6 +1,6 @@
1
1
  {
2
- "cli": "0.3.31",
3
- "docs-config": "0.3.31",
4
- "docs-theme": "0.3.31",
5
- "docs-transforms": "0.3.31"
2
+ "cli": "0.3.33",
3
+ "docs-config": "0.3.33",
4
+ "docs-theme": "0.3.33",
5
+ "docs-transforms": "0.3.33"
6
6
  }
@@ -5,7 +5,7 @@ disable-model-invocation: true
5
5
  user-invocable: true
6
6
  allowed-tools: Read, Write, Bash(git:*), Glob, Grep, AskUserQuestion, Task
7
7
  metadata:
8
- version: 1.12.4
8
+ version: 1.12.5
9
9
  ---
10
10
 
11
11
  # Agent Instructions Analysis
@@ -455,7 +455,7 @@ Use the `analysis` target:
455
455
  Follow the canonical loop exactly:
456
456
 
457
457
  1. Resolve `workflow.autoArtifactReview.analysis`; missing config means enabled, and only explicit `false` skips the loop.
458
- 2. Resolve `oat_orchestration_retry_limit`; default to `2` if unavailable.
458
+ 2. Resolve the retry bound from `oat_orchestration_retry_limit` in the active OAT project's `state.md` frontmatter; it is not an `oat config` key. Default to `2` when no project is active or the value is absent or invalid.
459
459
  3. Dispatch `oat-reviewer` in structured mode via Tier 1 subagent when available, falling back to the same reviewer prompt inline when needed.
460
460
  4. Apply Critical and High fixes when they are local to the analysis artifact, companion bundle, and unambiguous.
461
461
  5. Offer Medium and Low fixes rather than applying them silently.
@@ -6,7 +6,7 @@ disable-model-invocation: true
6
6
  user-invocable: true
7
7
  allowed-tools: Read, Write, Bash(git:*), Bash(oat config:*), Bash(oat docs nav sync --check:*), Bash(oat docs check:*), Bash(oat docs literals:*), Bash(pnpm:*), Bash(bash:*), Bash(jq:*), Bash(node:*), Bash(command -v:*), Bash(sed:*), Bash(npm root -g:*), Bash(test:*), Bash(oat --version), Bash(mkdir:*), Bash(date:*), Bash(echo:*), Bash(cd:*), Bash(pwd:*), Glob, Grep, AskUserQuestion, Task
8
8
  metadata:
9
- version: '1.7.5'
9
+ version: '1.9.0'
10
10
  ---
11
11
 
12
12
  # Docs Analysis
@@ -323,7 +323,9 @@ In `full` mode, evaluate the whole docs surface.
323
323
  Read the authored IA decision and `## Information architecture` section in the
324
324
  docs-app AGENTS.md (Fumadocs/MkDocs) or contributing page (Markdown).
325
325
  `documentation.ia` is a repository-only mirror: compare preset, decision path,
326
- tracks/principles and verification overlay to those authored sources. The
326
+ tracks/principles and verification overlay to those authored sources. A preset
327
+ ID and its approved label (for example `flat-small` and Flat Small) name the
328
+ same preset, not a contradiction. The
327
329
  authored record is authoritative; missing/broken records or contradictory
328
330
  mirrors become `ask_user` findings. No recorded IA means `ask_user` to choose
329
331
  and record one, not an inferred preset. Keep ordinary contract analysis useful
@@ -556,7 +558,10 @@ suppressions or automatic navigation ownership.
556
558
 
557
559
  If a generated root index or manifest exists:
558
560
 
559
- 1. Compare generated entries with the authored `## Contents` graph.
561
+ 1. Compare generated entries with the authored `## Contents` graph. Current
562
+ manifests link relative to the manifest file (an app-root manifest links
563
+ `docs/<page>.md`); links relative to the docs directory instead mean an older
564
+ CLI wrote it, so cite the CLI that regenerates it rather than content drift.
560
565
  2. Flag generated output that is missing, ignored/local-only when local guidance
561
566
  expects a tracked artifact, stale, ordered differently from authored maps, or
562
567
  unclear because generator semantics are undocumented.
@@ -594,9 +599,14 @@ For a Fumadocs app with recorded `navOwner: nav-sync`, compare generated
594
599
 
595
600
  For `hand-authored` or undeclared Fumadocs navigation, compare current meta.json
596
601
  membership/order with Contents without assuming strict generator output; do not
597
- flag rest entries merely because they are hand-authored. Report missing reader
598
- routes and differences with local ownership evidence; recommend no automatic
599
- regeneration. For nav-sync-owned MkDocs, use the same explicit-target read-only
602
+ flag rest entries merely because they are hand-authored. `oat docs check` runs
603
+ this comparison for both: a Contents page must be reachable (listed, shown by a
604
+ rest entry, borrowed by another folder or linked by URL), every pages entry must
605
+ name an existing page or folder, and listed pages keep Contents order.
606
+ Separators, labels, link items and borrowed pages are not compared. For
607
+ `hand-authored`, `oat docs nav sync --check` uses the same comparison and the
608
+ writing form refuses to run. Report missing reader routes and differences with
609
+ local ownership evidence; recommend no automatic regeneration. For nav-sync-owned MkDocs, use the same explicit-target read-only
600
610
  `oat docs nav sync --check --target-dir <docs-app-dir>`.
601
611
 
602
612
  If `mkdocs.yml` exists:
@@ -616,18 +626,23 @@ record whether app migration is relevant only when evidence or user intent suppo
616
626
 
617
627
  For framework apps read their package.json and installed docs packages against
618
628
  the running CLI's bundled `assets/public-package-versions.json`, without network.
629
+ The helper covers the `@open-agent-toolkit/docs-*` packages and, when the app
630
+ declares it in any dependency section, the app-local `@open-agent-toolkit/cli`
631
+ whose `oat docs generate-index` runs in `predev`/`prebuild`; a stale local CLI
632
+ writes a different manifest than the running CLI.
619
633
  Run this skill's production helper after resolving this skill's own directory:
620
634
 
621
635
  ```bash
622
636
  node "$SKILL_DIR/scripts/package-drift.mjs" --app "<docs-app-dir>" --cli "$(command -v oat)"
623
637
  ```
624
638
 
625
- If a package-manager wrapper prevents locating the CLI root, discover the bundle
626
- from that invoked installation offline. Inspect `command -v oat` and, for a shell
627
- shim, read its `exec` lines or `cmd-shim-target` comment (for example,
628
- `sed -n '1,160p' "$(command -v oat)"`). Resolve a relative JavaScript target from
629
- the shim's directory; do not evaluate copied shell text. Locate that target's
630
- package root containing `package.json` named `@open-agent-toolkit/cli` and
639
+ `--cli` follows a direct install to its package root. For a POSIX shell shim,
640
+ such as a pnpm global `oat`, the helper reads the shim as text without executing
641
+ it: the `# cmd-shim-target=` comment first, then relative `exec` targets resolved
642
+ from the shim's real directory. If the helper still reports that it cannot
643
+ locate the running CLI bundle (a wrapper it cannot parse), locate the invoked
644
+ installation offline without evaluating wrapper text: find its JavaScript entry
645
+ and that entry's package root containing `package.json` named `@open-agent-toolkit/cli` and
631
646
  `assets/public-package-versions.json`. `pnpm root -g` or `npm root -g` can help
632
647
  locate it, but newer pnpm installations may nest it in a hashed directory; use
633
648
  the actual shim target, never another checkout's bundle. Bind the inspected paths:
@@ -641,9 +656,14 @@ test "$(node "$OAT_INSTALLED_ENTRY" --version)" = "$(oat --version)" &&
641
656
  node "$SKILL_DIR/scripts/package-drift.mjs" --app "<docs-app-dir>" --versions "$OAT_INSTALLED_ROOT/assets/public-package-versions.json"
642
657
  ```
643
658
 
644
- Never substitute registry latest or this target repo's package version. Missing
645
- bundle metadata, missing installed packages, or non-orderable versions (including
646
- prereleases) mean unverified, never an upgrade. The helper compares stable numeric
659
+ Never substitute registry latest or this target repo's package version. The
660
+ helper finds installed packages with Node's lookup: the app's `node_modules`,
661
+ then each ancestor's, so hoisted installs (pnpm `node-linker=hoisted`, npm or yarn
662
+ workspaces) resolve. A docs directory without `package.json` (Markdown) returns
663
+ `applicable: false` with exit 0. Missing bundle metadata, missing installed
664
+ packages, or non-orderable versions (including prereleases) mean unverified,
665
+ never an upgrade; each `unverified` row carries a `reason` (for example, not
666
+ installed: run the app's install first, then re-run the helper). The helper compares stable numeric
647
667
  version components: older installed packages are `drift`; equal versions are
648
668
  `current`; newer installed packages are `ahead`, with no upgrade command. For
649
669
  `ahead`, report that the running CLI is stale and ask the operator to update or
@@ -651,12 +671,29 @@ select the intended CLI installation before re-analysis; do not recommend a docs
651
671
  package downgrade. `unverified` also has no package command and needs manual
652
672
  verification. Neither status authorizes a tooling update.
653
673
 
654
- The helper reports declared and installed versions, target versions and commands
655
- for orderable targets. If the app uses a different package manager, translate the
656
- command to its documented equivalent preserving package, exact target and
657
- dependency section. Cite the manifest, installed package path, bundle path and
658
- exact command. Report older-package drift as `tooling-update`, `approval: explicit`;
659
- describe unsupported scaffold repairs separately as `manual`. Markdown has no
674
+ The helper reports declared and installed versions, the installed manifest path
675
+ and target versions, and an `upgradeCommand` only for `drift`. The command pins
676
+ the `packageManager` of the app or its nearest ancestor (`npx --yes pnpm@<version>`,
677
+ which works without Corepack; `corepack pnpm@<version>` is equivalent where
678
+ Corepack is installed) and adds
679
+ `--ignore-workspace` for a nested app that the ancestor `pnpm-workspace.yaml`
680
+ `packages` globs do not include (its own lockfile alone does not make it
681
+ standalone). The output's `workspace` field reports `member`, `standalone`,
682
+ `root` or `undetermined`; for `undetermined` (glob syntax the helper does not
683
+ evaluate) the command omits `--ignore-workspace` and `reason` asks you to
684
+ confirm membership with `pnpm -r ls` first. Run it as given: a global pnpm of another major can rewrite the app's
685
+ `pnpm-workspace.yaml` settings and leave `node_modules` linked to a different
686
+ store version (`ERR_PNPM_UNEXPECTED_STORE`); recover by reinstalling with the
687
+ pinned version, not by switching managers. Without a `packageManager`, the
688
+ command uses bare `pnpm`; confirm its version matches the lockfile before
689
+ running it. When `packageManager` names another manager, the row has no command
690
+ and its `reason` asks for the equivalent add command; translate it preserving
691
+ package, exact target and dependency section. Cite the manifest, installed package path, bundle path and
692
+ exact command. Report older docs-package drift and older app-local CLI drift
693
+ together as one `tooling-update`, `approval: explicit`, listing each drifting
694
+ package's exact command in its own dependency section; apply's approved tooling
695
+ update bumps them and regenerates the manifest with the upgraded app-local CLI.
696
+ Describe unsupported scaffold repairs separately as `manual`. Markdown has no
660
697
  app-package drift check. This helper reads only and never upgrades anything.
661
698
 
662
699
  ### Step 7: Severity-Rate Findings
@@ -672,9 +709,10 @@ Use these defaults:
672
709
 
673
710
  Give every recommendation a unique stable ID (`R-001`, etc.) and
674
711
  `approval: explicit | default`; preserve IDs through review and never reuse a
675
- retired ID for a different change. `explicit` covers docs-package updates,
676
- restructure blocks and anything outside the Markdown scope (including authored
677
- IA decision/config writes). `default` covers ordinary in-scope content repairs.
712
+ retired ID for a different change. `explicit` covers tooling updates (docs
713
+ packages and the app-local CLI), restructure blocks and anything outside the
714
+ Markdown scope (including authored IA decision/config writes). `default` covers
715
+ ordinary in-scope content repairs.
678
716
  Missing evidence, `omit` and `ask_user` remain independent blockers regardless
679
717
  of approval class. Capture exact targets and commands; an explicit class is not
680
718
  permission to perform unsupported work. Apply's one input is this artifact plus
@@ -723,7 +761,7 @@ Use the `analysis` target:
723
761
  Follow the canonical loop exactly:
724
762
 
725
763
  1. Resolve `workflow.autoArtifactReview.analysis`; missing config means enabled, and only explicit `false` skips the loop.
726
- 2. Resolve `oat_orchestration_retry_limit`; default to `2` if unavailable.
764
+ 2. Resolve the retry bound from `oat_orchestration_retry_limit` in the active OAT project's `state.md` frontmatter; it is not an `oat config` key. Default to `2` when no project is active or the value is absent or invalid.
727
765
  3. Dispatch `oat-reviewer` in structured mode via Tier 1 subagent when available, falling back to the same reviewer prompt inline when needed.
728
766
  4. Apply Critical and High fixes when they are local to the analysis artifact and unambiguous.
729
767
  5. Offer Medium and Low fixes rather than applying them silently.
@@ -47,16 +47,19 @@ Do not invent missing audiences or choose an IA without approval.
47
47
  - Bundle metadata: {running CLI public-package-versions.json path or unverified}
48
48
  - Docs app manifest: {path; Markdown: not applicable}
49
49
 
50
- | Package | Declared / installed | Bundled | Status | Exact upgrade command | Recommendation ID |
51
- | ----------------------------- | ----------------------------------- | --------- | -------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------- |
52
- | {@open-agent-toolkit/docs-\*} | {range / actual version or missing} | {version} | {current / drift / ahead / unverified} | {drift only: helper upgrade command adapted to actual manager; otherwise none} | {drift only: R-NNN; approval: explicit; otherwise none} |
50
+ | Package | Declared / installed | Bundled | Status | Exact upgrade command | Recommendation ID |
51
+ | --------------------------------------------- | ----------------------------------- | --------- | -------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------- |
52
+ | {@open-agent-toolkit/docs-\* or declared cli} | {range / actual version or missing} | {version} | {current / drift / ahead / unverified} | {drift only: helper upgrade command adapted to actual manager; otherwise none} | {drift only: R-NNN; approval: explicit; otherwise none} |
53
53
 
54
54
  Only older installed packages (`drift`) receive a package-upgrade command and
55
- stable recommendation ID with `approval: explicit`. `current` needs no tooling
56
- recommendation, even if the helper emits a reinstall command. For `ahead`, select
55
+ stable recommendation ID with `approval: explicit`. Docs-package drift and
56
+ app-local `@open-agent-toolkit/cli` drift share one `tooling-update` ID, each row
57
+ keeping its own dependency section in its command; apply then regenerates the
58
+ manifest with the upgraded app-local CLI. `current` needs no tooling
59
+ recommendation and has no command. For `ahead`, select
57
60
  or update the intended CLI installation, then re-analyze; do not recommend a docs
58
61
  package downgrade. `unverified` requires manual verification before a package
59
- recommendation.
62
+ recommendation; record the helper's `reason` (for example, not installed).
60
63
 
61
64
  Unsupported app config/routes/scripts: {manual changes required; never automatic}.
62
65
 
@@ -38,8 +38,8 @@ Use this checklist when evaluating a docs surface.
38
38
 
39
39
  - Opening code fences have language identifiers.
40
40
  - Shell command examples follow the repo's documented fence convention; default
41
- to `sh` unless local guidance uses `bash` or the block requires Bash-only
42
- syntax.
41
+ to `bash` unless the example is POSIX-only (`sh`) or local guidance requires
42
+ another fence.
43
43
  - Headings are non-empty.
44
44
  - Each authored page has at most one document-level H1 unless the file is an
45
45
  intentional imported README or generated/imported artifact.