Skip to content

fix(cli): make a vitest filter that selects no test file say so - #17965

Merged
claude[bot] merged 4 commits into
mainfrom
claude/issue-17853-vitest-project-filter-silent-pass
Sep 13, 2026
Merged

fix(cli): make a vitest filter that selects no test file say so#17965
claude[bot] merged 4 commits into
mainfrom
claude/issue-17853-vitest-project-filter-silent-pass

Conversation

@os-sales

Copy link
Copy Markdown
Collaborator

Fixes #17853

Clause-②: no

packages/cli's tier comment block told the reader that nothing is lost, three lines above two commands that lose things silently. This makes the loss visible and rewrites the block that invited the misreading.

1. Acceptance item 1 first — and a correction the card is owed

Neither the filing seat nor triage could run the repro (no node_modules in a shared checkout). This is the first reading taken in a real worktree, on a built tree, at base 84e6b05b6:

leg exit files
vitest run --project unit test/i18n-extract-companion-orphan.test.ts 1 0No test files found, exiting with code 1, plus filter: and projects:
vitest run test/i18n-extract-companion-orphan.test.ts 0 1Test Files 1 passed (1), Tests 4 passed (4)

Two different counts, so the pair does not trip the STOP condition. But ⚠️ the card's headline sentence is FALSIFIED as literally written. Naming ONE integration-tier file under --project unit is not "reported as a passing file with zero cases executed" — it is red, with a diagnostic. vitest's printNoTestFound() already covers the all-filters-lost case.

The defect is one step over, and it is the shape that actually cost #16872 a round: the PARTIAL filter. Once at least one named path matches, the ones that matched nothing are dropped in complete silence. Measured here, two unit-tier paths plus one integration-tier path under --project unit:

 Test Files  2 passed (2)      <- THREE paths named, two counted
      Tests  21 passed (21)

The run naming only the two prints the same summary, and diff over the two captures is empty but for timestamps and durations. The discarded name appears nowhere in vitest's own output — the single occurrence in a captured terminal is pnpm's echo of the argv in ERR_PNPM_RECURSIVE_EXEC_FIRST_FAIL, which pnpm prints only when the run was already red, and which is therefore absent from exactly the green run that needed it. That is why the card's own count (five named, four counted) was right about the harm while its one-file repro was not.

2. The change

  • packages/cli/vitest-filter-preflight.ts (new) — reads process.argv through parseCLI, vitest's OWN exported parser, and the SAME two derived tier arrays the projects take as their include. Any named path that will select no test file is reported by name, with the tier it really lives in and a command that runs it.
  • packages/cli/vitest.config.ts — the whole :498-509 block rewritten (see below), and the preflight invoked at config load.
  • packages/cli/test/vitest-project-filter-preflight.test.ts (new, unit tier) — 28 cases.
  • packages/cli/tsconfig.test.json — the new root harness module named in include, one by one like its three siblings, so it is in the tsc program by declaration and not by a test's import.

⛔ Why this is not a reporter — a measured reversal

It was built as a test.reporters entry first, which is the obvious seam. Direction ② caught it. Naming test.reporters replaces vitest's own defaulting instead of extending it:

if (!resolved.reporters.length) {
  resolved.reporters.push([isAgent ? 'agent' : 'default', {}]);
  if (process.env.GITHUB_ACTIONS === 'true') resolved.reporters.push(['github-actions', {}]);
}

Two costs, one measured here and one that would only ever have shown up in CI:

  1. it pinned default where an agent terminal gets agent — a healthy control run gained two lines, so direction ② failed outright; and
  2. it would have dropped the github-actions reporter on every CI run, silently removing failure annotations, in the one environment a local control run cannot observe.

The reporter list belongs to vitest. The preflight runs at config load and touches no vitest seam.

⛔ Every uncertainty declines rather than guesses

An argv parseCLI refuses, a --project that is not a tier name (a negation or a glob), a --changed / --related run: each prints nothing. Silence is the status quo, so declining can never make a run worse than it is today; a guess could.

The rewritten block

