You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The last-admin protection introduced around PR #27 performs an unlocked admin-count read outside the transaction that applies the moderation change. Under concurrent admin actions, two requests can observe the same pre-update state and both proceed based on a stale count.
This creates a TOCTOU race in the last-admin guard.
Context
This was called out by the maintainer during review of #27 as a non-blocking follow-up to track separately.
Problem
The current flow is effectively:
Read/count active admins.
Decide whether the target admin can be blocked/demoted.
Perform the state change separately.
Because the count read is not protected by the same transaction/locking boundary as the mutation, concurrent requests can both pass the guard before either write commits.
Expected behavior
The last-admin invariant should be enforced atomically so that concurrent moderation actions cannot both succeed when doing so would leave the system without an active admin.
Suggested direction
Move the relevant read/check and mutation into one transaction.
Use an appropriate locking or serialization strategy supported by the current database layer so the invariant is preserved under concurrent requests.
Add a regression test covering concurrent attempts to block/demote admins when only the minimum allowed admin set remains.
Acceptance criteria
Concurrent admin moderation requests cannot bypass the last-admin protection.
The validation and state change are atomic with respect to the last-admin invariant.
Regression coverage demonstrates the race is prevented.
Summary
The last-admin protection introduced around PR #27 performs an unlocked admin-count read outside the transaction that applies the moderation change. Under concurrent admin actions, two requests can observe the same pre-update state and both proceed based on a stale count.
This creates a TOCTOU race in the last-admin guard.
Context
This was called out by the maintainer during review of #27 as a non-blocking follow-up to track separately.
Problem
The current flow is effectively:
Because the count read is not protected by the same transaction/locking boundary as the mutation, concurrent requests can both pass the guard before either write commits.
Expected behavior
The last-admin invariant should be enforced atomically so that concurrent moderation actions cannot both succeed when doing so would leave the system without an active admin.
Suggested direction
Acceptance criteria
Related: #27