v0.1.5
You have an architecture decision record. A Confluence page. Maybe a Miro board with boxes and arrows that everyone agreed on in the last design review.
Then a sprint happens.
A service that was never supposed to touch the database directly now has a db.query() call buried in a helper. A dead node that was deprecated three months ago is still receiving traffic. Nobody noticed. The CI pipeline passed. The linter was happy. The tests are green.
The architecture, however, is already wrong.
The gap that no tool fills
We lint code. We type-check code. We test code. But we have never had a way to formally define an architecture and then enforce it — continuously, deterministically, before a PR is merged.
Code linters catch bad syntax. Architecture linters should catch bad structure. The two aren't the same problem, and a code linter cannot solve the architecture one.
Think of it this way: ESLint is to code what ArchRAD is to architecture blueprints. One enforces style and correctness at the expression level. The other enforces intent at the system level.
What ArchRAD does
ArchRAD is a blueprint compiler and governance layer. You define your architecture as a formal Intermediate Representation — nodes, edges, metadata, allowed connections — and ArchRAD validates it against a deterministic rule engine.
Two rules that ship out of the box:
IR-LINT-MISSING-AUTH-010 — flags any service edge missing an authentication boundary.
IR-LINT-DEAD-NODE-011 — flags any node with no inbound or outbound connections.
Cold-start from an existing OpenAPI spec:
npx @archrad/deterministic ingest openapi ./openapi.yaml
npx @archrad/deterministic validate --ir ./graph.json
Detect drift between your blueprint and generated code:
npx @archrad/deterministic validate-drift --ir ./graph.json --target python --out ./out
If the IR says service A cannot talk directly to the database, and the generated code does exactly that — ArchRAD tells you. Before it ships.
Why deterministic matters
Every other architecture tool gives you opinions. ArchRAD gives you constraints.
The rule engine is graph-based and deterministic. The same IR, the same rules, the same inputs will always produce the same findings. No LLM guessing. No probabilistic output. This matters especially as AI coding agents become part of the workflow — agents need hard constraints, not soft suggestions.
MCP server — architecture governance inside your agent
0.1.5 ships archrad-mcp alongside the CLI. One install, two binaries. Add this to your Cursor or Claude Desktop config:
{
"mcpServers": {
"archrad": { "command": "archrad-mcp" }
}
}
Your agent can now call six tools against the same deterministic engine your CI uses — archrad_validate_ir, archrad_lint_summary, archrad_validate_drift, archrad_suggest_fix, and more. When the agent proposes connecting service A directly to the database, ArchRAD returns IR-LINT-DIRECT-DB-ACCESS-002 — before the code is written, not after the PR is opened.
Static remediation guidance ships for every built-in rule code. No generative output — archrad_suggest_fix returns curated, deterministic text for each finding. 127 tests cover the guidance corpus.
CI in ten lines
No separate Action needed — the CLI runs directly in any GitHub Actions workflow:
name: architecture drift
on: [push, pull_request]
jobs:
drift:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci
- run: |
npx archrad validate-drift \
--ir ./graph.json \
--target python \
--out ./golden-export \
--json
PRs fail when generated code drifts from the IR. Add --fail-on-warning to also gate on lint findings.
The OSS core is Apache-2.0
The engine — IR, linter, validator, MCP server — is fully open source under Apache-2.0. No telemetry, no lock-in, works offline.
Try it on your next architecture review:
npm install @archrad/deterministic
GitHub: github.com/archradhq/arch-deterministic
Questions, feedback, or drift horror stories — drop them in the comments or open an issue on GitHub.
Top comments (0)