auth.provider API
    Preparing search index...
    • Executes the four-step logout cascade in the fixed order mandated by A4 §6.2: Step 1: Read fanout context — sessionFamilyIndex.listFamilyIds(sid). Fail → return failed step:1 (steps 2–4 skipped; retry safe). Step 2: Fanout — collect-and-tally. - revokeFamily loop (per family; continues on per-op failure, tallies errors) - federationTokenStore.removeBySid (tallied on failure) If ANY failure → return failed step:2 with all errors (HALT before step 3). §6.2 critical rule: HALT preserves bookkeeping for retry. Running step 3 would erase reverse-index entries and silently mark the cascade complete despite an un-revoked family. Step 3: Reverse-index cleanup — only if step 2 fully succeeded. Per-op best-effort (log + continue; orphan entries bounded by TTL). - sessionRPRegistry.removeBySid - sessionFamilyIndex.removeBySid - sessionFederationIndex.removeBySid Never returns failed (step 3 best-effort; hence step range is 1|2|4 not 1|2|3|4). Step 4: Primary invalidation — userSessionStore.delete LAST (must succeed). Fail → return failed step:4.

      Note: broadcastBackchannelLogout is invoked by routes/logout.mts BEFORE cascadeLogout (it is "best-effort — never throws" per its own contract), so its position is functionally equivalent to being a no-throw step-2 op inside the cascade per §6.2 model. Moving it here would require pulling in sub/issuer/keyStore/fetchImpl/auditSink as new deps — a surface change beyond this helper's scope.

      Caller responsibilities:

      • Map outcome: "failed" to HTTP 503.
      • Invoke broadcastBackchannelLogout (best-effort) BEFORE calling this function.
      • Run Front-Channel / IdP-logout phases separately — this helper only handles the store cascade.

      Parameters

      Returns Promise<CascadeLogoutResult>