FINOS CALM v1 · MCP-NATIVE · BYOC

Architecture governance for the AI-agent era
Code-gen-time + PR-time. Same engine.

ArchRails is the only governance product that gates AI agents before they write code — then enforces the same rules at PR-time. Agentic-friendly auth, federated cross-repo enforcement on the FINOS CALM v1 standard, audit-grade evidence, BYOC deployment. Built for regulated institutions.

Built on FINOS CALM v1 OSFF London 2026 speaker Patent pending · Filed March 2026 Works with Claude Code · Cursor · Windsurf · Copilot · autonomous agents No customer source code stored — architecture files only
Cursor · services/trade-service/persistTrade.ts
1 Agent attempts
logger.info(`tax_id=${trade.tax_id}`)
ArchRails intercepts
no-pii-in-logs · matched: tax_id
"Tax IDs are PII; logs are not the audit trail."
Agent retries (compliant)
logger.info(`trade=${trade.id}`)
Every other governance product catches this at PR-time, after the wrong code is already written. ArchRails catches it before the agent's diff exists.
2 surfaces
Code-gen time + PR time
FINOS CALM
Open architecture standard
MCP
Open IDE protocol — works with any agent
0
Source files stored

The only product that gates AI agents at code-gen time

Every other architecture / governance / lint tool waits for PR-time. By then your agent has already written the wrong code. ArchRails runs inside the agent's MCP session — your controls fire before the diff exists. Then the same engine runs at PR-time as backstop.

Agentic-friendly auth

Long-lived API keys for AI agents, CI pipelines, and IDE plugins. Humans sign in once at the dashboard to issue a key; agents then run headless. No interactive browser sign-in mid-coding. Designed for autonomous workflows from day one.

Architecture is read-only to agents

Agents can't edit your CALM files to make non-compliant code legal. Architecture changes go through your normal human-reviewed PR process. The gate can't be rewritten by the thing it's gating.

Same engine at PR-time

If an agent is bypassed (raw git push, manual edit, a different agent), the merge gate runs the identical Python functions and still catches the violation. Two surfaces, one source of truth.

BYOC — Bring Your Own Cloud

Your code, your perimeter, your audit trail

ArchRails deploys into your AWS account. Your code never leaves your perimeter. The control plane runs in your VPC; architecture files, graphs, and audit artifacts stay in your buckets and your KMS keys. Audit-evidence bundles are written to your storage, not ours. GCP and Azure on the roadmap, available on request.

Cloud
AWS
Data residency
Your VPC · Your buckets · Your KMS keys
Evidence destination
Audit-evidence bundles to your storage

Two surfaces. Same brain. One product.

Architecture governance has lived at PR review forever. ArchRails keeps it there — and ALSO pushes the same rule engine into your IDE so agents catch violations before any code is written. Devs ship faster. Regulators still get the audit trail.

Code-gen time

Inline in your agentic IDE

Architecture policy applied at the agent layer — before any code is written. Implemented as an MCP server the agent connects to over a stable URL. When the agent attempts a change that violates your declared CALM architecture, ArchRails returns a deterministic deny with the relevant context, and the agent proposes an alternative that respects the architecture.

  • Same rule engine as PR-time (literally the same Python functions)
  • Works with any MCP-speaking agent — Claude Code, Cursor, Windsurf, autonomous agents in CI
  • Per-key audit log: every refusal records request_id, tenant, source IP, and the rule that fired
PR time

The authoritative merge gate

Every pull request runs through the full rule engine against the real diff. Verdicts post as inline review comments. High-severity violations block the merge. This is the auditable surface — the answer to "what enforces architectural compliance here?".

  • Catches anything the IDE-time check missed (or anyone bypassed)
  • Every verdict cites the exact CALM node / relationship / control
  • Drift detection: code-vs-architecture comparison on demand
Identical Python rule functions run in both surfaces. Drift between them is regression-tested in CI.
PR verdicts post in seconds, not minutes — built to keep merge velocity intact.

Cursor attempts a forbidden DB call during a 3 AM hotfix. ArchRails MCP blocks it inline; the agent rewrites against the CALM-permitted intermediary. Production stays in PCI scope.

