Dialogue · Architecture · Super
← Design notes

Super — the tier above admin

A super is an admin who can take a person out of the admin console. A shielded account keeps using the app exactly as before, while for every plain admin it simply is not there — not the username, not the spending, not the chats, and not the arithmetic that would otherwise give it away. Status: built. Written 2026-08-14.

The model. The console does not show an admin a filtered list — it shows them a smaller world. Rows, counts, totals, rankings and room transcripts are all computed as though the shielded accounts had never existed. Hiding the rows while leaving the totals whole would announce the shield by arithmetic, which is the same as not hiding it.

1 · The ladder, and why super is a flag

Three tiers, but only two role values in the database:

TierStored asCan
superrole='admin' + super_user=1everything an admin can, plus hide/reveal any account and grant the tier
adminrole='admin'the whole console, minus whatever is shielded from them
testerrole='tester'no console
the decisionSuper is a flag on top of admin, never a third role string. The app checks role == "admin" in roughly 45 places. Adding a third value would have turned every one of those into a site where a super silently loses a power, and the failure would be quiet — a missing button, a 403 nobody expects. As a flag, a super is an admin by construction and the tier can only ever add. It also means the wire's role field keeps meaning "effective privilege", so no client gate had to change.

The one contradiction that flag-plus-role allows is guarded: an account cannot be demoted to tester while it still holds the tier, because super_user=1 with role='tester' would be a user that is_super() accepts and all 45 admin checks refuse. The tier comes off first, as a separate act.

2 · What "hidden" means

ONE DATABASE users · dan  · bob  · cara · amy  · ben rooms · r1  · r2 · r3 (amy is in it) spend $40 total super admin SUPER'S CONSOLE 5 users · 3 rooms amy and ben listed, marked 「hidden」 $40 total ADMIN'S CONSOLE 3 users · 2 rooms no amy, no ben, no r3 no gap, no placeholder $31 total  — it adds up THE RULE A room with even ONE shielded member is hidden WHOLE — its title, its transcript, its member count and its cost. Showing it would leak the member through any of those four. Blast radius: every room they are in.
One database, two views. The admin's view is internally consistent — which is the point: nothing subtracts to reveal what is missing.

3 · What the shield covers

SurfaceWhat a plain admin gets
Users tabthe row is absent; the headcount drops with it
Overviewtotals, online count, room counts and both top-spender boards exclude them
Usage & costby_user, by_room, by_model, by_day, by_function and all four total windows exclude them
Rooms tabevery room they are in is gone — not greyed, not owner-less, gone
Console peek404 — the same answer a room with no transcript gives
The peek button's real path
(/api/rooms/…/state·replay·members·stream)
403. This is the widest read in the app: for a non-member it carries no history floor, so the raw replay would hand over unfloored history. The shield lands here, not only on /api/admin/*.
Invitesthe name is out of used_by and the uses counter is reconciled, so no mismatch names the code they joined on
Seentheir pieces are dropped, not anonymised — a Seen carries the user's own verdict and free-text note
Role · caps · reset · sign-out · delete404, byte-identical to an unknown id. /logout needs no password, so without this an admin could walk ids and read existence off the status code.
Profile · avatar · DM · seatingthe rank's bypass is withdrawn; the ordinary social check still runs (see §4)

4 · What it deliberately does not cover

be honest about thisThe shield is a console feature. It is not invisibility, and three things will still betray a hidden account to a determined admin.

What it does guarantee is the thing that was asked for: through the admin console, a plain admin can never read a shielded user's username, their spending, or a word of their chats.

5 · Granting the tier

The first super is minted out of band, on purpose. Only a super can grant the tier, so a console door for the first one would be exactly the reach the tier exists to deny. It is made by someone with shell access to the box and the database file — the same trust level as owning the server:

cd /opt/mad/Multi-Agent-Dialog
sudo -u mad MAD_DB_PATH=/var/lib/mad/app.db \
    .venv/bin/python lib/make_super.py enovy

No restart is needed — the flag is read per request. After that, a super works the tier from Users → ⋮: Hide from admins / Show to admins, and Make super / Revoke super. Both re-confirm the super's own password, the way promoting to admin already does.

Two guards worth knowing: the last super cannot revoke itself (that would leave shielded accounts hidden with nobody able to reveal them — make_super.py can always re-grant with shell access, so the guard makes the step deliberate rather than the state unrecoverable), and a super is always shielded, whatever the column says. A tier a plain admin can see is a tier they know to go looking for.

6 · The seams

SeamWhere
is_super(user) — the one tier predicatelib/auth.py
shielded_user_ids() — the only definition of «hidden» (folds in every super)lib/db.py
rooms_touching(uids) — the room halflib/db.py
_ev_clauses() — the one exclusion predicate for turn_events, by user OR roomlib/db.py
_hidden_for(user) — built once per admin requestlib/run_room.py
_admin_target(uid, me) — hidden reads as absent, for the five mutation routeslib/run_room.py
_admin_reach(user, uid) — replaces a bare role == "admin" in the social bypasseslib/run_room.py
33 checks, incl. the arithmetic and the probe oracleslib/smoketest.py § super tier / the shield
the disciplineNever re-derive «is this user hidden» from the two columns at a call site. Ask shielded_user_ids(). A second copy of the predicate is how one surface starts disagreeing with another — and here a disagreement is a leak.
Super tier · 2026-08-14 · a flag on top of admin, a read-path shield, and one exclusion predicate. Related: deployment topology · persona visibility (the other visibility model in this app).