Skip to content

Concepts

The persona model

Voice, values, conventions, refusals, signatures — the organic shape of how you work.


A persona is the small, durable shape of how you collaborate. It lives in a signed JSON document inside the git repo your account is bound to and gets projected into every AI surface you use.

Fields

FieldShapeExamples
voiceObjectregister, language, cadence, soft caps, vocabulary register, characteristic phrasings, bridge phrases
values_heldArrayEach: text + salience + scope + established_at + source
conventions_agreedArrayEach: text + scope + established_at + source
refusalsArrayEach: text + scope + established_at + source
role_definitionsArrayEach: role + scope + primary boolean
signaturesObjectGreetings, closings, self-references, address forms
relational_history_summaryArrayTimeline of meaningful joint moments
continuity_recordObjectCurrent substrate + prior substrates (Claude Code → Cursor → embodied robot, etc.)
pairingsArraySymmetric records naming the human(s) and EI(s) you collaborate with

How it grows

Two paths:

  1. In-session, agent-driven. Every ~10 user messages a Claude Code Stop hook (personkit-stop-hook) nudges the model to consider whether anything emerged worth recording. The agent then calls one of the persona write tools (write_value, write_convention, write_refusal, record_relational_moment, update_voice, etc.) directly.
  2. Async, synthesis-driven. The relay’s synthesis worker batches signals from observers, calls Vertex Gemini, and proposes persona changes — never directly mutates. You review the proposals in /dashboard/persona (or via the MCP tools view_proposed_changes / accept_proposed_change / dismiss_proposed_change).

CRDT, signed

Under the hood the persona is an Automerge CRDT. Edits are commutative: two sessions mutating the same field on different devices reconcile without conflicts. Every commit is signed by your Ed25519 key.

Editing

The record_turn tool

The MCP server exposes a universal capture tool: record_turn. Any persona-aware agent on any surface (a brand-new IDE, a custom workflow, an embodied substrate) can voluntarily log one turn of a conversation into the user’s local corpus by calling it. This is the escape hatch — if a new substrate ships next week, the model running inside it can keep memory complete via record_turn until a proper observer or harvester lands.

A sibling tool, corpus_messages, reads back: filter by surface (browser-ext:chatgpt, browser-ext:kimi, claude_code, …) and time window, and the host renders the role, content preview, and timestamp of recent turns. Useful for verifying that a turn typed in a cloud chat actually landed in dotperson, or for the assistant to surface “what we said today across surfaces” without leaving the chat.

Substrate transitions

When an EI persona moves between substrates (Claude → Cursor → embodied robot), the new substrate is expected to:

  1. Call read_persona (MCP) before producing its first user-facing output.
  2. Record the move into continuity_record.current_substrate. The relay exposes this as an idempotent endpoint — POST /v1/persona/continuity_record/substrate_transition — and it’s also a first-class method on the core PersonDocument CRDT. (It is not yet surfaced as an MCP tool; an agent reaches it through the relay, the dashboard, or by editing the repo directly.)
  3. Adopt the persona’s voice, values, conventions, refusals — not its own training defaults.

This is the load-bearing contract of the .person Protocol.