This page is the entry guide to Metnos microdesign. It does not describe the system from above — that is the job of Architecture — Introduction — but it shows you the parts: how they are named, what they do, how they talk to each other. We move from the general to the particular, fixing each term before we use it.
Metnos architecture lives on two tiers. The upper tier — Level 1
— describes the system as a whole: the four layers, the organs, the laws,
the ends. You find it in
Metnos_Architecture_Intro_v1.html.
This folder is the lower tier, Level 2: one HTML document per component, with the level of detail you need 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.
Everything in Metnos revolves around four nouns. Defining them now saves half an hour of confusion thirty lines down.
/opt/metnos/executors/ and synthesised ones under
~/.local/share/metnos/executors/, plus those imported from
external skills.There are twenty-one documented components. The diagram below groups them 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.
Three observations to read the diagram well.
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».
move; object:
files; criterion: invoice-attached PDFs in the «last
week» window), asks the prefilter to narrow the catalog to relevant
executors, and prepares the first step of the ReAct loop.rm -rf and
friends). For grey-zone operations, the rule-based judge assigns a score
and, above threshold, asks the user for confirmation via the
three-line card (what / where / why).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.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.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.
Below, the twenty-one documents grouped by role. All have an Italian
counterpart at
/it/architecture/.
| Component | Scope |
|---|---|
Cognitive engine |
The four-layer engine that plans and executes (replaces the iterative step-by-step planner): Fastpath serves user-approved shortcuts (hash + BGE-M3 cosine), Autopath recognises and reuses skills learned from feedback (sqlite, semantic + intent match), Validator checks the plan before running it, and the Engine block proposes the whole plan in a single local LLM call (Proposer), executes it deterministically (Executor), recovers by classifying the error into 4 classes (Recovery) and, if there is no way out, honestly explains what is missing (Terminator). One proposal instead of six calls: faster, zero cost, and faster still as it learns. |
agent_runtime |
ReAct loop, mode router, data piping between steps (from_step: int for lists, {{stepN.field}} for scalars), scratchpad, mnestome hooks. The engine that calls everyone else. |
scratchpad |
Per-turn temporary store: holds large observations without crowding the planner’s context. Builtin scratchpad_read with head/tail/range. |
grammar |
Constrained generation via GBNF for the PLANNER tool_call. Discriminated union name+args, recursive schema, contextual pool filter, post-decode validator. Solves thinking-loop, args mix-match, arbitrary escape-hatches. Bench convergence 50% → 100%. |
introvertive fast-path |
Three layers of memoization before the planner: L0 literal patterns (“what time is it”), L1 single-tool via canonical_matcher with BGE-M3 match on the canonical query log, L2 multi-step sequences via multi_tool_paths with active-day TTL. L2→L3 bridge to synthesis via proto-mnest. Hybrid argument extractor regex + memory + optional LLM. Persistent config in ~/.config/metnos/runtime.toml. |
lifecycle |
Unified system-change lifecycle: one change_intent object, one state machine (proposed→accepted→applied→observed→finalized, plus staged/rejected/failed/rolled_back), one UI /admin/changes. Funnels the proposal sources (telos, introspective, synt, fast-path, feedback) into one queue. Nightly pipeline: materialization (cross-source fingerprint dedup), per-kind application, observation with a grace window and physical rollback. |
| Component | Scope |
|---|---|
executor |
Anatomy of an executor: TOML manifest, Ed25519 signature, sandbox profile, lifecycle, vector contract (list-in, list-out). Current pool: 79 executors, including the multi-tier crawler (find_urls, read_urls_html, read_urls_pdf, login_session, group_entries) and handcrafted ones such as compute_files_loc. |
synt |
How new executors are born: five-stage pipeline (naming, signature, tests, description, code), reactive cascade (compose → generate) and introspective cascade (dedupe, generalize, specialize). |
skill_importer |
Imports third-party skills from agentskills.io and turns them into Metnos executors: five-stage pipeline (fetch, parse, map, wrap, register), verb mapping table skill_vocab_map.json, wrapping helpers with verb boundary, and CLI 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. |
| Component | Scope |
|---|---|
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. |
| Component | Scope |
|---|---|
vaglio |
Binary guard (forbidden paths, near-unrecoverable shell commands) and graded rule-based judge with configurable threshold. Probabilistic LLM judge deferred. |
policy |
Capability registry: thirteen canonical capabilities, 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. |
| Component | Scope |
|---|---|
channel |
Channel adapter (Protocol with send / poll) and first concrete implementation: TelegramChannel with long-poll, last_update_id persistence, daemon and systemd user unit. Multi-user: send_to(chat_id, OutboundMessage) + /start <token> for guest pairing. |
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 |
Three-line card for confirmation prompts: render_approval_card, ApprovalRequest, modulation full / medium / short by recurrence, Telegram dispatcher approve:<tok> / reject:<tok>. |
| Component | Scope |
|---|---|
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. |
| Component | Scope |
|---|---|
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. |
The closed vocabulary stands at 23 actions
(read, write, move, delete, create, find, list, filter, sort,
group, classify, get, set, send, describe, render, extract, compress,
compute, compare, change, order, share) and 22 objects
(files, dirs, packages, messages, events, calendars, contacts, places,
processes, urls, numbers, images, signatures, texts, proposals, inputs,
credentials, entries, persons, tasks, issues, pulls). 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.
Three pipeline primitives work on the turn's lists of entries:
filter_entries reduces one list (predicates on a field:
where_starts_with, where_contains,
where_glob, where_regex), filter_lists
combines two lists (set ops: intersect, union, difference, symdiff,
temporal overlap), compute_entries produces a scalar from
one list (sum, avg, min, max, count). 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.
The executor pool stands at 79 units across
hand-crafted and synthesised, plus executors imported from external
skills (Google Workspace, etc.). Five orthogonal producer verbs
(find for patterns, get for ids/state,
read for blobs from a source, list for
containers, filter for reduction).
Every microdesign file follows the same template as Architecture — Introduction:
id;MUST / MUST NOT / OK / ERROR
pattern, four lines max;