Coding standards¶
One rule underpins every INVA repository: all code is typed, formatted, linted
and tested before merge; a change without its tests and docs is incomplete.
This page is the estate-wide standard; each repo enforces it with gates suited
to its stack. The reference implementation is
emma-platform.
Toolchain by language¶
| Stack | Format | Lint | Types | Tests |
|---|---|---|---|---|
| Python | ruff format |
ruff check |
mypy (strict on pure modules) |
unittest / pytest + coverage |
| Node / TypeScript | prettier |
eslint |
tsc --noEmit |
vitest |
| IaC (Ansible / OpenTofu) | tofu fmt |
ansible-lint, tofu validate, shellcheck |
— | --check / plan diffs |
| Docs (all repos) | — | markdownlint |
— | mkdocs build --strict |
Every repo exposes these as make targets folded into a single make check
that mirrors CI, runs the fast ones through .pre-commit-config.yaml, and gates
secrets everywhere with gitleaks.
Structure & style¶
- Small, cohesive modules with explicit interfaces and explicit error handling. Keep the pure/business core free of I/O and third-party imports; put integrations behind typed seams (Protocols / interfaces). No new dependency without a stated reason.
- Types are not optional. New modules join the strict type set; legacy or integration modules may be relaxed temporarily with a documented, tracked follow-up — never silently.
- Comments explain intent — a decision, boundary or invariant — never what the next line already says. Remove dead code rather than commenting it out.
- Pin what must not drift: dependencies by version, container images by digest, models by checksum, docs/dev toolchains by exact pin.
Facts & provenance¶
Never invent an owner, date, budget, decision, metric or source. Material
decisions are ADRs in each repo's docs/decisions/ — cite them rather than
restating. Unknown values use the ⚠ placeholder convention and must be
resolved before any deploy (grep for ⚠ first).
Security baked in¶
Least privilege everywhere; server-side identity and tenant filtering; treat all
imported text as untrusted input. No secret material in code, config, logs,
prompts, commit messages or docs — a gitleaks finding is a hard stop. See
Git workflow for how this is enforced at merge time.