Generic AI review bots
Trained on open-source patterns. Suggests "best practices." Comments are confident but untraceable — no source, no context, no connection to your team's actual decisions.
ArchRails
Enforces your declared CALM architecture from Git. Every comment links back to the exact node, relationship, or interface it was derived from. Violations are provable — not guesses.
Architecture catalogs (Backstage, Cortex, Port, LeanIX, Ardoq)
Catalogs describe what shipped. They surface architecture after the fact and rely on humans to keep them in sync. Useful for inventory, not for stopping a violation from merging.
ArchRails
Enforces architecture at PR time and at code-gen time — the catalog is the merge gate, not a report. Drift can't accumulate because non-conforming changes never land.
Built on CALM — the open standard

ArchRails enforces architecture defined in FINOS CALM (Common Architecture Language Model) — an open standard maintained by the Fintech Open Source Foundation, not a proprietary YAML we invented.

Your architecture isn't locked in our format. The CALM JSON files describing your services, dependencies, and controls live in your repo, in your version control. If you ever leave ArchRails, your CALM files come with you and stay readable by every other CALM tool. New to CALM? Start with the FINOS tutorials.

On top of CALM, ArchRails layers per-tenant rules and bindings — deterministic structural verification at PR-time and at code-gen time, plus a contextual LLM explanation layer in the PR comment. Machine-verifiable constraint checking and human-readable guidance in the same review.

Architecture reviews you can trust

ArchRails doesn't invent standards. It enforces what your team defines in a CALM document, and cites every node it used.

No undocumented rules enforced

If a node, relationship, or interface constraint isn't in your calm.json, ArchRails won't enforce it. Full stop.

Every comment is CALM-traceable

Feedback cites the exact CALM node ID, relationship ID, or interface that triggered it — so teams align faster and argue less.

PR-scoped bounded context

Reviews resolve only the CALM nodes touched by the PR diff. Less noise, fewer false positives, no cross-service contamination.

Live Demo — Fully Interactive

Every PR shows exactly what it touched — and what it broke

This is the architecture graph ArchRails renders for every pull request. Drag nodes. Hover for details. Click any node to see how violations trace back to your CALM definition.

Architecture Graph · PR #847 — feature/order-refactor
2 violations detected · drag nodes · scroll to zoom
Service
Database
Actor
System
Violation
External
⚡ 2 violations
✓ 1 passed
🏗️ CALM Architecture Review
Relationship violation
OrderService calls PaymentService directly — must route via service-api-gateway
rel-connects-order-payment
Interface breach
OrderDatabase accessed via HTTP — node declares JDBC:5432 only
db-orders · iface-orders-sql
Node boundary respected
InventoryService changes scoped to service-inventory — no leakage
CALM sources: calm.json · rel-connects-order-payment calm.json · db-orders
Click any node above to inspect it Validate your own architecture
Audit-evidence posture

Built for regulated change-management

Evidence bundle
Per governed merge
Every governed merge produces a signed manifest: pre-merge approver, rule set applied, change diff hash, CALM snapshot. Generated automatically; written to your storage in your AWS account.
Chain of custody
Tamper-evident
Cryptographic hash chain from CALM definition to deployed artifact. Retention policy + access logs + offline-verifiable signatures — exportable in audit-ready format on demand.
FINOS CALM v1
Open standard
Architecture lives in your repo as portable CALM JSON. No proprietary YAML. Maintained by FINOS (Fintech Open Source Foundation). Your architecture isn't locked in our format.
CALM Visualizer — Free

Validate and visualize your CALM architecture before it ships

Paste your calm.json to instantly check for interface violations, missing controls, and structural issues — then render your architecture graph interactively. No account required.

  • Validates against FINOS CALM v1 schema
  • Interactive architecture graph with node detail panel
  • Flags relationship and interface violations inline
  • Free to use — no login, no limits
Open CALM Visualizer
Architecture Graph
● 6 nodes · 9 relationships
👤 Customer
⚡ API Gateway
📦 Order Service
⚠ Inv. Service
💳 Payment
🗄 Order DB
🗄 Inventory DB
■ Service ■ Database ■ Actor ■ Violation
✓ Workflow-file only — no app install
Drop a single workflow file into .github/workflows/. Works with self-hosted runners, GitHub Enterprise Server, and air-gapped environments. Architecture review fires on every PR.
ℹ How auth works
Tenant resolution uses ARCHRAILS_TENANT_ID and auth uses X-ArchRails-Token. GITHUB_TOKEN is auto-provisioned by Actions.

