agentleFS
xingfanxiaxingfanxia/AX-skills/clean-room-rewrite/SKILL.md

clean-room-rewrite

Skill4 starsChanged 55 days agoMITView on GitHub

Decide whether a legacy codebase should be rewritten or refactored, and when a rewrite wins, rebuild it clean-room — distill the old system into an executable behavior spec, have a builder that never reads the old source implement it, audit parity against the old code with independent models, then shadow-run on real data and cut over with rollback. Use when asked to rewrite, rebuild, or 回炉重造 a system, or to judge whether a codebase is too tangled to refactor.

The file

We split this skill into the rules it gives an agent

10 rules. About 0 are common, 10 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈10

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Distillers and auditors: read the old code, the live system, and the data.

    line 16
  2. Distinctive:

    Run the gate in references/decision-gate.md and write the verdict with its evidence before producing any spec.

    line 32
  3. Distinctive:

    A shadow run is possible: before users depend on the new system.

    line 52
  4. Distinctive:

    Bug and security audit, then improvements: Keep redesign out of the parity phase: lock parity, then change UI or behavior as recorded …

    line 116
  5. Distinctive:

    Rehearse and shadow: Import a production snapshot, run the new system beside the old one on real traffic and scheduled jobs, and diff …

    line 119
  6. Distinctive:

    Spec complete: every enumerated surface maps to at least one ledger ID, and every disagreement between the distillations is resolved.

    line 131
  7. Distinctive:

    Abort: if two consecutive parity rounds do not reduce the count of unledgered findings, distillation has failed.

    line 145
  8. Distinctive:

    When the whole system fails condition 3, apply the same loop per bounded context behind its existing contract: distill one context, rebuild …

    line 152
  9. Distinctive:

    Rewriting the wrong problem: When the pain is a heavy process layer, flaky tests, or missing knowledge, a rewrite rebuilds the same pain.

    line 172
  10. Distinctive:

    Deleting protection by directory: When collapsing a verification layer, classify each check by the contract it protects, not by its folder …

    line 178

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Clean-Room Rewrite

Classic rewrites fail because implicit behavior gets lost. AI refactors of a tangled codebase fail differently: once the agent reads the old code it anchors on the old structure, and the "rewrite" becomes a reshuffle of the same mess. A clean-room rewrite separates the two failure modes with an information barrier:

  • Distillers and auditors read the old code, the live system, and the data.
  • The builder reads only the spec package and the old system as a black box (its UI, public responses, and sample data) — never the old source.
  • The spec package is the only channel from old to new. Every gap an auditor finds goes back into the spec first, then into the code.
  • Parity is proven by execution — oracle tests and a shadow run on real data — not by review prose.

Method inspired by the AIHOT 2.0 rewrite by 卡兹克 (KKKKhazix/AIHOT). This skill adds a decision gate before any rewrite, an executable spec with traceable IDs, deterministic stop rules, a strangler variant for large systems, and a cutover/rollback contract.

Step 0 — decide first; most codebases should not be rewritten

Run the gate in references/decision-gate.md and write the verdict with its evidence before producing any spec. A rewrite wins only when all of these hold:

  1. The target is the existing product. Parity against old behavior is wasted when the roadmap will change much of it. If the wanted product differs substantially, write a target spec instead and lock parity only on the subset being kept.
  2. Structure is the dominant cost of change. Measured change coupling, duplication, and god files — not domain difficulty, not missing tests, and not a process or verification layer that happens to be heavy.
  3. Behavior is observable. A black-box oracle exists: a live site, API responses, job outputs, and production data you can replay.
  4. The spec fits the builder's context. The architecture plus one module's spec must fit in a builder's working context at a time; otherwise split into bounded contexts that each fit (Variant B). Agent hours are rarely the binding constraint; context and verification are.
  5. State migration is tractable and reversible. Persisted formats, IDs, money and entitlement state, and user records can be carried over and rolled back.
  6. A shadow run is possible before users depend on the new system.

The numbers in the gate are signals, not thresholds. Compare the full cost of the rewrite — distillation, build, migration, acceptance — with targeted repair. If any condition fails, the answer is a targeted refactor or Variant B. A verdict of "do not rewrite" is a complete result.

The verdict is a recommendation. Committing to a rewrite is an irreversible architecture decision that belongs to the product owner: deliver it as a ≤10-line verdict with the measurements, the cost estimate, and the ranked alternatives.

Roles

RoleReadsProduces
Distillers (≥2, independent)old source, live system, data, ops configindependent spec drafts
Reconcilerboth drafts + old sourcethe single reconciled spec package
Builderspec package + black-box oracle onlythe new system
Auditors (independent of the builder)old source + new source + specparity findings mapped to ledger IDs

Diversity catches omissions: use different model families for the two distillers and for auditors versus the builder when available. Scale the roles to the slice: a small Variant B context can use one distiller plus a strong oracle suite. With a single model, use fresh sessions with isolated context and lean harder on executable oracles.

