---
id: STATE-PFM-SEC-004
title: Membership status
object: DOM-PFM-SEC-003
product_area: platform
module: security
revision: 1
status: draft
design_intent: proposed
implementation_evidence: observed
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
states:
- name: invited
  meaning: The membership exists but cannot authorize ordinary work; assignments may be pending.
  provenance: observed
  source: services-platform:modules/security/services/persistence/users.ts:reinviteRevokedUser
- name: active
  meaning: Fresh evaluation can use the membership’s current active assignments.
  provenance: observed
  source: services-platform:modules/security/services/invitations/accept-invitation.ts
- name: suspended
  meaning: Fresh evaluation refuses this paused membership. Provider disabling is a separate best-effort action.
  provenance: observed
  source: services-platform:modules/security/services/invitations/suspend-user.ts
- name: revoked
  meaning: Access ended and invitations and assignments were revoked. Returning requires a new invitation on
    the retained row.
  provenance: observed
  source: services-platform:modules/security/services/invitations/revoke-user.ts
transitions:
- from: invited
  to: active
  trigger: The invited person accepts by password or Google.
  guard: The token is usable and the inviter still covers the pending grants, unless the founding-administrator
    exemption applies.
  side_effects:
  - Activate pending assignments atomically
  - Prepare the sign-in credential before the activation transaction
  - Record lifecycle and security events with the accepting actor
  who: The invited person
  provenance: observed
  source: services-platform:modules/security/services/invitations/accept-invitation.ts
- from: invited
  to: active
  trigger: An administrator directly activates a linked membership never sent an invitation.
  guard: The invited membership has an active linked identity, no sent invitation and the caller has access-management
    authority.
  side_effects:
  - Record activation without marking an invitation accepted
  who: Customer Administrator or Rhythm staff
  provenance: observed
  source: services-platform:modules/security/services/invitations/activate-user.ts
- from: invited
  to: revoked
  trigger: An administrator withdraws an invitation.
  guard: The target is reachable, is not the caller and the caller has access-management authority.
  side_effects:
  - Revoke outstanding invitations and all assignments
  - Queue provider disable atomically, then nudge dispatch and submit a flush
  who: Customer Administrator or Rhythm staff
  provenance: observed
  source: services-platform:modules/security/services/invitations/revoke-user.ts
- from: active
  to: suspended
  trigger: An administrator suspends an active membership.
  guard: The target is reachable, is not the caller and last-administrator guards pass.
  side_effects:
  - Revoke outstanding invitations atomically
  - After commit, attempt provider disabling and flush submission; report provider trouble separately
  who: Customer Administrator or Rhythm staff
  provenance: observed
  source: services-platform:modules/security/services/invitations/suspend-user.ts
- from: suspended
  to: active
  trigger: An administrator reinstates a suspended membership.
  guard: The caller may widen access for every retained assignment.
  side_effects:
  - Attempt provider enabling after commit
  - Keep withdrawn invitations withdrawn
  who: Customer Administrator or Rhythm staff
  provenance: observed
  source: services-platform:modules/security/services/invitations/suspend-user.ts
- from: active
  to: revoked
  trigger: An administrator revokes an active membership.
  guard: Self-revocation is refused and last-administrator checks pass.
  side_effects:
  - Revoke invitations and assignments, queue disabling, then nudge dispatch and submit a flush
  who: Customer Administrator or Rhythm staff
  provenance: observed
  source: services-platform:modules/security/services/invitations/revoke-user.ts
- from: suspended
  to: revoked
  trigger: An administrator revokes a suspended membership.
  guard: The target cannot be the caller’s membership.
  side_effects:
  - Revoke invitations and assignments and persist provider-disable work
  who: Customer Administrator or Rhythm staff
  provenance: observed
  source: services-platform:modules/security/services/invitations/revoke-user.ts
- from: revoked
  to: invited
  trigger: An administrator invites a revoked address within the same membership boundary.
  guard: Delegation checks permit the newly offered assignments.
  side_effects:
  - Reuse membership identity and history while creating a new invitation and pending grants
  who: Customer Administrator, Rhythm staff, or the provisioning first-administrator seed
  provenance: observed
  source: services-platform:modules/security/services/persistence/users.ts:reinviteRevokedUser
invalid:
- from: suspended
  to: invited
  why: A suspended membership returns through reinstatement, not invitation resend.
  provenance: observed
  source: 'services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts,
    activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts;
    services/membership/lockout.ts, last-administrator.ts.'
- from: revoked
  to: active
  why: A revoked membership requires invitation and acceptance before becoming active again.
  provenance: observed
  source: 'services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts,
    activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts;
    services/membership/lockout.ts, last-administrator.ts.'
- from: active
  to: invited
  why: An active membership uses password recovery rather than another invitation.
  provenance: observed
  source: 'services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts,
    activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts;
    services/membership/lockout.ts, last-administrator.ts.'
concurrency: Membership capabilities transact their related database changes. Destructive changes apply the
  relevant customer and staff lockout guards. Repeated revocation retains the original revocation time; acceptance
  consumes the token conditionally. Deletion removes the membership rather than introducing another status,
  retaining a former-user record and queuing provider deletion. Queue dispatch runs every minute, but retries,
  backlog and dead-letter handling preclude a completion deadline.
invariants:
- INV-DOM-PFM-SEC-003-02
- INV-DOM-PFM-SEC-003-11
- INV-DOM-PFM-SEC-003-12
- INV-DOM-PFM-SEC-003-21
evidence:
- 'services-platform at ad3f6a65: modules/security/db/users.table.ts; services/invitations/accept-invitation.ts,
  activate-user.ts, invite-user.ts, revoke-user.ts, suspend-user.ts, resend-invitation.ts, user-deletion.ts;
  services/membership/lockout.ts, last-administrator.ts.'
examined_at: '2026-10-23'
examiner: codex
---

# Membership status

## The Lifecycle

```mermaid
stateDiagram-v2
    state "Invited" as invited
    state "Active" as active
    state "Suspended" as suspended
    state "Revoked" as revoked
    invited --> active
    invited --> active
    invited --> revoked
    active --> suspended
    suspended --> active
    active --> revoked
    suspended --> revoked
    revoked --> invited
```

The diagram summarizes the observed transition rows; declared edges without an observed writer remain outside the operational graph.

## Transitions Explained

Membership status controls fresh authorization; provider state and cached decisions can lag. The structured transitions distinguish suspension’s single provider attempt from the durable removal work used for revocation and deletion.

A provider failure does not roll back the committed membership change. The removal queue retries individual messages and can exhaust into its dead-letter queue. Reinstatement does not restore withdrawn invitations.

## What Cannot Happen

A suspended membership returns through reinstatement, not invitation resend.

A revoked membership requires invitation and acceptance before becoming active again.

An active membership uses password recovery rather than another invitation.

## Concurrency and Timing

Membership capabilities transact their related database changes. Destructive changes apply the relevant customer and staff lockout guards. Repeated revocation retains the original revocation time; acceptance consumes the token conditionally. Deletion removes the membership rather than introducing another status, retaining a former-user record and queuing provider deletion. Queue dispatch runs every minute, but retries, backlog and dead-letter handling preclude a completion deadline.
