test(cli): mask comments in the nightly-tier readers of this package's own source, and derive the pins that bound a spelling - #18924
Merged
os-support-ai merged 2 commits intoSep 18, 2026
Conversation
…s own source WIP: the twelve nightly-tier test files that read `packages/cli`'s own source text now read it through the shared `maskComments`, and three byte-exact pins are rewritten to bind a derived property instead of a spelling. Claude-Session: https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3 Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DvvamiacK328idtBYJBxV3 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
📓 Docs Drift CheckNothing 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
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
This was referenced Sep 18, 2026
os-support-ai
marked this pull request as ready for review
September 18, 2026 06:45
os-support-ai
enabled auto-merge
September 18, 2026 06:46
os-support-ai
deleted the
claude/issue-18520-nightly-pin-source-readers
branch
September 18, 2026 07:03
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #18520
Clause-②: no
The nightly-tier test files under
packages/cli/test/that read this package's own sourceTEXT now read it through the shared mask (
scripts/js-comment-mask.mjs), and the pins thatbound a byte-exact SPELLING now bind a property derived from the source instead. Every file
was judged on its own; the table below gives the rung and the reason per file.
The population, re-derived — no number inherited
Predicate, stated: a file under
packages/cli/test/whose NAME puts it in a nightly tier(
scripts/nightly-tiers.mjs—*.e2e.test.*/*.live.test.*, and nothing else selects atier), which READS this package's own source text at test time, directly or through a helper
under
test/helpers/it imports. Evaluated over each file's local import closure, on MASKEDtext, so a read one module away still counts and a path named only in prose does not.
test/*.e2e.test.tscontainingreadFileSyncserve-port-readback,published-entry-stderr-nonblocking,run-dev-stderr-nonblockinggrep -rl readFileSync test/*.e2e.test.ts | xargs grep -l 'src/'⭐ 20 and 15 are not a contradiction — they are two predicates, and the delta is readable
both ways. Eight files are in the claim's 20 and not in mine, three are in mine and not in
its 20:
lint-eval-generator-load-envelopematchessrc/in a docblock sentenceand reads
/definitely/not/here.json. This is the false positive the dispatch predicted.src/, not ours —build-docs-step-count,build-multi-package-artifact,generate-skill,serve-publishes-bound-portcreatesrc/docsorsrc/skillsinside ascratch project and read
dist/objectstack.jsonback.scaffold-emission-policyreadspackages/create-objectstack'stemplate
package.json. JSON carries no comments, so no rung applies.bin/notsrc/—published-entry-stderr-nonblocking(already masked)and
run-dev-unbuilt-workspace(raw). Both read a hand-written published entry; the second isin this PR, the first was already correct.
config-miss-stdout-purityreadssrc/commandsthroughtest/helpers/config-miss-family.tsand never spellssrc/itself;invocation-loudnessandserve-host-fallback-baseDO spell../src/...but never read itas text — they
symlink/execFileit, so they are readers of a module, not of prose.Rung per file
build-json-failure-conversions.e2e.test.tssrc/commands/compile.tsindexOfORDER block (declAt/tryAt/loadAt/normalizeAt) is the #17633 shape verbatim — raw positions over a file whose docblocks nameawait loadConfig(. ⛔ The six frozen integers are card #18894's and are untouched here.build-json-failure-warnings.e2e.test.tssrc/commands/compile.tscloud-login-json-ndjson.e2e.test.tssrc/commands/cloud/login.tsemitJson(hits now partitions the call sites againstemitRecord's own brace-matched body: outside must be empty, inside must not be.login-json-ndjson.e2e.test.tssrc/commands/login.tslogin-json-noninteractive.e2e.test.tssrc/commands/login.tsrl.question(filter already binds a SHAPE (does the line carry the abort signal), not a spelling — rung 2 has nothing to convert.json-stdout-purity.e2e.test.tssrc/commands/**toHaveLength(10)demoted to a floor. The line above it already binds the SET against the map a sibling nightly file drives, so the integer was a second frozen copy of one fact. It stays as a floor because it is the only guard on the vacuum both sides share.config-miss-stdout-purity.e2e.test.tssrc/commands/**via helpertest/helpers/config-miss-family.ts, which this PR masks once for both consumers.test/helpers/config-miss-family.tssrc/commands/**json: Flags.boolean(beside autils/config.jsimport invents a direct member; a commented-outexport default class X extends Yinvents an alias.diff-usage-error-stream.e2e.test.tssrc/commands/**flags.jsonread — which is the print-ORDER failure that opened this card. ItstoBeGreaterThan(10)population control was already a floor.run-dev-unbuilt-workspace.e2e.test.tsbin/run-dev.jsexectakes the FIRST match, so a docblock recording the oldSTDERR_DRAIN_STALL_MSwould be read as the shim's bound. Its sibling over the other published entry already masks; this makes the pair consistent.serve-app-anchored-optional-import.e2e.test.tssrc/commands/serve.tsvalidate-json-failure-conversions.e2e.test.tssrc/commands/validate.tsvalidate-json-failure-warnings.e2e.test.tssrc/commands/validate.tsserve-port-readback·published-entry-stderr-nonblocking·run-dev-stderr-nonblockingRung 1 — where it applied, and where it did NOT
Rung 1 permits DELETING a nightly assertion when a per-PR sibling already binds the same
thing. I searched for a sibling for every byte-exact subject in this population and opened
the one I found:
serve-app-anchored-optional-importboundfunction importFromHost(specifier: string, hostRoot: string = servedAppRootOrCwd())— anargument LIST, the feat(cli):
objectstack dev --cert/--keyterminates TLS in the dev process, and the canonical origin follows the listener #17725 shape exactly.src/commands/serve-cluster-host-resolution.test.tsis queue-tier (its name carries no
.e2e, sonightly-tiers.mjsleaves it in the per-PR run)and binds that function's EXISTENCE, its module scope and its uniqueness. So this PR does not
re-pin any of that here; what it keeps, because the sibling does not bind it, is the DEFAULT —
read off the paren-matched parameter list.
anchorServedAppandservedAppRootOrCwdappear in no other test in the package. The login emitter contract(
emitRecord) appears in no queue-tier test at all. ForwarningsSoFar, the queue-tiertest/truncation-remainder-notices.test.tsbinds'warnings: warningsSoFar(),'incompile.ts— the CALL SITE, not the declaration and not the spread ORDER these files pin,and for
validate.tsit binds different payload keys entirely. Not the same thing, sonothing was deleted on its account.
serve-app-anchored-optional-importin detailFive
toContain/toMatchpins over whole statements ofserve.ts, in a file only the nightlytier collects. Each now binds what it was written for:
toContain('const { configPath: absolutePath, configExists } = anchorServedApp(args.config!);')anchorServedApp(call site (the declaration excluded by the samefunctionlookbehind the per-PR sibling uses), and its ARGUMENT isargs.config!. The destructured local names are deliberately no longer bound.not.toMatch(/const absolutePath = path\.resolve\(process\.cwd\(\), args\.config!\)/)path.resolve(process.cwd(), args.configwith whitespace tolerated. A negative pin on one exact spelling passes for every respelling of the defect.toContain('function importFromHost(specifier: string, hostRoot: string = servedAppRootOrCwd())')hostRootparameter's DEFAULT, read off the paren-matched parameter list. A third parameter or a renamedspecifierno longer reddens it.toContain('const hostRoot = servedAppRootOrCwd();')andtoContain('const root = hostRoot ?? servedAppRootOrCwd();')const/lethost-root binding: at least two exist, and none may be bound without resolving throughservedAppRootOrCwd().toMatch(/^function servedAppRootOrCwd\(\): string \{$/m)function servedAppRootOrCwd(, never indented, never aconst/let/var. The return-type annotation and the brace are not the defect.What the mask changed TODAY: nothing — and that is the measurement
Every converted reader was evaluated raw and masked over the same tree, and every verdict is
identical. Masking is therefore behaviour-preserving now and protective later — it did not
launder a stale pin green:
⛔
scripts/check-comment-mask-adoption.mjsis green before and after and its ledger isunchanged at 14 rows — because none of these twelve files ever carried a private stripper.
They carried NO masking at all, which is the blind spot the card names and the gate documents.
This PR adds no private stripper; every file imports the shared module.
Ablations
Each is a script with
traprestore onEXIT INT TERM, absolute paths, an on-disk occurrencecount proving the mutation landed, exit codes captured BEFORE any pipe, and a restore proven by
git hash-objectagainst the HEAD blob plus a cleangit statusfor both paths.without
OS_TEST_TIERS=nightlythe package collects none of these files, and it says soloudly. Recorded here because a run that measured nothing is the failure mode this card is
about. The numbers below are from the re-run with the switch set.
ABL-1 — the #17633 shape, reproduced and then shown fixed. A COMMENT is injected into
src/commands/info.tsbetweenasync run(and its firstflags.jsonread, namingprintHeader(. Behaviour is untouched; only prose moved.diff-usage-error-streamAssertionError: expected [ 'info.ts' ] to deeply equal []⭐ That failure line IS the card's first row: a docblock reporting an order change that never
happened.
ABL-2 —
serve.ts, both directions.const hostRoot = servedAppRootOrCwd();becomesprocess.cwd()a host root is bound without resolving through servedAppRootOrCwd(): expected [ Array(1) ] to deeply equal []— the new partition is not vacuousimportFromHost, same arguments, same behaviourexpected '…' to contain 'function importFromHost(specifier: st…'— #17725 verbatim, on a pin no pull request can seeABL-3 — the login emitter partition.
await emitJson(outsideemitRecordevery --json write in login.ts must go through emitRecord(): expected [ Array(1) ] to deeply equal []emitJson(payload, 0)All three restored cleanly:
git hash-objectmatches the HEAD blob for every mutated path andgit status --porcelainis empty for both paths in each script.Verification
OS_TEST_TIERSunset collects none of these files. Every red/green below isunder
OS_TEST_TIERS=nightly. Independently confirmed bypnpm check:tier-file-adoption:68 nightly-tier files on disk, owned by one package.
packages/clibuilt (pnpm --filter '@objectstack/cli...' build) so the pins that refuseat load on an absent
dist/index.jsactually run.--projectfilter — what CI runs:The 12 converted files were also run on their own under
OS_TEST_TIERS=nightlybefore thewhole runs: 12 files / 336 tests / exit 0.
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstackand reconciled with--ran: 47 derived, 46 run green, 1 NOTMEASURED —
pnpm check:dual-build-cjs-loadsexits 3 (PREREQUISITE NOT MET: it reads builtoutput for packages outside this closure). ⛔ Recorded as NOT MEASURED, not as a pass and not
as a red.
pnpm lintover the whole repo, unnarrowed.node --stack-size=4000 eslint . --no-inline-configover the whole repository, exit 0.This is the unnarrowed run, so no narrowing has to be justified.
skip-changeset, by measurement with controls both waysThis PR's own diff (
git diff --name-only origin/main...HEAD) is 12 files, all underpackages/cli/test/.packages/cli'sfiles[]is["dist","README.md","CHANGELOG.md"]andtsconfig.build.jsonhasinclude: ["src"], sotest/reaches neither. Measured against thebuilt tree rather than argued:
bodySpan,splitParams,paramsOf(the three symbols this PR introduces):0 files in
dist, 0 inREADME.md.anchorServedApp(2 files),servedAppRootOrCwd(2),emitRecord(3)in
dist, so the grep over the published tree finds things and the zero above is a reading,not a dead search.
scripts/**path is touched, so the published surface did not have to be re-derived.Fences
build-json-failure-{warnings,conversions}are untouched; card[finding] two more nightly-only
emitJsonexit-count pins freeze 11/10/1 overcompile.ts— green today, one honest exit from rerunning the #18848 p1 #18894 owns that axis. Only rung 3 was applied in those two files.compile.ts's own comment that the survivors are "exactly the set the union could not see" overstates what it keeps #18779) was re-measured at the start: zero intersection with this population,and it has since merged as
031e5fbfa3. Itscompile.ts/validate.tsedits moved no countthese pins read (compile.ts still 11 payloads, validate.ts still 7), re-measured after the
merge. This PR touches none of its six test files.
content/docs/releases/and everypackages/*/CHANGELOG.mduntouched.Acceptance notes
src/commands/serve-cluster-host-resolution.test.tscarries a privatestripCommentsatline 151. It is a DECLARED row in
check-comment-mask-adoption.mjs's shrink-only ledger,measured there as agreeing with the shared mask byte for byte over 212 files, so it is
recorded debt rather than a finding, and converting it is that ledger's per-row work.
Noted, not filed.
validate-json-failure-{warnings,conversions}still pin a multi-line spread ORDER invalidate.tsbyte-exactly (...ruleAdvisories, ...docWarnings, ...), and the twobuild-json-failure-*files pin the same shape overcompile.ts. That is a rung-1/rung-2question on an axis this PR did not open, and for the
build-*pair it sits in the file thefence closes. Noted, not filed — the carrier is card [finding] two more nightly-only
emitJsonexit-count pins freeze 11/10/1 overcompile.ts— green today, one honest exit from rerunning the #18848 p1 #18894, which is already open over thosetwo files.
invocation-loudness.e2e.test.tsandserve-host-fallback-base.e2e.test.tsreach../src/...and are NOT source-text readers (they symlink and execute it). No rung applies;recorded so the next re-derivation does not re-open them. Noted, not filed.
Generated by Claude Code