7d07fc01f1
Marty, 2026-09-16: leaders can write but 94% of positions cannot receive (47 of 771 have ever signed in to messaging, 482 messages sit 85% unread). profiles.js stores username + verified email per POSITION (one wallet holds one position, so a Triple Play holder has three; the person is the email and one email may hold several positions). Seeds the 40 emails already on file from member-alerts.json, pre-filled but unverified so confirming costs one tap. Writes are only ever accepted from a session that PROVED ownership: wallet personal_sign (messages.verifyChallenge) or the Telegram Mini App bridge. The public /my/<id> page is untouched and cannot write a profile, verified by test: all four endpoints 401 unauthenticated while /my/21 stays 200. Endpoints GET /api/public/profile, POST .../username, .../email-start, .../email-verify, plus GET /api/admin/profiles for coverage. Email codes: 6 digits, 15 min, 60s cooldown, 5/day, 6 tries. profile-gate.js is a two-step modal that cannot be dismissed, fired on dashboard boot (covers the Mini App landing) and right after a wallet sign-in. Chatbot canned answer + AI prompt updated. 28 unit tests pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>