Current state now reflects 1.2.0:3 (P3 hardening) built + sideloaded
(git f540a47, 221 tests). Add durable conventions for the three patterns
established this session: cross-user exerciseId ownership
(lib/exerciseOwnership), login timing-oracle avoidance
(verifyPasswordOrDummy), and the iOS-Safari auth-form retry
(lib/retryAction). ROADMAP: move the shipped P3 items (timing oracle,
exerciseId ownership) and the Next 15 bump into the Done lines.
P2 batch from the 2026-06-13 full-eval (EVALUATION.md / ROADMAP.md), reviewed by the reviewer agent. App-code + packaging only; no schema or data change, existing /data untouched.
Input validation: malformed JSON bodies, invalid date, and out-of-range or non-numeric pagination on /api/workouts now return 400 instead of 500. New lib/http.ts readJsonBody maps a bad body to a ZodError across the 11 CRUD routes whose catch maps ZodError to 400; me/import and admin/signups guard request.json() in an explicit try/catch.
Rate limiting: POST /api/auth now shares the UI login server action's per-IP 10-per-15min cap and returns 429 + Retry-After. clientIpFromHeaders reads the rightmost (trusted-proxy-appended) X-Forwarded-For entry instead of the spoofable leftmost.
Container: drops root. The entrypoint prepares /data as root, chowns it to nextjs, then exec su-exec nextjs:nodejs node server.js (su-exec added to the runner image). The container drop needs live sideload verification.
Multi-user authorization hardening from a full security evaluation (EVALUATION.md):
- P0: /api/settings/{export,import}-db are now admin-only. Previously any signed-in user could download the whole instance DB (all bcrypt hashes + plaintext AI keys) or replace it wholesale. Per-user CSV export/import stays open.
- AI custom-URL providers (Ollama, OpenAI-compatible) are now admin-only, and every server fetch to a user-supplied URL passes through assertSafeProviderUrl (blocks link-local/cloud-metadata; private LAN allowed by design). Fixed-URL cloud providers stay per-user. Removed the dead legacy /api/ai/config route.
- Dev: fixed broken quick-start (added npm run create-admin; rewrote README; dropped dead CLAUDE_API_KEY) and the export-db 0-byte path resolution (resolveDatabasePath now matches Prisma).
ExVer bumped to 1.1.0:8 (no schema/data migration). Tests 197 pass, build green, tsc clean.
Onboarding doc for fresh agent sessions: stack, commands, layout,
conventions, and an Always/Never list of gotchas hit during the AI
overhaul. Current state section tracks the 1.1.0:7 checkpoint.
ROADMAP.md holds the longer-term backlog. CLAUDE.md symlinks AGENTS.md
so Claude Code loads it. Secrets kept out — private registry/file-host
URLs and creds referenced by file location, not value.