.opencode/skills/improve-codebase-architecture/DEEPENING.md
How to deepen a cluster of shallow modules safely, given its dependencies. Assumes the vocabulary in LANGUAGE.md — module, interface, seam, adapter.
When assessing a candidate for deepening, classify its dependencies. The category determines how the deepened module is tested across its seam.
Pure computation, in-memory state, no I/O. Always deepenable — merge the modules and test through the new interface directly. No adapter needed.
Dependencies that have local test stand-ins (PGLite for Postgres, in-memory filesystem). Deepenable if the stand-in exists. The deepened module is tested with the stand-in running in the test suite. The seam is internal; no port at the module's external interface.
Your own services across a network boundary (microservices, internal APIs). Define a port (interface) at the seam. The deep module owns the logic; the transport is injected as an adapter. Tests use an in-memory adapter. Production uses an HTTP/gRPC/queue adapter.
Recommendation shape: "Define a port at the seam, implement an HTTP adapter for production and an in-memory adapter for testing, so the logic sits in one deep module even though it's deployed across a network."
Third-party services (Stripe, Twilio, etc.) you don't control. The deepened module takes the external dependency as an injected port; tests provide a mock adapter.