Event Flow
Events are the mechanism Vega uses to bridge the gap between a long-running background process (the scan) and the user-facing dashboard. Because scans can take minutes to run, the backend doesn't make the user wait for a single HTTP response — instead, it streams incremental updates as events.
How events work
flowchart LR
Codex[Codex CLI subprocess]
V16[v16 adapter\nv16/adapter.py]
BackAdapter[Backend v16 adapter\napp/projects/v16_adapter.py]
PS[ProjectService]
EventStore[Event store\nPostgres or JSON]
FindingStore[Finding store\nPostgres or JSON]
API[Events API\n/v1/repositories/:id/events]
UI[Dashboard\nLive scan feed]
Codex -->|stdout JSON stream| V16
V16 -->|V16Event objects| BackAdapter
BackAdapter -->|mapped Vega events| PS
PS -->|append| EventStore
PS -->|upsert| FindingStore
EventStore -->|GET events| API
API -->|JSON array| UI
The two event stores
Events flow into two different places, depending on what they represent:
Event store — an append-only log of everything that happened during the scan. Used by the frontend for the live scan feed and by operators for debugging. Stored in app/events/service.py.
Finding store — durable security issues extracted from finding_updated events. These are structured records with severity, file path, and evidence. Stored and updated via ProjectService. The frontend shows these on the findings page after the scan finishes.
Event kinds
| Kind | What it means | Stored as finding? |
|---|---|---|
scan_started |
v16 has started running | No |
scan_progress |
Status update (e.g., component N of M) | No |
scan_log |
Debug log from v16 or Codex | No |
finding_updated |
A security issue was discovered or updated | Yes |
scan_completed |
All components audited, scan is done | No |
scan_failed |
v16 encountered an error | No |
scan_cancelled |
User or operator stopped the scan | No |
Why this design?
The event stream serves three purposes:
- Live UI — the frontend polls the events endpoint and shows a feed of what's happening right now.
- Debug log — after a scan finishes, operators can read the full event log to understand what Codex analyzed and what it found.
- Findings source —
finding_updatedevents are the sole source of truth for security findings. The backend processes each one and upserts a finding record.
Debugging
If a scan appears to run but the UI doesn't update:
- Check that v16 actually emitted events — look at
v16-events.jsonlin the scan artifacts. - Check
app/projects/v16_adapter.py— did it successfully map the raw v16 events? - Check
app/events/service.py— were events persisted to the store? - Check the frontend — is it polling the right project/scan context, and are filters hiding events?
If events appear but no findings show up:
- Confirm v16 emitted
finding_updatedevents (checkv16-events.jsonl). - Check
ProjectServicefinding upsert logic inapp/projects/service.py. - If using Postgres, confirm migration
004_findings_columns.sqlhas been applied. - Check the frontend findings page filters — severity or status filters might be hiding results.