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

google/gemini-3.1-pro-preview · d2_webhooks · rep 3

pass
model
google/gemini-3.1-pro-preview
task
d2_webhooks
rep
3
day
2
steps
23
tokens
44,543
est. cost
$0.267
agent time
104s
wave
s4
started
2026-07-24T05:14:45Z

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 — 23 commands

#1exit 0
env | grep SUPABASE
SUPABASE_DB_PASSWORD=<redacted:SUPABASE_DB_PASSWORD>
SUPABASE_DB_URL=<redacted:SUPABASE_DB_URL>
SUPABASE_URL=https://<ref>.supabase.co
SUPABASE_SERVICE_ROLE_KEY=<redacted:SUPABASE_SERVICE_ROLE_KEY>
SUPABASE_PROJECT_REF=<ref>
SUPABASE_ANON_KEY=<redacted:SUPABASE_ANON_KEY>
#2exit 0
psql "$SUPABASE_DB_URL" -c "\df supabase_functions.http_request"
                       List of functions
 Schema | Name | Result data type | Argument data types | Type 
--------+------+------------------+---------------------+------
(0 rows)

#3exit 0
psql "$SUPABASE_DB_URL" -c "CREATE EXTENSION IF NOT EXISTS pg_net;"
CREATE EXTENSION
#4exit 0
psql "$SUPABASE_DB_URL" -c "\df net.http_post"
                                                                                                             List of functions
 Schema |   Name    | Result data type |                                                                                    Argument data types                                                                                     | Type 
--------+-----------+------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+------
 net    | http_post | bigint           | url text, body jsonb DEFAULT '{}'::jsonb, params jsonb DEFAULT '{}'::jsonb, headers jsonb DEFAULT '{"Content-Type": "application/json"}'::jsonb, timeout_milliseconds integer DEFAULT 5000 | func
(1 row)

#5exit 0
psql "$SUPABASE_DB_URL" -c "\d public.signups"
                                     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)

#6exit 0
curl -X POST "$SUPABASE_URL/functions/v1/hook-recorder" \
  -H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","plan":"pro"}'
{"ok":true}
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100    52    0    11  100    41     23     87 --:--:-- --:--:-- --:--:--   110
#7exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#8exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#9exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#10exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#11exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#12exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#13exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#14exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#15exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#16exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                   payload                    
----+-------------------------------+----------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
(1 row)

#17exit 0
cat << 'EOF' > setup_webhook.sql
CREATE OR REPLACE FUNCTION public.deliver_webhook()
RETURNS trigger AS $$
BEGIN
  PERFORM net.http_post(
    url := current_setting('app.settings.webhook_url'),
    headers := jsonb_build_object(
      'Content-Type', 'application/json',
      'Authorization', 'Bearer ' || current_setting('app.settings.service_role_key')
    ),
    body := jsonb_build_object(
      'email', NEW.email,
      'plan', NEW.plan
    )
  );
  RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

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.deliver_webhook();
EOF
#18exit 1
psql "$SUPABASE_DB_URL" -c "ALTER DATABASE postgres SET app.settings.webhook_url TO '$SUPABASE_URL/functions/v1/hook-recorder';"
ERROR:  permission denied to set parameter "app.settings.webhook_url"
#19exit 0
cat << 'EOF' > setup_webhook.sql
CREATE OR REPLACE FUNCTION public.deliver_webhook()
RETURNS trigger AS $$
DECLARE
  v_url text := current_setting('current_schema', true);
  v_jwt text;
BEGIN
  v_url := current_setting('app.webhook.url', true);
  v_jwt := current_setting('app.webhook.jwt', true);
  
  -- since we can't alter database settings easily as non-superuser,
  -- we can hardcode it or use Vault/pg_net with custom headers.
  -- Let's just hardcode the env variables.
END;
$$ LANGUAGE plpgsql;
EOF
#20exit 0
cat << EOF > setup_webhook.sql
CREATE OR REPLACE FUNCTION public.deliver_webhook()
RETURNS trigger AS \$\$
BEGIN
  PERFORM net.http_post(
    url := '$SUPABASE_URL/functions/v1/hook-recorder',
    headers := jsonb_build_object(
      'Content-Type', 'application/json',
      'Authorization', 'Bearer $SUPABASE_SERVICE_ROLE_KEY'
    ),
    body := jsonb_build_object(
      'email', NEW.email,
      'plan', NEW.plan
    )
  );
  RETURN NEW;
END;
\$\$ LANGUAGE plpgsql SECURITY DEFINER;

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.deliver_webhook();
EOF
psql "$SUPABASE_DB_URL" -f setup_webhook.sql
CREATE FUNCTION
DROP TRIGGER
CREATE TRIGGER
psql:setup_webhook.sql:19: NOTICE:  trigger "signups_webhook_trigger" for relation "public.signups" does not exist, skipping
#21exit 0
psql "$SUPABASE_DB_URL" -c "INSERT INTO public.signups (email, plan) VALUES ('test-insert@example.com', 'enterprise');"
INSERT 0 1
#22exit 0
sleep 5; psql "$SUPABASE_DB_URL" -c "SELECT * FROM public.webhook_receipts;"
 id |          received_at          |                          payload                           
----+-------------------------------+------------------------------------------------------------
  2 | 2026-07-24 05:15:33.160813+00 | {"plan": "pro", "email": "test@example.com"}
  3 | 2026-07-24 05:16:27.517413+00 | {"plan": "enterprise", "email": "test-insert@example.com"}
(2 rows)

#23exit 0
psql "$SUPABASE_DB_URL" -c "SELECT * FROM net.http_request_queue;"
 id | method | url | headers | body | timeout_milliseconds 
----+--------+-----+---------+------+----------------------
(0 rows)

What it said at the end

I have accomplished the task! Here is a summary of what I did: 1. **Enable pg_net extension:** We need to be able to make HTTP requests from inside Postgres, so I enabled the `pg_net` extension. 2. **Create Database Trigger Function:** I created a PL/pgSQL function (`public.deliver_webhook()`) that uses `net.http_post` to asynchronously fire an HTTP POST to `{SUPABASE_URL}/functions/v1/hook-recorder`. I injected the `SUPABASE_SERVICE_ROLE_KEY` directly into the `Authorization` header so it has valid JWT access, and I used `NEW.email` and `NEW.plan` to construct the JSON payload. 3. **Register the Trigger:** I attached the function as an `AFTER INSERT` trigger on `public.signups`. 4. **End-to-End Test:** I ran a test insert into `public.signups`. Because `pg_net` places requests onto an asynchronous queue handled by background workers, the request was fired automatically without blocking the database transaction. After a 5 second sleep, I queried `public.webhook_receipts` and confirmed the payload was successfully deposited by the edge function.

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