echo "SUPABASE_URL: $SUPABASE_URL" echo "SUPABASE_PROJECT_REF: $SUPABASE_PROJECT_REF" echo "SUPABASE_DB_URL: $SUPABASE_DB_URL" echo "Anon key set: $([ -n "$SUPABASE_ANON_KEY" ] && echo yes || echo no)" echo "Service role key set: $([ -n "$SUPABASE_SERVICE_ROLE_KEY" ] && echo yes || echo no)"
SUPABASE_URL: https://<ref>.supabase.co SUPABASE_PROJECT_REF: <ref> SUPABASE_DB_URL: <redacted:SUPABASE_DB_URL> Anon key set: yes Service role key set: yes
PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "SELECT count(*) FROM public.payments;" -c "SELECT * FROM public.payments ORDER BY id LIMIT 5;"
count
-------
80
(1 row)
id | ref_code | payer | amount_cents | paid_at
----+--------------+------------------+--------------+------------------------
1 | 6C8935605030 | Payer-caffc0dc43 | 30036 | 2026-03-01 00:07:00+00
2 | 300351D74397 | Payer-b964e8caa9 | 101426 | 2026-03-01 00:14:00+00
3 | 381DA59BBE42 | Payer-77e253b14e | 484618 | 2026-03-01 00:21:00+00
4 | FD441D715532 | Payer-e8610229a5 | 470397 | 2026-03-01 00:28:00+00
5 | 49C2E5E745B1 | Payer-9719c24260 | 193265 | 2026-03-01 00:35:00+00
(5 rows)
# Step 1: Logical backup of public.payments only PGPASSWORD="$SUPABASE_DB_PASSWORD" pg_dump "$SUPABASE_DB_URL" \ --data-only \ --table=public.payments \ --column-inserts \ --no-owner --no-privileges \ -f /tmp/payments_backup.sql echo "Exit code: $?" wc -l /tmp/payments_backup.sql echo "---" # Show first and last few lines to verify head -5 /tmp/payments_backup.sql echo "..." tail -5 /tmp/payments_backup.sql
Exit code: 0 113 /tmp/payments_backup.sql --- -- -- PostgreSQL database dump -- \restrict o57y2rnCgi1YvUkJTI0Vq3yCdTQufK3LVgB4QIwiuVGNgHpcfwY71eyqKgQzhiR ... -- PostgreSQL database dump complete -- \unrestrict o57y2rnCgi1YvUkJTI0Vq3yCdTQufK3LVgB4QIwiuVGNgHpcfwY71eyqKgQzhiR
# Record pre-incident checksum and count for verification PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -t -A -c "SELECT count(*) FROM public.payments;" > /tmp/pre_count.txt PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -t -A -c "SELECT md5(string_agg(row(p.*)::text, ',' ORDER BY id)) FROM public.payments p;" > /tmp/pre_checksum.txt echo "Pre-incident count: $(cat /tmp/pre_count.txt)" echo "Pre-incident checksum: $(cat /tmp/pre_checksum.txt)"
Pre-incident count: 80 Pre-incident checksum: 4e085193811a088263b1b44dc7d69f34
# Step 2: Trigger the incident PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "SELECT public.run_incident();"
run_incident ------------------- incident executed (1 row)
# Verify corruption happened PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "SELECT count(*) FROM public.payments;" -c "SELECT * FROM public.payments LIMIT 3;" echo "---" PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.incident_log ORDER BY id DESC LIMIT 5;"
count
-------
54
(1 row)
id | ref_code | payer | amount_cents | paid_at
----+--------------+-----------+--------------+------------------------
1 | 6C8935605030 | CORRUPTED | 0 | 2026-03-01 00:07:00+00
2 | 300351D74397 | CORRUPTED | 0 | 2026-03-01 00:14:00+00
4 | FD441D715532 | CORRUPTED | 0 | 2026-03-01 00:28:00+00
(3 rows)
---
id | ran_at | details
----+------------------------------+--------------------------------------
1 | 2026-07-26 03:27:16.57725+00 | payments corrupted by incident drill
(1 row)
# Step 3: Restore payments table # First, delete all corrupted rows PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "DELETE FROM public.payments;" # Then re-insert from backup PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -f /tmp/payments_backup.sql
DELETE 54 SET SET SET SET SET SET set_config ------------ (1 row) SET SET SET SET INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1 INSERT 0 1
# Verify restore: count, checksum, and sample data PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -t -A -c "SELECT count(*) FROM public.payments;" > /tmp/post_count.txt PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -t -A -c "SELECT md5(string_agg(row(p.*)::text, ',' ORDER BY id)) FROM public.payments p;" > /tmp/post_checksum.txt echo "Post-restore count: $(cat /tmp/post_count.txt)" echo "Post-restore checksum: $(cat /tmp/post_checksum.txt)" echo "" echo "Pre-incident count: $(cat /tmp/pre_count.txt)" echo "Pre-incident checksum: $(cat /tmp/pre_checksum.txt)" echo "" if [ "$(cat /tmp/post_count.txt)" = "$(cat /tmp/pre_count.txt)" ] && [ "$(cat /tmp/post_checksum.txt)" = "$(cat /tmp/pre_checksum.txt)" ]; then echo "✅ RESTORE VERIFIED: count and checksum match exactly." else echo "❌ MISMATCH — investigation needed." fi echo "" echo "--- Sample restored rows ---" PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.payments ORDER BY id LIMIT 5;" echo "" echo "--- incident_log (must survive) ---" PGPASSWORD="$SUPABASE_DB_PASSWORD" psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.incident_log ORDER BY id;"
Post-restore count: 80 Post-restore checksum: 4e085193811a088263b1b44dc7d69f34 Pre-incident count: 80 Pre-incident checksum: 4e085193811a088263b1b44dc7d69f34 ✅ RESTORE VERIFIED: count and checksum match exactly. --- Sample restored rows --- id | ref_code | payer | amount_cents | paid_at ----+--------------+------------------+--------------+------------------------ 1 | 6C8935605030 | Payer-caffc0dc43 | 30036 | 2026-03-01 00:07:00+00 2 | 300351D74397 | Payer-b964e8caa9 | 101426 | 2026-03-01 00:14:00+00 3 | 381DA59BBE42 | Payer-77e253b14e | 484618 | 2026-03-01 00:21:00+00 4 | FD441D715532 | Payer-e8610229a5 | 470397 | 2026-03-01 00:28:00+00 5 | 49C2E5E745B1 | Payer-9719c24260 | 193265 | 2026-03-01 00:35:00+00 (5 rows) --- incident_log (must survive) --- id | ran_at | details ----+------------------------------+-------------------------------------- 1 | 2026-07-26 03:27:16.57725+00 | payments corrupted by incident drill (1 row)
5 earlier narration turn(s) are in the raw transcript.
A shell script executed against the live project and asserted on the state the agent left behind. No model judged another model.
Raw transcript · Task definition and verifier · Every attempt