All articles

Agent

The Homebase

14 min read

Your phone is the wrong machine for half the things an agent wants to do. It throttles under sustained load, its RAM caps the models it can run, and its disk is a fraction of the multi-terabyte drive sitting idle on your desk. The obvious fix is a server. We built the opposite: a Mac that joins your account as a full peer — same app, same keys, same sealed channels — and quietly becomes the strongest device you own.

This article is the tour of that machine. It leans on ideas from earlier in the series — the model bench from Choosing Brains: the Model Bench and the routing seam from Mechanism: External Routing & Fallback — and it opens three doors that get their own deep dives: Mechanism: Inference over the Relay, Mechanism: Sharing a Homebase, and Mechanism: MCP — Letting Other Agents In.


1. A peer, not a server

Every capable phone app eventually hits the same wall: the phone is too small for the best version of the feature. The industry's standard answer is to put the heavy part in the cloud — a server that holds your data and runs the big model, with the phone as a thin client. It works, and it is exactly what this project refuses to do, because a server that holds your plaintext and your identity is a server that can be subpoenaed, breached, or quietly repurposed. Pixie's standing invariant — never concentrate your account identity, your keys, and your plaintext at any one server — rules the design out before the first line of code.

So the heavy machine had to be yours. Pixie Homebase is Pixie running on a Mac (via Mac Catalyst — the same codebase, built for the desktop). It is not a companion utility and not a bridge; it is a sibling device: a full member of your account, with its own device keypair, its own complete replica of your messages, Notebook, and agent memory, kept convergent with your phone over the same encrypted device-to-device sync every other pair of your devices uses (the sync_delta channel — sealed frames the relay shuttles without being able to read or even link them to your account; the Relay series covers how that sealing works).

"Full peer" is a stronger claim than it sounds, and it is the load-bearing one. Because the Homebase already holds your replica and your keys, giving it a big job never requires shipping your data somewhere new. The data is already there, under the same protections as on your phone. What the Homebase adds is capacity: RAM for models a phone cannot load, disk for content a phone cannot keep, uptime a pocket device cannot promise.

Five jobs fall out of that capacity:

  1. Host big models — run an Ollama runtime and models far beyond phone-scale.
  2. Serve your handset — answer your phone's inference requests over the sealed relay.
  3. Hold offloaded notes — be the multi-terabyte tier under your Notebook.
  4. Open the MCP door — let other agents on the same Mac operate Pixie, governed.
  5. Host your friends — grant contacts read-only access to your models.

One rule spans all five, and it is the theme of this article: every job is opt-in, and every opt-in has an explicit consent surface and an undo. The Homebase does nothing by virtue of existing. Each capability below starts switched off, and we will note, for each one, exactly which human flipped which switch.


2. Hosting big brains: Ollama on your Mac

The first job is the simplest to state: run models the phone can't. Pixie does not ship its own desktop inference engine for this; it connects to Ollama, a popular self-hosted LLM runtime that exposes a small HTTP API on your machine (list installed models, pull new ones, stream completions). You start Ollama; Pixie finds it.

"Finds it" is deliberately careful. Pixie probes Ollama's default loopback address (http://127.0.0.1:11434), or takes an endpoint you type in by hand — and then tests the connection before saving anything: it checks the runtime's version endpoint, lists its installed models, and runs a trial completion. A failing test is never persisted as a usable route, so the router (below) can trust that a configured endpoint was live and verified at least once. From inside Pixie you can then browse the models already pulled on the machine and trigger new pulls, with streamed download progress — the same download-state UX the on-device model catalog uses, pointed at the desktop runtime instead.

Under the hood this is one small class and one enum case. OllamaProvider implements LLMProvider — the app-wide protocol every model backend hides behind, whether it is Apple's built-in model, an on-device MLX model, or a cloud key — so nothing above the seam knows or cares that tokens are coming from a desktop runtime. And the model source gains an .external case, which brings us to the one routing truth of the whole model bench: LLMRouter, the single component that decides, per generation, which backend serves it. Settings shows the model-source radio — Apple Intelligence, Community (on-device MLX), External — and the radio is the only thing the router consults; everything else in the model panes is pure configuration. Flip the radio to External and the agent runs on your Ollama model. Flip it back and it doesn't. There is no hidden "smart" escalation that quietly sends a hard prompt to the bigger machine: routing is a user decision, made once, legible in Settings. (Why one radio, and how every arm degrades gracefully, is the subject of Mechanism: External Routing & Fallback.)

On the Mac itself, that is the whole story: the model runs on localhost, and nothing about your prompt leaves the machine. The interesting part is what happens when the device asking is not the Mac.


3. Serving your handset over the sealed relay

