From cc37abbfb04899f22d0da9fa6d85febf62be3a90 Mon Sep 17 00:00:00 2001 From: BigSimmo <87357024+BigSimmo@users.noreply.github.com> Date: Fri, 3 Jul 2026 19:35:39 +0800 Subject: [PATCH] =?UTF-8?q?test(rag):=20guard=20RC9=20=E2=80=94=20lexical?= =?UTF-8?q?=20text=20path=20must=20not=20fabricate=20a=20cosine=20similari?= =?UTF-8?q?ty?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Verified RC9 is fully handled at the SQL layer: match_document_chunks_text sets similarity=0 (documented inline) with the lexical signal in a hybrid_score capped at 0.5 (below the 0.64 moderate gate); match_document_lookup_chunks_text and match_document_table_facts_text return only text_rank, with no similarity column to fabricate. Adds a source-text regression guard so the chunks-text similarity=0 + capped-hybrid_score invariant cannot silently drift back (the neutralized 20260702170000 migration + known hybrid-RPC drift make schema.sql the canonical definition this guards). Co-Authored-By: Claude Opus 4.8 --- tests/supabase-schema.test.ts | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/tests/supabase-schema.test.ts b/tests/supabase-schema.test.ts index 80dab9cded..3d329824a6 100644 --- a/tests/supabase-schema.test.ts +++ b/tests/supabase-schema.test.ts @@ -687,3 +687,23 @@ describe("Supabase schema Data API grants", () => { } }); }); + +describe("RC9 — lexical text path must not fabricate a cosine similarity", () => { + // Regression guard for RC9. The text-only fallback (match_document_chunks_text) has no vector + // cosine; an earlier version fabricated a synthetic `similarity` (0.56 + text_rank*0.39) that was + // read downstream as a real semantic score, letting a pure keyword hit masquerade as moderate/strong + // (>=0.64) evidence. The canonical definition in schema.sql now leaves similarity at 0 and carries + // the lexical signal in a hybrid_score capped below the 0.64 moderate gate (plus lexical_score). + // The two other lexical text RPCs (match_document_lookup_chunks_text / _table_facts_text) return only + // text_rank — no similarity/hybrid_score column to fabricate. + it("match_document_chunks_text returns similarity 0, not a synthetic score", () => { + expect(schema).toContain("0::double precision as similarity"); + // The text path's hybrid_score is capped by least(0.5, ...) — strictly below the 0.64 moderate + // threshold — so a lexical-only row can order among its peers but never clears the moderate/strong + // evidence gate when merged with vector results. (Coefficients may be tuned; the 0.5 ceiling and + // text_rank basis are the invariant.) + expect(schema).toMatch( + /least\(0\.5, [0-9.]+ \+ \(least\(ranked\.text_rank, 1\) \* [0-9.]+\)\)::double precision as hybrid_score/, + ); + }); +});