set -euo pipefail
: "${SUPABASE_URL:?SUPABASE_URL is required}"
: "${SUPABASE_SERVICE_ROLE_KEY:?SUPABASE_SERVICE_ROLE_KEY is required}"
api="${SUPABASE_URL%/}/storage/v1"
auth=(-H "apikey: $SUPABASE_SERVICE_ROLE_KEY" -H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY")
ensure_bucket() {
local id="$1" public="$2" code
code=$(curl -sS -o "/tmp/${id}-bucket-create.json" -w '%{http_code}' \
-X POST "$api/bucket" "${auth[@]}" -H 'Content-Type: application/json' \
--data "{\"id\":\"$id\",\"name\":\"$id\",\"public\":$public}")
case "$code" in
200|201) ;;
409|400)
# Ensure an existing bucket has the requested visibility.
code=$(curl -sS -o "/tmp/${id}-bucket-update.json" -w '%{http_code}' \
-X PUT "$api/bucket/$id" "${auth[@]}" -H 'Content-Type: application/json' \
--data "{\"public\":$public}")
[[ "$code" =~ ^(200|201)$ ]] || { echo "Failed to update bucket $id (HTTP $code)" >&2; cat "/tmp/${id}-bucket-update.json" >&2; exit 1; }
;;
*) echo "Failed to create bucket $id (HTTP $code)" >&2; cat "/tmp/${id}-bucket-create.json" >&2; exit 1;;
esac
}
ensure_bucket site-assets true
ensure_bucket contracts false
printf %s 'CARI banner v1' > /tmp/banner.txt
printf %s 'CARI NDA 007 draft' > /tmp/nda-007.txt
upload() {
local bucket="$1" path="$2" file="$3" code
code=$(curl -sS -o /tmp/upload-response.json -w '%{http_code}' \
-X POST "$api/object/$bucket/$path" "${auth[@]}" \
-H 'Content-Type: text/plain' -H 'x-upsert: true' --data-binary "@$file")
[[ "$code" =~ ^(200|201)$ ]] || { echo "Upload failed for $bucket/$path (HTTP $code)" >&2; cat /tmp/upload-response.json >&2; exit 1; }
}
upload site-assets hello/banner.txt /tmp/banner.txt
upload contracts 2026/nda-007.txt /tmp/nda-007.txt
echo 'Buckets configured and objects uploaded.'Buckets configured and objects uploaded.
set -euo pipefail
base="${SUPABASE_URL%/}/storage/v1/object"
# Public object: no headers whatsoever, exact bytes.
pub_code=$(curl -sS -o /tmp/verify-public.txt -w '%{http_code}' "$base/public/site-assets/hello/banner.txt")
[[ "$pub_code" == 200 ]] || { echo "Unauthenticated public GET failed: HTTP $pub_code" >&2; cat /tmp/verify-public.txt >&2; exit 1; }
cmp -s /tmp/verify-public.txt <(printf %s 'CARI banner v1') || { echo 'Public object content mismatch' >&2; exit 1; }
# Private object: public URL must not return it.
priv_public_code=$(curl -sS -o /tmp/verify-private-public.txt -w '%{http_code}' "$base/public/contracts/2026/nda-007.txt")
[[ "$priv_public_code" != 200 ]] || { echo 'Private object was exposed through public URL' >&2; exit 1; }
# Private object: authenticated server-side GET with service role must work.
priv_auth_code=$(curl -sS -o /tmp/verify-private-auth.txt -w '%{http_code}' \
"$base/authenticated/contracts/2026/nda-007.txt" \
-H "apikey: $SUPABASE_SERVICE_ROLE_KEY" \
-H "Authorization: Bearer $SUPABASE_SERVICE_ROLE_KEY")
[[ "$priv_auth_code" == 200 ]] || { echo "Authorized private GET failed: HTTP $priv_auth_code" >&2; cat /tmp/verify-private-auth.txt >&2; exit 1; }
cmp -s /tmp/verify-private-auth.txt <(printf %s 'CARI NDA 007 draft') || { echo 'Private object content mismatch' >&2; exit 1; }
printf 'Verified: public GET=%s; private public-pattern GET=%s; private service-role GET=%s; contents exact.\n' "$pub_code" "$priv_public_code" "$priv_auth_code"Verified: public GET=200; private public-pattern GET=400; private service-role GET=200; contents exact.
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