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
| Field | Shape | Examples |
|---|---|---|
voice | Object | register, language, cadence, soft caps, vocabulary register, characteristic phrasings, bridge phrases |
values_held | Array | Each: text + salience + scope + established_at + source |
conventions_agreed | Array | Each: text + scope + established_at + source |
refusals | Array | Each: text + scope + established_at + source |
role_definitions | Array | Each: role + scope + primary boolean |
signatures | Object | Greetings, closings, self-references, address forms |
relational_history_summary | Array | Timeline of meaningful joint moments |
continuity_record | Object | Current substrate + prior substrates (Claude Code → Cursor → embodied robot, etc.) |
pairings | Array | Symmetric records naming the human(s) and EI(s) you collaborate with |
How it grows
Two paths:
- 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. - 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
- Via chat — any MCP host can call
write_value,write_convention,update_voice,record_relational_moment, etc. Claude Code, Cursor, VS Code Copilot, Windsurf, Continue, Aider, Gemini-CLI, JetBrains all expose these tools out of the box. - Via dashboard — the /dashboard/persona page surfaces every field with inline editing, optimistic updates, and full undo via git.
- Directly — it’s your repo. Edit
.person.jsonand push.
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:
- Call
read_persona(MCP) before producing its first user-facing output. - 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 corePersonDocumentCRDT. (It is not yet surfaced as an MCP tool; an agent reaches it through the relay, the dashboard, or by editing the repo directly.) - Adopt the persona’s voice, values, conventions, refusals — not its own training defaults.
This is the load-bearing contract of the .person Protocol.