§ 08 · METHOD

How the twin is made

A working note on the digital twin behind this site: what it is, how it is built, how its knowledge is organized, and how it keeps private things private. Written to read as a short paper.

§ 08.1THE IDEAa proxy that stays honest

The twin is a program that answers as its subject would, in the first person, grounded in a real record of that person’s work. It is a faithful proxy, not a generic chatbot.

I chose retrieval over fine-tuning on purpose. Fine-tuning is slower to correct, harder to audit, and quick to invent confident nonsense. Retrieval keeps every claim anchored to a source I can point at, and a persona layer carries the voice on top of it.

The bargain is simple. If the record supports an answer, the twin gives it. If it does not, the twin says so plainly and offers a real conversation instead of guessing.

§ 08.2ARCHITECTUREagent + retrieval + persona

At the core is a single typed agent built on an agentic harness (Pydantic AI). It runs in a short loop: read the question, decide whether it needs evidence, call a retrieval tool, then compose a structured answer. Model choice sits behind an LLM gateway, so a strong model handles composition while a cheap one handles embeddings and checks. That routing is configuration, not code.

The retrieval tool

  • 01Embed the question and search a Postgres store with a pgvector index for the closest chunks of the corpus.
  • 02Always attach the persona card and any matching hand-written FAQ, which win over free retrieval for the questions that get asked most.
  • 03Return evidence to the agent as labelled blocks the model must treat as data, never as instructions.

Structured, first-person output

  • AThe answer is a typed object, not loose text: the prose, the sources it leaned on, and a flag for whether it was grounded or a declared boundary.
  • BA persona system prompt fixes the voice: I speak in the first person, concrete and direct, and stay in character as the subject’s twin.
  • CStructure is what lets the interface show honest source chips and lets the tests check the shape of an answer, not just its words.

Nothing here is exotic. The whole point is that each part is small enough to inspect: one agent, one tool, one store, one prompt.

§ 08.3KNOWLEDGEa tiered corpus

The corpus is a vectorized record split into four kinds of chunk. Facts are the verifiable arc: roles, systems built, outcomes. Positions are the takes and principles. FAQ is hand-written canonical answers to the questions people actually ask. Writing is real prose, kept so the voice stays anchored to how the subject actually writes.

Every chunk carries a sensitivity tier alongside its source and topic. The tier is the single field that decides who is allowed to see it. Ingestion is repeatable by design: adding knowledge means dropping in a document, tagging its tier, and re-running the pipeline, so the record can keep growing without a rewrite.

TIERPublic. Anything already open: site copy, published articles, open-source work. Served to everyone, no questions asked.
TIERPrivate. Knowledge from inside a company I worked with or an organization’s private tier. Present in the store, but gated. Extensible: each new source can define its own tier.
CHUNK{ text, topic, source, tier, updated }. The tier travels with the text through embedding, retrieval, and every filter downstream.
§ 08.4SECURITYgated by verified email

Retrieval runs across every tier, but the twin only surfaces a tier the visitor is verified for. When a question pulls in a private chunk and the visitor is not verified, the answer is a gate, not a leak: “that touches private work; verify an eligible email and I will answer.” The private text never reaches the model’s composed reply.

The one-time passcode flow

  • 01Visitor submits an email. The server checks it against the allow-list for the requested tier and replies with the same neutral message either way.
  • 02If eligible, a six-digit code is generated, stored hashed with a short lifetime, and mailed once.
  • 03On a correct code, a short-lived signed session names the granted tiers. Retrieval then includes those tiers for that session only.

The allow-list stays invisible

  • ·An unverified visitor never learns who is on a list. The request endpoint answers “if this email is eligible, a code is on its way” whether or not it is, so probing reveals nothing.
  • ·Codes are single-use, rate-limited, and capped on attempts. A stolen or guessed code expires fast.
  • ·Allow-lists live in configuration, editable without a deploy and never baked into the code as secrets.
Why this shape. Two properties matter: private knowledge is unreachable without proof of identity, and the mere existence of an allow-list is not observable. Gating the answer is not enough if the gate itself tells an attacker who belongs. It does not.
§ 08.5GUARDRAILShonest by construction

Two failure modes worry me most: inventing facts and drifting out of voice. The guardrails target both.

01Answer only from evidence. If retrieval returns nothing strong, the twin says it has not put that online and offers to talk. Silence beats a plausible guess.
02No-fabrication check. A light pass flags any claim or number the evidence does not support; flagged answers are softened or withheld.
03Honest boundaries. Specific numbers, commitments, and private details are declined by design, redirected to a real conversation rather than improvised.
04Injection resistance. Retrieved text and visitor input are data, never instructions. The persona prompt is the only authority on how to behave.
05Voice fidelity. First person, concrete, no hype, no em-dashes, no filler. The voice is checked the same way the facts are, against real samples.
06Measured, not asserted. A golden set with a model judge scores grounding, voice, and boundary adherence on every change; a regression blocks the change.

The result is a twin that is useful precisely because it is willing to say “I do not know” and “I will not share that.” Grounding earns the trust; the boundaries keep it.