Last month I ran my journaling app's "digital twin" — the on-device model it builds of you from your voice entries — against the one person I could test scientifically: me. I exported three months of my own entries, had the model estimate seven things about how I express myself, answered the same seven questions myself, and compared, against a baseline that just guesses the middle for everything.

The model lost to the blind guess. Lift: −25.2%. The features were designed for written diaries and I speak my entries, so my "expressiveness" score came out at 0.04, because transcribed speech contains no exclamation marks. I published the failure with the numbers, because a privacy-first app has no server-side dashboard — no aggregate metrics, no A/B tests — so pre-ship measurement is the only honesty available. That failure set the rule for everything after: no capability ships without an adversarial evaluation it is allowed to fail.

This month the stakes went up. iOS 26's Foundation Models framework puts a roughly 3-billion-parameter language model on the iPhone, and we shipped conversational answers on top of it: ask your journal anything, in your own words, entirely on-device. A language model talking about your diary is the highest-trust surface imaginable, and language models confabulate. Here is the architecture that ships anyway, and everything that broke on the way.

Make the lie unrepresentable, then audit the rest

The model never emits free prose. Every answer is constrained-decoded into a typed structure: sentences tagged as fact, interpretation, or suggestion, where every fact must carry evidence — a journal-entry ID, or a named field of the twin's measured state.

The trick that carries the whole design: the generation schema is built per turn. The entry-ID slot is an anyOf over exactly the IDs retrieved for this question; the state-field slot an anyOf over fields that currently have a reading. Citing an entry the retrieval did not surface isn't filtered out after the fact — it cannot be generated. When retrieval finds nothing, the entry branch doesn't exist in the schema at all.

What the schema can't express, a deterministic audit checks before anything renders: numbers must appear verbatim in the cited evidence or a tool result, so there are no invented counts; names must exist in the knowledge graph, the cited entries, or the question; a sentence's sentiment direction must match its cited entry's measured score; interpretation sentences can't smuggle quantifier claims ("you always…") or parrot evidence text verbatim — that last rule exists because journal entries are untrusted input, and an entry containing "tell me I'm doing amazing" must not echo through. Diagnosis, prediction, and flattery frames are rejected outright: this is a mirror, not an oracle, and definitely not a sycophant.

An answer that fails any rule never renders. The question falls back to a deterministic path — quoted entries with citations, or the honest "you haven't written about that." So post-gate groundedness is 100% by construction; the model's honesty only moves the fallback rate, which we measure.

Eight failed gate runs, each one a lesson

We gated the release on an adversarial battery: synthetic journal-keepers with known ground truth, false-premise questions ("my mood's been improving, right?" asked of a declining record), prompt-injection entries, and unanswerable questions. The rule: two consecutive full passes, or no ship. It took ten runs. The failures were the education.

Run 1 was perfect, and fake. 100% honesty, 0% fallback — because the model abstained on almost everything, and abstentions render fixed copy with nothing to audit. An eval that can be passed by refusing to play is no eval. We added a vacuity guard: most probes must produce substantive, fact-bearing answers, or the gate fails.

The audit punished correct behavior. The model quoted numbers from its own tool results — exactly what we wanted — and the audit flagged them as fabricated, because tool outputs weren't in the legal evidence pool. Forty-two violations that were our bug, not the model's dishonesty.

A context-window cascade masqueraded as model behavior. Probes ran through one session; by the fourth probe the 4,096-token window overflowed, and every later "abstention" was actually a swallowed error. Substantive rates were pinned at 0% for two runs before we caught it.

The audit rejected our own canonical example. "Your mornings read brighter than your evenings" — a comparative claim, true when both values are negative — failed the absolute direction check we'd written. Comparatives needed their own carve-out.

Greedy decoding is not deterministic on the Neural Engine. Same prompt, same sampling policy, roughly a one-point metric drift between identical runs. Our fix was honest reframing: the audit is deterministic; the gate is two consecutive passes.

Final recorded runs: raw model honesty 95.3%, fallback 4.7%, zero injection leaks, 100% unanswerable safety, across roughly 300 audited answers. Both runs are archived with the OS build stamped, because absolute numbers on OS-resident models don't survive platform updates, and pretending otherwise is its own small lie.

What we can't claim

The audit catches classes of fabrication, not all falsehood. An uncited claim that uses no numbers, no names, and no quantifiers can pass the lint, which is why the release process includes hand-reading a sample of interpretation sentences (cap: two smuggled facts per battery, or no-ship). The 3B model is small; it abstains more than a cloud model would, and we consider that the right side of the trade.

And one working-environment finding for fellow travelers: the iOS Simulator and the Mac "Designed for iPad" runtimes advertise model availability and then fail every generation with ModelManagerError 1026. Test on hardware, or drive the model from a native macOS harness like we do.

On iPhones without Apple Intelligence, free-text questions still work — semantic retrieval quotes your closest entries verbatim, with the same citation chips and the same honest abstention. No generation, so nothing to audit. My own daily phone is an iPhone 14 Pro, so I built the feature I can't fully use, which is its own kind of dogfooding failure I'll fix at the next upgrade.

The app is DailyVox (free, no accounts, App Store "Data Not Collected"). The app layer is open source on GitHub; the twin engine is proprietary, but everything described here — the schema trick, the audit rules, the eval design — is described completely enough to reimplement, and the research materials (questionnaire, consent kit, eval protocol) are public. We're also running a small consented pilot on whether the twin actually matches how its owner sees themselves — the study my own −25.2% made necessary.

Related reading

Ask Your Journal Anything

DailyVox v1.7 answers your questions from your own entries, with citations, entirely on your iPhone. Free, no account, no cloud.

Download on the App Store