- Every conversation row in the inbox rendered an empty preview: the
frontend read `last_body`, which the API has never sent. It sends
`excerpt` plus `truncated`.
- `GET /api/codex?limit=-1` passed a negative LIMIT to Postgres -> 500.
Now bounded by Query(ge=1, le=200) -> 422.
- Registering with a >255 char email hit the VARCHAR(255) column and
surfaced as a 500. PATCH /api/profile already validated this; only
/auth/register was open.
The social layer had zero tests, despite routes/messages.py citing
"tests/test_messages.py's cross-user leak tests" and routes/profile.py
claiming "privacy rules that the tests pin". Neither file existed. Both now
do: auth required on every route, email only on /api/profile/me, no id or
password_hash on any public payload, third-party thread reads empty,
payload-supplied sender inert, veiled profiles 404 and stay off the roster.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>