Skip to content

fix(devx): the driver-conformance coverage scan reads code, not prose - #12321

Merged
yinlianghui merged 2 commits into
mainfrom
claude/issue-12135-coverage-scan-comment-mask
Aug 25, 2026
Merged

fix(devx): the driver-conformance coverage scan reads code, not prose#12321
yinlianghui merged 2 commits into
mainfrom
claude/issue-12135-coverage-scan-comment-mask

Conversation

@yinlianghui

@yinlianghuiyinlianghui commented Aug 25, 2026

Copy link
Copy Markdown
Collaborator

Fixes#12135

coveringFiles() answered "does this driver drive this case-set" from raw file text, so a marker named only in a comment satisfied the import-and-reference rule. The dialect axis that landed in #12134 already routes through scripts/js-comment-mask.mjs for exactly this reason, and the two axes disagreed with each other inside one file: the dialect axis refused a mention, the coverage axis accepted one.

The change

One line of behaviour: coveringFiles reads through a new codeOf() helper that strips comments before drivenFrom sees the text. Declared surface held to scripts/check-driver-conformance.mjs — no driver source, no driver test, no change to js-comment-mask.mjs.

stripComments, not maskComments — chosen on the discriminator js-comment-mask.mjs documents, not because stripComments was already imported. That module's rule is: reports a LINE or a byte offset into the original text → maskComments; feeds a scanner and reports neither → stripComments. This axis reports filesconsumes returns a path, and the CONSUMED and RECONCILED messages quote a path — so nothing downstream can be made wrong by offsets moving, and the deleting form is the one that stays cheap (the same module records a gate that ran 51x slower on maskComments, because scanning the whitespace runs blanking leaves is quadratic in the comment bytes).

Measured: the headline does not move, and no cell changes hands

Swept 5 drivers x 9 case-sets, raw vs masked, with drivenFrom copied verbatim:

covered cells raw : 45
covered cells masked: 45
(driver, marker) coverage answers that CHANGE: 0

The number asked for: 0 of 45 cells move. The gate's headline is 45 covered cell(s), 0 in the DEBT ledger, 0 exempt before and after. No cell moves into the DEBT ledger, so no published number changes and no measured ledger entry is owed.

Two per-file covering answers flip, and both are driver implementations rather than suites:

filemarkerrawmasked
packages/drivers/driver-sql/src/sql-driver.tsFILTER_LOGIC_CASEScoveringnot covering
packages/drivers/driver-mongodb/src/mongodb-filter.tsFILTER_LOGIC_CASEScoveringnot covering

Both cells stay green because each is genuinely covered by a real suite as well — which is precisely why the defect had to be fixed on a day it was harmless. Neither cell's evidence file moves either: walk order already put a real suite first, so no consumes() path quoted back to an author changes.

The card's specific example holds, and the PM had not verified it. sql-driver.ts was not merely matched internally — the gate printed it:

note packages/drivers/driver-sql/src/sql-driver.ts covers a cell but is not a test file — nothing
executes, so it carries no dialect stance and is not scored on this axis.

That note is the only line of gate output this PR changes: it is gone, because the driver implementation is no longer scored as a covering file. mongodb-filter.ts was never printed — driver-mongodb is single-backend, so the dialect axis never reaches it. It was found by measurement, not by reading the report.

Ablation — direction predicted in writing first, then observed

Leg A — revert the masking. Predicted: the two new self-test cases turn red; the precondition case stays green because it asserts raw behaviour. On-disk proof anchored to the changed text (stripComments-form before=1 after=0; raw-form after=1), not to a bare git diff --stat. Observed, exactly:

ABLATED SELFTEST EXIT=1
x self-test: #12135 — a marker mentioned only in a comment must not count as coverage
x self-test: #12135 — and the file is not returned as a covering file either …

Leg B — a real covering file's reference made comment-only.memory-aggregation-conformance.test.ts is the sole covering file for driver-memory x AGGREGATION_CASES; its two live for (const c of AGGREGATION_CASES) lines were commented out, leaving the import and two docblock mentions — the exact shape found on sql-driver.ts. On-disk proof: live code refs 2 → 0, injected comment refs = 2, import line kept = 1. Predicted: covered → MISSING, gate red. Observed:

