Skip to main content
Causeloop is two sibling repositories that must be checked out next to each other: the FastAPI/Python backend (/Users/rushabhpatel/Desktop/causeloop.ai/backend, this repo) and the Next.js/TypeScript frontend (/Users/rushabhpatel/Desktop/causeloop.ai/frontend). The product Compose stack builds the frontend’s Dockerfile by relative path (../../frontend from infra/docker-compose.product.yml), so the two checkouts must share a parent directory before any product-mode command will succeed. This page covers what to install and how to verify the install. For what to actually run day to day, see Local product stack.

Toolchain

The frontend repo’s own package.json does not pin an engines field. Treat it as subject to the same Node 20+ / npm 10+ baseline the doctor enforces on the backend side — the two frontends (the product console and the research workbench) are built and tested together and there is no supported reason to run them on different toolchains.

Install commands

From the backend repository root:
  • uv sync --dev installs the locked runtime and dev dependency groups (pytest, pytest-asyncio, ruff) from uv.lock, including the workspace-local causegraph package ([tool.uv.workspace] members = ["packages/causegraph"]). It’s required for the basic/mvp1/relational research modes and for running backend checks on the host (uv run ruff check ., uv run pytest). Product mode’s own tooling doesn’t need it: scripts/check_local_setup.py and scripts/smoke_product.py import only the Python standard library and run with a bare python3 — no venv or uv install required, per AGENTS.md.
  • npm ci --prefix apps/web installs the legacy research workbench’s pinned dependencies (apps/web/package-lock.json) — the Vite/React 18 SPA behind basic/mvp1/relational modes. It is not required for product mode, which never starts apps/web.
From the sibling frontend repository root (../frontend relative to this repo):
This installs the production Next.js 15 / React 19 console’s locked dependencies (package-lock.json). It’s required to run the frontend outside its container (npm run dev) and to run its own checks (npm run typecheck, npm test, npm run build, npm run e2e). It is not required to run the containerized product stack end to end — the frontend’s own Dockerfile installs dependencies inside the image from the same lockfile.
The backend’s Makefile wraps the first two commands into one target, make setup (command -v uv >/dev/null || brew install uv, then uv sync --dev, then cd apps/web && npm install). It doesn’t touch the sibling frontend checkout — you still run npm ci there yourself. AGENTS.md is explicit that no Make command is required or expected for product-mode work; treat make setup as a macOS convenience for engineers working in the legacy research modes, not as the canonical path.
Product mode needs no host-side Node/npm install at all if you only intend to run the containers: docker compose -f infra/docker-compose.product.yml up -d --build builds both the backend and frontend images from their respective Dockerfiles using the committed lockfiles. Install Node locally only when you need frontend hot reload or want to run its checks directly on the host.

The setup doctor

scripts/check_local_setup.py is a local, non-mutating verifier: it never calls OpenAI, never contacts a remote service, and never prints a secret value — only whether one is configured. Run it before claiming any mode is ready to use, and re-run it as the first troubleshooting step whenever something doesn’t come up.
or, for the historical research modes:
Add --json to either form for machine-readable, secret-safe output for tooling and code agents that need to parse results.
Checks: Python 3.12+, Docker Compose v2 (docker compose version), a reachable Docker daemon (docker info), and that the sibling source layout is intact — the backend’s Dockerfile, infra/docker-compose.product.yml, and services/api/product_app.py, plus the sibling frontend’s Dockerfile, package.json, and package-lock.json. If those all pass, it additionally renders docker compose -f infra/docker-compose.product.yml config and asserts the product worker advertises its full job-type contract (materialize_insights,send_email,train_tenant_model) and that the local Mailpit/S3-compatible provider parity markers are present. This is the mode documented in Local product stack.
Checks: Python 3.12+, uv, Node 20+, npm 10+, the .venv created by uv sync --dev, apps/web/node_modules created by npm ci --prefix apps/web, and the integrity of the tracked synthetic banking dataset (docs/issue-set-2-records.json — exactly 250 records, unique IDs, all governed fields populated). No Docker, no OpenAI key.
Everything basic checks, plus that an OPENAI_API_KEY is configured (value never printed) — required because this mode sends de-identified issue fields to OpenAI for a strict analysis run.
Everything mvp1 checks, plus Docker Compose v2, the presence of infra/causeloop.local.env, a live socket check against the configured Postgres DSN, an alembic current check that the database is at head, and that a Node runtime exposes the @oai/artifact-tool package (via CAUSELOOP_NODE_PATH or a bundled workers/artifacts/node_modules install) used by the reviewed-workbook exporter.
The doctor’s exit code is 1 if any check fails; each failing check prints its own fix instruction. Always act on the first failing check rather than the whole list — later checks frequently depend on earlier ones (for example, the relational migration check is skipped entirely if the Postgres socket check already failed).

Choosing a mode

product is the only mode that reflects the deployed system. The basic/mvp1/relational modes described here and in Research modes support the older embedded research workbench and are not part of the production boundary — see Backend repo tour for how the repo separates the two.
Pick the smallest mode that covers the work in front of you: