From arc
Discovers architectural friction — shallow modules, god files, duplication, coupling — and proposes structural refactors with competing interface options and a project-local RFC.
How 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>
<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 |
npx claudepluginhub commoninstruments/arc --plugin arcExplores codebases to identify architectural friction and opportunities to deepen shallow modules, improving testability, refactoring, and AI navigability.
Analyzes codebase architecture to find refactoring opportunities, consolidate tightly-coupled modules, and improve testability and AI-navigability using domain language and ADRs.
Identifies architectural friction in codebases and proposes scored deepening refactors for shallow modules to boost testability and AI-navigability.