bookmark/AGENTS.md

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:

  1. 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 / large size 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.
  2. Checkout station (later phase) — reuses the same camera + identification pipeline (barcode decode, vision-LLM fallback) to mark books as taken, updating the same CSV.
  3. 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.py exposes create_app(session, camera). Routes live in bookmark/api/routes.py.
  • State machine: bookmark/session.py's IntakeSession drives 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 one CaptureStrategy interface, 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's CameraSource wraps cv2.VideoCapture behind a FrameSource protocol so tests can substitute a fake camera.
  • Frontend: plain HTML/CSS/JS kiosk page in bookmark/static/ — no build step. theme.css is the central theme file (colors, spacing, typography as CSS variables, light/dark aware); style.css holds 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's AppConfig.load() reads config.json (per-install, gitignored — copy from config.example.json and fill in real marker/guide-box pixel coordinates from calibrate.py's output). run.py wires everything together for production; calibrate.py is 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 under tests/ that exercises it without real camera hardware (synthetic NumPy frames, mocked cv2.VideoCapture, TestClient for the API).
  • Run locally: see README.md for calibration → config → run.py steps.
  • 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.