Can Agents Run It? · evidence — Issue 1: Supabase

claude-sonnet-5 · d2_webhooks · rep 1

pass
model
claude-sonnet-5
task
d2_webhooks
rep
1
day
2
steps
18
tokens
87,571
est. cost
$0.525
agent time
111s
wave
s4
started
2026-07-24T05:06:14Z

The task as the agent received it

You have operator access to a hosted Supabase project. Credentials are in environment variables: SUPABASE_URL, SUPABASE_PROJECT_REF, SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY, SUPABASE_DB_URL, SUPABASE_DB_PASSWORD. Every INSERT into the existing table public.signups must deliver an HTTP webhook: a POST request with a JSON body containing at least the new row's email and plan values, sent to the receiver endpoint {SUPABASE_URL}/functions/v1/hook-recorder (an edge function that is already deployed on this project; SUPABASE_URL is in your environment). The receiver requires a valid project JWT in the Authorization header and records every payload it accepts. Implement the delivery from the database itself, so it fires for ANY insert into signups no matter which client performs it — no external workers, no cron, no client-side code. Delivery may be asynchronous (a few seconds is fine). Prove it end-to-end with a test insert before finishing: the receiver stores accepted payloads in public.webhook_receipts.

What it ran — 18 commands

#1exit 0
env | grep -i supabase | sed -E 's/(KEY|PASSWORD)=.*/\1=***REDACTED***/'
SUPABASE_DB_PASSWORD=***REDACTED***
SUPABASE_DB_URL=<redacted:SUPABASE_DB_URL>
SUPABASE_URL=https://<ref>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=***REDACTED***
SUPABASE_PROJECT_REF=<ref>
SUPABASE_ANON_KEY=***REDACTED***
#2exit 0
which psql curl jq node 2>&1; echo "---"; psql --version 2>&1
/usr/bin/psql
/usr/bin/curl
/usr/bin/jq
/usr/bin/node
---
psql (PostgreSQL) 18.4 (Debian 18.4-1.pgdg12+1)
#3exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "\d public.signups"
echo "---extensions---"
psql "$SUPABASE_DB_URL" -c "select extname, extversion from pg_extension order by extname;"
echo "---receiver test---"
curl -s -o /dev/null -w "%{http_code}\n" -X POST "$SUPABASE_URL/functions/v1/hook-recorder" -H "Content-Type: application/json" -d '{}'
                                     Table "public.signups"
   Column   |           Type           | Collation | Nullable |             Default              
------------+--------------------------+-----------+----------+----------------------------------
 id         | bigint                   |           | not null | generated by default as identity
 email      | text                     |           | not null | 
 plan       | text                     |           | not null | 'free'::text
 created_at | timestamp with time zone |           | not null | now()
Indexes:
    "signups_pkey" PRIMARY KEY, btree (id)

---extensions---
      extname       | extversion 
--------------------+------------
 pg_stat_statements | 1.11
 pgcrypto           | 1.3
 plpgsql            | 1.0
 supabase_vault     | 0.3.1
 uuid-ossp          | 1.1
(5 rows)

---receiver test---
401
#4exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
echo "--- available extensions matching net ---"
psql "$SUPABASE_DB_URL" -c "select name, default_version, installed_version from pg_available_extensions where name ilike '%net%' or name ilike '%http%';"
echo "--- schemas ---"
psql "$SUPABASE_DB_URL" -c "\dn"
--- available extensions matching net ---
  name  | default_version | installed_version 
--------+-----------------+-------------------
 http   | 1.6             | 
 pg_net | 0.20.4          | 
(2 rows)

--- schemas ---
          List of schemas
      Name      |       Owner       
----------------+-------------------
 app_private    | postgres
 auth           | supabase_admin
 extensions     | postgres
 graphql        | supabase_admin
 graphql_public | supabase_admin
 pgbouncer      | pgbouncer
 public         | pg_database_owner
 realtime       | supabase_admin
 storage        | supabase_admin
 vault          | supabase_admin
(10 rows)

#5exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "create extension if not exists pg_net schema extensions;"
psql "$SUPABASE_DB_URL" -c "select extname, extnamespace::regnamespace from pg_extension where extname='pg_net';"
CREATE EXTENSION
 extname | extnamespace 
