Prove what the types can, then test only what they cannot. Every invariant has one owner: the strongest rung of the proof ladder that can actually prove it. In order: types and linters, effects, proofs, database constraints, unit tests, integration tests, end-to-end tests.
Use the repository's current instructions and established conventions. Apply these defaults where the requested change needs a design decision; they do not authorize unrelated restructuring or new tooling.
Read the reference for the decision in scope:
| Decision | Reference |
|---|---|
| Decide which rung owns an invariant | Proof ladder |
| Represent states, workflows, and domain identities | Illegal states |
| Decode external input into useful types | Parse, don't validate |
| Type dependencies, failures, and resource lifetimes | Effects |
| Model recoverable errors and required gates | Errors as values |
| Guard a sensitive precondition | Proof parameters |
| Choose an abstraction or investigate performance | Simplicity |
| Maintain module boundaries and their documentation | Architecture docs |
Read a language reference only when its idioms, concurrency, or tooling details matter: TypeScript, Rust, Go, or Python.
For new TypeScript code and the full project template, Jess's stack is Effect, Effect Schema or Zod, xstate, and gdp-ts. For new Rust servers it is tokio, axum, snafu, aerosol, and sqlx. In an existing repository, use its equivalents; adding any of these is an architecture change to ask about first.
Use database-craft for schemas, constraints, queries, and jobs, and testing-craft for the test rungs. Repository setup belongs to project-bootstrap when that setup is requested. Follow the project's required verification; reviews do not automatically require a full test suite.
Adapted from leonardomso/rust-skills (MIT), Matklad's Rust100k series, Alexis
King's writing on parsing and type safety, and Matt Noonan's Ghosts of Departed
Proofs.