A reminder to myself of what a good two days look like.
It started as a restructuring hunch: maybe every family should get their own Airtable workspace. An hour of exploration killed that idea with facts — per-workspace billing, API caps on free tiers, quotas that turned out to be per-base anyway — and what survived was better: one workspace, a config base per family, a registry the museum app reads, and everything reversible by design.
From there it compounded:
- A gallery registry now resolves every museum through its family’s config base, with a legacy fallback so unmigrated tenants never noticed a thing. Live in prod, zero coordination windows.
- The access flow: a museum-voiced apply page (“Request your key”) on every museum, public even on the private ones, because applicants don’t have accounts — that’s the point. Honeypot, rate limits, 404s that reveal nothing.
- A curator gets a mail — “Someone is at the door” — in their family’s own palette and typeface, and welcomes a family member with one click. Scanner-safe, HMAC-signed, expiring. “Leave as is” is a first-class decision, because families shouldn’t be forced to formally reject relatives.
- A 15-minute heartbeat on the VPS reconciles Airtable (the single source of truth) into Keycloak: marker-based, disable-only, idempotent. Manual console edits don’t get reverted — they get reconciled into the truth.
- The first sync-managed user was provisioned today. The welcome mail explains “the door ritual”: enter your email, your key arrives, no password, ever.
The catches along the way were the best part: staging exposed a second auth layer the unit tests couldn’t see; the live tick exposed Cloudflare bot-blocking Python’s default user agent (“error code: 1010”); the form’s first reviewer (me) caught that visitors could self-nominate as curators. Every catch became spec, test, or runbook — nothing was patched silently.
All of it ran through the OpenSpec workspace pilot: one cross-repo change, four artifacts, every decision written down within minutes of being made. Piet asked for exactly this flow four days ago in an email thread. It exists now, and it’s nicer than what anyone asked for.
Hospitality, not administration.
// end