| name | approachability-audit |
| description | First-read approachability lens. Read code as a newly onboarded TypeScript developer to surface indirection, misleading names, type-system-only tricks, and wrong-owner boundaries. Cited by post-implementation-review and collapse-pass as their readability pass; also use directly when code feels clever or hard to follow on first read. |
Approachability Audit
Read the code like a smart but newly onboarded TypeScript developer.
Related skills: use post-implementation-review for the full second-read
ritual after implementation, refactoring for caller counting and inlining
mechanics, and cohesive-clean-breaks when a readability issue points to the
wrong public boundary.
The goal is not "make it shorter" or "make it more abstract." The goal is:
- make the first read cheaper
- make ownership boundaries obvious
- remove tricks that only exist for the type system
- keep real domain or validation boundaries intact
What to Look For
- Names that imply a more important concept than the code actually represents
- Types that pretend to be runtime truths but are only inference shims
- Client-only hacks living in server packages, or server concerns leaking into browser/shared code
- Single-use helpers that hide simple control flow
- Tiny wrappers that add vocabulary but not clarity
- Multiple files for one concept when readers really need one place to look
- "Smart" generic helpers where direct code would be easier to trust
- Ad-hoc
as assertions outside a clear parse or interop boundary
- JSDoc that restates code instead of explaining why the boundary exists
What Not to "Fix"
- Real parse boundaries at JSON, file, or network edges
- Runtime validation that protects unsafe input
- Shared contracts that genuinely belong in one place
- Repetition that is cheaper than an extra abstraction
Review Method
- Start with the entrypoint a caller uses first.
- Trace the minimum path needed to understand the behavior.
- Count the hops:
- if understanding one field or behavior requires jumping across multiple files, ask whether that indirection earns its keep
- Mark each abstraction as one of:
earns its keep
probably inlineable
wrong ownership boundary
misleading name
type-system workaround
- Prefer fixes that:
- move code to the right owner
- rename things honestly
- collapse fake layers
- replace cleverness with one explicit boundary
Output Shape
When reporting findings, prioritize:
- The one or two biggest readability or ownership smells
- Why a new TypeScript developer would stumble there
- The greenfield correction that would make the code easiest to trust
When editing code:
- keep commits surgical
- add or improve JSDoc on public boundaries
- do not add a new abstraction unless it reduces total cognitive load
- prefer explicit names like
*Bridge, *Contract, *Parser, *Factory, *State
Heuristics
Good smell
export type SessionContract = { ... };
Portable type, honest name, obvious job.
Bad smell
export type AppAuth = {
options: { plugins: [...] }
};
If this is not the real auth type, do not name it like it is.
Good workaround
export type CustomSessionClientBridge = { ... };
If a library forces a type trick, keep it local and name it as a bridge.
Go-to-Definition Is the First Read
A new developer's first read of a foreign symbol is Go-to-Def. Treat it as the canonical readability tool: pressing it from a call site should land on the actual source of truth in as few hops as possible. Counting hops (review method, step 3) means counting Go-to-Def hops.
The smell catalog that bloats the hop count (re-export chains,
destructure-re-exports, no-op adapters, identity-obscuring annotations) lives in
typescript "Go-to-Definition Awareness". Each extra hop
has to earn its keep: if a layer doesn't own a real invariant, name non-obvious
domain behavior, or isolate unsafe input, collapse it.
Success Criteria
The code should leave a new teammate thinking:
- "I know which file owns this concept."
- "I know which type is a real contract and which one is just library glue."
- "I don't have to reverse-engineer the architecture from naming accidents."