From e7299ac77909addfdf051c994fe7f0033797be61 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 17 Jul 2026 20:17:02 +0000 Subject: [PATCH] fix(equivalences): spec-matcher no longer bypasses review spec-matcher.ts inserted every JOIN match straight into status=auto_approved at a flat confidence=0.85 -- no standard_name check, no fiber_type check, no recent-competitor-price check, none of the discrimination catalog-reconcile.ts uses before auto-approving. That is real ground live: of the 1,455 currently auto_approved spec-basis equivalences, ~19% would fail a recent-price check and ~8% have a conflicting standard_name if re-scored against the rigorous bar (see sql/140 for the one-time reclassification of the existing rows). Fix: spec matches now insert as pending with re_research_due_at=NOW(), so they flow through the same maintenance:re-research-equivalences job (fixed 2026-07-17, sql/139) that already scores catalog-reconcile.ts pending rows -- real evidence-based confidence before anything is served as approved, not a blanket 0.85. opn-matcher.ts is untouched: OPN matches are manufacturer-confirmed ground truth from fx_compatibilities, not a heuristic guess, so blanket auto_approve there remains correct. --- packages/scraper/src/robots/spec-matcher.ts | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/packages/scraper/src/robots/spec-matcher.ts b/packages/scraper/src/robots/spec-matcher.ts index 4f75ee0..ec3aa40 100644 --- a/packages/scraper/src/robots/spec-matcher.ts +++ b/packages/scraper/src/robots/spec-matcher.ts @@ -14,9 +14,18 @@ * - Max 30 competitor matches per FX product (safety cap) * * Match quality: - * confidence = 0.85 + * confidence = 0.85 (starting prior only) * match_basis = '{spec}' - * status = 'auto_approved' + * status = 'pending' — unlike OPN matches (manufacturer-confirmed ground + * truth), spec matches are a coarse JOIN with no standard_name / fiber_type / + * recent-price discrimination, so they route into the same + * maintenance:re-research-equivalences pipeline as catalog-reconcile.ts's + * pending rows (evaluateEquivalenceResearch(), scheduler.ts) for real + * confidence scoring before ever being served as an approved equivalence. + * Found live 2026-07-17: of the equivalences this matcher had previously put + * straight into 'auto_approved', ~19% failed a recent-competitor-price check + * and ~8% had a conflicting standard_name — i.e. real false-positive risk + * was going live unreviewed. */ import { pool } from "../utils/db"; @@ -39,13 +48,14 @@ const INSERT_SPEC_MATCHES = ` match_basis, match_notes, created_at, - updated_at + updated_at, + re_research_due_at ) SELECT DISTINCT fx.id AS flexoptix_id, comp.id AS competitor_id, 0.85 AS confidence, - 'auto_approved' AS status, + 'pending' AS status, ARRAY['spec'] AS match_basis, 'Spec match: ' || fx.form_factor || ' ' || fx.speed_gbps || 'G ' || CASE WHEN fx.reach_meters <= 300 THEN 'SR' @@ -57,7 +67,8 @@ const INSERT_SPEC_MATCHES = ` THEN ' @' || tip_extract_wavelength_nm(fx.wavelengths) || 'nm' ELSE '' END AS match_notes, NOW() AS created_at, - NOW() AS updated_at + NOW() AS updated_at, + NOW() AS re_research_due_at FROM transceivers fx JOIN vendors vfx ON vfx.id = fx.vendor_id AND UPPER(vfx.name) LIKE '%FLEXOPTIX%' JOIN transceivers comp