Skip to content

fix: convert the five measured comment-mask ledger rows onto the shared mask - #12932

Merged
os-elon merged 5 commits into
mainfrom
claude/issue-12834-comment-mask-conversions
Aug 28, 2026
Merged

fix: convert the five measured comment-mask ledger rows onto the shared mask#12932
os-elon merged 5 commits into
mainfrom
claude/issue-12834-comment-mask-conversions

Conversation

@os-elon

@os-elon os-elon commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Fixes #12834

Converts the five measured comment-mask ledger rows onto
scripts/js-comment-mask.mjs and deletes each row from the shrink-only ledger
in scripts/check-comment-mask-adoption.mjs. One commit per row, per the triage
ruling: five PRs would be five concurrent edits to five lines of one file, and a
lost shrink-only row is not a red build, it is a guard that stops being watched.

Ledger: 19 rows to 14 (18 unconverted + 1 specimen, to 13 + 1).
packages/cli/src/commands/artifact-child-env.pin.test.ts is untouched and
stays unconverted — that reclassification is parked for triage.

Why this is not verdict preservation

All five guards answer identically before and after on today's tree. That is
the card's own sharpest point and it is not the goal here:

"Green over text it never read" is the failure, not the absence of one — the
deleted spans simply happen not to hold what these gates look for this week.

Each guard's own predicate was re-run under both strippers and each is recorded
below as unchanged. Five guards agreeing today is luck about this week's
sources, not a safety property: a line added tomorrow inside a swallowed span
was invisible to five gates at once.

Measured on this base, not quoted from the card

Every number in the card body was taken at f75a38afa and the ledger moved
again when #12833 landed, so all of it was re-measured at
aef1b7e641e7cead90f35db7cd1e06c46a021944.

Instrument: a span diff over ORIGINAL indices — both strippers remove a set of
positions, so for each file the row's private stripper and scanSource() each
produce a removed-position set, and the two directions are read off the
difference. Reported as non-whitespace characters, which is the
whitespace-normalised figure and is immune to the projection difference between
blanking, deleting, and dropping whole lines. Falsified before use: the naive
pair over the two #12398 specimens returns 980 and 224 non-whitespace
characters deleted (non-zero, so the instrument can fail), and the shared
scanner diffed against itself returns exactly 0.

row population deletes live code keeps prose picked
cli console-route-ledger 110 files / 1.64 MB 518 on 7 files 25,637 on 3 stripComments
app-showcase inert-wirings 91 files / 0.63 MB 4,399 on 5 files 225 on 4 stripComments
plugin-auth rate-limit-storage 423 files / 7.27 MB 439 on 7 files 16,392 on 8 stripComments
driver-sql live-dialect-matrix 152 files / 2.00 MB 66 on 1 file 4,420 on 53 stripComments
runtime error-envelope 10 modules / 0.39 MB 166 on 2 files 0 stripComments

What reproduces exactly: every population (110 files / 1.64 MB, 91, 423 files /
7.27 MB, 152, 10 modules), row 4's "54 files disagree" (1 deleting + 53
keeping), row 5's 166 characters on 2 modules keeping nothing, and the named
live sites — dev.ts, serve.ts, start.ts for row 1, auth-manager.ts for
row 3, logger-receiver-detach.test.ts for row 4, dispatcher-plugin.ts and
domains/mcp.ts for row 5.

What does not reproduce: the deleted-character magnitudes for rows 1 to 4.
Row 1's card figure is 10,263 against 518 measured here; the whole-span
convention gives 590, so it is not a counting-convention difference. The tree
has moved a long way since f75a38afa. The defect, its direction and its live
sites all reproduce; the magnitudes do not, and are restated above rather than
carried forward.

stripComments or maskComments

