# yigitcemakbas/loom architecture

> Architecture diagram of the GitHub repository yigitcemakbas/loom, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/yigitcemakbas/loom
- Repository: https://github.com/yigitcemakbas/loom

## Overview

Loom collects public-company material, evaluates disclosures and structured facts, and presents an auditable assessment with source passages and changes over time. The main workflow runs from a reader tracking companies through document ingestion and analysis to stored findings and the interface. README capabilities also include filing comparisons, insider and earnings data, full-text search, quantitative views, and scheduled refresh. Some route and ingestion wiring is unsampled; the graph omits uncertain links rather than inferring them.

Main entry points: [`backend/app/engine/pipeline.py`](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/pipeline.py) (Analysis orchestration), [`backend/app/ingestion/registry.py`](https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/registry.py) (Source adapters), [`backend/app/ingestion/sec_edgar.py`](https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/sec_edgar.py) (SEC filings), [`frontend/src/App.tsx`](https://github.com/yigitcemakbas/loom/blob/main/frontend/src/App.tsx) (Research interface)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_experience["Reader experience"]
  node_frontend["Research interface<br/>[App.tsx]"]
  node_client["API client<br/>[client.ts]"]
  node_api["Backend API<br/>[main.py]"]
  node_watchlist["Watchlists<br/>[watchlists.py]"]
  node_assessment_views["Assessment views<br/>[TodayPage.tsx]"]
end

subgraph group_collection["Data collection"]
  node_ingestion["Source adapters<br/>[registry.py]"]
  node_edgar["SEC filings<br/>[sec_edgar.py]"]
  node_structured["Structured feeds"]
  node_prices["Price history<br/>[prices.py]"]
end

subgraph group_analysis["Evidence analysis"]
  node_pipeline["Analysis orchestration<br/>[pipeline.py]"]
  node_extract["Finding extraction<br/>[extraction.py]"]
  node_compare["Disclosure comparison<br/>[diffing.py]"]
  node_fact_rules["Fact rules<br/>[fact_rules.py]"]
  node_assessment["Assessment synthesis<br/>[brief.py]"]
  node_scoring["Evidence scoring<br/>[engine.py]"]
end

subgraph group_persistence["Persistence"]
  node_documents["Document records"]
  node_blobs["Document text<br/>[blob_store.py]"]
  node_search["Passage search"]
  node_signals[("Finding records")]
end

subgraph group_operations["Refresh and integrations"]
  node_llm["Language model client<br/>[llm_client.py]"]
  node_scheduler["Background refresh<br/>[scheduler.py]"]
end

node_reader(("Reader"))
node_external_sources(("Public data sources"))
node_model_provider(("Model provider"))

node_reader -->|"reviews"| node_frontend
node_frontend -->|"requests data"| node_client
node_client -->|"calls API"| node_api
node_api -->|"routes requests"| node_watchlist
node_frontend -->|"shows assessments"| node_assessment_views
node_external_sources -->|"supplies filings"| node_edgar
node_external_sources -->|"supplies records"| node_structured
node_external_sources -->|"supplies prices"| node_prices
node_ingestion -->|"selects adapter"| node_edgar
node_ingestion -->|"selects adapter"| node_structured
node_ingestion -->|"selects adapter"| node_prices
node_edgar -->|"stores metadata"| node_documents
node_edgar -->|"stores text"| node_blobs
node_pipeline -->|"reads metadata"| node_documents
node_pipeline -->|"reads text"| node_blobs
node_pipeline -->|"runs extraction"| node_extract
node_pipeline -->|"runs comparison"| node_compare
node_pipeline -->|"applies rules"| node_fact_rules
node_pipeline -->|"requests analysis"| node_llm
node_pipeline -->|"writes findings"| node_signals
node_assessment -.->|"reads findings"| node_signals
node_scoring -->|"reads history"| node_signals
node_reader -.->|"searches passages"| node_search
node_search -->|"ranks metadata"| node_documents
node_search -->|"reads snippets"| node_blobs
node_scheduler -.->|"triggers refresh"| node_ingestion
node_scheduler -.->|"triggers analysis"| node_pipeline
node_llm -.->|"sends prompts"| node_model_provider

click node_frontend "https://github.com/yigitcemakbas/loom/blob/main/frontend/src/App.tsx"
click node_client "https://github.com/yigitcemakbas/loom/blob/main/frontend/src/api/client.ts"
click node_api "https://github.com/yigitcemakbas/loom/blob/main/backend/app/main.py"
click node_watchlist "https://github.com/yigitcemakbas/loom/blob/main/backend/app/api/routes/watchlists.py"
click node_assessment_views "https://github.com/yigitcemakbas/loom/blob/main/frontend/src/pages/TodayPage.tsx"
click node_ingestion "https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/registry.py"
click node_edgar "https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/sec_edgar.py"
click node_structured "https://github.com/yigitcemakbas/loom/tree/main/backend/app/ingestion/facts"
click node_prices "https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/prices.py"
click node_documents "https://github.com/yigitcemakbas/loom/blob/main/backend/app/repositories/document_repository.py"
click node_blobs "https://github.com/yigitcemakbas/loom/blob/main/backend/app/storage/blob_store.py"
click node_search "https://github.com/yigitcemakbas/loom/blob/main/backend/app/repositories/search_repository.py"
click node_pipeline "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/pipeline.py"
click node_extract "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/extraction.py"
click node_compare "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/diffing.py"
click node_fact_rules "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/fact_rules.py"
click node_assessment "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/brief.py"
click node_signals "https://github.com/yigitcemakbas/loom/blob/main/backend/app/repositories/signal_repository.py"
click node_scoring "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/statistics/engine.py"
click node_llm "https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/llm_client.py"
click node_scheduler "https://github.com/yigitcemakbas/loom/blob/main/backend/app/scheduling/scheduler.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_frontend,node_client,node_api,node_watchlist,node_assessment_views toneBlue
class node_ingestion,node_edgar,node_structured,node_prices toneAmber
class node_pipeline,node_extract,node_compare,node_fact_rules,node_assessment,node_scoring toneMint
class node_documents,node_blobs,node_search,node_signals toneRose
class node_llm,node_scheduler,node_reader,node_external_sources,node_model_provider toneIndigo
```

## Components

### Reader experience

- [Research interface](https://github.com/yigitcemakbas/loom/blob/main/frontend/src/App.tsx): `frontend/src/App.tsx`
- [API client](https://github.com/yigitcemakbas/loom/blob/main/frontend/src/api/client.ts): `frontend/src/api/client.ts`
- [Backend API](https://github.com/yigitcemakbas/loom/blob/main/backend/app/main.py): `backend/app/main.py`
- [Watchlists](https://github.com/yigitcemakbas/loom/blob/main/backend/app/api/routes/watchlists.py): `backend/app/api/routes/watchlists.py`
- [Assessment views](https://github.com/yigitcemakbas/loom/blob/main/frontend/src/pages/TodayPage.tsx): `frontend/src/pages/TodayPage.tsx`

### Data collection

- [Source adapters](https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/registry.py): `backend/app/ingestion/registry.py`
- [SEC filings](https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/sec_edgar.py): `backend/app/ingestion/sec_edgar.py`
- [Structured feeds](https://github.com/yigitcemakbas/loom/tree/main/backend/app/ingestion/facts): `backend/app/ingestion/facts`
- [Price history](https://github.com/yigitcemakbas/loom/blob/main/backend/app/ingestion/prices.py): `backend/app/ingestion/prices.py`

### Evidence analysis

- [Analysis orchestration](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/pipeline.py): `backend/app/engine/pipeline.py`
- [Finding extraction](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/extraction.py): `backend/app/engine/extraction.py`
- [Disclosure comparison](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/diffing.py): `backend/app/engine/diffing.py`
- [Fact rules](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/fact_rules.py): `backend/app/engine/fact_rules.py`
- [Assessment synthesis](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/brief.py): `backend/app/engine/brief.py`
- [Evidence scoring](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/statistics/engine.py): `backend/app/engine/statistics/engine.py`

### Persistence

- [Document records](https://github.com/yigitcemakbas/loom/blob/main/backend/app/repositories/document_repository.py): `backend/app/repositories/document_repository.py`
- [Document text](https://github.com/yigitcemakbas/loom/blob/main/backend/app/storage/blob_store.py): `backend/app/storage/blob_store.py`
- [Passage search](https://github.com/yigitcemakbas/loom/blob/main/backend/app/repositories/search_repository.py): `backend/app/repositories/search_repository.py`
- [Finding records](https://github.com/yigitcemakbas/loom/blob/main/backend/app/repositories/signal_repository.py): `backend/app/repositories/signal_repository.py`

### Refresh and integrations

- [Language model client](https://github.com/yigitcemakbas/loom/blob/main/backend/app/engine/llm_client.py): `backend/app/engine/llm_client.py`
- [Background refresh](https://github.com/yigitcemakbas/loom/blob/main/backend/app/scheduling/scheduler.py): `backend/app/scheduling/scheduler.py`

### Other components

- **Reader**
- **Public data sources**
- **Model provider**

## Connections

- Reader → Research interface: reviews
- Research interface → API client: requests data
- API client → Backend API: calls API
- Backend API → Watchlists: routes requests
- Research interface → Assessment views: shows assessments
- Public data sources → SEC filings: supplies filings
- Public data sources → Structured feeds: supplies records
- Public data sources → Price history: supplies prices
- Source adapters → SEC filings: selects adapter
- Source adapters → Structured feeds: selects adapter
- Source adapters → Price history: selects adapter
- SEC filings → Document records: stores metadata
- SEC filings → Document text: stores text
- Analysis orchestration → Document records: reads metadata
- Analysis orchestration → Document text: reads text
- Analysis orchestration → Finding extraction: runs extraction
- Analysis orchestration → Disclosure comparison: runs comparison
- Analysis orchestration → Fact rules: applies rules
- Analysis orchestration → Language model client: requests analysis
- Analysis orchestration → Finding records: writes findings
- Assessment synthesis → Finding records: reads findings
- Evidence scoring → Finding records: reads history
- Reader → Passage search: searches passages
- Passage search → Document records: ranks metadata
- Passage search → Document text: reads snippets
- Background refresh → Source adapters: triggers refresh
- Background refresh → Analysis orchestration: triggers analysis
- Language model client → Model provider: sends prompts
