← Documentation index Architecture › skills & backends

Metnos

skillbackend — two orthogonal axes
Architecture of the skill-versus-backend boundary
Audience: anyone who wants to know where a provider ends and a skill begins.

Reading time: 12 minutes.

Table of contents

  1. Two orthogonal axes
  2. The three skill tiers
  3. From one provider to many
  4. On/off lives on the backend
  5. Promotion: the mechanism
  6. How the others do it (Hermes, MCP)
  7. Going deeper
  8. What this means for you, in practice

1. Two orthogonal axes

In Metnos «skill» and «backend» answer two different questions. The backend says HOW a verb_object runs against a service. The skill says WHETHER and WHICH capabilities are unlocked, trusted and shipped. Conflating them leads to splitting executors apart; keeping them separate is what lets you add a provider without touching the planner.

 Backend / providerSkill
AnswersHOW I run verb_object against a serviceWHETHER / WHICH capabilities are unlocked, trusted, shipped
Axisobject × providerexternal dependency (credential / backend / hardware)
Visibilityinvisible to the LLM, resolved from configuration by the backend resolveruser-facing (enable / disable, dormancy, sandbox, packaging)

The two axes touch only when a skill has a single provider: in that case github, geo, mail are in practice the user-facing name of that provider's backend. They diverge as soon as a skill has several backends (a calendar is served over local ICS, Google or CalDAV) or has no external provider at all (photos, the core). The map is many-to-many: one provider (Google Workspace) serves several skills — mail, calendar, drive, sheets, docs.

Anti-duplication rule. The external dependency (credential, service endpoint, hardware) is declared once, at the backend. The skill aggregates it — the union of its backends' requirements — and does not re-declare it. The skill's dormancy is derived from its backends, not hand-written.
execution axis — HOW (invisible to the LLM) skill axis — WHETHER PLANNER (local model) always sees only find_issues canonical EXECUTOR provider-agnostic (object issues) BACKEND RESOLVER picks the provider from configuration github backend gitlab backend SKILL = activation / dormancy github skill (PAT) turns the github backend on/off gitlab skill (token) turns the gitlab backend on/off independent dormancy per provider does not change the planner pool
Figure 1 — The two axes. On the left, execution (planner → canonical executor → resolver → backend): invisible to the LLM, resolved from configuration. On the right, skills: they turn backends on and off, but never change the planner's pool, which always sees find_issues.

2. The three skill tiers

«Skill» ended up meaning three different things: a classification of executors already in the repository, real packages in the repository, and imported third-party code. The tier field unifies them under a single model. It lives in skills_catalog.py (function skill_tier()) and in the SKILL.md front matter.

TierWhat it isTrustWhere it livesActivation
1 — coreplanner and engine, local files, dirs, processes, time, local scheduler, persons, credentials, signatures, proposals, the scratchpad helpers (filter / sort / group / compute / describe / extract)maximumrepository, signed, multilingualalways on
2 — first_partycapabilities shipped with Metnos at the same standard as the core, but dormant until the dependency is present: github, photos, mail, web, geo, calendar, frontier, Google Workspacemaximumrepository (versioned bundle + signed executors)automatic, dormant if not configured
3 — importedthird-party code, not audited nor vendored (from agentskills.io and the like)lowuser data, with tracked provenanceopt-in, sandbox + 7-layer net
What gets shipped publicly. The release carries only tier 1 and 2, inside the signed repository. Tier 3 is not shipped: the user installs it, and it is precisely there that the README's security thesis applies («do not trust the package»). Promotion from tier 3 to tier 2 takes four joint yeses: generally useful, compatible license, willingness to maintain it (undo, i18n, re-sign), and support for a capability already in the catalog.

3. From one provider to many

Tomorrow GitLab might arrive alongside GitHub. The question is: how do you add a second provider for the same issues? Two paths.

Option (a): split the executor — REJECTED

Generate find_issues_github and find_issues_gitlab and let the planner choose. This works where a frontier model sits at the center and disambiguates by reading prose. In Metnos the planner is a local model, which faced with two nearly identical names develops a provider bias: it always picks the same one, or gets it wrong. Splitting breaks routing.

Option (b): abstract — CHOSEN

Cost of a new provider: +1 backend file, +1 skill (if it introduces a new credential), 0 new executors. It is the path calendar and files have already taken.
today: «baked-in» (debt) after: abstracted local PLANNER — confused find_issues _github find_issues _gitlab two near-identical names → provider bias local PLANNER — sees 1 tool find_issues (canonical) backend resolver github backend gitlab backend promotion one-off frontier + human review
Figure 2 — Mono→multi provider. On the left the «baked-in» state (find_issues_github + find_issues_gitlab confuse the local planner). On the right the abstracted state: a single find_issues, the resolver, two backends. The arrow is promotion: refactoring with a one-off frontier, then human review.
Known debt. Today GitHub is «baked-in»: the thirteen *_github executors carry the provider in the name. It works while the provider stays unique; the moment a second one arrives it must be abstracted. General rule: a provider that plausibly will have siblings (github→gitlab/gitea, IMAP mail, calendar) should be abstracted from the start; one that will stay unique may remain baked-in.

