Keystone
The app that taught me what not to build
Keystone was supposed to be the app. The single surface for calendar, health, reminders, notes, and life design. A unified dashboard for everything important, powered by Claude, built entirely in Swift.
It was the wrong idea. And I'm glad I built it.
What Went Wrong
The core mistake was trying to replace Apple's apps instead of working with them. Every "integration" was actually a full app rebuild:
Calendar views — EventKit gives you data, but rendering a calendar UI that feels native is thousands of lines of SwiftUI. Apple Calendar already does this. I was building a worse version of something people already have.
Notes editing — Rich text editing in SwiftUI is brutally limited. Apple Notes has a decade of polish. No amount of engineering was going to close that gap.
Reminders management — Lists, priorities, recurring items, location triggers. The overhead of matching Apple Reminders' features was enormous for zero marginal value.
The scope kept expanding because each feature was secretly an entire app. There was no definition of done because there was no clear boundary. I was building floor 3 while floor 2 had holes — exactly the kind of thing I now flag in other projects.
What Was Actually Good
Not everything was wasted. The weekly review — rating life domains, setting next week's focus, tracking patterns over time — that was the right idea in the wrong container. The journal with mood tracking, photo attachments, and a Claude integration button? That was ahead of its time.
And several services proved their value and got extracted:
ClaudeService — A clean Claude API client with tool use, streaming, and prompt caching. Now the foundation for SONET's API mode.
CalendarService — Protocol-based EventKit bridge with proper error handling and permission management. Pulled into SONET v2.
ReminderService — Same pattern. Same destination.
The protocol-based architecture — CalendarServiceProtocol, HealthServiceProtocol — was well-designed. The code was sound. The product vision was wrong.
The Theme System
One thing that shipped cleanly: the dynamic color system. Pick a hue, get a full palette — Primary, Accent, Success, Warning, Error — all derived mathematically. Deep Ocean gives you blues and teals. Evergreen gives you greens. Golden Ember gives you warm ambers and reds.
This entire system was extracted into BackboneKit. Every project in the ecosystem now uses it. That's probably Keystone's biggest lasting contribution — a theme engine that makes every new app look intentional from day one.
The Lesson That Changed Everything
The insight that came out of Keystone's failure is now the thesis behind everything I build:
Wrap around your life. Don't ask people to rebuild it.
People's calendars are already set up. Their notes have years of content. Their reminders have location triggers they configured once and forgot about. Any app that asks them to move all of that — or maintain it in two places — is dead on arrival.
SONET took the exact opposite approach: read from Apple's apps, enhance the data with Claude, write back to Apple's apps. The user never leaves their existing workflow. No migration. No dual-maintenance. The intelligence layer is invisible.
That philosophy only exists because Keystone tried the other way and hit a wall.
What Survived
BackboneKit — the security module, theme system, and platform utilities — was originally built for Keystone. Now it's shared infrastructure used by everything.
The research docs on product philosophy, Apple API capabilities, and integration design all live in the Research library. Thirty-seven documents of institutional knowledge, and a good chunk of it was earned the hard way during Keystone.
The repo's archived. No new commits. But its DNA is in everything that came after.
The full tour — from onboarding to themes. Scroll to browse.
What's the project you abandoned that ended up teaching you the most?