Problem: the signup handler counted users with a SELECT issued BEFORE the
transaction opened. Two parallel signups against an empty DB could both
observe count == 0 and both be promoted to admin — a violation of the
"exactly one first user" invariant. Not a confidentiality breach (both
rows passed the same signup checks), but real.
Fix: drop the JS-side count entirely. The is_admin column in the INSERT
is now populated via a subquery:
(SELECT CASE WHEN COUNT(*) = 0 THEN 1 ELSE 0 END FROM users)
SQLite's WAL serializes writers, so the second concurrent INSERT runs
after the first has committed. Its subquery sees count = 1 and returns
0; the new row is not admin. No transaction-mode tweak required.
Surfaced by /audit security (auth & session lens).