Skip to content

feat(oxc): add vendored anti-slop capability and shrink-only baselines - #401

Open
norvalbv wants to merge 1 commit into
codex/sc-1679-oxfmt-devkitfrom
codex/sc-1676-anti-slop-baselines
Open

feat(oxc): add vendored anti-slop capability and shrink-only baselines#401
norvalbv wants to merge 1 commit into
codex/sc-1679-oxfmt-devkitfrom
codex/sc-1676-anti-slop-baselines

Conversation

@norvalbv

Copy link
Copy Markdown
Owner

Closes SC-1676.

Depends on #400. This PR is based on the Oxfmt self-host migration so the overlapping package,
generated-distribution, and toolchain-decision changes are reviewed as one coherent stack. Merge
#400 first; this PR can then be retargeted to main without changing its anti-slop commit.

Summary

  • vendors the complete 15-rule dmmulroy/anti-slop production source at commit
    446268e5d15baa968eaec669ff65358d36ae6259 under its MIT license
  • adds opt-in devkit init --anti-slop installation; it implies Devkit's exact-pinned Oxc
    capability and installs a self-contained @oxlint/plugins@1.78.0 runtime without changing the
    consumer dependency graph
  • composes the namespaced rules through Devkit's managed Oxlint base, leaving the repository's
    ordinary Oxlint config in control of native/custom rules, off/warn/error, rule options, and
    scoped overrides
  • adds explicit create, read-only check, read-only inspect, and shrink-only prune baseline
    operations
  • fails closed unless a bounded runtime sentinel proves the repository root loads the exact managed
    Oxc base and registers the managed plugin; nested configs cannot shadow that proved chain
  • wires init, interactive selection, upgrade offers, doctor repair, clean/removal, help, docs, and
    emitted dist/ assets

Why this boundary

Anti-slop is a direct fit for Oxc's JS-plugin surface, so this PR moves that policy onto the pinned
Oxc runtime. It does not turn this into a broader toolchain migration: Biome remains Devkit's
formatter/linter where selected, ESLint remains responsible for existing cross-file/filesystem
topology plugins, and tsc --noEmit remains the type checker. The updated
oxc-toolchain-migration decision note records that boundary so later work can change it only with
its own parity and performance evidence.

Baseline and configuration contract

  • all rules default to error and are namespaced as anti-slop/<rule>
  • .anti-slop-baseline.json has no timestamp and is sorted deterministically
  • fingerprints are SHA-256 over rule ID, POSIX repository-relative path, normalized diagnostic,
    and normalized reported source line; absolute checkout paths and line numbers are excluded
  • identical findings carry counts, so an added third instance above a baselined count of two is new
  • normal checks never write; new errors fail while new warnings remain visible but non-blocking
  • create refuses to replace an existing baseline without explicit --force
  • prune can only remove absent debt or reduce counts, refuses new errors, and preserves all
    baseline entries outside a requested path scope
  • paths must be literal existing files/directories inside the repository; external/missing paths are
    rejected
  • baseline scans disable nested config discovery and use the repository root's overrides for
    scoped policy; managed/agent directories are excluded from adoption debt
  • devkit clean removes only managed plugin state and deliberately retains the consumer's baseline

Packaging and provenance

The upstream production tree is byte-for-byte unchanged. A digest regression test pins its 19-file
tree, the build emits JavaScript under dist/anti-slop, and the installer copies the plugin API to
the capability-specific, trackable plugin/oxlint-plugins-api/ path. The installed copy uses a
package import map, so consumers need no direct dependency and common node_modules / vendor
ignores cannot omit runtime bytes. The managed manifest records upstream commit, plugin API version,
complete rule registry, and plugin/config/probe digests. Doctor and baseline operations verify
provenance, exact Oxc-base bytes, plugin completeness, and runtime composition. Replacement is
lock-serialized and rollback-safe; interrupted init is recovered from on-disk manifests on retry.

Evidence

  • bun run format
  • bun run typecheck
  • bun run lint
  • bun run lint:structure
  • bun run build
  • focused anti-slop/Oxc/init/clean suite: 110/110 passed across 9 files
  • packed anti-slop capability E2E: 6/6 passed, including all 15 diagnostics; deterministic baselines across
    two checkout roots; missing baseline; create/check/new violation/fix; warning/off/scoped
    overrides; nested-config isolation; full-chain fail-closed behavior; interrupted-init recovery;
    path-scoped prune; doctor; clean with baseline retention; and package-mode git add/commit/clone
    with both node_modules and vendor/ ignored, followed by doctor/check without reinstalling
  • packed Oxc lifecycle E2E: 1/1 passed against the composed managed base
  • full repository suite: 3,834 passed, 5 skipped; 219 files passed and 1 skipped (220 total)
  • vendored source compared byte-for-byte with the pinned upstream checkout
  • generated package verified to include compiled plugin/lifecycle assets and no raw TypeScript plugin
    files
  • correctness review passed all four lenses after adversarial repros covering config comments,
    direct-fragment composition, nested shadowing, managed-base drift, concurrent replacement,
    interrupted install/clean, scoped check/prune, symlinks, and ignored delivery layouts; the final
    ship review additionally caught and fixed scoped create --force baseline replacement, with an
    E2E proving out-of-scope debt is preserved. A second review cycle caught stale filesystem-derived
    anti-slop activation and a non-exercising runtime sentinel; the Oxc manifest now records the
    selected integration explicitly, every init/doctor/install/remove caller supplies it, and the
    sentinel must observe an actual managed-rule diagnostic while ordinary lint suppresses the
    intentional probe through a nested managed config. A third cycle moved the paired anti-slop
    removal/Oxc rewrite under one lock; it now proves the base can be unwired before deleting plugin
    bytes, with lock-held and runtime-failure preservation regressions.
  • final GitNexus change detection found the expected selection/init/upgrade/clean execution flows;
    the shared defaultSelection hub makes the graph risk high, and its direct dependents plus the full
    suite were validated

