Deep Modules
When to use
- Lens mode — apply the vocabulary and checks below to judge or shape one interface, in a design, a review, or another skill that loads this one. No subagents. A single file or function is always lens mode.
- Audit mode — scan many modules you can't eyeball in one read for shallow ones, and return a ranked findings table. Dispatches subagents; runs Audit mode.
The lens
Use these terms exactly — don't substitute "component," "service," "API," or "boundary."
- Module — anything with an interface and an implementation; scale-agnostic (function, class, package, tier-spanning slice).
- Interface — everything a caller must know to use it correctly: the signature, plus invariants, ordering, error modes, required config, performance characteristics. Broader than "API/signature."
- Implementation — the body inside the module. Distinct from Adapter: a concrete thing satisfying an interface at a seam (a Postgres repo; an in-memory fake).
- Depth — leverage at the interface: behaviour a caller or test can exercise per unit of interface it must learn. Deep = lots of behaviour behind a small interface; shallow = interface nearly as complex as the implementation.
- Seam (Feathers) — a place you can change behaviour without editing in place; where the interface lives. Where to put it is its own decision.
- Leverage — callers' payoff: one implementation pays back across N call sites and M tests.
- Locality — maintainers' payoff: change, bugs, and knowledge concentrate in one place. Fix once, fixed everywhere.
What shallow looks like — the signals an audit hunts for:
- Pass-throughs — the interface just forwards and adds nothing.
- Leaked internals — the caller must know implementation details to use it.
- Untestable except by reaching past the interface.
- Pure functions extracted only for unit-testability, while the real bugs hide in the uncovered glue that calls them — no locality.
Principles
- The deletion test. Imagine deleting the module. If its callers get simpler and nothing substantial moves into them, it was a pass-through — fold it away or deepen it. If substantial hidden work would reappear, spread across callers, it earns its keep. Relocating trivial boilerplate to N callers is not "earning its keep" — that's still shallow.
- One adapter is a hypothetical seam; two is a real one. Don't introduce a seam unless something actually varies across it.
- A finding is a candidate, not a mandate. Respect a split preserved by a recorded project decision or convention; do not re-flag it.
- Depth is leverage, not a line ratio. Reject implementation-lines-to-interface-lines metrics; they reward padding.
Deepening move by dependency — how a shallow cluster is deepened depends on what it depends on:
| Dependency |
Deepening move |
| In-process (pure/in-memory) |
Merge the modules; test through the new interface directly. |
| Local-substitutable (PGLite, memfs) |
Merge; test with the stand-in. Seam stays internal. |
| Remote but owned (your services) |
Define a port at the seam; inject an HTTP adapter for prod, in-memory for tests. |
| True external (Stripe, Twilio) |
Take the dependency as an injected port; mock it in tests. |
Audit mode
Step 1 — Scope and cluster
Confirm what to audit — the whole repo, a directory, or a named subsystem — and read the top-level structure to identify the main modules. Then split the scope into clusters by feature/subsystem (files that change together), not just by directory — so a shallow pattern duplicated across directories still lands in one brief. Two guards:
- Size. If the scope is larger than three subagents can read closely, narrow it with the user first rather than sampling a big tree and presenting it as a complete audit.
- Prior decisions. Apply the "a finding is a candidate, not a mandate" principle — respect recorded conventions and settled decisions. If the repo has a domain glossary, name modules in its vocabulary.
Step 2 — Run the fan-out via multi-agent-analysis
Invoke the multi-agent-analysis skill via the Skill tool to dispatch the subagents, merge duplicates, and apply its confidence gate and own-verdict pass — don't restate that machinery here. Take its judged findings back for Step 3 — the ranked table is the only presentation. Hand it:
- Problem: "find shallow modules in ."
- Angles: one per cluster from Step 1 (its cap-at-3, concurrent dispatch, and
opus model apply).
- Per-subagent lens, relayed inline (a parent-side load doesn't reach subagents): paste the whole The lens section into each brief, plus how to size impact — S/M/L by how much leverage or locality the reshape unlocks, tagged which. Instruct each subagent to ground every finding in a named signal (the deletion-test outcome or leaked internal that shows it, not a bare assertion), and to return the Output Schema below instead of the generic Findings shape.
Step 3 — Present the ranked table
Sort multi-agent-analysis's judged findings by impact (L → S) then confidence, and render as a table — one row per finding, columns = the Output Schema fields (Module, What's shallow, Evidence, Deepening move, Impact, Confidence). Then stop — the audit is read-only.
Close with a one-line top recommendation. To pursue a finding, point the user to grill-me (stress-test the reshape) or tech-design (design it) — this skill does not carry that loop.
Output Schema
What each audit subagent returns.
Findings {
scope: string, // what was audited
findings: [ {
module: string, // path:symbol
shallow: string, // which signal, one line
evidence: string, // deletion-test outcome, leaked internal, or the logic N callers re-implement
move: string, // the deepening reshape, per the dependency table
impact: string, // "S" | "M" | "L", tagged leverage | locality
confidence: number // 0.00–1.00 that it's genuinely shallow and the move is right
} ],
dropped: string[] // findings multi-agent-analysis dropped as low-confidence or unevidenced, listed not ranked
}
1---2name: deep-modules3description: The deep-module primitive: a small interface hiding lots of behaviour. Apply the lens to judge or shape one interface, or audit a codebase for shallow modules (returns a ranked table). TRIGGER when: user says 'deep modules', 'is this a deep module', 'find shallow modules', 'audit from the deep-module lens'; a skill needs the deep-module vocabulary.4---56# Deep Modules78## When to use910- **Lens mode** — apply the vocabulary and checks below to judge or shape **one** interface, in a design, a review, or another skill that loads this one. No subagents. A single file or function is always lens mode.11- **Audit mode** — scan **many** modules you can't eyeball in one read for shallow ones, and return a ranked findings table. Dispatches subagents; runs [Audit mode](#audit-mode).1213## The lens1415Use these terms exactly — don't substitute "component," "service," "API," or "boundary."1617- **Module** — anything with an interface and an implementation; scale-agnostic (function, class, package, tier-spanning slice).18- **Interface** — everything a caller must know to use it correctly: the signature, plus invariants, ordering, error modes, required config, performance characteristics. Broader than "API/signature."19- **Implementation** — the body inside the module. Distinct from **Adapter**: a concrete thing satisfying an interface at a seam (a Postgres repo; an in-memory fake).20- **Depth** — leverage at the interface: behaviour a caller or test can exercise per unit of interface it must learn. **Deep** = lots of behaviour behind a small interface; **shallow** = interface nearly as complex as the implementation.21- **Seam** _(Feathers)_ — a place you can change behaviour without editing in place; where the interface lives. Where to put it is its own decision.22- **Leverage** — callers' payoff: one implementation pays back across N call sites and M tests.23- **Locality** — maintainers' payoff: change, bugs, and knowledge concentrate in one place. Fix once, fixed everywhere.2425**What shallow looks like** — the signals an audit hunts for:2627- Pass-throughs — the interface just forwards and adds nothing.28- Leaked internals — the caller must know implementation details to use it.29- Untestable except by reaching *past* the interface.30- Pure functions extracted only for unit-testability, while the real bugs hide in the uncovered glue that calls them — no locality.3132**Principles**3334- **The deletion test.** Imagine deleting the module. If its callers get simpler and nothing *substantial* moves into them, it was a pass-through — fold it away or deepen it. If *substantial* hidden work would reappear, spread across callers, it earns its keep. Relocating trivial boilerplate to N callers is not "earning its keep" — that's still shallow.35- **One adapter is a hypothetical seam; two is a real one.** Don't introduce a seam unless something actually varies across it.36- **A finding is a candidate, not a mandate.** Respect a split preserved by a recorded project decision or convention; do not re-flag it.37- **Depth is leverage, not a line ratio.** Reject implementation-lines-to-interface-lines metrics; they reward padding.3839**Deepening move by dependency** — how a shallow cluster is deepened depends on what it depends on:4041| Dependency | Deepening move |42|---|---|43| In-process (pure/in-memory) | Merge the modules; test through the new interface directly. |44| Local-substitutable (PGLite, memfs) | Merge; test with the stand-in. Seam stays internal. |45| Remote but owned (your services) | Define a **port** at the seam; inject an HTTP adapter for prod, in-memory for tests. |46| True external (Stripe, Twilio) | Take the dependency as an injected port; mock it in tests. |4748## Audit mode4950### Step 1 — Scope and cluster5152Confirm what to audit — the whole repo, a directory, or a named subsystem — and read the top-level structure to identify the main modules. Then split the scope into clusters by feature/subsystem (files that change together), not just by directory — so a shallow pattern duplicated across directories still lands in one brief. Two guards:5354- **Size.** If the scope is larger than three subagents can read closely, narrow it with the user first rather than sampling a big tree and presenting it as a complete audit.55- **Prior decisions.** Apply the "a finding is a candidate, not a mandate" principle — respect recorded conventions and settled decisions. If the repo has a domain glossary, name modules in its vocabulary.5657### Step 2 — Run the fan-out via multi-agent-analysis5859Invoke the `multi-agent-analysis` skill via the Skill tool to dispatch the subagents, merge duplicates, and apply its confidence gate and own-verdict pass — don't restate that machinery here. Take its judged findings back for Step 3 — the ranked table is the only presentation. Hand it:6061- **Problem:** "find shallow modules in <scope>."62- **Angles:** one per cluster from Step 1 (its cap-at-3, concurrent dispatch, and `opus` model apply).63- **Per-subagent lens, relayed inline** (a parent-side load doesn't reach subagents): paste the whole **The lens** section into each brief, plus how to size impact — S/M/L by how much leverage or locality the reshape unlocks, tagged which. Instruct each subagent to ground every finding in a **named signal** (the deletion-test outcome or leaked internal that shows it, not a bare assertion), and to return the [Output Schema](#output-schema) below instead of the generic Findings shape.6465### Step 3 — Present the ranked table6667Sort multi-agent-analysis's judged findings by impact (L → S) then confidence, and render as a table — one row per finding, columns = the [Output Schema](#output-schema) fields (Module, What's shallow, Evidence, Deepening move, Impact, Confidence). Then stop — the audit is read-only.6869Close with a one-line top recommendation. To pursue a finding, point the user to `grill-me` (stress-test the reshape) or `tech-design` (design it) — this skill does not carry that loop.7071---7273## Output Schema7475What each audit subagent returns.7677```78Findings {79 scope: string, // what was audited80 findings: [ {81 module: string, // path:symbol82 shallow: string, // which signal, one line83 evidence: string, // deletion-test outcome, leaked internal, or the logic N callers re-implement84 move: string, // the deepening reshape, per the dependency table85 impact: string, // "S" | "M" | "L", tagged leverage | locality86 confidence: number // 0.00–1.00 that it's genuinely shallow and the move is right87 } ],88 dropped: string[] // findings multi-agent-analysis dropped as low-confidence or unevidenced, listed not ranked89}90```