You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Two PRs ejected from the 2026-09-20 merge train failed the same way, and three from the previous train failed a near-identical variant. This is one habit, not five bugs, and it is worth fixing once.
The shape: the pure/rules layer gets genuinely good executing tests. The wiring/gate layer gets regex assertions over source text. And the wiring/gate layer is where the safety-critical logic lives.
The justification is false.#2778 states it in three separate docblocks: "this repo's vitest runs environment: 'node' with no jsdom/happy-dom and no @vue/test-utils — I checked rather than assumed."
20 of 139 specs already mount via // @vitest-environment jsdom: portalThemeSwitch, portalFailedTurn, portalReportsRendering, agentDetailDeepLink, workspaceRoomsGate, and 15 more
So the harness exists, is configured deliberately, and has 20 precedents. The belief that it doesn't is what routes delete-confirmations and keyboard contracts into regex-only coverage — and once there, the coverage cannot distinguish "written" from "runs".
Worth noting the belief is reasonable to arrive at: environment: 'node' is the default and the opt-in is a comment on line 1 of a spec file. Nothing announces the capability at the point someone is deciding how to test a component.
What closing looks like
Make the capability discoverable at the decision point. A short section in docs/memory/design-system-contract.md (read before any src/frontend/ change) naming the // @vitest-environment jsdom opt-in and pointing at portalThemeSwitch.spec.js as the copyable precedent.
Name the bar in the methodology. The tdd skill and /validate-pr already ask whether a test executes the changed path. Add the specific tell: a spec whose assertions are readFileSync/inspect.getsource/indexOf slices over the implementation proves the code was written. That is acceptable for spelling pins and AST guards, and not acceptable as the only coverage for a predicate that gates a destructive action or a keyboard contract.
Neither ejected PR was careless work — #2756's author built the store-lift pattern to make logic executable and applied it to teardownDefaultSelection one function away from canRemove. The habit survives good engineers paying attention, which is what makes it a process defect rather than a review miss. The near-miss was a fleet-delete confirmation that would have been enabled with nothing selected.
Found by /merge-train on 2026-09-20. Related: #2778, #2756, and the previous train's #2648 / #2645 / #2619 (backend half works, client half inert, suite asserts source text).
The pattern
Two PRs ejected from the 2026-09-20 merge train failed the same way, and three from the previous train failed a near-identical variant. This is one habit, not five bugs, and it is worth fixing once.
The shape: the pure/rules layer gets genuinely good executing tests. The wiring/gate layer gets regex assertions over source text. And the wiring/gate layer is where the safety-critical logic lives.
focusTrap.jsrules (25 tests, mutation-proven)BaseModal.vue— nothing at allSystemTeardownPanel.vuecanRemove,TeardownPreview.vuetoggle()Both are invisible to CI. Concretely:
@keydown, the Esc branch,list[idx].focus(), the focus return and the scroll lock leaves the full frontend suite at 3152 passed, byte-identical.canRemovewith||instead of&&(Remove enabled with zero agents selected, no acknowledgement, a stale preview, unverified membership) and an invertedtoggle()(every tickbox means its opposite) both pass the entire suite — all 36 source-regex tests and all 29 executing store tests. The guard asserts each condition string appears in the expression; it never evaluates it.The part that makes it fixable
The justification is false. #2778 states it in three separate docblocks: "this repo's vitest runs
environment: 'node'with no jsdom/happy-dom and no@vue/test-utils— I checked rather than assumed."On
devtoday:src/frontend/package.json—jsdom ^29.1.1,@vue/test-utils ^2.5.1src/frontend/vitest.config.js:16—plugins: [vue()], present specifically to enable the per-file opt-in, with a comment citing the bug(process): tests that assert source TEXT instead of executing the path — three green-CI ejections in one train, third run running #2829 evidence bar// @vitest-environment jsdom:portalThemeSwitch,portalFailedTurn,portalReportsRendering,agentDetailDeepLink,workspaceRoomsGate, and 15 moreSo the harness exists, is configured deliberately, and has 20 precedents. The belief that it doesn't is what routes delete-confirmations and keyboard contracts into regex-only coverage — and once there, the coverage cannot distinguish "written" from "runs".
Worth noting the belief is reasonable to arrive at:
environment: 'node'is the default and the opt-in is a comment on line 1 of a spec file. Nothing announces the capability at the point someone is deciding how to test a component.What closing looks like
docs/memory/design-system-contract.md(read before anysrc/frontend/change) naming the// @vitest-environment jsdomopt-in and pointing atportalThemeSwitch.spec.jsas the copyable precedent.tddskill and/validate-pralready ask whether a test executes the changed path. Add the specific tell: a spec whose assertions arereadFileSync/inspect.getsource/indexOfslices over the implementation proves the code was written. That is acceptable for spelling pins and AST guards, and not acceptable as the only coverage for a predicate that gates a destructive action or a keyboard contract..vuefile undercomponents/could warrant a warning, given the harness is available. Needs care — the legitimate uses (bug: a 503 from an exhausted credit balance is laundered into an "acceptable skip" across 32 tests #2889's AST call-site guard, thebaseButtonVariantBorderstructure pin) are real and should stay.Why P1
Neither ejected PR was careless work — #2756's author built the store-lift pattern to make logic executable and applied it to
teardownDefaultSelectionone function away fromcanRemove. The habit survives good engineers paying attention, which is what makes it a process defect rather than a review miss. The near-miss was a fleet-delete confirmation that would have been enabled with nothing selected.Found by
/merge-trainon 2026-09-20. Related: #2778, #2756, and the previous train's #2648 / #2645 / #2619 (backend half works, client half inert, suite asserts source text).