- Imported tracks are created directly under their final name with
O_EXCL (never overwriting; " (2)" on conflict), fsync'ed and checked
against SHA-256 — no hidden .pipu-tmp file next to them any more.
- On any failure the agent removes its own partial file and the empty
directories it created for it.
- The write check uses access(W_OK) and the read-only mount flag instead
of creating and deleting .pipu-write-test in the storage root.
- Tests assert the storage tree holds only audio files after successful
and failed writes and after the write check.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- users, refresh_tokens and audit_log schema (migration 00002)
- argon2id passwords with rehash on login, password policy, lockout
with exponential back-off and a per-IP rate limit in Redis
- Ed25519 JWT access tokens with kid-based key rotation; rotating
refresh tokens with reuse detection (cookie for web, body for Android)
- bootstrap admin on first start; must_change_credentials and
must_change_password gate every other endpoint
- /auth/login, /auth/refresh, /auth/logout(-all), /me, /me/password,
/me/bootstrap-credentials, /me/sessions; server-info reports
bootstrap_required
- role policy from docs/auth-and-roles.md with table tests
- problem+json errors with field errors; ru/en translations of the codes
- install.sh and update.sh generate JWT_PRIVATE_KEY
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>