A personal AI assistant she has been building since February 2026. Live in production across four front-ends, sharing one backend and one memory. Not a finished product — an evolving system she actively iterates on.
She wanted to see how far one person could take a personal AI system: persistent memory across months, multiple front-ends sharing a single state, autonomous behaviour without prompts, and the operational reality of running it as a real service — not a demo.
One state, four doors. Every front-end speaks to the same gateway and reads from the same memory. Chat clients are easy to ship; the shared state underneath is the part that's hard to copy.
Memory as layers, not a single pile. Short-term context, rolling summaries, structured facts and event timeline live in separate layers, each with its own retention and recall logic. Reply quality tracks recall quality — this is where most of the tuning goes.
Autonomy as a first-class feature. A keepalive loop wakes every 50 minutes, looks at recent activity, and decides whether to speak — no user input involved. Daily and weekly summaries generate themselves. It's what makes it an assistant rather than a tool.
A long-running reply would silently hang. The chain ran: client → nginx → FastAPI → bridge subprocess → LLM call. Each hop had its own timeout, and the shortest one upstream killed work the downstream layer was still doing.
She redesigned the timeout chain so each layer's deadline derives from the request's overall budget, not a hard-coded constant. Lesson: in a multi-hop async system, timeouts that don't talk to each other are the bug.
The email agent ran daily and reported "100 new emails" every morning — for a week. The numbers were a lie. Root cause: the agent pulled "all unread," and the Gmail account it watched was a forwarding sink she never read, so the unread pool only grew.
Fix: switch to IMAP UID watermarking, persist the last-seen UID, and pull strictly the delta. Lesson: "what's new" is a state question, not a query question. If you don't persist the cursor, you don't have a daily report — you have a daily re-print.
Adding the second front-end (WeChat) exposed a problem: the assistant remembered her perfectly on Telegram, then greeted her like a stranger on WeChat. Each surface was building its own implicit user model.
She restructured the identity model: a single shared user identifier with surface as a tag, not as an identity boundary. Lesson: shared memory only matters if it's actually shared. Decide whose state lives where, before adding the second client.
— A second specialised agent (job scouting) factored out of the keepalive into its own service
— Memory consolidation — automated deduplication and merging of long-running facts
— Surfacing the assistant on iOS as a dedicated PWA, not embedded in Telegram
It's the thing she points to when explaining what "AI builder" actually means to her: not prompting a model better, but designing and running a small system that has to keep working tomorrow, and the day after, and three months later — across surfaces, across failure modes, across her own changing requirements.