---------+--------------
 pg_net  | extensions
(1 row)

#6exit 0
# Test the receiver with anon key and service role key to see which is accepted
curl -s -o /tmp/resp1.txt -w "ANON: %{http_code}\n" -X POST "$SUPABASE_URL/functions/v1/hook-recorder" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SUPABASE_ANON_KEY" \
  -d '{"email":"probe@example.com","plan":"free"}'
cat /tmp/resp1.txt; echo
curl -s -o /tmp/resp2.txt -w "SERVICE: %{http_code}\n" -X POST "$SUPABASE_URL/functions/v1/hook-recorder" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY" \
  -d '{"email":"probe2@example.com","plan":"free"}'
cat /tmp/resp2.txt; echo
ANON: 200
{"ok":true}
SERVICE: 200
{"ok":true}
#7exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "\d public.webhook_receipts"
psql "$SUPABASE_DB_URL" -c "select * from public.webhook_receipts order by id desc limit 5;"
                                 Table "public.webhook_receipts"
   Column    |           Type           | Collation | Nullable |             Default              
-------------+--------------------------+-----------+----------+----------------------------------
 id          | bigint                   |           | not null | generated by default as identity
 received_at | timestamp with time zone |           | not null | now()
 payload     | jsonb                    |           | not null | 
Indexes:
    "webhook_receipts_pkey" PRIMARY KEY, btree (id)

 id |          received_at          |                     payload                     
----+-------------------------------+-------------------------------------------------
  3 | 2026-07-24 05:06:51.508947+00 | {"plan": "free", "email": "probe2@example.com"}
  2 | 2026-07-24 05:06:51.196946+00 | {"plan": "free", "email": "probe@example.com"}
(2 rows)

#8exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "\d vault.secrets" 2>&1 | head -30
echo "---"
psql "$SUPABASE_DB_URL" -c "select proname, pronamespace::regnamespace from pg_proc where proname ilike '%create_secret%' or proname ilike '%decrypted_secret%';" 2>&1
                                       Table "vault.secrets"
   Column    |           Type           | Collation | Nullable |              Default              
-------------+--------------------------+-----------+----------+-----------------------------------
 id          | uuid                     |           | not null | gen_random_uuid()
 name        | text                     |           |          | 
 description | text                     |           | not null | ''::text
 secret      | text                     |           | not null | 
 key_id      | uuid                     |           |          | 
 nonce       | bytea                    |           |          | vault._crypto_aead_det_noncegen()
 created_at  | timestamp with time zone |           | not null | CURRENT_TIMESTAMP
 updated_at  | timestamp with time zone |           | not null | CURRENT_TIMESTAMP
Indexes:
    "secrets_pkey" PRIMARY KEY, btree (id)
    "secrets_name_idx" UNIQUE, btree (name) WHERE name IS NOT NULL

---
    proname    | pronamespace 
---------------+--------------
 create_secret | vault
(1 row)

#9exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD

# Store secrets in vault (idempotent-ish: delete existing with same name first)
psql "$SUPABASE_DB_URL" <<SQL
do \$\$
begin
  delete from vault.secrets where name = 'project_url';
  delete from vault.secrets where name = 'service_role_key';
end \$\$;

select vault.create_secret('$SUPABASE_URL', 'project_url', 'Base URL of this Supabase project');
select vault.create_secret('$SUPABASE_SERVICE_ROLE_KEY', 'service_role_key', 'Service role JWT used for internal webhook calls');
SQL
DO
            create_secret             
--------------------------------------
 603fc4db-6e11-4f7a-989e-e5259b6b67b9
(1 row)

            create_secret             
--------------------------------------
 e5a09663-2d57-4cd1-8886-def1a3074bfd
(1 row)

#10exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "select name, decrypted_secret from vault.decrypted_secrets where name in ('project_url','service_role_key');"
       name       |                                                                                                      decrypted_secret                                                                                                       
------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
 project_url      | https://<ref>.supabase.co
 service_role_key | <redacted:SUPABASE_SERVICE_ROLE_KEY>
