From e6d87882f5cdd1752dc7cfbf4ca253da9ecbba19 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 10:02:52 +0000 Subject: [PATCH 1/3] Initial plan From e055e337ebeb55692b9ed6e5726925aebde0414e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 10:10:05 +0000 Subject: [PATCH 2/3] Preserve active indexing-v3 locks during strict-gate seeding --- ...25033425_strict_enrichment_gate_repair.sql | 71 +++++++++++++------ supabase/schema.sql | 71 +++++++++++++------ tests/supabase-schema.test.ts | 3 + 3 files changed, 105 insertions(+), 40 deletions(-) diff --git a/supabase/migrations/20260625033425_strict_enrichment_gate_repair.sql b/supabase/migrations/20260625033425_strict_enrichment_gate_repair.sql index 39ab71ab9d..d1f21bffd9 100644 --- a/supabase/migrations/20260625033425_strict_enrichment_gate_repair.sql +++ b/supabase/migrations/20260625033425_strict_enrichment_gate_repair.sql @@ -99,6 +99,8 @@ language plpgsql security invoker set search_path = public, extensions, pg_temp as $$ +declare + v_processing_lock_timeout interval := make_interval(mins => 45); begin return query with candidates as ( @@ -158,26 +160,55 @@ begin ) ) else - jsonb_strip_nulls( - (coalesce(d.metadata, '{}'::jsonb) - - 'indexing_v3_agent_locked_by' - - 'indexing_v3_agent_locked_at' - - 'indexing_v3_agent_next_run_at' - - 'indexing_v3_agent_last_error') - || jsonb_build_object( - 'indexing_v3_agent_status', 'deferred', - 'indexing_v3_agent_updated_at', now(), - 'completion_gate_missing', to_jsonb(c.missing), - 'completion_gate', jsonb_build_object( - 'result', 'deferred', - 'missing', to_jsonb(c.missing), - 'counts', c.counts, - 'presence', c.presence, - 'source', 'repair_strict_enrichment_gate_batch' - ), - 'enrichment_status', 'pending' - ) - ) + case + when coalesce(d.metadata->>'indexing_v3_agent_status', '') = 'processing' + and ( + case + when coalesce(d.metadata->>'indexing_v3_agent_locked_at', '') ~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}' + then (d.metadata->>'indexing_v3_agent_locked_at')::timestamptz + else null + end + ) >= now() - v_processing_lock_timeout + then jsonb_strip_nulls( + (coalesce(d.metadata, '{}'::jsonb) + - 'indexing_v3_agent_next_run_at' + - 'indexing_v3_agent_last_error') + || jsonb_build_object( + 'indexing_v3_agent_status', 'processing', + 'indexing_v3_agent_updated_at', now(), + 'completion_gate_missing', to_jsonb(c.missing), + 'completion_gate', jsonb_build_object( + 'result', 'deferred', + 'missing', to_jsonb(c.missing), + 'counts', c.counts, + 'presence', c.presence, + 'source', 'repair_strict_enrichment_gate_batch' + ), + 'enrichment_status', 'processing' + ) + ) + else + jsonb_strip_nulls( + (coalesce(d.metadata, '{}'::jsonb) + - 'indexing_v3_agent_locked_by' + - 'indexing_v3_agent_locked_at' + - 'indexing_v3_agent_next_run_at' + - 'indexing_v3_agent_last_error') + || jsonb_build_object( + 'indexing_v3_agent_status', 'deferred', + 'indexing_v3_agent_updated_at', now(), + 'completion_gate_missing', to_jsonb(c.missing), + 'completion_gate', jsonb_build_object( + 'result', 'deferred', + 'missing', to_jsonb(c.missing), + 'counts', c.counts, + 'presence', c.presence, + 'source', 'repair_strict_enrichment_gate_batch' + ), + 'enrichment_status', 'pending' + ) + ) + end end, updated_at = now() from candidates c diff --git a/supabase/schema.sql b/supabase/schema.sql index ec9b58a638..6e86609d52 100644 --- a/supabase/schema.sql +++ b/supabase/schema.sql @@ -637,6 +637,8 @@ returns trigger language plpgsql set search_path = public, extensions, pg_temp as $$ +declare + v_processing_lock_timeout interval := make_interval(mins => 45); begin if tg_op = 'INSERT' then NEW.content_hash := md5(coalesce(NEW.content, '')); @@ -3061,26 +3063,55 @@ begin ) ) else - jsonb_strip_nulls( - (coalesce(d.metadata, '{}'::jsonb) - - 'indexing_v3_agent_locked_by' - - 'indexing_v3_agent_locked_at' - - 'indexing_v3_agent_next_run_at' - - 'indexing_v3_agent_last_error') - || jsonb_build_object( - 'indexing_v3_agent_status', 'deferred', - 'indexing_v3_agent_updated_at', now(), - 'completion_gate_missing', to_jsonb(c.missing), - 'completion_gate', jsonb_build_object( - 'result', 'deferred', - 'missing', to_jsonb(c.missing), - 'counts', c.counts, - 'presence', c.presence, - 'source', 'repair_strict_enrichment_gate_batch' - ), - 'enrichment_status', 'pending' - ) - ) + case + when coalesce(d.metadata->>'indexing_v3_agent_status', '') = 'processing' + and ( + case + when coalesce(d.metadata->>'indexing_v3_agent_locked_at', '') ~ '^[0-9]{4}-[0-9]{2}-[0-9]{2}' + then (d.metadata->>'indexing_v3_agent_locked_at')::timestamptz + else null + end + ) >= now() - v_processing_lock_timeout + then jsonb_strip_nulls( + (coalesce(d.metadata, '{}'::jsonb) + - 'indexing_v3_agent_next_run_at' + - 'indexing_v3_agent_last_error') + || jsonb_build_object( + 'indexing_v3_agent_status', 'processing', + 'indexing_v3_agent_updated_at', now(), + 'completion_gate_missing', to_jsonb(c.missing), + 'completion_gate', jsonb_build_object( + 'result', 'deferred', + 'missing', to_jsonb(c.missing), + 'counts', c.counts, + 'presence', c.presence, + 'source', 'repair_strict_enrichment_gate_batch' + ), + 'enrichment_status', 'processing' + ) + ) + else + jsonb_strip_nulls( + (coalesce(d.metadata, '{}'::jsonb) + - 'indexing_v3_agent_locked_by' + - 'indexing_v3_agent_locked_at' + - 'indexing_v3_agent_next_run_at' + - 'indexing_v3_agent_last_error') + || jsonb_build_object( + 'indexing_v3_agent_status', 'deferred', + 'indexing_v3_agent_updated_at', now(), + 'completion_gate_missing', to_jsonb(c.missing), + 'completion_gate', jsonb_build_object( + 'result', 'deferred', + 'missing', to_jsonb(c.missing), + 'counts', c.counts, + 'presence', c.presence, + 'source', 'repair_strict_enrichment_gate_batch' + ), + 'enrichment_status', 'pending' + ) + ) + end end, updated_at = now() from candidates c diff --git a/tests/supabase-schema.test.ts b/tests/supabase-schema.test.ts index 226b0852b8..973ee52b59 100644 --- a/tests/supabase-schema.test.ts +++ b/tests/supabase-schema.test.ts @@ -251,6 +251,9 @@ describe("Supabase schema Data API grants", () => { ); expect(sql).toContain("'indexing_v3_agent_status', 'completed'"); expect(sql).toContain("'indexing_v3_agent_status', 'deferred'"); + expect(sql).toContain("coalesce(d.metadata->>'indexing_v3_agent_status', '') = 'processing'"); + expect(sql).toContain("then (d.metadata->>'indexing_v3_agent_locked_at')::timestamptz"); + expect(sql).toContain("'enrichment_status', 'processing'"); expect(sql).toContain("stage = 'strict_gate_deferred'"); expect(sql).toContain("'strict_gate_repair'"); expect(sql).toContain("extraction_quality = 'good'"); From efcf2bedde29ecf343a02245b4a755dd59b08aab Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 2 Jul 2026 11:28:13 +0000 Subject: [PATCH 3/3] Fix: move v_processing_lock_timeout declare to repair_strict_enrichment_gate_batch in schema.sql --- supabase/schema.sql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/supabase/schema.sql b/supabase/schema.sql index 6e86609d52..ef11456ff9 100644 --- a/supabase/schema.sql +++ b/supabase/schema.sql @@ -637,8 +637,6 @@ returns trigger language plpgsql set search_path = public, extensions, pg_temp as $$ -declare - v_processing_lock_timeout interval := make_interval(mins => 45); begin if tg_op = 'INSERT' then NEW.content_hash := md5(coalesce(NEW.content, '')); @@ -3004,6 +3002,8 @@ language plpgsql security invoker set search_path = public, extensions, pg_temp as $$ +declare + v_processing_lock_timeout interval := make_interval(mins => 45); begin return query with candidates as (