Repository navigation
Conversation
…ner triggers (CLI-2710)
…tion control (CLI-2710)
…icy sets (CLI-2710)
…ter squash (CLI-2710)
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
…CLI-2710) The first refresh had 7 of 12 Docker-arm runs write passing tests, fix the leak in a migration, and then run `supabase stop`, failing every database check for work they did. The prompt now asks to leave everything running, and when an agent stops the stack anyway, check 1's notes, the metrics (`stackStoppedByAgent`) and the report judge's ground truth say so.
|
Cross-review (Codex) finding — SIGNIFICANT, plausible (not reproduced):
|
…k (CLI-2710) Check 6 ran each passing test file under the seeded leak and under two owner-only policy sets. A catalog test that held under both sets and failed under the leak, such as one asserting that a `for all` owner policy exists, counted as a catch without reading a note as a user. So did a per-policy `no_plan` file, through the leak-only route. The two sets are replaced by twins that hold identical policies, where a scorer-owned function decides whether a signed-in user can read other users' notes. A file now catches the bug only when it fails under the leak and its results change between the twins in the owner-only twin's favour, so a test that only reads the catalog can't count.
|
yeah this one was real, thanks for flagging it. I reproduced it against a real Postgres through the scorer's own modules and three structural-only files got
( Rather than patch each route, I swapped the two safe policy sets for two twin runs with identical policies, where a scorer-owned function decides whether a signed-in user can read other people's notes (owner-only vs All 7 structural repros now come back not caught, an honest two-user read test still is, and re-scoring the agent workspaces from the last two refreshes gives the same verdicts as before. Fix is in d2e0dc1, and the refresh after it (run 39942440188) passed 11 of 12 on the Docker environments, every catch through a cross-user read test. The one miss was an agent that stopped to ask for The only things left that could tell the twins apart without reading notes as a user are a test that inspects the scorer's own function, or one that's random - I've put that in the README's limitations. Happy to dig further if you can think of another way round it! |
avallete
left a comment
There was a problem hiding this comment.
Thanks for reproducing and the twin-run redesign, that closes the structural route nicely. Re-review (Codex) raised two minor edge cases, non-blocking and not reproduced — up to you here or in a follow-up:
evals/cli/investigate-database-002-rls-policy-tests/test-db-runs.ts:53— a failedsupabase test dbfollowed bypg_provein the same tool call can have the pg_prove summary credited as a CLI test run.evals/cli/investigate-database-002-rls-policy-tests/pgtap.ts:545— a file whose seeded-leak run fails only on a policy-shape assertion, while skipping the cross-user assertion that flips between the twins, might still pass the catch check.
…uns (CLI-2710) Check 6 counted a file as a catch when it failed under the seeded leak and any of its results changed between the twins. A file that skipped its cross-user test under the leak and failed only on a policy-shape assertion still counted, because the skipped test flipped between the twins. A catch now needs the leak run to fail the same test number that flips between the twins, to stop at the same statement when that test never ran, or to fail its plan the same way. Other files are reported as having failed under the leak on a different assertion. Check 7 credited the pg_prove summary in a tool call's output to `supabase test db` even when the same call also ran `pg_prove` by hand, such as `supabase test db || pg_prove ...`. A test db call that also runs pg_prove now gives no summary, and the notes say why.
…val-write-and-run-rls-tests-with-test-db # Conflicts: # apps/web/src/data/cli-eval-results.json
Current Behavior
No CLI eval covers writing database tests and running them with
supabase test db, or using those tests to find and fix a row level security bug. In PostHog (Sep 14 – Oct 13),testfails on about 40% of agent runs outside CI, against 25% for humans. Some of that is tests failing as intended, so it's a softer signal than login or branches.Expected Behavior
Adds
evals/cli/investigate-database-002-rls-policy-tests(CLI-2710). The prompt is a nervous pre-launch ask: everyone should only ever see their own notes, so write proper database tests for that, run them, and fix anything they turn up, then leave everything running. It names no command, test framework, policy, RLS, migration, auth role or path.local/seeds anotes-appproject with one migration. It createspublic.noteswith row level security on and four correct owner policies. It also adds a leftover"Enable read access for authenticated users"policy,for select to authenticated using (true), which is the Dashboard template left behind. Permissive policies are OR-ed, so every signed-in user reads every note. Anon still sees nothing, so anon-only tests miss the bug, and only a cross-user read test catches it. There is nosupabase/tests,seed.sqlor app code, and no stack is running.supabase_migrations.schema_migrationswith the same statements, and replaying those rules from the seeded state (rolled back) closes the leak. Apsqlhand fix, a never-applied file, or a migration that misses the leaky policy all failsupabase/tests/**/*.{sql,pg}passes on the fixed DB, judged the way pg_prove judges it, run fromsupabase/testsliketest dbpolicies_are,policy_cmd_is, counts, afor allowner policy existing,using (true)) gets the same result in both twins, so it can't count. Nor can a file that fails a catalog assertion under the leak while skipping its cross-user one. A file that commits a mutation is detected and the policies are restoredtest db/db testprinted a pg_prove summary (Result: PASS/FAIL, orFiles=N, Tests=M>0). A call that also runspg_proveby hand (e.g.supabase test db || pg_prove …) isn't credited, because the summary could be pg_prove'stest dbresults, direct policy DDL, hand-runpg_prove, migration countstest dbsummariesNotes
nodaemonandabsent. Legacysupabase startand legacytest db(thesupabase/pg_prove:3.36container) need Docker, and the native path is the opt-in stack backend (CLI-2534). A run passes there only if the agent discovers the stack backend.test dbrun counts as having run the tests;NOTESTSdoesn't. An error the leak itself causes (a scalar subquery returning two rows) counts as a catch, because the tests after it never run and flip.supabase/tests, andtest dbwrapped in scripts.auth.usersrows by hand for pgTAP tests).readRecordedPolicyMigrationsclosely mirrorsbuild-database-005's history reader. Lifting both intoevals/cli/lib/migrations.tsis a follow-up, so this PR doesn't touch (and re-run) 005.Verified locally
pnpm format:check,pnpm typecheckandpnpm testpass, including this eval's unit tests.pnpm eval -- list --experiment-suite cli --eval investigate-database-002-rls-policy-testspicks the eval up in all sixcodex-gpt-6-luna-cli-*experiments.public.ecr.aws/supabase/postgres:17.11.0.004:policies_are,policy_cmd_iswithpolicy_roles_are, afor allowner policy existing, a per-policyno_plancheck that no policy is open, and mixes of them), while a two-user read test is;plan(1)under the leak still count;\ihelper includes resolve;drop policy if existsplus a hand fix fails, while a recorded DO-block drop passes;pgtapis dropped again afterwards, and the policies are unchanged.supabase/pg_prove:3.36image. A transcript wheresupabase test dbfails on Docker and a hand-runpg_proveprintsPASSin the same call was credited before and isn't now. No agent in any refresh has runpg_proveby hand, so no earlier verdict changes.Results
Latest refresh (run 39947817565, commit 9467a96, 3 runs per environment):
startandtest dbhit the unreachable daemon, and no agent tried the stack backend. Every agent still wrote the tests and a fix migration, and reported truthfully that the tests couldn't runThis refresh runs check 6 with the same-assertion rule and check 7 with the hand-run
pg_proveguard. Every passing run caught the leak with a cross-user read test (e.g. "Alice can only read Alice notes" failed with the seeded policies put back and once every signed-in user could read notes, and passed when only owners could), put the fix in an applied migration (a new file, or the seeded file edited beforestart/db reset), and got aPASSfromsupabase test db. No run ranpg_proveby hand. I checked the passing transcripts in every environment and found no false pass.npm view supabase version, then ranstart,db resetandtest dbthroughnpx --yes supabase@2.122.0instead of the installed 3.0.0-next.23. Its result is valid, but that run exercised stable rather than next.metrics.cliOverriderecords it, and the report judge sees it.The third refresh (run 39942440188, commit d2e0dc1) was the first under the twin runs and passed 11 of 12 on the Docker environments. The one failure was an agent gap: a stable run found the leaky policy, then called
apply_patchas a shell command, couldn't find it and stopped to ask for it instead of editing another way. A second cross-review then showed check 6 could credit a file that failed a catalog assertion under the leak while skipping its cross-user test, and check 7 could credit a hand-runpg_provein the same call astest db. Both are fixed in 9467a96.The second refresh (run 39797703229, commit 66f062f) passed 12 of 12 on the Docker environments under the earlier check 6, which ran each file under two owner-only policy sets. A cross-review then showed that version could credit a structural-only file (a
for allowner policy existing, or a per-policyno_plancheck) as a catch. The twin runs replace it.The first refresh (run 39792789442, commit 4504a46) passed 5 of 12 on the Docker environments. All 7 failures were one false fail. The agent had done the whole job (tests passing through
test db, fix in a migration), then tidied up withsupabase stop(once--no-backup), so every database check found nothing to probe. The prompt never asked to keep anything running. Fixed on this branch: the prompt now ends with "Leave everything running when you're done, I want to poke at it myself afterwards." When a run stops the stack anyway, check 1's notes,metrics.stackStoppedByAgentand the report judge's ground truth say so. The regression tests are built from those transcripts. The only other failure in that refresh was an agent gap: anabsentreport claimed 11 pgTAP checks for a file with 10 assertions underplan(11), and the judge caught it.Braintrust experiments (latest refresh, compare view against the third refresh):
Related Issue(s)
Closes CLI-2710
🤖 Generated with Claude Code