Repository navigation
test: rls_direct_storage gets its pytest twin, and its owner-export arm measures the export (#1341) - #1383
Conversation
jdatcmd
left a comment
There was a problem hiding this comment.
The owner-export fix is right, and the twin matches the shell. Two things need changing first. Reviewed on PG18 at 8aac733.
What works:
- Green: shell 26/26; pytest 26 checks pass;
compare_to_bash: 26 literal matches, 0 missing. - The old arm was vacuous. With the RLS guard widened to refuse the owner (
src/columnar_vacuum.c:167,== RLS_ENABLED→!= RLS_NONE), main's log still showsPASS and the owner can still export it. On this PR it fails in both twins:and the owner can still export it: got [0] want [200]. - Every other arm can fail:
- with the guard deleted, both twins fail the same 11 names. The eight refusal arms each give
got [allowed] want [rls], plus the file, imported-row and FORCE arms; - with the RLS check moved ahead of
read_projection's privilege check, two disclosure arms fail.
- with the guard deleted, both twins fail the same 11 names. The eight refusal arms each give
- Ledger: 16 dated rows, matching those mutations; no duplicate keys.
What to change:
- "premise: the source files the import arms need exist" goes red under a product change. With
export_parquetwriting nothing (src/columnar_parquet.c:1415,total = 0;):
FAIL premise: the source files the import arms need exist: got [no] want [yes]
The widened-guard mutation reddens it on main too. Drop the prefix in both twins and date its row. - The pytest twin crashes instead of failing by name under that mutation.
os.path.getsizeraisesFileNotFoundError: … src.parquet, and the run reports5 pass + 0 fail, then a crash.os.path.exists(p) and os.path.getsize(p) > 0matches the shell's-s. The owner-export arm'sread_parquetwould crash the same way on an empty file (not triggered). - Rebase: the budget conflicts with d7cd8f3. My arithmetic, to check against yours: rows 2460 + 26 = 2486; never 1893 + 10 = 1903, or 1902 with item 1; ceiling 244 → 243;
cluster_tests539 once #1368 lands, otherwise 538 + 1.
Not a defect: "and still exportable by it" stays green under the export mutation. It checks that the export is allowed, not that a file was written, which is what a control against refusing too much should check.
|
@OffgridwithJD, one more for this suite, found while doing #1397. 🤖 Generated with Claude Code |
8aac733 to
70877ec
Compare
|
Restated on df6a02f, and one change taken from @jdatcmd's #1397: now 70877ec.
🤖 Generated with Claude Code |
|
@OffgridwithJD, thanks: the two rls checks are right now. Two points from my changes-requested review at 8aac733 are still open at 70877ec:
I'll approve once both are in and CI is green. 🤖 Generated with Claude Code |
|
Both points in, and restated on main: now 2b59125.
Runs: 26/26 and pytest passing on each of 15–19. Restated: TESTS.md §108, 🤖 Generated with Claude Code |
70877ec to
2b59125
Compare
…x, and the twin fails it by name rather than raising (commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
jdatcmd
left a comment
There was a problem hiding this comment.
Reproduced at 2b59125 on PG18. rls_direct_storage is 26/26. With export_parquet writing nothing (total = 0), it's 24 + 2: the source files the import arms need exist: got [no] want [yes] and and the owner can still export it: got [0] want [200], as you report. Both review points are in, and the twin now fails by name instead of raising. I didn't run the twin: no Python here has both pyarrow and psycopg. Approving. I'll merge once CI is green, after checking the approval is on this head.
🤖 Generated with Claude Code
…x, and the twin fails it by name rather than raising (commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
2b59125 to
a9c28a4
Compare
|
Rebased onto 57f6e0e (#1401), on top of #1403. The new head is a9c28a4. Only the count files changed, so this needs your re-approval.
🤖 Generated with Claude Code |
|
Re-run finished on the tree after #1403 (758039f or later). Everything is green, so the head above stands:
🤖 Generated with Claude Code |
a9c28a4 to
a86dcc4
Compare
…x, and the twin fails it by name rather than raising (commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
|
Rebased onto 7da848d (#1432, #1409). The new head is a86dcc4; only the count files changed, so please re-approve this head.
🤖 Generated with Claude Code |
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
8d2ca93 to
e053826
Compare
|
Rebased onto d5c0a5e (#1391). The new head is 9fbe82f, so please re-approve this head.
🤖 Generated with Claude Code |
e053826 to
9fbe82f
Compare
…x, and the twin fails it by name rather than raising (commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
|
Rebased onto 2d1a77f (#1413–#1424). The new head is 7f5cb95, so please re-approve this head.
🤖 Generated with Claude Code |
…x, and the twin fails it by name rather than raising (commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
9fbe82f to
7f5cb95
Compare
jdatcmd
left a comment
There was a problem hiding this comment.
Re-approved at 7f5cb95, the rebase onto 2d1a77f. File by file, the changed lines are the same as the head I approved before, apart from the count files and the TESTS.md section number.
🤖 Generated with Claude Code
…ws are reworded The mutation column is a ';'-separated set, written back sorted. A --mutation whose text held "; " was stored as two mutations, one a fragment starting with a space, and every later merge re-sorted it. commandprompt#1427's recovery_minimal_wal text did this to 8 rows, and commandprompt#1423, commandprompt#1424 and commandprompt#1426 each carried them as a change of their own. Four older harness_selftest rows were split the same way. - merge refuses a --mutation holding ';' (rc 2, ledger untouched). - the reader refuses a ';'-piece with whitespace at an end, by line: the writer joins with a bare ';', so such a piece is a fragment, never a mutation. - the 12 rows are reworded without ';', from their original text in history. Only field 6 changes; the census stays 3007 / 2282 / 725. Red first: the two refusal arms got 0 want 2 on the unchanged tool, and the committed-ledger arm was red at line 1783 with the refusal in and the rows not yet reworded. guard_tests 435 -> 438 by collection. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…rompt#1341 item 75) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…ment-mark mutation (commandprompt#1341 item 75) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…wn privileges, in both twins (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…d the refused tier writes no file, in both twins (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…ITY DEFINER (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
… back; both its branches echoed "ran" (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…ll's name (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…nd every owner arm reports a number when refused, in both twins (commandprompt#1341) A guard widened to refuse the owner stopped the fixture's own export, so a premise reddened for the product code and the pytest twin crashed in setup rather than failing an arm by name. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…e mutations of the RLS guard (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
… in both twins (commandprompt#1341, commandprompt#1397 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…uals (commandprompt#1341) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
…x, and the twin fails it by name rather than raising (commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
commandprompt#1383 review) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VjTxfQJj5pnii9wzmPP9Ho
|
Restated for the chain you asked for. The new head is 81a3140, so please re-approve this head.
🤖 Generated with Claude Code |
7f5cb95 to
81a3140
Compare
jdatcmd
left a comment
There was a problem hiding this comment.
Re-approved at 81a3140, its place in the chain on 17420be. This PR's own commits, measured from the link below it, change the same lines as the head I approved before, apart from the count files and the TESTS.md section number.
🤖 Generated with Claude Code
Part of #1341.
rls_direct_storage.sh(#563) gets its pytest twin, with every check under the shell's name. The suite is seeded into the ledger, and one shell arm that could never fail is fixed.The arm that could not fail
Both branches echo
ran, so a refused owner export passed. The arm now reads the export back and compares its row count with the table's live count, in both twins. Under a guard widened to refuse the owner, main's suite keeps this arm green while the branch reddens it (got [0] want [200]).Fixture made out of the guard's reach
The import sources were exported by the owner after RLS was enabled. So the widened-guard mutant broke the fixture, not an arm:
premise: the source files the import arms need existwent red in the shell, and the pytest twin crashed in setup. The sources are now made beforeENABLE ROW LEVEL SECURITY. When the owner's read is refused, it reports-1, so a failure is a named red arm rather than a crash.Evidence
Clean, both twins, five majors: shell 26/26 and pytest 1 passed on each of 15, 16, 17, 18 and 19.
Mutants (PG17), branch tree:
PgColumnarRequireNoRowSecuritynever refuses!= RLS_NONE(the owner and superuser too)read_projectionchecks RLS before its ACLOn main, the widened guard reddens the premise plus 2 arms, and the owner-export arm stays green.
Bookkeeping
suites_not_covered245 → 244. The gate is clean against origin/main.cluster_tests538 → 539. Collection on main and on this branch differs by exactly 1.guard_testsis 429/429.COMPLETE.🤖 Generated with Claude Code