The reassurance ("nothing is skipped… pnpm test runs everything") is kept — it is true — but it is now stated as a fact about the POPULATION and immediately denied as a guarantee about one narrowed invocation. The safe command is printed FIRST, above the two that can lose things.

3. Two directions, both measured

Both legs of a guarded ablation in one worktree, against base 84e6b05b6. The mutation was proved on disk by blob hash (git hash-object == the base blob) before each BEFORE run, and the restore proved the same way (== the HEAD blob, git diff HEAD empty), under a trap ... EXIT INT TERM.

① A filtered-out invocation is now distinguishable. Same command, before → after:

  !! FILTER SELECTED NOTHING — 1 of the 3 path(s) you named will run no tests.

     test/i18n-extract-companion-orphan.test.ts
       lives in the `integration` tier; this run selected project `unit`.
       run it:  pnpm --filter @objectstack/cli exec vitest run --project integration test/i18n-extract-companion-orphan.test.ts

     ⛔ Nothing below counts the path(s) above: the file count, the pass/fail
        totals and the exit code are about the OTHER named paths only.
        To run every tier, which is what CI runs:
          pnpm --filter @objectstack/cli test

Occurrences of that banner — before: 0. After: 2 (once above the banner, once below the summary, which is where a reader looks for Test Files N passed).

⚠️ The run stays exit 0. This is a diagnostic, not a refusal — which the ruling permits ("red, warning, or at minimum one diagnostic line"). Making it red would also refuse a legitimate narrowing whose prefix spans both tiers, and that trade is the maintainer's, not this card's.

② A healthy narrowed run is byte-identical. --project unit naming two unit-tier files, before vs after:

raw bytes   before=235   after=235
sha256      before=2792e94eb841c997   after=2792e94eb841c997   (timing lines normalised)
diff        exit 0

⚠️ This direction is what reversed the reporter design. It was measured, not assumed, and it failed the first time.

A once-guard, also measured. vitest loads this config once per project and each load is its own module instance, so the first module-level flag guarded nothing: three loads printed the notice three times above the banner and three more at exit — six copies. The guard now lives on a scope object defaulting to globalThis, and the pin calls twice on one scope.

4. Verification

what command result
test-layer typecheck pnpm --filter @objectstack/cli typecheck exit 0 — ledger unchanged at 3 files / 28 errors
the new pin vitest run --project unit test/vitest-project-filter-preflight.test.ts exit 0Test Files 1 passed (1), Tests 28 passed (28)
repo lint pnpm lint exit 0 (full tree, not narrowed)
derived gate families scripts/pm/dispatch-gates.mjs → 48 commands 48 / 48 exit 0

Exit codes were captured before any pipe (cmd > file 2>&1; EXIT=$?). check:dual-build-cjs-loads first returned exit 3 PREREQUISITE NOT MET and check:query-options-erasure exit 124 from a 150s cap of my own; both were re-run to a real verdict (after a full pnpm build, and without the cap) and both are green — neither was reported as a measurement it was not.

NOT MEASURED, declared rather than smoothed: the integration tier was not run locally. The diff touches no integration-tier file, no spawn entry point and no driver/kernel boot path, so that layer is declared to CI. packages/cli's unit tier was likewise not run whole — the derived families and the new pin were.

5. ⚠️ Changeset — a measured divergence from the dispatch order

The order says "Changeset required: @objectstack/cli". Measured, nothing published moves, so this carries skip-changeset instead — flagged here rather than decided silently.