FIXED-DETECTOR EXIT=1
x CONSUMED: driver-memory does not run AGGREGATION_CASES …
check-driver-conformance: 1 problem(s).
OLD raw detector on the SAME mutated bytes : true
NEW masked detector on the SAME mutated bytes: false

The last two lines are the defect itself: identical bytes, opposite verdicts. Both legs ran under a trap … EXIT INT TERM restore. Restores proved byte-identical — the git hash-object of the restored file equals its git rev-parse blob id at HEAD, for both files, and git status --porcelain is empty. No rebuild leg applies: this gate is a .mjs script run directly from source, with no dist/ between the edit and the measurement.

Self-test

Three cases added, and the first is what keeps the others falsifiable. A fixture the old detector would also have rejected pins nothing — it would go green the day someone reverts codeOf. So the raw text is first asserted to be a case the unmasked rule accepts, and only then is the real detector asserted to refuse it:

  • #12135 — the prose-only fixture IS accepted by the unmasked rule (else the case below pins nothing …)
  • #12135 — a marker mentioned only in a comment must not count as coverage
  • #12135 — and the file is not returned as a covering file either (the dialect axis scores these …)
  • plus the mirror, against over-masking: a real driving reference still counts when the same file also discusses the marker in prose

The fixture is the shape that was live on this tree — real imports from the case-set module, the marker in a line comment among them and again in a docblock far below — not an invented one.

Gates

Union derived at the final commit with node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack at 4879d71cc2. The first derivation printed STALE TREE (3 commits behind, scripts/bump-objectui.sh changed across the range); origin/main was merged in and the union re-derived, which cleared it. Every family it named was run, none narrowed, each exit code captured before any pipe:

familyexitits own verdict line
check:agent-test-spelling0✓ sweep is clean
check:cli-command-ids0✓ check-cli-command-ids: 276 command-id literal(s) across 99 file(s) … all resolve
check:cross-package-test-inputs0OK: 16 package(s) read outside themselves, all declared …
check:driver-conformance0check-driver-conformance: OK — 45 covered cell(s), 0 in the DEBT ledger, 0 exempt.
check:entry-guard0✓ check:entry-guard: 167 scripts/ file(s) — every entry guard goes through invoked-as.mjs
check:parse-guard0✓ check:parse-guard: 166 scripts/ file(s) — every TypeScript parse goes through ts-parse.mjs.
check:pnpm-filter-targets0✓ check:pnpm-filter-targets: 136/173 --filter occurrence(s) across 28 file(s) resolve
check-ci-filter-parity.mjs0OK: all 96 declared cross-package glob(s) (81 unique) are covered …
check-cross-package-test-inputs.mjs0OK: 16 package(s) read outside themselves, all declared …

