Get Camino: Your Road to Spain
Sign in
Get your roadmap
HOW I WAS BUILT — THE RECEIPTS
The build log
The essay tells the story; this is the homework. Every major piece of Get Camino — newest first — with what shipped and the decisions that shaped it.
← Read the essay
The code on GitHub ↗
51
Take it with you (and get back to the top)
4 Jul 2026
WORK COMPLETED
The home page now says where the app is headed: a quiet band announcing the iPhone and Android apps — honestly marked "coming soon," not a fake download badge for something you can't download yet. And long scrolls got a back-to-top button: on the roadmap, the sample plan, and the sixty-step guide list, a floating arrow appears once you've scrolled a screen down and takes you home in one tap.
KEY DECISIONS
Honest placeholders over impressive-looking lies: no official store badge appears until there's a real listing behind it — swapping in the link is a one-line change when the apps ship.
The back-to-top button respects reduced-motion: it jumps instantly instead of animating for anyone who's asked their device to calm down.
50
The plan for Spanish
4 Jul 2026
WORK COMPLETED
A moving-to-Spain product that only speaks English lacks authenticity — so localization moved from "someday" to before launch. The technical design is written and approved: Spanish first (verified by a native-speaking family member), then French, German and Italian as fill-in-the-blanks exercises on the same plumbing. The engine stays language-free; translation is purely presentation.
KEY DECISIONS
Invariant 3 extends to translations, mechanically: a translated step may never carry a number its English source doesn't — the digit-lint now guards every language.
The language switcher is a feature, not a setting: each language listed in its own name, visible in the menu, because a Spanish speaker lost in an English UI can always find "Español".
Lola says tú, not usted — warmth is her voice in every language. And "Get Camino" and "Lola" never translate.
49
A real inbox and a real operator
4 Jul 2026
WORK COMPLETED
The product stopped using a personal Gmail: feedback@, privacy@ and legal@getcamino.app now route reports and rights requests (delivery tested end-to-end), and the legal pages name the actual operator — AELaboratories, Inc — with governing law updated to match its state. The path to a formal company is deliberately deferred: sole proprietorship until there's a proven revenue model.
KEY DECISIONS
Purpose-named addresses over one generic inbox: where an email lands tells you what it is before you open it — and they all route to a single mailbox anyway.
Incorporate when revenue proves the model, not before — the migration is mostly behind-the-scenes store agreements, so waiting costs little.
48
How-it-works redesign + "the product roadmap"
4 Jul 2026
WORK COMPLETED
The how-it-works page — untouched since the earliest days — got a layout pass: its sections ran edge-to-edge on desktop while every other page reads in a centered column, so each section's content now sits in the same 760px column, and the bureaucracy card says what the plan just learned (rules that differ by comunidad are flagged). This page was also renamed "the product roadmap".
KEY DECISIONS
Full-bleed section backgrounds stay — only the content inside is constrained. The rhythm of alternating bands is the page's structure; the fix was readability, not a rebuild.
Renamed to differentiate: "roadmap" is what Get Camino builds FOR YOU in the product; "the product roadmap" is where the product itself is going.
47
Every official source link, click-tested
4 Jul 2026
WORK COMPLETED
All 55 official source links were fetched and checked against their steps — status, where they redirect, and whether the page is actually about the step. Two failed honestly: the empadronamiento link died when a government portal was retired (now points at the law itself, art. 15 of the Ley de Bases del Régimen Local), and the NIE link landed visitors on a police-site cookie wall instead of NIE content (now the Ministerio del Interior's canonical NIE page).
KEY DECISIONS
Trust content, not status codes: administracion.gob.es serves "Error" pages with HTTP 200, so every link was verified by its actual heading, not its response code.
When a government info page is unstable, cite the law itself — BOE links outlive portal redesigns.
46
A safer name: Get Camino
4 Jul 2026
WORK COMPLETED
"Camino" is a lovely word — which is exactly the problem: plenty of businesses already want a piece of it. Until a proper trademark search happens, the app and site go by Get Camino (matching the domain we already own), extended brand "Get Camino: Your Road to Spain" — which happens to fit the App Store's 30-character name limit exactly. Every user-facing surface renamed: the name under the icon, the nav, the emails, the printed report, the legal pages, and how Lola introduces the product.
KEY DECISIONS
Brand defensively before brand spend: a distinctive compound beats a common word you'd have to fight for.
Identifiers never chase brands: the bundle id, URL scheme, and internal names stay put — a rename should never break sign-in or saved links.
45
The microphone and Lola learn turn-taking
4 Jul 2026
WORK COMPLETED
Family testing round four (build 27) nailed the last voice bug with a precise diagnosis: earlier builds only DUCKED Lola's voice while the mic was open — and never released the duck, so everything after went quiet. Build 27 fixed the volume but left her talking over you. Now it's explicit turn-taking: opening the mic cuts her line outright, and every later line plays at full volume. Also fixed: your spoken answer no longer reappears in the next question's box (the recognizer flushes one last result after it's told to stop — that flush was refilling the input the send had just cleared).
KEY DECISIONS
Replace audio-session side-effects with explicit app-level behavior: "mic opens → Lola stops" is one deterministic line, not a hardware mode.
Treat late recognizer events as stale by default — a gate flips before the engine is told to stop, on both web and iOS.
44
The paid endpoints learned to say no
4 Jul 2026
WORK COMPLETED
The two endpoints that cost real money per call — Lola's brain and Lola's voice — now carry real volume limits: a per-visitor per-minute cap and a global daily budget each, counted durably in the database. The in-memory counters they replace reset whenever the platform recycled a worker (a 70-request burst produced zero throttles); the new ones trip at exactly their limit, verified live. Cross-site browsers are locked out too: the platform's default wide-open CORS answer is replaced with a strict one pinned to our own origins.
KEY DECISIONS
Fail open, bounded in dollars: if the counter database hiccups, users keep working — and provider spend caps bound the worst case. Availability first at this scale.
Only requests that would actually reach the paid provider consume budget — malformed junk can't starve the day's capacity.
Measured before believing: the platform rewrites the Origin header and quietly recycles in-memory state, so every layer was burst-tested against the real runtime, not the docs.
43
Keyboard focus you can see
4 Jul 2026
WORK COMPLETED
Tab through any page and an amber ring — the brand's waypoint color — shows exactly where you are. Keyboard users get the ring; mouse and touch clicks don't.
KEY DECISIONS
Amber over cobalt: the one brand color that reads on both the cream background and the dark indigo bands.
:focus-visible, not :focus — a11y for keyboard users shouldn't add visual noise for everyone else.
42
A spinner is a moment, not a destination
4 Jul 2026
WORK COMPLETED
Family testing round five, all fixed: the app could cold-start into an eternal "Loading your roadmap…" (it now knows when there's nothing to load and takes you home); an interview answer could spin forever if the network hung (35-second limit, then Lola owns it and your answer is back in the box to resend); the microphone cue now appears when the mic is actually hot — so fast talkers stop losing their first words — and tapping it off keeps your last words instead of discarding them; and the answer box grows again as you dictate.
KEY DECISIONS
Every waiting state needs an exit: a timeout, a fallback, or a redirect — nothing may wait forever.
Two ways to end dictation, deliberately: mic-off KEEPS the recognizer's final flush (your last words); send DISCARDS it (it would refill the box that just cleared).
41
The robots test the app now
4 Jul 2026
WORK COMPLETED
End-to-end tests grew up: the web suite now signs in as a seeded test user (through the real magic-link machinery, no inbox involved) and walks the journeys that matter — saved roadmap, the week view, mark-done and undo, the no-op honesty gate, sign out. Twelve tests, twelve seconds, against the live staging site. Native flows are written for the iOS simulator and run on a free CI runner with zero build credits. First catch, before it even finished: a React hydration error firing on every page load (the nav wordmark rendered differently on server and client).
KEY DECISIONS
Tests sign in through the same code path real magic links use — a test-only backdoor would test the backdoor.
The test user lives ONLY in staging, and the seed script hard-refuses to run against production.
Runs are manual + pre-release, not per-push: each one spends real LLM calls, and our own rate limits apply to us too.
40
The plan learns geography
4 Jul 2026
WORK COMPLETED
Spain isn't one rulebook: transfer tax, wealth tax, school admission windows and property tax all vary by comunidad autónoma. The interview now asks where you're settling (name a city and Lola places it in its region), and every region-varying step says so — on your roadmap, in the guides, and on the printed report — naming your region when it's known.
KEY DECISIONS
Honest v1: the plan KNOWS your region and flags what varies there. Shipping 17 regions of rates without per-region official sources would break the no-invented-facts rule — that's a sourced content pass, now queued.
"Not sure yet" is a first-class answer: undecided movers get the scouting step and generic flags, not a forced guess.
39
Polish: structured data, a smarter front door, and quieter motion
4 Jul 2026
WORK COMPLETED
Search engines now get structured data (article + breadcrumbs on every guide, the full catalog as a list, the site itself); arriving at the interview from a guide gets acknowledged ("so glad you're looking into getting your NIE sorted") before the first question; and an accessibility pass landed — the rotating home photo rests when your system prefers reduced motion, controls carry proper roles and labels, and inputs are named for screen readers.
KEY DECISIONS
The interview greeting may acknowledge WHERE you came from, never facts about the topic — phrasing is the only surface the model owns.
Per-deploy preview URLs are now first-class origins for our own APIs: the hardening was blocking our own pre-production verification.
38
Links that dress well
4 Jul 2026
WORK COMPLETED
Every public page now unfurls properly when shared: a branded card (the compass-star tile, the promise, the domain) plus per-page social titles and descriptions. One Seo component owns the whole tag set, so no page can ship half of it.
KEY DECISIONS
Get Camino's links will live in WhatsApp threads and expat Facebook groups — a bare gray link and a branded card are different products there.
The share card is generated from the same brand-mark code as the app icons: one geometry, every surface.
37
The boring pages that make a real product
4 Jul 2026
WORK COMPLETED
Privacy policy, terms of use, and aviso legal — plain language, linked from every footer. Delete my account, in the menu: one warning, one tap, immediate and permanent (tested live, start to finish). And web analytics went cookieless, so there's no consent banner because there's nothing to consent to.
KEY DECISIONS
Account deletion is both Apple's requirement and the GDPR's right to erasure — one honest implementation serves both: hard delete, no grace period, no dark patterns to keep you.
No cookie banner by design: analytics that persist nothing client-side beat a banner everyone resents.
Legal pages follow the homework-page rule: if a data flow changes, the privacy page changes in the same PR.
36
Family-testing fixes, round three
4 Jul 2026
WORK COMPLETED
A former QA engineer joined the testing and it shows: Lola's voice dropped to phone-call volume after the first line (the microphone session was rerouting audio to the earpiece — playback now reclaims the loud speaker every time); a clarifying question mid-interview got a canned "sorry, didn't catch that" (Lola now answers what you asked, then re-asks — still forbidden from stating legal facts there); "on a date" became "did it earlier? add the date" with a forgiving date field that reads "25 April 2026", Spanish months, and "yesterday" — and shows you what it understood before saving; and the printable report got print-safe contrast and real page margins.
KEY DECISIONS
Date entry is a parser, not an AI: instant, offline, and incapable of hallucinating — and when input is genuinely ambiguous (04/05/2026) it asks rather than guesses.
The conversational interview keeps the honesty wall: Lola can explain what a question means, never what the law says — that lives in the sourced roadmap.
Print is its own medium: colors that read on a screen wash out on paper, and iOS ignores CSS page margins entirely — the report now carries both itself.
35
The guides learn to talk
4 Jul 2026
WORK COMPLETED
All sixty guide pages gained a written explainer — what the step actually is, how the process feels, who's involved — in Get Camino's voice. Each page's search snippet now uses its own opening sentence instead of a shared template.
KEY DECISIONS
The honesty rule became a build gate: a test fails if the prose contains any number that isn't already in that step's own title — new figures and deadlines can only live behind the official source link.
The lint caught its first violation before shipping (a cross-referenced form number) — the mechanism works.
Narrative explains, data asserts: prose adds context and texture, while every checkable fact stays in the catalog where the audit can see it.
34
Family-testing fixes, round two
4 Jul 2026
WORK COMPLETED
A second phone found four more: the feedback spinner could run minutes after the report had already arrived (the response stalls on some networks; a grace period now thanks you once the send is safely away); the step drawer's inputs hid under the keyboard (it now slides above it by the exact overlap the OS reports); Lola claimed to have "remodelled your plan" when nothing had moved (a no-op re-plan now says so honestly, and appointment dates are steered to "mark done on a date"); and the nav bar wrapped into two lines at larger iOS text sizes (bar labels now cap their scaling — menu items still scale fully).
KEY DECISIONS
Same phone model, different bug: accessibility text size is a device dimension of its own — test with it.
Never let a celebration outrun the diff: "I've remodelled your plan" is only said when a date actually moved.
When the work is provably done but the network is slow to say so, thank the user and stop the spinner — and count how often it happens.
33
Polish pass: the front door catches up
3 Jul 2026
WORK COMPLETED
The home and how-it-works pages predated almost everything shipped this week. Now: every public page has a real title, description and canonical URL (only the guides had them); how-it-works finally ends with a call to action, mentions the weekly email and the sourced guides, and uses the shared footer; the home topic strip links into the sixty guides it was always describing.
KEY DECISIONS
A page that explains everything and asks for nothing is a leak — every marketing page now ends with the same honest CTA.
One shared breakpoint hook replaced two copies of a subtle hydration workaround — the second copy had the bug the first one fixed.
The deploy script now strips iCloud conflict-copy directories from the export: one deploy silently shipped stale pages while the local build was correct.
32
The printable roadmap + a way to talk back
3 Jul 2026
WORK COMPLETED
The roadmap became a report: one tap renders a clean, print-ready PDF — hero next step, estimated vs firm dates, dateless steps that say what they're waiting for, official source URLs printed for the gestor. And a "Report a problem" line joined the menu: one text box, straight to the team inbox with platform, version and route attached. iPad support switched off for the first release.
KEY DECISIONS
The report is a pure function of the plan (the fourth thesis piece, finally shipped) — same honesty rules as the app: estimated says estimated, waiting says waiting, nothing invented.
One HTML generator serves both platforms: the browser's own print dialog on web, a real shared PDF file on iOS — no PDF library shipped to anyone.
Feedback goes to email, not a dashboard: at family-testing scale, the inbox IS the triage queue, and the recipient is hardcoded so the route can't be abused as a mail relay.
iPad off for launch: fewer screenshots, fewer review surfaces, nothing the phone experience doesn't already prove.
31
The homework goes public + links that open the app
3 Jul 2026
WORK COMPLETED
This whole section — the essay, this log, the roadmap — left the unlisted shadows: it's in the nav menu and the sitemap now, and every entry carries its ship date. And the links in Get Camino's emails gained universal links, so tapping "Open your roadmap" on an iPhone opens the app (signed in) instead of a logged-out browser tab.
KEY DECISIONS
Building in the open was already the point — hiding the receipts behind a direct link stopped making sense once the guides made content the front door.
Dates on every entry keep the log honest about pace: this product went from empty repo to sixty guides in four days, and the record should show it.
Universal links are configuration, not code: an entitlement plus a JSON file the domain serves — and Apple caches that file on install, so it only kicks in from the next build.
30
Sign in with Apple, solved
3 Jul 2026
WORK COMPLETED
A five-build mystery: Apple's own sign-in sheet rejected only this app, while every layer we could check was provably correct — the entitlement inside the signed binary, the App ID capability, fresh provisioning profiles, the auth provider config, active developer agreements. The failure lived in none of them: Apple's server-side provisioning for the App ID had gone stale. Toggling the capability off and back on forced a re-provision, and sign-in started working — even on the older builds.
KEY DECISIONS
Eliminate by evidence, not vibes: each layer was verified with an artifact (the IPA's own entitlements, the portal config, the agreement dates) before moving to the next.
The decisive clue was that an OLD build started working the moment the capability was re-provisioned — proof the broken state lived on Apple's servers, not in anything we shipped.
When every checkable layer is correct and the platform still fails, re-provision before you rewrite.
29
Family-testing fixes, round one
3 Jul 2026
WORK COMPLETED
Real devices found what simulators don't: the emailed sign-in code is 8 digits but the app said — and silently truncated to — 6, so codes could never verify; and the step drawer wouldn't scroll on iOS, hiding Lola's answers.
KEY DECISIONS
Never hardcode another system's format: the code length is the auth provider's choice, so the app now accepts whatever arrives and the copy just says "one-time code".
The drawer bug was a wrapper stealing the scroll gesture — the tap-to-close backdrop now sits behind the sheet instead of around it.
28
The "This week" view
3 Jul 2026
WORK COMPLETED
The roadmap gained a second lens: a toggle that filters to just what needs attention now — what's slipped past, and what's due in the next seven days. A clear week gets an honest "nothing needs you this week", with the next dated step so you know what's coming.
KEY DECISIONS
It's a filter over the same deterministic plan, not a second plan — the buckets keep the dependency-safe order, never re-sorted by date.
Due today is "this week", not overdue — the same midnight-grace rule as everywhere else, one predicate shared with the red treatment and the weekly email.
Steps still waiting on a milestone (no honest date) are never shown as "next up" — no fabricated urgency.
27
Sixty free guides
3 Jul 2026
WORK COMPLETED
Every catalog obligation got a public page (/guide/<id>): when it's due, why it matters, what comes first, the official source, and a category tip — plus a grouped index, prerendered HTML titles and descriptions for search engines, and a sitemap. The nav also unified: desktop now gets the same ☰ menu as mobile, with Sign out inside.
KEY DECISIONS
The catalog is the single source: pages are generated from the same data the engine plans with, so a guide can never disagree with a roadmap.
Timing is described as the RULE ("due within 30 days of arrival"), never a fabricated date — personal dates only exist in a real roadmap, which is what the page's CTA is for.
The sitemap is generated from the catalog too — adding an obligation automatically adds its page to search.
The unlisted "how I was built" section stays out of search; the guides are the front door.
26
The email loop, live
3 Jul 2026
WORK COMPLETED
The welcome email and weekly roundup went live end-to-end: server keys landed, both environments redeployed, a real weekly run fired from the scheduler, and real emails read in a real inbox. The live test caught two bugs no unit test saw: email links leaked the hosting platform's per-deploy URL instead of getcamino.app, and one sign-in sent the welcome email three times.
KEY DECISIONS
Test the loop by receiving the email, not by reading the code — both bugs were only visible in an actual inbox.
Links in emails come from one canonical per-environment origin, never from the request URL a proxy hands you.
The triple-send was two races stacked: the client now fires the welcome request once per sign-in, and the server claims the "already welcomed" flag before sending, rolling it back if the send fails.
25
The public roadmap
3 Jul 2026
WORK COMPLETED
This section gained a third page: the product roadmap, updated with every release — shipped, in progress, next, and the things we've said no to.
KEY DECISIONS
Saying no is part of the roadmap: no document vault (we refuse to be a honeypot for passports), no second country yet, no features on spec.
Updating it every release is a standing rule, written into the repo's instructions.
24
The email loop, part one
3 Jul 2026
WORK COMPLETED
Passwordless sign-in (magic link + one-time code) joined the dialog; a signed-out roadmap can be emailed to yourself — which quietly creates your account, with the roadmap riding along; a welcome email greets new users; and a weekly roundup engine (overdue + upcoming, capped at five, deterministic per-item tips) waits on its cron.
KEY DECISIONS
Email over app-store notifications as the retention loop: everyone has an inbox, and every email doubles as a no-password door back into the roadmap.
The roundup is a pure function of the profile — the same engine math as the roadmap, so the email can never disagree with the app.
Nothing pressing this week → no email. A roundup with nothing to say is spam.
Sending is Resend on our own domain; all bookkeeping (welcomed, nudged, opted out) lives in auth metadata, so no schema migration.
23
A calmer nav
3 Jul 2026
WORK COMPLETED
Signing in became one link that opens a dialog (Apple + Google, email next); narrow screens got a hamburger menu holding the browse links, leaving the bar to the two actions that matter.
KEY DECISIONS
Actions live on the bar, browsing lives in the menu — and future content sections have a home waiting.
The split is viewport-width, not platform: an iPad earns the full bar, a narrow desktop window earns the burger.
22
The keyboard, third time
3 Jul 2026
WORK COMPLETED
The interview composer clipped behind the iOS keyboard through two attempted fixes. The framework's keyboard-avoidance component was removed entirely, replaced by a hook that pads by the exact overlap the OS reports.
KEY DECISIONS
When a framework abstraction guesses geometry and guesses wrong twice, stop tuning it — use the number the OS actually gives you.
The two failed fixes stay in the record: that's what "verified on device" is for.
21
Overdue, honestly
3 Jul 2026
WORK COMPLETED
Steps past their due date now say so in red — on the card, in the stats, and in the step sheet, which nudges: mark it done with the real date, or tell Lola what changed and the plan re-flows.
KEY DECISIONS
One deterministic predicate defines "overdue" everywhere — the roadmap today, the weekly email next.
Due today is NOT overdue — you get until midnight before anything turns red.
20
Sign in with Apple
3 Jul 2026
WORK COMPLETED
The official Apple button on iOS, exchanging Apple's identity token directly for a session — no password, no web redirect. Three failed builds taught us Apple's provisioning model the hard way.
KEY DECISIONS
Provisioning profiles are immutable snapshots of capabilities — enabling a capability means re-minting the profile, not editing it. The playbook is now written down.
The native token flow needs no Apple client secret — fewer credentials to hold is a feature.
19
The sample plan
3 Jul 2026
WORK COMPLETED
A public, read-only roadmap for a fictional couple — built by the real engine on a canned profile — with tap-to-expand deterministic detail and interview CTAs.
KEY DECISIONS
Show the payoff before asking for the interview's effort.
The sample's arrival date floats months ahead so its deadlines never look stale.
The LLM coach stays off the public page — a free anonymous LLM endpoint is an abuse surface, and the plan isn't the visitor's to edit. The expanded card teases what the real thing does instead.
18
The test suite & CI
3 Jul 2026
WORK COMPLETED
A deterministic engine suite (15 tests, ~140 ms) runs in CI on every push and inside the deploy gate; API contract tests and a Playwright smoke suite run against the deployed staging site.
KEY DECISIONS
Fast, offline, deterministic tests gate deploys; anything paid or networked is opt-in so CI never burns tokens.
The audit-fix regressions ARE the test fixtures — personas double as executable documentation.
17
The re-verification pass
3 Jul 2026
WORK COMPLETED
All 28 uncited official obligations re-verified one by one against their issuing authorities (tax agency procedure pages, ministry information sheets, the BOE, the DGT, the Instituto Cervantes) and given canonical links; a missing EU-registration obligation was discovered and added.
KEY DECISIONS
The catalog reached 60 obligations: 55 official — every single one citable — and 5 honest recommendations.
The audit's persona check exposed the EU gap: an empty plan is a finding, not a nuisance.
16
The cold-eyed audit
3 Jul 2026
WORK COMPLETED
A full fresh-eyes review of architecture, catalog, and interview found real bugs: a language-exam rule mishandling Filipino applicants, two interview answers collected but never read, the drift-check invariant living in dead code, and 28 "official" items with no citation attached.
KEY DECISIONS
Auditing your own product is scheduled work, not luck.
Every fix shipped with a regression persona so it can't silently regress.
The invariant checker was revived as a script that gates every deploy.
15
Citizenship vs. renewal — asking instead of assuming
2 Jul 2026
WORK COMPLETED
A new interview question (do you hope to become a citizen, or keep renewing residence?) now gates the entire citizenship track; a second new question gates the scouting trip to people still choosing a region.
KEY DECISIONS
The engine had silently assumed everyone naturalises — a big assumption belongs to the user, deterministically, not to the catalog.
14
Native parity
2 Jul 2026
WORK COMPLETED
Three TestFlight builds brought iOS level with web: spoken Lola (expo-audio streaming a GET variant of the TTS route), native crash reporting with readable stack traces, native analytics.
KEY DECISIONS
Each build verified on a real device before being called done.
Android deliberately deferred to the very end — no test device, no pretend testing.
13
Observability
2 Jul 2026
WORK COMPLETED
Sentry across web, the API routes, and native iOS — one project tagged by platform and environment — plus an uptime monitor that pages on downtime, and daily budget caps on the paid API routes.
KEY DECISIONS
One Sentry project with tags beats three projects to manage.
The Workers runtime fits no Sentry SDK, so the API routes send minimal envelopes by hand — a smaller correct thing over a bigger wrong one.
12
Official sourcing & the source taxonomy
2 Jul 2026
WORK COMPLETED
Every webinar-derived claim researched against government sources; corrections applied (regional tax ranges, renewal windows, a voluntary-not-mandatory registry); the taxonomy simplified to official | recommendation.
KEY DECISIONS
A tag is not a citation — "official" ultimately came to require a canonical URL the user can check.
Six items stayed honest recommendations rather than being dressed up as law.
Webinar links were kept as staff-only cross-checks with timestamps — ideation material, not user-facing truth.
11
Lola's voice
2 Jul 2026
WORK COMPLETED
ElevenLabs TTS behind /api/tts (key server-side), a warm Spanish-accented English voice, on by default, with a visible mute pill.
KEY DECISIONS
Two failed autoplay fixes are part of the record: browsers block audio without a user gesture. The real fix rides the gesture users already make ("Let's get started") to unlock a Web Audio context for the whole session.
The sound control lives with the conversation, not in the reply composer — the composer is for composing.
10
Product analytics
2 Jul 2026
WORK COMPLETED
PostHog on web and later native: a funnel from first visit through interview to roadmap, feature-health events, person profiles.
KEY DECISIONS
Every event stamped with its environment so our own testing never pollutes real usage.
Local dev sends nothing — the key simply doesn't exist there.
09
Brand into product
2 Jul 2026
WORK COMPLETED
The azulejo compass-star became the app icon set (iOS, adaptive Android, splash, favicon), generated from a single SVG by a script.
KEY DECISIONS
One source of truth, regenerated on demand — no hand-exported icon zoo.
Apple rejects icons with alpha channels; the pipeline flattens automatically.
08
Staff tooling & gating
2 Jul 2026
WORK COMPLETED
Dev test personas and internal cross-check links, first gated by environment + a user-id allowlist, later replaced by a server-owned is_staff flag on the profiles table.
KEY DECISIONS
Feature flags belong in the database, not hardcoded into client bundles — extended testers get access with one SQL update.
The client can never write its own staff flag; column-level grants enforce it.
07
iOS to TestFlight
1 Jul 2026
WORK COMPLETED
Native builds through EAS with an App Store Connect API key (fully non-interactive), through review rejections to installable TestFlight builds; native Google sign-in, dictation, and Dynamic Island safe-areas verified on device.
KEY DECISIONS
Machine-drivable release infrastructure over click-ops: the API key lets any session cut a build.
Fix rejections at the root (an unused library referencing the photo roll was removed, not excused).
06
Deploy pipeline + environments
1 Jul 2026
WORK COMPLETED
EAS Hosting with development / staging / production environments, a custom domain, and a deploy script that pulls each environment's vars and clears bundler caches.
KEY DECISIONS
One early build silently baked the staging database into production — the fix became a permanent guard: the deploy script sources the pulled env, wipes caches, and prints exactly what it baked.
Infrastructure came after the product had earned it, then all at once.
05
The living plan
2 Jul 2026
WORK COMPLETED
Mark steps done (today or back-dated); completions re-anchor downstream deadlines to what actually happened; a free-text "something changed" box re-plans deterministically.
KEY DECISIONS
Progress is just more profile input — the engine stays a pure function.
The LLM translates free text into a profile-field delta ONLY; the diff users see is computed deterministically, never narrated from imagination.
04
Catalog expansion by webinar mining
2 Jul 2026
WORK COMPLETED
Fifteen relocation-webinar transcripts mined by five parallel agents; the catalog grew from ~20 to 54 obligations across tax, property, visas, healthcare, and citizenship.
KEY DECISIONS
Every obligation carries a provenance tag from day one, enforced by the type system.
Anything we couldn't ground was pulled to a backlog rather than shipped on vibes — invented precision (fake form numbers, made-up deadlines) got stripped.
03
Server-side LLM proxy
1 Jul 2026
WORK COMPLETED
All Anthropic calls moved behind /api/lola (Expo API route on the hosting platform's Workers runtime); the client bundle no longer contains any key.
KEY DECISIONS
Secrets live only in server env vars — a browser bundle is public by definition.
Layered, fail-open hardening: payload caps are the real enforcement; origin checks and per-IP limits are extra layers that never lock out legitimate users.
02
The Expo app + auth + storage
1 Jul 2026
WORK COMPLETED
Expo Router app targeting web, iOS, and Android from one codebase; Supabase Google sign-in; profiles saved per-user under RLS.
KEY DECISIONS
One codebase, three platforms — platform differences isolated into .native.ts twin modules Metro resolves automatically.
Separate staging and production Supabase databases so a test can never touch a real user's data.
01
The walking skeleton
30 Jun 2026
WORK COMPLETED
A deterministic plan engine (~7 obligations), a catalog-derived interview, Lola's persona prompt, and a report prototype — the whole pipeline end to end before any real app existed.
KEY DECISIONS
Model obligations, not journeys: ~100 finite atomic units generate the thousands of individual journeys for free.
Four invariants written down before features: deterministic engine, catalog-derived interview, Lola never invents facts, plan = pure function of profile.
The LLM gets exactly two bounded surfaces (phrase a question, extract an answer). Everything load-bearing is boring, testable code.
Still being written — the log grows as the work does.
Get Camino
Guidance only — not legal or tax advice.
Privacy
·
Terms
·
Aviso legal