- Be conservative, explicit, and boring.
- When unsure, ask; don’t guess.
- Make minimal, targeted changes; avoid refactors unless requested/necessary.
- Preserve existing structure, conventions, and tooling.
- Don’t add dependencies without strong justification.
- Write strict, idiomatic TS; follow the repo’s tsconfig and lint rules.
- No
any(useunknown, generics, or proper types). - Prefer
interfacefor public shapes;typefor unions/helpers. - Prefer immutability (
readonly,ReadonlyArray) where practical. - Narrow with type guards; avoid assertions and
!except as a last resort. - Prefer exhaustive handling (
neverchecks) for unions. - Treat caught errors as
unknownand narrow before use.
- Target the repo’s supported Node LTS (don’t assume versions; check config/docs).
- Prefer
async/await; never swallow rejections. - Avoid module top-level side effects (I/O, network, reading env, global mutations) unless explicitly intended.
- Env vars: validate centrally; read at runtime (not import-time); don’t mutate in app code (tests only with scoped setup/teardown).
- Error handling: rethrow with context; preserve
causewhen available; don’t throw strings. - Library code should not log; CLIs may log intentionally with consistent exit codes.
- New logic requires tests unless truly trivial (types-only, re-exports, comments/formatting).
- Tests must be deterministic and isolated; avoid shared mutable state.
- Prefer behavioral tests; mock sparingly.
- No committed
.only/.skip(unless explicitly justified). - Bug fixes must include a regression test.
- Avoid snapshots unless they add clear value and are stable.
- Follow existing formatting/lint; keep functions small and readable.
- Prefer named exports.
- Update docs/comments when behavior changes (comments explain “why”, not “what”).
- Never log secrets; validate/sanitize external inputs (paths/URLs/user data).
- Dependency adds must be justified (need, alternatives, maintenance/license/security impact).
- Change public APIs or introduce breaking changes without explicit instruction.
- Perform stylistic rewrites or micro-optimizations.
- Typecheck + lint + tests pass.
- New behavior has coverage (including failure paths); no unintended snapshot changes.
- No unnecessary diff churn; no accidental top-level side effects; env usage is validated and intentional.