fix(tooling): let the clocked-window rule see a load routed through a same-package helper - #19201
Merged
os-try-charles merged 2 commits intoSep 19, 2026
Merged
Conversation
… same-package helper
The clocked-window rule in `check-test-source-alias` classifies loads by
scanning comment-masked source for a LITERAL specifier sitting inside an
`import(...)` / `require(...)` form. A wrapper offers no such site: the test
writes `loadOptionalPackage('@objectstack/cloud-connection')` and the helper
one frame down writes `await import(specifier)` — a VARIABLE. The file
therefore earned no `clocked` entry AND no `moduleScope` entry, so both of
the conditions the diagnostic needs were unmet at once and the gate stayed
silent over a probe measured at 5005ms against a 5000ms `testTimeout`.
The reader now follows ONE hop: a callee declared in the test file itself, or
imported through a RELATIVE specifier resolving inside the same package, whose
body performs a dynamic load of a non-literal specifier. Everything else is
unchanged — the population is still the specifiers the package was already
measured to resolve through `dist/`, read at the same granularity. A callee
reached through a bare specifier is another package's code and is not
followed; one that imports a literal is already read at its own site.
Measured over the whole repo: the reader newly reports zero files, because
the one call site it reaches (`packages/cli/src/utils/optional-package.test.ts`)
already pays the load at module top. With that module-top import ablated in
memory, the old reader reports nothing and the new one reports that call —
the defect this fixes, reproduced on today's tree.
The cheaper variant priced against it — flag a test file naming a registered
specifier as a string literal anywhere with no module-scope load — reports 502
findings across 418 files and not one true positive: 383 type-only import
clauses, 78 `vi.mock` registrations, 25 plain fixture strings and 16 specifiers
quoted inside generated-source literals.
Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk
Co-authored-by: Claude <noreply@anthropic.com>
…lation An `every()` over an empty finding list is vacuously true, so both text assertions passed with the reader disabled and only the presence and the count legs drove red. Pairing each with the count makes four of the seven new cases fail when the reader is removed. Claude-Session: https://claude.ai/code/session_017ef78bLdybu3AffehKkhfk Co-authored-by: Claude <noreply@anthropic.com>
os-try-charles
marked this pull request as ready for review
September 19, 2026 12:29
os-try-charles
deleted the
claude/issue-17658-clocked-window-helper-reach
branch
September 19, 2026 12:55
This was referenced Sep 19, 2026
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.
Part of #17658
What was silent
The clocked-window rule classifies loads by scanning comment-masked source for a literal specifier sitting inside an
import(...)/require(...)form. A wrapper offers no such site:So the file earned no
clockedentry and nomoduleScopeentry — both of the conditions the diagnostic needs, unmet at once — and the gate said nothing over a probe measured at 5005ms against a 5000mstestTimeout.⭐ The live instance is not red today:
packages/cli/src/utils/optional-package.test.ts:61carries the module-topimport '@objectstack/cloud-connection';that #17180 landed, and lines 55-59 are a hand-written comment describing this exact blind spot. Until this PR the file was protected by a comment, not by a detector. ⛔ No file underpackages/cliis touched here — that is the measured object.Both candidate predicates, priced over the whole repo
Each was implemented against the real scan and run over every workspace package with tests. Baseline (today's reader) reports 0 clocked findings repo-wide.
Candidate 1's 502 findings, classified by the reading that decides each — not one of them is a load:
import type { RemoteTable, SchemaValidationResult } from '@objectstack/spec/contracts'(packages/cli/src/commands/datasource/envelope-unwrap.test.ts:76),import type { IObjectQLEngine } from '@objectstack/spec/contracts'(packages/cli/src/commands/migrate/meta.stored-flow-resolution.integration.test.ts:26). Erased before anything resolves — this gate's own header states a type-only clause is accepted as neither a finding nor a compliance token.vi.mockregistration.vi.mock('@objectstack/platform-objects/plugin', ...)(packages/cli/src/commands/secret/orphans.guards.test.ts:48),vi.mock('@objectstack/runtime', ...)(packages/cloud-connection/src/marketplace-install-local-corrupt-ledger.test.ts:42). The specifier names a module to REPLACE; no cold transform of the real dependency is paid at that site at all.JSON.stringify({ name: '@objectstack/spec', version: '1.0.0' })writing a manifest into a tempdir (packages/cli/src/commands/doctor-unexamined-spec-tree.test.ts:341);require_.resolve('@objectstack/plugin-security')(packages/cli/src/utils/unmanaged-tables.integration.test.ts:61) — a resolve, not a load."import { defineStack } from '@objectstack/spec';"as fixture file CONTENT (packages/cli/test/i18n-extract-check-dry-run.test.ts:89), andexpect(survivor.stdout).toContain("import * as Data from '@objectstack/spec/data'")(packages/cli/test/generate-agent-retired.e2e.test.ts:150).⇒ candidate 1 is not a reach fix, it is a different rule with a 100% false-positive rate on this tree. Candidate 2 landed.
Candidate 2 reaches exactly one call site in the repo —
packages/cli/src/utils/optional-package.test.ts:139,loadOptionalPackage('@objectstack/cloud-connection'), via./optional-package.js— and reports nothing, because line 61 pays the load at module top. That is the correct verdict: the file is compliant. Its binding detector finds a same-package loader in 13 test files (loadOptionalPackage,bootStack,createHostImporter,mergeRuntimeModule,probeOrganizations); none of the others hands it a registered specifier as a literal, so none is reported.Red first, then green
The real instance, reproduced. Line 61 blanked in memory only (nothing written to
packages/cli;git status packages/clistayed clean), full gate over the real tree:That remedy is the one-line change #17180 landed, and it is what the card's leg C printed when the load was spelled as a literal.
The self-test fixture, ablated. From the committed tree,
helperRoutedLoadSiteswas disabled with an earlyreturn []. The mutation was proved on disk (marker occurrences 0 → 1,git hash-object680a0a39 → different), and restored withgit checkout HEAD -- ...verified by hash equality and an emptygit diff HEAD.4 of the 7 new cases drive red under the ablation; the other 3 are the negative controls (the non-loader callee, the bare-specifier callee, the paid control), which are vacuous without the reader by construction.
The control fixture.
packages/clocked-helper-routed-paidis the same routed call in a file that already pays the load at module top — the remedy this gate prints, and the state the real instance is in today. It must report nothing, and does.Scope held
dist/, read at the same granularity.@objectstack/cloud-connectionis already inKNOWN_UNALIASED_TEST_IMPORTS['@objectstack/cli']; the gate already meant to cover it and simply could not SEE the call. The ledger is byte-identical.bootStackshows up in the binding scan and is deliberately not reported: the rule still requires a dynamic load, not a boot. That widening has an open question on the thread.SELF_TEST_BATTERY_FLOORstays 9. The clocked-window battery declares 12 to 19.Gates
node scripts/check-test-source-alias.mjsnode scripts/check-test-source-alias.mjs --self-testpnpm check:test-source-aliaspnpm check:cross-package-test-inputsnode scripts/check-self-test-wired.mjs+--self-testnode scripts/check-scripts-symbol-anchors.mjs+--self-testnode scripts/check-declaration-mirrors.mjs+--self-testpnpm check:nul-bytesdispatch-gates --commandsderives--ran)pnpm lint(repo-wide,eslint . --no-inline-config)a66ebc98Type check: the diff is one
.mjsgate script that notsconfigprogram compiles and no TypeScript file imports (git grepfinds only prose references), and it carries no.d.mtsmirror —check-declaration-mirrorsaudits that in both directions and is green. So there is no type-check lane for this diff, which is why thedispatch-gatestypecheck-shaped family names are not silence here.Gate timing: 5.1s to 6.4s on the full scan; the projections a file needs are now computed once and handed to both readers instead of per rule.
Acceptance notes
Changeset: none, and
skip-changesetis applied. Nothing already published moves — no published package'sfiles[]reaches a repo-rootscripts/path (checked across every non-private workspace manifest), and the root manifest is private with nofiles[].Out of scope, noted and not filed:
Generated by Claude Code