Changes touching this path

  • RLS arrives on the trigger #702 named rather than on a schedule, because #1725 made it fire the same night: forge_member_writer holds SELECT, INSERT and DELETE on repo_member and SELECT on account_key and repo, which are base tables and not views, and its owner-scoping lived entirely in three SQL statements the site writes. It also held a bare unpredicated SELECT on repo, so it could enumerate every namespace on the forge including the metadata-private ones. Migration 0014 enables RLS on eight tables - the schema header's own repo-scoped group plus proposal, which 0011 added to that group after this ticket was written - and the verdict on the forge role is that it is UNCONSTRAINED, said out loud rather than decorated: all eight of its policies are USING (true) WITH CHECK (true), named forge_ingest_is_unconstrained so the catalogue itself prints the admission, because it writes every tenant from one process with no request-scoped identity and a predicate would be either inert or an outage. What ENABLE does buy is exactly this ticket's condition 2, the accident it was deferred against: a role no policy names now reads zero rows, so an ALTER DEFAULT PRIVILEGES that hands a reader every future table is answered by the tables themselves. The per-transaction ingest binding that would make the forge role genuinely constrainable is filed as #1732. FORCE ROW LEVEL SECURITY was proved rather than assumed, and is deliberately NOT set: on a real cluster a postgres-owned table with RLS enabled AND forced and zero policies still reads 2 of 2 as postgres, where a NOBYPASSRLS role reads 1 of 2 at the same moment, and a non-superuser-owned table reads 2 without FORCE and 0 with it - so the mechanism works, it is inert against a superuser owner, and setting it would be precisely the decorative control this ticket forbids. The red proofs are the output that matters and one of them corrected the method: a policy must be proved by REPLACING its predicate with true, never by dropping the policy, because enabled-with-no-policy is deny-all and returns zero, which proves nothing about the predicate - the first draft did exactly that and it is recorded so the next reader does not repeat it. With the predicate widened instead, the cross-owner INSERT lands and owner B's roster gains a collaborator its owner never named. One thing only a real run could find: membership.pg.test.ts's foreign-key case went red because the policy now stands in FRONT of the constraint, so an unscoped statement never reaches the foreign key the test is about, and left alone it would have quietly become an RLS test named for the wrong mechanism - so it is fixed and the RLS half split into its own case. The site half ships in the same change because it must: membership/db.ts gains withOwner, owner/db.ts's shape minus READ ONLY, and without it 0014 empties the membership surface (#702) c562196e · dbf3dbe6…

Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.