You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Deleting the hand-written has_permission read filters converts enforcement from partial failure to total failure. Today a forgotten filter leaks one route, which is why #822 stayed contained to collections. Once they are gone, a policy dropped by a bad migration, a staging refresh from a dump that reassigned ownership, or FORCE lost is a full read leak with no second line, and rollback stops being "drop the policies" and becomes "revert several PRs".
Scope
Keep every filter site in #811, #812, and #813 active, and record when it disagrees with RLS:
filter dropped a row that RLS returned → policy gap. Must always be zero.
That single counter is the alarm.
The converse is not measurable: if RLS drops a row, the Python loop never iterates it, so "the filter would also have dropped this" cannot be counted. Confirmation that RLS is doing the work comes from the canary in #810.
This issue owns three things:
The counter — emission, naming, and where it surfaces. It has to be visible where the team already looks, not only in logs.
The soak decision. Staging is required; it doubles as an active test of policy coverage during the pilot (Pilot: enable RLS on score_calibrations in staging #825). Production for a release cycle is the recommendation, because that window is precisely when you want dropping a policy to be a complete rollback, which is only true while these filters remain. Decide it here.
The exit criterion, applied once across all three deletion issues.
Why the gate exists
Deleting the hand-written
has_permissionread filters converts enforcement from partial failure to total failure. Today a forgotten filter leaks one route, which is why #822 stayed contained to collections. Once they are gone, a policy dropped by a bad migration, a staging refresh from a dump that reassigned ownership, orFORCElost is a full read leak with no second line, and rollback stops being "drop the policies" and becomes "revert several PRs".Scope
Keep every filter site in #811, #812, and #813 active, and record when it disagrees with RLS:
That single counter is the alarm.
The converse is not measurable: if RLS drops a row, the Python loop never iterates it, so "the filter would also have dropped this" cannot be counted. Confirmation that RLS is doing the work comes from the canary in #810.
This issue owns three things:
Acceptance criteria