files[] for @objectstack/cli is dist README.md CHANGELOG.md. After a full build, each new symbol greps to 0 hits across all three; positive controls on the same paths hit (runServe → 1 file, objectstack → 150 files, dist/ holds 16 entries, so the probe is not blind). The four changed paths — vitest.config.ts, vitest-filter-preflight.ts, tsconfig.test.json, test/** — are test harness, and tsconfig.build.json compiles src only.

Per AGENTS.md, a patch would publish a CHANGELOG sentence to consumers about a change they cannot observe, and picking a level to satisfy a gate is exactly what that rule forbids. ⇒ If the seat wants the changeset anyway, say so and it lands in a follow-up commit.

6. Fences observed

Acceptance notes

  • The .claude/ half stays unfiled by this seat, as ordered. The card's option ③ and its closing "second axis" — the agent contract judges integration-tier exposure by which FILES a diff touches, while the real exposure is what the derived command EXECUTES — are governed surface and route to domain:skills. This work makes that card no less necessary: the preflight tells a reader when a narrowed run lost something, but nothing here makes a narrowed run a valid pre-delivery target.
  • Same-class, wider, reported not filed by this PR: seven other packages declare vitest projects (types, objectql, rest, runtime, spec, qa/dogfood, core). The silent partial-filter drop is vitest's behaviour, not this config's, so it is live in all of them; the preflight landed here is package-local by design. Raised in the report for the seat to route.
  • Not a defect, recorded so the next reader does not chase it: the block is at :496-509, one line below the :498-509 the dispatch printed, and the "fast, local default" line is :506 — the card's own citation — not :505. The :583 / :613 citations hold exactly.
  • The win32 slash() normalisation vitest applies to filters is deliberately not mirrored, and a --project negation or glob is deliberately not modelled. Both are stated in the module header; each can only ever mis-aim a diagnostic, never a run.

Generated by Claude Code

os-sales and others added 4 commits September 13, 2026 07:40
`vitest run` drops a positional filter that matches nothing without any
diagnostic, as long as some other filter matched: five paths in, four
counted, the discarded name printed nowhere. The output is byte-identical
to the run that named only the four, so it is indistinguishable from "ran
and passed".

Wire a reporter that reads vitest's own resolved filters and collected
specifications and names every path that selected nothing, with the tier
it lives in and a command that runs it. It writes zero bytes when nothing
was lost. Rewrite the tier comment block, which printed its "nothing is
skipped" reassurance three lines above the two commands that can lose
things.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c
Naming `test.reporters` replaces vitest's own reporter defaulting instead
of extending it: it pins `default` where an agent terminal gets `agent`
(measured: a healthy control run gained two lines, so direction ② failed)
and it would drop the `github-actions` reporter on every CI run, removing
the failure annotations in the one environment a local control cannot
observe.

Read the command line through vitest's own exported `parseCLI` instead,
at config load, over the same two derived tier arrays the projects take
as their `include`. Every case the preflight cannot model — an argv the
parser refuses, a `--project` that is not a tier name, a `--changed` run
— declines silently rather than guessing.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c
vitest's `CliOptions` is an interface, so it is not assignable to
`Record<string, unknown>`; the cast that would hide that is also what
would stop a vitest upgrade from surfacing a renamed option as a type
error. Declare the three fields this module reads instead, and hand the
real `parseCLI` to the pin unaltered so the compatibility is pinned.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c
…r load

vitest loads this config once per project and each load is its own module
instance, so the module-level flag guarded nothing: measured, three loads
printed the notice three times above the banner and three more at exit.
Move the guard onto a scope object defaulting to globalThis, and pin it
by calling twice on one scope. A repeat call still returns the notice to
its caller; returning the empty string there would read as "nothing lost".

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

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/cli, touching 13 documentable anchor(s). ⚠️ 1 changed file(s) yielded no anchor (packages/cli/vitest.config.ts), so the pages documenting them are NOT COVERED by this run — this is not a clean bill of health for those files.

4 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/data-modeling/field-types.mdx (via EMPTY (symbol, a top-level const object))
  • content/docs/deployment/troubleshooting.mdx (via EMPTY (symbol, a top-level const object))
  • content/docs/kernel/services-checklist.mdx (via EMPTY (symbol, a top-level const object))
  • content/docs/protocol/objectql/types.mdx (via EMPTY (symbol, a top-level const object))
What this run could not see
  • 1 changed file(s) yielded no anchor (packages/cli/vitest.config.ts) — pages documenting those are invisible to this run
  • 11 name(s) were too generic to anchor anything (single lowercase words)
  • the SDK route bridge reached 60 of 215 client-bound route-ledger rows — the other 155 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 155: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 100 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • 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 — 24 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 146c291943400664b8d0ef6dc39aba9c98746550packageMentionDocs.

Which tree this was computed on

This run read content/docs from acebaa4fd578fb99687941c41a2578bbbe62f23b — the merge of head cc49814d84f0bfa21851f1731d3207cbb5614983 into base 146c291943400664b8d0ef6dc39aba9c98746550, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin acebaa4fd578fb99687941c41a2578bbbe62f23b && git checkout acebaa4fd578fb99687941c41a2578bbbe62f23b
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 146c291943400664b8d0ef6dc39aba9c98746550 cc49814d84f0bfa21851f1731d3207cbb5614983 && git checkout -B drift-repro 146c291943400664b8d0ef6dc39aba9c98746550 && git merge --no-ff cc49814d84f0bfa21851f1731d3207cbb5614983

node scripts/docs-audit/affected-docs.mjs --json 146c291943400664b8d0ef6dc39aba9c98746550

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 146c291943400664b8d0ef6dc39aba9c98746550 → pass the list as
args.docs, on the commit named under Which tree this was computed on.

@claude

claude Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

Contract review

PR #17965 · card #17853 · head cc49814d84f0bfa21851f1731d3207cbb5614983

Reviewed-by: domain:cli execution PM seat (#6024), session session_01TSf4DV7ziu4V5j73e46b7c, R73 — 2026-09-13T10:21Z
Independence: SELF-REVIEW. This seat wrote the dispatch order (5651877643) and its rider; no second seat has read this PR. ⛔ Discount accordingly.
Judgment tier: default. Verdict: PASS, and it overturns one instruction this seat gave — see ③.


① ⭐ The card's headline premise is FALSIFIED, and the dev handled it exactly as instructed

Acceptance item 1 said: run triage's pair, and if both legs give the same result, STOP and correct the card. They gave different results, so the stop condition did not trip and the work proceeded — but the card's framing is wrong:

leg A  vitest run --project unit test/i18n-extract-companion-orphan.test.ts
       → exit 1, "No test files found, exiting with code 1", 0 files
leg B  same file, no --project
       → exit 0, Test Files 1 passed (1), Tests 4 passed (4)
tier control: `vitest list --filesOnly --project integration` names the file (line 11 of 46);
              the --project unit listing does NOT (204 entries, grep exit 1)

⇒ Naming ONE integration-tier file under --project unit is exit 1 No test files found, ⛔ not “a passing file with zero cases executed”. vitest's own printNoTestFound() already covers the all-filters-lost case.

The real defect is one step over, and it is exactly what cost #16872 a round — the PARTIAL filter. Once at least one named path matches, the paths that matched nothing are dropped in total silence: three paths under --project unit prints Test Files 2 passed (2), and the capture diffs empty against the run that named only the two. ⇒ The card was right about the harm and wrong about the mechanism, and the delivery repairs the mechanism that actually bites.

⚠️ For any future reader: judge this PR against the measured defect, ⛔ not against the card's title.

② The fix, and the comment block that made the harm possible

A config-load preflight (packages/cli/vitest-filter-preflight.ts, wired from vitest.config.ts — 3 references; CONTROL: projects → 5) names every path that will run no tests, with the tier it lives in and a command that runs it. The :496–509 comment block is rewritten so the “nothing is skipped” reassurance can no longer be read as a guarantee about one narrowed invocation, and the safe command is printed first.

⇒ That block was the whole trap: it reassured the reader that pnpm test runs everything, three lines above a command that silently loses files, with the safe one printed below the lossy one.

③ ⛔ This seat's dispatch order was WRONG about the changeset, and the dev was right

The order said “Changeset required: @objectstack/cli. The dev measured that nothing published moves and applied skip-changeset instead — flagging it in the PR body rather than deciding silently. Verified here, and the dev is right:

packages/cli/tsconfig.build.json   include: ['src']
the four changed files             ALL outside src/
   packages/cli/vitest-filter-preflight.ts · vitest.config.ts · tsconfig.test.json
   · test/vitest-project-filter-preflight.test.ts
packages/cli files[]               ["dist","README.md","CHANGELOG.md"]
label on the PR                    skip-changeset  ✓ applied

⇒ The build compiles src only, so no changed file can reach dist/, so nothing a consumer can observe moves. AGENTS.md makes “nothing published moves” the criterion and forbids picking a level to satisfy a gate; a patch would ship a CHANGELOG sentence about a change no consumer can see.

Ruled: skip-changeset stands. The order's line was a default applied without checking the criterion — ⛔ a dispatch order is not evidence, and a dev that measures against it rather than obeying it is doing the job correctly. Recorded here rather than quietly dropped.

④ ⭐ The delivery falsified its own first design — twice

This is the part that makes the rest trustworthy:

  1. Direction 2 failed the first time and reversed the design. The first attempt pinned default in a test.reporters entry — which added two lines to a healthy run in an agent terminal (where the reporter is agent) and would have dropped the github-actions reporter in CI. Rebuilt on vitest's own exported parseCLI at config load; ⛔ no vitest seam is named now. ⇒ The acceptance's second direction (“a healthy run's output is byte-identical”) caught a change that would have quietly degraded CI reporting.
  2. A second defect found on the way: the config is loaded once per project, so a module-level once-flag guarded nothing — six copies of one notice. The guard moved to a scope object and is pinned by calling twice on one scope.

Direction 2 now measures byte-identical: raw bytes 235 before / 235 after, sha256 of the timing-normalised capture identical (2792e94eb841c997), diff exit 0. Direction 1: banner occurrences 0 → 2. Ablation discipline: mutation by git restore --source=, proved on disk by git hash-object against the base blob before each leg, restore proved against the HEAD blob with git diff HEAD empty, under a trap with absolute paths.

⑤ Fences and declared gaps

.claude/        touched → False   (the card's option ③ and its “second axis” are governed surface)
content/docs/   touched → False
CONTROL packages/cli/ touched → True
files: 4, +696/−8

vitest-tiers.ts's SPAWN/KERNEL predicates and the two-tier partition are untouched. Gates: 48 derived, 48 run, 48/48 exit 0, --ran reconciles 48 accounted / 0 unrun; two needed a second pass and are reported as re-runs rather than as passes they never were (check:dual-build-cjs-loads first exit 3 PREREQUISITE NOT MET; check:query-options-erasure first exit 124 from the dev's own 150s cap). NOT MEASURED and declared: the integration tier and the whole unit tier, both CI's.

⭐ The docs blind spot this seat's rider flagged over packages/cli/vitest.config.ts was hand-read and is clear, with the zero back-checked as instructed: exactly one page under content/docs/ matches any of --project unit / --project integration / vitest.config / vitest run, and it documents a customer's scaffolded plugin project, not this harness — and only 1 page in that tree mentions vitest at all, so the single hit is the whole vitest surface of the docs rather than a blind probe.

#17978 filed for the same silent partial-filter drop in the seven other packages that declare vitest projects — the mechanism is vitest's own TestProject.filterFiles, not any config of ours, so it is package-independent. The card states plainly that the seven-package claim is DERIVED, NOT MEASURED.


Verdict and what remains

PASS. ⚠️ One red check, and ⛔ it is not this PR's and ⛔ not a test failure:

Dogfood Regression Gate is FAILURE while all three of its shards and Dogfood Verify CLI are SUCCESS — verified here on this head. The dev root-caused the aggregator job as never dispatched to a runner (runner_id=0, runner_name='', steps=0, log a hard 404, against a control shard reading runner_id=1000793503, 19 steps, log fetches) — the shape scripts/check-shard-attestation.mjs itself defines as abandoned, and whitelisting which a maintainer ruling of 2026-08-07 rejected. ⚠️ Those field-level readings are relayed: /actions/jobs/{id} is unreachable from this session. What this seat measured itself is the decisive half: every shard it aggregates passed, so there is no test outcome behind that red.

This seat's own rider (5652306941) offered a two-way fork — (a) a dogfood invocation selects zero files, or (b) the predicate over-fires — and the answer was outside both. Corrected at 5652342228. ⇒ Enumerating the alternatives is itself a claim, and “which of these two” can be wrong in a way neither branch reveals.

⛔ This seat cannot re-run it: POST /actions/runs/{id}/rerun-failed-jobs answers 403 Resource not accessible by integration. Per the standing rule for a failure judged not-this-PR's with no means to re-run: said once, here. The flip to ready re-fires the pull_request workflows, which is the legitimate re-run this seat does have — ⛔ not an empty commit and ⛔ not a close-and-reopen. If the fresh run is red on a shard, that is a real failure and this PR's to root-cause.

domain:cli execution PM seat · #6024 · session session_01TSf4DV7ziu4V5j73e46b7c · R73 · contract review of record · Independence: SELF-REVIEW


Generated by Claude Code

@claude
claude Bot marked this pull request as ready for review September 13, 2026 10:20
@claude
claude Bot enabled auto-merge September 13, 2026 10:21
@claude

claude Bot commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

⚠️ Requiredness is now MEASURED, not inferred — this PR is blocked on one abandoned job, and the ask is precise

domain:cli execution PM seat (#6024), session session_01TSf4DV7ziu4V5j73e46b7c2026-09-13T10:22Z. This refines the “said once” in the contract review (5652677286); ⛔ it is not a second report of the same failure, it is the answer to the question that review left open.

branches/main/protection answers 403 to this seat, so which contexts are required could not be read directly. It has now been established by experiment instead — three PRs, same seat, same minute:

PR #17972  red: Auto Label + Check PR Size          armed 10:21:17Z → added_to_merge_queue  ✓
PR #17979  red: Auto Label + Check PR Size          armed 10:21:18Z → added_to_merge_queue  ✓
PR #17965  red: Dogfood Regression Gate (this PR)   armed 10:21:36Z → auto_merge_enabled only,
                                                     ⛔ NO added_to_merge_queue, mergeable_state: blocked
queue refs confirm it: pr-17972-9fca8eb7… and pr-17979-ca9d9d36… exist; pr-17965-* does not

Check PR Size and Auto Label are NOT required (two PRs entered the queue red on both), and Dogfood Regression Gate IS — this PR is armed and the door is held by exactly one check.

What is holding it, restated in one line

That check is FAILURE while all three of its shards and Dogfood Verify CLI are SUCCESS — the aggregator job was never dispatched to a runner (runner_id=0, steps=0, log 404; relayed field-level, since /actions/jobs/{id} is unreachable from this session). ⛔ There is no test outcome behind that red.

⚠️ The ready_for_review flip at 10:20:45Z did not re-run it — measured: the failure's timestamp is still 08:48:53Z, unchanged. So that lever, which this seat named in the review as the re-run it does have, does not reach this job. ⛔ Correcting that here rather than leaving it standing.

The precise ask

This seat cannot re-run it: POST /actions/runs/{id}/rerun-failed-jobs403 Resource not accessible by integration. Either of these clears it, and ⛔ neither is available to this seat:

  1. an Actions re-run of that one job — cheapest, and legitimate under the standing rule (a job that executed zero steps died before any test body ran); or
  2. any further commit on this branch, which re-fires the workflow on synchronize.

⛔ Not acceptable, and not done: an empty commit, a close-and-reopen, skipping or quarantining the check, or whitelisting the abandoned shape — a maintainer ruling of 2026-08-07 rejected that whitelist, and scripts/check-shard-attestation.mjs records two prior incidents of this exact shape painting a false red over zero test failures.

The PR stays armed and watched. Auto-merge is enabled, so the moment that check is green the queue takes it with no further action.

domain:cli execution PM seat · #6024 · session session_01TSf4DV7ziu4V5j73e46b7c · R73


Generated by Claude Code

@claude
claude Bot added this pull request to the merge queue Sep 13, 2026
Merged via the queue into main with commit 08f5f0e Sep 13, 2026
56 of 57 checks passed
@claude
claude Bot deleted the claude/issue-17853-vitest-project-filter-silent-pass branch September 13, 2026 11:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/l 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.

1 participant