Runtime sanity sample

This is not a replacement for the earlier Frink-scale migration benchmark. On an Apple M4 / 24 GiB
Mac, Node 22.20.0, and Oxlint 1.78.0, the final sentinel-inclusive wrapper over a copied Devkit
authored-code surface (cli/ plus gate-engine/) produced a deterministic baseline of 1,613
findings / 1,486 fingerprints in 0.65 s wall with 223 MB maximum RSS. Seven subsequent
baseline-aware checks had a 0.60 s median wall time and 187 MB median maximum RSS
(/usr/bin/time -l); the baseline SHA-256 remained
ac7fb9b2119c035d795f8f3448289170c1c5069b9af00b0b3870b8f22c45941d. This bounds the final
wrapper/adoption overhead; the saved Frink benchmark/decision evidence remains the source for
cross-tool migration claims.

Known limits

  • Oxc's JS-plugin API remains alpha, so the exact Oxlint/plugin API pins and packed all-rule fixture
    are the compatibility boundary for upgrades.
  • These rules are syntax/scope based and do not replace TypeScript checking.
  • A consumer root Oxlint config must retain ./.devkit/oxc/oxlint.base.json in its extends chain;
    doctor reports/repairs managed-side drift, while a consumer-owned missing root pointer requires an
    explicit config edit.
  • Baseline operations intentionally disable nested config discovery; use root-level Oxlint
    overrides for path-specific anti-slop policy.
  • Identical findings within one file are fungible counted debt units. Fixing one while adding an
    indistinguishable occurrence keeps that fingerprint's count flat; this is intentional so
    unrelated line shifts do not explode an adopted repository's baseline. The ship gate's
    count-offset finding is waived with this explicit non-growth rationale.

Closes SC-1676.

Depends on #400. This PR is based on the Oxfmt self-host migration so the overlapping package,
generated-distribution, and toolchain-decision changes are reviewed as one coherent stack. Merge
#400 first; this PR can then be retargeted to `main` without changing its anti-slop commit.

## Summary

- vendors the complete 15-rule `dmmulroy/anti-slop` production source at commit
  `446268e5d15baa968eaec669ff65358d36ae6259` under its MIT license
- adds opt-in `devkit init --anti-slop` installation; it implies Devkit's exact-pinned Oxc
  capability and installs a self-contained `@oxlint/plugins@1.78.0` runtime without changing the
  consumer dependency graph
- composes the namespaced rules through Devkit's managed Oxlint base, leaving the repository's
  ordinary Oxlint config in control of native/custom rules, `off`/`warn`/`error`, rule options, and
  scoped overrides
- adds explicit `create`, read-only `check`, read-only `inspect`, and shrink-only `prune` baseline
  operations
- fails closed unless a bounded runtime sentinel proves the repository root loads the exact managed
  Oxc base and registers the managed plugin; nested configs cannot shadow that proved chain
- wires init, interactive selection, upgrade offers, doctor repair, clean/removal, help, docs, and
  emitted `dist/` assets

## Why this boundary

Anti-slop is a direct fit for Oxc's JS-plugin surface, so this PR moves that policy onto the pinned
Oxc runtime. It does not turn this into a broader toolchain migration: Biome remains Devkit's
formatter/linter where selected, ESLint remains responsible for existing cross-file/filesystem
topology plugins, and `tsc --noEmit` remains the type checker. The updated
`oxc-toolchain-migration` decision note records that boundary so later work can change it only with
its own parity and performance evidence.

## Baseline and configuration contract

- all rules default to `error` and are namespaced as `anti-slop/<rule>`
- `.anti-slop-baseline.json` has no timestamp and is sorted deterministically
- fingerprints are SHA-256 over rule ID, POSIX repository-relative path, normalized diagnostic,
  and normalized reported source line; absolute checkout paths and line numbers are excluded
- identical findings carry counts, so an added third instance above a baselined count of two is new
- normal checks never write; new errors fail while new warnings remain visible but non-blocking
- create refuses to replace an existing baseline without explicit `--force`
- prune can only remove absent debt or reduce counts, refuses new errors, and preserves all
  baseline entries outside a requested path scope
