Skip to content

ADR 0001 — Architecture baseline

  • Status: Accepted
  • Date: 2026-05-03
  • Decision drivers: the two source design docs (Stock_Factor_Graph and Stock_KG_Schema_and_LLM_Integration); a hard requirement that the whole project be hostable on GitHub for free, with no maintainer running cost.

Context

We are building a stock knowledge graph + LLM reasoning system. The source design docs prescribe most of the schema, query patterns, and pipeline architecture. The remaining decisions concern technology choices, repo organisation, and hosting.

Decisions

1. Property graph: Neo4j

Neo4j (Community 5.x locally; AuraDB Free for the hosted demo). Reasons: most mature Cypher implementation, free tier large enough for an S&P 100 demo (200 k nodes / 400 k relationships), the source doc treats it as the default. Alternatives considered: Memgraph (no managed free tier comparable to AuraDB), TigerGraph (proprietary GSQL, steeper integration curve).

2. Single Postgres for time-series + vectors + audit + docs

timescale/timescaledb-ha:pg16 locally; Supabase Free hosted. Reasons: one DB to operate; pgvector available; SQL ergonomics; 500 MB free tier is sufficient for indicator history + audit log + transcript embeddings for an MVP. Alternatives: InfluxDB (purpose-built for TS but adds a service); kdb+ (paid).

3. Object storage: S3-compatible

MinIO locally; Cloudflare R2 Free hosted. Reasons: S3 API is universal; R2 free tier offers 10 GB and zero egress fees, which makes it the most generous free S3-compatible option. Alternatives: GitHub LFS (size limits, paid above 2 GB); Backblaze B2 (similar free tier).

4. Backend: FastAPI in a container, deployed to Hugging Face Spaces

Reasons: HF Spaces accepts arbitrary Docker images, gives 16 GB RAM and 2 vCPU on the free tier, and provides a stable public URL. Sleeps after 48 h of inactivity but auto-wakes. Alternatives: Render free (limited RAM, sleeps, slower wake), Fly.io free (256 MB RAM is tight), Railway (no permanent free tier).

5. Frontend: Next.js with static export, hosted on GitHub Pages

Reasons: Pages is unlimited for public repos (1 GB site, 100 GB/mo bandwidth); static export avoids the need for a Node runtime; Next ecosystem is familiar. The static UI calls the FastAPI backend on HF Spaces.

6. LLM: bring-your-own-key, provider-pluggable

The user enters their own Anthropic / OpenRouter / OpenAI / local-Ollama endpoint in the UI; the key is forwarded per request and never persisted server-side. Reasons: free hosting cannot fund LLM calls. Pluggable from day one because most users on the free tier will not have an Anthropic account funded.

7. CI / scheduled ingestion / container builds: GitHub Actions

Reasons: free unlimited minutes for public repos; cron, container build/push, and Pages deploy all native; the source-doc-required ingestion cadences (daily, hourly, monthly) all express naturally as schedule: cron triggers.

8. License: Apache-2.0

Reasons: permissive enough to attract contributors; explicit patent grant matters when shipping anything LLM-adjacent. Alternatives considered: MIT (simpler, no patent grant), AGPL (forces SaaS forks open — unwanted friction for a tool meant to be embeddable).

9. Documentation: MkDocs Material → GitHub Pages

Reasons: Python-native, simple pip install-and-mkdocs serve workflow, ships with Mermaid support out of the box, looks good without theme work.

10. Repo layout: flat top-level packages

api/, kg/, orchestrator/, llm/, ingestion/, eval/, common/, ui/, schema/, docs/, tests/. Reasons: each domain has clearly different lifecycles; flat layout matches the conceptual layers of the architecture and avoids deep src/market_view/... nesting that adds nothing.

Consequences

  • Constraint: AuraDB Free is 200 k / 400 k. The hosted demo is capped at S&P 100 (with all indicators, events, and edges). Full S&P 500 will require either self-hosted Neo4j or a paid AuraDB plan.
  • Constraint: free-tier services sleep. AuraDB sleeps after 3 days of inactivity, Supabase after 7. We mitigate with a keepalive.yml weekly cron, but the demo can still cold-start (~30 s on first call after a sleep). Documented in the UI.
  • Constraint: BYOK is mandatory. Users without an Anthropic key cannot use the LLM compose stage. We keep the read-only graph queries usable without a key as a fallback (returning structured results, no prose).
  • Local-first is preserved. docker compose up reproduces the entire stack offline. The free-tier hosts are deployment targets, not dependencies — if any partner shrinks its free tier, only the public demo is affected.
  • No vendor data. Default ingestion uses only free public sources (SEC EDGAR, FRED, BLS/BEA, Treasury, GDELT, Wikidata). Bloomberg / Refinitiv / FactSet / transcript vendors live behind opt-in flags with the user's licensed access.

Open questions deferred

  • Multi-region or multi-tenant hosting. Out of scope for v1.
  • Auth on the public API. v1 uses CORS + BYOK headers; if abuse becomes a real problem, add a lightweight token + rate-limit layer.
  • Switching to a paid Neo4j once the public demo outgrows AuraDB Free. Probably never necessary for a personal/portfolio project; documented as a growth path.