# sirius-5107/sentinel architecture

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

- Interactive diagram: https://gitdiagram.com/sirius-5107/sentinel
- Repository: https://github.com/sirius-5107/sentinel

## Overview

Sentinel is a financial intelligence platform: it collects market articles, enriches and deduplicates them, then synthesises signals into market events and daily briefs. Its persistence layer stores articles and domain records; shared domain models and protocols define cross-stage contracts. The README also describes knowledge, research, publishing, API and CLI capabilities, but these are roadmap or package placeholders in the supplied tree. Edges for the documented pipeline use the README; implementation edges cite the source index or excerpts, so unsampled behavior is not assumed.

Main entry points: [`sentinel/processing/processor.py`](https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/processor.py) (Article processor), [`sentinel_core/models`](https://github.com/sirius-5107/sentinel/tree/main/sentinel_core/models) (Domain models), [`sentinel/services/collection.py`](https://github.com/sirius-5107/sentinel/blob/main/sentinel/services/collection.py) (Collection service), [`sentinel/intelligence/synthesiser.py`](https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/synthesiser.py) (Event synthesiser)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_collection["Collection"]
  node_collection_service["Collection service<br/>[collection.py]"]
  node_ingestion_service["RSS ingestion<br/>[ingestion.py]"]
  node_collector_factory["Collector factory<br/>[factory.py]"]
  node_rss_collector["RSS collector<br/>[rss.py]"]
  node_scraper["Web scraper<br/>[scraper.py]"]
  node_config["Source configuration<br/>[loaders.py]"]
end

subgraph group_processing["Processing"]
  node_processing_orchestrator["Article processor<br/>[processor.py]"]
  node_classifier["Classifier<br/>[classifier.py]"]
  node_scorer["Importance scorer<br/>[scorer.py]"]
  node_extractor["Entity extractor<br/>[extractor.py]"]
  node_deduplicator["Deduplicator<br/>[dedup.py]"]
end

subgraph group_intelligence["Intelligence"]
  node_analyst["Analyst<br/>[analyst.py]"]
  node_synthesiser["Event synthesiser<br/>[synthesiser.py]"]
  node_daily_brief["Daily brief<br/>[daily_brief.py]"]
  node_knowledge[("Knowledge base")]
  node_research["Research documents"]
  node_publishing["Publishing channels"]
  node_api["REST API"]
  node_cli["Operations CLI"]
  node_scheduler["Scheduler"]
  node_analysis_prompts["Analysis prompts<br/>[analysis.py]"]
  node_event_prompts["Event prompts<br/>[event_synthesis.py]"]
end

subgraph group_data["Persistence"]
  node_repository["Domain repositories<br/>[repository.py]"]
  node_orm_models["Database mappings<br/>[models.py]"]
  node_db_session["Database session<br/>[session.py]"]
  node_postgres[("PostgreSQL + pgvector")]
end

subgraph group_core["Shared domain"]
  node_domain_models["Domain models"]
  node_value_objects["Value objects<br/>[value_objects.py]"]
  node_enums["Domain enums"]
  node_protocols["Stage protocols<br/>[protocols.py]"]
  node_exceptions["Domain exceptions<br/>[base.py]"]
end

node_investor(("Investor / operator"))

node_investor -.->|"initiates collection"| node_collection_service
node_collection_service -->|"selects collector"| node_collector_factory
node_collection_service -->|"loads sources"| node_config
node_collection_service -->|"persists run data"| node_repository
node_collector_factory -->|"creates"| node_rss_collector
node_collector_factory -->|"creates"| node_scraper
node_ingestion_service -->|"collects with"| node_rss_collector
node_ingestion_service -->|"saves articles"| node_repository
node_rss_collector -->|"yields articles"| node_domain_models
node_rss_collector -->|"implements collector contract"| node_protocols
node_collection_service -.->|"passes collected articles"| node_processing_orchestrator
node_processing_orchestrator -->|"classifies"| node_classifier
node_processing_orchestrator -->|"scores"| node_scorer
node_processing_orchestrator -->|"extracts entities"| node_extractor
node_processing_orchestrator -->|"deduplicates"| node_deduplicator
node_processing_orchestrator -->|"enriches articles"| node_domain_models
node_processing_orchestrator -->|"implements processor contract"| node_protocols
node_processing_orchestrator -.->|"passes processed signals"| node_synthesiser
node_synthesiser -->|"uses prompts"| node_event_prompts
node_synthesiser -->|"creates market events"| node_domain_models
node_synthesiser -->|"uses provider contract"| node_protocols
node_analyst -->|"uses prompts"| node_analysis_prompts
node_investor -.->|"requests brief"| node_daily_brief
node_daily_brief -.->|"publishes brief"| node_publishing
node_synthesiser -.->|"maintains event knowledge"| node_knowledge
node_knowledge -.->|"supports research"| node_research
node_investor -.->|"queries insights"| node_api
node_investor -.->|"operates pipeline"| node_cli
node_scheduler -.->|"triggers runs"| node_collection_service
node_repository -->|"maps domain records"| node_orm_models
node_db_session -->|"configures mappings"| node_orm_models
node_db_session -.->|"opens sessions"| node_postgres
node_repository -.->|"persists records"| node_postgres
node_orm_models -->|"maps domain models"| node_domain_models
node_domain_models -->|"uses validated types"| node_value_objects
node_domain_models -->|"uses classifications"| node_enums
node_domain_models -.->|"validates domain rules"| node_exceptions

click node_collection_service "https://github.com/sirius-5107/sentinel/blob/main/sentinel/services/collection.py"
click node_ingestion_service "https://github.com/sirius-5107/sentinel/blob/main/sentinel/services/ingestion.py"
click node_collector_factory "https://github.com/sirius-5107/sentinel/blob/main/sentinel/collector/factory.py"
click node_rss_collector "https://github.com/sirius-5107/sentinel/blob/main/sentinel/collector/rss.py"
click node_scraper "https://github.com/sirius-5107/sentinel/blob/main/sentinel/collector/scraper.py"
click node_processing_orchestrator "https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/processor.py"
click node_classifier "https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/classifier.py"
click node_scorer "https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/scorer.py"
click node_extractor "https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/extractor.py"
click node_deduplicator "https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/dedup.py"
click node_analyst "https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/analyst.py"
click node_synthesiser "https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/synthesiser.py"
click node_daily_brief "https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/daily_brief.py"
click node_knowledge "https://github.com/sirius-5107/sentinel/tree/main/sentinel/knowledge"
click node_research "https://github.com/sirius-5107/sentinel/tree/main/sentinel/research"
click node_publishing "https://github.com/sirius-5107/sentinel/tree/main/sentinel/publish"
click node_api "https://github.com/sirius-5107/sentinel/tree/main/sentinel/api"
click node_cli "https://github.com/sirius-5107/sentinel/tree/main/sentinel/cli"
click node_scheduler "https://github.com/sirius-5107/sentinel/tree/main/sentinel/scheduler"
click node_repository "https://github.com/sirius-5107/sentinel/blob/main/sentinel/db/repository.py"
click node_orm_models "https://github.com/sirius-5107/sentinel/blob/main/sentinel/db/models.py"
click node_db_session "https://github.com/sirius-5107/sentinel/blob/main/sentinel/db/session.py"
click node_domain_models "https://github.com/sirius-5107/sentinel/tree/main/sentinel_core/models"
click node_value_objects "https://github.com/sirius-5107/sentinel/blob/main/sentinel_core/types/value_objects.py"
click node_enums "https://github.com/sirius-5107/sentinel/tree/main/sentinel_core/enums"
click node_protocols "https://github.com/sirius-5107/sentinel/blob/main/sentinel_core/interfaces/protocols.py"
click node_exceptions "https://github.com/sirius-5107/sentinel/blob/main/sentinel_core/exceptions/base.py"
click node_config "https://github.com/sirius-5107/sentinel/blob/main/sentinel/config/loaders.py"
click node_analysis_prompts "https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/prompts/analysis.py"
click node_event_prompts "https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/prompts/event_synthesis.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_collection_service,node_ingestion_service,node_collector_factory,node_rss_collector,node_scraper,node_config toneBlue
class node_processing_orchestrator,node_classifier,node_scorer,node_extractor,node_deduplicator toneAmber
class node_analyst,node_synthesiser,node_daily_brief,node_knowledge,node_research,node_publishing,node_api,node_cli,node_scheduler,node_analysis_prompts,node_event_prompts toneMint
class node_repository,node_orm_models,node_db_session,node_postgres toneRose
class node_domain_models,node_value_objects,node_enums,node_protocols,node_exceptions,node_investor toneIndigo
```

## Components

### Collection

- [Collection service](https://github.com/sirius-5107/sentinel/blob/main/sentinel/services/collection.py): `sentinel/services/collection.py`
- [RSS ingestion](https://github.com/sirius-5107/sentinel/blob/main/sentinel/services/ingestion.py): `sentinel/services/ingestion.py`
- [Collector factory](https://github.com/sirius-5107/sentinel/blob/main/sentinel/collector/factory.py): `sentinel/collector/factory.py`
- [RSS collector](https://github.com/sirius-5107/sentinel/blob/main/sentinel/collector/rss.py): `sentinel/collector/rss.py`
- [Web scraper](https://github.com/sirius-5107/sentinel/blob/main/sentinel/collector/scraper.py): `sentinel/collector/scraper.py`
- [Source configuration](https://github.com/sirius-5107/sentinel/blob/main/sentinel/config/loaders.py): `sentinel/config/loaders.py`

### Processing

- [Article processor](https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/processor.py): `sentinel/processing/processor.py`
- [Classifier](https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/classifier.py): `sentinel/processing/classifier.py`
- [Importance scorer](https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/scorer.py): `sentinel/processing/scorer.py`
- [Entity extractor](https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/extractor.py): `sentinel/processing/extractor.py`
- [Deduplicator](https://github.com/sirius-5107/sentinel/blob/main/sentinel/processing/dedup.py): `sentinel/processing/dedup.py`

### Intelligence

- [Analyst](https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/analyst.py): `sentinel/intelligence/analyst.py`
- [Event synthesiser](https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/synthesiser.py): `sentinel/intelligence/synthesiser.py`
- [Daily brief](https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/daily_brief.py): `sentinel/intelligence/daily_brief.py`
- [Knowledge base](https://github.com/sirius-5107/sentinel/tree/main/sentinel/knowledge): `sentinel/knowledge`
- [Research documents](https://github.com/sirius-5107/sentinel/tree/main/sentinel/research): `sentinel/research`
- [Publishing channels](https://github.com/sirius-5107/sentinel/tree/main/sentinel/publish): `sentinel/publish`
- [REST API](https://github.com/sirius-5107/sentinel/tree/main/sentinel/api): `sentinel/api`
- [Operations CLI](https://github.com/sirius-5107/sentinel/tree/main/sentinel/cli): `sentinel/cli`
- [Scheduler](https://github.com/sirius-5107/sentinel/tree/main/sentinel/scheduler): `sentinel/scheduler`
- [Analysis prompts](https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/prompts/analysis.py): `sentinel/intelligence/prompts/analysis.py`
- [Event prompts](https://github.com/sirius-5107/sentinel/blob/main/sentinel/intelligence/prompts/event_synthesis.py): `sentinel/intelligence/prompts/event_synthesis.py`

### Persistence

- [Domain repositories](https://github.com/sirius-5107/sentinel/blob/main/sentinel/db/repository.py): `sentinel/db/repository.py`
- [Database mappings](https://github.com/sirius-5107/sentinel/blob/main/sentinel/db/models.py): `sentinel/db/models.py`
- [Database session](https://github.com/sirius-5107/sentinel/blob/main/sentinel/db/session.py): `sentinel/db/session.py`
- **PostgreSQL + pgvector**

### Shared domain

- [Domain models](https://github.com/sirius-5107/sentinel/tree/main/sentinel_core/models): `sentinel_core/models`
- [Value objects](https://github.com/sirius-5107/sentinel/blob/main/sentinel_core/types/value_objects.py): `sentinel_core/types/value_objects.py`
- [Domain enums](https://github.com/sirius-5107/sentinel/tree/main/sentinel_core/enums): `sentinel_core/enums`
- [Stage protocols](https://github.com/sirius-5107/sentinel/blob/main/sentinel_core/interfaces/protocols.py): `sentinel_core/interfaces/protocols.py`
- [Domain exceptions](https://github.com/sirius-5107/sentinel/blob/main/sentinel_core/exceptions/base.py): `sentinel_core/exceptions/base.py`

### Other components

- **Investor / operator**

## Connections

- Investor / operator → Collection service: initiates collection (evidence: `README.md`)
- Collection service → Collector factory: selects collector (evidence: `sentinel/services/collection.py`)
- Collection service → Source configuration: loads sources (evidence: `sentinel/services/collection.py`)
- Collection service → Domain repositories: persists run data (evidence: `sentinel/services/collection.py`)
- Collector factory → RSS collector: creates (evidence: `sentinel/collector/factory.py`)
- Collector factory → Web scraper: creates (evidence: `sentinel/collector/factory.py`)
- RSS ingestion → RSS collector: collects with (evidence: `sentinel/services/ingestion.py`)
- RSS ingestion → Domain repositories: saves articles (evidence: `sentinel/services/ingestion.py`)
- RSS collector → Domain models: yields articles (evidence: `sentinel/collector/rss.py`)
- RSS collector → Stage protocols: implements collector contract (evidence: `sentinel/collector/rss.py`)
- Collection service → Article processor: passes collected articles (evidence: `README.md`)
- Article processor → Classifier: classifies (evidence: `sentinel/processing/processor.py`)
- Article processor → Importance scorer: scores (evidence: `sentinel/processing/processor.py`)
- Article processor → Entity extractor: extracts entities (evidence: `sentinel/processing/processor.py`)
- Article processor → Deduplicator: deduplicates (evidence: `sentinel/processing/processor.py`)
- Article processor → Domain models: enriches articles (evidence: `sentinel/processing/processor.py`)
- Article processor → Stage protocols: implements processor contract (evidence: `sentinel/processing/processor.py`)
- Article processor → Event synthesiser: passes processed signals (evidence: `README.md`)
- Event synthesiser → Event prompts: uses prompts (evidence: `sentinel/intelligence/synthesiser.py`)
- Event synthesiser → Domain models: creates market events (evidence: `sentinel/intelligence/synthesiser.py`)
- Event synthesiser → Stage protocols: uses provider contract (evidence: `sentinel/intelligence/synthesiser.py`)
- Analyst → Analysis prompts: uses prompts (evidence: `sentinel/intelligence/analyst.py`)
- Investor / operator → Daily brief: requests brief (evidence: `README.md`)
- Daily brief → Publishing channels: publishes brief (evidence: `README.md`)
- Event synthesiser → Knowledge base: maintains event knowledge (evidence: `README.md`)
- Knowledge base → Research documents: supports research (evidence: `README.md`)
- Investor / operator → REST API: queries insights (evidence: `README.md`)
- Investor / operator → Operations CLI: operates pipeline (evidence: `README.md`)
- Scheduler → Collection service: triggers runs (evidence: `README.md`)
- Domain repositories → Database mappings: maps domain records (evidence: `sentinel/db/repository.py`)
- Database session → Database mappings: configures mappings (evidence: `sentinel/db/session.py`)
- Database session → PostgreSQL + pgvector: opens sessions
- Domain repositories → PostgreSQL + pgvector: persists records
- Database mappings → Domain models: maps domain models (evidence: `sentinel/db/models.py`)
- Domain models → Value objects: uses validated types (evidence: `sentinel_core/models/article.py`)
- Domain models → Domain enums: uses classifications (evidence: `sentinel_core/models/article.py`)
- Domain models → Domain exceptions: validates domain rules