(2 rows)

#11exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" <<'SQL'
create or replace function public.signups_webhook_trigger()
returns trigger
language plpgsql
security definer
set search_path = public, extensions, vault
as $$
declare
  v_url text;
  v_key text;
  v_payload jsonb;
  v_request_id bigint;
begin
  select decrypted_secret into v_url
    from vault.decrypted_secrets where name = 'project_url';

  select decrypted_secret into v_key
    from vault.decrypted_secrets where name = 'service_role_key';

  v_payload := jsonb_build_object(
    'email', NEW.email,
    'plan', NEW.plan,
    'id', NEW.id,
    'created_at', NEW.created_at
  );

  select net.http_post(
    url := v_url || '/functions/v1/hook-recorder',
    headers := jsonb_build_object(
      'Content-Type', 'application/json',
      'Authorization', 'Bearer ' || v_key
    ),
    body := v_payload
  ) into v_request_id;

  return NEW;
end;
$$;

drop trigger if exists signups_webhook_trigger on public.signups;

create trigger signups_webhook_trigger
after insert on public.signups
for each row
execute function public.signups_webhook_trigger();
SQL
CREATE FUNCTION
DROP TRIGGER
CREATE TRIGGER
NOTICE:  trigger "signups_webhook_trigger" for relation "public.signups" does not exist, skipping
#12exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "select n.nspname, p.proname from pg_proc p join pg_namespace n on n.oid=p.pronamespace where p.proname='http_post';"
 nspname |  proname  
---------+-----------
 net     | http_post
(1 row)

#13exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "\dn net"
psql "$SUPABASE_DB_URL" -c "select current_setting('search_path');"
    List of schemas
 Name |     Owner      
------+----------------
 net  | supabase_admin
(1 row)

       current_setting        
------------------------------
 "\$user", public, extensions
(1 row)

#14exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" <<'SQL'
create or replace function public.signups_webhook_trigger()
returns trigger
language plpgsql
security definer
set search_path = public, extensions, vault, net
as $$
declare
  v_url text;
  v_key text;
  v_payload jsonb;
  v_request_id bigint;
begin
  select decrypted_secret into v_url
    from vault.decrypted_secrets where name = 'project_url';

  select decrypted_secret into v_key
    from vault.decrypted_secrets where name = 'service_role_key';

  v_payload := jsonb_build_object(
    'email', NEW.email,
    'plan', NEW.plan,
    'id', NEW.id,
    'created_at', NEW.created_at
  );

  select net.http_post(
    url := v_url || '/functions/v1/hook-recorder',
    headers := jsonb_build_object(
      'Content-Type', 'application/json',
      'Authorization', 'Bearer ' || v_key
    ),
    body := v_payload
  ) into v_request_id;

  raise log 'signups_webhook_trigger: dispatched request_id=%', v_request_id;

  return NEW;
end;
$$;
SQL
CREATE FUNCTION
#15exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "select rolname from pg_roles where rolname in ('postgres','authenticator','anon','authenticated','service_role');"
psql "$SUPABASE_DB_URL" -c "\dp net.*" 2>&1 | head -20
psql "$SUPABASE_DB_URL" -c "select proowner::regrole from pg_proc where proname='signups_webhook_trigger';"
    rolname    
---------------
 authenticated
 anon
 service_role
 postgres
 authenticator
(5 rows)

                                                   Access privileges
 Schema |           Name            |   Type   |           Access privileges            | Column privileges | Policies 
--------+---------------------------+----------+----------------------------------------+-------------------+----------
 net    | _http_response            | table    | supabase_admin=arwdDxtm/supabase_admin+|                   | 
        |                           |          | =arwdDxtm/supabase_admin               |                   | 
 net    | http_request_queue        | table    | supabase_admin=arwdDxtm/supabase_admin+|                   | 
        |                           |          | =arwdDxtm/supabase_admin               |                   | 
 net    | http_request_queue_id_seq | sequence | supabase_admin=rwU/supabase_admin     +|                   | 
        |                           |          | =rwU/supabase_admin                    |                   | 
(3 rows)

 proowner 
----------
 postgres