Drop this file into .github/workflows/archrails.yml. Set three repository secrets — GITHUB_TOKEN is provided automatically by GitHub Actions.

.github/workflows/archrails.yml
Add to your repo
# ArchRails Architecture Governance — GitHub CI Mode
# Required secrets:  ARCHRAILS_TENANT_ID · ARCHRAILS_TOKEN · ARCHRAILS_WEBHOOK_URL
# GITHUB_TOKEN is auto-provisioned by Actions — no configuration needed.

name: ArchRails Architecture Check
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review]

jobs:
  archrails-check:
    name: Architecture Governance
    runs-on: ubuntu-latest
    permissions:
      contents: read         # read repo contents for diff fetch
      pull-requests: write   # post review comments
      statuses: write        # write commit status

    steps:
      - name: Send PR event to ArchRails
        env:
          ARCHRAILS_TENANT_ID: ${{ secrets.ARCHRAILS_TENANT_ID }}
          ARCHRAILS_TOKEN:     ${{ secrets.ARCHRAILS_TOKEN }}
          ARCHRAILS_URL:       ${{ secrets.ARCHRAILS_WEBHOOK_URL }}
          GITHUB_TOKEN:        ${{ secrets.GITHUB_TOKEN }}
          PR_EVENT:            ${{ toJson(github.event) }}
          RUN_ID:              ${{ github.run_id }}
          RUN_ATTEMPT:         ${{ github.run_attempt }}
        run: |
          # Inject archrails_tenant_id and github_token into the PR event payload.
          # The workflow's own GITHUB_TOKEN lets downstream Lambdas fetch the diff
          # and post review results — no separate installation token required.
          PAYLOAD=$(echo "$PR_EVENT" | jq \
            --arg tenant_id    "$ARCHRAILS_TENANT_ID" \
            --arg github_token "$GITHUB_TOKEN" \
            '. + {archrails_tenant_id: $tenant_id, github_token: $github_token}')

          HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \
            --max-time 30 \
            -X POST "$ARCHRAILS_URL" \
            -H "Content-Type: application/json" \
            -H "X-GitHub-Event: pull_request" \
            -H "X-GitHub-Delivery: ${RUN_ID}-${RUN_ATTEMPT}" \
            -H "X-ArchRails-CI: github" \
            -H "X-ArchRails-Token: $ARCHRAILS_TOKEN" \
            -d "$PAYLOAD")

          echo "ArchRails response: $HTTP_STATUS"

          # 202 = queued  |  204 = ignored (draft, disabled, etc.)
          # 4xx/5xx = configuration problem — surface it.
          if [[ "$HTTP_STATUS" -ge 400 ]]; then
            echo "::error::ArchRails rejected the payload (HTTP $HTTP_STATUS). Check ARCHRAILS_TOKEN and ARCHRAILS_TENANT_ID."
            exit 1
          fi
          echo "ArchRails review queued successfully."
Repository Secrets to configure
ARCHRAILS_TENANT_ID Your tenant ID — from the dashboard after provisioning.
ARCHRAILS_TOKEN Per-tenant shared secret — provided during provisioning.
ARCHRAILS_WEBHOOK_URL Your endpoint, e.g. https://api.archrails.io/webhook
GITHUB_TOKEN ✓ Auto-provisioned  No setup needed.
Talk to sales

GitLab integration runs via CI pipeline. Add the job below to your .gitlab-ci.yml and set three CI/CD variables.

.gitlab-ci.yml
Add to your repo
stages:
  - review

