Control Attestation

When Asqav signs an action under compliance mode, it runs a sequence of enforcement controls before minting the receipt: an org-wide emergency halt check, a delegation scope check for delegated agents, a quorum gate for gated risk classes, a mandate gate, policy evaluation, and content scanning. Asqav records which of those controls genuinely executed on this sign in a server-built controls_evaluated block, signed into the receipt payload. An offline verifier holding only the receipt can read which controls ran without querying the issuer's database.

What controls_evaluated proves, and what it does not

controls_evaluated enumerates the enforcement controls that genuinely fired on this sign. Each key is present only when its control ran. An absent key means the control never ran or does not apply, never that it ran and passed silently. This omission-over-false rule is the whole point: a verifier reads presence as proof of execution and absence as honest silence.

Asqav never defaults a control to a passing value. A control that never executed is left out of the block entirely. A populated key carries the server-authoritative signal that proves the code path ran, derived only from what executed, never copied from the request body.

The controls_evaluated block

json
{
  "controls_evaluated": {
    "emergency_halt": { "checked": true, "halted": false },
    "delegation_scope": { "checked": true },
    "quorum": { "fired": true, "attestation_hash": "ec9694c4261f27e98b1556fa7774dd68369e79260b77a368f5af7c64a90a77ce" },
    "mandate": { "checked": true },
    "policy": { "evaluated": true, "matched_count": 2 },
    "content_scan": { "ran": true, "blocking": false },
    "result": "allowed"
  }
}

Per-key provenance, each server-built and never request-supplied:

Why an absent key is honest silence, never a silent pass

The dominant failure mode in a control-attestation block is a field that reads as passing when the control never ran. A policy: {evaluated: true} on a sign with no matched policy would tell a verifier a policy ran when none did. A content_scan: {ran: true} when the scanner is disabled would tell a verifier the content was scanned when it was not. Both are false attestations.

Asqav avoids both by omission. A control that never ran is absent. policy appears only when matched_count is at least one. content_scan appears only when the scanner actually executed. There is no tri-state where a key is present with a false value that a reader might mistake for a passing control. Absence is the fail-closed honest default.

A compliance permit with no matching policy signs an observation, not an allow

A common first sign under compliance mode asks for policy_decision: permit on an org that has not yet registered any ActionTypePolicy for the action type. A permit asserts that a policy allowed the action, but no policy ran, so signing a decision: allow receipt here would be a false attestation. Asqav instead auto-routes that one input to the honest observation receipt: it signs decision: observation with receipt_type: protectmcp:lifecycle, and the controls_evaluated block omits the policy key because zero policies matched. The receipt asserts no policy outcome at all, which is the truthful statement for an un-policied action.

So the downgrade is never silent, the sign response carries a policy_enforcement field set to observation_no_policy whenever this auto-route fires. A caller that set compliance_mode: true and policy_decision: permit reads policy_enforcement and decision from the response and sees that no policy matched and the receipt is an observation, not an enforced allow. On every other path the field is absent. The policy_enforcement field is a response-only signal and is not part of the signed receipt. The signed bytes carry only the honest observation shape.

A deny or rate_limit with no matching policy is not auto-routed. Those decisions cannot be honestly weakened to an observation, because doing so would drop a block the caller requested, so they are still rejected with HTTP 412 no_policy_evaluated_for_action_type. Register a policy for the action type to assert a real enforcement decision, or send policy_decision: none with receipt_type: protectmcp:lifecycle to sign an observation receipt directly.

The false-control-attestation guard

A receipt that carries controls_evaluated but is malformed is a false attestation, so Asqav rejects it before the receipt persists. The conformance gate fires the false_control_attestation_guard when the block is present but is not an object, carries an unknown control key, carries a quorum without fired: true and a 64-hex attestation_hash, or carries a policy with evaluated: true but matched_count below one. The verbatim guard messages are:

text
false_control_attestation_guard: controls_evaluated must be an object of fired controls (got: <repr>)
false_control_attestation_guard: unknown control key (got: <repr>)
false_control_attestation_guard: quorum requires fired=true and a 64-hex attestation_hash (got: <repr>)
false_control_attestation_guard: policy.evaluated=true requires matched_count >= 1 (got: <repr>)

Can a caller set controls_evaluated directly?

No. It is server-built only. A caller-supplied controls_evaluated in the request body is dropped before the request model is built, so it can never echo into the receipt. The block is assembled inside the sign handler from the actual control results in scope at the mint point.

How does an auditor use controls_evaluated?

The auditor holds the Audit Pack with the signed receipts. To weigh the control attestation, the auditor:

  1. Reads controls_evaluated from the signed payload.
  2. Reads each present key as proof the named control executed on this sign.
  3. Reads each absent key as the control not running, never as a silent pass.
  4. For quorum, recomputes or resolves the approved quorum session behind attestation_hash.
  5. For policy, reads matched_count as the number of active policies that matched the action type.

Related documentation