✓ Microdesign v1.1 — APPROVED (25 April 2026). Canonical doc approved after the 25/4/2026 end-to-end simulation, aligned with the Architecture v1.1 and the Dialogue on executors and distributed memory. Normative reference for implementation. New concept compared to the previous microdesign.
← Documentation index Microdesign › mnestome

Metnos

mnestome — the emergent graph of all mnests
Microdesign v1.1 — 24 April 2026
Aligned with Architecture v1.1 (ch. 9, Figure 6) and the Dialogue on executors.
New concept introduced by v1.1 (does not replace anything existing).

Audience: whoever implements the data schema, the ager, the snapshots.
Reading time: 16 minutes.

Contents

  1. Scope and boundaries
  2. What the mnestome is
  3. What the mnestome is NOT
  4. Data schema
  5. Operations: insert, query, update
  6. The ager: how decay operates
  7. Pruning, snapshots, archival
  8. Linguistic variant: mnestome vs mnestoma
  9. Bootstrap: the first mnestome
  10. Observability and debugging
  11. Open questions

1. Scope and boundaries

This document defines the mnestome: the data structure that holds the set of all active mnests and governs their lifecycle. It is the third of three canonical docs introduced by the Dialogue on executors and distributed memory (24 April 2026), and it is a new concept: the previous microdesign did not have it. Technically it is a weighted directed graph persisted in SQLite; ontologically it is Metnos's relational memory — what it remembers having done together.

Boundaries

The document covers:

It does not cover, and defers to other docs:

2. What the mnestome is

The mnestome is a weighted directed graph in which:

The mnestome emerges. No one designs it a priori: it is born empty at first boot and forms turn after turn, while the gateway observes which executors pass output to which others. The shapes it takes reflect how the system is used: an «invoice archiving» user's mnestome has different clusters than a «daily news roundup» user's, even when the seed of executors is the same.

Why a graph, not a list. The «graph» shape captures a property the list would not: operational proximity. Two executors that often appear one after the other in the same turn are closer than two that never meet. The graph makes it explicit; the list hides it. Almost every Vaglio, ager and synt decision is easier to formulate in graph terms.

3. What the mnestome is NOT

The word «memory» in an AI agent has too many meanings. It is worth saying clearly what the mnestome is not:

