type-design-review
Overview
A specialist review lens for type design: whether a type carries strong,
clearly expressed, well-encapsulated invariants — or leans on documentation and
caller discipline to stay valid. The guiding principle is make illegal states
unrepresentable: the best invariant is one the type system enforces so the
invalid case cannot be constructed at all.
This is a deliberately-invoked pass focused on the shape of the data, not the
behavior around it. Reach for it when a change introduces or reshapes a type.
When To Use
- A change introduces a new type, domain model, struct, dataclass, enum, or
interface.
- A PR adds several types and you want each reviewed for design quality.
- Someone is refactoring an existing type to strengthen its guarantees, and
wants the invariants and encapsulation assessed first.
- The user asks whether a type "makes illegal states unrepresentable" or
"enforces its invariants".
Boundaries
- Not general code review. Correctness, performance, and style belong to
local-review. This lens looks only at type/invariant design.
- Not error-handling review. Swallowed errors and fallbacks are
error-handling-review.
- Read-only. Produce an assessment; do not edit source.
- Pragmatism over purity. A simpler type with fewer guarantees can beat a
complex one that over-models. Weigh the maintenance cost of every suggestion;
perfect is the enemy of good.
Workflow
For each new or changed type:
- Identify the invariants — implicit and explicit. Data-consistency rules,
valid state transitions, cross-field relationships, business rules encoded in
the type, pre/postconditions. Name them; you cannot rate what you have not
named.
- Rate the four axes, 1–10, each with a one-line justification. See
references/rating-rubric.md for what each axis measures and what low vs.
high looks like:
- Encapsulation — are internals hidden; can the invariants be violated
from outside?
- Invariant expression — how clearly does the structure communicate the
invariants; are they compile-time where possible?
- Invariant usefulness — do the invariants prevent real bugs and match the
domain, without being over- or under-restrictive?
- Invariant enforcement — checked at construction; every mutation guarded;
is it impossible to build an invalid instance?
- Flag anti-patterns from
references/rating-rubric.md (anemic models,
exposed mutable internals, doc-only invariants, god-types, missing
construction validation, inconsistent mutation guards).
- Recommend pragmatic improvements — concrete, language-appropriate, and
worth their complexity and breaking-change cost.
Output Contract
One block per type, findings-oriented:
## Type: <TypeName> (<path:line>)
### Invariants
- <each invariant, one line>
### Ratings
- Encapsulation: X/10 — <justification>
- Invariant expression: X/10 — <justification>
- Invariant usefulness: X/10 — <justification>
- Invariant enforcement: X/10 — <justification>
### Strengths
- <what the type does well>
### Concerns
- <specific issue, with the illegal state it permits>
### Recommended improvements
- <concrete, pragmatic change; note breaking-change/complexity cost>
When several types are reviewed, order blocks by lowest minimum axis rating
first (weakest design surfaced first). State explicitly when a type is
well-designed — a high score is a real result.
Verification
- Every reviewed type cites a real
path:line.
- Every axis rating carries a justification; every
Concern names the concrete
illegal state the current design permits.
- Recommendations are language-appropriate and acknowledge their cost.
Resources
references/rating-rubric.md — what each of the four axes measures (with
low/high anchors), the anti-pattern catalog, and language-specific tools for
making illegal states unrepresentable in TypeScript and Python.
Sibling skills
local-review — general diff review; run this lens when it flags a new type,
or invoke it directly.
error-handling-review — the failure-handling lens; orthogonal.
api-design — for interface/contract shape at the API boundary rather than
the invariants of an internal type.
1---2name: type-design-review3description: Review the design of a new or changed type — does it make illegal states unrepresentable, enforce its invariants at construction, and encapsulate its internals? Rates encapsulation, invariant expression, invariant usefulness, and enforcement. Use when introducing a new type or data model, reviewing the types added in a PR, or refactoring a type for stronger guarantees. Not general diff review (local-review).4---56# type-design-review78## Overview910A specialist review lens for **type design**: whether a type carries strong,11clearly expressed, well-encapsulated invariants — or leans on documentation and12caller discipline to stay valid. The guiding principle is *make illegal states13unrepresentable*: the best invariant is one the type system enforces so the14invalid case cannot be constructed at all.1516This is a deliberately-invoked pass focused on the shape of the data, not the17behavior around it. Reach for it when a change introduces or reshapes a type.1819## When To Use2021- A change introduces a new type, domain model, struct, dataclass, enum, or22 interface.23- A PR adds several types and you want each reviewed for design quality.24- Someone is refactoring an existing type to strengthen its guarantees, and25 wants the invariants and encapsulation assessed first.26- The user asks whether a type "makes illegal states unrepresentable" or27 "enforces its invariants".2829## Boundaries3031- **Not general code review.** Correctness, performance, and style belong to32 `local-review`. This lens looks only at type/invariant design.33- **Not error-handling review.** Swallowed errors and fallbacks are34 `error-handling-review`.35- **Read-only.** Produce an assessment; do not edit source.36- **Pragmatism over purity.** A simpler type with fewer guarantees can beat a37 complex one that over-models. Weigh the maintenance cost of every suggestion;38 perfect is the enemy of good.3940## Workflow4142For each new or changed type:43441. **Identify the invariants** — implicit and explicit. Data-consistency rules,45 valid state transitions, cross-field relationships, business rules encoded in46 the type, pre/postconditions. Name them; you cannot rate what you have not47 named.482. **Rate the four axes**, 1–10, each with a one-line justification. See49 `references/rating-rubric.md` for what each axis measures and what low vs.50 high looks like:51 - **Encapsulation** — are internals hidden; can the invariants be violated52 from outside?53 - **Invariant expression** — how clearly does the structure communicate the54 invariants; are they compile-time where possible?55 - **Invariant usefulness** — do the invariants prevent real bugs and match the56 domain, without being over- or under-restrictive?57 - **Invariant enforcement** — checked at construction; every mutation guarded;58 is it impossible to build an invalid instance?593. **Flag anti-patterns** from `references/rating-rubric.md` (anemic models,60 exposed mutable internals, doc-only invariants, god-types, missing61 construction validation, inconsistent mutation guards).624. **Recommend pragmatic improvements** — concrete, language-appropriate, and63 worth their complexity and breaking-change cost.6465## Output Contract6667One block per type, findings-oriented:6869```70## Type: <TypeName> (<path:line>)7172### Invariants73- <each invariant, one line>7475### Ratings76- Encapsulation: X/10 — <justification>77- Invariant expression: X/10 — <justification>78- Invariant usefulness: X/10 — <justification>79- Invariant enforcement: X/10 — <justification>8081### Strengths82- <what the type does well>8384### Concerns85- <specific issue, with the illegal state it permits>8687### Recommended improvements88- <concrete, pragmatic change; note breaking-change/complexity cost>89```9091When several types are reviewed, order blocks by lowest minimum axis rating92first (weakest design surfaced first). State explicitly when a type is93well-designed — a high score is a real result.9495## Verification9697- Every reviewed type cites a real `path:line`.98- Every axis rating carries a justification; every `Concern` names the concrete99 illegal state the current design permits.100- Recommendations are language-appropriate and acknowledge their cost.101102## Resources103104- `references/rating-rubric.md` — what each of the four axes measures (with105 low/high anchors), the anti-pattern catalog, and language-specific tools for106 making illegal states unrepresentable in TypeScript and Python.107108## Sibling skills109110- `local-review` — general diff review; run this lens when it flags a new type,111 or invoke it directly.112- `error-handling-review` — the failure-handling lens; orthogonal.113- `api-design` — for interface/contract shape at the API boundary rather than114 the invariants of an internal type.