The rule rejects `vi.mock` / `vi.doMock` / `vi.unstable_mockModule` and the
`jest` equivalents, on the argument that a test which rewrites the module graph
asserts against a stand-in the production code never sees. It is already off for
`**/*.test.{ts,tsx}`, `**/*.spec.{ts,tsx}`, `tests/**` and `**/__mocks__/**` via
the existing override in config/oxlint-anti-slop.json; that override is
unchanged here. What the rule actually catches is module mocking that has drifted
out of a spec and into a first-party `.ts` support module, where nothing marks it
as test-only.
73 violations at baseline, all of them in test-support code. 9 were relocated
back into spec files the override already exempts; the remaining 64 sit in 10
files that are test-only but do not match the override globs, and carry a
file-level disable naming the rule and the reason.
Relocated:
- terminal-hydration-store-test-bootstrap.ts: the sonner / sync-runtime-graph /
pty-transport `vi.mock` calls moved into the two specs that import it
(terminals-hydration-canonical-rows, terminals-hydration-canonical-pty-overlap).
Vitest hoists `vi.mock` inside a test file, so registration is strictly earlier
than the previous module-eval-time call; the bootstrap keeps only the preload
API proxy. Both importers were updated.
- ipc-events-ssh-authority-test-fixtures.ts: the 6 direct-ssh `vi.doMock` calls
moved into useIpcEvents-agent-status-ssh-authority.test.ts as a local
`stubDirectSshModules()` helper, which also de-duplicates the three copies the
spec already had inline. The fixture now returns the store state and coordinator
doubles it builds, typed via the exported DirectSshReconnectCoordinatorDouble.
Suppressed, with justification (each is `/* oxlint-disable
anti-slop/no-module-mocking -- ... */`, rule named, no blanket disable):
- config/scripts/headless-serve-shutdown-matrix.test.mjs (1) - a genuine Vitest
spec that the override misses only because its globs say {ts,tsx}. The script
under test is a top-level CLI module; the alternative is spawning real docker.
- src/main/codex-accounts/runtime-home-service-test-harness.ts (1) - stubs one
probe predicate in ../pty/shell-startup-env, imported directly by several
main-process readers; 17 specs share it.
- src/main/computer/desktop-script-provider-test-harness.ts (2) - stubs
child_process/fs-promises for a provider that shells out; 8 specs share it.
- src/main/github/work-item-search-test-harness.ts (4) - one consumer lives in
tests/e2e, where the relative mock ids resolve differently, so moving the calls
into the specs would silently stop mocking there.
- src/renderer/src/components/automations/automations-page-test-harness.tsx (14)
- the mount rig for 10 AutomationsPage specs.
- src/renderer/src/components/terminal-pane/remote-runtime-pty-transport-test-harness.ts
(1) - stubs refreshWebRuntimeSessionTabsSnapshot, imported directly by several
renderer runtime modules; 18 specs share it.
- src/renderer/src/hooks/ipc-events-agent-status-window-test-fixtures.ts (7) -
stubReactSyncEffect/stubAuxiliaryModules, shared by 11 specs.
- src/renderer/src/hooks/ipc-events-close-routing-test-harness.ts (11) - stubs
and hook invocation are one unit; 4 specs share it.
- src/renderer/src/hooks/ipc-events-terminal-create-test-harness.ts (13) - its
only spec is at 799 of an 800 max-lines budget.
- src/renderer/src/hooks/ipc-events-test-harness.ts (10) - shared by 8 specs.
No violation was converted to real dependency injection, and no max-lines disable
was added.
Verified: the audit command exits 0 with no output (and reports errors on a
planted probe, so the rule is live); node config/scripts/run-typecheck-projects-in-parallel.mjs
exits 0; 354 spec files / 2506 tests covering every importer of every touched
file pass. No mobile/ file was touched.
The changed-code quality gate's root Oxlint scan runs without --config so it never
loads the anti-slop JS plugin, which made all 10 of those file-level suppressions
read as "Unused oxlint-disable directive". check-changed-code-quality.mjs now
exempts directives naming an anti-slop rule from that unused-directive warning,
the same carve-out isCastingDirectiveUnusedWarning already makes for the casting
suppressions the casting config enforces. Such a directive can never suppress a
root-config rule, so nothing the root scan would otherwise report is hidden;
audit:anti-slop remains the scan that enforces the rule.
Phase 6 of the relay split: the relay's deploy/operate surface moves under cloud/ with 24 cloud-* workflows gated on ORCA_CLOUD_OPERATIONS_ENABLED, the Cloud SQL rollout lease action, the relay Terraform root (dual-accept identities for both repositories), scripts, docs, CODEOWNERS, and a terraform validate job in Cloud Verify.
A diagnostic's span often reaches past the block a split moved — most commonly
to a hook dependency array, which legitimately grows when closure variables
become props. Requiring every line of the span to match contiguously reported
the moved body as new.
The block must still start at the same line in the base and appear in order,
and >=90% of it must be present. Genuinely new code shares neither the anchor
nor the ordering.
A file-splitting refactor makes every line of the new module an added line, so
pre-existing lint debt in code that merely moved starts failing the gate. The
only way to satisfy it is to edit the moved code, which is what a
behavior-preserving refactor must not do. Exempt a diagnostic when its
highlighted lines already existed verbatim and contiguous in the base revision.