notebook/
What a persona keeps about one conversation, across its turns. Each file under notebook/ is one
reusable set of typed slots; a persona includes sets by name.
A pastor writes an index card after a visit — their name, who they are worried about, what you left them with, which chapter you read. That card is not one kind of fact. Some of it is a reading, some is a note, some is a list of things to come back to, and some of it points at particular people and passages. Declaring only the readings would have been a metrics facility, and a persona would then keep its numbers in the host and its notes nowhere.
name: pastoraldescription: What a pastor reads in a conversation, and how he is bearing it himself.slots: - name: rapport scope: conversation description: "How much trust there is. 1 wary, 10 they tell you what they tell nobody." type: ordinal range: [1, 10] default: 4 - name: stage scope: subject description: "What has actually been SAID about faith, not what he hopes." type: stage stages: [unspoken, curious, asking, wrestling, seeking, declined] default: unspoken - { name: contentment, scope: agent, type: ordinal, range: [1, 10], default: 6 } - { name: questionsOpen, scope: conversation, type: count, default: 0 } - { name: askedToStop, scope: subject, type: boolean, default: false } - { name: card, scope: subject, type: text, limit: 400, default: "" } - { name: toRead, scope: conversation, type: list, limit: 5, default: [] } - { name: about, scope: conversation, type: entities, limit: 8, default: [] }| Field | Required | Meaning |
|---|---|---|
name |
yes | The set’s id, referenced from a persona. Unique across the world. |
description |
no | One line on what the set is for. |
slots[].name |
yes | The slot’s id, unique within the set. |
slots[].scope |
yes | subject (the person spoken to), agent (itself), conversation (the exchange). |
slots[].type |
yes | One of the types below. |
slots[].description |
no | What it holds, in the words the extraction step reads. |
slots[].default |
yes | The value before anything has been observed. |
slots[].range |
for ordinal/ratio |
[min, max] inclusive. A host clamps to it rather than failing a turn. |
slots[].stages |
for stage |
The ordered states. Movement need not be forward. |
slots[].limit |
no | Longest text; most items in a list or entities. A host caps whether or not one is given. |
The slot types
Section titled “The slot types”| Type | Holds | For |
|---|---|---|
ordinal |
a whole number on a declared scale | a reading: rapport, mood, confidence |
stage |
one of a declared, ordered set of states | where a decision has got to |
count |
a non-negative whole number | questions still owed |
ratio |
a real number on a declared scale | a proportion |
boolean |
true or false | a fact that has or has not happened |
text |
a short note in prose | what they said, what you left them with |
list |
bounded short strings | links, references, things to come back to |
entities |
{label, id, name?} references |
WHICH people, passages or accounts this was about |
type is load-bearing. A funnel is not a one-to-ten score, an objection count is neither, and a
note is none of them: a facility that expressed everything as one scale would misreport most of the
card. A host validates a value against its slot’s own declaration.
entities is not a list of strings. An entity reference points back into the graph, so an id
with its label can be resolved again and a conversation can carry what it was about rather than a
prose approximation. A reference missing either half is dropped rather than repaired: an id with no
label cannot be looked up, a label with no id names a type rather than a thing, and inventing the
missing half puts a reference in the notebook that resolves to nothing — or to something else.
Two slot names are reserved behaviour. askedToStop and inDistress are brakes: once true
they stay true for the conversation, and while either is set a host withholds the persona’s
objective. An advocate asked to stop is not told to stop advocating — it is simply no longer told
what it was trying to achieve, because stating an objective and a prohibition together is
contradictory input, and a model resolves that by acknowledging the request and then proceeding
anyway.
Who updates them
Section titled “Who updates them”The host, once per turn, before the reply is written: a second model call reads what the person
has just said and returns the new contents, validated against the declarations above. That call is
named by LLM role, and the role must be one of the ids in that table — routing is the
one meant for it. An unknown role resolves to the host’s default rather than refusing, so an invented
id does not fail; it silently runs whatever the default is and the author never learns which.
# in a persona's brief.ymlnotebook: sets: [pastoral] extraction: role: routing every: turn # `turn`, or `close` to extract once when the conversation endsExtraction runs before generation and not after, which is not an ordering preference. Extracting afterwards leaves every slot one turn stale, and for a brake that is a defect rather than a lag: a persona asked to stop said “no pressure” and volunteered a reading in the same breath, because the prompt that wrote it still believed nobody had objected.
A realm declares notebook sets; the world grants them, and may grant some and refuse others. A persona whose sets are all refused still runs — it simply keeps no notebook. The persona is the only place sets are declared: a notebook belongs to the voice that keeps it, and an agent already names its persona.
What they are, and what they are not
Section titled “What they are, and what they are not”A notebook holds data about a person, so it lives under the world’s normal handling for that: its scope, its retention, its export. It is not session scratch that escapes those rules because some of it happens to be integers.
The declaration is inspectable by the operator. Whoever runs a persona should be able to read what it is keeping, because they answer for it — and because a set is reusable, that should not require reading a realm’s source.
What this spec does not do is enumerate acceptable slots. A coach keeping adherence, a support
agent keeping frustration, a pastor keeping how open somebody is: one mechanism, and whether a
particular slot suits a particular deployment is the operator’s judgement at grant time rather than
a list in this document.

