SuperAPI AI Directory

subtraction-audit

Coding & development

View repository

Updated 10-15 22:14

About this skill

Subtraction Audit · Subtraction Audit

The history of a single AI conversation is a history of corruption: AI writes code too easily, too bloatedly, too prone to divergence; whether written by humans or machines, code will eventually corrupt. This methodology turns "anti-corruption" into a repeatable process:Evidence-driven subtraction audit + risk-tiered execution + machine gates。

Core Principles (read first, never skip)

  1. Gates > Prose: conventions must become executable checks (non-zero exit code means failure), otherwise Agents will not comply. AI's compliance with enforced gates is far higher than with prose-style conventions.
  2. Tests are not truth: tests pin down current behavior, not correct behavior—behavior may be the product of historical compromises. A test must be able to fail for the mechanism you report, otherwise it is lying.
  3. Deletion is a first-class citizen: simplification is a routine workflow, not a spring cleaning. Zero deleted lines per month = corruption alarm.
  4. Decisions must be written down: every non-trivial deletion gets a decision record (Problem / Evidence / Cost / Rollback Conditions).
  5. Evidence first: candidates without consumption evidence are never reported. "Looks useless" is not evidence; rg is.

When to use

  • The user wants to "clean up the repository", "find dead code", "can these be deleted"
  • The user is worried that AI-written code is bloated/divergent/unmaintainable
  • The user wants to set up quality gates for a repository (especially one primarily developed by AI)

Workflow

Phase 0 · Understand the architecture first (most important, most prone to failure)

Before claiming anything is "dead", answer these first—skipping this step is equivalent to building your report on a foundation:

  • Where are the entry points? How are routes/endpoints mounted? (static import / dynamic require / framework auto-discovery such as Next.js pages / string paths)
  • Is there asame-named live file? (Example:routes/agent/feedback.ts is suspected dead, but routes/feedback.ts is live and mounted at /api/feedback—two different files)
  • How do build/deploy describe it? (docker-compose, deploy manifest, runbook, README claims vs reality)
  • Is there anything that looks like a "placeholder/skeleton" but is actuallyproduction core? (Small packages may be queue consumers, workers, schedulers)
  • Are environment variables/config knobs referenced externally (.env.example, deployment platform env, container orchestration)
  • Are database tables / queues / event names referenced by strings

Counterexample lesson (real incident): a 101-line "worker skeleton" was actually a production-required DB queue consumer (polling the generation_tasks table). It not being in the deploy manifest ≠ it is dispensable—that may beconfiguration drift, it may even mean the production queue has stalled. Do not treat "not in the deploy config" as "not needed".

Phase 1 · Baseline measurement

  1. Dead code baseline:npx knip --reporter json(unused exports / types / files / dependencies / duplicate implementations / binaries)
  2. Repository hygiene: mistakenly committed files (whose commit message does not match the contents),.gitignore coverage, whether.env is tracked (a security item, must be checked), committed large artifacts/tool output, empty directories, dead gates (scripts that exist but are not wired into CI/hooks)
  3. CI/hook inventory:.github/, what husky pre-commit actually runs; whether lint/test/typecheck are executed by any automated process.Zero CI is the root cause of accumulated rot, and should be listed separately as a systemic issue
  4. Record the baseline numbers — every subsequent cleanup should bring them down; they may only go down, never up

Phase 2 · Domain-parallel investigation

Dispatch parallel subagents by domain (api / web / worker / shared / root and scripts), with the same methodological prompt for each domain:

  • Investigation categories: ① Dead code (zero production references; test-only references count too; annotate the evidence) ② Duplicate representations (two mirrors of the same fact: two objects mirroring the same set of fields, hand-written types coexisting with generated types) ③ Hand-rolled vs mature dependencies (protocol parsing/retry/glob/diff/throttling — replaceable by mature npm packages or Node built-ins) ④ Speculative generalization (config knobs with no owner, placeholder services, large commented-out blocks, unused APIs maintained only to be protected by tests) ⑤ Dead dependencies (present in package.json, zero imports in source)
  • Iron rule: for every candidate, first search the entire repository for consumers,distinguishing production / test / documentationthree types of consumption; report nothing without evidence; at the end you must provide an "intentionally excluded" list (those verified as live/intentionally retained)

Phase 3 · High-risk review (mandatory before deletion)

