Source REVIEWER, APPROVED, and ASSIGNED edges from standalone Siphon tables
## Problem
REVIEWER, APPROVED, and ASSIGNED edges are currently extracted from array columns on the merge_requests materialized view. These arrays lose most of the data — the MVs surface only a fraction of the rows in the Siphon source tables:
| Edge | Siphon source table | MV arrays (merge_requests) | Graph (gl_edge) |
|---|---|---|---|
| REVIEWER | 3,273 | 25 | 27 |
| APPROVED | 7,143 | 50 | 50 |
| ASSIGNED | 6,986 | 45 | 220 |
The graph is missing most reviewer, approval, and assignment relationships.
## Proposed solution
Each edge type has a dedicated Siphon source table (`siphon_merge_request_reviewers`, `siphon_approvals`, `siphon_merge_request_assignees`) with the full set of records. We should:
- Add `etl:` blocks to `approved.yaml`, `assigned.yaml`, and `reviewer.yaml` pointing at the corresponding Siphon source table instead of deriving edges from merge_requests MV arrays
- Add DDL for the three Siphon source tables in `fixtures/siphon.sql`
- Add integration tests to verify each edge type indexes correctly from its standalone source
issue