(1 row)

#16exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "select net.http_post(url := '$SUPABASE_URL/functions/v1/hook-recorder', headers := jsonb_build_object('Content-Type','application/json','Authorization','Bearer $SUPABASE_ANON_KEY'), body := jsonb_build_object('email','direct_net_test@example.com','plan','free')) as request_id;"
sleep 3
psql "$SUPABASE_DB_URL" -c "select * from public.webhook_receipts order by id desc limit 3;"
 request_id 
------------
          1
(1 row)

 id |          received_at          |                         payload                          
----+-------------------------------+----------------------------------------------------------
  4 | 2026-07-24 05:07:53.483842+00 | {"plan": "free", "email": "direct_net_test@example.com"}
  3 | 2026-07-24 05:06:51.508947+00 | {"plan": "free", "email": "probe2@example.com"}
  2 | 2026-07-24 05:06:51.196946+00 | {"plan": "free", "email": "probe@example.com"}
(3 rows)

#17exit 0
export PGPASSWORD=$SUPABASE_DB_PASSWORD
TEST_EMAIL="trigger_test_$(date +%s)@example.com"
echo "Inserting with email=$TEST_EMAIL"
psql "$SUPABASE_DB_URL" -c "insert into public.signups (email, plan) values ('$TEST_EMAIL', 'pro') returning *;"
echo "Waiting for async webhook delivery..."
sleep 4
psql "$SUPABASE_DB_URL" -c "select id, received_at, payload from public.webhook_receipts where payload->>'email' = '$TEST_EMAIL';"
Inserting with email=trigger_test_1784869682@example.com
 id |                email                | plan |          created_at           
----+-------------------------------------+------+-------------------------------
  1 | trigger_test_1784869682@example.com | pro  | 2026-07-24 05:08:03.147095+00
(1 row)

INSERT 0 1
Waiting for async webhook delivery...
 id |         received_at          |                                                          payload                                                           
----+------------------------------+----------------------------------------------------------------------------------------------------------------------------
  5 | 2026-07-24 05:08:03.31952+00 | {"id": 1, "plan": "pro", "email": "trigger_test_1784869682@example.com", "created_at": "2026-07-24T05:08:03.147095+00:00"}
(1 row)

#18exit 0
TEST_EMAIL2="rest_client_test_$(date +%s)@example.com"
echo "Inserting via PostgREST (anon key) with email=$TEST_EMAIL2"
curl -s -X POST "$SUPABASE_URL/rest/v1/signups" \
  -H "apikey: $SUPABASE_ANON_KEY" \
  -H "Authorization: Bearer $SUPABASE_ANON_KEY" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d "{\"email\":\"$TEST_EMAIL2\",\"plan\":\"enterprise\"}"
echo
echo "Waiting..."
sleep 4
export PGPASSWORD=$SUPABASE_DB_PASSWORD
psql "$SUPABASE_DB_URL" -c "select id, received_at, payload from public.webhook_receipts where payload->>'email' = '$TEST_EMAIL2';"
Inserting via PostgREST (anon key) with email=rest_client_test_1784869694@example.com
[{"id":2,"email":"rest_client_test_1784869694@example.com","plan":"enterprise","created_at":"2026-07-24T05:08:14.838134+00:00"}]
Waiting...
 id |         received_at          |                                                                payload                                                                
----+------------------------------+---------------------------------------------------------------------------------------------------------------------------------------
  6 | 2026-07-24 05:08:14.99918+00 | {"id": 2, "plan": "enterprise", "email": "rest_client_test_1784869694@example.com", "created_at": "2026-07-24T05:08:14.838134+00:00"}
(1 row)

What it said at the end

End-to-end proof successful. The insert into `signups` triggered the webhook automatically, and it landed in `webhook_receipts` with the correct email and plan. Let's also test via the REST API (anon key) to prove it works regardless of which client performs the insert — not just via direct psql/service role.

15 earlier narration turn(s) are in the raw transcript.

How it was graded

A shell script executed against the live project and asserted on the state the agent left behind. No model judged another model.

exit 0 OK

Check it yourself

Raw transcript · Task definition and verifier · Every attempt