Add a review pass for every candidate, especially api/web routes and public exports:

  • rg across the entire repository,including dynamic references and string paths(import.meta.glob、require(、.route("字符串"))
  • Live file with the same namecheck (see the Phase 0 lesson)
  • Framework auto-discoverycheck (Next.js pages/API routes are auto-registered by the framework — knip will produce false positives here; confirm whether the app uses framework routing or explicit routing such as React Router)
  • Deployment/documentation reference check (deploy manifest, runbook, env)
  • Whether a test pins down that it does not exist (e.g. doesNotMatch(/<Component/) assertions) — that is supporting evidence for deletion

Phase 4 · Risk classification

Level Meaning Action
🟢 Green Evidence loop closed (zero production + test + documentation consumption, no same-name/dynamic/framework references) Safe to delete
🟡 Yellow Confirm before deleting (is there a runtime parse? Does the local implementation have its own copy? Does merging require a smoke test?) Check first, then delete
🔴 Red Requires a product decision (are both implementation paths alive? Which one does production depend on? Is deployment affected?) Separate work item; ask a human

Phase 5 · Batch execution

  • Each batch = one category of candidates (hygiene → dead files → dead exports → duplicate merging → dead dependencies); do not mix batches
  • One decision record per batch (DECISIONS.md: Problem / Evidence / Cost / Rollback condition)
  • Run verification after each batch:tsc --noEmit(full package, not checking only half) + lint + knip baseline does not rise
  • Changes involving production components (queue consumers, workers, deployment-related, env knobs) must be smoke-tested after modification

Phase 6 · System fixes (more important than deleting code)

  • Zero CI is the root cause: build minimal CI—lint + test + typecheck full package + knip baseline, fail means red
  • Complete the hooks: pre-commit runs lint/typecheck (staged scope)
  • Put "lines deleted" into the monthly review metrics: zero means alarm

Deliverable template (report structure)

  1. Rot inventory baseline (knip numbers)
  2. Systemic issues (CI/gates/deployment drift—list separately, more important than deleting code)
  3. P0 hygiene (accidental commits/artifacts/ignore) → P1 dead files → P2 dead exports → P3 duplicate implementations → P4 dead state → dead dependencies
  4. Security special items (whether .env is committed, secret scanning)
  5. Intentional exclusion list (verified as alive)
  6. Risk-based execution plan + list of questions that must be answered by the product

Common pitfalls

  • Treating "not in the deployment manifest" as "not needed"—it may be configuration drift or a production outage (worker lesson)
  • Being misled by knip false positives—framework auto-discovery, dynamic require, and string references all cause false positives, so manual review is mandatory
  • Seeing only the trees—deleting only obvious dead symbols, missing the places with the heaviest file-level duplicate lifecycle/defensive mechanisms (check: two files implementing the same withRetry, two parallel component trees)
  • Deleting everything at once without verification—must batch + verify the baseline after each batch
  • Not distinguishing production/test/documentation consumption—"referenced only by tests" is also dead code, but the evidence must be annotated
  • Deleting 🔴-level candidates without asking product questions

Supporting templates

Sub-agent domain-splitting prompt skeleton(used in Phase 2):

你是代码简化审计员。审计目标:<路径>(<规模>)。只读,绝不修改文件、不跑构建。
方法:只报有证据的候选。每个候选先在**整个仓库**用 rg 搜消费方,区分"生产代码消费" vs "只有测试/文档消费"。没有消费证据的一律不报。
重点找:①死代码 ②重复表示 ③手搓 vs 成熟依赖 ④投机性泛化 ⑤死依赖。
产出:Markdown 表格,按置信度排序,最多 15 条。每列:候选(文件:行+符号)| 证据(rg 搜了什么)| 建议动作 | 置信度(高/中/低)。末尾列"有意排除的"。中文输出。

Decision record template(used in Phase 5):

# DECISION: <删除/合并/降级> <对象>

## Problem
<当前 API/文件/依赖是什么,消费证据(生产 N 处 / 仅测试 / 仅文档)>

## 证据
<rg 命令与结果;同名/动态/框架引用检查结果>

## 代价 / 我们放弃什么
<最强的反对理由;未来可能需要的场景>

## 回退条件
<什么情况下要恢复>

## 验证
<tsc / lint / knip 基线对比;冒烟范围>

References

  • Methodology originates from DeepSeek Harness:dsh-find-simplifications skill, AGENTS.md conventions, 144 simplification-type Agent Notes, quality gate records, postmortem 0002/0003 (tests are not the truth)
  • Real-world case: berryon subtraction audit (4 domains in parallel + knip baseline + risk grading), lessons have been embedded in this document