Changes touching this path

  • the sync surface learns membership, which is ADR 0077's other half: AccessClass::of stops being a byte compare and becomes owner-or-member, with the owner compare staying FIRST because a repo can have an owner with no account at all - repo carries no tenant_id and a push creates no tenant - and the membership arm resolving through a LIVE account_key row, since a rotation retires a key precisely so a leaked one stops working and reading a collaborator's sealed metadata is what a leaked key would be used for. The read is a new trait method with no writing sibling, and liveness stays in the CALLER so the two stores cannot disagree about #927's rule. Two breaks prove it and the interesting one is the small break: resolving membership before the owner compare moves exactly ONE cell of twenty-one, which is the point rather than a weakness, because a matrix without an accountless owner in it would not have moved at all. The dangerous shape is the other one - resolving from account_key alone with no repo_member join, which makes every account a member of every repo - and it turns eight of twenty-one green including two whole columns; the same break is red in SQL against a live cluster, and the unjoined query is run BESIDE the shipped one inside the test and asserted to admit the repo it should not. The write rules are pinned by #1650's method rather than described: the whole matrix of five signers across both door positions, run with membership rows planted for every account and again with none, demanding identical rendered answers including the message text, with a control that those same rows really do move the read class - and folding membership into require_pusher flips the contributor cell from a 403 that names another account to ok, which IS a stranger moving the owner's ref. The may_ship_key pin found something that strengthens ADR 0077's sixth decision: widening the class ships no key that was not already world-readable, and a member gets the Internal object's BYTES with the key set asserted as exactly the published oid rather than as an absence - but making may_ship_key answer true left the case GREEN, because verify_publication independently refuses a non-world object, so the lane is closed THREE times and not twice and the pin cannot be broken by widening Member in any spelling. A gap the ticket and the ADR both missed is pinned rather than fixed: a rotated owner's OTHER live key reads Anon on their own repo while require_pusher admits it, which this change did not cause since a byte compare answered the same way, but the new matrix makes it visible - the remedy needs no new predicate, only a repo_member row for the owner's own account. The claim that there is exactly one read method here was a live count in nine places and staled the moment a second arrived, so all nine become names and no number is written anywhere (#1728) 1fc1f6a2 · 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.