Picked per guard by what it reports, which the module's own header makes the
criterion. All five report a line number, a bare file path, a specifier, or a
match count — none reports a byte offset into the original text — so all five
take stripComments. Row 1 is the one where it bites: its lineOf() counts
newlines in the STRIPPED text to report file:line, and stripComments
removes comment characters while keeping every newline, so the reported line
stays the real line. Pinned by the existing assertion that a mount after a
three-line block comment reports line 4.

Per-guard predicates, re-run under both strippers

Cross-package declarations

Row 1 needed none: @objectstack/cli already declares the
js-comment-mask.mjs + .d.mts pair. check:cross-package-test-inputs then
named the other four itself, and named the exact inputs list each wanted:
plugin-auth had an entry and needed the pair added; example-showcase,
driver-sql and runtime read outside themselves for the first time and take
their first entries, each with a matching turbo #test task. Without the
$TURBO_ROOT$ inputs the package's test cache stays keyed on package-local
files and a change to the shared mask replays a stale green — the #7802 shape
this gate exists for. Gate goes 20 packages to 23.

One correction the conversion forced

The gate header said row 1 "stays recorded ... nobody has re-read its scanner".
Deleting the row leaves that prose describing a row that no longer exists, so it
is rewritten to point at this shrink. Found by re-measuring the PM's per-row
count of 2 for that row: it is one ledger row plus one header prose mention, not
two rows.

No changeset — derived, with a receipt

Eight paths change: five *.test.ts, scripts/check-comment-mask-adoption.mjs,
scripts/cross-package-test-inputs.mjs, turbo.json. The "root scripts/
publishes nothing" shortcut does not cover this on its own, since four of the
five rows sit in published packages, so it was derived instead: all four
declare files: ["dist","README.md","CHANGELOG.md"], app-showcase is
private: true, a search for the five converted basenames under every dist/
returns 0 artifacts, packages/cli/tsconfig.build.json excludes
src/**/*.test.ts explicitly, and check:published-files passes stating it
"admits no test, test-harness config or build script". No published byte moves,
so nothing is user-visible and skip-changeset is applied.

Verification, all at 2659125a0

