Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 21 additions & 1 deletion .github/workflows/docs-drift-check.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -105,6 +105,17 @@ jobs:
const crossCutting = data.crossCuttingSymbols || [];
const weak = data.weakAnchorsDropped || [];
const coarse = data.packageMentionDocs || [];
// ── HOW MUCH OF THE SDK BRIDGE'S DECLARED SURFACE THIS RUN COULD REACH (#9572)
// The `sdk` anchor kind is what puts `api/client-sdk.mdx` on the list, and it
// rides one hop: a registrar's `path:` tail selecting a route-ledger row. A row
// no tail can select is invisible to EVERY run — measured on `9ff11921a`, 45 of
// 221 client-bound rows are reachable and 176 are not, and 88 of those 176 name
// a client method at least one hand-written page carries. None of that printed
// anywhere before this block: the run simply never mentioned the SDK page and
// looked healthy. A structural blind spot is exactly what the "what this run
// could not see" section is for, so it is rendered here beside the per-run
// narrowings rather than left for a reader to infer from a gap.
const bridge = data.bridgeCoverage || null;
// ── WHICH TREE THIS WAS COMPUTED ON (#9519) ─────────────────────────────
// The row set is a fact about two commits and this comment named neither.
// Pages are read with `readFileSync` from the WORKING TREE, and on a
Expand DownExpand Up@@ -193,6 +204,14 @@ jobs:
if (crossCutting.length) limits.push(`**${crossCutting.length}** cross-cutting symbol(s) contributed no route anchor: \`${crossCutting.join('`, `')}\``);
if (overbroad.length) limits.push(`**${overbroad.length}** anchor(s) matched too much of the corpus to be a work list: \`${overbroad.join('`, `')}\``);
if (weak.length) limits.push(`**${weak.length}** name(s) were too generic to anchor anything (single lowercase words)`);
if (bridge && bridge.measured && bridge.unreachable > 0) limits.push(`the SDK route bridge reached **${bridge.reachable}** of **${bridge.clientRows}** client-bound route-ledger rows — the other **${bridge.unreachable}** have no registrar \`path:\` tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run: \`node scripts/docs-audit/affected-docs.mjs --bridge-coverage\``);
// A broken scan is not a coverage number and must not read like one — see
// `bridgeCoverageFrom`. Rendered outside the collapsed section below, because
// "the bridge found no ledger at all" is not a limit of this run, it is a
// defect in the tool that every subsequent run will keep reporting as clean.
const bridgeBroken = (bridge && bridge.measured && (bridge.brokenScan || []).length)
? ['', `> ⛔ The SDK route bridge's own scan came back structurally empty: ${bridge.brokenScan.join('; ')}. Treat every \`sdk\` row above as unavailable rather than absent.`]
: [];
// Rendered whenever there is anything to say, INCLUDING when the only thing to
// say is "the wide net exists and holds N pages". A short list is the right
// answer here, but a reader must be able to tell a short list from a blind one
Expand DownExpand Up@@ -231,7 +250,7 @@ jobs:
// whose own tree does yield a row is owed the reason. With no anchors the
// run has no opinion to disagree with, and the bytes would be pure noise on
// every docs-tooling-only PR (#9037 — every byte here is relayed).
body = [marker, '### 📓 Docs Drift Check', headline, ...limitsBlock,
body = [marker, '### 📓 Docs Drift Check', headline, ...bridgeBroken, ...limitsBlock,
...(anchorList.length ? treeBlock : [])].join('\n');
} else {
const detail = (data.detail || []).reduce((m, d) => (m[d.doc] = d.via, m), {});
Expand DownExpand Up@@ -280,6 +299,7 @@ jobs:
);
}
}
body.push(...bridgeBroken);
body.push(...limitsBlock);
body.push(...treeBlock);
body.push(
Expand Down
44 changes: 40 additions & 4 deletions scripts/docs-audit/README.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,6 +24,10 @@ node scripts/docs-audit/affected-docs.mjs --all

# pin the classifiers, package-root and anchor derivations (needs no repo state; CI runs this before the mapping)
node scripts/docs-audit/affected-docs.mjs --self-test

# how much of the DECLARED client-bound route surface the `sdk` bridge can reach (diff-free)
node scripts/docs-audit/affected-docs.mjs --bridge-coverage
node scripts/docs-audit/affected-docs.mjs --bridge-coverage --json # + the unreachable rows themselves
```

**Derivation (#9192): a doc is *affected* when it NAMES something the change touched.**
Expand DownExpand Up@@ -81,6 +85,37 @@ cross-cutting helper, and "which routes mention this name" then answers *every*
Reported as `crossCuttingSymbols`. `SCREAMING_SNAKE` constants are kept out of the bridge
entirely — a data table is consulted by handlers, it is not their implementation.

### The `sdk` bridge reaches part of its own population, and says which part (#9572)

The `sdk` hop needs a registrar `path:` tail to select a route-ledger row. Measured on
`9ff11921a`: **45 of the 221 client-bound ledger rows are reachable, 176 are not.** An
unreachable row is not "unlisted this time" — no symbol change bridges to it, ever.

That number now travels with the answer. `bridgeCoverage` is emitted on every run whose
change carried a bridgeable symbol (`{ measured: false, reason }` when it did not — never a
fabricated zero), the drift comment renders it in *What this run could not see*, and
`--bridge-coverage` answers it with no diff at all.

Two things it deliberately is **not**:

- **Not a verdict.** The ratio is reported. Failing CI on it would widen the recognizer
under CI pressure, which the #9747 family declines explicitly. What *does* exit non-zero
is `brokenScan` — no ledger found, no tail produced, or a ledger file matching the
convention that the row recognizer parses to zero rows. Those cannot fire on a tree where
the scan works at all, and each of them otherwise reports `0 of 0 unreachable`, which is
arithmetically true and reads exactly like a healthy bridge.
- **Not a fix for the 176.** The card measured the causes and they are unrelated: ~97 rows
have no static registration of any shape in `packages/**` (better-auth mounts the auth
table; the runtime dispatcher matches `cleanPath` with `===`), ~50 have a `path:` literal
in a scanned registrar whose static remainder `routeTailOf` declines once the
`${basePath}` interpolation is stripped, and the rest are method-call registrations in
files outside `REGISTRAR_FILE_RE`. Each needs its own before/after measurement per
#9432's standard.

Half the blind spot is load-bearing: **88 of the 176** unreachable rows name a client
method that at least one hand-written page carries (31 distinct pages, `api/client-sdk.mdx`
among them), so the silence is not an empty region.

### What it cannot see is reported, never implied

`anchorlessChanges` lists changed files that yielded no anchor at all; a non-empty value
Expand DownExpand Up@@ -302,10 +337,11 @@ the source, before it lands on `main`. Reviewers (or an on-demand audit run) dec
to re-verify.

The comment also carries a collapsed **"What this run could not see"** section:
anchorless files, cross-cutting symbols, over-broad anchors, and the coarse
package-mention count. That is the point-of-use half of #9192 — every one of the three
derived-list failures in that shift was caught only because a dev widened the probe past
what the tool offered, never because the tool signalled its own limits where it was read.
anchorless files, cross-cutting symbols, over-broad anchors, the coarse package-mention
count, and the `sdk` bridge's reach over the client-bound ledger rows (#9572). That is
the point-of-use half of #9192 — every one of the three derived-list failures in that
shift was caught only because a dev widened the probe past what the tool offered, never
because the tool signalled its own limits where it was read.

### The comment forks release-owned pages into a read-only section (#6893)

Expand Down
Loading
Loading