{
  "version": "act 2.1.1",
  "slug": "architectural-refactoring",
  "name": "architectural-refactoring",
  "description": "Execute structural decompositions based on an architectural analysis report. Use when breaking circular dependencies, splitting god classes, reducing coupling between modules, extracting interfaces at seam boundaries, or executing any large-scale structural change identified in an architectural analysis. Requires a prior architecture audit (the architecture-audit skill) that produced project-map.md and a run report.",
  "url": "https://act101.ai/docs/skills/architectural-refactoring",
  "body_md": "# Architectural Refactoring with act\n\nExecute structural decompositions based on an architectural analysis report.\n\n## Prerequisites\n\nA prior architecture audit must exist:\n\n- `project-map.md` at the workspace root \u2014 the living architectural document, including its\n  `## Refuted & Re-characterized Findings` ledger.\n- A run report at `docs/act/<YYYY-MM-DD-HHMMSS>/report.md` \u2014 use the run with the highest\n  timestamp. `docs/act/` is gitignored, so on a fresh clone the report may be absent even though\n  `project-map.md` (which carries findings and the Refuted ledger forward) survives. If no local\n  report exists, work from `project-map.md` and re-run `architecture-audit` to regenerate one.\n\nIf neither exists, run the `architecture-audit` skill first. (`architecture-audit` replaces the\nformer `architectural-analysis` skill. If any doc still references that name, or a single\n`docs/architectural-analysis-report.md`, it is stale \u2014 use the artifacts above.)\n\n## Rules\n\n1. **Start from the audit** \u2014 Read `project-map.md` and the latest `docs/act/<ts>/report.md` first. Every refactoring decision must trace back to a confirmed finding (by its finding ID) in that report. Check the map's Refuted & Re-characterized Findings ledger first \u2014 never \"fix\" a smell that was already investigated and disproven.\n\n2. **Find boundaries, don't invent them** \u2014 Use `act analyze seams` together with `act analyze clusters`. A zero-seam result is not proof that no boundary exists when clusters are hub-collapsed or collapsed into one cluster; in that case use `top_hubs`, dampened clusters, `split_module`, and `simulate` to identify the smallest verified cut.\n\n3. **Evaluate before cutting** \u2014 Before extracting a module, use `act analyze surface --files <files>` to measure the API surface. If the surface is too wide, the extraction will create more coupling, not less.\n\n4. **Break cycles first** \u2014 Circular dependencies are the highest priority. Use `act analyze cycles` to find them, then break the simplest edge in each cycle.\n\n5. **Extract interfaces at seams** \u2014 At each seam boundary, extract an interface that both sides depend on. Use `act query interface <file>` to understand the current API, then `act refactor extract-interface` to create it.\n\n6. **Stable foundations first** \u2014 Start with the most stable modules (lowest instability in `act analyze coupling`). Make them independent before touching unstable modules.\n\n7. **Measure coupling reduction** \u2014 After each refactoring step, re-run `act analyze coupling` and `act analyze cycles` to verify that coupling decreased and cycles were broken.\n\n8. **Use dead code analysis for cleanup** \u2014 Before and after each major refactoring, run `act analyze dead-code` to identify symbols that are no longer needed.\n\n9. **Record every remediation** \u2014 After each verified step, append one row to `remediation-log.md` (workspace root) keyed to the finding ID it resolves (see Recording Remediations). Do **not** edit `project-map.md` \u2014 `architecture-audit` owns the map and folds the log into it on the next run. To refresh the map after a batch of remediations, re-run `architecture-audit`.\n\n10. **Incremental, verifiable steps** \u2014 Each refactoring step should be small enough to verify independently. Commit after each step. Never make multiple structural changes at once.\n\n## Workflow\n\n1. Read `project-map.md` (including its Refuted ledger) and the latest `docs/act/<ts>/report.md`\n2. Prioritize confirmed findings by ID: cycles > god classes > high coupling > dead code\n3. For each finding:\n   a. Verify it's still present (`act analyze cycles` / `act analyze coupling`)\n   b. Plan the refactoring (identify boundaries/seams, measure surface)\n   c. **Before cutting, simulate the intended change** \u2014 call\n      `simulate(ops=[\u2026], include=[\u2026])` with the planned change expressed as\n      `split_file`/`move_file`/`remove_edge`/`merge_files`/`delete_module` ops and record the\n      predicted deltas (cycles resolved, coupling changes, violations cleared/introduced) in the\n      remediation row's \"Verified by\" cell. For a chokepoint or refuted-ledger row that hinges\n      on \"is this wide module load-bearing or a pass-through?\", `delete_module{file}` settles it\n      deterministically. Read `deletions.surface_consumers` first \u2014 external symbols calling or\n      extending the module's own surface (`top_consumers` names them); any non-zero count means\n      load-bearing. `surface_consumers: 0` certifies a conduit ONLY when `deletions.surface_modeled`\n      is `true` (false \u2192 UNKNOWN, never \"clean\"). `rewired_edges`/`severed_edges` describe the\n      file-routing side. Record the surface count + a named consumer in the \"Verified by\" cell\n      instead of re-arguing the deletion test by hand. Example for a planned split of a god module:\n\n      ```\n      simulate(ops=[{op: \"split_file\", file: \"src/core.ts\", groups: [[\"parseUser\", \"validateUser\"], [\"formatReport\"]]}])\n      ```\n\n      The result shows `cycles.resolved`, `coupling.changed` (per-unit before/after instability),\n      and \u2014 when an `[architecture]` contract exists \u2014 `violations.cleared`/`violations.introduced`.\n      If the simulation introduces new violations or does not resolve the target cycle, revise the\n      cut before touching disk.\n   d. Execute the refactoring using `act refactor` operations. **When the change is\n      a repetitive mass edit** \u2014 the same transform repeated across many sites (a\n      deprecation rename across the codebase, an import reorganization, wrapping a\n      pattern) \u2014 do not hand-edit site by site. Author and run a recipe instead (see\n      Mass Changes below).\n   e. Verify the fix (re-run the specific analysis, check tests)\n   f. Commit the code fix\n   g. Append a remediation row to `remediation-log.md` \u2014 its `Commit` column references the\n      step-f commit; record the log row in its own follow-up commit (don't try to embed the row\n      in the very commit it names)\n4. After the batch, re-run `architecture-audit` to refresh `project-map.md`. It reads the log,\n   re-verifies each claimed fix against fresh structural evidence, and folds confirmed\n   remediations into the map. This closes one audit \u2192 refactor \u2192 re-audit cycle; the next cycle\n   starts from the refreshed map and goes deeper.\n\n**If there's nothing to remediate** \u2014 when the report's confirmed findings are already all\n`RESOLVED` in `remediation-log.md`, or the report surfaces no confirmed actionable findings (only\nrefuted/re-characterized entries remain), do **not** invent work and do **not** re-open refuted\nsmells. The cycle's next step is a fresh audit, not a manufactured refactor. Recommend it the same\nclean-slate way the audit hands off to you: \"Clear context, then run `/architecture-audit`.\" A new\naudit re-baselines against the current structure and surfaces the next layer of findings \u2014 that is\nhow the cycle goes deeper: refactoring exhausts a report, the audit produces the next one.\n\n## Mass Changes \u2014 Author a Recipe, Don't Hand-Edit\n\nWhen a structural remediation is the **same transform repeated across many sites** \u2014\na deprecation rename propagated through the codebase, an import reorganization, wrapping\na recurring pattern \u2014 drive it as a codemod recipe rather than editing each site by hand.\nA recipe (`match \u2192 transform \u2192 optional verify`) runs one `act refactor` operation in bulk\nacross every matching site, atomically, with optional gate-verify and receipts. This is the\nexecutor for repetitive mass changes; reserve site-by-site `act refactor` calls for the\nhandful of one-off cuts.\n\nRun it via the `recipe_run` MCP tool, or `act recipe run <recipe.toml>` on the CLI:\n\n1. **Preview first.** Run with `preview` (MCP) / `--preview` (CLI) to list every match and\n   its planned operation before anything touches disk. Confirm the match set is exactly the\n   sites you intend \u2014 no more, no less \u2014 before applying.\n2. **Verify behaviour-changing transforms.** A pure rename only needs the match set checked.\n   For any transform that can change behaviour (wrapping awaits, restructuring calls), enable\n   the recipe's verify stage so the E6 gate trio runs over each changed file; sites that fail\n   verification come back `FLAGGED` instead of silently applied.\n3. **Cut atomically.** For a remediation that must land as a single all-or-nothing change,\n   set `all_or_nothing` (MCP) / `--all-or-nothing` (CLI) \u2014 if any site fails, the whole run\n   rolls back via history and the tree is left untouched.\n4. **Record receipts.** Run with `receipts` (MCP) / `--receipts` (CLI) to emit E7 receipts for\n   verified transforms, and record the receipt ID(s) in the remediation row's \"Verified by\"\n   cell exactly as for any other receipted step (see Recording Remediations).\n\n`recipe_run` parameters: `recipe_path` (required), `root`, `preview`, `all_or_nothing`,\n`receipts`. The per-site report it returns (matched / applied / failed / flagged / rolled_back)\nis the evidence for the remediation row \u2014 one recipe run resolves the finding across all sites,\nso log it as a single remediation keyed to the finding ID. `recipe_run` is an Enterprise tool.\n\n## Recording Remediations\n\nRemediations go in an append-only ledger, **not** in `project-map.md`. The map is a full-state\ndocument that `architecture-audit` rewrites wholesale on every run \u2014 writing remediations into it\nwould be clobbered on the next audit and would put two skills in conflict over one file. Keep the\naction history separate from the state document:\n\n- **File:** `remediation-log.md` at the workspace root (git-tracked, sibling of `project-map.md`).\n  It must be durable, so do **not** place it under the gitignored `docs/act/<ts>/` tree.\n- **Append only.** Never rewrite or reorder existing rows. One row per verified step.\n- **Key every row to a finding ID** from the report it resolves, so the next audit can match the\n  claim against the live structure.\n\nRow format:\n\n```markdown\n| Date | Finding | Status | Change | Commit | Verified by |\n|------|---------|--------|--------|--------|-------------|\n| 2026-05-28 | C-3 (auth\u2194router cycle) | RESOLVED | Extracted `AuthPort` interface at the seam; router depends on the interface, not auth | abc1234 | `act analyze cycles` \u2192 0 cycles; tests pass |\n| 2026-06-12 | C-7 (validateAge logic) | RESOLVED | Tightened boundary condition in validateAge | def5678 | `act analyze coupling` \u2192 0 violations; receipt `8bb683bbfe8e27cf` |\n```\n\nWhen the remediation step ran `act gate --receipts` (or `gate(receipts=true)`) over the change,\nor a refactor op was run with `receipt=true`, record the receipt ID(s) in the Verified-by cell\nalongside the structural check. Receipts are evidence, never authority \u2014 any hash or schema\nmismatch at consumption time discards the receipt and falls back to fresh verification\nautomatically. Emission mechanics and the receipt JSON schema live in the refactor-receipt skill;\nthis skill only records the IDs.\n\n`Status` is `RESOLVED` (fix verified) or `PARTIAL` (reduced but not eliminated \u2014 note what\nremains). The next `architecture-audit` reads this log in Phase 0, re-verifies each claim against\nfresh structural evidence, and reflects confirmed fixes in the map (flagging any claim the\nstructure contradicts). That hand-off \u2014 refactoring writes the log, the audit folds it into the\nmap \u2014 is what lets the audit \u2192 refactor cycle run repeatedly and go deeper each pass.\n\n## Delegation\n\n- Use `refactoring` skill for individual operations (rename, extract, move)\n- Use `code-generation` skill for scaffolding new modules\n- Use `code-navigation` skill to understand code before modifying it\n\n## Token-Saving Hints\n\n- Use `act analyze cycles` with `--max-length 3` to focus on the tightest cycles first\n- Use `act analyze coupling --threshold 0.7` to focus on the most unstable modules\n- Use `act query skeleton` instead of reading full files\n- Re-run only the specific analysis that your change affects, not the full suite"
}