Deterministic IR/IR-LINT validation, policy packs, drift vs exports (archrad). Apache-2.0.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste into ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)

Your architecture drifts before you write a single line of code. archrad validate catches it β deterministically, in CI, before the PR merges.
Define your system as a graph. ArchRAD compiles it, lints it against architecture rules, and tells you exactly what's wrong β with rule codes, not opinions.
You should see something like (exact wording may vary slightly by version):
For a smaller graph (single endpoint, no DB edge), try fixtures/minimal-graph.json β you will get different warnings (e.g. health/auth heuristics), not IR-LINT-DIRECT-DB-ACCESS-002.
No IR file yet? Cold-start from an existing OpenAPI spec:
ArchRAD is a blueprint compiler and governance layer. You define your architecture as an IR β nodes, edges, allowed connections β and ArchRAD validates it against a deterministic rule engine. The same IR, the same rules, the same inputs always produce the same findings.
| Command | What it checks | Codes |
|---|---|---|
archrad validate | Graph structure + architecture lint | IR-STRUCT-* IR-LINT-* |
archrad lint | Architecture lint only (fast inner-loop; skips structural) | IR-LINT-* |
archrad explain <code> | Canonical rule guidance without running a pass | β |
archrad policies-sha256 --dir <policies> | Generate a archrad-policy-pack.sha256 manifest for signed PolicyPacks | β |
archrad validate-drift | IR vs generated code on disk | DRIFT-* |
archrad ingest openapi | Derive IR from OpenAPI (local path or https URL for --spec; -H for URL auth headers) | β |
archrad ingest backstage | Backstage catalog-info.yaml β IR (Component, Resource, API, System; Location file targets) | β |
archrad fragment merge | Merge 2+ IR files β union by node.id (conflicts β stderr); --prefix-fragments for disjoint union | β |
archrad export | Compile IR β FastAPI or Express + Docker | β |
Ingest + merge workflows: docs/INGEST.md. All commands / flags: docs/CLI_REFERENCE.md. Codegen (export): docs/EXPORT.md.
archrad reconstruct + --codebase)"The IR looks clean β but is that what was actually shipped?"
The validation pipeline above checks your authored IR (the design contract). The --codebase flag bridges the gap to the real codebase by reconstructing an IR from source code and comparing them.
A developer can author a compliant IR (passes all IR-STRUCT-* and IR-LINT-* rules) while the actual code bypasses the documented architecture. The most dangerous pattern: an IR that shows a clean service layer but code that directly queries the database.
When --codebase is provided, the pipeline runs three stages:
Implementation drift uses a separate exit threshold: --fail-on, --fail-on-warning, and --max-warnings apply only to IR-STRUCT-, IR-LINT-, and merged PolicyPack findings. IR-DRIFT-IMPL-* are gated solely by --impl-drift-fail-on (default: drift severities error fail the command).
| Code | Severity | What it catches |
|---|---|---|
IR-DRIFT-IMPL-000 | warning | Authored IR could not be parsed for drift comparison (fix structural issues first) |
IR-DRIFT-IMPL-001 | warning | IR declares HTTP-like entry nodes but reconstruction detected zero artifacts in --codebase |
IR-DRIFT-IMPL-002 | warning | HTTP / health routes in code but authored IR has no HTTP-like nodes |
IR-DRIFT-IMPL-003 | error | Direct DB connection in code, no DB edge in authored IR |
IR-DRIFT-IMPL-004 | error | HTTP route in code not present in authored IR |
IR-DRIFT-IMPL-005 | warning | Service-to-service call in code, no edge in authored IR |
IR-DRIFT-IMPL-006 | info | Auth middleware in code, no auth node in authored IR |
IR-DRIFT-IMPL-003 is the critical one. An error there means the authored IR hides a direct DB dependency.
| Language | Detected patterns |
|---|---|
| Node.js / TypeScript | Express, Fastify, NestJS routes; pg, Prisma, TypeORM, Sequelize, Mongoose, Redis; Passport, express-jwt, NestJS guards, Auth0, Okta, Keycloak, Cognito; axios, got, node-fetch, gRPC |
| Python | Flask, FastAPI, Django URLs, DRF @action; SQLAlchemy, psycopg2, asyncpg, PyMongo, motor, redis-py; login_required, jwt_required, FastAPI OAuth2; requests, httpx, aiohttp, gRPC |
| C# | Minimal API MapGet/MapPost; ASP.NET Core [HttpGet]/[ApiController]; EF Core DbContext, Npgsql, Dapper; [Authorize], AddAuthentication, JWT bearer; HttpClient, gRPC, RestSharp |
Reconstruction is best-effort signal, not certainty:
eval, reflection, metaprogramming, and generated code are not detected.Treat IR-DRIFT-IMPL-* findings as "review required", not absolute truth. The reconstructed IR is signal, not certainty.
Authored IR (authored.json) shows clean layered architecture:
But src/api/routes.ts contains:
Running archrad validate --ir authored.json --codebase ./src:
The IR said no direct DB access. The code said otherwise. IR-DRIFT-IMPL-003 caught the gap.
archrad.yml)Drop an archrad.yml at the root of your repo and skip re-typing flags:
archrad walks upward from the CWD looking for archrad.yml (or
archrad.yaml). Explicit CLI flags always override the config. Use
--no-config to ignore any discovered file, or --config <path> to
point at a non-standard location. Full schema: docs/CONFIG.md.
archrad lint + archrad explainarchrad lint is the fast inner loop; use archrad validate once before the CI gate to also enforce IR structural shape. With archrad.yml at repo root, both run with no flags.
After install, archrad-mcp is on your PATH. Add it to your IDE:
Your agent can call the same engine as the CLI via six MCP tools (e.g. archrad_validate_ir, archrad_lint_summary, archrad_validate_drift, archrad_policy_packs_load, archrad_list_rule_codes, archrad_suggest_fix). See docs/MCP.md for parameters and local testing.
schemas/archrad-ir-graph-v1.schema.json (editor/CI; optional at runtime).validateIrStructural: arrays, ids, HTTP config, edge refs, cycles (IR-STRUCT-*). Uses an internal normalized graph (see docs/IR_CONTRACT.md).openapi.yaml (document shape, not Spectral).Architecture lint (IR-LINT-*) sits after structural checks: rule visitors on the parsed graph (heuristics, not schema).
| Layer (OSS) | What it is | Codes |
|---|---|---|
| IR structural validation | Graph well-formedness: ids, edges, cycles, HTTP path/method | IR-STRUCT-* |
| Architecture lint (basic) | Deterministic heuristics only (no AI, no org policy) | IR-LINT-* |
| OpenAPI structural validation (document shape) | Parse + required top-level OpenAPI fields on generated spec | (string warnings, not IR codes) |
| Layer (Cloud β not this package) | Examples |
|---|---|
| Policy engine | SOC2, org rules, entitlement |
| Architecture intelligence | Deeper NFR / cost / security reasoning |
| AI remediation | Repair loops, suggested edits |
config.url / config.method, unknown edge endpoints, directed cycles.buildParsedLintGraph β LINT_RULE_REGISTRY in src/lint-rules.ts). If the IR cannot be parsed, buildParsedLintGraph returns { findings } (IR-STRUCT-) instead of null; use isParsedLintGraph() or call validateIrLint, which forwards those findings. Each rule returns IrStructuralFinding[]; runArchitectureLinting / validateIrLint flatten them. Custom org rules: compose runArchitectureLinting with your own (g) => findings in CI (worked example: docs/CUSTOM_RULES.md), or fork and append to LINT_RULE_REGISTRY if the stock archrad validate CLI must emit your codes. CLI archrad validate / archrad export print lint under **Architecture lint (IR-LINT-)** (grouped separately from structural). Codes include IR-LINT-DIRECT-DB-ACCESS-002, IR-LINT-SYNC-CHAIN-001, IR-LINT-NO-HEALTHCHECK-003, IR-LINT-HIGH-FANOUT-004, IR-LINT-ISOLATED-NODE-005, IR-LINT-DUPLICATE-EDGE-006, IR-LINT-HTTP-MISSING-NAME-007, IR-LINT-DATASTORE-NO-INCOMING-008, IR-LINT-MULTIPLE-HTTP-ENTRIES-009, IR-LINT-MISSING-AUTH-010, IR-LINT-DEAD-NODE-011. Sync-chain depth counts synchronous edges only; mark message/queue/async hops via edge.metadata.protocol / config.async (see edgeRepresentsAsyncBoundary in lint-graph.ts and docs/ENGINEERING_NOTES.md).openapi.yaml, handlers, deps.make run / docker compose up --build.openApiStructuralWarnings.IR contract: schemas/archrad-ir-graph-v1.schema.json. Parser boundary + normalized shapes: docs/IR_CONTRACT.md (normalizeIrGraph β materializeNormalizedGraph).
Trust builder: IR-STRUCT-* errors block export; IR-LINT-* warnings are visible and can gate CI via --fail-on-warning / --max-warnings; OpenAPI shape issues surface as export warnings.
Reference (OSS): docs/DRIFT.md (deterministic validate-drift), docs/RULE_CODES.md (finding codes; MCP docsUrl targets GitHub anchors), docs/MCP.md (MCP tools + local testing).
Generators may emit retry/timeout/circuit-breaker code when the IR carries matching edge or node config (e.g. retryPolicy). That is code generation, not a guarantee. OSS does not currently require or lint βevery external call must have timeout/retryβ β that class of rule is semantic / policy and fits ArchRad Cloud or custom linters on top of the IR.
| Mode | Best for | Example |
|---|---|---|
| CLI | Quick local scaffolding, CI, βno Node projectβ usage | archrad export --ir graph.json --target python --out ./out |
| YAML β IR | Author graphs in YAML, emit JSON for validate/export | archrad yaml-to-ir -y graph.yaml -o graph.json |
| OpenAPI β IR | Derive HTTP nodes from OpenAPI 3.x (same IR shape as YAML path); ArchRad Cloud merge uses the same library | archrad ingest openapi --spec openapi.yaml -o graph.json |
| CLI validate | CI / pre-commit: IR structural + architecture lint, no codegen | archrad validate --ir graph.json |
| CLI validate-drift | After export or merges: on-disk tree vs fresh deterministic export from same IR | archrad validate-drift -i graph.json -t python -o ./out |
Library (@archrad/deterministic) | IDPs / pipelines | runDeterministicExport β files + findings; runValidateDrift / runDriftCheckAgainstFiles for drift |
MCP (archrad-mcp) | Cursor / Claude Desktop / other MCP hosts | stdio server: validate IR, lint summary, drift, policy packs, static archrad_suggest_fix β see docs/MCP.md |
MCP (Cursor example): after npm i -g @archrad/deterministic (or npx), add a server with command archrad-mcp and no args (stdio). Pass ir inline or irPath to a JSON file for large graphs. archrad_suggest_fix returns curated text for a finding code (e.g. IR-LINT-MISSING-AUTH-010) β not machine-generated IR patches. Step-by-step testing (smoke script, MCP Inspector, Cursor chat prompts): docs/MCP.md, section Local testing.
Input is structured IR (JSON), not natural language. There is no archrad export --prompt "...". Pass a graph file (nodes/edges).
Fixtures (in this repo): fixtures/minimal-graph.json (small); fixtures/demo-direct-db-violation.json / fixtures/demo-direct-db-layered.json (before/after IR-LINT-DIRECT-DB-ACCESS-002); fixtures/ecommerce-with-warnings.json (many lint rules); fixtures/payment-retry-demo.json (retry-related codegen in export). --target python is the FastAPI bundle; there is no separate fastapi target. To go from plain English β IR, use ArchRad Cloud or your own LLM step; this package only does IR β files.
Recording demos and GIFs (VHS, storyboards, drift replay): scripts/README_DEMO_RECORDING.md only β not required to use the CLI.
OpenAPI β JSON (spec as source of truth): each operation under paths becomes an http node (config.url + config.method). Then validate and export like any other IR:
OpenAPI security β IR β lint: ingestion copies global and per-operation security requirement names onto each HTTP node as config.security (sorted, deterministic). An operation with explicit security: [] becomes config.authRequired: false (intentionally public). If the spec declares no security at any level, nodes are left without those fields β then archrad validate can surface IR-LINT-MISSING-AUTH-010 on HTTP-like entry nodes (compliance gap from the spec artifact alone).
YAML β JSON (lighter authoring): edit fixtures/minimal-graph.yaml (or your own file) and compile to IR JSON, then validate or export:
YAML must have either top-level graph: (object) or top-level nodes: (array); bare graphs are wrapped as { "graph": { ... } } automatically.
After npm install -g or npx (typical):
From a git clone (contributors): run npm ci && npm run build in the package root (there is no prepare hook β see docs/ENGINEERING_NOTES.md), then use node dist/cli.js the same way you would use archrad (e.g. node dist/cli.js validate --ir fixtures/minimal-graph.json).
Deterministic drift (thin, OSS): compare an existing export tree on disk to a fresh export from the same IR. Detects missing / changed generated files (line endings normalized). Optional --strict-extra flags files present on disk but not in the reference export. Not semantic βdoes code match intentβ β ArchRad Cloud adds builder/UI drift checks and broader governance.
Example output (stderr):
Structural errors look like β IR-STRUCT-... with Fix: lines. Use --json to consume findings in GitHub Actions or other CI.
--ir β JSON: { "graph": { "nodes", "edges", "metadata" } } or a raw graph (CLI wraps it).--target β python | node | nodejs--out β output directory (created if needed)--host-port <n> β host port Docker publishes (default 8080; container still listens on 8080 inside). Same as env ARCHRAD_HOST_PORT.--skip-host-port-check β donβt probe 127.0.0.1 before export.--strict-host-port β exit with error if the host port appears in use (CI-friendly).--danger-skip-ir-structural-validation β UNSAFE: skip validateIrStructural before export (never in CI). Parse/normalize failures (invalid root, empty graph) are still detected via validateIrLint and block export with IR-STRUCT-* in irStructuralFindings. A hidden --skip-ir-structural-validation remains as a deprecated alias.--skip-ir-lint β skip validateIrLint during export.--fail-on-warning / --max-warnings <n> β if set, no files are written when IR structural + lint findings violate the policy (same semantics as validate).By default, if 8080 (or your --host-port) looks busy on localhost, the CLI warns so you can change the port before docker compose fails with a bind error.
Export runs IR structural validation, then architecture lint, then codegen. Structural errors abort with no files written. irLintFindings contains only IR-LINT-*; IR-STRUCT-* from a failed parse always appear under irStructuralFindings (including when structural validation was skipped). Lint warnings print by default; use --fail-on-warning / --max-warnings to block writes for CI.
Optional: isLocalHostPortFree / normalizeGoldenHostPort from the same package if you want your own preflight.
This path assumes you cloned the repo and ran npm ci && npm run build in the package root. If you only installed with npm install -g @archrad/deterministic, use archrad instead of node dist/cli.js (same flags).
You should see 422 Unprocessable Entity (FastAPI/Pydantic) or 400 with a clear body β proof the stack is live and validation matches the spec, not a silent 500.
Quick check from a clone: cd packages/deterministic && npm ci && npm run build && npm test, then export to ./tmp-out, cd tmp-out && make run, curl as above. Use --host-port 18080 (or node dist/cli.js export ... --host-port 18080) if 8080 is busy.
Optional: bash scripts/golden-path-demo.sh runs the same flow. Demo recording (GIFs, tapes, drift replays): scripts/README_DEMO_RECORDING.md.
This repository is only the deterministic engine β local, offline, no phone-home.
| Here (OSS) | ArchRad Cloud (commercial product) |
|---|---|
IR structural + architecture lint (validate, IR-STRUCT-*, IR-LINT-*), compiler (export), validate-drift (on-disk vs fresh export), OpenAPI document-shape warnings, golden Docker/Makefile | Policy engine, deeper architecture intelligence, AI remediation, richer drift / sync UX in the builder |
archrad CLI forever, no account required for this package | Auth, orgs, quotas, billing |
| No proprietary LLM orchestration or βrepairβ loops | LLM generation, repair, multi-model routing |
| No Git sync, no enterprise policy injection in this repo | Git push, governance, compliance dashboards |
You can depend on this CLI and library without ArchRad Cloud. The cloud product stacks collaboration and AI on top of the same deterministic contract.
See CONTRIBUTING.md.
Apache-2.0 β see LICENSE.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/deterministic)<a href="https://allmcps.com/mcp/deterministic"><img src="https://allmcps.com/api/badge/deterministic?style=directory" alt="Deterministic on AllMCPs" /></a>