# sathvikboina/recession-ews architecture

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

- Interactive diagram: https://gitdiagram.com/sathvikboina/recession-ews
- Repository: https://github.com/sathvikboina/recession-ews

## Overview

This is a label-first recession early-warning research pipeline, not yet a forecasting system: the README says feature tables and models have not been built. Its implemented workflow scopes candidate series, fetches and harmonises data, builds a frozen BEAI recession chronology, then compares it with NBER dates. The graph also preserves the documented runtime configuration and Phase 2 specification/dictionary deliverables. Model, feature, and dashboard stages are omitted because they are explicitly not started; unsampled pipeline links rely on README documentation.

Main entry points: [`scripts/03_labels.py`](https://github.com/sathvikboina/recession-ews/blob/master/scripts/03_labels.py) (Label runner), [`scripts/harmonize.py`](https://github.com/sathvikboina/recession-ews/blob/master/scripts/harmonize.py) (Quarterly harmonisation), [`src/ews/labels/build.py`](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/build.py) (BEAI builder), [`src/ews/runtime.py`](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/runtime.py) (Window utilities)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_planning["Scope and specification"]
  node_phase2["Dictionary generator<br/>[build.py]"]
  node_spec["Study specification<br/>[spec.py]"]
  node_runtime_config["Runtime configuration"]
  node_scope["Collection shortlist<br/>[scope_catalog.py]"]
  node_window["Window utilities<br/>[runtime.py]"]
end

subgraph group_collection["Data collection"]
  node_fetch["FRED collection<br/>[fetch_fred.py]"]
  node_raw[("Raw downloads")]
  node_harmonize["Quarterly harmonisation<br/>[harmonize.py]"]
  node_interim[("Interim data")]
  node_clean[("Clean panel")]
end

subgraph group_labeling["Recession labeling"]
  node_label_cli["Label runner<br/>[03_labels.py]"]
  node_label_build["BEAI builder<br/>[build.py]"]
  node_factor["Dynamic factor<br/>[dfm.py]"]
  node_dating["BBQ dating<br/>[bbq.py]"]
  node_diffusion["Diffusion gate<br/>[diffusion.py]"]
  node_freeze["Frozen-input checks<br/>[freeze.py]"]
  node_episode_ids["Episode renumbering<br/>[ids.py]"]
end

subgraph group_validation["Validation and outputs"]
  node_labels[("Frozen label artifacts")]
  node_compare["NBER comparison<br/>[04_compare_nber.py]"]
  node_results[("Validation results")]
end

node_researcher(("Researcher"))
node_nber["NBER chronology"]

node_researcher -->|"sets collection scope"| node_scope
node_spec -->|"drives generation"| node_phase2
node_researcher -->|"configures runtime"| node_runtime_config
node_runtime_config -.->|"defines scope"| node_scope
node_runtime_config -->|"sets study window"| node_window
node_scope -->|"selects series"| node_fetch
node_fetch -->|"writes downloads"| node_raw
node_raw -->|"supplies inputs"| node_harmonize
node_harmonize -->|"stages data"| node_interim
node_harmonize -->|"writes harmonised panel"| node_clean
node_clean -->|"supplies growth panel"| node_label_cli
node_label_cli -->|"checks frozen inputs"| node_freeze
node_label_cli -->|"renumbers episodes"| node_episode_ids
node_label_cli -->|"builds chronology"| node_label_build
node_label_build -->|"estimates factor"| node_factor
node_label_build -->|"dates turning points"| node_dating
node_label_build -->|"gates episodes"| node_diffusion
node_label_cli -->|"writes frozen outputs"| node_labels
node_labels -->|"provides label chronology"| node_compare
node_nber -->|"provides reference dates"| node_compare
node_compare -->|"writes comparisons"| node_results
node_fetch -->|"uses shared window"| node_window
node_harmonize -->|"uses shared window"| node_window
node_label_cli -->|"reads reporting window"| node_window

click node_phase2 "https://github.com/sathvikboina/recession-ews/blob/master/build.py"
click node_spec "https://github.com/sathvikboina/recession-ews/blob/master/spec.py"
click node_runtime_config "https://github.com/sathvikboina/recession-ews/tree/master/config"
click node_scope "https://github.com/sathvikboina/recession-ews/blob/master/scripts/scope_catalog.py"
click node_window "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/runtime.py"
click node_fetch "https://github.com/sathvikboina/recession-ews/blob/master/scripts/fetch_fred.py"
click node_raw "https://github.com/sathvikboina/recession-ews/tree/master/data/raw"
click node_harmonize "https://github.com/sathvikboina/recession-ews/blob/master/scripts/harmonize.py"
click node_interim "https://github.com/sathvikboina/recession-ews/tree/master/data/interim"
click node_clean "https://github.com/sathvikboina/recession-ews/tree/master/data/clean"
click node_label_cli "https://github.com/sathvikboina/recession-ews/blob/master/scripts/03_labels.py"
click node_label_build "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/build.py"
click node_factor "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/dfm.py"
click node_dating "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/bbq.py"
click node_diffusion "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/diffusion.py"
click node_freeze "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/freeze.py"
click node_episode_ids "https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/ids.py"
click node_labels "https://github.com/sathvikboina/recession-ews/tree/master/outputs/labels"
click node_compare "https://github.com/sathvikboina/recession-ews/blob/master/scripts/04_compare_nber.py"
click node_results "https://github.com/sathvikboina/recession-ews/tree/master/outputs/results"

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_phase2,node_spec,node_runtime_config,node_scope,node_window toneBlue
class node_fetch,node_raw,node_harmonize,node_interim,node_clean toneAmber
class node_label_cli,node_label_build,node_factor,node_dating,node_diffusion,node_freeze,node_episode_ids toneMint
class node_labels,node_compare,node_results toneRose
class node_researcher,node_nber toneIndigo
```

## Components

### Scope and specification

- [Dictionary generator](https://github.com/sathvikboina/recession-ews/blob/master/build.py): `build.py`
- [Study specification](https://github.com/sathvikboina/recession-ews/blob/master/spec.py): `spec.py`
- [Runtime configuration](https://github.com/sathvikboina/recession-ews/tree/master/config): `config`
- [Collection shortlist](https://github.com/sathvikboina/recession-ews/blob/master/scripts/scope_catalog.py): `scripts/scope_catalog.py`
- [Window utilities](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/runtime.py): `src/ews/runtime.py`

### Data collection

- [FRED collection](https://github.com/sathvikboina/recession-ews/blob/master/scripts/fetch_fred.py): `scripts/fetch_fred.py`
- [Raw downloads](https://github.com/sathvikboina/recession-ews/tree/master/data/raw): `data/raw`
- [Quarterly harmonisation](https://github.com/sathvikboina/recession-ews/blob/master/scripts/harmonize.py): `scripts/harmonize.py`
- [Interim data](https://github.com/sathvikboina/recession-ews/tree/master/data/interim): `data/interim`
- [Clean panel](https://github.com/sathvikboina/recession-ews/tree/master/data/clean): `data/clean`

### Recession labeling

- [Label runner](https://github.com/sathvikboina/recession-ews/blob/master/scripts/03_labels.py): `scripts/03_labels.py`
- [BEAI builder](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/build.py): `src/ews/labels/build.py`
- [Dynamic factor](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/dfm.py): `src/ews/labels/dfm.py`
- [BBQ dating](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/bbq.py): `src/ews/labels/bbq.py`
- [Diffusion gate](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/diffusion.py): `src/ews/labels/diffusion.py`
- [Frozen-input checks](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/freeze.py): `src/ews/labels/freeze.py`
- [Episode renumbering](https://github.com/sathvikboina/recession-ews/blob/master/src/ews/labels/ids.py): `src/ews/labels/ids.py`

### Validation and outputs

- [Frozen label artifacts](https://github.com/sathvikboina/recession-ews/tree/master/outputs/labels): `outputs/labels`
- [NBER comparison](https://github.com/sathvikboina/recession-ews/blob/master/scripts/04_compare_nber.py): `scripts/04_compare_nber.py`
- [Validation results](https://github.com/sathvikboina/recession-ews/tree/master/outputs/results): `outputs/results`

### Other components

- **Researcher**
- **NBER chronology**

## Connections

- Researcher → Collection shortlist: sets collection scope (evidence: `README.md`)
- Study specification → Dictionary generator: drives generation (evidence: `build.py`)
- Researcher → Runtime configuration: configures runtime (evidence: `README.md`)
- Runtime configuration → Collection shortlist: defines scope
- Runtime configuration → Window utilities: sets study window (evidence: `src/ews/runtime.py`)
- Collection shortlist → FRED collection: selects series (evidence: `README.md`)
- FRED collection → Raw downloads: writes downloads (evidence: `README.md`)
- Raw downloads → Quarterly harmonisation: supplies inputs (evidence: `README.md`)
- Quarterly harmonisation → Interim data: stages data (evidence: `README.md`)
- Quarterly harmonisation → Clean panel: writes harmonised panel (evidence: `README.md`)
- Clean panel → Label runner: supplies growth panel (evidence: `scripts/03_labels.py`)
- Label runner → Frozen-input checks: checks frozen inputs (evidence: `scripts/03_labels.py`)
- Label runner → Episode renumbering: renumbers episodes (evidence: `scripts/03_labels.py`)
- Label runner → BEAI builder: builds chronology (evidence: `src/ews/labels/build.py`)
- BEAI builder → Dynamic factor: estimates factor (evidence: `src/ews/labels/build.py`)
- BEAI builder → BBQ dating: dates turning points (evidence: `src/ews/labels/build.py`)
- BEAI builder → Diffusion gate: gates episodes (evidence: `src/ews/labels/build.py`)
- Label runner → Frozen label artifacts: writes frozen outputs (evidence: `scripts/03_labels.py`)
- Frozen label artifacts → NBER comparison: provides label chronology (evidence: `README.md`)
- NBER chronology → NBER comparison: provides reference dates (evidence: `README.md`)
- NBER comparison → Validation results: writes comparisons (evidence: `README.md`)
- FRED collection → Window utilities: uses shared window (evidence: `scripts/fetch_fred.py`)
- Quarterly harmonisation → Window utilities: uses shared window (evidence: `scripts/harmonize.py`)
- Label runner → Window utilities: reads reporting window (evidence: `scripts/03_labels.py`)