Suites (each package's own, under the shared verify lock): cli 18 passed ·
app-showcase 33 passed · plugin-auth 5 passed · driver-sql 17 passed 3 skipped ·
runtime 52 passed.

Gates re-derived from the ACTUAL diff with scripts/pm/dispatch-gates.mjs
rather than from the dispatch list, which surfaced three the brief did not name
(check:driver-conformance, check:examples-live-imports,
check:turbo-task-graph — the last because this diff edits turbo.json) plus
the convention-triggered set for editing a gate script. All green, exit status
captured before any pipe: check:comment-mask-adoption and its --self-test,
check:cross-package-test-inputs, check-ci-filter-parity,
check:agent-test-spelling, check:bash32-floor, check:cli-command-ids,
check:entry-guard, check:parse-guard, check:pnpm-filter-targets,
check:watch-hint-literal, check:published-files, check:test-source-alias,
check:type-source-resolution, check:slot-lookup,
check:page-declaration-shape, check:objectql-double-limit,
check:turbo-task-graph, check:driver-conformance,
check:examples-live-imports, check-plugin-teardown-shape,
docs-audit/check-affected-docs, docs-audit/check-drift-comment,
bare-root-worklist --self-test, check:pm-dispatch-gates,
check:query-options-erasure, check:engine-double-contract,
check:where-matcher, check:nul-bytes, check:i18n, check:i18n-coverage,
check:type-check-coverage. Repo-wide pnpm lint also run whole rather than
narrowed: green in 66s.

Typecheck for all five packages passes — but two of them, plugin-auth and
runtime, exclude **/*.test.ts from their tsconfig, so that green says
nothing about two of the five edited files. Measured directly instead with a
throwaway config that includes them: plugin-auth reports 0 errors on its file,
runtime reports 6 — and the same 6 are present on the unconverted file at
aef1b7e6, at line numbers exactly 10 lower, which is the length of the import
comment this PR adds. Pre-existing test-layer debt, nothing introduced: that
debt is already ledgered in scripts/check-type-check-coverage.mjs, whose
@objectstack/runtime entry records errors: 217 — exactly what this probe
re-measured — so nothing drifts up and nothing needs filing.


Generated by Claude Code

claude added 5 commits August 28, 2026 08:34
…mment mask

`console-route-ledger.conformance.test.ts` carried a private hand-rolled
stripper: string-aware but REGEX-BLIND, so the `//` that closes a regex
literal such as `/^https?:\/\//i` read as a line-comment opener and it
deleted to end of line. Measured on this base over the file's real
population (`packageSourceFiles()`, 110 non-test `.ts` under
`packages/cli/src`, 1.64 MB): 518 non-whitespace characters of live code
deleted across 7 files -- `commands/dev.ts`, `commands/init.ts`,
`commands/serve.ts`, `commands/start.ts`, `utils/config.ts`,
`utils/dev-restart.ts`, `utils/storage-driver.ts` -- plus 25,637
non-whitespace characters of block-comment prose KEPT behind phantom
strings opened at a quote inside a regex character class.

Converted to `stripComments` from `scripts/js-comment-mask.mjs`. That
projection, not `maskComments`: this file reports `file:line` and bare
file names, never an offset into the original, and `stripComments` keeps
every newline so `lineOf()` still counts the real line.

The census verdict does not move on today's tree -- `MOUNT_SHAPED`
resolves to exactly `[utils/console.ts]` either way -- which is a fact
about this week's sources, not a safety property: a mount added tomorrow
inside a swallowed span was invisible to this guard.

Deletes the shrink-only ledger row in the same commit, and corrects the
gate header prose that said this row "stays recorded".

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
…omment mask

`inert-wirings.test.ts` stripped block comments with the naive
`/\*[\s\S]*?\*/` sweep, which has no idea what a string literal is: it
opened a phantom comment at a block-comment opener sitting INSIDE a
string and ran to the next terminator far below. Measured on this base
over the file's real population (`sourceFiles()`, 91 `.ts` under
`examples/app-showcase/src`, 0.63 MB): 4,399 non-whitespace characters of
live code deleted across 5 files -- `coverage.ts`, `ui/actions/index.ts`,
`ui/pages/crm-workbench.page.ts`, `ui/pages/renewals-pipeline.page.ts`,
`ui/pages/task-desk.page.ts`.

Its line arm dropped only whole-line `//` comments, deliberately never a
trailing one, so it also KEPT 225 non-whitespace characters of trailing
prose that the guard could have matched on. The shared scanner removes
both and is string-aware, so the reason that arm was written anchored --
"a trailing `//` would eat the `//` in a URL inside a string" -- no
longer costs anything.

Converted to `stripComments`, not `maskComments`: the one guard here
reports bare file paths, never a line or an offset.

The import makes this package's suite read outside itself for the first
time, so it takes its first `CROSS_PACKAGE_TEST_INPUTS` entry and a
matching `@objectstack/example-showcase#test` turbo task. Both halves are
required: without the turbo `$TURBO_ROOT$` inputs the package's test
cache stays keyed on package-local files and a change to the shared mask
replays a stale green. `check:cross-package-test-inputs` named both, and
named the exact inputs list.

The retired-`retryDelayMs` offender set stays empty under the shared
mask, so the verdict does not move on today's tree -- luck about this
week's sources rather than a safety property.

Deletes the shrink-only ledger row in the same commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
…red comment mask

`rate-limit-storage-isolation.test.ts` carried a private hand-rolled
stripper that tracked the three string forms but was REGEX-BLIND, so the
doubled slash closing a literal like `/^https?:\/\//i` read as a
line-comment opener and it deleted to end of line. Measured on this base
over the file's real population (every `.ts` under `plugin-auth/src` as a
declared superset of the resolver-dependent import-graph limb, plus the
two cross-package roots it reads whole -- `packages/runtime/src` and
`packages/services/service-sms/src` -- 423 files, 7.27 MB): 439
non-whitespace characters of live code deleted across 7 files, this
package's own `auth-manager.ts` among them, plus 16,392 non-whitespace
characters of comment prose KEPT behind phantom strings.

