# shen0122/firstcatch architecture

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

- Interactive diagram: https://gitdiagram.com/shen0122/firstcatch
- Repository: https://github.com/shen0122/firstcatch

## Overview

FirstCatch is a personal open-source contribution radar. The main workflow reads subscribed repositories and preferences, incrementally fetches and filters issues, batch-triages and scores candidates, deep-dives feasible top-ranked issues, then renders and pushes a digest. A separate tracking path records the user’s PR outcomes so recommendations can be compared with merge results for scorer calibration. The README documents these capabilities; sampled source confirms core orchestration, fetching, scoring, deep-dive, notification, and storage behavior. Tracker internals were not sampled, so its detailed wiring is limited to documented behavior.

Main entry points: [`firstcatch.py`](https://github.com/shen0122/firstcatch/blob/master/firstcatch.py) (Pipeline runner), [`inspector/memory.py`](https://github.com/shen0122/firstcatch/blob/master/inspector/memory.py) (SQLite memory), [`inspector/fetch.py`](https://github.com/shen0122/firstcatch/blob/master/inspector/fetch.py) (Issue fetcher), [`inspector/deepdive.py`](https://github.com/shen0122/firstcatch/blob/master/inspector/deepdive.py) (Fix deep-dive)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_discovery["Issue discovery"]
  node_subscriptions["Subscriptions<br/>[repos.yaml]"]
  node_runner["Pipeline runner<br/>[firstcatch.py]"]
  node_fetcher["Issue fetcher<br/>[fetch.py]"]
  node_memory[("SQLite memory<br/>[memory.py]")]
end

subgraph group_analysis["Candidate analysis"]
  node_triage["Batch triage<br/>[triage.py]"]
  node_scorer["Signal scorer<br/>[scoring.py]"]
  node_deepdive["Fix deep-dive<br/>[deepdive.py]"]
  node_agent["ReAct agent<br/>[github_agent.py]"]
end

subgraph group_delivery["Digest delivery"]
  node_digest["Digest renderer<br/>[digest.py]"]
  node_notifier["Webhook notifier<br/>[notify.py]"]
end

subgraph group_feedback["Outcome feedback"]
  node_tracker["PR tracker<br/>[tracker.py]"]
  node_calibrator["Score calibration<br/>[calibrate.py]"]
end

node_contributor(("Contributor"))
node_github_mcp["GitHub MCP"]
node_llm["LLM service"]
node_repositories["Git repositories"]
node_chat_webhooks["Chat webhooks"]

node_contributor -->|"starts run"| node_runner
node_subscriptions -->|"configures"| node_runner
node_runner -->|"runs fetch"| node_fetcher
node_fetcher -->|"lists and hydrates"| node_github_mcp
node_fetcher -->|"checks and records"| node_memory
node_runner -->|"classifies issues"| node_triage
node_triage -->|"requests classification"| node_llm
node_runner -->|"scores triage"| node_scorer
node_runner -->|"stores recommendations"| node_memory
node_runner -->|"deep-dives top issues"| node_deepdive
node_deepdive -->|"shallow clones"| node_repositories
node_deepdive -->|"requests verification"| node_agent
node_agent -->|"calls code tools"| node_github_mcp
node_agent -->|"runs ReAct"| node_llm
node_runner -->|"renders results"| node_digest
node_runner -->|"pushes digest"| node_notifier
node_notifier -->|"sends report"| node_chat_webhooks
node_contributor -->|"requests tracking"| node_tracker
node_tracker -->|"polls PR status"| node_github_mcp
node_tracker -->|"records PR outcomes"| node_memory
node_memory -->|"provides joined outcomes"| node_calibrator
node_contributor -->|"runs analysis"| node_calibrator

click node_subscriptions "https://github.com/shen0122/firstcatch/blob/master/config/repos.yaml"
click node_runner "https://github.com/shen0122/firstcatch/blob/master/firstcatch.py"
click node_fetcher "https://github.com/shen0122/firstcatch/blob/master/inspector/fetch.py"
click node_memory "https://github.com/shen0122/firstcatch/blob/master/inspector/memory.py"
click node_triage "https://github.com/shen0122/firstcatch/blob/master/inspector/triage.py"
click node_scorer "https://github.com/shen0122/firstcatch/blob/master/inspector/scoring.py"
click node_deepdive "https://github.com/shen0122/firstcatch/blob/master/inspector/deepdive.py"
click node_agent "https://github.com/shen0122/firstcatch/blob/master/github_agent.py"
click node_digest "https://github.com/shen0122/firstcatch/blob/master/inspector/digest.py"
click node_notifier "https://github.com/shen0122/firstcatch/blob/master/inspector/notify.py"
click node_tracker "https://github.com/shen0122/firstcatch/blob/master/inspector/tracker.py"
click node_calibrator "https://github.com/shen0122/firstcatch/blob/master/eval/calibrate.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_subscriptions,node_runner,node_fetcher,node_memory toneBlue
class node_triage,node_scorer,node_deepdive,node_agent toneAmber
class node_digest,node_notifier,node_chat_webhooks toneMint
class node_tracker,node_calibrator toneRose
class node_contributor,node_github_mcp,node_llm,node_repositories toneIndigo
```

## Components

### Issue discovery

- [Subscriptions](https://github.com/shen0122/firstcatch/blob/master/config/repos.yaml): `config/repos.yaml`
- [Pipeline runner](https://github.com/shen0122/firstcatch/blob/master/firstcatch.py): `firstcatch.py`
- [Issue fetcher](https://github.com/shen0122/firstcatch/blob/master/inspector/fetch.py): `inspector/fetch.py`
- [SQLite memory](https://github.com/shen0122/firstcatch/blob/master/inspector/memory.py): `inspector/memory.py`

### Candidate analysis

- [Batch triage](https://github.com/shen0122/firstcatch/blob/master/inspector/triage.py): `inspector/triage.py`
- [Signal scorer](https://github.com/shen0122/firstcatch/blob/master/inspector/scoring.py): `inspector/scoring.py`
- [Fix deep-dive](https://github.com/shen0122/firstcatch/blob/master/inspector/deepdive.py): `inspector/deepdive.py`
- [ReAct agent](https://github.com/shen0122/firstcatch/blob/master/github_agent.py): `github_agent.py`

### Digest delivery

- [Digest renderer](https://github.com/shen0122/firstcatch/blob/master/inspector/digest.py): `inspector/digest.py`
- [Webhook notifier](https://github.com/shen0122/firstcatch/blob/master/inspector/notify.py): `inspector/notify.py`

### Outcome feedback

- [PR tracker](https://github.com/shen0122/firstcatch/blob/master/inspector/tracker.py): `inspector/tracker.py`
- [Score calibration](https://github.com/shen0122/firstcatch/blob/master/eval/calibrate.py): `eval/calibrate.py`

### Other components

- **Contributor**
- **GitHub MCP**
- **LLM service**
- **Git repositories**
- **Chat webhooks**

## Connections

- Contributor → Pipeline runner: starts run
- Subscriptions → Pipeline runner: configures
- Pipeline runner → Issue fetcher: runs fetch
- Issue fetcher → GitHub MCP: lists and hydrates
- Issue fetcher → SQLite memory: checks and records
- Pipeline runner → Batch triage: classifies issues
- Batch triage → LLM service: requests classification
- Pipeline runner → Signal scorer: scores triage
- Pipeline runner → SQLite memory: stores recommendations
- Pipeline runner → Fix deep-dive: deep-dives top issues
- Fix deep-dive → Git repositories: shallow clones
- Fix deep-dive → ReAct agent: requests verification
- ReAct agent → GitHub MCP: calls code tools
- ReAct agent → LLM service: runs ReAct
- Pipeline runner → Digest renderer: renders results
- Pipeline runner → Webhook notifier: pushes digest
- Webhook notifier → Chat webhooks: sends report
- Contributor → PR tracker: requests tracking
- PR tracker → GitHub MCP: polls PR status
- PR tracker → SQLite memory: records PR outcomes
- SQLite memory → Score calibration: provides joined outcomes
- Contributor → Score calibration: runs analysis
