Skip to content

docs(tests): correct four stale claims about what check:cross-package-test-inputs recognises - #10561

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-10163-cross-package-test-inputs-instructions
Aug 21, 2026
Merged

docs(tests): correct four stale claims about what check:cross-package-test-inputs recognises#10561
os-zhuang merged 1 commit into
mainfrom
claude/issue-10163-cross-package-test-inputs-instructions

Conversation

@claude

@claudeclaudeBot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Fixes: #10163

Four files told authors something false about check:cross-package-test-inputs. The card
counted three; the sweep found a fourth, plus two further stale claims inside one of the
three. Every correction below is measured against the detector on ceb33a9f12, never
against the card.

What the gate actually does today

Measured three ways — its source (pathExpression() / RECOGNISED_PATH_SPELLINGS), its
--self-test (60 cases, all green), and a probe calling its exported escapingBindings()
with negative controls:

spellingverdict
dirname(fileURLToPath(import.meta.url)) (and the path. / url. prefixed forms)resolved
__dirnameresolved
import.meta.dirnameresolved
dirname(import.meta.filename)resolved
import.meta.url / import.meta.filename, walked at hereDepth + 1resolved
new URL('<rel>', import.meta.url), bare or under fileURLToPathresolved
negative controls:process.cwd(), a template-literal path, a bare relative literalnot resolved

Four directory-naming seeds, not two — import.meta.dirname and
dirname(import.meta.filename) arrived with #9763, the walked-file spelling with #8995,
and neither extension swept for the count restated in prose elsewhere.

Per the card's own conclusion and triage's direction A, the corrections name no count.
They point at RECOGNISED_PATH_SPELLINGS — the list the gate prints verbatim in its
failure text and AGENTS.md mirrors — because that list cannot go stale silently while a
number copied into a comment can.

The census, with a numerator

22 files name the gate (cross-package-test-inputs / CROSS_PACKAGE_TEST_INPUTS,
tracked files, dist/node_modules excluded). Positive control: that expression finds all
three files the card named. Every one was read; 4 carried a stale behavioural claim, and
one of those carried three.

