-- sql/138-transceiver-speed-drift-guard.sql -- Closes a gap in the sql/125+126 "no physically-impossible compatibility rows" -- invariant: compat_speed_guard() (126) only fires on INSERT/UPDATE of the -- `compatibility` table itself. It never re-validates existing 'compatible' -- spec_match rows when a TRANSCEIVER's speed_gbps changes later (e.g. the daily -- enrich-modulation-fec.sh self-heal, sql/135, recovering speed from part-number -- tokens for previously NULL/junk rows). Found live 2026-07-12: 189 compat rows -- had gone physically-impossible because their transceiver's speed_gbps was -- updated (all sampled rows dated today, i.e. by the 03:30 cron) after the -- compat row was already written as 'compatible'. -- -- Fix mirrors 126 exactly, just triggered from the other table: AFTER UPDATE OF -- speed_gbps on transceivers, re-validate every 'compatible' spec_match -- compatibility row referencing that transceiver against the same evidence-based -- ceiling (v_switch_effective_max) used by v_compat_speed_errors. Curated rows -- (vendor_matrix/vendor_compat/tested/datasheet) are never touched. Idempotent, -- safe to re-run. -- Backup of affected rows before remediation (audit trail, matches -- tip_speed_gbps_rollback precedent from sql/136). create table if not exists compat_speed_drift_backup_20260712 as with em as materialized ( select switch_id, effective_max_gbps from v_switch_effective_max) select c.*, e.effective_max_gbps, t.speed_gbps as tx_speed_gbps, now() as backed_up_at from compatibility c join em e on e.switch_id = c.switch_id join transceivers t on t.id = c.transceiver_id where c.status = 'compatible' and c.verification_method = 'spec_match' and e.effective_max_gbps > 0 and t.speed_gbps is not null and t.speed_gbps > e.effective_max_gbps; -- One-time remediation: flip the rows found live today (same logic as 125's -- Remediation B, using the full evidence-based ceiling incl. curated bump). with em as materialized ( select switch_id, effective_max_gbps from v_switch_effective_max) update compatibility c set status = 'incompatible', notes = case when c.notes is null or c.notes = '' then 'auto(138): transceiver speed exceeds switch max port speed (post-hoc drift)' else c.notes || ' | auto(138): transceiver speed exceeds switch max port speed (post-hoc drift)' end from em e, transceivers t where e.switch_id = c.switch_id and t.id = c.transceiver_id and c.status = 'compatible' and c.verification_method = 'spec_match' and e.effective_max_gbps > 0 and t.speed_gbps is not null and t.speed_gbps > e.effective_max_gbps; -- Durable fix: re-validate on transceiver speed change. create or replace function compat_speed_guard_on_transceiver_change() returns trigger language plpgsql as $$ begin if NEW.speed_gbps is distinct from OLD.speed_gbps and NEW.speed_gbps is not null then update compatibility c set status = 'incompatible', notes = case when c.notes is null or c.notes = '' then 'auto(138): transceiver speed exceeds switch max port speed (post-hoc drift)' else c.notes || ' | auto(138): transceiver speed exceeds switch max port speed (post-hoc drift)' end from v_switch_effective_max e where e.switch_id = c.switch_id and c.transceiver_id = NEW.id and c.status = 'compatible' and c.verification_method = 'spec_match' and e.effective_max_gbps > 0 and NEW.speed_gbps > e.effective_max_gbps; end if; return NEW; end $$; comment on function compat_speed_guard_on_transceiver_change() is 'AFTER UPDATE OF speed_gbps on transceivers: re-validates existing compatible spec_match rows for this transceiver against the evidence-based switch ceiling, closing the drift gap left by compat_speed_guard() (126), which only fires on compatibility writes. Never touches curated rows.'; drop trigger if exists trg_compat_speed_guard_on_transceiver_change on transceivers; create trigger trg_compat_speed_guard_on_transceiver_change after update of speed_gbps on transceivers for each row execute function compat_speed_guard_on_transceiver_change(); insert into _migrations (filename, applied_at) select '138-transceiver-speed-drift-guard.sql', now() where not exists (select 1 from _migrations where filename = '138-transceiver-speed-drift-guard.sql');