# c9sa/safewatchv2 architecture

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

- Interactive diagram: https://gitdiagram.com/c9sa/safewatchv2
- Repository: https://github.com/c9sa/safewatchv2

## Overview

SafeWatch ingests public posts, turns them into structured incident candidates, classifies and evaluates them, then routes them toward publication, rejection, or retry. The sampled source confirms Reddit fetching, Supabase persistence, workflow entry, and agent-node storage calls; the README documents the broader workflow and dashboard/trace goals. Several listed modules were not sampled, so their internal wiring is shown only where the README explicitly describes it.

Main entry points: [`graph/nodes.py`](https://github.com/c9sa/safewatchv2/blob/main/graph/nodes.py) (Workflow nodes), [`agents/fetcher.py`](https://github.com/c9sa/safewatchv2/blob/main/agents/fetcher.py) (Post fetcher), [`graph/workflow.py`](https://github.com/c9sa/safewatchv2/blob/main/graph/workflow.py) (Graph workflow), [`graph/routing.py`](https://github.com/c9sa/safewatchv2/blob/main/graph/routing.py) (Retry routing)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_ingestion["Post ingestion"]
  node_fetcher["Post fetcher<br/>[fetcher.py]"]
end

subgraph group_processing["Agent workflow"]
  node_processor["Post processor<br/>[process_post.py]"]
  node_workflow["Graph workflow<br/>[workflow.py]"]
  node_nodes["Workflow nodes<br/>[nodes.py]"]
  node_routing["Retry routing<br/>[routing.py]"]
  node_cleaner["Cleaner agent<br/>[cleaner.py]"]
  node_classifier["Classifier agent<br/>[classifier.py]"]
  node_decision["Decision agent<br/>[decision.py]"]
  node_verifier["Optional verifier"]
end

subgraph group_records["Incident records"]
  node_raw[("Raw posts<br/>[db_readwrites.py]")]
  node_incidents[("Incident records<br/>[db_readwrites.py]")]
end

subgraph group_visibility["Audit and review"]
  node_messages[("Agent messages<br/>[db_readwrites.py]")]
  node_observability["Trace logging<br/>[observability.py]"]
  node_dashboard["Dashboard"]
end

node_reddit(("Reddit"))
node_caller(("Workflow caller"))
node_evidence(("External evidence"))

node_reddit -->|"provides posts"| node_fetcher
node_fetcher -->|"fetches posts"| node_reddit
node_fetcher -->|"inserts posts"| node_raw
node_caller -->|"submits post ID"| node_processor
node_processor -->|"invokes"| node_workflow
node_workflow -->|"dispatches steps"| node_nodes
node_nodes -->|"loads post"| node_raw
node_nodes -->|"checks and creates"| node_incidents
node_nodes -->|"runs cleaning"| node_cleaner
node_nodes -->|"runs classification"| node_classifier
node_workflow -->|"routes retry"| node_routing
node_routing -->|"requests retry"| node_classifier
node_decision -->|"supplies decision"| node_routing
node_nodes -->|"saves outputs"| node_incidents
node_nodes -->|"stores agent messages"| node_messages
node_observability -.->|"logs traces"| node_messages
node_dashboard -.->|"reviews records"| node_incidents
node_dashboard -.->|"reviews traces"| node_messages
node_verifier -.->|"checks evidence"| node_evidence

click node_fetcher "https://github.com/c9sa/safewatchv2/blob/main/agents/fetcher.py"
click node_raw "https://github.com/c9sa/safewatchv2/blob/main/services/db_readwrites.py"
click node_processor "https://github.com/c9sa/safewatchv2/blob/main/pipeline/process_post.py"
click node_workflow "https://github.com/c9sa/safewatchv2/blob/main/graph/workflow.py"
click node_nodes "https://github.com/c9sa/safewatchv2/blob/main/graph/nodes.py"
click node_routing "https://github.com/c9sa/safewatchv2/blob/main/graph/routing.py"
click node_cleaner "https://github.com/c9sa/safewatchv2/blob/main/agents/cleaner.py"
click node_classifier "https://github.com/c9sa/safewatchv2/blob/main/agents/classifier.py"
click node_decision "https://github.com/c9sa/safewatchv2/blob/main/agents/decision.py"
click node_incidents "https://github.com/c9sa/safewatchv2/blob/main/services/db_readwrites.py"
click node_messages "https://github.com/c9sa/safewatchv2/blob/main/services/db_readwrites.py"
click node_observability "https://github.com/c9sa/safewatchv2/blob/main/services/observability.py"
click node_verifier "https://github.com/c9sa/safewatchv2/tree/main/agents"

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_fetcher toneBlue
class node_processor,node_workflow,node_nodes,node_routing,node_cleaner,node_classifier,node_decision,node_verifier toneAmber
class node_raw,node_incidents toneMint
class node_messages,node_observability,node_dashboard toneRose
class node_reddit,node_caller,node_evidence toneIndigo
```

## Components

### Post ingestion

- [Post fetcher](https://github.com/c9sa/safewatchv2/blob/main/agents/fetcher.py): `agents/fetcher.py`

### Agent workflow

- [Post processor](https://github.com/c9sa/safewatchv2/blob/main/pipeline/process_post.py): `pipeline/process_post.py`
- [Graph workflow](https://github.com/c9sa/safewatchv2/blob/main/graph/workflow.py): `graph/workflow.py`
- [Workflow nodes](https://github.com/c9sa/safewatchv2/blob/main/graph/nodes.py): `graph/nodes.py`
- [Retry routing](https://github.com/c9sa/safewatchv2/blob/main/graph/routing.py): `graph/routing.py`
- [Cleaner agent](https://github.com/c9sa/safewatchv2/blob/main/agents/cleaner.py): `agents/cleaner.py`
- [Classifier agent](https://github.com/c9sa/safewatchv2/blob/main/agents/classifier.py): `agents/classifier.py`
- [Decision agent](https://github.com/c9sa/safewatchv2/blob/main/agents/decision.py): `agents/decision.py`
- [Optional verifier](https://github.com/c9sa/safewatchv2/tree/main/agents): `agents`

### Incident records

- [Raw posts](https://github.com/c9sa/safewatchv2/blob/main/services/db_readwrites.py): `services/db_readwrites.py`
- [Incident records](https://github.com/c9sa/safewatchv2/blob/main/services/db_readwrites.py): `services/db_readwrites.py`

### Audit and review

- [Agent messages](https://github.com/c9sa/safewatchv2/blob/main/services/db_readwrites.py): `services/db_readwrites.py`
- [Trace logging](https://github.com/c9sa/safewatchv2/blob/main/services/observability.py): `services/observability.py`
- **Dashboard**

### Other components

- **Reddit**
- **Workflow caller**
- **External evidence**

## Connections

- Reddit → Post fetcher: provides posts
- Post fetcher → Reddit: fetches posts
- Post fetcher → Raw posts: inserts posts
- Workflow caller → Post processor: submits post ID
- Post processor → Graph workflow: invokes
- Graph workflow → Workflow nodes: dispatches steps
- Workflow nodes → Raw posts: loads post
- Workflow nodes → Incident records: checks and creates
- Workflow nodes → Cleaner agent: runs cleaning
- Workflow nodes → Classifier agent: runs classification
- Graph workflow → Retry routing: routes retry
- Retry routing → Classifier agent: requests retry
- Decision agent → Retry routing: supplies decision
- Workflow nodes → Incident records: saves outputs
- Workflow nodes → Agent messages: stores agent messages
- Trace logging → Agent messages: logs traces
- Dashboard → Incident records: reviews records
- Dashboard → Agent messages: reviews traces
- Optional verifier → External evidence: checks evidence
