@@ -41,7 +41,7 @@ matching arm entirely, so a doc naming `@objectstack/service-automation` but not
4141repo path was a guaranteed miss — #4162 .) A deleted package falls back to the coarse
4242` packages/<x> ` token, which still substring-matches any doc naming the deleted path.
4343
44- ** Two exclusions:** change classes that cannot make an implementation-accuracy doc
44+ ** Three exclusions:** change classes that cannot make an implementation-accuracy doc
4545stale are dropped before the changed-package roots are derived:
4646
47471 . ** Test files** (` *.test.* ` / ` *.spec.* ` at any depth, plus ` __tests__ ` /
@@ -52,16 +52,46 @@ stale are dropped before the changed-package roots are derived:
52522 . ** Package tooling scripts** (` <packageRoot>/scripts/** ` ): build/verification
5353 tooling, not the runtime behaviour docs describe (#4183 flagged 106 docs for a diff
5454 whose only code change was a new check script). Narrow on purpose: ` src/scripts/** `
55- is runtime code and stays counted, and so does ` package.json ` — exports/deps
56- changes ARE implementation. No package publishes runtime code from ` scripts/ `
55+ is runtime code and stays counted. No package publishes runtime code from ` scripts/ `
5756 (checked against every ` files ` allowlist; three plugins ship a lone
5857 ` i18n-extract.config.ts ` only for lack of a ` files ` field).
58+ 3 . ** Dev-only manifest edits** (#6893 ): a ` <packageRoot>/package.json ` whose changed
59+ ** top-level keys** are all in ` {scripts, devDependencies} ` . This is the only
60+ ** field-level** exclusion — ` package.json ` as a file stays counted, because
61+ ` exports ` / ` main ` / ` dependencies ` / ` files ` / ` version ` changes ARE implementation.
62+
63+ It is the residue of exclusion 2: #4183 dropped the check * script* but kept the
64+ ` package.json ` line registering it, so the same PR still lit up the same doc set
65+ through the manifest. Measured over 400 merged commits, five had a ` package.json ` as
66+ their only ` packages/** ` implementation change, and ** all five** touched nothing but
67+ those two keys — 152 doc-rows in total, none of which could be stale:
68+
69+ | commit | keys changed | docs flagged |
70+ | :--| :--| --:|
71+ | ` df0605ba5 ` | ` scripts ` | 12 |
72+ | ` 2672f855f ` | ` scripts ` | ** 113** — #6893 's headline number |
73+ | ` a64315556 ` | ` devDependencies ` | 10 |
74+ | ` 77d9001c7 ` | ` devDependencies ` | 13 |
75+ | ` 466bd9285 ` | ` devDependencies ` | 4 |
76+
77+ The last three are ` test(...) ` commits: exactly the class exclusion 1 exists to kill,
78+ leaking through the manifest instead. The allowlist is an allowlist on purpose — an
79+ unknown or newly-invented key falls on the ** counted** side — and unparseable, added
80+ or deleted manifests are counted too.
81+
82+ ** Why it cannot narrow the net:** the classifier is per * file* . A PR that also touches
83+ that package's ` src/** ` derives the package root from those files anyway, so this arm
84+ only ever decides the case where the manifest is the package's sole change. Verified
85+ both directions on the real diffs (#6893 ): adding an ` exports ` entry to
86+ ` packages/spec/package.json ` still flags 113 docs, and a ` scripts ` entry * alongside* a
87+ ` src/ ` edit also still flags 113 — with the manifest itself reported as skipped.
5988
6089The excluded counts are reported in the summary line and as ` testFilesSkipped ` /
61- ` scriptFilesSkipped ` in ` --json ` , so the narrowing is never silent. ` --self-test ` pins
62- the classifiers * and* the package-root derivation against paths that must and must not
63- match (` commands/test.ts ` is implementation; ` foo.conformance.test.ts ` is not; a
64- container directory must never come out as a package root).
90+ ` scriptFilesSkipped ` / ` devOnlyManifestsSkipped ` in ` --json ` , so the narrowing is never
91+ silent. ` --self-test ` pins the classifiers * and* the package-root derivation against
92+ paths that must and must not match (` commands/test.ts ` is implementation;
93+ ` foo.conformance.test.ts ` is not; a container directory must never come out as a package
94+ root; ` dependencies ` is never dev-only).
6595
6696** And one deliberate non-exclusion:** ` packages/*/CHANGELOG.md ` stays counted, even though
6797release notes define behaviour no more than a test does. Extending the exclusion there
@@ -76,7 +106,9 @@ looks like the obvious next step and is a provable no-op, for two independent re
761062 . Even if it did run, ` changeset version ` writes ` package.json ` next to every
77107 ` CHANGELOG.md ` it appends to — 45 of the former against 46 of the latter on the first
78108 page of #3910 's diff — so dropping the CHANGELOGs would leave the derived package-root
79- set bit-identical.
109+ set bit-identical. Exclusion 3 does ** not** undercut this: what ` changeset version `
110+ rewrites is ` version ` (and workspace ` dependencies ` ranges), neither of which is in
111+ the dev-only allowlist, so those manifests stay counted.
80112
81113A hand-edited CHANGELOG outside a release is also close to nonexistent in practice. Left
82114counted, and recorded here so the idea is not rediscovered as a gap.
@@ -168,6 +200,27 @@ and posts/updates a single advisory PR comment listing the docs that reference t
168200changed code. ** Never fails the build** — it only flags drift at the source, before it
169201lands on ` main ` . Reviewers (or an on-demand audit run) decide whether to re-verify.
170202
203+ ### The comment forks release-owned pages into a read-only section (#6893 )
204+
205+ Same ruling as [ 1b] ( #release-owned-pages-are-in-scope-and-read-only-4920 ) , one level
206+ down. The comment used to list ` content/docs/releases/v17.mdx ` in the same bulleted list
207+ as editable pages — so a reader treating the advisory as a worklist was being pointed at
208+ the one edit AGENTS.md forbids outright. The specimen that made it concrete: PR #6921
209+ changed two diagnostic strings in ` packages/lint ` and got back three rows, one of them
210+ that release page.
211+
212+ They are ** not filtered out** . ` docs ` in ` --json ` stays the full set (it is what scopes
213+ the audit, and #4920 rejected excluding these pages for good reasons); ` releaseOwnedDocs `
214+ is a ** partition** of it — ` releaseOwnedDocs ⊆ docs ` , always — and the comment renders it
215+ under its own ⛔ heading telling the reader to file an issue instead of editing.
216+
217+ ` affected-docs.mjs ` therefore holds a third literal copy of ` RELEASE_OWNED_PREFIX ` ,
218+ alongside AGENTS.md's guardrail row and the audit workflow's own const. Copies, because
219+ the workflow is evaluated in a sandbox VM that cannot import and a shared module would
220+ leave * it* the only unanchored one. ` check-audit-scope.mjs ` iterates
221+ ` RELEASE_OWNED_CONSUMERS ` and fails if any copy stops matching the guardrail row — ** add
222+ a consumer, add it to that list.**
223+
171224## 3. ` docs-accuracy-audit ` workflow — the LLM audit
172225
173226A Claude Code multi-agent workflow (` .claude/workflows/docs-accuracy-audit.js ` ). For each
0 commit comments