"""core/platform_admin.py — THE PLATFORM-OPERATOR PREDICATE (wave 19, owner item 13 / ruling R3). There are now TWO kinds of administrator in this product and they must never be confused: * a **tenant admin** (`role: 'admin'`) runs ONE company's workspace — its accounts, its keychains, its databases. Nurilab's admin is one; Royal's is one. `core.perms.is_admin` is that wall and it is scoped to the caller's own tenant everywhere it is used. * a **platform admin** operates LOOPABLE ITSELF — the cross-tenant view of who our customers are, what they are running, and what it costs. That is a different question and it needs a different key, because every tenant already has an admin and none of them may see the others. ⛔ THE DOUBLE LOCK, and why it is two conditions and not one (R3, verbatim: "NEW fail-closed `platform_admin` server predicate (tenant-scoped `is_admin` does NOT qualify)"): record flag `platform_admin is True` AND `tenant == 'loopable'` Either half alone is a promotion path we do not want to exist. The flag alone would mean a tenant admin who can write user records (Y4's `POST /admin/users` is reachable by every tenant admin) could mint themselves a cross-tenant reader inside their OWN company. The tenant alone would mean every future account in the `loopable` workspace — a designer, a contractor — reads every customer's operational data by virtue of their email domain. Requiring both means the promotion needs a write to a record AND membership of a tenant that no customer's admin can create accounts in. FAIL-CLOSED IN THE STRICT SENSE: `is True`, not truthiness. A record carrying the string "false", a 0, a "yes", or a partially-read dict is NOT a platform admin. The flag is absent on every pre-wave record, which is the correct answer for all of them. ⚠ THE FLAG MUST RIDE `users._public()` OR THIS PREDICATE IS BLIND. `deps._user_for` builds every API session from that projection, so a field that lives only on the stored record is invisible to every route that asks this question — the same rule `core.users` states for `perms`/`perms_v` ("the wall travels on this projection or it does not travel"), recurring on a new field. Both sides land in the same change, and `verify_api.py`'s W19-ADMIN section drives the predicate through a real SESSION rather than through a hand-built dict, so a dropped projection is red. This module deliberately holds NO routes, NO store reads and NO imports of the permission layer: it is one question, answerable from the session's own user dict, callable from either host. """ #: The ONE tenant slug a platform administrator may belong to. A constant rather than an env var #: on purpose — "which company operates this platform" is not a per-deployment setting, and an #: env-var reader here would be one misconfigured container away from admitting another slug. PLATFORM_TENANT = 'loopable' def is_platform_admin(user): """True iff `user` is a Loopable platform operator. Fail-closed on anything else. `user` is the PUBLIC session projection (`core.users._public`) or a raw record — both carry the same two keys, so the predicate answers identically wherever it is asked. None, {}, a non-dict, a missing flag or a mismatched tenant are all False, and none of them are an error: "not a platform admin" is the answer for almost every session the product will ever serve. """ if not isinstance(user, dict): return False if user.get('platform_admin') is not True: return False return str(user.get('tenant') or 'royal-imports').strip().lower() == PLATFORM_TENANT