Converted to `stripComments`, not `maskComments`: every finding here
reports a package-relative file path and a specifier, never a line or an
offset into the original.

`check:cross-package-test-inputs` then named the module and its `.d.mts`
sibling as paths no declared glob covered, so both are added to this
package's globs and to `@objectstack/plugin-auth#test` inputs. The
coupling is real rather than a scanner artefact: the import refs this
scan extracts -- and therefore its reachability verdict -- are a function
of the module's scanning behaviour.

The extracted refs are unchanged on all 423 files, so the `#6040`
packaging invariant's verdict does not move on today's tree. That is a
fact about this week's sources, not a safety property.

Deletes the shrink-only ledger row in the same commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
…ared comment mask

`live-dialect-matrix.isolation.test.ts` stripped comments with the naive
two-regex pair. Measured on this base over the file's real population
(`codeOf()` across all 152 `*.test.ts` in `packages/drivers/driver-sql/src`,
2.00 MB): 54 files disagree with the shared scanner. Mostly the safe
direction -- 4,420 non-whitespace characters of trailing line-comment
prose KEPT by the anchored line arm, which the guard could have matched
on -- but the block arm also DELETES 66 non-whitespace characters of live
code in `logger-receiver-detach.test.ts`, where a fixture STRING quotes a
docblock and the sweep eats the string.

Converted to `stripComments`, not `maskComments`: the guard reports bare
file names, never a line or an offset.

`check:cross-package-test-inputs` then named this package as reading
outside itself for the first time, so it takes its first
`CROSS_PACKAGE_TEST_INPUTS` entry and a matching
`@objectstack/driver-sql#test` turbo task, without which the package's
test cache stays keyed on package-local files and a change to the shared
mask replays a stale green.

The direct-`OS_TEST_*_URL` offender set stays empty under the shared
mask, so the verdict does not move on today's tree -- a fact about this
week's sources, not a safety property.

Deletes the shrink-only ledger row in the same commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
…hared comment mask

`error-envelope.conformance.test.ts` stripped comments with the naive
two-regex pair, whose trailing arm is UNANCHORED: a doubled slash
anywhere on a line opened a phantom comment and the rest of the line
went. Measured on this base over the file's real population (the ten
modules in its own `MODULES` list, 0.39 MB): 166 non-whitespace
characters of live code deleted on 2 of them and nothing kept -- purely
the blind direction. `dispatcher-plugin.ts` loses the rest of the line at
a doubled slash in a mount path inside a template literal, `domains/mcp.ts`
at the one in an https URL it builds.

Converted to `stripComments`, not `maskComments`: these guards report
match counts and matched text, never a line or an offset.

`check:cross-package-test-inputs` then named this package as reading
outside itself for the first time, so it takes its first
`CROSS_PACKAGE_TEST_INPUTS` entry and a matching
`@objectstack/runtime#test` turbo task, without which the package's test
cache stays keyed on package-local files and a change to the shared mask
replays a stale green.

All four per-module counts (numeric code, type-as-code, envelopes,
builder calls) are identical across all ten modules under both
strippers, so the `#3842` numeric-code pin's verdict does not move on
today's tree. That is a fact about this week's sources, not a safety
property: a numeric `code` written tomorrow after a doubled slash on the
same line was invisible to this guard.

Deletes the shrink-only ledger row in the same commit, taking the
shrink-only ledger from 19 rows to 14.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CPrUz21stTFhJRUirdc4yw
@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

Nothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs.

What this run could not see
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.

Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 4d11427534381fefaec1b8150c5dd501eca8900apackageMentionDocs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Five comment-mask ledger rows are measured DELETING live code — convert them off their private strippers

2 participants