PatchWatch Data Flow

May 13, 2026 · View on GitHub

flowchart TD
    subgraph POLL ["patchwatch poll"]
        direction TB
        SUG1["SUG API<br/>list_releases"] --> SUG2["SUG API<br/>vulnerabilities_in_release"]
        SUG2 --> SUG3["SUG API<br/>vulnerability_detail +<br/>affected_products"]
        SUG3 --> PICK["pick_desktop_kb()<br/>best x64 desktop KB"]
        PICK --> KB_CHECK{KB already<br/>enumerated?}
        KB_CHECK -- no --> T1["Tier 1<br/>support.microsoft.com CSV"]
        T1 -- fallback --> T2["Tier 2<br/>MS Update Catalog<br/>download + extract MSU"]
        T1 --> DB_KB["DB: kb_enumerations<br/>kb_files"]
        T2 --> DB_KB
        KB_CHECK -- yes, skip --> DB_KB
        DB_KB --> TRIAGE_CHECK{Already triaged<br/>at this revision?}
        TRIAGE_CHECK -- no --> LLM1["Anthropic API — triage<br/>CVE desc + file list<br/>→ ranked files + confidence"]
        LLM1 --> DB_TRIAGE["DB: cve_triage"]
        TRIAGE_CHECK -- yes, skip --> DB_TRIAGE
        SUG3 --> DB_CVE["DB: cves<br/>cve_kbs"]
    end

    subgraph WEB ["patchwatch web"]
        direction TB
        UI1["GET /cves<br/>CVE list + search"] --> UI2["GET /cves/{id}<br/>detail + analyze button"]
        UI2 -- "POST /cves/{id}/analyze" --> QUEUE["AnalyzeService<br/>mpsc channel<br/>serial worker"]
        QUEUE --> ORCH
        UI2 -- "GET /jobs/{id}/status<br/>HTMX polling" --> STATUS["job status fragment<br/>queued → fetching → diffing<br/>→ synthesizing → done"]
        UI3["GET /cves/{id}/report<br/>synthesis + findings"] --> REPORT_VIEW
    end

    subgraph ORCH ["analyze_cve (orchestrator)"]
        direction TB
        WB["Winbindex<br/>fetch file metadata<br/>select pre/post pair"] --> DL["download patched +<br/>previous binary<br/>cached on disk"]
        DL --> GHIDRA["ghidriff<br/>Ghidra diff<br/>→ changed functions JSON"]
        GHIDRA --> LLM2["Anthropic API — synthesis<br/>diff summaries<br/>→ primary binaries + ranked functions"]
        LLM2 --> DB_SYN["DB: cve_synthesis<br/>cve_synthesis_binaries"]
        DB_SYN --> LLM3["Anthropic API — deep analysis<br/>decompiled code pre/post<br/>→ findings + patch summary"]
        LLM3 --> DB_FIND["DB: function_findings"]
        DB_FIND --> MD["write report.md"]
    end

    subgraph DB ["SQLite (patchwatch.db)"]
        direction TB
        T_CVES["cves<br/>cve_kbs"]
        T_KB["kb_enumerations<br/>kb_files"]
        T_TRIAGE["cve_triage"]
        T_JOBS["diff_jobs"]
        T_SYN["cve_synthesis<br/>cve_synthesis_binaries"]
        T_FIND["function_findings"]
    end

    DB_CVE --> T_CVES
    DB_KB --> T_KB
    DB_TRIAGE --> T_TRIAGE

    T_TRIAGE -- "load rankings" --> WB
    T_KB -- "load file list" --> WB

    QUEUE -- "create diff_job" --> T_JOBS
    T_JOBS -- "status updates" --> STATUS

    DB_SYN --> T_SYN
    DB_FIND --> T_FIND

    T_SYN --> REPORT_VIEW["render report<br/>synthesis + per-function<br/>findings with code snippets"]
    T_FIND --> REPORT_VIEW