Follow-up to the previous two commits, all four issues were introduced by them:
- The legacy `access_all`-group authority was accepted by
`caller_may_grant_collection_manage`, so a Custom member with manageGroups +
editAnyCollection could create an access_all group holding itself, use the
derived authority to persist `collections_groups.manage`, then leave the group
and keep collection deletion without ever holding deleteAnyCollection. The
clamp now takes only a real stored grant again, and the legacy exception is
limited to members holding none of the three collection permissions -- which
is the shape the migration leaves a group-derived Manager in, and never a
member who can create such a group in the first place.
- `Collection::to_json_details` reported `manage: false` for a member reaching
every collection even when a real grant existed, so the client rendered
controls that disagree with the guards. Both the cached and the uncached path
now read the effective grant.
- The SQLite rollback script continued after a failed statement, so a second run
dropped `users_organizations` and committed an empty replacement. It now sets
`.bail on`, refuses up front unless the permission columns are present, and
the README documents `-bail` instead of claiming the run is atomic regardless.
- The downgrade acknowledgement was never consumed, so one approval authorized
every later revert. It is now dropped by the revert it permits and cleared
again on re-upgrade.