What the mnestome is NOTWhere that concept lives, then
The LLM's conversational memory (recent turns, in-token context).In the working memory of the execution trace, see memory.html (in Italian and pending rewrite).
The episodic memory of past conversations (what Roberto said yesterday).In the episodic memory, indexed by sender. See memory.html.
The semantic memory of facts about Roberto and his world («the dog's name is Fido»).In the semantic memory, extracted via reflection and approved by the user.
The audit log of completed actions.In workspace/.audit/, append-only, JSONL.
The user's file workspace (notes, invoices, photos).In workspace/, managed separately.
The definition of capabilities (the individual executors).In workspace/executors/, file by file.

The mnestome is the observed relation between executors: who worked with whom, how often, how recently. Nothing more.

4. Data schema

The mnestome lives in workspace/.mnestome/mnest.sqlite, a single SQLite file. The choice of SQLite is deliberate: zero services to start, zero external dependencies, trivial backup (file copy), proven reliability.

Table executors

A lightweight replica of the manifest, in fast-read mode for gateway queries. The canonical manifest always remains workspace/executors/<name>/manifest.toml; this table is an index.

CREATE TABLE executors (
  name           TEXT NOT NULL,
  version        TEXT NOT NULL,
  state          TEXT NOT NULL,        -- seed | active | quarantine | archived
  loaded_at      TEXT NOT NULL,        -- ISO 8601
  manifest_hash  TEXT NOT NULL,        -- blake3
  PRIMARY KEY (name, version)
);
CREATE INDEX idx_executors_state ON executors(state);

Table mnests

CREATE TABLE mnests (
  id             TEXT PRIMARY KEY,     -- ULID
  src_executor   TEXT NOT NULL,
  src_version    TEXT NOT NULL,
  dst_executor   TEXT NOT NULL,        -- canonical name OR desired name (proto)
  dst_version    TEXT,                 -- NULL for proto
  weight         REAL NOT NULL CHECK (weight BETWEEN 0 AND 1),
  uses           INTEGER NOT NULL CHECK (uses >= 1),
  ts_first       TEXT NOT NULL,
  ts_last        TEXT NOT NULL,
  decay_lambda   REAL NOT NULL DEFAULT 0.018,
  state          TEXT NOT NULL,        -- proto | active | decaying | superseded
  tags           TEXT,                 -- JSON array
  desired_sig    TEXT,                 -- JSON, only for proto
  CHECK (ts_last >= ts_first),
  UNIQUE (src_executor, src_version, dst_executor, dst_version, state)
);
CREATE INDEX idx_mnests_dst    ON mnests(dst_executor);
CREATE INDEX idx_mnests_src    ON mnests(src_executor);
CREATE INDEX idx_mnests_weight ON mnests(weight DESC);
CREATE INDEX idx_mnests_state  ON mnests(state);

Table events

Append-only, records every reinforcement or decay applied. Allows the weight trajectory of a mnest to be reconstructed and to be recomputed later if the formula changes.

CREATE TABLE events (
  id          INTEGER PRIMARY KEY AUTOINCREMENT,
  mnest_id    TEXT NOT NULL,
  ts          TEXT NOT NULL,
  kind        TEXT NOT NULL,           -- reinforce | decay | state_change
  delta       REAL,                    -- weight delta (NULL for state_change)
  new_state   TEXT,                    -- only for state_change
  reason      TEXT,                    -- e.g. "ager nightly", "synt approved"
  FOREIGN KEY (mnest_id) REFERENCES mnests(id)
);
CREATE INDEX idx_events_mnest ON events(mnest_id);
CREATE INDEX idx_events_ts    ON events(ts);

View v_mnestome

The «live» graph for read queries. Excludes superseded and shows active + proto:

CREATE VIEW v_mnestome AS
SELECT id, src_executor, src_version, dst_executor, dst_version,
       weight, uses, ts_last, state, tags, desired_sig
FROM mnests
WHERE state IN ('active', 'proto');

5. Operations: insert, query, update

Insert / reinforcement: record_passing

The only write operation during a turn. Atomic per pair. Pseudocode:

def record_passing(src, dst, turn_ctx) -> mnest_id:
    with conn.transaction():
        if dst.exists:
            row = SELECT * FROM mnests
                  WHERE src_executor = src.name AND src_version = src.version
                    AND dst_executor = dst.name AND dst_version = dst.version
                    AND state = 'active'
            if row:
                w = decay(row.weight, now() - row.ts_last, row.decay_lambda) + REINFORCE_DELTA
                UPDATE mnests SET weight = clamp01(w), uses = uses + 1, ts_last = now()
                INSERT INTO events (mnest_id, ts, kind, delta, reason)
                       VALUES (row.id, now(), 'reinforce', REINFORCE_DELTA, turn_ctx.id)
                return row.id
            else:
                id = ulid()
                INSERT INTO mnests (id, src_*, dst_*, weight, uses, ts_first, ts_last, state, tags)
                       VALUES (id, ..., BOOTSTRAP_WEIGHT, 1, now(), now(), 'active', tags)
                INSERT INTO events (mnest_id, ts, kind, delta, reason)
                       VALUES (id, now(), 'reinforce', BOOTSTRAP_WEIGHT, turn_ctx.id)
                return id
        else:
            # proto-mnest
            id = ulid()
            desired = build_desired_signature(turn_ctx)
            INSERT INTO mnests (..., dst_executor=dst.desired_name, dst_version=NULL,
                                ..., state='proto', desired_sig=desired)
            return id

Main queries

QueryUse
top_k_outgoing(executor, k)Given an executor, returns the k heaviest outgoing mnests.
top_k_incoming(executor, k)Given an executor, returns the k heaviest incoming mnests.
walk(start, max_depth)Weighted BFS from the starting node, up to a maximum depth. Used by the gateway to build the execution context.
recurring_protos(min_uses, since)List of proto-mnests that have crossed a recurrence threshold. Trigger of the synt.
by_tag(tag)All mnests with a given tag. Used by observability and the ager for clustering.
decaying()Mnests in decaying state. Used by the ager for archival proposals.

State updates

State transitions are made by specific components (ager, synt, gateway in case of executor quarantine). All are accompanied by an events row with kind = 'state_change' and a mandatory reason; this is the principle of reversibility (ch. 14 of the Architecture): you do not change state without a trace of the why.

6. The ager: how decay operates

The ager is the process that applies decay and signals the state transitions that pure time requires. It runs once a day, in a night window (default: 04:00 local time), in a long but low-impact transaction:

  1. Decay: for every active mnest, compute weight_new = weight_old · exp(-λ · Δt) where Δt is the time elapsed since the last event. Update the weight and write a decay-kind events row.
  2. Decay state: every mnest that falls below the decay weight threshold moves to decaying; it is signalled in the proposals channel to the gateway.
  3. Archive proposal: every decaying mnest below archive weight with ts_last > 90 days enters the list of archival proposals shown to Roberto.
  4. Proto purge: every proto-mnest that falls below min proto weight is deleted (anti-noise).
  5. Recurring proto detection: search proto-mnests with uses >= SYNTH_TRIGGER_USES and weight >= SYNTH_TRIGGER_WEIGHT; signal them to the synt as candidates for synthesis.
  6. Snapshot: on the first of the month, copy the SQLite file into workspace/.mnestome/snapshots/YYYY-MM.sqlite.

The ager is a pure example of a component that only does maintenance: it does not modify the structure of mnests, does not create executors, does not speak to the user. It proposes; the deciders are synt + Roberto, or the archival policy that the gateway applies in the next turn.

7. Pruning, snapshots, archival

Monthly snapshot

On the first of the month (UTC), the ager produces a snapshot of the live file:

workspace/.mnestome/snapshots/2026-04.sqlite      # current month
workspace/.mnestome/snapshots/2026-03.sqlite.zst  # older, compressed
workspace/.mnestome/snapshots/2026-02.sqlite.zst
...

The snapshot serves three purposes: rollback in case of corruption of the live file, historical analysis of the graph, trace for whoever wants to understand how Metnos «formed» over time. Snapshots older than 12 months are .zst-compressed but never deleted: history is a first-rate datum.

Live file pruning

The live file would stay up even when full, but for performance and cleanliness a periodic pruning helps:

Executor archival

When an executor moves to archived, its mnests move to superseded with reason = 'executor archived'; they remain readable, are excluded from the v_mnestome view, and after 90 days move to the archive table.

8. Linguistic variant: mnestome vs mnestoma

The term has two normative forms:

The double form is intentional and to be preserved. Translating mnestoma into mnestome in English gives the English reader the right reflex (the biological suffix evokes an emergent graph, like the microbiome). Translating mnestome into mnestoma in Italian follows the phonetic rule that avoids suffixes felt as incongruous (mnestome in Italian would sound like a verbal imperative, «you, memorise!»).

9. Bootstrap: the first mnestome

At first boot, the mnestome is empty. The question «then where do we start?» has three concrete answers:

  1. Start empty. For most instances, the mnestome is empty at first boot and forms over a month of use. It is slow but correct: the user's specificity enters the graph's shape immediately.
  2. Minimal seed (recommended). A seed of 12-15 known mnests, hard-coded in the repo, wires the most common passings between seed executors (e.g. fs_read → pdf_extract, web_fetch → markdown_render). They have state = 'seed' to distinguish them and weight BOOTSTRAP_WEIGHT (see mnest.html ch. 6).
  3. Import from snapshot. For migrations or sharing (future), a clean snapshot can be imported. Import goes through validation: the cited executors must exist and be signed.

10. Observability and debugging

The user can inspect the mnestome from the CLI (via the Metnos mnestome command):

Metnos mnestome list                        # all active mnests
Metnos mnestome list --tag invoice          # filtered by tag
Metnos mnestome top 20                      # the 20 heaviest
Metnos mnestome graph executor fs_read      # neighbourhood of an executor
Metnos mnestome proto                       # current proto-mnests
Metnos mnestome history mnest_01HW...       # event history of a mnest
Metnos mnestome snapshot --month 2026-03    # opens the monthly snapshot

The web dashboard (see observability.html, in Italian and pending rewrite) has a graphical view of the same content, with filters and drill-down. The transparency rule: the user can always know what Metnos thinks it knows.

11. Open questions

  1. Write concurrency. The gateway is a single process, so writes are naturally serial. When remote executors arrive in the future (ch. 4 of the Architecture), the gateway stays unique but calls may arrive from multiple turns in parallel. Is SQLite WAL enough? Open.
  2. Schema migration. The SQLite file lives long. How do we manage schema migrations across Metnos versions? Numbered declarative migrations, Alembic-style? Open.
  3. Snapshot privacy. Monthly snapshots contain executor names and tags, but no contents. The privacy surface is low, but if one wanted to share a snapshot for debug, a tag redaction function would be useful. To be designed if needed.
  4. Integration with episodic memory. The mnestome and the episodic memory of conversations are kept separate by design (ch. 3). Does it make sense to have an explicit cross-reference (a mnest citing the turn_id that generated it)? The inverse (a turn citing the mnests it reinforced) is already in the audit. Open.

first in the triad
executor
The node of the mnestome.
second in the triad
mnest
The edge of the mnestome.
level 1
Architecture, ch. 9
The big picture.
index
Microdesign
All docs.

Metnos — mnestome microdesign v1.1 — 2026-04-24
New canonical doc (concept introduced by v1.1).