6.7 KiB
Bookmark — Agent & Developer Context
Bookmark is a camera-driven book intake and checkout inventory system built for Books in Hand, a nonprofit that keeps books out of landfills and in people's hands. It is a standalone client project — not part of the CircuitForge product line, no BSL tiering, no CircuitForge license server integration. Owned by / donated to the nonprofit.
This file is the entry point for any AI coding assistant (Claude Code, Codex, Cursor, etc.) or human contributor picking up this codebase. Read it before making changes.
What This Project Does
Two physical stations, camera-driven:
- Intake station — a volunteer places a book on a marked platform under
a downward-facing webcam. The system captures front and back photos in a
guided flow, determines a
small/medium/largesize bucket deterministically (by checking which physical platform markers are covered vs. exposed — no OCR, no ML), and writes a row to a CSV catalogue. This size bucket feeds Books in Hand's year-end tax and 501(c)(3) reporting, including charitable write-off valuation — it must stay deterministic because a wrong bucket has real financial consequences. - Checkout station (later phase) — reuses the same camera + identification pipeline (barcode decode, vision-LLM fallback) to mark books as taken, updating the same CSV.
- Batch OCR/ISBN backfill (later phase) — a separate pass, run on demand on GPU-equipped hardware, decodes ISBN barcodes first and falls back to a local vision-LLM (VLM) to read the cover when no barcode is present, filling in title/author/ISBN for the catalogue and the future public website. Low-confidence matches are flagged for human review — never auto-published.
Full design rationale and phase-by-phase build order live in:
- Design spec:
circuitforge-plans/books-in-hand/superpowers/specs/2026-07-13-inventory-system-design.md - Phase 1 implementation plan:
circuitforge-plans/books-in-hand/superpowers/plans/2026-07-13-bookmark-intake-station-plan.md
Those live in a separate private planning repo and won't always be available to whoever is working in this repo — treat this file as the self-contained summary; the sections below capture what those docs decided.
Terminology
Never use the generic term "AI" in code, comments, docs, or UI copy. Name the specific mechanism instead: "LLM", "VLM" (vision-LLM), "OCR", "barcode decode". This keeps claims about what the system does precise and avoids overstating capability.
Architecture (Phase 1 — Intake, the only phase built so far)
- Backend: Python 3.11+, FastAPI + Uvicorn.
bookmark/main.pyexposescreate_app(session, camera). Routes live inbookmark/api/routes.py. - State machine:
bookmark/session.py'sIntakeSessiondrives the guided front → back → next-book flow, calling into:bookmark/sizing.py— pure, deterministic marker-occlusion check (determine_size_bucket). No ML.bookmark/image_processing.py— pure crop-to-book function (crop_to_book), contour-diff against a calibrated empty-platform reference frame.bookmark/catalogue.py— CSV read/write layer (Catalogue,BookRecord). The CSV (catalogue.csv) is the single source of truth for Phase 1 — no database.bookmark/capture_strategies/— three swappable, interchangeable trigger strategies behind oneCaptureStrategyinterface, selected via config (never hardcode one):manual_button.py(button/key press),motion_stop.py(frame-diff stabilization countdown),stable_centered.py(auto-detect a book filling the guide box and holding steady).
- Camera:
bookmark/camera.py'sCameraSourcewrapscv2.VideoCapturebehind aFrameSourceprotocol so tests can substitute a fake camera. - Frontend: plain HTML/CSS/JS kiosk page in
bookmark/static/— no build step.theme.cssis the central theme file (colors, spacing, typography as CSS variables, light/dark aware);style.cssholds component styles that reference those variables. Keep all future frontend work theme-aware and responsive through this same file — don't hardcode colors/spacing in component CSS or inline styles. - Config/entrypoint:
bookmark/config.py'sAppConfig.load()readsconfig.json(per-install, gitignored — copy fromconfig.example.jsonand fill in real marker/guide-box pixel coordinates fromcalibrate.py's output).run.pywires everything together for production;calibrate.pyis a one-time-per-install interactive script that captures the empty-platform reference frame.
Hardware Context (informs future phases, not code in this repo yet)
Donated hardware: a 3U server (AMD EPYC Rome 8-core, 32GB DDR4, nVidia A400 — upgradeable to RTX 4000, 512GB NVMe + 4TB SATA SSD) hosts the intake station and, in Phase 2+, a shared local vision-LLM service that both intake and the future checkout kiosk(s) call over the LAN. Up to 3 Intel NUCs (mixed generation) are available for kiosk stations. Cameras are not provided — a USB webcam per active station still needs sourcing.
Global Constraints (binding across all phases)
- No cloud services anywhere in Phase 1. Phase 2's only outbound network calls are ISBN/title lookups against Open Library / Google Books, made only after barcode decode or local VLM inference has already run.
- Size-bucketing must stay deterministic (geometry/visibility only) — never derive it from OCR, ML, or an LLM/VLM step.
- Both the wide (uncropped, shows platform markers) and cropped (book-only) images are kept for every capture — the wide image is the audit trail for size-bucketing.
- No authentication/login on either station (nonprofit, low-stakes, kiosk-appropriate).
- LLM/VLM output (Phase 2+) assists; a human reviews and approves before anything gets published to the future public site — never auto-publish.
Development Workflow
- Python:
.venv/bin/pip install -e ".[dev]"from repo root. - Tests:
.venv/bin/pytest -v— TDD throughout; every module has a test file undertests/that exercises it without real camera hardware (synthetic NumPy frames, mockedcv2.VideoCapture,TestClientfor the API). - Run locally: see
README.mdfor calibration → config →run.pysteps. - Commit frequently, one logical change per commit, conventional-commit-style
subjects (
feat:,fix:,docs:,chore:,test:).
Out of Scope Here
- Website redesign and site publishing/export of catalogue data — separate effort, contingent on the client's own timeline.
- Checkout station and batch OCR/ISBN backfill — future phases, each gets its own plan before implementation starts; don't build ahead of the current phase's plan.