[AVAILABLE].
packages/policy, 72 tests. CLAIMS.md 2.2/2.3.What it is
A Policy is a named, versioned, ordered list of rules. Each rule pairs a condition (a boolean expression over named “signals”) with an outcome: approve, reject, or require override.PolicyEngine evaluates a transaction’s signals against a policy’s rules and
returns exactly one Decision.
Why it exists
Every action Parmana authorizes has to be justified by something a human can read and a machine can evaluate identically every time. A policy is that something: not a prompt, not a model call, a plain data structure that produces the same outcome for the same input, every time, forever. That’s what makes an authorized action defensible after the fact.How it behaves
The runtime executes exactly one, explicitly referenced policy, identified byPolicyReference { name, version, schemaVersion } on the Business Transaction. It does not
discover policies, negotiate them, auto-select “latest,” or substitute an alternative.
PolicyRouter loads by exact name and version; PolicyValidator checks the loaded policy’s
identity before evaluation runs.
Rules are evaluated sequentially, first match wins:
findFirstMatch returns null, and the outcome defaults to REJECT
(PolicyEngine.ts:191-206, toOutcome’s default case). There is no code path where an
unmatched transaction is approved. This is what “fail closed” means here in practice: the
absence of a rule is a denial, not a pass-through. A trailing { "always": true } rule
typically makes the reject-by-default behavior explicit in the policy document itself.
Binding a signal to the executed Intent
Evaluatingtransaction.signals alone has a gap: nothing, by itself, connects those signals
to transaction.intent — the action, target, and parameters that actually get signed and
executed if the Decision is APPROVED. A caller could declare signals describing a small,
fully-verified action while intent executes something else entirely, and still receive a
signed APPROVED trust record for it. This was a real, live bypass, not a hypothetical one —
see Security for what it looked like in practice and how severe it was.
Policy.boundSignals is the fix: an optional map from a signal key to an intent dot-path.
Every entry declares “this signal must equal this exact field of what’s actually executed”:
SignalIntentBinder (packages/policy/src/SignalIntentBinder.ts) checks every declared
binding by strict equality — a signal the caller never declared at all counts as a violation,
not a pass, since undefined almost never equals a real intent value:
RuntimeEngine.execute (packages/runtime/src/RuntimeEngine.ts) runs this check immediately
before PolicyEngine.evaluate, over the exact signals about to be evaluated and the exact
intent that will be signed and executed if approved. A violation is built into an ordinary
PolicyDecision with outcome REJECT and a reason naming every mismatched field — no rule is
ever evaluated, and no authorization is ever generated for a mismatched request, the same
fail-closed shape as any other policy rejection (see Write your first
policy for what a rejection actually does).
Minimal example
Frompolicies/vendor-payment/2.0.0/policy.json, a real policy in this repo:
What a Decision records
TrustChainValidationComponent and RuntimeEngine refuse to execute when required trust
artifacts are missing or the Decision is not APPROVED (CLAIMS.md 2.4). Only an APPROVED
Decision can produce a signed execution authorization.
Next
Execution authorization
What an APPROVED decision becomes: a signed, single-use envelope.
Determinism and clocks
What “deterministic” means precisely, and where it does and doesn’t apply.