DX is a feature: how we decide what ships
Our internal heuristic for choosing libraries, abstractions, and patterns — biased toward what an LLM agent can navigate without help.
Every dependency is a tax. Every abstraction is a bet that the team will remember why it exists six months later. UseDeploy is opinionated because non-opinionated boilerplates always end up as someone else's opinionated boilerplate, just with worse defaults.
The three rules
1. The contract is the docs.
If you cannot understand what an endpoint expects by reading packages/contracts/src/<context>.ts, the schema is wrong. No prose-only docs, no Notion pages, no Confluence. The Zod schema is the source of truth, and the OpenAPI artifact is generated from it.
2. The error type is part of the public API.
Result<T, DomainError> everywhere in the application layer. Throwing is reserved for genuinely unexpected failures (DB unreachable, signing key missing). When an LLM reads a use case and sees Result<User, EmailAlreadyTaken>, it knows the failure mode without running the code.
3. The diff should fit on a screen.
If a feature requires touching twelve files, the architecture is leaking. Bounded contexts exist so that adding a new field, a new use case, or a new endpoint is local. When it is not local, that is the signal — fix the seam, do not paper over it.
Why AI-readability matters even if you do not use AI
The constraints that make a codebase legible to an LLM agent are the same constraints that make it legible to a human who joined yesterday: explicit types, predictable folder layout, no clever metaprogramming, no implicit globals. Optimizing for the dumb-but-fast reader makes the codebase better for the smart-and-slow reader too.
That is the whole pitch.