Anton, chapter 1: Genesis

March 7, 2026 · 4 min read

I have a simple idea: build an assistant more reliable and secure than OpenClaw, which I find frustrating and terrifying at the same time. What better use case than a family assistant that handles the complexities of running a family of 6. If I can reliably replace myself for some common chores then I've won. What's more, I have this DGX Spark sitting at home that seems like the perfect host for my new assistant. I call him Anton. In reference to the series Silicon Valley.

The day starts where I tend to start: with a contract, not code. By 09:25 the repo has a pnpm + Turborepo monorepo, TypeScript throughout, empty apps/ and packages/, an implementation plan, and a shared types package as the central contract surface. Nothing that runs. But the shape of what runs is written down first. I always do this. Agreeing with yourself on the interfaces upfront is dirt cheap; refactoring three weeks later is not.

The household

Then the household map. WhatsApp as the entry point because that's where the family already lives. The Spark over Tailscale as the host, because everything about Anton (his memory, his data, his voice) is going to be physically close to me, not in someone else's cloud. The TNAS, Plex, Transmission, the gws CLI for Google Workspace: all the things he needs to be useful. Docker Compose with three services: Postgres, WhatsApp, Worker. A deploy script that rsyncs the lot to the Spark. No staging, no laptop. I want to be in production from hour one. The real thing.

Identity as data

Then a question I've been chewing on for weeks: identity. Is Anton a tool or a character? I don't want a system prompt baked into a string somewhere in the code. I want the personality to be a document (identity.md) loaded at runtime. Anton's personality and my context as data, not code. The reason is practical more than philosophical: if I change my mind about who Anton is, or my family does, or a kid moves out, I want to edit a file, not push code. Treating context as data feels like the kind of decision that compounds.

Afternoon capabilities

Afternoon is capabilities, three commits between 16:00 and 17:30. Media first: Plex search, Transmission control. Then calendar, Google Workspace, voice transcription. I almost cut voice. I'm not sure the family will actually use it, and the day's budget is tight. In the end I leave it in, on the principle that when you have room to integrate a maybe, you integrate it. The cost of finding out is the same as the cost of guessing wrong, and the upside is asymmetric.

I also add a memory layer. Deliberately simple: Postgres rows tagged by user. No embeddings, no fancy retrieval. The rule I have in mind is to build the simplest version that lets me see what the system actually wants, then design for that. Memory will need real retrieval semantics eventually, but I don't know what shape yet, and the worst thing I can do is guess.

For the orchestration question (how the parent agent should route between domains) I pick LangGraph. It's a great choice. Structure, an observable state machine, checkpointing, a clean way to express subgraphs per domain with classify-and-dispatch at the top. Reliable, traceable, well thought out. I'm glad to have a framework that already has answers for problems I haven't yet hit.

First production bug

Then the first production bug, four hours in. WhatsApp is throwing "bad encryption" errors on incoming messages (a Baileys quirk). Five minutes reading the library, the fix is wiring getMessage for retry decryption. What I notice isn't the fix. It's that the system is real enough by mid-afternoon to throw production bugs in the first place. Stub systems don't fail like that.

Evening is orchestration. BullMQ + Redis schedule queue. And then a refactor I'm framing as a cleanup: a commit that makes WhatsApp a thin shim that enqueues jobs, and lets the worker own all the agent logic. It just feels right to keep transport-layer concerns out of the agent. Cleaner that way.

By midnight Anton can take a WhatsApp message, route it through Postgres-tracked history, dispatch to a domain, run scheduled jobs from the database, self-update via an API endpoint, and redeploy from one shell script. Usable end to end.

I go to bed satisfied. The system is real, deployed on the Spark, talking to the family group on WhatsApp, with seven domains' worth of subgraphs registered and a quiet schedule queue waiting for work. It has the shape I wanted going in: a personal assistant living close to my data, on my hardware, with a personality I can edit as a file.