Local intent verification

How the browser independently re-derives and checks what a transaction does before any signature is ever requested.

Local intent verification is the mechanism that lets you catch a lying or compromised PolicyVault server before you ever sign anything — without having to trust the server's own description of what a transaction does.

The core idea

Before the signing dialog offers any signing action, the browser:

  1. takes the exact unsigned-transaction bytes it is about to hand to your wallet and strictly decodes them — any unknown field, pre-filled signature, unexpected value, or malformed structure refuses outright;
  2. builds a requested intent from its own action context — the amounts you actually typed, the recipients you actually entered, the wallet identity you're actually connected with — never from a description the server supplied;
  3. combines that with the vault's covenant state the browser already independently knows (live outpoint, covenant id, protected value, fee reserve, approver slots, agent policies, recipient registry);
  4. derives an intent manifest — a structured, deterministic description of exactly what the decoded transaction does — using the same portable, deterministic code the server itself runs, executed locally in the browser rather than trusted from the server;
  5. cross-checks the manifest, the independently built requested intent, and the independently decoded transaction against each other through a complete, fail-closed set of checks.

On a full pass

The signing dialog renders a full human-readable explanation — the requested action, every output with its exact destination and amount, the fee, the vault's protected value and fee reserve before and after, exactly how much of the per-transaction cap and periodic budget this spend consumes, approval status, and any policy impact — along with the exact statement:

THIS TRANSACTION DOES EXACTLY WHAT WAS REQUESTED AND NOTHING ELSE.

On any failure

The dialog renders an unmistakable DO NOT SIGN state naming which specific check failed, and — critically — no signing action is presented at all. The signing flow independently refuses to proceed even if something tried to force it, at more than one point in the pipeline. This should never happen during normal operation against an honest server; it exists specifically as the backstop against a manipulated or buggy one.

Why this matters

This is the property that lets a PolicyVault client detect a manipulated server or frontend before a signature exists, rather than discovering damage after the fact. It only works because the verification code runs locally, using your own independently supplied intent — checking a manifest against a server-supplied description of "what you asked for" would prove nothing, since a dishonest server could just supply a matching description alongside a mismatched transaction.

Scope and honest limits

This is implemented in the JavaScript-based web client, using the same portable core the server runs. The Python client does not currently ship this local verification core — see Python SDK for that asymmetry stated plainly. And whatever the browser verifies, the wallet's own native display (see What KasWare signs) remains the final, irreducible check: a user who signs without reading either can still be misled by a fully compromised environment.

See also: If the hosted server is compromised, Covenant enforcement.