When my first dead-export script ran against a 3,300-file TypeScript/React/Python monorepo, it reported 2,266 dead exports. That number was completely wrong.
I had matched import { symbol } across files, which missed 1,722 symbols referenced via namespace imports (ns.helper()), JSX tags (<Widget />), or internal same-file calls, plus 648 framework entrypoint exports (index.ts, page.tsx, route.ts, sst.config.ts) and 270 barrel re-exports (export * from). And when I hashed every function body to find clones, 4,559 2-line getters and trivial wrappers collided across unrelated files.
After filtering out < 25 normalized-token functions (CLS008), framework entrypoints (CLS009), and separating same-file internal callers (CLS006) from zero-caller orphans (CLS005), I ran the corrected analyzer across all 3,300 files (4,544 non-trivial functions) and 153 local Claude Code (~/.claude/projects/**/*.jsonl) and Codex CLI (~/.codex/sessions/**/*.jsonl) transcripts.
What the 3,300-File + 153-Transcript Audit Found
- 39.0% Blind Function Additions in Agent Sessions (
CLS010/CLS011): Across153Claude Code and Codex sessions (1,813deduplicated tool calls),23of59new function definitions (39.0%) and59of132file write/patch calls (44.7%) were executed before the agent ran a singleGrep,Glob, orrgsearch in that session. - 117 Exact Structural Function Clone Groups (
CLS001/CLS002): Using Type-2 token normalization (stripping comments, collapsing strings to"STR", numbers toNUM, and non-keyword identifiers toIDon functions>= 25tokens), we found19multi-file exact clone clusters (>= 3copies) and98pairwise structural clones (2copies).-
DataWordmarkwas copy-pasted7times acrossflash.tsx,june.tsx,minimax.tsx,novel.tsx,sheep.tsx,video.tsx, andstats-shell.tsx. -
getReviewCommentContext,getUserPrompt, andsubscribeSessionEventswere duplicated acrossindex.tsandgithub.handler.ts.
-
- 370 Cross-File Duplicate Helper Names (
CLS004):370non-trivial function names (>= 25tokens) were re-implemented in 2 or more separate files (summarizein 3 files,chatin 2 files). - 163 Truly Dead Zero-Caller Orphan Exports (
CLS005) vs 381 Internal-Only Over-Exports (CLS006):381functions were exported withexporteven though they were only called inside their defining file (stripeWebhook,lakeVpc,isStableSessionSwitch), while163exported functions had0cross-file references and0internal calls (startVisualStabilityProbe,stopVisualStabilityProbe,runVisualStabilityScenario).
The Three False-Positive Traps We Fixed
- Whole-Repo Identifier Indexing (
1,722false positives eliminated): Instead of greppingimport { foo },clonesievebuilds a per-file identifier token frequency map across the repository and compares external file hits against same-file occurrences. - Entrypoint & Framework Convention Exclusions (
648entrypoints +270barrels skipped):CLS009excludesindex.*,main.*,cli.*, Next.js conventions (page.tsx,layout.tsx,route.ts,GET,POST,metadata,generateStaticParams), config files, andexport * frombarrels. - 25-Token Structural Floor (
4,559trivial getters skipped):CLS008requires at least25normalized tokens before running exact skeleton hashing or 4-gram Jaccard shingle comparison (CLS003).
Running clonesieve on Your Repo
I published clonesieve (v0.1.0, zero dependencies, MIT licensed) so you can run the 14-rule audit (CLS001 to CLS014) on your repository and generate a Canonical Helper Registry table for CLAUDE.md:
# Audit your repository for structural clones, duplicate helper names, and dead exports npx clonesieve . What rules or CLAUDE.md indexing tricks have worked best for you to keep agents from writing a 4th copy of existing helpers?