4. On/off lives on the backend

In the multi-provider model the skill does not turn the executor on and off: it turns the backend on and off. This changes who sees what.

Desired effect: turning a provider on or off does not change the planner's tool pool — it always sees find_issues — it only changes routing. Disable one of the two: the other keeps serving. Disable both: the executor goes dormant.

Today gating is by pattern on the executor name (skills_catalog): it works only while the provider is unique. The new piece to build is a skill→backend map plus the rule «executor dormant = AND over all its backends being off». It is the first brick: needed as soon as the first multi-backend executor exists.

5. Promotion: the mechanism

Merging a baked-in, mono-provider skill (*_github) into find_issues + backends is an extraordinary operation. A one-off frontier LLM is allowed ONLY for the refactoring; detection and apply stay deterministic and human-gated — auto-signing frontier-generated code would break the trust model.

PhaseWhoWhat
WHEN (trigger)deterministicon the 2nd provider's arrival — typically the import of a skill that maps onto an object already covered only by provider-suffixed executors (*_github, recognized by the naming authority). Object overlap + provider mismatch → «promotion candidate». No LLM needed to spot it.
WHERE (seam)reused infrastructuredetection in the importer admission layer; refactoring via an escalation to a frontier model in agentic mode; landing in the admin changes page as a change of kind promote_provider, no auto-apply; apply writes the files, re-signs (§7.10), registers skill↔backend and per-backend gating (§4).
HOW (pipeline)frontier only in the middledetect (det.) → the frontier generates {canonical executor + backends/<obj>/{p1,p2}.py + skill→backend map} → the change is proposed → human review → apply + sign + verify with the 7-layer admission + smoke.
Deterministic edges, creative center. The frontier sits only in the middle: it drafts the refactoring. The edges — noticing it is needed, and applying with a signature — are deterministic code and human hands. Three new, independent, incremental pieces: (1) a promotion-candidate detector; (2) the promotion prompt for the frontier escalation; (3) the per-backend gating of §4 — which is needed anyway and is the one to build first.

6. How the others do it (Hermes, MCP)

To see why Metnos separates skills and backends while the others fuse them, look at who sits at the center choosing the provider.

 Hermes / drop-in skillsClaude-Code + MCP familyMetnos
who picks the providerfrontier (reads SKILL.md, disambiguates)frontier (reads tool descriptions)medium local model (Gemma): has a bias on the provider
skill vs backendfused (skill = folder of scripts = provider)fused (tool / MCP server = provider)separate (backend = execution, skill = activation)
multi-providerparallel skills per provider, the agent choosesparallel tools / servers, the model choosesone canonical executor + one backend per provider (resolver)
credential / dormancyrequired_credential_files + setupimplicit (server connected or not)formalized dormancy
trustruns the skill's code with its own privilegesruns tools / serversclosed vocabulary + 7-layer sandbox
A forced consequence, not a lag. Hermes and the MCP clones put a frontier at the center: they can afford parallel skills or tools per provider (option (a)), because the model disambiguates from prose. Metnos runs on a local model, where (a) produces provider bias → it must abstract (option (b)). The skill↔backend separation is not an architectural lag: it is the inevitable consequence of the local planner and the security-by-construction model.

7. Going deeper

To understand…Read
how a third-party skill is imported and turned into signed executorsskill importer
the layered sandbox imported executors run insandbox
the checks before every risky actionvaglio
what an executor is and how it is builtexecutor

8. What this means for you, in practice

What this means for you, in practice. From your point of view, what does all this change? Not much. This complexity lives under the hood. You'll only run into it when you use functions that do the same thing but are offered by different providers — and in fact, only the moment you add the second provider for the same capability: at that point you just ask to «merge» the two skills, and Metnos creates a new backend. Honestly: how often will that happen in everyday use of a tool like Metnos? How often will you use GitLab and GitHub at the same time?
The upside. Metnos is built to stay as local as possible, at no added cost: the brain you use every day runs on your own machine. That abstraction complexity — merging two skills into a backend — is the only moment where, and only if needed, Metnos turns once to a frontier model (presumably paid) to generate the new backend's code. An occasional, explicit, rare cost — not a continuous dependency on the cloud. The rest of the time you are, and stay, local.

Metnos — skill ↔ backend, two orthogonal axes