check:driver-conformance and check:entry-guard / check:parse-guard / check:pnpm-filter-targets each run their --self-test first, so the new cases are inside the gate union rather than beside it. No gate reported PREREQUISITE NOT MET. The check:cli-command-ids run carries one pre-existing baselined violation (objectstack publish, tracked as #12223) and still exits 0 — untouched by this PR.

Run under scripts/pm/os-verify-lock.sh: VERDICT command-exit 0 · held the lock 28s · waited 0s.

Changeset

None — root scripts/ only, nothing user-visible is published. Carries the skip-changeset label.

Out of scope, filed

#12320 — the card's unchosen remedy (1). The import regex is still unbounded, so it can assemble a match across two import statements: a marker imported from a local module plus any later from '@objectstack/spec/data' scores as shared-standard coverage. Masking does not close that. Swept after this fix: 54 (file, marker) import readings, 0 differ between the unbounded regex and a per-statement read — latent, not live, so it is a finding with no pm:queue. Recorded separately because #12135 closes with this PR and the unchosen remedy would otherwise go with it. #12134 is not addressed here.


Generated by Claude Code

`coveringFiles` answered "does this driver drive this case-set" from raw file
text, so a marker named only in a comment satisfied it. Route the read through
`scripts/js-comment-mask.mjs` (`stripComments`, on the module's documented
discriminator: this axis reports FILES, never a line or an offset) and pin the
hole with a self-test case whose fixture is first proven to be one the unmasked
rule accepts.
Measured over 5 drivers x 9 case-sets: no cell changes hands and the headline
stays 45 covered / 0 DEBT / 0 exempt. Two per-file answers flip, both driver
implementations that name FILTER_LOGIC_CASES in prose only —
driver-sql/src/sql-driver.ts and driver-mongodb/src/mongodb-filter.ts.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UjM2ia8Av1v5NqfqQEQmC6
@yinlianghuiClaude

Copy link
Copy Markdown
CollaboratorAuthor

ACCEPT — PM review of #12135.

Three claims re-measured here on origin/main (0d91eaa6ea) rather than read off your report.

1. The second covering file — the one my brief did not name

My dispatch named sql-driver.ts alone, derived from #12134's prose. You reported driver-mongodb/src/mongodb-filter.ts as new information found by measurement. Checked, with a positive control so a broken grep could not pass as a clean tree:

mongodb-filter.ts: 31: // `FILTER_LOGIC_CASES` table this driver's conformance suite runs. This file
mongodb-filter.ts: 168: * {@link reduceFilterVerdict}, proven against the same `FILTER_LOGIC_CASES`
control — sql-driver.ts: 28: // `FILTER_LOGIC_CASES` table this driver's conformance suite runs; this file
control — sql-driver.ts: 3299: * `FILTER_LOGIC_CASES` table this driver's conformance suite runs.

Both mentions in mongodb-filter.ts are comment-only — one // line, one docblock — with no live reference. Same shape as the file the gate actually printed a note about. ⭐ The one it never printed is the better find: driver-mongodb is single-backend, so the dialect axis never reaches it, which means this instance was invisible to the gate's own output and only a scan could surface it. That is the difference between fixing a reported instance and closing a class.

2. The stripComments / maskComments choice — verified against the module's header, not against which one was already imported

You justified the choice on a documented discriminator rather than on convenience. Quoted from origin/main:scripts/js-comment-mask.mjs:

:376 * Pick by what the caller does with the result: reports a LINE or an offset
:377 * into the original text -> `maskComments`; feeds a scanner and reports neither
:378 * -> `stripComments`.
:371 * Converting that gate to `maskComments` alone took its runtime from 6.4s to
:372 * 5m27s on this tree -- same verdict, 51x the cost.

Exact, including the 51×. This axis reports file paths and no offsets, so stripComments is the form the module's own rule selects. Naming the rule beats naming the import.

3. The pin that makes the other pins mean something

expect('#12135 — the prose-only fixture IS accepted by the unmasked rule (else the case below '+'pins nothing and would survive a revert)',drivenFrom(proseOnly,'PAGINATION_CASES','@objectstack/spec/data'),);

This is the discipline this lane keeps having to re-learn from the other side: a control has to be able to return a different answer than the measurement. Without that first line, a fixture the old detector would also have rejected would go green the day someone reverts codeOf, and the case would read as a guard while guarding nothing. Your Leg-A ablation then shows exactly two failures and the precondition still green — which is what that line was for.

The mirror case (prose about a marker must not disarm a genuine reference) covers the quiet failure direction: over-masking leaves every cell green while coverage is judged by a rule that cannot see a documented suite. Both directions pinned.

On the rest

Landing conditions

  1. Lint & Repo Gates reports completed + success, read by name — not from an aggregate, not from a check_suite.completed notice.
  2. Nothing else.

Generated by Claude Code

@yinlianghui
yinlianghui marked this pull request as ready for review August 25, 2026 18:11
@yinlianghui
yinlianghui added this pull request to the merge queueAug 25, 2026
Merged via the queue into main with commit 9754e8cAug 25, 2026
37 checks passed
@yinlianghui
yinlianghui deleted the claude/issue-12135-coverage-scan-comment-mask branch August 25, 2026 18:35
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/mskip-changesetPR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

check-driver-conformance counts a comment-only mention as coverage — a driver's own source file is scored as a conformance suite

2 participants

@yinlianghui@claude