feat(switch-db): durable guard + validator for switch/compat quality
- trg_compat_speed_guard: BEFORE INSERT/UPDATE on compatibility forces algorithmic (spec_match/community) rows whose transceiver is faster than the switch max port speed to status=incompatible. Curated rows never touched. Makes the "no physically-impossible compatibility" invariant structural, so it survives a scraper regression. - check_switch_quality(): on-demand proof; CI gate is `select bool_and(pass) from check_switch_quality() where enforced` (must be true). Data-source gaps (coding coverage, speed<=0, datasheet) tracked as enforced=false so they do not fail the gate before the data exists.
This commit is contained in:
parent
98d0946975
commit
479a0dbe56
98
sql/126-switch-quality-enforcement.sql
Normal file
98
sql/126-switch-quality-enforcement.sql
Normal file
@ -0,0 +1,98 @@
|
||||
-- sql/126-switch-quality-enforcement.sql
|
||||
-- Durable enforcement + on-demand validation for the switch/compatibility DB.
|
||||
-- Complements sql/125 (which cleaned the data): makes the "no physically-impossible
|
||||
-- compatibility rows" invariant structural, so it survives a scraper regression.
|
||||
--
|
||||
-- Design (same "no false positives" rule as 125):
|
||||
-- * The guard NEVER touches curated rows (vendor_matrix/vendor_compat/tested/datasheet)
|
||||
-- -- those are trusted and, on understated switches, are the source of truth.
|
||||
-- * For algorithmic rows (spec_match/community), if the transceiver is faster than the
|
||||
-- switch's fastest known port (stored max_speed_gbps OR ports_config-derived), the row
|
||||
-- is FORCED to status='incompatible' rather than dropped -- it stays recorded but is
|
||||
-- excluded by every consumer that filters status='compatible' (e.g. queries.ts:302).
|
||||
-- * Forcing (not RETURN NULL) means the guard never conflicts with the 125 flagging
|
||||
-- UPDATE and never silently loses data. Idempotent; safe to re-run.
|
||||
--
|
||||
-- Depends on sql/125 (fn_ports_max_gbps + the v_* views). Apply after 125.
|
||||
|
||||
-- ── Guard: keep physically-impossible algorithmic matches out of 'compatible' ──
|
||||
create or replace function compat_speed_guard() returns trigger
|
||||
language plpgsql as $$
|
||||
declare
|
||||
sw_ceiling numeric;
|
||||
tx_speed numeric;
|
||||
begin
|
||||
-- Trust curated/vendor/tested sources; they define reality on understated switches.
|
||||
if NEW.verification_method in ('vendor_matrix','vendor_compat','tested','datasheet') then
|
||||
return NEW;
|
||||
end if;
|
||||
if NEW.status is distinct from 'compatible' then
|
||||
return NEW; -- only guard rows claiming compatibility
|
||||
end if;
|
||||
|
||||
select greatest(coalesce(s.max_speed_gbps,0), coalesce(fn_ports_max_gbps(s.ports_config),0))
|
||||
into sw_ceiling
|
||||
from switches s where s.id = NEW.switch_id;
|
||||
|
||||
select t.speed_gbps into tx_speed
|
||||
from transceivers t where t.id = NEW.transceiver_id;
|
||||
|
||||
if sw_ceiling is not null and sw_ceiling > 0
|
||||
and tx_speed is not null and tx_speed > sw_ceiling then
|
||||
NEW.status := 'incompatible';
|
||||
if NEW.notes is null or NEW.notes = '' then
|
||||
NEW.notes := 'auto(126): transceiver speed exceeds switch max port speed';
|
||||
elsif position('auto(12' in NEW.notes) = 0 then
|
||||
NEW.notes := NEW.notes || ' | auto(126): transceiver speed exceeds switch max port speed';
|
||||
end if;
|
||||
end if;
|
||||
return NEW;
|
||||
end $$;
|
||||
|
||||
comment on function compat_speed_guard() is
|
||||
'BEFORE INSERT/UPDATE guard on compatibility: forces algorithmic (non-curated) rows whose transceiver is faster than the switch max port speed to status=incompatible. Never alters curated rows.';
|
||||
|
||||
drop trigger if exists trg_compat_speed_guard on compatibility;
|
||||
create trigger trg_compat_speed_guard
|
||||
before insert or update on compatibility
|
||||
for each row execute function compat_speed_guard();
|
||||
|
||||
-- ── Validator: prove switch-DB quality on demand (CI / cron) ──────────────────
|
||||
-- Hard invariants have enforced=true; data-source gaps (coverage, datasheet) are
|
||||
-- reported but enforced=false so they don't fail the gate before the data exists.
|
||||
-- CI gate: select bool_and(pass) from check_switch_quality() where enforced; -- must be true
|
||||
create or replace function check_switch_quality()
|
||||
returns table(check_name text, detail text, pass boolean, enforced boolean)
|
||||
language sql stable as $$
|
||||
select 'no_impossible_spec_match_compat',
|
||||
(select count(*) from v_compat_speed_errors)::text || ' impossible rows',
|
||||
(select count(*) from v_compat_speed_errors) = 0,
|
||||
true
|
||||
union all
|
||||
select 'coding_coverage_100G_ge_50pct',
|
||||
coalesce((select coverage_pct from v_coding_coverage where tier = 100), 0)::text || '%',
|
||||
coalesce((select coverage_pct from v_coding_coverage where tier = 100), 0) >= 50,
|
||||
false
|
||||
union all
|
||||
select 'transceivers_speed_positive',
|
||||
(select count(*) from v_transceiver_speed_errors)::text || ' with speed<=0',
|
||||
(select count(*) from v_transceiver_speed_errors) = 0,
|
||||
false
|
||||
union all
|
||||
select 'switches_have_max_speed',
|
||||
(select count(*) from v_switch_completeness where max_speed_gbps is null)::text || ' missing',
|
||||
(select count(*) from v_switch_completeness where max_speed_gbps is null) = 0,
|
||||
false
|
||||
union all
|
||||
select 'no_understated_switch_ports',
|
||||
(select count(*) from v_switch_understated_ports)::text || ' understated',
|
||||
(select count(*) from v_switch_understated_ports) = 0,
|
||||
false;
|
||||
$$;
|
||||
|
||||
comment on function check_switch_quality() is
|
||||
'Switch-DB quality proof. select bool_and(pass) from check_switch_quality() where enforced; must be true (no physically-impossible compatibility rows). enforced=false rows track datasheet/data-source gaps.';
|
||||
|
||||
insert into _migrations (filename, applied_at)
|
||||
select '126-switch-quality-enforcement.sql', now()
|
||||
where not exists (select 1 from _migrations where filename = '126-switch-quality-enforcement.sql');
|
||||
Loading…
x
Reference in New Issue
Block a user