Both wave-4 workers hit the 5h session limit ~11 minutes in and were then lost
to a sprite suspend. This commit preserves the work that landed before that,
independently verified green (assembleDebug + testDebugUnitTest, 94 tests).
F1-livesync:
- LiveSyncTest + server/live-sync-test.sh: end-to-end exercise against a real
PocketBase (auth, push with client ids, pull, tombstones, cover round-trip).
Gated behind LIVE_SYNC=1 so the normal test task stays green with no server.
- Fix: BookDto.authors must be nullable. PocketBase serializes an unset `json`
field as literal null (unlike text/number, which come back ""/0), so decoding
any real response with empty authors threw. Found by the live test; no fake
had ever reproduced it.
- Fix: cover upload derived its media type from the filename instead of
hardcoding image/jpeg.
F2-release:
- ScreenFixtures + LibraryScreenPaparazziTest: library populated and empty,
light and dark (4 PNGs).
Still owed by wave 4: screenshots for the other five screens, release keystore
+ signed APK, top-level README.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016mTs3kQXQsQwonXpEq7aEw
Guard now polls every 30s but renews every 15 min. Coupling them meant a wave that
finished just after a renewal sat undetected for a full interval with the sprite
pinned hot.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Nav graph, setup with distinct URL-vs-credential errors, locations tree with reorder
and bulk move, settings; library grid with search/sort/filter, detail with soft-delete
undo, continuous scan with duplicate-ISBN warning.
Verified by orchestrator: assembleDebug exit 0; testDebugUnitTest exit 0,
91 tests, 0 failures, 0 errors (68 -> 91).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The wave-3 loss was caused by sprite auto-suspend, not nohup process-group
semantics. /.sprite/llm.txt: 'When idle, sprites pause automatically. Services and
sessions keep sprites alive.' Detached processes are on neither list, so setsid is
necessary but not sufficient.
tasks/wave-guard.sh holds a /v1/tasks lease (max 3600s, renewal is DELETE+POST since
re-POST returns 409), renews every 15 min while workers run, writes logs/WAVE<N>-DONE,
then releases the lease so the sprite can suspend rather than idle hot.
Also documents hazard #6 (pgrep -f / pkill -f matching the orchestrator's own shell)
and adds the wave-3 worker prompts and shared screen contract.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>