LLMs write code that accretes: duplicated blocks, dead files, stale docs, structural sprawl. CodeEraser measures it, judges it, and gates it with a score that is only allowed to get better.
$ ce check --roast check score 925/1000 | axes 0:61 1:0 2:297 3:0 4:0 5:0 6:171 | 595 candidates ratchet: 0 added, 0 removed, 0 over, 0 tolerance drawn -> pass note: 10 blocks collapsed into existing members, 335 intra-file pairs off the sim table roast: suspiciously clean. who did you pay?
Real output: CodeEraser on its own repository; violations are banked, new entropy fails the gate.
| Without CodeEraser | With CodeEraser | |
|---|---|---|
| writes refused before they reached disk | 0 | 2 |
| duplicate clone blocks left behind | 4 | 0 |
| duplicated doc segments | 1 | 0 |
| removals still owed | 1 | 0 |
| check score | 871 | 979 |
One seven-step task, two identical copies of the seed; the only variable is whether CodeEraser is in the loop — the write-time guard, the Stop audit, and, once the audit refuses, the eraser acting on its own plan. Both runs still end red — not on the same things.
The seed, demo/seed/: a cent-exact Python and TypeScript invoicing service, clean by the same gates before either run; the task adds discounts, a compact report, CSV/JSON output and money formatting.



ce join prints.The gate: one 0–1000 score over seven axes, a shrink-only ratchet against the banked baseline, and a hard floor for CI.
05 · scoring and ratchetT1/T2 clones by winnowing fingerprints, under a clone-block budget that only ratchets down.
01 · T1/T2 clonesT3 near-clones, renamed and reshaped copies included, judged by tree edit distance in the Haskell core.
02 · T3 near-miss clonesLiveness on the cached reference graph: no kept in-edge and no entry flag means dead; an unmentioned-declaration advisory beside it never reddens a gate.
06 · dead codeDuplicated prose across docs and comments, judged by exact Jaccard over live segments.
03 · documentation duplicationTree-scale entropy over the whole repository: layout divergence, doc staleness, redundancy and modularity axes.
04 · structure judgmentSize, complexity and readability per file and function, core-graded against the global table or the file's own [[rules.class]] lines.
Your score across mainline history, cached per commit, rebuildable, honest about direction.
10 · trend slopeDeterministic and two-phase: dead files, verbatim doc twins and whole-unit exact clones, planned first, applied only from a clean worktree, never by a model.
12 · deterministic eraseChange heat over a git window, per unit: how much of a file is being rewritten rather than added to.
07 · three-signal joinChurn, duplication and liveness folded into one verdict, so a hot, duplicated, dead corner names itself.
07 · three-signal joinThe same-role advisor: offline integer BM25 over the index's term bags, the core deciding which candidates play the query's role. Advice only.
15 · sparse retrievalDatalog over the index’s own facts, judged in the core, every answer with its derivation; written as assertions, architecture constraints make ce rules a gate that exits on the first violation.
Dead code inside one function (unreached statements, unread stores and locals) on the core's control-flow graph; a verdict only where the language's blind precision exam passed, unused parameters always advice.
17 · intra-function dead codeHow a clone group folds into one function: differences become parameters; the core answers the parameter count, the member to keep, the lines saved, and feasible or why not. Advice only.
18 · clone merge suggestionsHow directories depend on each other: layers, the cheapest cycle cuts, file clusters and files outside their cluster's directory, fan-in, fan-out, instability, and what a change to a named file reaches. Advice only.
19 · architecture analysisAs a Claude Code plugin: duplicate writes stopped as they are written, a write let through at ask recorded once it lands, audits at stop, health at session start.
11 · guard tier ladderInteger or exact-rational arithmetic over measured facts; every rule cites its implementing line.
t = window + kgram - 1 = 26 + 25 - 1 = 50 tokens
cloneDecidesWith (num, den) t n1 n2 = (mx - t) * den >= num * mx where mx = max n1 n2score = max 0 (scoreScale - raw `div` (violCostNeutral * wTotal)) tolerated(c) = max (c * tolNum `div` tolDen) (c + tolAbs)
50 ms907 ms650 ms0.00 per 500 edits17/17 scoped (100%)Every number is produced by replay (cli/tests/it/bench.rs and bench_backfill.rs) from one source, contracts/bench/bench.json — never hand-filled.
Complete evaluation dashboard →
docs/diagrams/architecture.en.json; every component cites its source files. Open the full-size SVG.The component-level stack and its enforcement map →
GitHub Releases: GUI + CLI + judgment core, SHA256-pinnedbrew install skymanbp/codeeraser/codeerasercargo install codeeraserce setup # by hand: /plugin marketplace add skymanbp/CodeEraser@release, then /plugin install codeeraser@codeeraserce update --yesFive platforms: x86_64-windows · x86_64-linux · aarch64-macos · x86_64-macos · aarch64-linux. The Windows installer runs ce setup; AppImage and dmg users run it once. The Homebrew formula (macOS and Linux) comes from the same pins.
ce update compares the latest tag with this build (exit 0 / 1 / 2); --yes swaps ce and ce-core only after both SHA256 pins verify, never a copy the plugin or cargo owns (they name their own update); --installer saves the verified GUI installer. The GUI has its own update screen; in Claude Code, /codeeraser:update.
ce check . --fail-under 911 # ratchet + floor; exit 1 turns the pipeline redce precommit # staged net LOC + touched duplicatesce mcp # every report family as a read-only tool for any agentAll fifteen release binaries (five platforms × ce / ce-core, plus the five GUI installers) are SHA256-pinned in plugin/bin/manifest.env: the hash chain, not code signing, is the anchor (how a release is cut).