← Documentation index Foundations › Architecture guide
Architecture guide

Metnos

From the whole system to its component contracts

One tutorial, two levels of detail. Start with the ideas, follow a real request, then zoom into the components that make each promise executable.

Status: pre-1.0
HTML format — printable as PDF
Simple language, exact contracts, diagrams that can be read without the code.

Your route through the system

OrientPurpose, bets, vocabulary and boundaries. Follow a turnFrom a message to a measured, honest result. Understand actionExecutors, authority, placement and synthesis. See what persistsMemory, senses, channels, safety and undo. Open the machineComponent map, contracts and implementation guides.
Full chapter index
  1. What Metnos is
  2. The three bets
  3. The key concepts
  4. The layered architecture
  5. Anatomy of a multitool turn
  6. Executors and authority
  7. Synt: the tool factory
  8. Models and deterministic routing
  9. Memory
  10. Image pipeline
  11. Channels
  12. Safety and reversibility
  13. Component atlas
  14. Eight principles
  15. What Metnos is not
  16. Where to go next

One architecture, three levels of zoom

WhyThe principles and limits that make Metnos a particular kind of assistant.
What happensThe complete path of a turn, including denial, recovery and undo.
How it is builtCanonical component contracts: schemas, calls, authority and error conditions.
How to use this guide. Read straight through once. On a second pass, use the component links as trapdoors into implementation detail. The overview explains the promise; the component page defines the contract that keeps it.
Part I · Orientation

Know what you are looking at

Purpose first, then design bets, then the small vocabulary used throughout the rest of the guide.

1. What Metnos is

Metnos is a self-hosted architecture for a governed agent. Its core does not define an application domain: it plans, applies policy, remembers, synthesizes, isolates and audits. The admitted executor set defines what a concrete instance can actually do. Executors are small signed programs, generated or imported only inside a closed vocabulary and orchestrated by a local-first LLM planner. Frontier models are optional consults, not the residence of the system.

The name comes from mētis (cunning intelligence) + noûs (mind). It lives on a machine under your physical and legal control. The reference instance is reached through Telegram and the browser (port 8770), and its current executor catalog covers files, mail, photos, calendars, the web, GitHub and host operations. Those are uses of that catalog, not limits of Metnos. Change the admitted executors and enabled skills/backends, and the operational domain changes without changing the governing architecture.

Scope rule. Mail, photos and calendars do not belong to Metnos itself. They belong to executors in the reference catalog. Maintaining Metnos through GitHub is already a different use of the same architecture.
Metnos at a glance your machine — data, logic and models stay here Phone Telegram, anywhere confirmation buttons Browser chat + admin dashboards HTTP :8770 outbound long-poll the Metnos process Channels Telegram daemon · web server :8770 The mind (ch. 5) intent → plan memory → Mētis engine a whole plan as structured output deterministic boundaries around the LLM proposal The guards (ch. 12) policy · vaglio (consent) · sandbox Vectorized executors (ch. 6) signed catalog + synthesis under control list in → list out backends & skills (your choice) files & folders mail (IMAP/SMTP) photos & indices calendar web & search GitHub they act here configured LLM backends endpoints resolved for fast · middle · wise · creative local or remote, without changing the planner it thinks here persistent memory mnestome · fast-paths · undo history · audit (SQLite) frontier tier (cloud, opt-in) a consult when asked for — never the engine self-hosted: no mandatory dependency on third-party services; the cloud is a door you open, not a room you live in.
Figure 1 — Metnos at a glance. The process lives on your machine: channels receive, the mind plans through configured tiers, guards filter, and executors act on enabled backends. Remote providers and the frontier tier are explicit choices.

The identity card

ItemActual state
ShapePython ≥ 3.12 process, executor-based microarchitecture, and constrained one-shot planning in the Mētis engine (ch. 5).
ToolsSigned executors in the catalog, plus those synthesized on the fly and those imported behind a gate (ch. 7). All are vectorized: list in, list out. The domain reference provides the user view; current names and counts live in the generated catalog.
BrainCompatible local or remote LLM endpoints; five abstract tiers fast / middle / wise / creative / frontier (ch. 8). Frontier = cloud opt-in.
ChannelsTelegram (outbound long-poll, no open ports) + web on port 8770 (chat and admin dashboards), ch. 11.
DevicesA controlled part of the catalog can run on registered PCs in the same network through metnos-client: the server remains the point of policy, selection, signing and audit; the device runs only executors declared compatible. Detail: remote executors.
SensesIn-process image pipeline: semantics + faces + EXIF in one unified index (ch. 10).
LanguageContext per user and per request. Prompts, manifest descriptions, visible messages, and the input lexicon have declared sources and fallbacks. Italian and English are fully supported; adding another language requires translation and testing across all four areas.
License / statusAGPL-3.0; pre-1.0. Public repository: github.com/brunialti/metnos — the public distribution of code and release materials.

2. The three bets

The whole project rests on three architectural bets. They are deliberate positions, not optimizations: each one reverses a widespread habit of agent frameworks.

Three bets, one system 1 · Closed vocabulary Tools are not imported on trust: they are synthesized inside a closed, audited grammar. «don't trust the package: the package has to earn its place» ch. 3 · 6 · 7 2 · Local first The planner is an LLM on your hardware. No cloud round-trip to think or act. the frontier is an optional consult, not the engine ch. 8 3 · Deterministic boundaries Pools, signatures, validation and execution are controlled code; the model only proposes inside those boundaries. the probabilistic part stays explicit, measured and subject to control ch. 5 · 8 together: a governed, inspectable agent of your own
Figure 2 — The three bets. Each one reverses an agent-framework habit: skills imported on trust, cloud-first design, the LLM as an oracle re-rolled every turn.

The comparison, with no discounts

Typical agent frameworkMetnos
ToolsHand-written, imported or generated free-form, then run as-is with the assistant's privilegesSynthesized at runtime too — but from a closed, audited vocabulary: signed, aged, smoke-tested and screened before they can ever run
SafetyTrust the author of the packageDon't trust the package: the package must pass the checks (7-layer gate, ch. 7)
LLMOften cloud-firstLocal first; frontier opt-in
RoutingThe model may choose freely among ungoverned toolsA typed pool, grammar, validator, and validity signatures constrain the proposal. A valid cache hit is reproducible; a new LLM proposal may vary (ch. 8)
OutputFree-form, different per toolUniform: list in / list out, pipeable between steps (ch. 6)
UndoRare or best-effortFirst-class: a closed catalog of reverse patterns, moves = COPY-then-DELETE, honest ok_count (ch. 12)
LanguageEnglish only, strings in codePer-user language; prompts, manifests, messages, and lexicon are distinct validated data

Where determinism lives

