# DEEPENING — Domain-modeling depth lens

This lens asks: **does this area model the domain at the right depth?**
Are the abstractions earning their keep, or are they shallow wrappers
hiding nothing?

The discipline is to **find abstractions that have failed to deepen** —
classes, modules, or types that started as a single-use convenience and
never grew into something that captures domain meaning.

## What "deep" means

A deep abstraction:

- Has a name that maps to a domain concept the user / business cares
  about
- Encapsulates more behavior than its interface suggests (you can call
  one method and trust it to handle multiple internal concerns)
- Reads naturally in client code without the reader needing to know
  the abstraction's internals

A shallow abstraction:

- Has a name that mirrors implementation detail rather than domain
  concept (e.g., `DataManager`, `Helper`, `Utils`)
- Encapsulates almost no behavior — the interface is wider than the
  internals (mostly pass-through)
- Reads as noise in client code; the reader has to look inside the
  abstraction to know what it does

## Red flags this lens surfaces

- **Anemic types** — types that are bags of fields with no methods, OR
  classes with methods that just return fields.
- **Pass-through wrappers** — `class FooService { constructor(api) { this.api = api } create(x) { return this.api.create(x) } }` adds nothing.
- **Single-call-site abstractions** — extracted "for reuse" but only
  called from one place. Inline them.
- **God objects** — abstractions that grew too deep AND too wide,
  collecting unrelated responsibilities. Different problem, same lens.

## Apply in Phase 1

When the explore step scans the named area:

1. For each module / class / type, ask: "what domain concept does this
   model?"
2. If the answer is "none — it's an implementation detail dressed up as
   a concept", flag it as a candidate.
3. Note in the inventory: `{File}:{Symbol} — shallow ({reason})`. The
   deletion test in Phase 2 will rank these.

## What this lens does NOT cover

- Boundary shape between modules → see `INTERFACE-DESIGN.md`
- Naming consistency within / across modules → see `LANGUAGE.md`

DEEPENING is about whether each abstraction is the right size. The
sibling lenses are about whether the gaps between them are well-shaped
and whether the language is consistent.

## Deletion test (Phase 2 prep)

For each candidate this lens flags, the Phase-2 deletion test asks:

> If I deleted `{Symbol}` and inlined its body at every call site, what
> domain meaning would be lost?

If the answer is "nothing — it was just a name on a syntactic shape",
the deletion test passes and the candidate is high-priority for refactor
(remove the abstraction; the area gets shallower in surface area but
deeper in meaning per remaining concept).

If the answer is "we'd lose the {domain concept} as a first-class
thing in the code", the deletion test fails — the abstraction was
earning its keep, just maybe at the wrong depth. Re-scope to a sibling
lens.
