For example, you can ask Metnos: “Find the PDF files modified today.” If you later repeat the same request, Metnos may reuse the plan that already worked. There is nothing to enable: the check happens automatically.
Before calling the planner, Metnos tries to recognise the request. If a reusable plan exists and is still valid, it runs that sequence of executors. If the context or catalogue has changed, it treats the entry as invalid and returns to normal planning.
Planning is needed when a request is new or requires a new composition of
capabilities. Repeating it when the system already holds a valid plan adds work
and variability without improving the result. For example, a request already
solved with get_urls and describe_entries can reuse
that sequence, provided its arguments are derived from the current request.
What remains is to recognise a known request — and to judge when one that is merely similar sits close enough to be handled the same way. Two reuse layers handle this distinction. They recognise different degrees of similarity, but share one purpose: run a known plan without asking the planner to build it again.
Both layers reuse plans that have already run, but at different levels of generality. L0 starts from one request: an exact match may reuse a plan that contains request-specific values. Only plans known to be generalisable are eligible for L0's semantic match against differently worded but equivalent requests. L1 instead starts from the complete intent and a group of related requests; before execution, values that depend on the question are derived again from the current text.
| Layer | What it recognises | How |
|---|---|---|
| L0 | An already solved request. Exact matching may retain a request-specific plan; semantic matching is limited to plans that are safe to generalise. | Deterministic fingerprint (0a), then similarity through the configured embedding model (0b) |
| L1 | A family of requests. Reuses a general plan associated with a complete intent and a semantic group. | Intent, semantic similarity, and deterministic selection of the best plan |
The order is fixed: L0 first; if it finds nothing, L1. If both miss, the request reaches the planner (the engine), as always.
The planner does not disappear: L0 and L1 are controlled shortcuts. A new or ambiguous request, a turn with attachments, or a request without a valid match continues through the normal engine.
fastpath.py)
The first layer lives in runtime/engine/fastpath.py and stores
previously executed plans in a SQLite database
(fastpaths.sqlite). An entry is created after a successful turn
produced by the engine, L1, or an L0 semantic match. Metnos records the
normalised request, its fingerprint, an embedding when available, the complete
plan, and the intent expressed as a verb and object. No separate approval is
needed: the plan consists of admitted executors and has just completed a real
execution successfully.
The search runs in two phases:
An L0 entry removed because it aged, became invalid, or received negative feedback can be recreated by the next successful turn. Removing it does not remove the underlying capability.
undo_last_turn,
get_inputs, get_approval, and authenticated browsing
tools produce no fastpath, because their meaning or session identifier depends
on the current turn.since_iso="2026-06-11") is not recorded: replaying it on
another day would open a time window already frozen in the past. Relative dates
(time_window="today") are kept, because each replay works
them out afresh.autopath.py)
The second layer lives in runtime/engine/autopath.py. It does not
look for the same wording. It finds a semantic family, checks that the intent
object matches, and reuses only plans without literal arguments tied to the
original request. Variable arguments are derived again from the current
request before execution.
An autopath can arise in two ways. Positive feedback promotes a successful plan once it reaches the configured threshold, which is one confirmation by default. Alternatively, two successful runs of the same intent can seed a shadow autopath when the latest plan contains at least four steps. A shadow is usable but remains distinct from a confirmed plan; the first positive rating confirms it. This second path reduces the cost of recurring requests without presenting a non-human signal as human approval.
The boundary is deliberate: L0 favours repetition of the same request; L1 generalises to a family of requests and may derive either from explicit feedback or from the shadow seeding described above. L0 comes first in the cascade. Before execution, both layers validate their signatures, realign arguments with the current request, and pass through the same preparation and safety checks used for a new plan.
Every stored plan carries two signatures: one for the executors it uses and one for the candidate family available for that intent. The signature also incorporates the version of routing and presentation rules. Metnos recomputes them before reuse: a changed or removed executor, a new competing capability, or a routing change turns the entry into a miss. The system replans instead of executing a decision made in a different operational context.
These signatures are user-agnostic and contain no profiles, affinities, or personal preferences. L1 therefore remains a shared cache of plan decisions with deterministic keys. Effects authorised for the user and final presentation — language, tone, length, and format — are applied outside the plan key.
The candidate family comes from the canonical vocabulary, including the
relationships between specialised content and filesystem carriers. For
example, a new files capability may change a plan operating on
images or texts. Query words and manifest affinities
do not enter the signature: invalidation follows catalogue semantics without
making L1 specific to a user or to one phrasing.
L0 fastpaths are retained or retired by fixed rules, with no model in the
loop. Each night the task_state_reaper process applies three aging
rules and four retirement conditions.
| Rule | Criterion | Default | Env |
|---|---|---|---|
| Never reused | Created more than N days ago but never served a second time | 14 days | METNOS_FASTPATH_GRACE_DAYS |
| Stale | Last use more than N days ago | 30 days | METNOS_FASTPATH_STALE_DAYS |
| LRU cap | Total entries above the cap; least recently used are pruned | 500 | METNOS_FASTPATH_MAX |
| Code | Cause | Transfers usage |
|---|---|---|
| C1 | A tool in the plan no longer exists in the catalogue (retired, renamed, archived). Replay would fail. | No |
| C2 provenance | The fastpath was promoted to a synthetic executor (see §9) and that executor is now in the catalogue. | Yes |
| C2 name | An executor named {verb}_{object} matching the intent exists, but no tool in the plan belongs to that family. The fastpath would shadow the executor. | Yes |
| C2 pre-filter | For multi-step plans: the deterministic routing pre-filter on the canonical query shows that a single executor now covers the intent (even under a different name). | Yes |
When a fastpath is retired because an executor superseded it (the C2
conditions), its usage count (n_uses) passes to that executor
through the lifecycle statistics store. Previously observed usage is therefore
not reset.
Pruning removes a stored route, not its executors. If the same request returns and succeeds, L0 can record the updated plan again.
Recognising a plan is not enough: it must also be bound to the values in the current request, such as paths, URLs, accounts, dates, or quantities. Before every execution, Metnos applies one shared sequence of deterministic transformations. Each transformation operates only on fields declared by the executor schema; when there is no reliable signal, it does not invent a value.
args_extractor.py identifies known types, including URLs, Linux
and Windows paths, email addresses, explicit quantities, file extensions
(“PDF files” becomes *.pdf), dates, and time windows in
Italian and English.This preparation also applies to plans retrieved from L0 and L1. A plan with literal values that cannot be generalised remains eligible only for the exact request; some plans, including those with embedded numeric identifiers or authenticated sessions, are not stored at all.
Fastpath and autopath thresholds are read from the Metnos process environment;
when a variable is absent, the module default applies. The former
[fast_path] and [multi_tool_fast_path] sections in
~/.config/metnos/runtime.toml have been retired and are ignored.
The Praxis page can inspect and flush the caches, but it does not edit these
thresholds. A persistent override therefore belongs in the service
configuration; constants read at import time require a process restart.
| Variable | Default | Meaning |
|---|---|---|
METNOS_FASTPATH | 1 | Enables L0; setting it to 0 disables the layer |
METNOS_CLUSTER_COSINE_HIGH | 0.90 | Base semantic threshold; L0 matching uses this value plus 0.02 |
METNOS_FASTPATH_STALE_DAYS | 30 | Calendar days after which an unused entry is pruned |
METNOS_FASTPATH_GRACE_DAYS | 14 | Grace days for never-reused entries |
METNOS_FASTPATH_MAX | 500 | Maximum rows (LRU cap) |
| Variable | Default | Meaning |
|---|---|---|
METNOS_AUTOPATH | 1 | Enables L1; setting it to 0 disables the layer |
METNOS_AUTOPATH_MIN_OBS | 1 | Minimum positive observations to promote an autopath |
METNOS_AUTOPATH_FLOOR | 0.87 | Minimum similarity on the exact-intent fallback |
METNOS_AUTOPATH_TTL_ANTI | 2592000 (30 d) | Anti-autopath duration in seconds |
METNOS_AUTOPATH_TTL_REPEAT | 3600 (1 h) | Temporary exclusion after a repeat request |
METNOS_AUTOPATH_KEEP_OBS | 5000 | Maximum recent observations without a verdict to retain |
METNOS_AUTOPATH_STALE_DAYS | 90 | Inactivity period before an active autopath is removed |
METNOS_AUTOPATH_DEMOTED_TTL_DAYS | 30 | Retention period for a demoted autopath |
METNOS_SEED_STEPS | 4 | Minimum step count for shadow seeding |
METNOS_SEED_REPEAT | 2 | Successful observations of the same intent required for shadow seeding |
| Variable | Default | Meaning |
|---|---|---|
METNOS_FP_PROMOTE_MIN_CLUSTER | 3 | Minimum distinct fastpaths in the group |
METNOS_FP_PROMOTE_MIN_USES | 15 | Minimum cumulative usage |
METNOS_FP_PROMOTE_MIN_AGE_DAYS | 30 | Minimum group age |
METNOS_FP_PROMOTE_MAX_PER_NIGHT | 3 | Maximum new proposals per night |
METNOS_FASTPATH_AUTOPROMOTE | off | Enables Mode 2 auto-promotion (no human approval) |
METNOS_FP_AUTOPROMOTE_MIN_CLUSTER | 5 | Minimum distinct fastpaths for auto-promotion |
METNOS_FP_AUTOPROMOTE_MIN_USES | 50 | Minimum cumulative uses for auto-promotion |
METNOS_FP_AUTOPROMOTE_MIN_NIGHTS | 3 | Nights on which the same proposal must have been observed |
When several recurring L0 fastpaths share the same plan structure (the skeleton
hash) and the same intent, each night the task_fastpath_promotion
process weighs them as candidates to become a synthetic executor in their own
right. What it weighs is the group, never the single instance: at least three
distinct fastpaths, fifteen uses in all, and thirty days of age. And only
multi-step shapes are promoted: single-step ones already have an executor, and
there the fastpath only saves the LLM call, not the plan.
Why from L0 and not from L1. The analysis looks at the L0 fastpaths, not the L1 autopaths, because evidence of concrete requests lives in L0: how many distinct requests recur, how often, and for how long (the three numbers above). L1 is already general and arises from user feedback or shadow seeding, but it does not retain that count of distinct requests. Generalisation therefore happens here by grouping L0 fastpaths with the same plan shape and intent.
For candidates whose family is free, Metnos records the source fastpath
identifiers and fingerprints in the promotions table. Once the new
executor enters the catalogue, the nightly process uses that link to retire
exactly the entries that produced it. Composition candidates do not receive
this automatic provenance because their final name depends on the
human-selected qualifier; their L0 entries remain manageable under
Settings > Memory > Praxis.
© 2026 Roberto Brunialti · Metnos documentation