The production path applies a deterministic guard immediately before invoking an executor. The guard blocks closed classes of dangerous accesses and commands. The module also exposes a graded judge, but that second phase is not part of the current engine's ordinary path: documenting both as if they always ran would be inaccurate.
The Vaglio checks one action that the engine has already selected. It does not select the executor, interpret the request by itself, grant permissions, or replace the policy, human consent, sandbox, or executor-level checks.
The main distinction is between:
judge(intent, executor_name, args, context) returns a
Verdict with these fields:
| Field | Meaning |
|---|---|
approved | Whether the action passes the complete call. |
reason | Readable reason produced by the guard or judge. |
ts | Unix time of the decision. |
judge_kind | rule-based-v1,
llm-v1, or safe-verb-shortcut. |
score | A value from 0 to 1; it is 0 for a guard block. |
blocked_by | guard, judge, or
no value when the call approves. |
This contract describes the module's complete API. It does not imply that every call site uses both phases.
guard_check(executor_name, args, context) recursively inspects
arguments that may represent an access target. Strings under content fields such as
body, text, comment, or message are not treated as paths: mentioning a protected
path in a document is not the same as accessing it.
The guard applies three families of checks:
~/.ssh, cloud credentials, /etc/passwd,
/etc/shadow, /root, /boot, and block
devices.The first violation returns (False, reason). With no match, the
guard returns (True, None); this does not certify that the action is
harmless under every possible effect.
If a caller uses judge(), the guard runs first. After a positive
guard result, verbs in the SAFE_VERBS vocabulary take a short circuit
and receive an approved verdict with
judge_kind=safe-verb-shortcut.
For other verbs, the default rule-based-v1 backend starts from a
base score, adds signals that match the intent to the executor, and reduces the
score for indicators such as path traversal or unusual argument names. The final
comparison uses METNOS_JUDGE_THRESHOLD, whose default is
0.30.
This score is a local heuristic. It does not prove alignment with the user's ends and must not be described as a general semantic verification.
With METNOS_JUDGE_KIND=llm-v1, a caller of judge()
uses the middle LLM role. The prompt follows the turn language and
receives the intent, executor name, argument keys only, and selected context
fields; argument values are not sent.
If the router, call, or parsing fails, the module returns a fallback score of
0.5. With the default threshold, this degradation tends to approve.
It is therefore an explicit availability behaviour, not fail closed and not a
security guarantee.
judge() writes monthly JSONL records under the user's
vaglio/ directory. A record includes the verdict, intent, executor,
argument-key names, and context-key names; it does not include argument values. A
logging failure does not change the verdict.
The log makes an API decision inspectable. It does not reconstruct the whole turn by itself, nor does it turn a model's explanation into evidence.
The shared engine receives guard_check as
vaglio_guard. It invokes the guard immediately before the executor
and during parallel-wave preflight. A block produces a result in the
vaglio_guard error class and aborts the plan before the effect.
The engine has a separate judge hook, but the current dispatcher does not pass
judge() to it. Therefore, in the ordinary path:
| Component | Status in the production path |
|---|---|
| Deterministic pre-execution guard | Wired and active. |
| Rule-based or LLM graded judge | Available as an API, not wired into the ordinary dispatcher. |
| Policy and human approval | Separate flows, applied when required by the capability contract. |
| Module cross-user check | Helper available; its existence does not prove that every send calls it. |
Ask Metnos with a request like this example:
“Read /etc/hosts and show me the uncommented lines.”
Reading a configuration file is not confused with changing the system tree. If
you instead ask “Replace /etc/hosts with this content,” the
guard recognizes the mutating verb and protected path and stops the step before
invocation.
The visible answer should describe the blocked operation and a useful reason in the turn language. The guard's internal text remains technical data and does not authorize the renderer to invent exceptions.
| Setting | Default | Effect |
|---|---|---|
METNOS_JUDGE_KIND | rule-based-v1 | Backend used by callers of judge(). |
METNOS_JUDGE_THRESHOLD | 0.30 | Threshold for the graded judge. |
runtime/vaglio.py: guard, judges, verdict, and logging.runtime/platform_policy.py: protected trees by platform.runtime/engine/executor.py: pre-invocation guard.runtime/agent_runtime.py: current dispatcher wiring.