Your linter checks code after it's written. Cofferdam tells your agent the rules before it writes — and guarantees the debt only goes down.
cofferdam is a software architecture and code-quality analyzer for TypeScript with a Rust core. Layer rules, frozen boundaries, import invariants, and complexity budgets are declared once in cofferdam.invariants.toml, enforced in CI, and advised to AI coding agents just-in-time. Findings are bucketed into five categories — Consistency, Design, Readability, Refactor, Warning — and priority-sorted within each; the category model is inspired by Elixir's Credo.
advise <file> ↓ ┌────────────────────────────────┐
advise --diff ↑ │ cofferdam │
│ layers · invariants · │
│ boundaries · baseline │
├────────────────────────────────┤
│ tsc │
├────────────────────────────────┤
│ Biome / ESLint │
├────────────────────────────────┤
│ Biome / Prettier │
└────────────────────────────────┘
Cofferdam sits above your linter and type-checker, not instead of them — see where cofferdam sits for the full picture.
Full docs site: https://tajd.github.io/cofferdam
- Check catalog — every built-in check with bad/good examples
- CLI reference — flags and exit codes
advisereference — the JSON envelope agents branch on, plusadvise --analyzebudget headroom- llms.txt — the entrypoint for LLM agents: version, subcommands, agent workflow, docs links
- Install guide — binary overrides, air-gapped installs, building from source
- CI recipes — GitHub Actions, GitLab, CircleCI, Drone, pre-commit
- Suppression syntax —
// cofferdam-ignoredirectives - Ignore syntax —
.cofferdamignorerules - Per-path overrides — retune or disable single checks on matching globs via
[[overrides]] - Type-aware checks — checks backed by the TypeScript type system (requires Node + ts-morph; opt out with
[engine] type_aware = false) - Output formats — text, JSON, compact, SARIF
- Architectural specs —
cofferdam.invariants.toml,Design.LayerViolation,Design.BoundaryFrozen - Budgets & ratchet —
[budgets]hard caps,baseline ratchet/prune,check --trend - AI agent workflow —
cofferdam agentsonboarding prompt, plusagents --hooks - Agent hooks — wire
adviseinto a PreToolUse hook - MCP server —
cofferdam-mcpexposing advise/check/explain/invariants to agent hosts - Doctor — environment + config diagnostics (
cofferdam doctor)
npm install --save-dev @cofferdam/cofferdam
pnpm add -D @cofferdam/cofferdam
yarn add --dev @cofferdam/cofferdamThe postinstall script downloads the matching prebuilt binary for your platform (Linux x64/arm64 glibc + musl, macOS x64/arm64, Windows x64). Node 16+ required. Binary overrides, air-gapped installs, and building from source (Rust 1.93+): install guide.
$ cofferdam advise src/app/checkout.ts
src/app/checkout.ts
layer: app public_api: no
Design.LayerViolation imports must target layer(s) [domain, infra]
Design.InvariantViolation "no-direct-db-access": must not import src/infra/db
Design.BoundaryFrozen not frozen
Refactor.CognitiveComplexity limit 15
$ cofferdam advise --diff main
would_fire: 1
src/app/checkout.ts:12 imports src/infra/db from layer `app` (Design.InvariantViolation)
would_clear: 0An agent runs advise before editing and advise --diff before asking for a
commit. For finding-level output on the code as it stands today, cofferdam check gives the same priority-sorted, severity-gated report any linter
does — see the agent workflow docs and
output formats for both.
One command in any runner with Node:
npx --yes @cofferdam/cofferdam checkReady-made workflows (GitHub Actions, GitLab, CircleCI, Drone, pre-commit), PR-only mode, and baselines: docs/ci-recipes.md.
TypeScript (TS / TSX / JS / JSX / MJS / CJS via oxc) is the primary surface. A Rust adapter ships as the second language and polylingual proof; SQL, IaC, and GraphQL adapters follow the same shape. Details: language support.
Cofferdam runs against its own source on every PR (cd-9tq, cd-91zc):
- TS SDK —
packages/check-sdk/src/is scanned by thedogfoodjob in.github/workflows/ci.yml. The repo-rootcofferdam.invariants.tomldeclares the SDK aspublic_apiso leaf-package re-exports aren't flagged as orphans; the three legitimate complexity findings onplugin-host.tsride in.cofferdam/baseline.jsonand are tracked separately. CI fails on any new finding at--fail-on=high. - Rust workspace — the
dogfood-rustjob in the same workflow scans every workspacesrc/against.cofferdam/baseline-rust.json.
To run the same gate locally before pushing:
cargo build --release -p cofferdam-cli
./target/release/cofferdam check packages/check-sdk/src \
--baseline .cofferdam/baseline.json --fail-on=highPhase 4, in progress. See MAINTAINERS.md for the phased roadmap.
MIT.