CodeEraser is an open-source tool that catches duplicate code and documentation at the moment an AI coding assistant writes it, before it hits disk. Built in Rust with a Haskell judgment core, it targets a specific problem: as teams increasingly rely on LLM-assisted coding, codebases accumulate redundant functions, repeated paragraphs, and files that only ever grow. CodeEraser tries to stop that drift at the source rather than cleaning it up after the fact.

How It Catches Duplication at Write Time

The system works by normalizing every file's tokens (identifiers become ID, literals become LIT, comments are dropped) and fingerprinting them with k=25, w=26 shingles. Any shared run of 50 or more tokens produces a shared fingerprint stored in a SQLite WAL index maintained by a per-project daemon. When an AI coding tool proposes a write, the PreToolUse probe checks it against existing content in 48ms at the median. Two refusals happen before content reaches disk: one for exact T1/T2 clones that the replaced content didn't already carry, and one for files that would exceed a 750-line hard limit or the limit declared in the project's rules.

The tool subtracts matches the replaced content already carried, so refactoring or moving code doesn't trigger false positives. On a live-stream reading, the system misfired on none of 719 production probes.

Layers Beyond the Hot Path

Beyond the fast T1/T2 check, CodeEraser has a cold T3 path that uses structural fingerprints and MinHash/LSH (128 permutations, 32 bands) to generate candidates, then computes Zhang-Shasha tree edit distance in exact integer arithmetic. A separate documentation duplication layer uses NFC-normalized words, 5-word shingles, and Jaccard similarity with an exact rational threshold of 0.80 or a 50-word verbatim run.

The tool also tracks dead code and unreferenced declarations through a per-language resolution ladder that maps imports, re-exports, doc links, and package roots into a graph. It computes strongly connected components and reachability, then issues four-way verdicts on whether code is unreferenced or unreachable. A mention universe built from every identifier across all text files (stored as fnv1a64 hashes) produces an unmentioned declaration advisory. These are always advisory, never blocking.

Same-Role Advice From the Repository Itself

One of the more interesting features is a same-role advisor that uses the repository's own index as term bags (names, shapes, callees, docs, structure, literals) scored with integer BM25. It identifies the units most similar to a given unit and returns them in a single exact order, with a role bit that holds only when the name, callee, and shape channels agree. The --widen flag adds an in-repo PPMI associative view. The system never produces a blocking verdict or exit code; it is purely advisory.

Structure as a Measured Thing

CodeEraser scores structural quality across eight axes: geometry, naming diversity, mixing, misplacement, documentation coverage, stale docs, redundancy, and modularity. It uses Tsallis-2 entropy per directory and chi-squared divergence from a declared layout. A split-ROI pricing model estimates the cost of reorganizing files using four cost legs (crossing references, clone cuts, churn crossings, a new-file penalty). The check score itself is designed so that moving lines around cannot game it, using violation mass over opportunity on each axis.

The Demo Results

In a controlled demo using a scripted agent on a small Python and TypeScript invoicing service, CodeEraser blocked two writes that would have introduced duplicate helpers and refused a Stop audit turn that would have left duplicate blocks behind. Without the tool, the same task produced four duplicate clone blocks, one duplicated doc segment, and a lower check score (871 versus 979 with CodeEraser active). The tool ships as a CLI, a GUI with eleven screens, a Claude Code plugin with three hooks and sixteen read-only MCP tools, and integrations with pre-commit and CI. Installers are available through Homebrew, winget, and direct download.