From f9553373d60ebda78534e195c303ea75e3adb131 Mon Sep 17 00:00:00 2001 From: pyr0ball Date: Mon, 13 Jul 2026 11:22:22 -0700 Subject: [PATCH] docs: drop AI/ML terminology in README, document marker ordering - README "How it works" step 3: "not by any AI/ML step" -> "not by any model inference step", per AGENTS.md's terminology rule (no generic "AI" when describing system capability). - AppConfig gets a docstring spelling out that markers must be ordered smallest-bucket-boundary first, since determine_size_bucket trusts this order and a misordered config would silently produce a wrong (tax-relevant) size bucket. AppConfig.load() also now validates that marker area is non-decreasing across the list and raises ValueError if not, since this project's nested physical markers get larger as bucket size increases. --- README.md | 5 +++-- bookmark/config.py | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 662337f..afffde9 100644 --- a/README.md +++ b/README.md @@ -30,8 +30,9 @@ volunteer/client work — it isn't part of any commercial product line. 2. A volunteer centers the book; capture fires automatically or on a button press (configurable). 3. The system photographs the front, determines size — **deterministically**, - by checking which physical markers are covered, not by any AI/ML step — - then prompts the volunteer to flip the book and photographs the back. + by checking which physical markers are covered, not by any model + inference step — then prompts the volunteer to flip the book and + photographs the back. 4. Every book gets a row in a CSV catalogue: images, size bucket, and a status that later pipeline stages (OCR backfill, checkout) update. diff --git a/bookmark/config.py b/bookmark/config.py index c28963e..5d3c722 100644 --- a/bookmark/config.py +++ b/bookmark/config.py @@ -7,6 +7,23 @@ from .sizing import MarkerRegion @dataclass class AppConfig: + """ + IMPORTANT — `markers` ordering requirement: + + `markers` must be listed smallest-bucket-boundary first, largest last + (see `bookmark.sizing.determine_size_bucket`, which trusts this order + and does not re-sort). The physical rig's nested markers get larger as + the size bucket grows, so marker area (width * height) should be + non-decreasing across the list in config.json. `AppConfig.load()` + validates this area ordering and raises `ValueError` if it's violated, + but it cannot verify that markers are ordered by *bucket name* + ("small" < "medium" < "large") independent of that, since bucket + naming is config-defined — an install with correctly-increasing marker + areas but mislabeled bucket names would still silently produce a wrong + (but plausible-looking) size bucket. Get the marker order right in + config.json; this is tax-report-relevant data for Books in Hand. + """ + device_index: int catalogue_path: Path captures_dir: Path @@ -19,6 +36,7 @@ class AppConfig: def load(cls, path: Path) -> "AppConfig": data = json.loads(Path(path).read_text()) markers = [MarkerRegion(**marker) for marker in data["markers"]] + _validate_marker_area_order(markers) return cls( device_index=data["device_index"], catalogue_path=Path(data["catalogue_path"]), @@ -28,3 +46,24 @@ class AppConfig: guide_box=tuple(data["guide_box"]), trigger_strategy=data["trigger_strategy"], ) + + +def _validate_marker_area_order(markers: list[MarkerRegion]) -> None: + """ + `determine_size_bucket` requires `markers` ordered smallest -> largest + bucket boundary. We can't infer bucket order from names alone, but the + physical rig's nested markers get larger as the bucket size grows, so + marker area (width * height) should be non-decreasing across the + ordered list. A misordered config would silently produce a wrong (but + plausible-looking) tax-relevant size bucket, so fail loudly here + instead. + """ + areas = [marker.width * marker.height for marker in markers] + for previous, current in zip(areas, areas[1:]): + if current < previous: + raise ValueError( + "config.json 'markers' must be ordered smallest-bucket to " + "largest-bucket, with non-decreasing marker area — found a " + f"marker with area {current} listed after one with area " + f"{previous}. Check the marker order in config.json." + )