Skip to content

[finding] docs-audit: declinedIn reads neither discriminator, so a literal-union route: TYPE member in any OTHER quote is billed as an unread row — a PARTIAL-read verdict on an accurate ledger #10901

Description

@os-zhuang

Filed unassigned by the os-dev seat implementing #10793 (session c970724d-303c-5614-9d20-a3f92205cfad). Recording, not fixing — out of that card's scope, and measured as a by-product of its reproduction. No live instance on today's tree.

What

#10793 made the row recognizer read through both of #10500's exact discriminators, so a
single-quoted route: 'GET /a' | 'GET /b' TYPE member no longer mints a phantom row. The
complement scan did not move: declinedIn still runs over raw text, through neither
codeOnly nor typeDeclRegions.

So the same type member, written in either of the two quotes the recognizer declines, is
billed as a route: value the parse failed to read — and that is a verdict, not a
number.

Measured (this tree, parseLedgerSource + bridgeCoverageFrom driven directly)

export interface Entry { route: "GET /api/v1/gone" | "GET /api/v1/meta"; client: string }
export const L = [
{ route: 'GET /api/v1/meta', family: 'metadata', disposition: 'sdk', client: 'meta.getTypes' },
];

rows 1 · routesDeclared 2 · declined 1 · brokenScan 1

x-route-ledger.ts is a PARTIAL read of that ledger, not its shape — the row recognizer
reads single-quoted values only and read 1 of 2 declared `route:` value(s) and 1 of 1
declared `client:` value(s); declined 1: line 1: route: "GET /api/v1/gone"

The backtick spelling behaves identically (declined 1 · brokenScan 1, naming
route: `GET /api/v1/gone` ). The file declares one row and the tool calls it a
partial read of two, exits 1, and names the entry interface's own type member as the row it
could not read.

Why this is not #10794, which was closed not planned

#10794 is the same scan reading raw prose — a route: "GET /x" inside a comment. Its
remedy is codeOnly, and triage declined it. This one is not prose: a type member is
genuinely in code position, so codeOnly cannot reach it and never could. The discriminator
that answers it is typeDeclRegions, the second of #10500's pair — the same one #10793 just
applied to the recognizer and to the first term of the denominator. declinedIn is now the
only route:/client: scan in the file that reads through neither.

It also fails in the opposite direction to #10793: loud, not silent. A named entry and a
non-zero exit on an accurate ledger is a false RED, which is the failure mode the
type-declaration exclusion exists to prevent — see the --self-test note that removing that
exclusion turns all seven of today's accurate ledgers red (259 of 266).

Why it is a finding and not a live defect

All seven live ledgers declare route: string; and nothing else. Scanned on this tree with
the codeOnly + typeDeclRegions pair: 0 quoted route: / client: leads inside a type
declaration in any quote, across all seven. Live figures stay exact (259 of 259,
221 of 221, 176 unreachable), and #10793's before/after moved none of them.

Likelihood is lower than the single-quoted spelling this repo's formatter produces — the
formatter rewrites double quotes back to single — but a type member is exactly where a
template literal or a hand-written double quote survives review, because it is a type, not
a table row anybody is reading as data.

Direction, not a prescription

  1. Leave it. Nothing fires today, and the shape needs a ledger that unions its route:
    member in a quote the recognizer declines.
  2. Give declinedIn the same two discriminators — the narrow version is to skip
    typeDeclRegions only, which is the half codeOnly cannot cover and the half [finding] docs-audit: declinedIn still reads raw text, so a route: quoted in a comment in ANY other spelling is billed as an unread row — a PARTIAL-read verdict on an accurate ledger #10794's
    closure did not decide. It moves the declined population, so it wants its own
    before/after against the --bridge-coverage header on the same terms [finding] docs-audit: the ledger ROW recognizer reads raw text, so a route: 'X' written in a comment becomes a real row #10683 and [finding] docs-audit: the ledger row recognizer now reads codeOnly but still not typeDeclRegions — a literal-union route: TYPE member still mints a silent phantom row #10793
    did. Measured delta today would be zero.
  3. Fold it into declarationsIn. The file already states this design goal twice ("two
    scans that each decide separately what "in code position" means are two scans that can
    drift into disagreeing while both look right"), and after [finding] docs-audit: the ledger row recognizer now reads codeOnly but still not typeDeclRegions — a literal-union route: TYPE member still mints a silent phantom row #10793declinedIn is the last
    scan still deciding it for itself. Bigger change, same population effect.

(2) is the cheap one that closes the class; (3) is the one that removes the second opinion.

Refs: #10793, #10794, #10683, #10500, #9896.


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions