Eric's spec, all nine points. Two committed local-only stores follow
the local_games.json pattern — furniture.json (units of openings with
interior dims; a dimensionless opening is a virtual spot like a travel
case) and locations.json (game key -> opening + note). Shelf layouts
are nobody's data but the owner's; nothing touches upload.
The Shelves page builds furniture without hand-editing JSON — the
acceptance bar (two double-wides above three rows of four cubes, two
bookcases, a travel case) is a TEST, driven entirely through the
endpoints the UI calls. Presets for Kallax/Billy/custom/virtual,
grid creation with A1-style labels, openings editable/deletable/
reorderable. Units render as grids: zone, count, fill bar (stacked
thinnest-axis vs interior height), ⚠ on overfull or any resident that
can't fit. Openings open as a modal — a bottom sheet at phone widths,
search-first with thumb-sized targets for the moving-day loop.
Unshelved games list alongside with one-tap suggestions (only openings
they verifiably fit, with room).
Containment composes: a game stored inside another box inherits its
container's location, rides along in the opening's resident list
(marked), and refuses direct assignment naming its container. The
detail page's where-it-lives card gains the picker (openings grouped
by unit, each labeled fits / doesn't fit / can't verify) plus virtual
notes ("lent to Sarah, June"); the Library list shows a location line,
filters by unit or unshelved, and search matches location text and
zones.
bggpipe dims drops its hardcoded Kallax for the user's actual
furniture: per-opening capacity, overfull and misfit warnings,
unshelved count. bggpipe shelve --import loads a name,opening CSV
(ids or labels), rejecting — never guessing — unknown names, ambiguous
copies, unknown/ambiguous openings, misfits, and contained games.
Ten new tests incl. the acceptance flow, inheritance, CSV rejects,
and a phone-sheet smoke; 372 total.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
Eric's brief, implemented to the letter. BGG keeps physical dimensions
on VERSIONS, not games, so enrich runs a second cached pass over
thing?versions=1 (same batching, token, rate limit, and cache as every
call). A game with a chosen version takes that exact version's numbers
(source "version", mirrored onto its version dict); a versionless game
gets numbers only when every printing with data agrees within 0.5" per
axis (source "unanimous", keeping the MAX per axis — the planning
question is "will it fit"); disagreement stores nulls as "conflicting"
— never a guess — and BGG's 0 parses as "never entered", not a real
dimension. rpgitems and local games are "absent". Read-only: upload
untouched.
The new offline `bggpipe dims` reports coverage by source, the ten
biggest footprints, and a Kallax fit check (13.2" square opening,
15.4" deep; a box fits if SOME orientation puts two axes through the
opening within the depth) — naming every misfit and every game whose
dimensions can't be verified, because can't-verify ≠ fits. Trusted
numbers surface on the Library detail page as a "box" row.
First real run: 54 version-exact, 16 unanimous, 39 conflicting, 27
absent; three genuine misfits (Bugs in the Kitchen's 17" box, History
of the World and Risk LotR both over the 15.4" depth).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
Eric wanted the library on his blog; the spec always called games.json
"the seed for a future web frontend." The new export stage renders it
as self-contained static pages — an index with search, one page per
game with facts, chips, the owner's edition and the description — that
drop into any static host (Hugo's static/ folder included). No server,
no build step, no external requests from the published pages.
Public pages carry obligations a localhost app doesn't. Cover art is
downloaded once from BGG's CDN instead of hotlinked (0.3s between
fetches — a guest, not a crawler; part-file writes so a failure never
leaves a truncated image; re-runs skip what exists, so the export is
idempotent and resumable like every stage). The footer shows a
Powered-by-BGG badge per BGG's public-app policy — text by default,
upgraded to the official logo when the owner saves it from their
registered-application page as data/powered-by-bgg.png — plus the
trademark attribution. And one privacy rule, tested: shelf photos are
never exported; they picture the inside of the owner's home. Covers
and hand-added local art only, per Eric's explicit choice.
Slugs are deterministic and collision-stable (two editions of one game
get -2 suffixes in sorted-key order) so re-exports keep every URL.
Descriptions un-double-encode BGG's entities. First real run: 136
pages, 254 covers, 64MB, live on the blog's static directory.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
Eric's clean-room run produced screenshots of states the gallery
never had: Review showing LIVE ballots (Agricola vs Revised Edition,
with per-candidate ranks, owner counts and view-on-BGG links, and the
search BGG/RPGGeek buttons), the editions pass in full flight (five
English Catan printings to choose from — the version-selector shot
Eric asked for days ago), the Queue with real pending adds and a
pending version update, a dry run's would-add output (now
illustrating the guide's Uploading-safely section), and extract
streaming per-photo counts (now illustrating the guide's web-app
section). The old Review and Queue images showed stub-era done/empty
states with captions about waiting on tokens — retired.
Also linked, at Eric's suggestion: the pipeline's actual output is
public at boardgamegeek.com/collection/user/ewagoner — the README
status line and tour intro now point at it, because "here's the
collection it built" beats any amount of claimed battle-testing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
Eric's clean run put a price on the pipeline's only paid step:
65 shelf photos, 136 games, under a dollar on the default model. The
README's vision requirement and the guide's config section both now
say so, plus the shape of the cost — one-time, since per-photo reads
are cached and re-runs are free — and that the BGG side costs nothing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
Eric has seen the criticism land on other BGG apps: why does this
thing want my password? The README now answers it where the
requirement appears: BGG has no write API, so uploading means signing
into the real website in a visible browser on the user's own machine
— that login is the password's entire job. And the reassurance that
matters: no server, no telemetry, no analytics, nothing collected;
credentials go to boardgamegeek.com and nowhere else, the only other
contact is the user's own chosen vision provider (photos only, and a
local Ollama keeps even those home). The guide's credentials section
links back and notes the saved browser session stays local too.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g
Eric's read on the first-visitor experience: 190 lines of pitch,
manual, gallery, and contributor doc is intimidating when the visitor
only needs the first 40. Split three ways:
README.md is now the front door — what it is, why it exists (told in
first person now, since it IS a personal itch scratched), how the six
stages work, requirements, quick start, one hero screenshot, and the
development/citizenship/license notes. Sixty percent shorter.
docs/tour.md carries the full gallery: all seven pages, the game
detail view, and the phone set, captions intact.
docs/guide.md is the complete user's guide: credentials and config,
the stages and their flags, phone pairing, photo technique, curation
stores, RPG handling, upload safety (including the collection-export
lag), the no-token-yet path, and the keep-data-out-of-git rationale.
Every relative link and README→guide anchor machine-verified to
resolve.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016jXZFSTZQKzAC8fqpWSz9g