ArchitectureControl plane + runtime planeOperator proof

The system only feels coherent when request ingress, evaluator logic, and operator proof are reading the same contract.

This architecture is not a generic stack diagram. It is the actual split between the application surface, gateway edge, runtime evaluator, and operator-facing control plane that already exists in the repo.

application ingressgateway edgeruntime evaluatordecision receiptsdashboardclimcpapplication ingressgateway edgeruntime evaluatordecision receiptsdashboardclimcp

Layer map

System split

Each layer owns a specific part of the truth: ingress, routing, live evaluation, or operator context. The problem starts when one side pretends to own all of them.

App surface

Framework wrappers and direct SDK calls are the ingress line.

Protected traffic begins in the adapter or direct client that owns the request lifecycle inside the application.

Framework packages + @cosantoir/node

Gateway edge

Public paths stay stable while traffic is routed to the correct upstream.

The gateway is where auth and service routing can evolve without forcing application teams to relearn the public contract.

services/api-gateway

Runtime plane

Evaluator routes decide allow, deny, challenge, and budget state.

The runtime plane turns request context into a concrete decision and emits receipts that other surfaces can read later.

services/dev-eval

Control plane

Policies, tenancy, usage, and analytics stay in the operator-facing service.

The control plane owns policy CRUD, site semantics, and analytics views without becoming the request path itself.

services/dev-protection + apps/developer

Runtime sequence

Request journey

Follow one protected request through the stack. That is the fastest way to see which component owns which decision.

01

Application ingress

The wrapper or direct client derives method, path, site id, user agent, IP, and optional user identity before any evaluator call happens.

02

Contract selection

Gateway origin, runtime key, and site id determine which evaluator route and policy partition are even in play.

03

Runtime evaluation

WAF, budgets, email checks, signup risk, IP intelligence, and bot logic resolve into a concrete decision.

04

Receipt emission

The runtime plane returns headers such as `x-request-id`, `x-correlation-id`, `Retry-After`, and `X-RateLimit-*` when relevant.

05

Operator proof

Dashboard views, CLI probes, and MCP tools read the same runtime truth instead of reconstructing behavior from symptoms.

Contract line

Three shared values

Gateway origin, runtime key, and site id are the line that keeps app code, evaluator services, and operator tooling in agreement.

Receipt line

Returned proof

Request ids, correlation ids, and rate-limit headers make the runtime explainable after the fact.

Stable invariants

Shared contract

The contract is not the internal topology. It is the request semantics, credential line, and evaluator routes that application teams actually depend on.

Stable public paths
/v1/dev/waf/evaluate
/v1/dev/bot/evaluate
/v1/dev/ip/lookup

Boundary map

Stable contract, mutable topology

text
01Stable public contract
02 /v1/dev/waf/evaluate
03 /v1/dev/bot/evaluate
04 /v1/dev/ip/lookup
05 
06Mutable internal topology
07 services/api-gateway -> routing + auth edge
08 services/dev-eval -> live evaluator routes
09 services/dev-protection -> policies, tenancy, analytics

Correlated investigation

Operator proof

The center narrative is incomplete if the right side cannot verify it. Dashboard views, CLI probes, and MCP tools are how the architecture proves itself.

Dashboard

Visual investigation lane

Use the web surface when teams need policy edits, usage views, and decision trails in one place.

CLI

Terminal investigation lane

Use the CLI when login, request probes, and telemetry audits are faster than clicking through the UI.

MCP

Agent investigation lane

Use MCP when an internal model needs bounded access to evaluator context without general system access.

Design discipline

Boundary rules

The architecture gets stronger when each layer stops leaking into the wrong job and starts returning usable proof to the rest of the system.

Keep evaluator routes and receipt headers stable even if service ownership changes behind the gateway.

Do not force the control plane to become the live request path just because it owns policy state.

Do not let CLI and MCP invent their own configuration logic; they should use the same contract line as the SDK.

Design each rail so it explains the same sequence the main content is teaching.

Last updated Mar 24, 2026