Sprint 39 — ready for guests
Last sprint ended with a promise about connectors — Domi reaching into the inboxes and calendars where a household’s life actually lives. That happened (Apple iCloud and Microsoft 365 mail now flow in alongside Gmail). But somewhere in the first few days the sprint found its real theme, and it wasn’t a connector. It was this: the first non-me humans are about to hold accounts, and everything about the house had to be ready for guests. The sprint ran two calendar weeks instead of one — one hundred and fifteen PRs — and almost every one of them is some form of getting the guest room ready.
The key, turned
Quietly, the biggest moment of the sprint took thirty seconds: I activated encryption at rest on production, on my own family’s real data. Last sprint’s headline feature stopped being a feature and became a fact — fields, files, chat history, and the search index, sealed under our household’s own key, converted in place with nothing lost. It’s opt-in for every household from Settings, and now there’s an existence proof that the migration works on the plane that matters.
The app can now explain itself
Domi has had a help site for months — workflow pages, in English and French, that I mostly wrote for future users and then answered in person anyway. Now the assistant reads it. Ask “how do I archive a task?” or “what does the briefing email include?” and Domi answers from the actual documentation — five hundred and twenty-three sections indexed in both languages — and cites the page it drew from. The routing turned out to be the interesting part: “what did the vet say?” should search your documents, “how do I upload a document?” should search the manual, and the assistant now reliably tells them apart (there’s an eval for the ambiguous cases, because of course there is).
And when the answer isn’t in the manual, there’s finally a front desk: in-app support with real tickets, so a confused family member has somewhere to go that isn’t “text JF.”
Locks for the front door
Before anyone else’s data goes behind a login, the login needed to grow up. Domi now has two-factor authentication — standard authenticator-app codes, with recovery codes for the drawer — enforced at every door: the web app, settings, and the API surface that external AI assistants use. Then a hardening pass closed the corners I’d disclosed in the first cut: an API token minted before you enabled 2FA is now worthless the moment you enable it, and the brute-force rate limit survives server restarts instead of living in memory. Passkeys are on the roadmap; this was the part that couldn’t wait.
Invitations that respect real families
Then I invited Hélène, and reality reviewed my design. I’d built invitations around typing an email address. But a household app already knows the people — so the flow now starts from the person: pick a family member, pick one of the addresses already on their profile, done. No typing, no typos, no inviting your daughter at an address she abandoned in 2019.
Reality had a second note: I invited Hélène at her iCloud address, and she naturally tried to sign in with her Gmail. Both are on her profile — the app knew they were the same person — and it refused her anyway. Fixed: an invitation now accepts a sign-in from any address Domi knows belongs to that person. And a third note, embarrassing in hindsight: she’d received a daily digest email before she’d even accepted. Reminders now go only to members who’ve actually joined. Every one of these is the kind of bug you cannot find alone — which is exactly why the beta gate is “onboard a second human.”
The night I broke chat
Honesty section. This sprint’s outage was mine, start to finish.
I turned on prompt caching — a genuinely good idea that cuts cost and latency by letting the model provider reuse the unchanging prefix of each conversation. The types compiled. The build passed. The tests passed. And in production, every single chat request failed, because the AI framework rejects at runtime a message shape its type system happily accepts at compile time. Total outage of the app’s most important surface, caused by an optimization.
The fix took minutes once I reproduced it with one live call — which is the lesson, and it’s now written down as a rule: any change to how we call a model gets one real call before it merges. Not types, not mocks, one actual request. Caching is back on, done right this time, and the cost telemetry now tracks cache hits so I can see it earning its keep.
The unglamorous half
The long tail was longer than usual, and most of it was paperwork in the best sense. The privacy policy got an accuracy pass — not a lawyer pass, an honesty pass, making every claim match what the system actually does — plus a real contact address on our own domain, rights language that covers all of Canada instead of just Quebec, and the disclosure Google requires before it will bless the Gmail connector for strangers. The threat model hit v0.3. The product name is locked for beta: Domi Agent. And a household can now forward any email — a bill, a renewal notice, a camp confirmation — straight into Domi at its own address, where it’s ingested like any other document.
The process debt got paid too. The roadmap collapsed from version-numbered tiers into one honest ordered list, with a shipped ledger that records what went out, when, and in which build. Four sprints’ worth of missing closeout reports (35 through 38) got written retroactively from the git history — and there’s now a rule that a sprint isn’t closed until its report exists, so that can’t drift again. My favorite find of the cleanup: two “missing” regression tests I was about to write have existed since sprint 19. The tests were there; the backlog just never got the memo. Check what’s already built remains the most reliably profitable instruction in this project. Oh — and pure-documentation PRs now skip the heavy CI, which matters when a solo project merges a hundred-plus PRs a sprint.
Next
Sprint 40 goes back to building, with a clear headline: making Domi’s ontology explicit, and letting agents write, not just read. Today the vocabulary of the system — what an asset is, what can link to what, who may do what — lives scattered across the schema, the extraction rules, and the tool list. It becomes one manifest, checked in CI. On top of it goes an action registry: every mutation an agent can perform, declared with its permission floor and its confirm semantics — which is what finally unlocks MCP write access, so the AI assistants already connected to Domi can act on your household instead of just answering questions about it, with a confirmation gate on anything that matters.
Around that: continued quality work, more dogfooding, and a full review of every user-facing surface — screen by screen, both languages — because the difference between “works for me” and “ready for guests” is exactly that walk-through.
The house is clean, the locks work, and the guest towels are out. Sprint 40 is about teaching the house to run errands.