personalities/
Each subdirectory under personalities/ is one persona the host can run the assistant as — its voice, behaviours, guardrails, and display name. The host renders the chat system prompt by including Jinja templates from the active persona’s directory; switching personality is a directory swap, not a prompt rewrite.
personalities/└── roger/ ├── identity.yml ├── brief.yml ├── personality.jinja ├── behaviours.jinja ├── guardrails.jinja ├── response_format.jinja └── verbosity.jinjaidentity.yml— the persona’s display metadata.name:is the display name under this persona (shown on chat bubbles, used by the LLM when introducing itself).description:is an optional one-liner for a picker, a column heading or a listing — a realm offering several personas as choices needs a label per persona, and this is where a label belongs.source:is optional and is set automatically torealmfor realm-shipped personalities; only set it explicitly when overriding the default.
name: Rogerdescription: "One line for a picker, where a realm offers several personas" # optionalsource: realm-
*.jinjafiles — included into the chat system prompt at the matching slots.personality.jinjacarries the voice / character,behaviours.jinjacarries do/don’t rules,guardrails.jinjacarries safety constraints,response_format.jinjacarries output-shape rules,verbosity.jinjacarries length / pacing rules. All five are optional — omit any file you don’t need and the host skips its include line. -
brief.yml— optional. The persona in the form a single non-chat call needs. The.jinjafiles are slots a host assembles into a chat system prompt at session scope; a brief is the same persona compacted into one request, for a realm verb that calls a model directly rather than through chat. A persona with nobrief.ymlis chat-only and is simply not offered to a verb.
objective: | What Roger is trying to achieve in a conversation. A persona with one advocates.sampling: maxTokens: 600 # what this persona RUNS atnotebook: sets: [pastoral] extraction: role: routing| Field | Required | Meaning |
|---|---|---|
objective |
no | What this persona is trying to achieve in a conversation. A persona with an objective advocates; one without it answers. |
openingMove |
no | How it opens when it speaks first. |
notebook |
no | The notebook sets it keeps, and how they are extracted. |
sampling |
no | What this persona RUNS at — topP, maxTokens. Distinct from an agent’s conversation.sampling, which bounds what a caller may ask for. |
brief |
no | The persona’s voice compacted into a few hundred words, for a realm that calls a model directly rather than through chat. Omit it on the chat path: personality.jinja is already carrying the voice there, and a second copy of it is a second thing to keep true. It never renders in chat — a rule meant for conversations goes in behaviours.jinja or guardrails.jinja; written only here, it reaches no conversation. |
objective, openingMove and notebook do reach chat: a host renders them as the persona’s agenda
on every turn. For an agent you talk to they are part of what its sponsor signs, like the .jinja
sections — an edited objective waits for a signature before it reaches a conversation.
An agent’s job and a persona’s objective are not the same sentence. job is what the agent is
for, in the words of whoever answers for it; objective is what it is trying to achieve in a
conversation. A brake suppresses the objective and never the job — an agent asked to stop advocating
still does its job.
What is NOT here, deliberately: subjects the persona avoids, and subjects it does not claim
competence in. guardrails.jinja says both already, in prose, more precisely than a list can — “name
the kind of professional they need and go back to what you can offer” is not expressible as
unversed: [medicine]. Two statements of one rule is one too many.
An objective is the field that turns a voice into an agent with an interest of its own, and it is
declared rather than implied for exactly that reason: a persona that is advocating should say so in a
file an operator can read, not only in the way it happens to argue.
sampling — what the persona runs at
Section titled “sampling — what the persona runs at”A persona may declare how long it answers and how widely it samples, when a realm verb calls it
directly. It declares no temperature: current models ignore a sampling temperature or reject one, so
a host sets none, and a temperature a brief.yml still declares is ignored rather than refused.
sampling: maxTokens: 400 # what she runs atThis is not an agent’s conversation.sampling, and the two do different jobs:
| Declares | Governs | |
|---|---|---|
brief.yml → sampling |
what the persona runs at | the call the host makes when nobody asked for anything |
agents/<name>.yml → conversation.sampling |
a range | what a caller may ask for, clamped |
Precedence, highest first: a caller’s request, clamped to the agent’s range; then the persona’s declared value, clamped to the same range; then the role’s own settings. A persona therefore cannot escape an operator’s bounds by declaring a number — it states a preference inside them, which is the same request-and-grant that governs everything else a realm asks for.
A host that does not read sampling ignores it and runs the role’s settings, so declaring one never
breaks a realm; it simply does not take effect. A surface whose model call takes no sampling
arguments at all — as a host’s general-purpose completion tool may not — cannot honour it, and the
persona will run at whatever the role gives.
A brief resolves by the same rules as the rest of the bundle: the slug is unique across the world and a world-authored persona of that name shadows the realm’s. So a brief is not a private copy a realm owns — it is one more field of a persona the host resolves, and a realm must not assume the persona a reader sees is the one in its own directory.
Resolution is therefore the HOST’s. A realm that reads its own personalities/ directory to find
a brief — which is all a realm can do until a host exposes personas to a verb — bypasses
shadowing, and should say so rather than present the result as the resolved persona.
The two forms describe one person and must agree on substance, differing only in form. Nothing
in the format enforces that, so a realm whose build can check it should: a persona whose voice and
whose brief disagree is a defect no reader can see. The least a build can do is fail when a brief
ships without an identity.yml beside it, or when a focuses/ file names a defaultPersona that
ships no brief.
A realm’s personality is referenced by slug (its directory name) from a focuses/ file (defaultPersona: roger) or directly via the host’s persona picker. Slug must be unique across the world; on collision with a world-authored personality, the world wins.

