Two places on the admin surface ask a reviewer to make a judgement about an account, and neither can show them who the account is. Both landed in #122.
Assigning an owner. docs/spec/profile-and-credentials.md:75 is deliberate that the override is "a human check rather than a mechanism" — an admin decides, and no automated email match is wanted. But the check itself is "does the claimer's verified account email equal practitioner_contacts.contact_email", and the panel can only show one side of it: the contact address is rendered, and the input takes an account uuid. The admin is being asked to compare an address against an opaque identifier, so in practice the comparison happens in the Supabase dashboard in another tab, or it does not happen. The consequence of getting it wrong is real — the profile is handed over, every credential's verified is cleared, and A → B is refused by the guard, so the repair is unassign-then-reassign.
Naming who performed a check. practitioner_credentials.verified_by is an account id. The queue currently renders your own check as Checked by <you>, anybody else's as another Bluehex admin, and a null one as with no admin recorded — which is reachable today, since every seeded verified row has it null. "Another Bluehex admin" is the honest thing to say when the id cannot be resolved, and it is a poor substitute for a name on the surface whose whole subject is who vouched for what.
Why it is a migration rather than a query
auth is not an exposed schema, so PostgREST cannot reach auth.users at all, and public.admins carries no grant to bluehex_admin. There is nothing to select.
The likely shape is one narrow security definer function returning an email for an account id, executable by bluehex_admin alone — the same idiom as my_profile() in 20260822050002_profile_own_reads.sql, and subject to the same rule that the predicate is the whole control. Both callers above are served by it. Worth deciding at the same time whether it takes one id or a set, since the queue would call it once per verified credential otherwise.
Not to be built
An automated email match on assignment. The spec refuses it on purpose — that override is exactly where social engineering comes back, and a mechanism there would launder a human decision into an automatic one.
Two places on the admin surface ask a reviewer to make a judgement about an account, and neither can show them who the account is. Both landed in #122.
Assigning an owner.
docs/spec/profile-and-credentials.md:75is deliberate that the override is "a human check rather than a mechanism" — an admin decides, and no automated email match is wanted. But the check itself is "does the claimer's verified account email equalpractitioner_contacts.contact_email", and the panel can only show one side of it: the contact address is rendered, and the input takes an account uuid. The admin is being asked to compare an address against an opaque identifier, so in practice the comparison happens in the Supabase dashboard in another tab, or it does not happen. The consequence of getting it wrong is real — the profile is handed over, every credential'sverifiedis cleared, andA → Bis refused by the guard, so the repair is unassign-then-reassign.Naming who performed a check.
practitioner_credentials.verified_byis an account id. The queue currently renders your own check as Checked by <you>, anybody else's as another Bluehex admin, and a null one as with no admin recorded — which is reachable today, since every seeded verified row has it null. "Another Bluehex admin" is the honest thing to say when the id cannot be resolved, and it is a poor substitute for a name on the surface whose whole subject is who vouched for what.Why it is a migration rather than a query
authis not an exposed schema, so PostgREST cannot reachauth.usersat all, andpublic.adminscarries no grant tobluehex_admin. There is nothing to select.The likely shape is one narrow
security definerfunction returning an email for an account id, executable bybluehex_adminalone — the same idiom asmy_profile()in20260822050002_profile_own_reads.sql, and subject to the same rule that the predicate is the whole control. Both callers above are served by it. Worth deciding at the same time whether it takes one id or a set, since the queue would call it once per verified credential otherwise.Not to be built
An automated email match on assignment. The spec refuses it on purpose — that override is exactly where social engineering comes back, and a mechanism there would launder a human decision into an automatic one.