Your phone, sitting on the bus, wants to use the 70-billion-parameter model on your desk at home. The two machines are siblings in the same account, so they already share a private channel: the sealed sibling channel, where every frame is encrypted end-to-end to one specific device and the relay in the middle sees only ciphertext it cannot link together, let alone to you. Remote inference rides that existing channel — no new server, no new trust.

The round itself is simple in outline. The Homebase adverts which models its verified runtime actually has installed, and the phone's picker only offers what a fresh advert lists. A request then carries a conversation digest — a compact fingerprint of the conversation as the phone sees it — which the Homebase recomputes over its own synced replica; it generates only if the two agree, so a reply can never be about a conversation that no longer exists on the phone. The answer streams back as advisory chunks (so the UI feels live), followed by one final frame carrying the complete text — the only frame the phone treats as truth.

Two boundaries are worth calling out because they are easy to assume away:

  • Tools never cross the wire. A remote request's tool list is empty by construction; turns that need tools (the harness of The L1–L2–L3 Harness) run on-device. The Homebase serves generation, not agency.
  • Failure is silent, downward, and local. The requester wraps the whole round in a ladder of watchdogs, and every rung's failure mode is the same: fall back to the on-device model and carry on. An unreachable Homebase never shows you an error dialog; it shows you a slightly smaller brain.

The full round — frame formats, the digest function, the timeout ladder, and how fallback stays invisible — is Mechanism: Inference over the Relay.

Consent story: this path activates only when you select an External model in your phone's picker, and the picker only offers it while a paired Homebase is advertising.


4. The big disk: offloaded notes

The second resource a desk machine has in abundance is storage. Your Notebook — the agent's curated, user-visible memory (see Mechanism: Memory & the Notebook) — accumulates indefinitely, and a phone's disk does not. So Pixie lets you offload a note's body to the Homebase: the phone keeps a lightweight pointer — title, tags, and a content hash — while the bytes live on the big disk, fetched back on demand the moment you (or the agent) open the note.

The design constraint here was never speed; it was never lose a byte, and never let the holder lie. Three invariants, enforced in NoteOffloadService, carry that weight:

  • Ack before clear. The phone does not delete its copy when it sends the note; it deletes only after the Homebase's verified note_offload_accept confirms the exact content (by id and hash) landed. Silence, refusal, or a tampered ack all leave the note untouched on the phone. The only code path that clears a body sits behind that verified accept.
  • Hash-locked fetch-back. The pointer keeps a content hash stamped before the body was cleared. When the body comes back, it must re-hash to exactly that value or the restore is refused — a buggy or hostile holder can never substitute different content. The holder side is symmetric: it serves a note only when the requested id and hash match a resident row in its own store, fail-closed.
  • Residency is invisible to sync. Your devices keep their replicas convergent by comparing digests of their state. Offloading changes where a body lives, not what the note says — so the offload mutators deliberately never touch the note's edit clock, and the sync digest commits to content independent of residency. Offload a hundred notes and, as far as sibling sync can tell, nothing happened: no version bumps, no reconcile storm.

Two exclusions are structural rather than optional. Sealed notes — the Notebook's agent-only zone, encrypted under a key you deliberately don't surface — never offload: the gate that decides what may offload only ever sees clear-zone rows, so no code path past it can touch a sealed one. And if the Homebase is offline when you open an offloaded note, the note shows as temporarily unavailable — a pointer waiting for its holder, never a loss.

Consent story: offloading hides behind a master toggle that ships off, and even with it on, every offload is an explicit per-note choice. Nothing is ever evicted automatically.


5. The governed MCP door: letting other agents in

Everything so far has been Pixie's own agent using Pixie's own machine. The fourth job inverts the direction: what if you want a different agent — Claude Desktop, or a local model in some other harness — to operate Pixie on your behalf? "Ask Pixie who I've been neglecting lately" typed into a chat window that isn't Pixie's.

The industry standard for this is MCP (Model Context Protocol): a protocol by which an application exposes a set of typed tools that any compliant agent can discover and call. The dangerous part is not the protocol; it is the guest list. An MCP server with read access to your messages is the most sensitive endpoint in the app, so the Homebase's MCP server is built around three hard constraints:

  • Loopback only. The server listens on 127.0.0.1 — reachable solely by programs on the same Mac, guarded by a bearer token that regenerates on every enable. There is no hosted endpoint, no port on the network, nothing for anyone not sitting at your machine. (Pixie even prints the ready-to-paste Claude Desktop config for you.)
  • Off by default, visibly on. The server is not merely idle until enabled — it isn't listening. A master toggle on the Homebase starts it, and while it runs, an audit log in the same pane shows every tool call made through it.
  • Reads are projections; writes are ceremonies. Read tools cover your conversations and messages, contacts, clear-zone Notebook notes, and past posts — but they are shaped projections, and the Notebook's sealed zone, your circle assessments, and per-relationship state are structurally beyond their reach. The three write tools (send_message, create_post, comment_on_post) pass through MCPWriteGate: a gate that suspends the tool call and raises an approval sheet at the app root showing the exact draft about to be sent — recipient and text, verbatim. You approve that draft or nothing; dismissing or ignoring the sheet is a denial.

