Help us improve
Share bugs, ideas, or general feedback.
From arc
Discovers architectural friction — shallow modules, god files, duplication, coupling — and proposes structural refactors with competing interface options and a project-local RFC.
npx claudepluginhub howells/arc --plugin arcHow this skill is triggered — by the user, by Claude, or both
Slash command
/arc:refactorThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
<tool_restrictions>
Explores codebases to identify architectural friction and opportunities to deepen shallow modules, improving testability, refactoring, and AI navigability.
Audits codebase architecture for tightly-coupled modules and suggests refactors toward deep modules with simple interfaces. Use for architectural improvement, refactoring opportunities, or making code more testable.
Analyzes codebase architecture to find refactoring opportunities, consolidate tightly-coupled modules, and improve testability and AI-navigability using domain language and ADRs.
Share bugs, ideas, or general feedback.
<tool_restrictions>
EnterPlanMode — BANNED. Do NOT call this tool. This skill has its own structured process.ExitPlanMode — BANNED. You are never in plan mode.
</tool_restrictions><arc_runtime> This workflow requires the full Arc bundle, not a prompts-only install.
Paths in this skill use these conventions:
agents/..., references/..., disciplines/..., templates/..., scripts/..., rules/..., skills/<name>/... are Arc-owned files at the plugin root. Resolve the plugin root from this skill's filesystem location — it's the directory containing agents/ and skills/../... is local to this skill's directory..ruler/..., docs/..., src/..., or any project-relative path refers to the user's project repository.
</arc_runtime><required_reading> Before starting, read these references:
references/architecture-patterns.md — import depth rules, boundary violationsreferences/component-design.md — compound vs simple component patternsreferences/maintainability-review.md — strict god-file, duplication, and structural simplification barreferences/complexity-optimization.md — safe optimization patterns and behavior-preservation checksAlso read, when present in the target project:
CONTEXT.md or the relevant context from CONTEXT-MAP.mddocs/adr/*.md or area-specific ADRs
</required_reading>Discover structural friction, propose deep-module refactors, and create project-local RFCs.
This workflow reviews existing code with the explicit goal of creating a refactoring plan or RFC./arc:refactor./arc:audit.Use these terms consistently:
From John Ousterhout's A Philosophy of Software Design:
A deep module has a small interface hiding a large implementation. Deep modules are:
A shallow module has an interface nearly as complex as its implementation. Shallow modules:
Apply the deletion test to suspected shallow modules: if deleting the module makes complexity vanish, it was pass-through indirection; if deleting it spreads complexity across callers, it was earning its keep.
Read the project context before judging architecture:
CONTEXT-MAP.md exists, use it to find the relevant CONTEXT.md.CONTEXT.md if present.docs/adr/ or the relevant area if the candidate touches a documented decision.Use the project's domain vocabulary when naming candidate modules. If a better module name uses a concept not in CONTEXT.md, note that the context should be updated during the grilling loop.
For JavaScript/TypeScript projects, run the Arc-owned god-file and duplication scanner when available:
python3 scripts/find-god-files.py . --max-files 40
Use --include-tests only when the user asks about duplicated tests or test-suite cleanup.
The scanner is heuristic. It ranks likely candidates; it does not decide. Read the highest-ranked files before proposing changes.
Also run the Arc-owned read-only codebase mapper when available:
python3 scripts/codebase-map.py ${scope:-.} --format markdown
Use the map to orient exploration around route surfaces, services, data layer, largest files, high fan-in/fan-out modules, and import cycles. The mapper output is not a finding by itself. Read the relevant files before proposing any refactor.
Classify confirmed candidates:
god-component — React component doing rendering, data shaping, effects, mutations, validation, and subview control in one file.god-script — CLI/build/migration script mixing argument parsing, I/O, domain logic, formatting, and side effects.god-module — non-UI module with multiple unrelated responsibilities.duplication — repeated functions, schemas, UI fragments, query builders, scripts, or formatting logic.shallow-module — interface nearly as complex as the implementation.package-extraction — grouped behavior that belongs in a discrete package/module because it has a coherent concept, multiple callers, and a stable interface.Use the Agent tool with subagent_type=Explore to navigate the codebase. If the user provided a
path or focus area, start there. Otherwise, explore broadly.
Do NOT follow rigid heuristics. Explore organically and note where you experience friction:
The friction you encounter IS the signal.
Present a numbered list of refactoring opportunities. For each candidate:
| Field | Description |
|---|---|
| Cluster | Which modules/concepts are involved |
| Type | shallow-module, package-extraction, god-component, god-script, god-module, duplication |
| Evidence | Line count, responsibility mix, duplicated blocks, import depth, call patterns, shared types |
| Problem | Why the current shape causes friction |
| Proposed direction | Plain-English description of what would change |
| Dependency category | See categories below |
| Locality / leverage | What change gets concentrated, and what callers gain |
| Test impact | What existing tests would be replaced by boundary tests, or what characterization tests are needed first |
| Complexity impact | Current complexity, proposed complexity, and behavior-preservation risk when performance is part of the refactor |
| Severity | How much this costs day-to-day |
Ask the user: "Which of these would you like to explore?"
Do NOT propose final interfaces yet. The point is to choose which candidate deserves deeper work.
Use a grilling loop before writing the RFC. Ask one question at a time, with your recommended answer included. Resolve:
CONTEXT.md should gain or sharpen a term.Update project context inline only for durable domain language, not temporary implementation details.
Before spawning interface-option agents, write a user-facing explanation of the chosen candidate:
Show this to the user, then immediately proceed to Step 7.
Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a radically different interface for the deepened module.
Give each agent a technical brief (file paths, coupling details, dependency category, what's being hidden) plus a different interface constraint:
| Agent | Constraint |
|---|---|
| Agent 1 | "Minimise the interface — aim for 1-3 entry points max and maximise leverage per entry point" |
| Agent 2 | "Maximise flexibility — support many use cases and extension" |
| Agent 3 | "Optimise for the most common caller — make the default case trivial" |
| Agent 4 (if applicable) | "Use ports & adapters for cross-boundary dependencies" |
Each sub-agent outputs:
Present all options, then compare them in prose. Give your own recommendation — which option is strongest and why. If elements from different options combine well, propose a hybrid. Be opinionated.
Create a refactor RFC in docs/arc/plans/YYYY-MM-DD-[scope]-refactor-rfc.md:
## Problem
[Describe the architectural friction — which modules are shallow and coupled,
what integration risk exists, why this makes the codebase harder to navigate]
## Proposed Interface
[The chosen interface option — signature, usage example, what it hides]
## Package / Module Extraction
[If applicable: where the new package/module lives, what it owns, what remains in callers, and how imports migrate]
## Dependency Strategy
[Which category applies and how dependencies are handled]
## Testing Strategy
- **Characterization tests to write first**: [current behaviours that must be pinned before splitting]
- **New boundary tests to write**: [behaviours to verify at the interface]
- **Old tests to delete**: [shallow module tests that become redundant]
- **Test environment needs**: [local stand-ins or adapters required]
## Decomposition Order
1. [First safe extraction]
2. [Second safe extraction]
3. [Import migration / cleanup]
## Implementation Recommendations
[Durable guidance NOT coupled to current file paths:
- What the module should own (responsibilities)
- What it should hide (implementation details)
- What it should expose (the interface contract)
- How callers should migrate]
Save the RFC and summarize the recommendation. Do not auto-commit it unless the user asks.
When assessing a candidate, classify its dependencies:
Pure computation, in-memory state, no I/O. Always deepenable — merge the modules and test directly.
Dependencies with local test stand-ins (PGLite for Postgres, in-memory filesystem). Deepenable if the stand-in exists. Test with the local stand-in running in the test suite.
Your own services across a network boundary. Define a port (interface) at the module boundary. The deep module owns the logic; the transport is injected. Tests use an in-memory adapter.
Third-party services (Stripe, Twilio) you don't control. Mock at the boundary. The deepened module takes the external dependency as an injected port; tests provide a mock.
The core principle: replace, don't layer.
From the architecture patterns reference:
| Signal | What it means |
|---|---|
5+ levels of ../ imports | Code is reaching across boundaries |
| Barrel file re-exporting everything | Hiding the real dependency graph |
| Test file longer than source file | Testing internals, not behaviour |
| "Utils" folder with 20+ files | Shallow modules masquerading as shared code |
| Type file imported by 10+ modules | Hidden coupling through shared types |
| Feature spread across 8+ files | Over-decomposition, shallow modules |
| Mock setup longer than test body | Integration seams are in the wrong place |
| Large component mixes effects, validation, mutation, and rendering | God component |
| Script mixes CLI parsing, I/O, transformation, and output formatting | God script |
| Same schema/query/formatting code appears in several places | Missing shared module |
| Same concept used from multiple apps/packages | Candidate package/module extraction |