- POST /api/fenjaops/invites on server.js (requireAuth+requireAdmin).
Ignores any is_admin field in the body — always stores 0. Records
the acting admin's email in invited_by so the audit trail shows
who added whom (CLI adds still record "cli").
- admin/index.html: new "Invite a new user" form panel at the top
(email + optional first name).
- admin/admin.js: wires the form submit to the POST, shows inline
success/error, refreshes the tables on success.
- admin/admin.css: form styling matching the existing paper/ink
palette; mobile stacks.
- Docs: CLAUDE.md, PROJECT.md, OPERATIONS.md, CHECKLIST.md, README.md
all updated. New non-negotiable property in PROJECT.md: no web
endpoint can set is_admin=1 or delete an invite — promotion +
removal stay on bin/invite.js. New CHECKLIST.md section H2 covers
the page's gating, the invite form, and an escalation-path audit.
Admin promotion and invite deletion remain CLI-only so a compromised
admin session cannot escalate or evict.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>