Skip to content

v0.5.7

@Pasenchuk Pasenchuk tagged this 16 Jul 00:38
The emit schemas existed without any emit() in the code (2026-07-16
'silent contract lie' audit). Session lifecycle events now go through the
transactional outbox atomically with the UserSession write, mirroring
staff_roles:

- SessionService.create emits user.session_created (login/refresh/SSO/QR)
- SessionService.revoke_by_jti (logout), new SessionService.revoke_session
  (per-device revoke endpoint) and SessionService.revoke_all (password
  change, revoke-all) emit user.session_revoked; idempotent re-revokes
  stay silent
- suspicious-login 'this wasn't me' endpoint now revokes via
  SessionService.revoke_all (its raw .update() skipped blacklisting and
  would have skipped the event)
- events.py: payload dataclasses + registry entries

Tests validate outbox payloads against the published JSON schemas; the
three registration-emit tests updated for the second (session) event now
present in the flow.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Assets 2
Loading