Enforce the barrier by construction. A worktree is not a barrier — it shares Git history, and earlier sessions still hold the old source in context. The builder gets a fresh directory with no old Git history containing only the spec package and the carried-over data, a fresh session, and no read access to the old repository. The old schema reaches the builder only through contracts/data-model.md; production snapshots enter the builder's environment at the shadow phase, not before. "Please do not look" is not a barrier.

Carry data, not structure. Knowledge bases, copy, prompts, translations, fixtures, and static assets are data: move them verbatim and list them in the spec's carry-over manifest. Rewriting curated domain data from prose loses it. Generated artifacts such as database types are not data; regenerate them from the target schema.

Phases

  1. Inventory and gate (Step 0). Enumerate routes, APIs, tables, jobs, webhooks, environment config, external integrations, and persisted formats mechanically — scripts and listings, not recollection.
  2. Distill in parallel into the package format of references/spec-package.md: behavior ledger, contract inventory, pitfall ledger, data and migration notes, operations, carry-over manifest, non-goals, and black-box oracle tests recorded against the old system.
  3. Reconcile. Diff the drafts; resolve every disagreement against the old source; check that every enumerated surface maps to a ledger ID. Design the target architecture for parallel agents: contracts and data model first, modules with narrow context.
  4. Build clean-room. Contracts, schema, and migrations first; then modules in parallel. The oracle suite is the builder's acceptance. Deviations go in a decisions log, not silently into code; dropping or changing behavior needs the owner's authorization, not only a decisions entry.
  5. Parity audit. Independent auditors compare old and new by module and report gaps against ledger IDs. Each gap amends the spec, then the builder fixes it. Finish with a fresh-context pass per feature module that ignores implementation and compares function and logic only.
  6. Bug and security audit, then improvements. Keep redesign out of the parity phase: lock parity, then change UI or behavior as recorded decisions. Mixing them makes a regression indistinguishable from an intended change.
  7. Rehearse and shadow. Import a production snapshot, run the new system beside the old one on real traffic and scheduled jobs, and diff outputs. Classify every difference as bug, intended change, or noise.
  8. Independent end-to-end acceptance by an agent other than the builder.
  9. Cutover with rollback per references/parity-and-cutover.md.
  10. Tune on real data — caching, payload size, queries — and monitor.

Stop rules

Audit loops need deterministic exits or they never end:

  • Spec complete: every enumerated surface maps to at least one ledger ID, and every disagreement between the distillations is resolved.
  • Build complete: the oracle suite passes, and each ledger ID is implemented or is an owner-authorized non-goal.
  • Parity complete: zero open blocking findings; every difference classified as a bug is fixed and the oracle suite re-run green after the fix; the shadow diff has no unclassified difference over a window in which every scheduled job ran at least once. Two consecutive clean audit rounds are supporting evidence, not a substitute.
  • Cutover ready: rollback was rehearsed, including the path for transactions created after the switch, and its timing measured.

And one exit for failure:

  • Abort: if two consecutive parity rounds do not reduce the count of unledgered findings, distillation has failed. Stop, then fall back to Variant B on a smaller context or to targeted refactoring. Set a budget up front and stop when it is spent without convergence.

Variant B — strangler rewrite for large systems

When the whole system fails condition 3, apply the same loop per bounded context behind its existing contract: distill one context, rebuild it clean-room, shadow it behind a flag or route split, cut over, and delete the old path after the hold period before starting the next. Each context passes the gate on its own; a missing oracle or rollback is not waived because the slice is small. Start with the context whose change cost is highest and whose state is simplest. Never run two contexts half-migrated at once.

Variant B requires the old and new sides to serve the same contract. A redesigned surface that changes the product shape (different navigation, features, or information model) is a new product, not a strangler slice: condition 0 applies, and retiring the old surface is a product decision.

Failure modes

  • Prose-only spec. Implicit behavior — URLs, field order, cache headers, cookie names, timezones, retry semantics — survives only as contracts and oracle tests (Hyrum's law).
  • Leaky barrier. A builder that reads the old code "just to check" reproduces its structure.
  • Rewriting the wrong problem. When the pain is a heavy process layer, flaky tests, or missing knowledge, a rewrite rebuilds the same pain.
  • Money, auth, and private-data boundaries rebuilt from prose. These need explicit contract tests and replay/concurrency checks carried over or re-recorded before cutover. Keep a single writer for money state; see the cutover reference.
  • Deleting protection by directory. When collapsing a verification layer, classify each check by the contract it protects, not by its folder or era; an aggregate gate often hides a money or auth check inside.
  • Data migration as an afterthought. Schema, IDs, and persisted payloads are part of the contract inventory from phase 1.
  • Cutover without a rehearsed rollback.

Deliverables

  • the gate verdict with its measurements;
  • the reconciled spec package and oracle suite;
  • the new system, with a decisions log and a carry-over manifest;
  • audit reports whose findings are mapped to ledger IDs and closed;
  • the shadow-run diff classification, cutover record, and rollback evidence.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.