@archrad/deterministic

OSS Architecture

Deterministic compiler and linter for system architecture. No AI, no network calls, no cloud dependency. Click any component for detail.

Component view — click any node for detail
entrypoints
archrad CLI (cli.ts)
archrad-mcp (mcp-server.ts)
library core (index.ts)
normalizeIrGraph
validateIrStructural
validateIrLint
PolicyPack loader
LINT_RULE_REGISTRY
buildParsedLintGraph
deterministic codegen
runDeterministicExport
pythonFastAPI.ts
nodeExpress.ts
golden-bundle.ts
post-export checks
OpenAPI structural
runValidateDrift
Data flow — IR JSON to findings or exported code
input
IR JSON { graph: { nodes[], edges[] } }
normalize + materialize (internal to validateIrStructural)
validation pipeline — structural first, lint only if no structural errors
validateIrStructural → IR-STRUCT-*
if no errors →
validateIrLint (builds ParsedLintGraph internally) → IR-LINT-*
PolicyPack visitors compiled → input to lint (optional)
sortFindings (errors first)
output — validate path
IrStructuralFinding[] { code, severity, message, nodeId?, fixHint? }
output — export + drift path
runDeterministicExport
Export file map Record<path, contents>
runValidateDrift → DRIFT-MISSING / DRIFT-MODIFIED
archrad validate flow
Read IR from --ir path
validateIrStructural\nnormalize → IR-STRUCT-*
hasIrStructuralErrors?
yes →
skip validateIrLint
no →
validateIrLint\n+ optional PolicyPack
sortFindings / print or --json
fail →
exit 1
pass →
exit 0
Exit policy: error severity always fails. Warnings fail only with --fail-on-warning or --max-warnings N.
archrad validate-drift flow
Read IR + --out (export directory)
runValidateDrift
normalize + structural + lint\n(export build pass)
runDeterministicExport in memory
diff expected vs on-disk files
DRIFT-MISSING / DRIFT-MODIFIED findings
exit code from combined findings + policy
MCP session (stdio) — tools delegate to same library core as CLI
IDE / host → stdio JSON-RPC
archrad-mcp receives tool call
archrad_validate_ir
normalize\n→ structural\n→ lint
archrad_validate_drift
runValidateDrift\n(same as CLI)
archrad_suggest_fix
getStaticRuleGuidance\n(no network)
findings JSON → IDE
Security model — what stays local
CUSTOMER MACHINE / VPC
IR graph JSON
@archrad/deterministic engine
PolicyPack YAML / JSON
Findings output
Exported code files
archrad-mcp (stdio only)
trust boundary
EXTERNAL (OSS MODE)
No telemetry
No network calls
No auth tokens
No data egress
No network port opened
Air-gap capable — works with zero internet access after install.
MCP transport — stdio only in OSS. No port opened.
No native deps — pure JS, no binary extensions.
Node ≥ 20 required. No cloud SDK dependencies.
Built-in IR-LINT rules — all deterministic, no AI in validation path
Code What it catches Sev
IR-LINT-SYNC-CHAIN-001Sync dependency chain depth ≥ 3 from HTTP entry (async edges excluded)warning
IR-LINT-DIRECT-DB-ACCESS-002HTTP-like node connects directly to datastore — no service layerwarning
IR-LINT-NO-HEALTHCHECK-003No HTTP node exposes /health, /healthz, /ping, /status, /ready, /livewarning
IR-LINT-HIGH-FANOUT-004Node has ≥ 5 outgoing edges (threshold fixed at 5 in OSS)warning
IR-LINT-ISOLATED-NODE-005Node with no edges when graph has edges elsewherewarning
IR-LINT-DUPLICATE-EDGE-006Same from→to pair appears more than oncewarning
IR-LINT-HTTP-MISSING-NAME-007HTTP-like node has no display name fieldwarning
IR-LINT-DATASTORE-NO-INCOMING-008Datastore node has no incoming edgeswarning
IR-LINT-MULTIPLE-HTTP-ENTRIES-009Multiple HTTP entry nodes with no incoming edgeswarning
IR-LINT-MISSING-AUTH-010HTTP entry node has no auth node or auth config (often relevant to PCI-DSS / HIPAA compliance contexts)warning
IR-LINT-DEAD-NODE-011Node receives edges but has no outgoing edges (non-sink types only)warning
Extension points
PolicyPack — declarative YAML/JSON (no TypeScript required)
apiVersion: archrad/v1
kind: PolicyPack
rules:
  - id: ORG-NO-DIRECT-DB
    message: Services must not connect directly to databases
    severity: error
    match:
      edge:
        from: { type: service }
        to: { type: database }
Load: archrad validate --ir ir.json --policies ./policies/
MCP: archrad_validate_ir { policiesDirectory: "./policies" }
Custom lint visitors — TypeScript API
import { validateIrLint } from '@archrad/deterministic';

const myRule = (g: ParsedLintGraph) => {
  // inspect g.nodeById, g.edges, g.adj
  return [];
};

const findings = validateIrLint(ir, {
  policyRuleVisitors: [myRule]
});
Adding built-in rules — append to registry
// lint-rules.ts
export function ruleMyNewRule(g: ParsedLintGraph) {
  return [];
}

export const LINT_RULE_REGISTRY = [
  ...existingRules,
  ruleMyNewRule, // ← append here
];