Versioned state
Mesh should not treat agent memory, tool access, or persona configuration as loose markdown files on disk. Those files are fine as an export format, but they are the wrong source of truth for a multiplayer system that needs to be durable, auditable, recoverable, and perspective-isolated. Seeperspective.md for the RuntimeAgent perspective boundary, runtime/context-resolution.md for how that boundary applies to model context, and runtime/memory-retrieval.md for how eligible memory is selected and ranked.
Why not markdown as the canonical store
Markdown repos are convenient for a hacker workflow, but they have structural problems:- they are easy to mutate silently
- they do not naturally preserve provenance
- they do not give you a clean rollback story
- they make branching and forking awkward
- they spread important runtime state across files that are hard to query
- they make it too easy to accidentally share state between agents that happen to use the same filesystem
What Mesh should do instead
Mesh should store the canonical state in Postgres using append-only, versioned tables. The important pieces are:- self/profile state — persona, style, operating constraints, goals
- tool grants — what capabilities an agent has been given
- memory entries — durable remembered facts with provenance
- prompt snapshots — the assembled material used for a turn
- revisions — immutable history for every change
RuntimeAgent. Multi-agent hosting is operational multiplexing, not a shared state space.
A human-readable markdown export can still exist, but only as a view over the structured state.
Perspective ownership
Memory belongs to the RuntimeAgent that learned it. If Lyra and Daedalus both interact with Victor, Lyra’s memory about Victor and Daedalus’s memory about Victor are separate state. The control plane may correlate the external identities for operational reasons, but that correlation does not make either agent’s memory eligible context for the other. The same rule applies to profile state, tool grants, and prompt snapshots: there is no deployment-global fallback state that an agent silently inherits because another RuntimeAgent already has it. A cross-connector identity link established in one perspective may organize that RuntimeAgent’s memory across Slack, Telegram, or GitHub. It does not bootstrap identity or memory in another perspective.Provenance is part of memory
A durable memory entry must retain enough provenance for future context resolution to decide whether it is appropriate to reuse:- which RuntimeAgent learned it
- which Actor or Actors it concerns inside that perspective
- which Conversation and MessageEvents produced it
- when it was learned
- what audience could observe the source conversation
Why append-only matters
Append-only state gives us:- auditability
- rollback
- forking
- reproducibility
- safe experimentation
- the ability to inspect exactly what the runtime believed at a given turn
Intended behavior
When a profile or tool grant changes:- write a new revision owned by the RuntimeAgent
- preserve the prior version
- mark the new one as current for that RuntimeAgent
- assemble the runtime prompt from that agent’s current version plus context resolved entirely inside its perspective
Prompt snapshots
A prompt snapshot is the audit record of what one RuntimeAgent actually knew for one turn. It must never contain references sourced from another RuntimeAgent’s perspective merely because both are hosted by the same process. The snapshot should eventually record the agent id plus the source message, memory, and state revisions used to assemble it. Seeruntime/context-resolution.md.
Design principles
DB is canonical. Markdown is presentation. State is RuntimeAgent-owned. Co-residency is not shared cognition. Those are the right boundaries for a system that wants to be multiplayer from the start.Current state
This document is the intent. What is actually built, as of0019_run_ledger.sql:
-
persona — built (
agent_persona_revisions): the operator-authored identity text rendered into every prompt. Append-only revisions with an explicitactiveflag (one per agent, enforced by a partial unique index), written by the admin API’s persona endpoints and edited on the agent’s profile page. Reverting activates an earlier revision; it never mints a copy, so history records what happened. The loader resolves the active revision into the serving agent andturn.Enginerenders it — this one is behavior, not intent. -
memory entries + revisions — built and live in both directions, keyed to
runtime_agents(id), and actor-attributed as of0018_actor_attributed_memory.sql. Operators author them through the admin API; the runtime loads the newest eligible live entries into each prompt and exposes four verbs (remember,recall,amend,forget). Each entry now distinguishes subject (subject_actor_id, who the claim is about), source (source_actor_idplussource_message_event_id, who supplied it and on what basis), and visibility (perspectiveorconversation, the hard eligibility filter). The two actor references are composite foreign keys intoactors (runtime_agent_id, id), so cross-perspective attribution is rejected by the database rather than by convention. Both are nullable: an unresolved subject is a legitimate state, not a defect to paper over with a guess.memory_entry_revisionsis an operation log, not merely a body history. Each row records itsoperation(create/amend/forget), the attributed state it produced, and who supplied the change. Every write — includingforget, which soft-deletes and advances the revision counter — commits its entry and its revision row in one transaction, so a committed memory is never missing its history and a retired memory stays auditable. An agent-authored entry hassource_type='agent', a NULL operator id, and provenance derived from the persisted inbound message’s graph record. Retrieval is lexical (PostgreSQL FTS) plus a current-subject boost and recency; the semantic and salience axes inruntime/memory-retrieval.mdremain to be implemented. -
prompt snapshots — built and live, keyed to
runtime_agents(id). The turn engine records the assembled system prompt before provider execution and each durable model-call row references that snapshot, so the audit record and invocation cannot silently drift apart. -
tool grants — not built.
0003createdtool_sets/tool_set_revisionsspeculatively; nothing ever read them and0009dropped them. They return designed against the tool contract, not resurrected — see the 0009 header for what a real grant schema has to carry. -
profile state — there is no separate profile row. The profile is the
runtime_agentsrow (display_name, the three model-role columns,settings) plus its persona revisions;0009droppedagent_profilesrather than keep a 1:1 surrogate that had to be kept in sync.