A staged workflow that turns an unfamiliar or messy codebase into a mapped, documented, evidence-backed one, so an AI (or a person) works from proof instead of guesswork.
Every long-lived codebase collects dark code: parts that look understandable but hide how the system actually behaves. Unclear ownership, silent side effects, a script that quietly touches production, prose that promises a feature the code never implements. Dark code is dangerous because it makes people confident about things they cannot actually prove.
Anti-Dark-Code is the antidote. It gives an AI a fixed set of numbered passes to run, one at a time, each producing durable records the repo keeps. The rule underneath all of it is short: do not guess. Mark every claim as proven, likely, or unknown, and never let a likely claim get written down as a proven one.
Facts come from evidence in the repo, not from the model's memory or a confident guess. If the code cannot prove it, the skill will not claim it. That single habit is what keeps the whole workflow honest.
Every claim the skill records carries one of three labels. This is the vocabulary the whole workflow shares.
When a check would force a claim down to inferred, the skill writes inferred. It downgrades rather than rounds up. Anything it cannot resolve becomes a written unknown with an owner, a risk level, and the next best check, so nothing quietly disappears.
Run one numbered pass on one bounded slice, finish it, record it, then move on. No interleaving passes. Small, reversible steps beat one sweeping change.
Auth, billing, deletion, secrets, migrations that rewrite saved data, hash or receipt truth: document the finding first, propose the smallest safe edit, and stop for a human before touching it.
Two more hold across every pass. Preserve scope honesty: one clean file does not stand in for a whole mixed system, and out-of-repo control planes are named, not folded into local coverage. Protect the record: comments that explain a trust boundary, an ordering rule, or a recovery path are treated as load-bearing and are not silently removed.
The skill is a menu of numbered passes grouped into families. A run loads only the one pass it is doing, does that work, reports back, and picks the next. Most passes are read-only or docs-only. Only the remediation pass changes application code, and only after the map, the unknowns, and the approval gates are in place.
The newest rule sits under everything else: never spend model intelligence on work a compiler, schema, dependency graph, seed, diff, or test runner can settle exactly. Agents do the judgment. The computer does the mechanics and produces the evidence.
A small deterministic tool ships inside the skill (scripts/adc.py, plain Python, no dependencies). It profiles a repo without executing any of its code, evaluates all twenty verification capabilities against what it found, installs and upgrades the repo copy with checksums, runs approved quality gates as exact argument arrays with real exit codes, and stages flow-back proposals. When a gate passes, the result collapses to one line. When it fails, the agent receives a small bounded failure packet, and the full log stays local, pattern-redacted, out of the conversation.
The gate runner is dry-run by default. Execution requires all three: each command individually marked approved by the owner, a recorded global owner confirmation in the gate file, and the explicit allow-exec flag on the invocation. Any new or changed generated gate resets the confirmation, and a gate whose underlying script changed after approval is blocked until re-reviewed.
Gates are organized on a four-level confidence ladder, so a run knows how much verification a moment deserves. It prevents the two classic failures: running almost nothing during development, or running everything after every tiny edit.
Seconds. Format, typecheck, lint, schema and architecture rules. Cheap enough that skipping it is never worth it.
A few minutes. Affected unit and contract tests, focused integration, replay and invariant checks for the touched surface.
Selective depth. Property and metamorphic checks, short fuzz runs, changed-module mutation, perf smoke, targeted fault injection.
The heavy battery. Full suites, long fuzz and soak campaigns, migration and platform matrices, statistical canaries for emergent behavior.
On a harness that can spawn subagents, the skill switches on an orchestration mode. This changes only how the work runs, never the pass order, the approval gates, or the evidence rules. The most important boundary: the fan-out lives inside a single pass. Many readers, many slices, many verification angles, but still one pass at a time. Passes never run in parallel with each other.
A pass that fans out follows the same shape every time. Free shell work does the counting. Mid-tier readers do the reading. Independent verifiers try to break each claim. One orchestrator writes the record. A subagent's claim never enters the record as proven on its own word.
A subagent's claim enters the record as inferred. It becomes verified only when the orchestrator personally re-opens the citation, or two independent readers with different angles agree, or a command settles it. Effort is spent re-checking the highest-risk claims first.
Model choice is spoken in plain tiers, not product names, so it travels to any harness: cheap-and-wide for the reading, a step up for the riskiest slice, top tier and few calls for synthesis. There are two dials, not one. Tier raises the capability ceiling. Effort buys more thinking on the same ceiling.
Verification produces a free signal for tuning them. At each checkpoint the orchestrator counts how many claims per family survived, then adjusts the next batch:
The orchestrator quotes the fan-out shape (how many agents, at what tier) before launching, especially after any usage limit. Each unit of paid work is its own call with a stable prompt, so if a run dies partway it resumes from cache: completed work replays for free, and only the unfinished calls run again. Progress is read straight from the run journal with shell tools, never by paying an agent to summarize it.
Agent-driven work leaves debris the same way old systems leave dark code: gigabytes of logs, hundreds of snapshots, one-off scripts nobody can explain. Pass 09 handles it with one principle first. The lasting value of a generated file is the claim it supports plus the recipe that regenerates it. Record both, then the file itself drops into one of four tiers and gets handled by the tier's rule, not by a hunch.
Never touched. Anything git-tracked, or named by a steering file (docs, review artifacts, assets, history). A broad "clean it all up" does not override this.
Record the recipe, then remove. One command or seed rebuilds it fast. Archive as a short-retention fallback, spot-check that it rebuilds, then delete the originals.
Archive first, delete later, never the reverse. Checksum, compress, verify by re-hashing, add parity data when the archive is the only copy, and ask before removing originals.
Hard stop. Nobody can explain it. Archive it untouched or leave it in place, record an unknown, and ask. Absence of references proves it is unused by current code, not that it is safe to delete.
Deletion is always the second step, never the first. Everything moves through a reversible quarantine, gets verified against a checksum manifest, and only then, with per-group approval, gets removed. A tracked ledger records where each thing went and how to get it back, so a future session can answer that from the record alone.
The skill used to ship as parallel Claude and Codex variants, and they drifted. It is now one model-neutral core. Host differences (how Claude Code, Codex, or Gemini CLI discovers a skill, which tools it prefers) live in small addendum files inside the core, never as separate editable trees.
Knowledge flows one way by default: the clean core flows down into repos; repo knowledge stays in its repo. The only path upstream is a sanitized, content-hashed proposal staged into the shared core's review inbox, which a human reads, generalizes, and promotes. A compromised or simply overfitted repository cannot rewrite the shared skill and poison every future project.
Exact savings before this measurement protocol existed are unmeasured. The skill makes no automatic network calls and sends no telemetry. If a host reports the tokens used during one assisted run, that is usage, not proof of savings.
A tokens-saved claim requires a quality-qualified controlled pair: the same provider, model, counter method and adapter, equivalent task and repository state, equivalent tool access, the same acceptance contract with both outcomes passing, and one run with the skill compared with one baseline run without it. Tokenizer or context-compaction estimates are useful engineering proxies, but remain separate from provider-reported token counts. Public community receipts are opt-in and self-reported, never provider-attested.
The public brief works without metrics data. When a validated summary is published, this panel reports its paired sample count without turning unpaired usage or estimates into a savings claim.
Every pass reports back the same way: which pass ran on which slice, what was created or updated, what unknowns were recorded, which risks moved, which approval gates were crossed or are still pending, and what to run next. The durable outputs live in the repo:
You do not need to understand the machinery. If you use an AI coding assistant, paste this into it:
Install the anti-dark-code skill for me: download https://github.com/LynxTWO/anti-dark-code-skill to a temporary folder, place its inner anti-dark-code folder into my assistant's skills directory (~/.claude/skills/ for Claude Code, ~/.agents/skills/ for Codex or Gemini), delete the downloaded copy, and confirm by reading the skill's VERSION file. Then tell me what it can do.
Your assistant will ask permission to run a download command and a copy command. That is normal for this one-time install; approve them. Afterwards, close your assistant and open it again inside your project, then ask things like "map this project and tell me what actually runs," or "audit this codebase before I change anything."
Three reassurances: the checks it sets up never run without your approval; it marks everything it records as proven, likely, or unknown instead of guessing; and it keeps its notes in a small folder inside your project, in ordinary text files it asks before creating.
One model-neutral core; per-host discovery via user-level symlinks or junctions; managed, checksummed repo installs with a repo-owned calibration overlay; identity-bound calibration; exact argv gates behind three locks with real exit codes; proposal-only flow-back.
git clone https://github.com/LynxTWO/anti-dark-code-skill
cd anti-dark-code-skill
python3 anti-dark-code/scripts/adc.py validate
python3 anti-dark-code/scripts/adc.py bootstrap --repo <repo> --hosts all
# review the printed plan, then re-run with --apply
The README's operator manual covers the trust model, binding, gate semantics, exit codes, and the multi-machine pattern. Installation and profiling never execute repository code.
If the skill only lives in your assistant's skills folder, replacing that folder with the latest copy is the whole upgrade. If you installed it into projects, re-run the installer from the new core: it preserves each project's calibration and verifies the repository binding. Coming from a version before repository binding existed (the old separate Claude and Codex variants)? Read MIGRATION.md first: the installer will ask you to explicitly accept your legacy calibration, and it resets gate approvals on the way in. That is protection, not breakage. The README's upgrade section has the exact commands.