Decision, raised during T10.4 hazard review:
- Admin bootstrap: manage_users.py moves from creating an admin account to
promoting an existing one, by username, on a row Okta's JIT provisioning
(T10.3) already created. Rejected blind account creation — the exact
OKTA_IDENTITY_CLAIM format is still unconfirmed by security, and a
hand-typed username that doesn't match it produces an orphaned second
account instead of promoting the real one. Ongoing (non-bootstrap) admin
naming needs no new work: html/users.js's existing role dropdown already
handles it.
- Break glass: none, by design, matching the precedent already on record
for the abandoned LDAPS design (D13/D14) rather than assumed to carry
over untested. If Okta is unreachable, the app is unreachable for
everyone until Okta is restored. Rejected a toggleable emergency local
login — it would reintroduce the stored credential D15 exists to
eliminate.
Also corrects T10.4's scope in wave-10.md: hazard review found real call
sites of hash_password/verify_password/password_problem the original
bullet didn't name (create_user(), admin_reset_password(), users.js's
admin forms, browser_check.py/launcher_check.py fixtures), plus a
verification-gate ordering problem (smoketest.py and seed_demo.py
authenticate via POST /api/auth/login, which T10.4 removes, and both are
named explicitly in CLAUDE.md's verification section). Fixed by having
T10.4 switch both scripts to mint a session with auth.create_token()
directly, the same technique browser_check.py already uses, rather than
waiting on T10.7.
D16