- paths must be literal existing files/directories inside the repository; external/missing paths are
  rejected
- baseline scans disable nested config discovery and use the repository root's `overrides` for
  scoped policy; managed/agent directories are excluded from adoption debt
- `devkit clean` removes only managed plugin state and deliberately retains the consumer's baseline

## Packaging and provenance

The upstream production tree is byte-for-byte unchanged. A digest regression test pins its 19-file
tree, the build emits JavaScript under `dist/anti-slop`, and the installer copies the plugin API to
the capability-specific, trackable `plugin/oxlint-plugins-api/` path. The installed copy uses a
package import map, so consumers need no direct dependency and common `node_modules` / `vendor`
ignores cannot omit runtime bytes. The managed manifest records upstream commit, plugin API version,
complete rule registry, and plugin/config/probe digests. Doctor and baseline operations verify
provenance, exact Oxc-base bytes, plugin completeness, and runtime composition. Replacement is
lock-serialized and rollback-safe; interrupted init is recovered from on-disk manifests on retry.

## Evidence

- `bun run format`
- `bun run typecheck`
- `bun run lint`
- `bun run lint:structure`
- `bun run build`
- focused anti-slop/Oxc/init/clean suite: 110/110 passed across 9 files
- packed anti-slop capability E2E: 6/6 passed, including all 15 diagnostics; deterministic baselines across
  two checkout roots; missing baseline; create/check/new violation/fix; warning/off/scoped
  overrides; nested-config isolation; full-chain fail-closed behavior; interrupted-init recovery;
  path-scoped prune; doctor; clean with baseline retention; and package-mode git add/commit/clone
  with both `node_modules` and `vendor/` ignored, followed by doctor/check without reinstalling
- packed Oxc lifecycle E2E: 1/1 passed against the composed managed base
- full repository suite: 3,834 passed, 5 skipped; 219 files passed and 1 skipped (220 total)
- vendored source compared byte-for-byte with the pinned upstream checkout
- generated package verified to include compiled plugin/lifecycle assets and no raw TypeScript plugin
  files
- correctness review passed all four lenses after adversarial repros covering config comments,
  direct-fragment composition, nested shadowing, managed-base drift, concurrent replacement,
  interrupted install/clean, scoped check/prune, symlinks, and ignored delivery layouts; the final
  ship review additionally caught and fixed scoped `create --force` baseline replacement, with an
  E2E proving out-of-scope debt is preserved. A second review cycle caught stale filesystem-derived
  anti-slop activation and a non-exercising runtime sentinel; the Oxc manifest now records the
  selected integration explicitly, every init/doctor/install/remove caller supplies it, and the
  sentinel must observe an actual managed-rule diagnostic while ordinary lint suppresses the
  intentional probe through a nested managed config. A third cycle moved the paired anti-slop
  removal/Oxc rewrite under one lock; it now proves the base can be unwired before deleting plugin
  bytes, with lock-held and runtime-failure preservation regressions.
- final GitNexus change detection found the expected selection/init/upgrade/clean execution flows;
  the shared `defaultSelection` hub makes the graph risk high, and its direct dependents plus the full
  suite were validated

## Runtime sanity sample

This is not a replacement for the earlier Frink-scale migration benchmark. On an Apple M4 / 24 GiB
Mac, Node 22.20.0, and Oxlint 1.78.0, the final sentinel-inclusive wrapper over a copied Devkit
authored-code surface (`cli/` plus `gate-engine/`) produced a deterministic baseline of 1,613
findings / 1,486 fingerprints in 0.65 s wall with 223 MB maximum RSS. Seven subsequent
baseline-aware checks had a 0.60 s median wall time and 187 MB median maximum RSS
(`/usr/bin/time -l`); the baseline SHA-256 remained
`ac7fb9b2119c035d795f8f3448289170c1c5069b9af00b0b3870b8f22c45941d`. This bounds the final
wrapper/adoption overhead; the saved Frink benchmark/decision evidence remains the source for
cross-tool migration claims.

## Known limits

- Oxc's JS-plugin API remains alpha, so the exact Oxlint/plugin API pins and packed all-rule fixture
  are the compatibility boundary for upgrades.
- These rules are syntax/scope based and do not replace TypeScript checking.
- A consumer root Oxlint config must retain `./.devkit/oxc/oxlint.base.json` in its extends chain;
  doctor reports/repairs managed-side drift, while a consumer-owned missing root pointer requires an
  explicit config edit.
- Baseline operations intentionally disable nested config discovery; use root-level Oxlint
  `overrides` for path-specific anti-slop policy.
- Identical findings within one file are fungible counted debt units. Fixing one while adding an
  indistinguishable occurrence keeps that fingerprint's count flat; this is intentional so
  unrelated line shifts do not explode an adopted repository's baseline. The ship gate's
  count-offset finding is waived with this explicit non-growth rationale.
@coderabbitai

coderabbitai Bot commented Aug 16, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: da6914d1-a1bd-4210-bea1-d7c66c2449a8

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant