-- Regression test: recall_lessons() graph_proximity mixin (v0.2.0-step4) -- Pure-SQL predicate checks; no live table required. -- Recall@10 targets: ≥0.55 on 100-row synthetic, ≥0.45 on 1000-row LOO. -- 1. Formula coefficient breakdown (fixed terms, defaults γ=0.2 δ=0.2) -- cosine=0.4, importance=0.2, prov_strength=0.1; variable: γ×recency + δ×graph_proximity SELECT 0.4 AS cosine_weight, 0.2 AS importance_weight, 0.1 AS prov_strength_weight, 0.4 + 0.2 + 0.1 AS fixed_weight_sum, (0.4 + 0.2 + 0.1) < 1.0 AS leaves_room_for_recency_and_graph; -- Expected: cosine=0.4, importance=0.2, prov_strength=0.1, sum=0.7, t -- 2. graph_proximity formula: 1.0 - depth/max_depth (max_depth=5) SELECT round((1.0 - 1::float / 5)::numeric, 2) AS proximity_depth1, round((1.0 - 2::float / 5)::numeric, 2) AS proximity_depth2, round((1.0 - 3::float / 5)::numeric, 2) AS proximity_depth3, round((1.0 - 4::float / 5)::numeric, 2) AS proximity_depth4; -- Expected: 0.80, 0.60, 0.40, 0.20 (depth=5 would be 0.0, blocked by depth < max_depth guard) -- 3. GUC range clamping: GREATEST(0.0, LEAST(0.5, input)) SELECT GREATEST(0.0, LEAST(0.5, -0.1::float)) AS clamp_below_zero, GREATEST(0.0, LEAST(0.5, 0.0::float)) AS clamp_at_min, GREATEST(0.0, LEAST(0.5, 0.2::float)) AS clamp_midpoint, GREATEST(0.0, LEAST(0.5, 0.5::float)) AS clamp_at_max, GREATEST(0.0, LEAST(0.5, 0.9::float)) AS clamp_above_max; -- Expected: 0, 0, 0.2, 0.5, 0.5 -- 4. COALESCE sentinel: non-anchor lessons get proximity=0 (no graph signal) SELECT COALESCE(NULL::float, 0.0) AS no_graph_signal, COALESCE(0.8::float, 0.0) AS depth1_signal, COALESCE(0.0::float, 0.0) AS zero_proximity_passthrough; -- Expected: 0, 0.8, 0 -- 5. Score upper bound check: with all components maxed at defaults -- max = 0.4*1 + 0.2*1 + 0.2*1 + 0.1*1 + 0.2*1 = 1.1 SELECT round((0.4*1.0 + 0.2*1.0 + 0.2*1.0 + 0.1*1.0 + 0.2*1.0)::numeric, 1) AS max_score_defaults, round((0.4*1.0 + 0.2*1.0 + 0.2*1.0 + 0.1*1.0 + 0.5*1.0)::numeric, 1) AS max_score_delta05; -- Expected: 1.1, 1.4 -- 6. Edge types traversed by graph_walk (causal, temporal, derives_from) SELECT ('causal' = ANY(ARRAY['causal','temporal','derives_from'])) AS causal_included, ('temporal' = ANY(ARRAY['causal','temporal','derives_from'])) AS temporal_included, ('derives_from' = ANY(ARRAY['causal','temporal','derives_from'])) AS derives_from_included, ('semantic' = ANY(ARRAY['causal','temporal','derives_from'])) AS semantic_excluded, ('contradicts' = ANY(ARRAY['causal','temporal','derives_from'])) AS contradicts_excluded; -- Expected: t, t, t, f, f -- 7. depth guard: traversal halts when depth >= max_depth (depth < 5) SELECT (0 < 5) AS depth0_traverses, (4 < 5) AS depth4_traverses, (5 < 5) AS depth5_blocked, (6 < 5) AS depth6_blocked; -- Expected: t, t, f, f -- 8. Recall@10 performance targets (validated offline; thresholds recorded here) SELECT 0.55 AS recall_at10_target_100row_synthetic, 0.45 AS recall_at10_target_1000row_loo, 'graph_proximity mixin vs cosine-only baseline'::TEXT AS benchmark_comparison; -- Expected: targets documented (live evaluation run offline)