Architecture

Hard rule: indexer writes Postgres only. Matcher projects Neo4j. API serves the graph. Studio is a client.

Services

Piece Role
Indexer (Go) Allowlisted eth_getLogs → typed Postgres events
Matcher (TS) Correlators → Neo4j nodes/edges; watermark on evt_base
API (TS) Hono HTTP + MCP; optional x402; disposition via rules or local composer
Rules Drools disposition; API falls back if it is down
Studio Vite app on demo.aefi.io
www This site on aefi.io

Public path

Browser → Cloudflare (DNS / WAF / Tunnel)
  ├─ aefi.io          → www
  ├─ demo.aefi.io     → studio
  └─ api.aefi.io      → API → Neo4j Aura
Indexer / matcher → Cloud SQL Postgres

Correlators

Disposition

Fact payloads go to POST /v1/disposition on the rules service. If that call fails or is disabled, a local TypeScript composer labels confidence. The envelope always names confidence_model_version.