feat(oxc): add vendored anti-slop capability and shrink-only baselines - #401
Open
norvalbv wants to merge 1 commit into
Open
feat(oxc): add vendored anti-slop capability and shrink-only baselines#401norvalbv wants to merge 1 commit into
norvalbv wants to merge 1 commit into
Conversation
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.
Contributor
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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. Comment |
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.
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
mainwithout changing its anti-slop commit.Summary
dmmulroy/anti-slopproduction source at commit446268e5d15baa968eaec669ff65358d36ae6259under its MIT licensedevkit init --anti-slopinstallation; it implies Devkit's exact-pinned Oxccapability and installs a self-contained
@oxlint/plugins@1.78.0runtime without changing theconsumer dependency graph
ordinary Oxlint config in control of native/custom rules,
off/warn/error, rule options, andscoped overrides
create, read-onlycheck, read-onlyinspect, and shrink-onlyprunebaselineoperations
Oxc base and registers the managed plugin; nested configs cannot shadow that proved chain
emitted
dist/assetsWhy 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 --noEmitremains the type checker. The updatedoxc-toolchain-migrationdecision note records that boundary so later work can change it only withits own parity and performance evidence.
Baseline and configuration contract
errorand are namespaced asanti-slop/<rule>.anti-slop-baseline.jsonhas no timestamp and is sorted deterministicallyand normalized reported source line; absolute checkout paths and line numbers are excluded
--forcebaseline entries outside a requested path scope
rejected
overridesforscoped policy; managed/agent directories are excluded from adoption debt
devkit cleanremoves only managed plugin state and deliberately retains the consumer's baselinePackaging 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 tothe capability-specific, trackable
plugin/oxlint-plugins-api/path. The installed copy uses apackage import map, so consumers need no direct dependency and common
node_modules/vendorignores 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 formatbun run typecheckbun run lintbun run lint:structurebun run buildtwo 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_modulesandvendor/ignored, followed by doctor/check without reinstallingfiles
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 --forcebaseline replacement, with anE2E 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.
the shared
defaultSelectionhub makes the graph risk high, and its direct dependents plus the fullsuite 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/plusgate-engine/) produced a deterministic baseline of 1,613findings / 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 remainedac7fb9b2119c035d795f8f3448289170c1c5069b9af00b0b3870b8f22c45941d. This bounds the finalwrapper/adoption overhead; the saved Frink benchmark/decision evidence remains the source for
cross-tool migration claims.
Known limits
are the compatibility boundary for upgrades.
./.devkit/oxc/oxlint.base.jsonin its extends chain;doctor reports/repairs managed-side drift, while a consumer-owned missing root pointer requires an
explicit config edit.
overridesfor path-specific anti-slop policy.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.