EDGAR lakehouse
Chat with data Ask in plain English β€” every answer shows the query behind it

SEC EDGAR

Public companies file their results with the SEC, and then sometimes revise them. A revenue figure filed in February can be restated in August, and both numbers were officially filed. Most systems overwrite the old one, which quietly destroys the ability to answer "what did we believe when we made that decision in March?"

This project keeps both. Six repositories take filings from the SEC, clean and version them, and put two things in front of you: a site you can browse, and a chatbot you can ask in plain English.


Where the data comes from

SEC EDGAR

EDGAR is the SEC's public filing system β€” Electronic Data Gathering, Analysis and Retrieval. Every US public company files its annual and quarterly results there, and the whole archive is free: no key, no account, no licence. It is one of the few genuinely open financial datasets of real consequence.

This project reads three endpoints:

Endpoint What it gives
/Archives/edgar/daily-index/… the list of everything filed on one day
/submissions/CIK…json one company's filing history and profile
/api/xbrl/companyconcept/…json one financial concept for one company, across periods

Companies are identified by CIK β€” Central Index Key, the SEC's permanent id, always zero-padded to ten characters because the leading zeros are part of the URL. The API asks two things in return: no more than 5 requests a second, and a real contact email in the User-Agent header. It returns 403 without one, which is easy to mistake for a permissions problem.

The interesting part is the catch. A company can amend a filing, and the revised figure and the original are both official. Any system that overwrites the old value can no longer answer what was known at the time β€” and that question is the entire reason this project exists.

1 Β· How a filing becomes an answer

Dataflow

A container wakes up daily and downloads the day's filings exactly as the SEC returns them. Nothing is parsed at that stage, so a later mistake can be re-derived without asking the SEC again. The data then passes through three layers β€” raw, cleaned, and shaped-for-questions β€” and the last is exported as four small files that the site and the chatbot read. Neither ever touches the warehouse, so the pages stay up when the compute is asleep and no page view costs anything.

2 Β· Inside Databricks

Databricks layers

The three layers are a common pattern called medallion. Bronze keeps the raw response. Silver cleans and de-duplicates it, and rows failing a quality check move to a quarantine table rather than being dropped, so you can see what was rejected and why. Gold is shaped for the questions people actually ask.

The idea the whole project is built around lives in silver: a restatement is a new assertion, not an edit. The original figure stays, flagged superseded. That is what makes point-in-time answers possible at all.

3 Β· How the chatbot answers

Chatbot architecture

The model never calculates. It reads your question and picks one of nine fixed SQL tools plus its arguments; DuckDB runs the query, and the model reports what came back. Every figure in every answer came from a query, and each answer shows the tool trace that produced it.

That is a deliberate limit, not a missing feature. A model that writes its own SQL, or does its own arithmetic, can produce a confident wrong number that looks exactly like a right one.

4 Β· Six repositories

Repository dependencies

Repo What it does
1 Β· contracts Defines every table, column and file name once, as an installable package.
2 Β· infrastructure Terraform for every bucket, role, schedule and the host this runs on.
3 Β· ingest Pulls filings from the SEC into S3 and a Databricks volume.
4 Β· pipelines The medallion transform and the export the site reads.
5 Β· serving The site and its JSON API.
6 Β· chatbot This repo β€” the chat interface.

The arrows point one way only. Repos 3–6 install repo 1's package at a pinned version and none keeps a private copy, so they cannot drift apart about what a column means. An earlier version did keep copies; they drifted for weeks behind a check that compared only part of the definition, and deleting the copies was the fix.

5 Β· What runs on AWS

AWS components

Every figure below is real, taken from Cost Explorer rather than a pricing calculator, and projected to a full month. Everything lives in us-east-2 β€” the region the Databricks metastore is in, so no byte crosses a region boundary.

Component What it does Per month
EventBridge Scheduler fires the daily ingest at 06:00 UTC $0.00
ECS Fargate 0.5 vCPU / 1 GB, three tasks a day, ~30–90s each $0.07
ECR one container image, about 200 MB $0.02
S3 β€” raw system of record, moves to infrequent access at 90 days $0.02
S3 β€” serving four Parquet files and a manifest, ~120 KB $0.01
S3 β€” state Terraform state, versioned $0.00
Secrets Manager one secret: the SEC User-Agent $0.40
CloudWatch Logs ingest logs, 14-day retention $0.00
SSM Parameter Store 19 standard parameters $0.00
IAM, VPC, ECS cluster roles, security groups, no NAT gateway $0.02
Databricks Free Edition, serverless $0.00
Pipeline total β‰ˆ $0.55
EC2 t4g.micro the host serving this chatbot and the site $6.13
Bedrock per token, only when someone chats usage

EventBridge is free here β€” 14 million invocations a month are included and this uses thirty. There is no NAT gateway and no load balancer, which are the two line items that usually dominate a bill of this shape; a NAT alone would cost roughly sixty times the entire pipeline.

The one real cost is a single small instance, and it hosts the site and this chatbot together. Giving each its own would have added $5–7 a month to duplicate an IAM role and sit idle.


Using the chatbot

Open edgar.xiaoxiaolei.com/chat. Nothing to install, nothing to sign in to. A Back to the site link returns you to the main pages.

Questions it answers well:

Reading an answer:

What it refuses, and why:

If an answer looks wrong, the same numbers are browsable on the site, and the originals are on SEC EDGAR β€” every figure traces back to an accession number you can look up yourself.


Running it yourself

run.bat     # refreshes SSO, then serves on http://localhost:8501

Credentials, the Bedrock model-access form, and the acceptance script are in docs/SETUP-CREDENTIALS.md.

Gold data comes from repo 4's export in S3; this repo produces none of its own. Point SERVING_PREFIX at the export, or DATA_DIR at a local copy.

Design

One UI sits behind two interchangeable orchestrators (AGENT_IMPL): LangGraph by default, Google ADK as the alternate. One shared fake-model suite passes under both, and CI runs the ADK job with skips promoted to failures so the seam cannot rot silently.

Properties that are tests, not claims


Non-commercial portfolio demo on Databricks Free Edition and a personal AWS account. Data is a point-in-time export of public SEC filings. Not investment advice; materiality_band is a product heuristic, not an accounting standard.