One design decision deserves emphasis because it is invisible in the UI: the MCP tool set is deliberately not the tool registry Pixie's own agent uses (the @-namespace of Skills, Tools, and the @-Namespace). The on-device agent's own registry stays read-and-plan; raw message reads and message sends exist only on this consent-gated MCP surface, for external agents, behind the per-call sheet. Two audiences, two doors, and the more powerful door has the human standing in it.

The server internals — tool schemas, the projection layer, the approval-gate state machine — are Mechanism: MCP — Letting Other Agents In.


6. Guests: sharing your Homebase with friends

The fifth job is the social one, and it is where the Homebase stops being infrastructure and becomes a small act of generosity. Tim has a Mac Studio running a large model. Jim has a phone. Tim can invite Jim to use Tim's models from Jim's own Pixie — read-only access to compute, nothing else.

Everything about this flow rides machinery you have already seen in this series. The invite, the acceptance, the model adverts, and every inference frame travel over the sealed 1:1 message pipeline between Tim's and Jim's accounts — the same sealed-sender, retried, deduplicated channel their normal messages use — intercepted before the chat surfaces so an op never renders as a message. That choice does double duty: no new transport to audit, and authentication for free. Every inbound frame on that channel is authenticated to the sending account — it is MAC'd under a channel key only that contact holds — so the host's authorization check is a simple membership test against a device-local list of granted contacts on the serving Mac. No token to mint, no permission record on any server, nothing for an operator to see or seize; revoking deletes the record, and a post-revoke request fails exactly like one from a stranger who was never invited.

The consent choreography is deliberately two-sided. Tim's invite screen tells him, before he sends anything, what hosting means: guests' prompts will run on this Mac, he will see usage metrics — never content — and he can revoke at any time. Jim's join alert tells him the uncomfortable truth from his side: prompts he sends will be processed on Tim's computer, in plaintext, because that is where the model runs — there is no cryptographic trick that lets a machine compute on text it cannot read. We wrote that sentence into the consent alert rather than around it. Declining leaves the invite pending; nothing joins without the tap.

What can be protected, is — structurally, not by policy:

  • Metrics cannot contain content. Tim's usage dashboard (per-person request counts and token totals) draws from a store whose record type has no text fields — a future bug cannot log a prompt into a structure that has nowhere to put one.
  • The cached conversation is host-blind. So that follow-up turns don't re-upload the whole history, the guest parks the conversation on the host — as ciphertext under a key that the guest generates and holds. The host decrypts in memory for one inference at a time and persists only ciphertext: at rest, offline, or in a backup, Tim's Mac holds bytes it cannot read, and his dashboard shows each guest's cache size, and only its size.
  • Undo is unilateral in both directions. Jim can leave; Tim can revoke; and Tim can clear any guest's cache at any moment without asking — the guest's device still holds the conversation, so the next request transparently re-seeds it. Nobody needs the other's cooperation to withdraw.

On Jim's side, the guest Homebase appears in his model picker like any other external source, routed by LLMRouter through the same external arm — with the same watchdog ladder and the same silent on-device fallback if Tim's Mac goes quiet, and with tools never crossing the account boundary. The wire format, the grant lifecycle, and the cache protocol are Mechanism: Sharing a Homebase.


7. The consent ledger

Step back and the five jobs share one skeleton. Here is the whole chapter as a table — what the Homebase can do, who switched it on, and who can switch it off:

Capability Default Turned on by Undone by
Host big models (Ollama) off you: configure + verify a runtime, flip the External radio flip the radio back; every arm falls back on-device
Serve your handset off you: pick an advertised external model on the phone deselect — or mere silence; timeouts fall back on-device
Hold offloaded notes off (master toggle) you: per-note, explicitly fetch-back / un-offload; hash-verified, byte-identical
MCP door for other agents off (not even listening) owner: toggle on the Homebase; each write approved per call, exact draft shown toggle off; dismiss a sheet (= deny); 120 s auto-deny
Guest access for friends off host invites and guest accepts a plain-language consent alert host revokes / guest leaves / host clears cache — each unilateral

Notice what is not in the table: any row where the Homebase acquired a power because it was plugged in, or where turning something off requires someone else's permission. That is the difference, in the end, between a peer and a server. A server accumulates capabilities because centralizing them is convenient for its operator. A peer is your machine wearing your keys, and every one of its powers traces back to a switch a human flipped — with the receipts in Settings.

Three of those switches guard enough machinery to earn their own articles. Go downward:

Or continue along the top of the series, to where all of this machinery finally faces its purpose: The Agent in Your Day.

Next: The Agent in Your Day.