Product architecture

What CausalAgent actually is, minus the demo

Nine services. One job each. An agent's own telemetry goes in one end; a causal graph of why it behaved that way comes out the other. Everything here ships to a customer — nothing here is the Astronomy Shop.

Deliberately left out: the Astronomy Shop (11 storefront microservices), its OTel Collector, Kafka, Postgres, Locust, and Ollama — that's a synthetic traffic generator for local demos and CI, not part of what ships. See the Wiring page for that full picture.
INPUT — CUSTOMER'S OWN AGENT STORAGE STANDALONE — LLM JUDGES SURFACE Customer's agentic workflow OTel SDK or their own Collector — not part of CausalAgent — OTLP · gRPC :4317 / HTTP :4318 variable-extractor the actual product boundary allowlist extraction · PII blocklist · schema-driven ClickHouse variable rows · graphs read by causal-engine Redis stream buffer / cache also read live by api causal-engine PC · FCI · PCMCI+ · DAGMA-DCE · LiNGAM BF-BIC/BOSS · KSG · Transfer Entropy DoWhy + EconML for effect sizes edge-quality graded, not just discovered api :8000 orchestrates engine + storage + extractor Dashboard React + D3 · human MCP / external agents programmatic, outside CausalAgent beside the customer's agent — privacy-preserving, verdict only hallucination-judge :8091 groundedness-judge :8092
The dotted line matters: the judges don't call into CausalAgent — they run inline with the customer's agent, score a (prompt, completion) pair locally, and only the verdict (a boolean, a label) ever leaves the container. That verdict becomes a span attribute the agent's own OTel export already carries — which is why it shows up downstream as an extracted variable without either judge ever touching the extractor directly.

Also not drawn: api queries ClickHouse, Redis, and variable-extractor directly for live status, not only through causal-engine — omitted to keep the one path that matters, discovery, uncluttered.

The nine components

What each one is for, and the one thing it depends on.

ServicePort(s)Job
variable-extractor:8001 · OTLP :4317/:4318The only ingest path. Allowlist-only extraction against a YAML schema; blocks PII before anything is written.
clickhouse:8123 · :9000Columnar store for every extracted variable row and every discovered graph.
redis:6379Stream buffer between extraction and storage; live cache for the API.
causal-engine:8002Reads ClickHouse only. Ten discovery/estimation algorithms behind one selector; grades every edge before it's trusted.
api:8000The only public surface. Orchestrates the other three; nothing external talks to them directly.
dashboard:5173React + D3 — the human-facing consumer of the API.
hallucination-judge:8091Standalone. Scores a (prompt, completion) pair; only the verdict leaves the container.
groundedness-judge:8092Standalone sibling — scores whether an answer is derived from retrieved context.
MCP / external agents—Not a CausalAgent service — any programmatic client of the API, alongside the dashboard.