Commit fb3baa62bc57

Vincent Demeester <vincent@sbr.pm>
2026-06-08 15:36:00
feat(skills): add improve-codebase-architecture skill
Added a skill that surfaces deepening opportunities in a codebase, grounded in Ousterhout's deep-modules philosophy. Walks shallow vs deep modules, applies the deletion test, presents candidates as a markdown report, and hands the chosen refactor to grill-me for design. Adapted from Matt Pocock's skill, simplified to drop the CONTEXT.md/ADR/HTML-report ecosystem in favour of local conventions.
1 parent aebbd91
Changed files (1)
dots
agents
skills
improve-codebase-architecture
dots/agents/skills/improve-codebase-architecture/SKILL.md
@@ -0,0 +1,85 @@
+---
+name: improve-codebase-architecture
+description: Find deepening opportunities in a codebase — refactors that turn shallow modules into deep ones for better testability and AI-navigability. USE WHEN user wants to improve architecture, find refactoring opportunities, consolidate tightly-coupled modules, reduce friction, or make a codebase easier for agents to work in. Best run periodically (weekly or after a surge of development).
+---
+
+# Improve Codebase Architecture
+
+Surface architectural friction and propose **deepening opportunities** —
+refactors that turn shallow modules into deep ones. The goal is a codebase
+that is easy to test and easy for an agent to navigate, because **a badly
+structured codebase makes agents produce badly structured code.**
+
+Grounded in John Ousterhout's _A Philosophy of Software Design_: the best
+modules are **deep** — a lot of behaviour behind a small, simple interface.
+
+## Glossary
+
+Use these terms exactly in every suggestion. Consistent language is the point.
+
+- **Module** — anything with an interface and an implementation (function, class, package, file, slice).
+- **Interface** — everything a caller must know to use the module: types, invariants, error modes, ordering, side effects, config. Not just the type signature.
+- **Implementation** — the code inside.
+- **Depth** — leverage at the interface: a lot of behaviour behind a small interface. **Deep** = high leverage. **Shallow** = interface nearly as complex as the implementation.
+- **Seam** — where an interface lives; a place behaviour can be altered without editing in place.
+- **Leverage** — what callers gain from depth: they get a lot while having to know little.
+- **Locality** — what maintainers gain from depth: change, bugs, and knowledge concentrated in one place instead of scattered.
+
+### Key tests
+
+- **Deletion test** — imagine deleting the module. If complexity vanishes, it was a pass-through (shallow, delete it). If complexity reappears, duplicated across N callers, it was earning its keep (deepen it).
+- **The interface is the test surface.** If a module is hard to test through its interface, the interface is wrong — don't reach for mocks, fix the seam.
+- **Shallow smell** — many tiny files you must bounce between to understand one concept; pure functions extracted only for testability while the real bugs live in how they're wired together.
+
+## Process
+
+### 1. Explore
+
+Walk the codebase organically — don't apply rigid heuristics. Note where *you*
+experience friction as you read:
+
+- Where does understanding one concept require bouncing between many small modules?
+- Where are modules **shallow** — interface nearly as complex as the implementation?
+- Where have pure functions been extracted just for testability, while the real bugs hide in how they're called (no **locality**)?
+- Where do tightly-coupled modules leak across their seams?
+- Which parts are untested, or hard to test through their current interface?
+
+Apply the **deletion test** to anything you suspect is shallow: would deleting
+it concentrate complexity, or just move it around? "Concentrates" is the signal.
+
+For larger codebases, dispatch parallel explorer subagents (see the
+`dispatching-parallel-agents` skill) over different areas and collect their friction notes.
+
+### 2. Present candidates (markdown report)
+
+Write a markdown report (per project convention — prefer markdown over HTML).
+Do NOT propose final interfaces yet. For each candidate:
+
+- **Files** — which modules are involved
+- **Problem** — why the current architecture causes friction (name the shallowness)
+- **Solution** — plain-English description of the deepening, no code yet
+- **Benefits** — in terms of **locality** and **leverage**, and how testing improves
+- **Before / After** — a short sketch (ASCII or mermaid) of the shallow structure vs. the deepened one
+- **Strength** — `Strong`, `Worth exploring`, or `Speculative`
+
+End with a **Top recommendation**: which candidate to tackle first and why.
+
+Then stop and ask: *"Which of these would you like to explore?"*
+
+### 3. Deepening loop
+
+Once the user picks a candidate, hand off to the `grill-me` skill to walk the
+design tree for that refactor — constraints, dependencies, the shape of the
+deepened module, what sits behind the seam, which tests survive. Only after
+that shared understanding is reached do you propose the concrete interface and
+implementation plan.
+
+If the user rejects a candidate for a load-bearing reason that a future review
+would otherwise re-suggest, note it (e.g. a short ADR or a line in the project's
+architecture notes) so the next run doesn't re-litigate it.
+
+## Cadence
+
+This is maintenance, not a one-off. Run it weekly or after a burst of feature
+work. Each pass that deepens a shallow module makes every later agent session
+produce better output — the gains compound.