Metnos does not present model prose as evidence. Prefiltering, grammar, validation, admission gates, execution, and cache-validity checks are controlled components under test. When a request has a stored plan that is still valid, the fast path reuses it without a new model call. When a plan must be generated, the proposal remains probabilistic but bounded and observable (ch. 9).

3. The key concepts, in seven cards

Seven words carry the whole document. Defining them now saves you half an hour of confusion thirty lines from here; each one has its implementation contract in the component atlas below.

executor — an executable capability: a small program that does one thing well (read files, send an email, move messages, search photos). It accepts lists as input and produces lists as output, carries a manifest that describes it, an Ed25519 signature that authenticates it and a sandbox profile that confines it. It is the only class of things that act in the system.
closed vocabulary — every executor is named verb_object[_qualifier[_descriptor]], composing governed sets of canonical actions and objects plus qualifiers in four families. It is not an aesthetic convention: it is the boundary of what the system can name — and therefore synthesize. New terms enter only through explicit governance (necessary · general · understandable).
manifest — the TOML identity card of an executor: a description in prescriptive chapters (SCOPE / PATTERN / NOT / OUT), the argument schema, affinity keywords, the reversibility pattern, the code digest. It is not documentation for humans: it is the tool's prompt, written so that a mid-size LLM uses it well (ch. 6).
synt — the process that brings into existence what the pool cannot do yet: a cascade of strategies ordered by cost that first composes existing executors and only as a documented exception generates new code, in five stages plus a semantic check (ch. 7). It proposes; the human approves.
vaglio — (Italian for «sifting») the filter that always sits before execution: a deterministic guard (forbidden paths, unrecoverable commands) followed by a judge that weighs grey-zone operations and, above threshold, asks the user for explicit confirmation with buttons on the channel (ch. 12).
mnest · mnestome — a mnest is the thread linking two executors that were activated together: it is born from context, reinforced by use, and decays if not reused. The mnestome is the graph of all mnests: the system's associative memory, on SQLite, curated by a nightly process (the ager). It gives the planner the intuition of «which executor usually follows which» (ch. 9).
skill ↔ backend — two orthogonal axes: a skill decides whether a group of capabilities is active, trusted and configured (dormant until its prerequisite appears); a backend decides how an action runs against a concrete service (calendar = local ICS or Google), chosen by configuration — never by the LLM. The planner never sees the provider.

The anatomy of a name

The closed vocabulary is the project's most fertile idea: it makes names composable (the planner can predict what a capability it has never seen is called), filterable (the prefilter reasons over verb and object) and synthesizable (synt cannot name anything outside the grammar).

Anatomy of a name: verb_object[_qualifier[_descriptor]] find _ images _ indices _ dry-run action governed canonical set read, write, move, find, get, list, filter, send, … object governed canonical set files, messages, events, images, urls, entries, … qualifier (opt.) 4 families format · mode safety · provider descriptor (opt.) kebab-case, max 30 behavioural variant with identical arguments the 5 producer verbs, orthogonal find = pattern / query get = known ids or snapshot read = id → content list = enumerate the container filter = predicate over a list the axis is the primary input, never a synonym read_messages move_files get_urls classify_entries write_files_doc find_issues_github The vocabulary is CLOSED: a new term enters only if necessary, general and understandable to a mid-size LLM. Synonyms before extension; human escalation for every new word. The grammar decides what is nameable.
Figure 3 — The anatomy of a name. Four positional levels, the last two optional; the five producer verbs are distinguished by their primary input, so the planner never has to choose among synonyms.
Part II · A request in motion

Follow one turn from words to effects

The layers are easier to understand after watching data, decisions and authority move through them.

4. The layered architecture

Metnos is an onion: the outside talks to the world, the inside executes. Each layer trusts only the one beneath it, and privileges shrink as you move toward the core. A request — whether from a user or from a scheduled task — crosses all of them, in order.

