SPEC: lookup outcome is three-way; wave 5 worker prompt

SPEC now states that a source which could not be reached must never be
reported as a book that does not exist: Found / NotFound / Unavailable,
where NotFound requires every source to have answered authoritatively.
Also records that a rejected barcode must not be silent, and that the
by-ISBN cover URL is not evidence a cover exists.

run-task.sh exports CLAUDE_CODE_PRINT_BG_WAIT_CEILING_MS=0, per the wave-4
post-mortem: `claude -p` otherwise kills background tasks at 600s, so a
worker that backgrounds a Gradle build can never report on it. Safe to
edit now — no workers are running (hazard: never edit it while they are).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CDcPottghJXEvfYKqFM7zf
This commit is contained in:
Sprite
2026-09-09 10:42:32 +00:00
co-authored by claude
parent 1ba22a9f36
commit 1969b74cc9
3 changed files with 208 additions and 2 deletions
+18 -2
View File
@@ -91,12 +91,28 @@ Never let sync failure surface as a crash or a blocking dialog — a quiet statu
Primary Open Library: https://openlibrary.org/api/books?bibkeys=ISBN:{isbn}&format=json&jscmd=data
Fallback Google Books: https://www.googleapis.com/books/v1/volumes?q=isbn:{isbn} (no key)
Cover: https://covers.openlibrary.org/b/isbn/{isbn}-L.jpg else GB imageLinks (force https, zoom=2)
Merge: prefer whichever has a title; fill blanks from the other. Return null if both miss,
and the UI must then offer manual entry pre-filled with the scanned ISBN.
Merge: prefer whichever has a title; fill blanks from the other.
Cover URL comes from a source that REPORTS one. Never synthesize the by-ISBN cover
URL as if it were evidence: for an edition with no art that endpoint returns 200 +
a 43-byte 1x1 transparent GIF, which loads "successfully" and paints nothing. As a
last resort it may be used only with `?default=false`, which makes a miss a 404.
Lookup outcome is THREE-WAY, never a bare null. A source that could not be reached
must never be reported to the user as a book that does not exist:
Found(metadata) - at least one source returned a record
NotFound - EVERY source answered authoritatively and none had it
Unavailable - no source could be reached (non-2xx, timeout, transport error)
and none of the reachable ones had it
UI: Found -> the save sheet. NotFound -> manual entry pre-filled with the scanned
ISBN. Unavailable -> a retry affordance, with manual entry as the escape hatch;
it must NOT claim the book is unknown.
## Barcode scanning
CameraX Preview + ImageAnalysis -> ML Kit BarcodeScanning (EAN_13, EAN_8, UPC_A).
Validate ISBN-13 checksum before lookup; ignore non-book barcodes. Debounce repeats.
A rejected barcode is NOT silent: the camera screen must say a code was read and
was not a book ISBN, or the user cannot tell a non-book barcode from a dead camera.
Throttle that message — a non-book barcode sits in frame emitting continuously.
Continuous mode: after a save, stay on camera for the next book (shelving a box of
books is the real use case). Show a running "added this session" count.
Handle: camera permission denial, torch toggle, and a manual-ISBN-entry escape hatch.