OidcDeskCredential authenticates a bearer through the validation scheme only
(never the default scheme; the cookie authenticates nothing on /api/desk and a
bearer authenticates no cookie page) and returns sub, audience and scopes. The
desk keeps judging audience, scope and per-request Active membership.
The issuer registers desk.read/desk.answer and stamps audience bifrost-desk on
tokens that carry one; client permissions are what limit scopes, so the MAS
client can neither ask for them nor use its chat token on the desk. A Desk
section without Bifrost:Oidc now fails startup in StartupConfigurationValidator.
Packages: OpenIddict.Validation.AspNetCore and .ServerIntegration 7.7.1.
No production Ratatoskr client is seeded.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
DeskNotes becomes DeskRedaction: one function over entry and list that nils
every note and replaces every answerer with the fixed sentinel "masked" for a
caller who is not a decider of the Mind (X3). A decider keeps both. The
sentinel is not derived from the account id and is not a UUID.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The per-room tail was chained with .then(run), so a rejected run skipped every later report for that room and left the cleanup as an unhandled rejection. Chain on both outcomes and clean up on both. A test reaches it with a presence failure plus a throwing logger and fails on the old chain.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
CultLib 286a9af scoped the two packages under @gamecult. The directories under packages/ keep
their short names; only the bare specifiers change.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
An ack posted her m.read, so the receipt tracked the queue, not the model. The mouth now posts m.read only
at the event id Huginn reports in gamecult.persona.chat_read.v1, for an event it delivered to her in that
room, forward only, brake read fresh. The ack posts nothing. Presence is online within presenceGraceMs of
a read report, a send or an ack, unavailable after, offline under the brake; a change is PUT at once.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The identity becomes the Matrix localpart at SSO, so a new account must not mint a name that
a Matrix account already holds (the 13 Synapse localparts) or a system name. Native register
refuses a reserved name; a derived identity takes the next free suffix. Lookups of existing
accounts and existing rows are untouched; there is no exemption path.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Fails at this commit with DbUpdateConcurrencyException from CloseMotionAsync:
Motion.Status became a concurrency token in BifrostDbContext.cs:288.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A __Host- cookie is only removed by a Set-Cookie that is itself Secure. The
hardening test now checks Secure on every header, deletion included, and the
completion tests pin that success and refusal both clear the attempt cookie
with Secure, Path=/ and no Domain.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A signed-in retract on a full account table must say busy with no sign-in offer (the
retract door passes its voter to Throttled), and a spent cast budget must say only
"too fast", for anonymous and signed-in voters alike. Both mutants survived Soul s4.
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
- answerInvites takes a fresh brake read after the long-poll
- readUpTo reads the brake when each receipt would post; held brake drops it, one log line
- the brake read and offline presence PUT precede the full-backlog early return
- a throwing logger cannot reject the unawaited receipt call
- tests: fake keeps the raw path and honours abort signals; the braked-round carve-out is offline presence PUTs only
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>