docs: add AGENTS.md project context (CLAUDE.md symlinked for compatibility)
This commit is contained in:
parent
827d0d2e2a
commit
b16d6b4250
2 changed files with 128 additions and 0 deletions
127
AGENTS.md
Normal file
127
AGENTS.md
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
# 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.
|
||||
1
CLAUDE.md
Symbolic link
1
CLAUDE.md
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
AGENTS.md
|
||||
Loading…
Reference in a new issue