Refuse an emailless identity where the session is minted, and rows the upstream should not have sent
CI / full-gate (push) Successful in 2m53s

This commit is contained in:
2026-09-02 18:24:56 +02:00
parent 390ac5f112
commit 18dc4f3136
14 changed files with 59 additions and 33 deletions
+4 -3
View File
@@ -186,9 +186,10 @@ Revisit only if the stated reason stops holding.
node names exactly one of `public`, `session`, `permission` — discovery refuses none, two, and a
flag spelled anything but `true`, so a forgotten gate fails the boot rather than publishing a page.
`src/auth/gate.ts` is the one home of the rule the plugin router, the host's own route table and
the menu all read. Exactly-one-gate is a discovery-time rule on manifests, not a runtime invariant:
`allows({}, user)` stays open **by design**, because the central override's `groups` builds header
nodes that carry no gate. Making `allows` fail closed would hide every operator-grouped section. `session` exists because a plugin whose data is
the menu all read. Exactly-one-gate is a discovery-time rule on manifests, not a runtime
invariant: `allows({}, user)` stays open **by design**, because the central override's `groups`
builds header nodes that carry no gate. Making `allows` fail closed would hide every
operator-grouped section. `session` exists because a plugin whose data is
the visitor's own — their upstream account, their own tokens — has no distinction a permission could
name; the alternative, granting every newly registered user a permission, couples the identity
lifecycle to a Keto write that nothing retries when it fails. A page scoped to "mine" joins on