Runbook — lineage_warnings Triage (#527)
What this is
debate_recommendation_outcomes.lineage_warnings is an Array(LowCardinality(String)) column populated at write time from a frozen vocabulary (4 active contamination + 2 informational Pass 3 + 2 reserved-deferred tags). Empty array means no detected contamination.
A live-emission v5 row (confluence_version ∈ {'v5', 'v5_partial'}) with contamination warnings (net_sign_mismatch, zero_triple, magnitude_outlier_v5, conviction_inconsistent) is the silent-leak detection cohort — what should never happen if the v5 pipeline is healthy. Smoke D gates exclusively on this cohort.
Pass 3 reconstructed rows (v5_reconstructed, v5_partial_reconstructed) carry only informational tags (reconstructed, optionally v5_source_unknown) — Pass 3 does NOT call derive_lineage_warnings, so these rows are invisible to Smoke D by construction. Surface them in cohort filtering for calibration jobs (filter out reconstructed cohort to avoid forward-looking-bias contamination of v5 calibration). Activating contamination surveillance on Pass 3 rebuilds is a Phase 1.5 follow-up.
Vocabulary
Active contamination warnings (Phase 1)
Informational tags (Pass 3 reconstruction; NOT contamination)
Reserved (deferred to Phase 1.5)
These tags are inLINEAGE_WARNING_VOCAB but never emitted from Phase 1 derivation. Activation requires data outside the orchestrator hot path (prev-day v43 lookup, cross-table tier observation). Tracked in the Phase 1.5 follow-up issue.
Response when smoke-d fires
- Query the offending rows (matches the Smoke D gate exactly — live-emission v5 family + hasAny on contamination tags):
- Bucket by warning tag (most common first).
- If a single tag dominates (>80% of rows), follow that tag’s “First-look” location above.
- If multiple tags co-occur on the same rows, the producer is upstream of all of them — likely the parser. Check
stock_parser.pyrecently-shipped changes (git log -- api/app/services/stock/). - File a tracking P0 referencing the smoke-d issue. Roll back the most recent debate_outcome_writer or stock_parser deploy if no fix in <2h.
Adding new vocab
- Add tag to
LINEAGE_WARNING_VOCABinapi/app/services/debate/lineage_warnings.py. - Add detection logic in
derive_lineage_warnings. - Add a row to the table above + a “First-look” location.
- Cardinality ceiling 32 — if you’re approaching it, audit existing tags first.