docker-compose.yml — 30 services
How CausalAgent is actually wired together
One docker compose up boots three things at once: a synthetic storefront that generates OpenTelemetry traffic, the CausalAgent pipeline that turns those traces into a causal graph, and a pair of LLM judges that run alongside a customer's own agent. This is the path a request actually takes, and every service in the stack.
Astronomy Shop — demo traffic source Ingestion — OTel Collector · Variable Extractor CausalAgent core — the product LLM Judges — standalone, customer-deployed
- 1 Envoy routes into the shop and, in parallel, into checkout.
- 2 Every shop service and checkout-agent emit OTel spans.
- 3 The Collector forwards everything to the extractor.
- 4 Typed variable rows land in ClickHouse and Redis.
- 5 The engine reads ClickHouse and discovers a DAG.
- 6 The API orchestrates engine + storage + extractor.
- 7 The dashboard renders the graph.
Every service, for reference
The diagram above collapses the shop's eleven microservices into one box to keep the mechanism readable. This table doesn't — every container in docker-compose.yml, grouped the same way.
CausalAgent core6
| Service | Port(s) | Role |
|---|---|---|
| variable-extractor | :8001 | Ingest boundary — OTel spans in, typed variable rows out, PII blocklist enforced here. |
| causal-engine | :8002 | Reads ClickHouse, runs PC / PCMCI+ / FCI / DAGMA-DCE / LiNGAM / BF-BIC / KSG / Transfer Entropy / DoWhy / EconML, produces the DAG. |
| api | :8000 | Public HTTP surface — orchestrates engine, storage, and extractor; the only thing the dashboard and MCP clients talk to. |
| dashboard | :5173 | React + TypeScript + D3 UI — Investigate, Lenses, Operate, Simulate workspaces. |
| clickhouse | :8123 · :9000 | Columnar store for extracted trace variables and causal graphs. |
| redis | :6379 | Cache and stream buffer between the extractor and downstream consumers. |
Astronomy Shop — synthetic storefront18
| Service | Port(s) | Role |
|---|---|---|
| otel-collector | :4317 · :4318 · :8889 | Every shop service's OTel exporter points here; forwards on to variable-extractor. |
| frontend-proxy | :8081 | Envoy — the storefront's public entry point, routes to every backend service. |
| frontend | — | React storefront UI, served behind the proxy (no directly exposed port). |
| load-generator | :8089 | Locust — auto-starts 20 simulated users against the storefront. |
| checkout | :5050 | Orchestrates cart, currency, payment, shipping; calls checkout-agent for the LLM decision gate. |
| checkout-agent | :8090 | LLM-powered checkout decision gate — emits gen_ai.* spans (tokens, latency, hallucination flags). |
| ollama | :11434 | Local LLM runtime — serves checkout-agent and product-reviews (gemma3:1b by default). |
| cart | — | Backed by valkey-cart. |
| currency | :7001 | Currency conversion. |
| payment | — | Injected failures, gated by flagd. |
| shipping | — | Calls quote for rate generation. |
| quote | — | Shipping-quote generation, used only by shipping. |
| product-catalog | :8088 | Postgres-backed; gated by flagd. |
| product-reviews | :3551 | Postgres + Ollama-backed LLM review generation. |
| recommendation | — | Reads product-catalog. |
| ad | — | Ad service with deliberately injected latency. |
| image-provider | — | Serves product images. |
| — | Order-confirmation email stub. |
Shop infrastructure4
| Service | Port(s) | Role |
|---|---|---|
| kafka | :9092 | Async event bus for the shop's own internal messaging. |
| postgresql | — | Backs product-catalog and product-reviews. |
| valkey-cart | :6380 | Redis-compatible store dedicated to the cart service. |
| flagd | — | Feature flags — gates injected failure scenarios across the shop. |
LLM judges — standalone, customer-deployed2
| Service | Port(s) | Role |
|---|---|---|
| hallucination-judge | :8091 | Scores a (prompt, completion) pair for hallucination. Runs beside the customer's own agent — text never leaves the container. |
| groundedness-judge | :8092 | Scores whether an answer is derived from its retrieved context or fabricated. Same privacy contract as its sibling. |