env | grep -i supabase; echo "---"; which psql curl jq 2>/dev/null; echo "---"; psql --version 2>/dev/null; curl --version 2>/dev/null | head -1
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> --- /usr/bin/psql /usr/bin/curl /usr/bin/jq --- psql (PostgreSQL) 18.4 (Debian 18.4-1.pgdg12+1) curl 7.88.1 (x86_64-pc-linux-gnu) libcurl/7.88.1 OpenSSL/3.0.20 zlib/1.2.13 brotli/1.0.9 zstd/1.5.4 libidn2/2.3.3 libpsl/0.21.2 (+libidn2/2.3.3) libssh2/1.10.0 nghttp2/1.52.0 librtmp/2.3 OpenLDAP/2.5.13
psql "$SUPABASE_DB_URL" -c "\d public.orgs" -c "\d public.org_members" -c "\d public.tickets" 2>&1 | head -80
Table "public.orgs"
Column | Type | Collation | Nullable | Default
--------+------+-----------+----------+-------------------
id | uuid | | not null | gen_random_uuid()
name | text | | not null |
Indexes:
"orgs_pkey" PRIMARY KEY, btree (id)
"orgs_name_key" UNIQUE CONSTRAINT, btree (name)
Referenced by:
TABLE "org_members" CONSTRAINT "org_members_org_id_fkey" FOREIGN KEY (org_id) REFERENCES orgs(id) ON DELETE CASCADE
TABLE "tickets" CONSTRAINT "tickets_org_id_fkey" FOREIGN KEY (org_id) REFERENCES orgs(id) ON DELETE CASCADE
Table "public.org_members"
Column | Type | Collation | Nullable | Default
---------+------+-----------+----------+---------
org_id | uuid | | not null |
user_id | uuid | | not null |
role | text | | not null |
Indexes:
"org_members_pkey" PRIMARY KEY, btree (org_id, user_id)
Check constraints:
"org_members_role_check" CHECK (role = ANY (ARRAY['admin'::text, 'member'::text]))
Foreign-key constraints:
"org_members_org_id_fkey" FOREIGN KEY (org_id) REFERENCES orgs(id) ON DELETE CASCADE
"org_members_user_id_fkey" FOREIGN KEY (user_id) REFERENCES auth.users(id) ON DELETE CASCADE
Table "public.tickets"
Column | Type | Collation | Nullable | Default
--------+--------+-----------+----------+----------------------------------
id | bigint | | not null | generated by default as identity
org_id | uuid | | not null |
title | text | | not null |
status | text | | not null | 'open'::text
Indexes:
"tickets_pkey" PRIMARY KEY, btree (id)
Foreign-key constraints:
"tickets_org_id_fkey" FOREIGN KEY (org_id) REFERENCES orgs(id) ON DELETE CASCADE
psql "$SUPABASE_DB_URL" <<'SQL' 2>&1 | head -60
SELECT 'orgs' AS t, count(*) FROM public.orgs
UNION ALL SELECT 'org_members', count(*) FROM public.org_members
UNION ALL SELECT 'tickets', count(*) FROM public.tickets;
SELECT * FROM public.orgs;
SELECT om.*, u.email FROM public.org_members om JOIN auth.users u ON u.id = om.user_id ORDER BY om.org_id, om.user_id;
SELECT t.* FROM public.tickets t ORDER BY t.org_id, t.id;
SELECT relname, relrowsecurity FROM pg_class WHERE relname IN ('orgs','org_members','tickets') AND relnamespace='public'::regnamespace;
SQL t | count
-------------+-------
orgs | 2
org_members | 3
tickets | 5
(3 rows)
id | name
--------------------------------------+--------
31af8222-1924-4ca9-8143-ff7a6f922e9e | Acme
1c48b480-959f-47bc-a7f3-91411e5d5108 | Globex
(2 rows)
org_id | user_id | role | email
--------------------------------------+--------------------------------------+--------+-----------------------
1c48b480-959f-47bc-a7f3-91411e5d5108 | a31020b0-9c1e-420d-a06a-52492c241836 | member | wen-outsider@cari.dev
31af8222-1924-4ca9-8143-ff7a6f922e9e | 3e29c3dd-20f9-4a4a-9c59-5393f34c3b7a | admin | uma-admin@cari.dev
31af8222-1924-4ca9-8143-ff7a6f922e9e | b66ac58d-7ab7-4ed4-bce2-c092462a7cc9 | member | vic-member@cari.dev
(3 rows)
id | org_id | title | status
----+--------------------------------------+----------------+--------
4 | 1c48b480-959f-47bc-a7f3-91411e5d5108 | Migrate DNS | open
5 | 1c48b480-959f-47bc-a7f3-91411e5d5108 | Renew cert | open
1 | 31af8222-1924-4ca9-8143-ff7a6f922e9e | Fix login | open
2 | 31af8222-1924-4ca9-8143-ff7a6f922e9e | Update billing | open
3 | 31af8222-1924-4ca9-8143-ff7a6f922e9e | Rotate keys | open
(5 rows)
relname | relrowsecurity
-------------+----------------
org_members | f
orgs | f
tickets | f
(3 rows)
psql "$SUPABASE_DB_URL" <<'SQL' 2>&1 | head -40
SELECT schemaname, tablename, policyname FROM pg_policies WHERE schemaname='public';
SELECT proname, prosecdef FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace WHERE n.nspname='auth' AND proname IN ('uid','role');
SQLschemaname | tablename | policyname ------------+-----------+------------ (0 rows) proname | prosecdef ---------+----------- role | f uid | f (2 rows)
psql "$SUPABASE_DB_URL" <<'SQL' 2>&1
-- =========================================================
-- Helper functions (SECURITY DEFINER => run as table owner,
-- bypass RLS, avoiding recursive policy evaluation on
-- org_members). They still read the *caller's* JWT via auth.uid().
-- =========================================================
CREATE OR REPLACE FUNCTION public.is_org_member(p_org_id uuid)
RETURNS boolean
LANGUAGE sql
SECURITY DEFINER
SET search_path = public
AS $$
SELECT EXISTS (
SELECT 1 FROM public.org_members om
WHERE om.org_id = p_org_id
AND om.user_id = auth.uid()
);
$$;
CREATE OR REPLACE FUNCTION public.is_org_admin(p_org_id uuid)
RETURNS boolean
LANGUAGE sql
SECURITY DEFINER
SET search_path = public
AS $$
SELECT EXISTS (
SELECT 1 FROM public.org_members om
WHERE om.org_id = p_org_id
AND om.user_id = auth.uid()
AND om.role = 'admin'
);
$$;
GRANT EXECUTE ON FUNCTION public.is_org_member(uuid) TO anon, authenticated;
GRANT EXECUTE ON FUNCTION public.is_org_admin(uuid) TO anon, authenticated;
-- =========================================================
-- Enable Row Level Security on all three tables
-- =========================================================
ALTER TABLE public.orgs ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.org_members ENABLE ROW LEVEL SECURITY;
ALTER TABLE public.tickets ENABLE ROW LEVEL SECURITY;
SQL
echo "exit=$?"CREATE FUNCTION CREATE FUNCTION GRANT GRANT ALTER TABLE ALTER TABLE ALTER TABLE exit=0
psql "$SUPABASE_DB_URL" <<'SQL' 2>&1 -- ===================== TICKETS ===================== -- Any member (any role) of the org can READ tickets. DROP POLICY IF EXISTS tickets_select ON public.tickets; CREATE POLICY tickets_select ON public.tickets FOR SELECT USING (public.is_org_member(org_id)); -- Only admins can INSERT / UPDATE / DELETE tickets of their org. DROP POLICY IF EXISTS tickets_insert ON public.tickets; CREATE POLICY tickets_insert ON public.tickets FOR INSERT WITH CHECK (public.is_org_admin(org_id)); DROP POLICY IF EXISTS tickets_update ON public.tickets; CREATE POLICY tickets_update ON public.tickets FOR UPDATE USING (public.is_org_admin(org_id)) WITH CHECK (public.is_org_admin(org_id)); DROP POLICY IF EXISTS tickets_delete ON public.tickets; CREATE POLICY tickets_delete ON public.tickets FOR DELETE USING (public.is_org_admin(org_id)); -- ===================== ORG_MEMBERS ===================== -- Members can see ONLY the member list of their own org. DROP POLICY IF EXISTS org_members_select ON public.org_members; CREATE POLICY org_members_select ON public.org_members FOR SELECT USING (public.is_org_member(org_id)); -- (No INSERT/UPDATE/DELETE policies => default-deny for writes) -- ===================== ORGS ===================== -- Remains readable by authenticated users (members need it). DROP POLICY IF EXISTS orgs_select ON public.orgs; CREATE POLICY orgs_select ON public.orgs FOR SELECT TO authenticated USING (true); SQL echo "exit=$?"
NOTICE: policy "tickets_select" for relation "public.tickets" does not exist, skipping DROP POLICY CREATE POLICY NOTICE: policy "tickets_insert" for relation "public.tickets" does not exist, skipping DROP POLICY CREATE POLICY NOTICE: policy "tickets_update" for relation "public.tickets" does not exist, skipping DROP POLICY CREATE POLICY NOTICE: policy "tickets_delete" for relation "public.tickets" does not exist, skipping DROP POLICY CREATE POLICY NOTICE: policy "org_members_select" for relation "public.org_members" does not exist, skipping DROP POLICY CREATE POLICY NOTICE: policy "orgs_select" for relation "public.orgs" does not exist, skipping DROP POLICY CREATE POLICY exit=0
cat > /tmp/auth.sh <<'BASH'
#!/usr/bin/env bash
# Get a JWT for a user via password grant
URL="$SUPABASE_URL/auth/v1/token?grant_type=password"
ANON="$SUPABASE_ANON_KEY"
email="$1"; pass="$2"
resp=$(curl -s -X POST "$URL" \
-H "apikey: $ANON" \
-H "Content-Type: application/json" \
-d "{\"email\":\"$email\",\"password\":\"$pass\"}")
echo "$resp" | jq -r '.access_token // .msg // .error_description // .'
BASH
chmod +x /tmp/auth.sh
UMA=$(/tmp/auth.sh uma-admin@cari.dev Passw0rd-uma-11)
VIC=$(/tmp/auth.sh vic-member@cari.dev Passw0rd-vic-22)
WEN=$(/tmp/auth.sh wen-outsider@cari.dev Passw0rd-wen-33)
echo "UMA len: ${#UMA}"; echo "VIC len: ${#VIC}"; echo "WEN len: ${#WEN}"
echo "$UMA" | head -c 60; echo; echo "$VIC" | head -c 60; echo; echo "$WEN" | head -c 60; echo
echo "$UMA" > /tmp/uma.jwt; echo "$VIC" > /tmp/vic.jwt; echo "$WEN" > /tmp/wen.jwtUMA len: 796 VIC len: 798 WEN len: 800 eyJhbGciOiJFUzI1NiIsImtpZCI6Ijg4MmRlOWVlLWM4NTctNDVkNC04OTc4 eyJhbGciOiJFUzI1NiIsImtpZCI6Ijg4MmRlOWVlLWM4NTctNDVkNC04OTc4 eyJhbGciOiJFUzI1NiIsImtpZCI6Ijg4MmRlOWVlLWM4NTctNDVkNC04OTc4
cat > /tmp/test.sh <<'BASH'
#!/usr/bin/env bash
URL="$SUPABASE_URL/rest/v1"
ANON="$SUPABASE_ANON_KEY"
jget(){ # table, jwt, query
curl -s -G "$URL/$1" -H "apikey: $2" -H "Authorization: Bearer $2" ${3:+-d "$3"} \
| jq -r 'length' 2>/dev/null || echo "ERR"; }
jrw(){ # method, table, jwt, data
curl -s -o /dev/null -w "%{http_code}" -X "$1" "$URL/$2" \
-H "apikey: $3" -H "Authorization: Bearer $3" -H "Content-Type: application/json" \
${4:+-d "$4"}; }
UMA=$(cat /tmp/uma.jwt); VIC=$(cat /tmp/vic.jwt); WEN=$(cat /tmp/wen.jwt)
ACME=31af8222-1924-4ca9-8143-ff7a6f922e9e
GLOBEX=1c48b480-959f-47bc-a7f3-91411e5d5108
echo "=== TICKETS READ ==="
echo "anon tickets: $(jget tickets "$ANON" "select=id" ) (expect 0)"
echo "uma(acme admin): $(jget tickets "$UMA" "select=id" ) (expect 3)"
echo "vic(acme member): $(jget tickets "$VIC" "select=id" ) (expect 3)"
echo "wen(globex only): $(jget tickets "$WEN" "select=id" ) (expect 2)"
echo "=== TICKETS WRITE ==="
echo "vic INSERT (member) -> $(jrw POST tickets "$VIC" "{\"org_id\":\"$ACME\",\"title\":\"x\",\"status\":\"open\"}") (expect 403)"
echo "uma INSERT (admin) -> $(jrw POST tickets "$UMA" "{\"org_id\":\"$ACME\",\"title\":\"x\",\"status\":\"open\"}") (expect 201)"
echo "wen INSERT acme -> $(jrw POST tickets "$WEN" "{\"org_id\":\"$ACME\",\"title\":\"x\",\"status\":\"open\"}") (expect 403)"
echo "uma UPDATE own -> $(jrw PATCH tickets?id=eq.1 "$UMA" "{\"status\":\"closed\"}") (expect 200)"
echo "uma DELETE (cleanup)-> $(jrw DELETE tickets?id=eq.1 "$UMA" "") (expect 200... restore next)"
echo "vic DELETE acme -> $(jrw DELETE tickets?id=eq.2 "$VIC" "") (expect 403)"
BASH
bash /tmp/test.sh=== TICKETS READ === anon tickets: 0 (expect 0) uma(acme admin): 2 (expect 3) vic(acme member): 2 (expect 3) wen(globex only): 2 (expect 2) === TICKETS WRITE === vic INSERT (member) -> 401 (expect 403) uma INSERT (admin) -> 401 (expect 201) wen INSERT acme -> 401 (expect 403) uma UPDATE own -> 401 (expect 200) uma DELETE (cleanup)-> 401 (expect 200... restore next) vic DELETE acme -> 401 (expect 403)
UMA=$(cat /tmp/uma.jwt); ANON="$SUPABASE_ANON_KEY" echo "=== raw uma tickets (first 500 chars) ===" curl -s -G "$SUPABASE_URL/rest/v1/tickets?select=id" \ -H "apikey: $UMA" -H "Authorization: Bearer $UMA" | head -c 500 echo; echo "=== headers ===" curl -s -D - -o /dev/null -G "$SUPABASE_URL/rest/v1/tickets?select=id" \ -H "apikey: $UMA" -H "Authorization: Bearer $UMA" | head -20 echo "=== raw anon ===" curl -s -G "$SUPABASE_URL/rest/v1/tickets?select=id" -H "apikey: $ANON" | head -c 300
=== raw uma tickets (first 500 chars) ===
{"message":"Invalid API key","hint":"Double check your Supabase `anon` or `service_role` API key."}
=== headers ===
HTTP/2 401
date: Sun, 26 Jul 2026 03:00:05 GMT
content-type: application/json;charset=UTF-8
content-length: 99
access-control-allow-origin: *
x-content-type-options: nosniff
access-control-allow-methods: GET,HEAD,PUT,PATCH,POST,DELETE,OPTIONS,TRACE,CONNECT
access-control-max-age: 3600
sb-error-code: UNAUTHORIZED_INVALID_API_KEY
sb-gateway-version: 1
sb-project-ref: <ref>
sb-request-id: 019f9c5d-90ad-7e4e-af3a-57c2b22c5154
strict-transport-security: max-age=31536000; includeSubDomains; preload
set-cookie: __cf_bm=YqK71eRwqZ7mK4SWiicud1SzhxNswLZ7ob0h19AQlag-1785034805.415857-1.0.1.1-wuCsOuR79rK7ZV19SwQ0vD7Dk2WSp0f4hrKirFTJEUOlGCiKTWoaQRkNutNPVZVcv80nrYhGOLS0JHM63qjPGd8WGn5Gg2mKOWmvCQ6p4hQkKA_XMNHBtjjOIs9DtKmj; HttpOnly; SameSite=None; Secure; Path=/; Domain=supabase.co; Expires=Sun, 26 Jul 2026 03:30:05 GMT
server: cloudflare
cf-ray: a21026eddd9c18b5-FRA
alt-svc: h3=":443"; ma=86400
=== raw anon ===
[]cat > /tmp/test.sh <<'BASH'
#!/usr/bin/env bash
URL="$SUPABASE_URL/rest/v1"
ANON="$SUPABASE_ANON_KEY"
jget(){ # table jwt query
curl -s -G "$URL/$1" -H "apikey: $ANON" -H "Authorization: Bearer $2" ${3:+-d "$3"} \
| jq -r 'length' 2>/dev/null || echo "ERR"; }
jrw(){ # method table jwt data
curl -s -o /dev/null -w "%{http_code}" -X "$1" "$URL/$2" \
-H "apikey: $ANON" -H "Authorization: Bearer $3" -H "Content-Type: application/json" \
${4:+-d "$4"}; }
UMA=$(cat /tmp/uma.jwt); VIC=$(cat /tmp/vic.jwt); WEN=$(cat /tmp/wen.jwt)
ACME=31af8222-1924-4ca9-8143-ff7a6f922e9e
GLOBEX=1c48b480-959f-47bc-a7f3-91411e5d5108
echo "=== TICKETS READ ==="
echo "anon tickets: $(jget tickets "$ANON") (expect 0)"
echo "uma(acme admin): $(jget tickets "$UMA") (expect 3)"
echo "vic(acme member): $(jget tickets "$VIC") (expect 3)"
echo "wen(globex only): $(jget tickets "$WEN") (expect 2)"
echo "=== ORG_MEMBERS READ ==="
echo "anon org_members: $(jget org_members "$ANON") (expect 0)"
echo "uma org_members: $(jget org_members "$UMA") (expect 3: own org=2, but wait count all? expect 2 Acme)"
echo "vic org_members: $(jget org_members "$VIC") (expect 2 Acme)"
echo "wen org_members: $(jget org_members "$WEN") (expect 1 Globex)"
echo "=== ORGS READ ==="
echo "anon orgs: $(jget orgs "$ANON") (expect 0)"
echo "uma orgs: $(jget orgs "$UMA") (expect 2)"
echo "=== TICKETS WRITE ==="
echo "vic INSERT (member) -> $(jrw POST tickets "$VIC" "{\"org_id\":\"$ACME\",\"title\":\"x\",\"status\":\"open\"}") (expect 403)"
echo "uma INSERT (admin) -> $(jrw POST tickets "$UMA" "{\"org_id\":\"$ACME\",\"title\":\"x\",\"status\":\"open\"}") (expect 201)"
echo "wen INSERT acme -> $(jrw POST tickets "$WEN" "{\"org_id\":\"$ACME\",\"title\":\"x\",\"status\":\"open\"}") (expect 403)"
echo "uma UPDATE own -> $(jrw PATCH tickets?id=eq.1 "$UMA" "{\"status\":\"closed\"}") (expect 200 -> restore)"
echo "uma restore own -> $(jrw PATCH tickets?id=eq.1 "$UMA" "{\"status\":\"open\"}") (expect 200)"
echo "vic DELETE acme -> $(jrw DELETE tickets?id=eq.2 "$VIC") (expect 403)"
echo "=== ORG_MEMBERS WRITE (default deny) ==="
echo "uma INSERT member -> $(jrw POST org_members "$UMA" "{\"org_id\":\"$ACME\",\"user_id\":\"$UMA\",\"role\":\"member\"}") (expect 403)"
BASH
bash /tmp/test.sh=== TICKETS READ === anon tickets: 0 (expect 0) uma(acme admin): 3 (expect 3) vic(acme member): 3 (expect 3) wen(globex only): 2 (expect 2) === ORG_MEMBERS READ === anon org_members: 0 (expect 0) uma org_members: 2 (expect 3: own org=2, but wait count all? expect 2 Acme) vic org_members: 2 (expect 2 Acme) wen org_members: 1 (expect 1 Globex) === ORGS READ === anon orgs: 0 (expect 0) uma orgs: 2 (expect 2) === TICKETS WRITE === vic INSERT (member) -> 403 (expect 403) uma INSERT (admin) -> 201 (expect 201) wen INSERT acme -> 403 (expect 403) uma UPDATE own -> 204 (expect 200 -> restore) uma restore own -> 204 (expect 200) vic DELETE acme -> 204 (expect 403) === ORG_MEMBERS WRITE (default deny) === uma INSERT member -> 400 (expect 403)
echo "=== ticket counts after tests (via service role) ==="
psql "$SUPABASE_DB_URL" -t -c "SELECT org_id, count(*) FROM public.tickets GROUP BY org_id ORDER BY org_id;"
echo "=== rows 1,2 present? ==="
psql "$SUPABASE_DB_URL" -t -c "SELECT id, status FROM public.tickets WHERE id IN (1,2) ORDER BY id;"
echo "=== org_members write test with valid uuid (should be 403 default-deny) ==="
ANON="$SUPABASE_ANON_KEY"; UMA=$(cat /tmp/uma.jwt)
curl -s -o /dev/null -w "%{http_code}\n" -X POST "$SUPABASE_URL/rest/v1/org_members" \
-H "apikey: $ANON" -H "Authorization: Bearer $UMA" -H "Content-Type: application/json" \
-d '{"org_id":"31af8222-1924-4ca9-8143-ff7a6f922e9e","user_id":"00000000-0000-0000-0000-000000000000","role":"member"}'
echo "=== full org_members count still 3? ==="
psql "$SUPABASE_DB_URL" -t -c "SELECT count(*) FROM public.org_members;"=== ticket counts after tests (via service role) ===
1c48b480-959f-47bc-a7f3-91411e5d5108 | 2
31af8222-1924-4ca9-8143-ff7a6f922e9e | 4
=== rows 1,2 present? ===
1 | open
2 | open
=== org_members write test with valid uuid (should be 403 default-deny) ===
403
=== full org_members count still 3? ===
3
psql "$SUPABASE_DB_URL" -t -c "DELETE FROM public.tickets WHERE title='x' AND org_id='31af8222-1924-4ca9-8143-ff7a6f922e9e';" echo "=== final ticket counts (should be Acme=3, Globex=2) ===" psql "$SUPABASE_DB_URL" -t -c "SELECT org_id, count(*) FROM public.tickets GROUP BY org_id ORDER BY org_id;" echo "=== final ticket titles ===" psql "$SUPABASE_DB_URL" -t -c "SELECT id, title, status FROM public.tickets ORDER BY id;"
DELETE 1 === final ticket counts (should be Acme=3, Globex=2) === 1c48b480-959f-47bc-a7f3-91411e5d5108 | 2 31af8222-1924-4ca9-8143-ff7a6f922e9e | 3 === final ticket titles === 1 | Fix login | open 2 | Update billing | open 3 | Rotate keys | open 4 | Migrate DNS | open 5 | Renew cert | open
psql "$SUPABASE_DB_URL" <<'SQL' 2>&1
SELECT c.relname AS table, c.relrowsecurity AS rls_enabled
FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace
WHERE n.nspname='public' AND c.relname IN ('orgs','org_members','tickets');
SELECT tablename, policyname, cmd, roles, qual,
with_check FROM pg_policies WHERE schemaname='public' ORDER BY tablename, policyname;
SQL table | rls_enabled
-------------+-------------
org_members | t
orgs | t
tickets | t
(3 rows)
tablename | policyname | cmd | roles | qual | with_check
-------------+--------------------+--------+-----------------+-----------------------+----------------------
org_members | org_members_select | SELECT | {public} | is_org_member(org_id) |
orgs | orgs_select | SELECT | {authenticated} | true |
tickets | tickets_delete | DELETE | {public} | is_org_admin(org_id) |
tickets | tickets_insert | INSERT | {public} | | is_org_admin(org_id)
tickets | tickets_select | SELECT | {public} | is_org_member(org_id) |
tickets | tickets_update | UPDATE | {public} | is_org_admin(org_id) | is_org_admin(org_id)
(6 rows)
12 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