fix(devx): refuse an appended path filter that a baked positional already swallows (objectui#7814) - #9504
Merged
Conversation
…eady swallows (objectui#7814) `pnpm --filter <pkg> test <one file>` does not narrow the run. objectui#3240 bakes a positional into every package `test` script (`vitest run --root ../.. packages/<pkg>/`), and Vitest UNIONS positional filters, so the appended path sits beside the baked one and every file the baked filter admits still runs. It exits 0 and prints a green summary for the PACKAGE, which reads exactly like a narrowed run for the FILE — the count is real, the attribution is not. Measured on this base, argv captured from inside the guard itself during a real run: both filters arrive in ONE `positionals` array, in ONE process, and the guard returned `null` for every config load of that run. It could see the union and said nothing. `evaluateVitestInvocation` now returns a `subsumed-positional-filter` verdict when one positional contains another as a substring — which is exactly how Vitest matches them, so the longer one admits a subset of what the shorter already admits and changes the collected set by nothing. The message names which filter was swallowed by which, and hands back the form that does narrow (`pnpm exec vitest run --root ../.. <path>`), spelled for the caller's cwd. The check runs LAST, after the three existing verdicts, so it only ever adds refusals: every invocation refused before is still refused with the same code. The bare `pnpm --filter <pkg> test` — the baked filter alone — stays allowed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013VGeMu3p6qEFWR6K6GGLaW
os-try-charles
marked this pull request as ready for review
September 14, 2026 13:08
os-try-charles
deleted the
claude/issue-7814-vitest-argv-union-guard
branch
September 14, 2026 13:27
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 #7814
STEP 1 — the measurement, and it says YES
The question the dispatch put: can the guard, at the point it runs, see BOTH the baked
packages/cli/filter and the appended positional?Captured out of the guard itself on
origin/main(d7d0956568), by appending a dump insideassertCanonicalVitestInvocationduring a real run of the card's command. Quoted, not summarised:Both filters arrive in one
positionalsarray, in one process (pid 16985), for all five config loads of that run — and the guard returnednullevery time. It could see the union and said nothing. ⇒ STEP 2 is reached.The instrumented guard was restored byte-identically afterwards:
git diff HEAD0 bytes, on-disk blob back to695d6f2b93bbed51c1ace196519c3ef2feda6eb4, probe marker count 0.The card's numbers, re-measured on this base (not copied)
The card recorded 16 files / 246 tests vs 43 from 2026-09-06. Those are timestamps. On
d7d0956568:pnpm --filter @object-ui/cli test packages/cli/src/__tests__/app-generator.test.tspnpm exec vitest run --root ../.. packages/cli/src/__tests__/app-generator.test.tsSame file, same tree, same base. 266 against 47 — and the widened one is bit-identical to the bare
pnpm --filter @object-ui/cli test, which also reports 17 / 266. That equality is the defect stated as a measurement: the appended path changed nothing.STEP 2 — the smallest loud reading
evaluateVitestInvocationgains asubsumed-positional-filterverdict: refuse when one positional contains another as a substring. That is exactly how Vitest matches positionals — substring of the test file path, unioned — so a positional containing another admits a subset of what the other already admits, and adds zero files to the run.The message names the union and hands back the form that does narrow. Real output of the card's own command on this branch:
Exit status 1. The message is Chinese to match the three verdicts already in that file; making the fourth English would have left the guard bilingual.
Only ever refuses MORE —
gates_weakened: NONEThe new check runs last, after
double-dash-args,package-cwdandmissing-path-filter. Every invocation refused before is refused with the same code now; the new verdict can only turn a formernullinto a refusal. Pinned as its own test.Non-regression, measured:
pnpm --filter @object-ui/cli test(baked filter alone, the legitimate package-level run) → still allowed, exit 0, 17 / 266.pnpm exec vitest run --root ../.. PATH(the form the message recommends) → exit 0, 1 / 47.testscript carries exactly one, so nothing existing trips the new verdict.Ablation — the pin's control is the current silent-green run
Fix committed first, then
scripts/vitest-invocation-guard.mjsalone reverted to the base blob and restored, each leg proved on disk by blob hash:subsumed-positional-filteroccurrences695d6f2b93…e5069f5263…The three that fail without the fix: refuses the exact invocation the card measured, reads subsumption the way Vitest matches, yields to the older verdicts.
git diff HEAD0 bytes after restore.Verification
pnpm exec vitest run scripts/→ 158 files passed, 2 skipped; 4644 tests passed, exit 0. (Run whole rather than one file: nine otherscripts/__tests__files read this guard.)pnpm exec tsc -p tsconfig.scripts.json --noEmit→ exit 0.pnpm exec eslinton both changed files → exit 0. One pre-existing warning (VITE_CONFIG_NAMEunused) that is present at the base revision too, in a part of the file this diff does not touch.check:control-bytes,check:new-line-citations,check:entry-guard,check:test-path-roots,check:shell-escape-residue→ all exit 0.node scripts/check-changeset-presence.mjs→ exit 0, and it states the reading: 2 files changed, 0 of them published source of a package the release covers. No changeset owed.node scripts/check-governed-queue-guard.mjs --teston both paths → NOT GOVERNED.Heavy runs were serialised through
scripts/pm/os-verify-lock.shin the sibling checkout.Scope held
⛔ No package's
testscript touched — the bakedpackages/PKG/filter is a different card's question, and changing it would silently re-scope every package's test run. ⛔AGENTS.mdnot touched (governed surface). One sentence there is now stale as a consequence of this change; it is called out in the report on the card rather than edited here.Generated by Claude Code