Seven Layer
Authority Fabric

Offline verification

A verifier that holds no socket, no path and no clock — it checks only what you hand it, and it never answers with a boolean.

The claim is that a complete result or refusal can be checked after every SCSA service has been stopped. scsa-verify is the thing that makes the claim checkable — by a customer, an auditor, or a regulator with no reason to trust the people who built the system.

It is written as the adversary's tool, not ours. Three consequences follow, and they explain most of the design.

1. It cannot reach anything you did not hand it

verify takes a set of inputs, every field of which is a byte slice. There is no path, no socket, no clock and no ambient configuration in the signature, so a reviewer does not have to take a promise on faith — the type says what the function can see.

Freshness is evaluated at the envelope's own decided_at, which is the only defensible reference point. An auditor opening an archive in 2031 is not asking whether the evidence is fresh today; they are asking whether it was fresh when the decision was taken.

2. It never answers with a boolean

"Invalid" tells a relying party nothing they can act on. The verifier returns a verdict: a list of named claims, each one of

StatusMeaning
VerifiedThe claim was checked and holds.
FailedThe claim was checked and does not hold — with the reason.
UnevaluatedThe object needed to check it was never supplied.

The one confusion the crate exists to prevent is Unevaluated reading as Verified. So there is no is_ok(), no boolean on the verdict, and the overall summary cannot be Verified while any claim is unevaluated.

This matters more than it sounds. Most verification bugs in the wild are not "checked and got the wrong answer" — they are "never checked, and the caller assumed otherwise."

3. A refusal is a product, not an error

An envelope carrying Refused is verified exactly the way a completed one is, and a clean result is reported as verified, flagged as a verified refusal.

"No permitted operation completes unilaterally" is only a claim a customer can check if the denial is portable evidence — and evidence a tool reports as a failure is not portable evidence.

A refusal is invited to name the object it refused over, because the naming form is the only one an operator can act on: it identifies which appraisal expired.

What gets checked

Given an envelope and whatever supporting objects you have:

  • The envelope's canonical encoding round-trips byte for byte. If re-encoding the decoded object does not reproduce your input, the signature covers different bytes than you are holding.
  • The signature verifies against the named authority, under the correct domain separation for its object type and schema version.
  • x_wrap and x_auth are each bound to every field they claim to bind, and neither is presented in the other's place.
  • A Completed outcome carries a transparency inclusion proof, and the proof checks against the stated root at the stated size.
  • Consistency between checkpoints, where you supply two.
  • The quorum actually met its threshold and its diversity floor, counting only execution shares — human approvals and attestations are not counted as shares.
  • Evidence was inside its freshness window at decided_at.
  • The constitution digest the decision was taken under is the one you expected.

Anything you did not supply comes back Unevaluated, by name, so you can see the hole rather than infer its absence.

Getting the bytes

GET /v1/operations/{intent_digest}/bundle

returns a canonical EvidenceBundle in audit scope — everything needed to check the decision, without seat contributions.

GET /v1/operations/{intent_digest}/recipient-bundle

returns the bundle including contributions, for the party the operation was performed for.

Archive the bundle. It is self-contained: verification years later needs the bundle and the verifier, and nothing else that is still running.

Cross-implementation status

Three implementations of the canonical encoding exist: the Rust reference, a TypeScript verifier, and a JavaScript implementation written from the published wire-format specification alone. The third reproduces 134 of 134 test vectors emitted by the reference — every object digest, digest construction, primitive, canonical-CBOR reject and specified ambiguity — with zero disagreements.

That establishes the specification is sufficient to implement against: an engineer with the spec and no access to the reference produces byte-identical results. It does not establish independence — all three implementations were written by the same team, so a shared misreading of RFC 8949 would be reproduced faithfully by all of them. Treat cross-implementation agreement with an outside party as still unproven.

On this page