The layers, from the outside in 1 · Channels adapters to the world: Telegram daemon (pairing, buttons) · web server :8770 (chat, admin, SSE) runtime/channels/ · metnos_http_server 2 · Turn runtime normalizes the request · literal shortcuts · intent extraction (verb + object + keywords) agent_runtime · intent_extractor 3 · Cognitive engine — Mētis plan memory (L0 · L1) → prefilter → constrained proposer → validator → execution targeted recovery on errors · honest terminator on dead ends — ch. 5 runtime/engine/* 4 · Guards policy (three autonomy levels) · vaglio = guard + judge + consent · bubblewrap sandbox around every invoke policy · vaglio · sandbox 5 · Executors signed, synthesized or imported behind the gate — all vectorized, all with their manifest executors/ · ~/.local/…/executors/ 6 · Backends & skills the concrete provider (local files, IMAP, Google Workspace, GitHub, web…) chosen by configuration, never by the LLM backends/ · skills 7 · Persistent tissues mnestome · fast-path/autopath archives · undo history + blobs · append-only audit (all SQLite + filesystem) ~/.local/share/metnos/ a request crosses them in order privileges and trust shrink downwards
Figure 4 — The seven real layers, with the modules that implement them. The cognitive engine (layer 3) is the heart of chapter 5; the guards (layer 4) sit always between the plan and the effect.

5. Anatomy of a multitool turn

If you read only one chapter, read this one. We follow an example request — «find the spam mails and move them to the trash» — from entry to answer: four tools chained together, one structured proposal, and every step measured and annotated.

5.1 The cascade, step by step

The ground rule: the model is the last resort, not the first. Memory is tried first without an LLM. For a new request, the proposer asks the model for the whole structured plan. The number of calls depends on candidate and grammar configuration; execution of the validated plan follows deterministic rules.

One turn, from entry to answer «find the spam mails and move them to the trash» literal shortcuts a closed table: «what time is it», «where am I», «undo»… microseconds ✗ no match → continue intent_extractor — fast-tier LLM, reasoning off verb = move object = messages kw = spam… ~0.4 s compound requests → an ordered list of clauses the Mētis engine — one entry point, every layer records whether it answered Fastpath L0 — automatically recorded successes exact fingerprint · semantics only for generalizable plans 0 LLM ✗ miss Autopath L1 — plans confirmed by feedback searches by meaning of the request, then by exact intent 0 LLM ✗ miss: new request prefilter → the clause's pool find_messages classify_entries filter_entries move_messages rank: verb+object » qualifier » affinity (cap +3) 0 LLM deterministic: same query → same pool, same order Mētis Proposer — configured wise tier proposes the whole plan: steps + links + final message N adaptive candidates, each constrained by the GBNF grammar verb-filter on the pool · early-stop if the first convinces · teleological ranking constrained LLM the model chooses INSIDE the rail: no prose, no invented args (ch. 8) Validator — deterministic plan check do the tools exist? are the args well-formed? do references point to real steps? 0 LLM trivial error → 1 re-proposal, never run Deterministic execution — step by step, no dice 1 find_messages → 42 entries 2 classify spam / not spam 3 filter → 12 entries 4 move_messages ⚙ vaglio: consent → ok_count=12 for each step: resolve from_step and placeholders → vaglio → invoke in sandbox → observation safety caps: max 12 steps per turn · same executor max 3 times in a row render of the final message "Moved ${step4.ok_count} mails to the trash." → real values L0 records success; L1 observes L1 becomes active after positive feedback (ch. 9) a step fails? Targeted recovery classifies: wrong tool · wrong args · missing input re-proposes excluding the failed tool, re-runs Terminator — the honest dead end «I cannot solve: X. To proceed: Y.» records the gap — never an invented answer «Moved 12 mails to the trash.» the log records which layer answered and the ms of every phase per-phase telemetry: intent_ms · prefilter_ms · vaglio_ms · exec_ms — every turn is measurable and comparable
Figure 5 — The anatomy of a multitool turn. Valid shortcuts are tried first; for a new request, the Proposer asks the model for a structured plan and the Validator checks it before execution. Vaglio precedes every step that requires it; the right side shows targeted recovery and the declared dead end.
  1. Literal shortcuts. A closed table recognizes the most common phrases («what time is it») in microseconds. Here: no match.
  2. Intent. One call to the fast tier (reasoning off, ~0.4 s) extracts the canonical verb, the object and keywords. Compound requests become an ordered list of clauses, each with its own pool.
  3. Plan memory. Fastpath L0 reuses an automatically recorded success; Autopath L1 reuses a generalized skeleton confirmed by positive feedback. Both check catalog and pool signatures before a hit. Here: miss, because this is the first time.
  4. Prefilter. The catalog shrinks to the relevant pool for the clause: verb+object match, qualifier bonus, and — to break ties among siblings — the curated affinity bonus (cap +3). All deterministic: same query, same pool, same order.
  5. Mētis Proposer. The wise tier produces the whole structured plan: steps, links, and final message. Depending on configuration it may generate one or more candidates; the GBNF grammar limits available names and deterministic ranking selects the candidate to validate.
  6. Validator. A typecheck of the plan before running it: existing tools, well-formed args, real references. A trivial error costs one re-proposal, not one wrong execution.
  7. Execution. Pure mechanics: for every step the runtime resolves the placeholders, passes through the vaglio, invokes in the sandbox, accumulates the observation. Caps: 12 steps per turn, same executor max 3 times in a row.
  8. Closing. The final message is composed from actual results. If the turn succeeds and is cacheable, L0 records its plan; L1 stores an observation and requires positive feedback before promoting the generalized skeleton.

5.2 The plan: what the model actually proposes

The Proposer does not produce prose: it produces a structured object — steps, slots to fill (fillers), final message. This is the real plan for our request:

{
  "steps": [
    {"tool": "find_messages",
     "args": {"folder": "INBOX", "query": "is:unread"}},
    {"tool": "classify_entries",
     "args": {"from_step": 1, "dimension": "spam"}},
    {"tool": "filter_entries",
     "args": {"from_step": 2, "where_field": "spam", "where_value": "spam"}},
    {"tool": "move_messages",
     "args": {"from_step": 3, "dst_folder": "${FILLER:trash_folder}"}}
  ],
  "fillers": {
    "trash_folder": {
      "prompt": "What is the trash folder called for this account?",
      "default": "Trash",
      "tier": "fast"
    }
  },
  "final_message": "Moved ${step4.ok_count} mails to the trash."
}

Worth noting: the model does not know the account's trash folder name — and does not make one up. It declares a slot (${FILLER:trash_folder}) that the runtime will fill at the right moment with a cheap micro-call (cached) or with the default.

5.3 Data piping: how the steps talk to each other

PlaceholderWhat it does
from_step: NTake the entries produced by step N (1-based) and pass them whole to this step. Lists travel only this way: never pasted back into the prompt.
${stepN.field}Extract a scalar field from step N's result (nested paths supported). Used mostly in the final message.
${FILLER:name}A slot filled on the fly by a micro-call to the fast tier (cached) or by the declared default.
${RUNTIME:key}Turn context, resolved by the runtime: actor (who is speaking), lang, channel.
Data piping: lists between steps, scalars in placeholders step 1 · find_messages folder="INBOX" query="is:unread" → entries (42 mails) step 2 · classify_entries from_step: 1 dimension="spam" → entries + spam field step 3 · filter_entries from_step: 2 where spam == "spam" → entries (12 mails) step 4 · move_messages from_step: 3 dst=${FILLER:trash_folder} → results, ok_count=12 entries entries entries ${FILLER:trash_folder} a slot declared by the plan, filled by the runtime: fast-tier micro-call (cached) or the default → «Trash» ${RUNTIME:actor · lang · channel} turn context, injected by the runtime: who is speaking, in which language, from which channel final_message — the template of the reply "Moved ${step4.ok_count} mails to the trash." filled after execution with the real values → «Moved 12 mails to the trash.» ${step4.ok_count} a scalar, not a list legend of the links from_step — whole lists between steps ${stepN.field} — a scalar field ${FILLER:name} — a slot filled on the fly ${RUNTIME:key} — turn context
Figure 6 — The plan of Figure 5 seen as a data flow. Lists stream between steps via from_step; scalars, slots and context pass through typed placeholders that the executor resolves deterministically.

Partial results and limits

If a limit truncates a result by entries, bytes, or steps, the executor declares it through truncated, used, and available_total when its contract provides those fields, and the runtime makes the limit visible in the answer. It may offer to widen a limit only when technically possible, and never widens it on its own. Presenting a partial result as complete is an error.

Part III · Acting

Small programs, explicit authority

Executors do the work. Manifests limit it. Policy and placement decide where the work may happen.

6. Executors: vectorized by construction

Every executor accepts a list and returns a list — even when the list has zero or one element. There is no *_batch anywhere: the batch version is the executor. It is the decision that keeps plans short and results composable.

One contract for N = 0, 1, a thousand paths = [] paths = ["/tmp/x.txt"] paths = [… ×1000] degenerate or huge list: same entrance, no special case move_files iteration, pagination and time windows live INSIDE; branching goes back to the planner explicit caps: max_total, max_results, max_bytes always a list, plus the truth results = […] ok_count = 12 (real, not hoped) truncated = true used = 200, available_total = 312 cap_field = "max_total" move_files_batch  does not exist — and never will: the vectorized form is the only form.
Figure 7 — The vectorized contract. Zero, one or a thousand elements cross the same code; caps are explicit arguments and truncation is declared in the fields, never hidden.

Three conventions follow from the contract, and you will see them everywhere:

The manifest: the tool's prompt

Every executor carries a TOML manifest. It is not courtesy documentation: it is what the planner reads when it decides whether and how to use the tool — written for a mid-size local LLM, not for a frontier model. Short sentences, literal examples, defaults spelled out; the description follows four prescriptive chapters:

The same manifest also declares where the executor may run. The platforms and [placement] fields prevent sending to Windows a tool written only for Linux, or running on a PC an executor that has not been audited for the device. When the chat names a paired PC, the runtime uses those declarations to choose server or device execution; if the target is not reachable, the outcome is honest, not a silent fallback.

[description]
en = "SCOPE: search files by pattern in directory.
      PATTERN: find_files(base_path=\"/\", patterns=[\"*.jpg\"]).
      NOT: list_dirs+filter_entries; get_files (ID lookup).
      OUT: entries=[{path,name,type,mime,kind,size,mtime}]."
One manifest feeds four different mechanisms executors/find_files/manifest.toml name = "find_files" affinity = ["find","search","cerca", "file","glob","pattern",…] [description] SCOPE: … PATTERN: find_files(…) NOT: … OUT: entries=[{…}] per language (IT+EN), with state tracking [args] — JSON Schema base_path (req) · patterns · recursive max_total … types, defaults, examples reverse_pattern + capabilities e.g. "swap_src_dst" · fs:read · provider:access [code] sha256 digest + signature files = ["find_files.py"] prefilter (ch. 5) curated affinity breaks ties among siblings Proposer pool (ch. 5) the model copies the FORM from PATTERN, never invents GBNF grammar (ch. 8) the args schema becomes the decode rail undo (ch. 12) the reverse pattern comes from a closed catalog the digest binds manifest to code: if the file changes without re-signing, the loader discards the executor — no code drifting away
Figure 8 — One manifest, four consumers: prefilter, planner pool, grammar and undo each read different fields of the same TOML. The digest binds the manifest to the signed code.

One execution policy

Every executor call, local or remote, crosses the same execution engine. In one place the runtime applies metrics, backpressure, per-resource limits and a cap derived from the hardware. The default deliberately remains serial and the cross-executor pool is off: adopting the infrastructure does not change the order, inputs, outputs or capabilities of existing executors.

[execution]
effect = "unknown"
parallelism_class = 0
resource_class = "default"
concurrency_key = "none"
equivalence_gate = "unverified"
ClassRequested budgetAdmission
0No cross-executor thread.Default for every existing and generated executor.
1Moderate concurrency.Only after verified equivalence; always within engine and hardware limits.
2High concurrency.
3Controlled maximum.

The class measures only a budget: it grants no authority and does not mean read-only. A future executor that creates or mutates objects may run concurrently, but it must declare an isolation key, provide the resource identity, and pass equivalence, collision, idempotency and postcondition tests. If any evidence is missing, the loader reduces it to class 0.

All three executor-generation paths — Synt proposals, reactive synthesis and skill generation — also consume one central contract. The local model may design a rich implementation, but it cannot rewrite identity, lifecycle, I/O or the initial execution policy. When it parallelizes independent entries, the worker count comes from the engine and results must return in input order.

Preservation rule. An executor stays serial until it explicitly declares parallel eligibility and passes equivalence testing. Changing the central policy propagates limits and observability to all executors; it never promotes one implicitly.

Remote authority: declared once, consumed three times

A provider name in an argument is data, not permission. For a conforming executor, remote access exists only when the manifest declares an effective provider:access capability. A closed when condition can make that capability active only for the selected backend. Invalid or non-matching conditions grant nothing.

Authority rule. The same effective binding governs credentials, network and placement. Names, suffixes and arbitrary arguments are never independent permission paths for conforming executors.

Execution on the server or on a registered PC

The normal shape remains simple: the plan selects an executor, the runtime sends it through policy and vaglio, then invokes it in the server sandbox. Remote executors add one controlled detour: for selected executors declared portable, the execution point may be a registered PC in the same LAN or overlay network.

This is not a new channel and not a generic backend. The channel is still Telegram or web; the backend is still files, mail, calendar or another service. The remote executor is the place where the small signed program runs. Metnos keeps on the server the executor choice, policy checks, device registry, payload signing, timeout and audit.

chat "on office PC" Metnos server planner + policy + vaglio manifest: platforms + placement signed queue, deadline, audit metnos-client outbound poll + signature check registered PC compatible executor Job Object / bwrap signed result signed result: same shape as a local executor
Figure 8b — A remote executor does not move the mind: it moves only the execution of an admitted executor. The server remains the authority that decides, signs, waits and records.

The choice does not depend on the browser IP address. In the web UI, the machine opening the page may be the server, another PC on the network, or a browser behind a proxy; from Telegram there is no local browser at all. Metnos therefore uses the name of the paired device and anchors it in the request language: “on the laptop” is a target, “the laptop” alone is not.

The remote client does not receive general freedom. It polls the server instead of exposing ports; verifies the server signature before execution; downloads only signed and compatible executors; writes the result to a local spool before delivery. If the server is not reachable, it retries delivery without rerunning the work already done.

The remote client is contained by construction: on Windows the Job Object bounds duration, memory and process trees; on Linux the sandbox uses bwrap when present. Remote executors can also perform file-changing operations on the device — write, move, and delete — under the required safeguards: idempotency, audit, and device-aware reversibility (deterministic reverse patterns and blob backups queued to the same device for undo; the known gap being that blob-restore is not remotable). Executors whose dependencies cannot be resolved on the device stay server-only.

The operational details — PC pairing, UI installation, heartbeat, signed queue, per-OS sandboxing and current limits — live in the remote executors component contract.

7. Synt: the tool factory

When the pool cannot do something, the planner does not improvise code in the middle of the turn: it hands over to synt, the process that brings into existence what is missing. It first tries to compose existing executors; only as a documented exception does it generate a new one — in five stages, each with its own contract.

The assembly line: five stages + verification each stage sees only the minimal slice of context; the closed vocabulary enters ONLY at stage 1 1 · NAMING a name conforming to the closed vocabulary + revertible, critical middle tier 2 · SIGNATURE args schema, required capabilities, reversibility pattern middle tier 3 · TESTS 4-6 birth tests: happy case, empty list, invalid args, edge middle tier 4 · DESCRIPTION chaptered description (SCOPE/PATTERN/NOT/OUT) + affinity keywords middle tier 5 · CODE the Python file with def invoke() (+ reverse if needed) wise tier stage 6 · semantic verification (fail-safe) a separate LLM compares description and code: do they say the same thing? when in doubt it rejects: better to lose a good synth than admit a bogus one Ed25519 signature + digest manifest and code bound together birth tests in the sandbox the 4-6 tests of stage 3, actually run into the pool, next to its siblings same vectorized contract, same manifest, same sandbox as the hand-written executors Synthesis is local: no external provider writes code that will run on your machine. And a bug in a synthesized executor is fixed by iterating the stage's prompt, never by hand-editing the generated file.
Figure 9 — The synthesis pipeline: four procedural stages on the middle tier, the code on the top tier, then independent semantic verification, signature and birth tests. The multi-stage design converges where the single prompt failed.

Two triggers, one cascade

ModeTriggerTiming
ReactiveDuring a turn: the planner finds no executor that satisfies the request.Synchronous — the user is waiting; composition of existing executors is tried first.
IntrovertiveAt night, the ager walks the mnestome and finds recurrences and overlapping traces.Asynchronous, in homeostasis: it currently proposes deduplication only; generalisation and specialisation are not active generators.

In both cases the same rule holds: synt proposes, the human approves. No self-modification without a filter; every proposal comes with its rationale, and is reversible.

The 7-layer gate

The same funnel applies to synthesized code and to skills imported from outside: no package runs on trust.

The admission gate: seven layers, no exceptions package / new synth untrusted 1 signature Ed25519+digest 2 vocabulary name + affinity 3 aging usage quarantine 4 sandbox profile from manifest 5 smoke test execution proven 6 LLM verifier description vs code 7 audit append-only trusted executor in the pool «don't trust the package — the package has to earn its place» drop-in skill formats execute third-party code with the assistant's privileges: for an agent that touches files, mail and shell, that is remote code execution by design. Metnos chooses security by construction. imported skills pass through the same gate as native executors
Figure 10 — The 7-layer gate, identical for synthesized and imported executors: signature, vocabulary, usage quarantine, sandbox, smoke test, semantic verification, audit. Only at the end of the funnel does a package become a trusted executor.

8. Five tiers, governed routing

Tiers are abstract roles, not pinned models: fast / middle / wise / creative are assignments you bind to whatever endpoint you have, and frontier is the optional cloud role. Several tiers may share one endpoint or use separate endpoints: the planner always sees the role.

TierRoleConstraint
fastShort structured decisions: intent, fillers, and bounded reductions.Configured endpoint; short replies. Mandatory.
middleProcedural work and intermediate judgments: extraction, classification, and synthesis stages 1-3.The role's deterministic policy.
wiseThe planner and high-fidelity synthesis: whole plans, code, and verification.The role's deterministic policy.
creativeDivergent proposals and editorial text, including synthesis stage 4.Separate policy with temperature 0.35.
frontierAn external consult when explicitly requested (e.g. analyzing an issue).Cloud API, opt-in, with managed fallback if the key is absent.

A tier is not a model

Tiers describe roles and requirements, not a specific model. A GPU or NPU is not mandatory: an administrator can bind a tier to a CPU endpoint, an available local model, or an external service where the role permits one. The quality of the selected model affects planning quality, not installation validity.

Three controls on variability

An LLM at temperature zero does not automatically make new planning reproducible. Metnos reduces variability and, more importantly, separates the probabilistic proposal from deterministic controls before and after it:

Abstract tiers on the left, controls on the right fast intent · fillers · classify middle synt 1-4 · descriptions wise plans · synth code configured endpoints shared or distinct by role model and parameters may change: think · num_predict frontier cloud consult, opt-in only when asked, never the engine Control 1 — explicit seed a configured seed reduces one source of variability, but does not turn the model into a pure mathematical function. METNOS_LLM_SEED=42 (default; -1 = explicit randomness) Control 2 — ties broken by curated data among siblings with the same object, the manifest's distinctive affinity decides (generic verbs excluded), never a coin flip. prefilter: bonus = min(|query ∩ affinity|, 3) Control 3 — grammar and validator from the step's pool a GBNF is generated (discriminated union): the grammar limits output when enabled; the validator rejects inconsistent names, arguments and references. same request → same pool; valid cache → same stored plan a new proposal may vary; controls and transitions remain testable a soft constraint = «please keep to the right lane» · a grammar = the guard-rail the first can be ignored, the second cannot: every candidate token is filtered against the grammar before being chosen + verb-filter: the pool narrows to the verbs compatible with the clause's intent
Figure 11 — Tiers are roles bound to configured endpoints; controls reduce variability and prevent a structurally invalid proposal from being executed.

Controlled structure

The proposer requests a structured object, uses grammar when configured, and still applies balanced parsing followed by validation. Unreadable or non-conforming output is not executed.

Part IV · What surrounds action

Memory, senses, channels and safeguards

These tissues make the executor system useful over time, visible to the user and safe enough to operate.

9. The memory that speeds things up

Metnos trains no models: no fine-tuning, no RLHF. Everything it learns is inspectable data — plans, traces, shortcuts — and anything learned can be read, corrected, deleted. The practical effect: the more you use it, the less it calls the model.

The circle: use → record → reuse when safe a successful turn the plan actually worked L0 records; L1 observes plan, intent and world signatures indexed for future use a similar request, tomorrow if arguments and signatures remain valid: reuse without new planning explicit positive feedback confirms the L1 observation and may promote the generalized skeleton mnestome — the graph of mnests (SQLite) two executors activated together → a thread that strengthens with use and decays if unused; gaps remain as aspirations the clock is usage time, not the calendar: a system that sleeps does not age maintenance and governed proposals configured jobs prune expired records and may turn useful recurrences into synthesis candidates; a proposal remains separate from application changes pass through the change_intent lifecycle (ch. 7) every turn leaves traces learning = accumulating inspectable records, not training the model
Figure 12 — Reuse without training: L0 records cacheable successes, L1 promotes a generalization after positive feedback, co-activations feed the mnestome, and proposed changes remain under the decision lifecycle.

10. The senses: the image pipeline

To search your photos, Metnos ships nothing to anyone: three in-process extractors turn every image into three signals — what is seen, who is there, where and when — fused into one unified index queried through the ordinary vocabulary.

Three signals from every photo, one single index a photo from the archive semantics — configured visual embedder the image becomes a vector: «sunset at the sea», «birthday cake», «mountain trail» faces — configured detection and recognition finds the faces, turns them into identity prints; people get registered by name only if you ask context — EXIF GPS coordinates, date and time, camera: the where and the when with no model at all unified index one record per photo: scene + people + place + time built once, queried forever «the mountain photos from last summer» find_images_indices the same vocabulary as everything else all in-process, on your machine: the photo archive never leaves home
Figure 13 — The image pipeline uses configured roles for scene semantics and faces, and reads EXIF for place and time. The three signals converge into a unified index queried through an ordinary executor.

A search arrives from the channel like any other request: the planner composes find_images_indices with the criteria extracted from the sentence, and the channel shows inline previews. Building the index is a background job, incremental and restartable, started with a sentence («index the photos in…»).

11. The channels: Telegram and web

A channel is an adapter: it converts an external interface into messages and replies, plus one optional capability — rendering buttons for confirmations and choices. Two channels come with the install; adding more does not touch the core.

Two entrances, zero ports open to the Internet the Metnos machine web server — port 8770 chat (SSE streaming) + admin dashboards Telegram daemon OUTBOUND long-poll toward the bot API browser on the LAN (or via your own VPN overlay) admin key on first connect proposals · executors · runs safety · turns · charts HTTP :8770 Telegram API the daemon does the asking: no open ports, no public IP phone wherever there's network, you talk to your bot inline buttons who may speak? only the paired: signed Ed25519 codes with expiry, an authorization level per person an unknown sender is discarded without echo; vaglio confirmations and choices (get_inputs) arrive as buttons on the channel
Figure 14 — The two channels. The browser talks directly to the server on 8770 (streaming chat + dashboards); Telegram works by outbound long-poll, so no open ports and no public IP. Below, the pairing that decides who may speak.
ChannelWhat it offers
Web :8770Chat in the browser with streaming replies (SSE), image previews, feedback badges; admin dashboards for proposals, executors, runs, safety and turns. The same API answers JSON or HTML depending on Accept. Admin key auto-created on first start, file with 0600 permissions.
TelegramYour personal bot: messages, photos, inline buttons for vaglio confirmations and multiple-choice inputs. Pairing via the /pair command and a signed, expiring code.

The Tutor: explaining without executing

Explicit questions about how to use Metnos are intercepted at the shared HTTP/Telegram boundary, before the planner and without consuming a pending dialog. The first pass distinguishes explanations, actions, mixed requests, and intents that are still uncertain. A page name, relative path, or canonical URL may identify a published source directly; otherwise the configured embedder compares the question with units in the signed SQLite catalog.

After retrieval, the authenticated principal filters the sources. A signed source may request only registered, bounded, read-only observations: admitted executors, services, devices owned by the user, and that user's scheduled tasks. The local model composes the answer exclusively from this evidence; it receives no tools and crosses the central llm slot in the serial class.

If a request also contains a separable action, Tutor answers the informational part, preserves the operational clause verbatim, and asks whether to hand it to the ordinary Metnos engine. The handoff is single-use, bound to the user and conversation, and occurs only after confirmation. Tutor does not execute the action. Feedback may improve retrieval for that person alone without changing the planner or its plan caches.

The Tutor boundary

The runtime governs identity, audience, source integrity, the observation registry, and action handoff. Semantic classification, retrieval, and composition are used where language variety would make a phrase table brittle. An invalid catalog, a weak match, or insufficient context produces an explicit outcome, never an invented capability.

12. Safety and reversibility

Safety is not a module: it is a chain of independent guards, and an action must pass all of them. And since even the best guard makes mistakes, the last defense is being able to go back: honest undo, by construction.

The chain of guards — and undo as the last defense pairing who are you? signed code, a role per person unknown = discarded policy three autonomy levels: ReadOnly · Supervised · Full capability per category vaglio guard: forbidden and unrecoverable; judge + consent via buttons always BEFORE running sandbox bubblewrap with a profile from the manifest: network, user, IPC isolated never bare subprocesses signature + audit code bound to manifest via digest; every action in an append-only ledger drift = silent discard the last defense: first-class undo ● a closed catalog of reverse patterns (5): swap src/dst · delete what was created · restore from blob · delete by id ● every move is COPY → check → DELETE: never a deletion without a confirmed copy ● overwritten content goes to sha256-hashed blobs in the turn history: «undo» puts it back where it was ● honest ok_count in undo too: if it says it undid 3 things, it undid 3 things skills stay dormant until their prerequisite appears; disabling one removes the whole surface the system skill (shell, sudo, packages, mounts) exists — which is exactly why every privileged action requires explicit consent, and the whole skill can be switched off with one sentence
Figure 15 — Five guards in series (pairing, policy, vaglio, sandbox, signature+audit) and, below, the safety net: an undo with a closed catalog of reverse patterns, verified copies before any deletion, and honest counts.

Administrative capabilities and their boundary

With the corresponding executor set, a Metnos instance can administer a machine through the shell, sudo, packages, and mounts. Every privileged action passes through the vaglio and applicable authorization, uses the available containment layers, and is recorded. The system skill can be disabled, preventing Metnos from using these operating-system capabilities.

Part V · Open the machine

From promises to component contracts

The overview and the implementation model meet here: one map, one worked request and one catalog of deeper contracts.

13. Component atlas

The architecture above says what the system promises. This atlas shows which component owns each promise and where its exact contract lives.

13.1 From overview to component contracts

Metnos architecture has two levels of zoom. The upper level describes the system as a whole: its layers, organs, laws and ends. It is the path you have just followed from chapter 1.

The lower level is the set of component deep dives linked below: one HTML document per component, with the detail needed to write the code without guessing. Decisions here are not opinions — they are contracts: data schemas, function signatures, sandbox flags, error conditions. When the code and the document drift apart, the document wins and the code is adjusted; or the document is corrected on the spot — never «later».

The rule of life is short: a component is not implemented until its HTML exists, has been approved, and speaks the same language as the code already in place.

Check. Before you read on, two points should be obvious: (a) Level 1 explains what, Level 2 explains how; (b) Level 2 documents are contracts, not drafts. If either is unclear, re-read the previous paragraph before continuing.

13.2 Four nouns, now as implementation contracts

Everything in Metnos revolves around four nouns. Defining them now saves half an hour of confusion thirty lines down.

executor
An executable capability: a small program that does one thing well (read files, send mail, compute a hash, OCR a PDF, discover fresh URLs on a site). Every executor takes lists in and returns lists out; it has a manifest that describes it, an Ed25519 signature that authenticates it, and a sandbox profile that confines it. Product membership, origin, and transport remain separate axes. GitHub executors maintained by Metnos are builtin with handcrafted origin, not imports; the generated catalog is the single source for the source-tree domain breakdown.
mnest
The thread that links two executors when the planner has fired them together. It is not a code pointer, it is a trace: born from context, reinforced by repetition, decayed when unused.
mnestome
The emergent graph of all mnests. It is the system’s associative memory: it lives on SQLite, is curated by a nightly process (the ager), and gives the planner the intuition for «which executor usually follows which». The Italian counterpart of the term is mnestoma.
agent runtime
The turn runtime: it receives the request, extracts intent, tries L0/L1 plan memory, and asks the Mētis engine for a structured one-shot plan when needed. After validation it runs executors in sequence, collects observations, and applies Vaglio, policy, and sandbox controls to each step.
Check. Try to finish these sentences out loud: «An e-mail is sent by an…», «When two executors often work together, between them a… is born», «All these threads together form the…», «Who decides the order of the steps is the…». If you answer executor, mnest, mnestome, agent runtime, you may proceed.

13.3 The component map

The documented components are organized by role. The diagram below groups the main nodes by role: thick black border for the central engine, green shapes for the «services» the engine consults, blue shapes for the «tissues» that hold state, bronze shapes for the peripheral organs facing the user and the environment. Arrows show who calls whom.

telos — ultimate ends channel (Telegram) pairing approval_ux agent runtime one-shot plan · validation controlled execution vaglio policy sandbox synt executor (pool) signed contracts + controlled synthesis scratchpad turn state mnest co-activation traces mnestome graph + ager obs. dashboard orients
Component map. Solid arrow: direct call. Dashed arrow: orientation or read.

Three observations to read the diagram well.

  1. Telos is a soft signal: it guides the components where it is wired without replacing the request, policy, or capabilities. The workspace file declares ends and weights; it grants no authority.
  2. Vaglio always runs before execution, never after. Once an executor has fired, going back is not free: undo exists, but it costs history and backup blobs.
  3. The executor pool is extensible but governed: Synt first tries to compose existing capabilities and, when genuinely needed, can generate a new executor. Naming, manifest, tests, signature, and admission lifecycle remain mandatory.

13.4 A second worked request

To pin the map down, let’s follow a simple request from inbox to reply: «move to ~/Archive/2026 the invoice PDFs that arrived this week».

  1. Channel. Telegram receives the user message. The daemon checks that the sender is paired with sufficient authorisation; otherwise the message is silently dropped. Pairing means «channel + sender ID recognised»: it is obtained by replying to a signed Ed25519 code with a TTL.
  2. Agent runtime — planning. The runtime extracts the intent (canonical verb: move; object: files; criterion: invoice-attached PDFs in the «last week» window), asks the prefilter to narrow the catalog to relevant executors, requests a structured plan from the proposer, and validates it before the first step runs.
  3. Vaglio — guard + judge. Before the executor fires, Vaglio checks two things: that the path is not forbidden, that the shell command is not unrecoverable (rm -rf and friends). For grey-zone operations, policy and the judge determine whether a human decision is required. If so, the channel shows a localized proposal that makes the action, target, and relevant consequences recognizable.
  4. Sandbox + executor. The runtime invokes read_messages inside bwrap with the flags derived from the manifest. The output comes back as a list of entries; each entry is a dict with the PDF path and metadata.
  5. Pipe. The next step is move_files; it takes the previous step’s list via from_step: N. Ground truth lives in the scratchpad: the planner sees not the whole list, but a synthetic view large enough to decide.
  6. Mnest + mnestome. The pair read_messages → move_files reinforces an existing trace in the graph; if absent, it creates one. The nightly ager will do upkeep: decay, merges, drops.
  7. Reply. The runtime answers the user via Telegram with the number of files moved and the first reason for skipping if any have been left out. The final_answer includes a truncation marker if the input list had been capped.
Check. Without looking back: who talks to the user? who decides the sequence? who fires the executors? who checks the operation is allowed? who remembers that two capabilities went hand in hand? If your answers are channel, agent runtime, agent runtime, vaglio, mnestome, the map is yours.

13.5 Canonical component deep dives

Below, the documents are grouped by role. All have an Italian counterpart at /it/architecture/.

Central engine
ComponentScope
Cognitive engine The engine that plans and executes. Fastpath L0 reuses cacheable successes recorded automatically; Autopath L1 reuses generalized skeletons confirmed by positive feedback. Catalog and pool signatures are checked before every hit. For a new plan, the Proposer produces one or more structured candidates according to configuration, the Validator checks them, the Executor runs the admitted plan, and recovery or termination reports the outcome without inventing it.
agent_runtime Turn orchestration: channel and identity, intent extraction, dispatch to the one-shot engine, data flow between steps (from_step: int for lists and placeholders for scalars), suspended dialogs, scratchpad, telemetry, and mnestome hooks.
scratchpad Per-turn temporary store: holds large observations without crowding the planner’s context. Builtin scratchpad_read with head/tail/range.
grammar GBNF-constrained generation when enabled: a discriminated union of name and arguments, recursive schema, and contextual pool filter. The post-decode validator remains mandatory and rejects inconsistent combinations.
fastpath and autopath Two layers before the proposer. L0 stores the complete plan of a successful turn: a fingerprint serves the same request, while the configured embedder may match only generalizable frameworks. L1 stores a related cluster's skeleton and becomes active after positive feedback. Both validate current world signatures; requests with content-specific arguments remain exact-match only.
Tutor Local pre-planner guide: compiles admitted manifests, runtime registries, published documentation, and curated procedures into a signed catalog. It also recognizes public sources by filename, may add typed current observations, and hands an action clause to the engine only after confirmation. Feedback refines retrieval for one user without entering plan caches.
mail accounts Configuration of IMAP/SMTP mailboxes, including non-Google providers: encrypted bindings, multiple accounts, env-file compatibility, and the boundary with Gmail-specific features.
lifecycle Unified change lifecycle: one change_intent object, one state machine, and the /admin/changes UI. Active adapters are telos, introspective, synt, and user feedback. The daily materializer deduplicates sources; the applier processes accepted records every ten minutes; the daily observer measures effects and finalizes or rolls them back according to kind.
model virtualization How Metnos assigns the llm, embedder, and vlm roles to providers configured through {llm,embedding,vlm}_tiers.toml. Consumers request a function rather than a concrete brand or model, so local or HTTP backends can change without rewriting the planner or Tutor.
Executable capabilities and their birth
ComponentScope
executor Anatomy of an executor: TOML manifest, Ed25519 signature, sandbox profile, lifecycle, and vector contract (list-in, list-out). The current count lives in the generated catalog rather than this prose.
executor catalog Inventory generated from signed manifests: every first-party executor grouped by canonical domain, with purpose, criticality, platforms, and source location.
remote_executors How a controlled part of the executor catalog can run on registered devices: metnos-client, device pairing, manifest placement, per-OS sandboxing, UI installation and explicit Windows/Linux limits.
intelligent executors Narrow-mandate agents behind a regular executor contract: bounded adaptive loops, deterministic resolvers before models, unchanged authority, and verifiable postconditions. login_sites is the first example.
synt How new executors are born: a five-stage pipeline (naming, signature, tests, description, code), a reactive cascade (compose → generate), and introspective maintenance currently limited to deduplication.
skill_importer Acquires local, agentskills.io, or GitHub skills and turns them into Metnos executors through parsing, closed-vocabulary translation, generation, admission, signing, and registration. The skill_vocab_map.json table and verb boundary guide translation; commands are metnos-skills import|list|uninstall|status|evaluate.
skills & backends Why skills and backends are two orthogonal axes: the backend says HOW you run a verb_object (configuration, backend_resolver, invisible to the LLM), the skill says WHETHER/WHICH capabilities are unlocked (activation, dormancy, sandbox). Three tiers (core / first_party / imported), multi-provider architecture transparent to the planner, promotion with a one-off frontier.
Associative memory
ComponentScope
mnest The co-activation trace between two executors: anatomy, lifecycle, decay, persistence, proto-mnest.
mnestome The emergent graph of all mnests: SQLite data schema, atomic operations, nightly ager, snapshot. Italian term: mnestoma.
Safety, rules, and isolation
ComponentScope
vaglio Binary guard (forbidden paths, near-unrecoverable shell commands) and graded rule-based judge with configurable threshold. Probabilistic LLM judge deferred.
policy Closed capability registry, autonomy × capability table (ReadOnly / Supervised / Full), per_target persistent grants, combined effective_outcome.
sandbox bwrap profile derived from the manifest: read-only mount of the code, network isolation if no capability requires it, graceful fallback if bwrap is missing. Landlock deferred.
User-facing channel
ComponentScope
channel Common channel adapter (Protocol with send / poll) and the TelegramChannel implementation, with long polling, persistent last_update_id, a daemon, and a systemd user unit. Multi-user delivery uses send_to(chat_id, OutboundMessage); /start <token> pairs a guest.
http_api Second HTTP server (port 8770): uniform agent channel on POST /agent/turn (SSE + JSON), /admin dashboard in htmx + Jinja2 + uPlot, user management, introvertiva proposals, scheduler runs. Auth via admin key (7-day cookie) or device Bearer.
pairing Two paths: /pair with TTL-bound signed Ed25519 codes for technical devices, and /start <token> short-lived for family/guests (multi-user). Registry users.db with host + guests, user_channels, resolve_recipients. Host bootstrap on first run.
approval_ux Confirmation flow in web chat and Telegram. Its public contract is semantic rather than a fixed number of lines or buttons: it identifies the action, purpose, and relevant consequences; preserves the user's language and identity; and never turns one confirmation into an implicit persistent grant.
Multilingual
ComponentScope
multilang Three multilingual layers: LLM prompts (runtime/prompts/<lang>/<role>.j2), executor descriptions (TOML manifest + companion JSON), user-facing messages (i18n.sqlite). Latest-wins source-of-truth: no language is canonical by construction; the latest editor wins. Admin command metnos-prompts add-language <code>. Opt-in frontier tier for higher quality.
Visibility and ends
ComponentScope
observability Static HTML dashboard aggregating Metnos’s data sources (mnestome, pairings, turns, Vaglio decisions, scheduler). Generated on demand: no live server, no JavaScript.
telos The user’s ultimate ends, the alignment function, the bother budget with scheduler quotas, the non-renunciation telos (t.coltivazione_strumenti) and the stop clause. The TELOS.md file lives in the workspace.

13.6 Vocabulary and primitives

The closed vocabulary stands at 26 actions (read, write, move, delete, create, find, list, filter, sort, group, classify, get, set, send, describe, render, extract, compress, compute, compare, change, order, share, open, login, act) and 27 objects (files, dirs, packages, messages, events, contacts, places, processes, urls, numbers, images, signatures, texts, proposals, persons, tasks, inputs, approval, credentials, issues, pulls, calendars, entries, lists, skills, sites, preferences). Qualifiers come in four families: format/encoding, modality, safety policy, and provider (for specific non-default backends like _google_workspace). Centralised in runtime/vocab.py.

The planner currently exposes nine consumers for lists of entries. The five structural or numeric operators are filter_entries, filter_lists, sort_entries, group_entries, and compute_entries. The four in-process semantic helpers are classify_entries, compare_entries, extract_entries, and describe_entries. The first group filters one list, combines two lists, sorts, merges/deduplicates, or computes an aggregate; the second classifies, compares semantically, extracts structured records, or summarizes. The list is checked against the runtime registry and signed manifests. Concrete user example: «Is there an HLT appointment that overlaps with an MNM one in the next 3 months?» → the planner builds in six steps read_events → filter HLT → filter MNM → filter_lists(op=overlap) → final_answer. In extraction, dates come out as ISO 8601 when day, month, and year are written in the text. Many sites omit the year on recent rows: there the value carries the current year with a leading asterisk (*2026-05-29), which states that the year was assumed rather than read. The field stays empty only when no date can be derived at all: a visible date never becomes an empty field.

This guide does not copy a changing executor count into prose. The generated catalog is rebuilt from signed manifests and provides the current inventory. The Composer sees the same contract for every executor and does not select by transport. Five orthogonal producer verbs (find for patterns, get for ids/state, read for blobs from a source, list for containers, filter for reduction).

13.7 How to read the contracts

The pages linked from this guide distinguish what the system provides today from what remains proposed. Read them with these rules:

14. The principles, in eight cards

If you remember only eight sentences from this document, make it these. Everything else — code, prompts, conventions — follows from here.

1Vectorized by construction. Every executor accepts a list and returns a list, even a degenerate one. The batch version is the executor: *_batch does not exist.
2A closed, governed vocabulary. Everything that acts has a composable name inside a closed grammar. A new term enters only if necessary, general and understandable.
3No silent failure. Counts reflect what actually happened; truncation is declared, not hidden; a partial result presented as complete is a bug.
4Deterministic > LLM. Where an automaton or a table suffices, the model is not used. The LLM enters where an equipotent parser would genuinely be too complex — and it enters constrained.
5Never an implicit delete. Every move is copy → check → delete; never DELETE without a confirmed COPY.
6Reversibility with a rationale. Every evolutionary act (synthesis, merge, archive) is reversible and motivated. Saying yes costs less when you can go back.
7i18n by construction. Every user-facing string and prompt is per-language data: a new language is a translation pack, not a fork of the code.
8Understandability as a duty. If the user does not understand the system, the system is useless. Simplicity is not aesthetics: it is the criterion that selected everything else.

15. What Metnos is NOT

Half of the design lives in the no's. Every temptation to add an item from this list must be resisted.

16. Where to go next

You now have both levels: the system from above and the map of its component contracts. Use the atlas for implementation detail, or continue with the tour, the domain reference, and the interface guide.

reference
Component contracts
Return to the atlas and open the exact implementation contract you need.
operational reference
Domains and examples
What you can ask Metnos, domain by domain, with natural phrases ready to adapt.
introductory guide
The interface
The two channels, the Settings sections, and the map of pages with their navigation paths.
tour · 10 min
Quick Tour
The fast lap with screenshots: what using it feels like, before studying it.
operational guide
Tutor
How Metnos compiles current sources and explains capabilities, procedures, and pages without executing operations.
component contract
Remote executors
How Metnos moves selected executors from the server to a registered PC while keeping policy, audit and explicit limits.
code
The repository
AGPL-3.0, pre-1.0: the public subset of the daily-driven instance, installer included.

Metnos — Architecture Guide.
Bilingual IT+EN documentation at metnos.com; code at github.com/brunialti/metnos.