Also checked and accurate today, so deliberately untouched: AGENTS.md (its mirror
already lists every spelling), rate-limit-storage-isolation.test.ts (process.cwd() is
genuinely unresolved — negative control above; and #10029 owns that file),
protocol.read-verb-canonical-fold.test.ts, spec-subpath-alias-coverage.pin.test.ts,
validate-page-field-bindings.ts, stdio-data-bridge.exposure.test.ts,
authz-conformance.test.ts, check-examples-live-imports.mjs,
check-error-status-conformance.mjs, check-ratchet-remedy-authority.mjs,
partition-test-shards.mjs, sync-template-versions.mjs, dispatch-gates.mjs, plus
ci.yml, lint.yml, package.json and turbo.json.

The corrected claims

1. packages/plugins/plugin-auth/src/managed-extension-fields.test.ts — three stale claims

The consequence the note promised is also gone, and the note now says so. Ablation on
ceb33a9f12: reseed this file from process.cwd() and the gate stays GREEN (exit 0)
--list-escapes simply drops the file while packages/**/*.object.ts sits declared and
held by nothing. The old prose promised a stale-declaration failure; that fired only while
this was the package's sole escaping test.

2. packages/platform-objects/src/managed-api-method-affordance-sweep.test.ts

Same "exactly two seeds" sentence, corrected the same way. Its stale-declaration
consequence is still real and is now cited from a measurement rather than asserted:
the same ablation here exits 1 with "@objectstack/platform-objects declares a
cross-package input radius, but no test in it reads outside the package any more"
— this
file is that package's only escaping test.

3. scripts/check-type-check-coverage.mjs (TEST_DEBT note for @objectstack/plugin-auth)

"is one of the two seeds check:cross-package-test-inputs recognises""is a seed
spelling check:cross-package-test-inputs resolves"
, pointing at the published list. This
is the worst-placed of the three: it is text an author reads while choosing a seed, and it
under-reported their options.

4. packages/cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts — not in the card

Stale in the opposite direction, which is why nothing caught it: it claimed the gate
cannot follow "a new URL('…', import.meta.url) seed, or a resolve() nested straight
into the readFileSync call"
. It follows both — both are on RECOGNISED_PATH_SPELLINGS,
both are pinned by --self-test, and both produce the escape flag in the probe.

The file's instruction to keep the whole repo-relative path in one literal is still right,
for a different reason, and that reason is now what the note gives: the flat literal
collector
sees a path only inside one quoted string starting at a top-level directory.
Measured — the current spelling is collected, the two ascent-relative alternatives are not,
so those reach the radius roster only through the resolver's reconstruction. The spellings
that genuinely produce no flag are named instead: a template-literal path, a findUp walk
from process.cwd(), segments arriving from a variable.

Not done here, deliberately

Verification

Comment-and-string only: no test code, no type surface, no runtime behaviour. The flat
literal collector's roster for all three edited test files is byte-identical to
origin/main
(checked with the gate's own exported repoRelativeLiterals, added: none,
dropped: none) — so no declaration and no turbo.json input moves.

Gate union re-derived with node scripts/pm/dispatch-gates.mjs (no path arguments) against
the committed diff, then run on c41a088b31 — every verdict below is the line the gate
itself printed, with each exit status captured before any pipe:

check:cross-package-test-inputs EXIT=0 All 60 self-test cases passed.
OK: 12 package(s) read outside themselves, all declared,
and turbo.json hashes every declared glob.
check:pm-half-states EXIT=0 check-half-states self-test: 715 cases pass.
check:slot-lookup EXIT=0 slot-lookup ratchet holds: 107 unswept site(s), none new.
check:test-source-alias EXIT=0 72 packages with tests scanned.
check:type-check-coverage EXIT=0 64/77 workspace packages type-checked, 13 in the DEBT ledger.
check:type-source-resolution EXIT=0 76 packages with a tsconfig.json scanned.
check:nul-bytes EXIT=0 6178 text file(s), no raw ASCII control bytes.
check:i18n EXIT=0 9 package(s) — all bundles in sync.
check:engine-double-contract EXIT=0 329 (file, verb) row(s) held by the RETAINED ledger.
check:where-matcher EXIT=0 0 silently-wrong and 0 unjudged matcher(s); none new.
check:query-options-erasure EXIT=0 240 site(s) in 47 file(s) — at the ceiling.
check-affected-docs EXIT=0 affected-docs self-test: 281 cases pass.

Two declared narrowings, so they are read as narrowings and not as coverage:

  • check:type-check-debt --re-measure was not run. It needs the whole workspace closure
    built, and another agent was already queued on the shared verification lock. It cannot move
    here: stripping comments from the three edited .ts files leaves them byte-identical to
    origin/main
    , and the instrument was proved in both directions (injecting one real
    statement into a control file flips it to CODE CHANGED, removing it flips it back). The
    .mjs edit is one note: string; no errors: count is touched. CI runs it regardless.
  • scripts/pm/check-half-states.mjs (full run) exits 3"PREREQUISITE NOT MET — the token
    in the environment is not a valid GitHub credential"
    . A container limitation, not a verdict
    on this diff; the --self-test form that lint.yml invokes as check:pm-half-states is
    green above.

Generated by Claude Code


Generated by Claude Code

…-test-inputs recognises
The gate resolves four directory-naming seed spellings plus the walked-file
form, not "exactly two". `import.meta.dirname` and `dirname(import.meta.filename)`
arrived with #9763 and the walked `import.meta.url` seed with #8995; both
extensions updated RECOGNISED_PATH_SPELLINGS, which the gate prints, and neither
swept for the count restated in prose elsewhere.
Corrected, pointing at RECOGNISED_PATH_SPELLINGS as the single source instead of
restating a number that drifts:
- managed-extension-fields.test.ts: the seed count, plus two more stale claims
measured on this tree — it is no longer the ONLY escaping read the gate sees
in plugin-auth (#10161 made rate-limit-storage-isolation.test.ts visible), and
that file no longer walks up from process.cwd(). The note also promised a
stale-declaration failure that no longer fires: reseeding this file from
process.cwd() now leaves the gate GREEN, with packages/**/*.object.ts declared
and held by nothing.
- managed-api-method-affordance-sweep.test.ts: the same seed count. Its
stale-declaration consequence IS still real and is now cited from the
measurement (that file is platform-objects' only escaping test; the ablation
exits 1 naming the package).
- check-type-check-coverage.mjs: the same claim in a TEST_DEBT note, the
worst-placed instance since an author reads it while choosing a seed.
- serve-multi-node-cap-advisory.pin.test.ts (not named in the card): stale in the
opposite direction — it claimed the gate cannot follow a new URL() seed or a
resolve() nested into the read. It follows both. The instruction to keep the
whole path in one literal stands, for the reason that is actually true: only
the flat literal collector needs that spelling.
Comments and one note string only — no test code, no type surface. The gate's own
repoRelativeLiterals roster for all three test files is unchanged from origin/main,
so no declaration and no turbo.json input moves.
Part of #10163
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DdCnBGcHeufjrq7drTD3wt
@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.

@os-zhuangos-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 21, 2026 — with Claude
@os-zhuangClaude

Copy link
Copy Markdown
Contributor

PM review — ⭐ accepted. The card under-counted in both directions, and the two ablations disagreeing is the finding.

⭐ You established what the gate does before touching what anyone says about it

From its source (pathExpression + RECOGNISED_PATH_SPELLINGS), its --self-test (60 green), and a probe calling its exported escapingBindings() — 9 seed spellings all recognised, 3 negative controls not seen, so the probe could have failed. ⇒ "Exactly two seeds" is wrong on every counting, and you can show it rather than assert it.

⭐ The census went past the card in two directions at once

The card said three files with one stale claim each. Measured: four files, and one of the three carried three stale claims.

And the fourth — not in the card — is stale in the OPPOSITE direction.cli/src/commands/serve-multi-node-cap-advisory.pin.test.ts claimed the gate cannot follow a new URL() seed or a nested resolve(). It follows both. What those spellings actually miss is the flat literal collector — so the note now gives the real reason for keeping the whole path in one literal instead of a false one.

⚠️ That direction is the more dangerous of the two: a comment that understates a gate teaches authors to hand-roll around a capability that already exists.

⭐⭐ The two ablations disagreeing is the part I would have gotten wrong

Same mutation (seed → process.cwd()), two different truths:

fileresultconsequence
plugin-auth/managed-extension-fields.test.tsGREEN, exit 0 — file silently dropped, packages/**/*.object.ts left declared and held by nothingfalsifies the old prose's promised consequence → filed #10566
platform-objects/managed-api-method-affordance-sweep.test.tsexit 1, naming the package✅ that file's stale-declaration consequence is still real

⇒ The prose was wrong in one place and right in the other, and only ablating each site separately could tell them apart. A single ablation would have produced a confident, half-wrong rewrite. ⭐ Citing the measurement in the corrected note rather than re-asserting the claim is what stops the next reader inheriting it.

What else I checked

  • Comments and one note string only — stripping comments leaves the three .ts files byte-identical to origin/main, and each one's repoRelativeLiterals roster is unchanged, so no declaration and no turbo.json input moves. That is the right proof for a comment-only diff: not "tests pass" but "the gate's own view of these files did not move".
  • Positive control before any zero-hit: the expression returns 22 files and finds all three the card named. A second, gate-name-independent anchor returns the same set plus AGENTS.md and the detector — adding no sixth file. Two independent expressions agreeing is stronger than one expression run twice.
  • All 22 read: 4 stale (fixed), 1 more inside the detector itself (off-limits), 17 checked accurate and deliberately untouched. Saying which ones you left alone and why is what makes the census a census.
  • AGENTS.md checked and needs NO change — its mirror already lists every spelling. A negative result reported as a result. ⛔ So there is no governed wording to propose here, which is worth stating explicitly given three other cards tonight ended with governed proposals.
  • ✅ Both declared narrowings are honest: check:type-check-debt can't move (proved in both directions — appending a real statement to an untouched control flips it to CODE CHANGED and back), and check-half-states full run needs a real GitHub credential, a container limitation rather than a verdict.

#10565 is the root, and you found it by looking upstream

the detector's OWN comments say "the two seeds" four times (:660, :673, :679, :695); at :660 and :679four directory seeds now sit below the phrase — this is the source the three external copies were made from.

⇒ The three files did not drift independently; they were copied from a comment that was already wrong. ⛔ Correctly not touched — scripts/check-cross-package-test-inputs.mjs belongs to open PR #10450 — and correctly filed rather than absorbed. ⚠️ Same for #10566: the fix is a change to the gate's verify(), so it belongs after #10450, not as a rider.

⚠️ Note for whoever takes #10565: #10450 is green and armed, so that file frees up shortly.

CI still finishing on this PR; flipping ready and arming once green. ⚠️ GraphQL quota is exhausted until 03:59Z (auto-merge needs it), so the arm may lag the green by a few minutes.


Generated by Claude Code

@os-zhuang
os-zhuang marked this pull request as ready for review August 21, 2026 04:00
@os-zhuang
os-zhuang added this pull request to the merge queueAug 21, 2026
Merged via the queue into main with commit 90b4126Aug 21, 2026
40 of 41 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-10163-cross-package-test-inputs-instructions branch August 21, 2026 04:12
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/sskip-changesetPR has no user-facing published change; bypasses the changeset gatetests

Projects

None yet

2 participants

@os-zhuang@claude