archrails_review:
  stage: review
  image: alpine:3.20
  rules:
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  before_script:
    - apk add --no-cache curl
  script:
    - |
      curl --silent --fail -X POST "${ARCHRAILS_ENDPOINT}" \
        -H "X-Gitlab-Token: ${GITLAB_WEBHOOK_SECRET}" \
        -H "X-Gitlab-Event: Merge Request Hook" \
        -H "Content-Type: application/json" \
        -d "{
          \"archrails_tenant_id\": \"${ARCHRAILS_TENANT_ID}\",
          \"object_kind\": \"merge_request\",
          \"project\": {
            \"id\": ${CI_PROJECT_ID},
            \"path_with_namespace\": \"${CI_PROJECT_PATH}\"
          },
          \"object_attributes\": {
            \"iid\": ${CI_MERGE_REQUEST_IID},
            \"action\": \"update\",
            \"last_commit\": { \"id\": \"${CI_COMMIT_SHA}\" }
          }
        }"
CI/CD Variables to set
ARCHRAILS_ENDPOINT — provided on provisioning
GITLAB_WEBHOOK_SECRET — provided on provisioning
ARCHRAILS_TENANT_ID — your organization ID
Talk to sales

Common questions

CALM (Common Architecture Language Model) is a FINOS open standard for describing architecture as machine-readable JSON. We use it because it solves a problem that has quietly worsened for 15 years: ask five engineers to draw your system's architecture and you get five different pictures — a point Google's Adam Bender called out at SE@TP 2026. CALM ends the divergence: one declared graph that every human, every coding agent, and every CI step reads off, with deterministic verification on top.
No. After you connect a repo, ArchRails generates the initial declaration for you — you review it, merge it, and enforcement starts. If you'd rather author by hand, the free CALM Visualizer is available with no account required. Declaring the architecture once is the fundamental that lets AI amplification go in a useful direction; without it, more agents just means more entropy.
No. ArchRails runs as a GitHub Actions / GitLab CI step in your own pipeline, processes the PR diff in memory, posts a review comment, and discards the data. Your source code is never copied, indexed, or stored. The CI workflow uses your repo's existing CI token — ArchRails never holds repo-wide credentials.
Copilot and generic AI review bots score code against general best practices learned from open-source training data. They have no idea what your system is or isn't supposed to do. ArchRails enforces your declared architecture — the specific nodes, allowed connections, controls, and interface contracts in your calm.json. Every comment is traceable to a node ID you authored. It's deterministic, not probabilistic, and the same gate runs at PR time and inside the coding agent — so the agent can't reach an API your architecture forbids. As Adam Bender put it at SE@TP 2026: “all of your APIs just became public” the moment you let agents loose. ArchRails is the contract that says which ones they're allowed to call.
Agents write whatever you let them write. The default behaviour is to find any API they can call and call it. ArchRails sits in front of the agent. Before a code change lands, the agent attests the proposed change against your architecture and gets back a deterministic verdict. Violations come back with the node ID, the rule that was broken, and sanctioned alternatives — the agent doesn't get to negotiate, and it doesn't waste tokens generating a path that would never have merged.
Yes. A single calm.json at the repo root describes your full system graph, and ArchRails only evaluates the slice of the graph a given PR actually touches — a payment-service change won't trigger inventory-service checks. This is deliberate: dependency graphs scale quadratically with codebase size, so at the 10× AI-driven velocity everyone is preparing for, evaluating everything on every PR is how you burn your test budget into the ground.
Because adding probabilistic review on top of a system you can't reason about doesn't get you intellectual control — it gets you a louder bottleneck. As Bender put it at SE@TP 2026, AI is an amplifier: magnitude, not direction. The deterministic CALM check is the fundamental layer: same engine, same verdict, every PR and every agent call. The LLM sits on top — translating the verdict into a readable PR comment, suggesting which sanctioned node to use instead. We use AI to explain a verdict; we never use it to be the verdict.
Two paths. Request a demo to walk through architecture governance with the founding team and scope the right engagement shape. Start a free 14-day eval for self-provisioned hands-on access — corporate email required, full access to shipped features. On day 15 the tenant moves to read-only until an annual contract is signed.

Built by an engineer who's lived design drift

Marc Daniel Registre

Marc Daniel Registre

Founder & Engineer

ArchRails started as a practical system: keep architecture consistent as teams scale — without relying on tribal knowledge. By grounding reviews in a CALM architecture graph rather than generic training data, every violation is provable and every comment is traceable.

Make architecture review automatic — and provable

Start with one repo and one CALM document. ArchRails will enforce it on every pull request.

Request a demo Try CALM Visualizer