binding_ref, or a retention_chain_ref) so the bound record becomes version-provable (you can prove exactly which policy was in force) and rotation-detectable (a record sealed under policy P fails recomputation under a rotated policy P').
It is strictly additive over the frozen Layer 1. It introduces no new cryptographic primitive and changes nothing in the canonicalisation substrate — it composes the same RFC 8785 JCS + SHA-256 already in use.
Apache-2.0 open source. Install via
pip install algovoi-policy-binding or npm install @algovoi/policy-binding. Python and TypeScript are byte-for-byte identical on the same input. Adopters who pin and verify against the canonical vectors qualify for a free v0 licence key for the mandate auditor — see Adopters below.How it works
Two references, both computed with RFC 8785 JCS canonicalisation and SHA-256:policy_refis the content hash of the policy/ruleset/mandate snapshot itself. Because the policy is JCS-canonicalised first, key order in the policy document does not affect the result.policy_bound_refbinds that policy hash to asubject_ref— the frozen reference of the thing the policy governed. The construction is version-agnostic: thesubject_refis imported by hash, so the same construction binds a policy to a settlement-actionbinding_ref(v1) or to aretention_chain_ref(v0 or v1) without any change.
subject_ref is imported by hash, Policy Binding does not need to know — and is not coupled to — the internal shape of whatever it binds. The subject can evolve independently; the binding stays valid as long as the subject hash is unchanged.
What an auditor can verify
| Auditor holds | What they can check |
|---|---|
| A bound record + the policy document | That the record was sealed under exactly this policy (policy_ref recomputes) |
| A bound record + a different (rotated) policy | Rotation is detected — policy_bound_ref fails to recompute under P' |
| A bound record + the subject | That the policy is bound to this specific subject and no other |
Invariants
The construction holds five invariants, each backed by a conformance check:| Invariant | Meaning |
|---|---|
| Stability | The same (policy, subject) always yields the same policy_bound_ref across implementations and time |
| Snapshot-binding | The policy_bound_ref is bound to the exact policy bytes; any change to the policy changes the ref |
| Rotation-detection | A record sealed under P does not recompute under a rotated P' (negative case) |
| Subject-binding | The same policy bound to different subjects yields different refs; substituting the subject changes the result |
| Key-order-invariance | JCS absorbs policy key order — policy_ref(P) equals policy_ref(P) with its keys shuffled |
Conformance vectors
policy_binding_v1 — 14 checks across three subject types and both rotation directions. Cross-validated Python + TypeScript, byte-for-byte.
Subjects (the published canonical references from the conformance corpus):
| Subject | Canonical ref |
|---|---|
retention_chain_v0 | sha256:f15a1dcd03cc039204dff24619ff4815ad041ad8796b94f59d52252043d0d08f |
retention_chain_v1 | sha256:60081d57e585e6a7ee0b79e1204aae2be3739a539c6524074003408b3de1951e |
settlement_action_binding_v1 | sha256:7dc4a2bf62b3c5eabd10fc875ff7fc10f188666f15838c4a51464cc72e80f6ca |
| Policy | policy_ref |
|---|---|
P (aml.transfer v1) | sha256:acc943b05fa8e8096e5b313288bc4f919cc2661f167c833770509a53049afa1c |
P' (aml.transfer v2) | sha256:858fd6694716f503448ea89da802c0c2942e2619938f126d0088cb4ba9af5d35 |
P key-shuffled | sha256:acc943b05fa8e8096e5b313288bc4f919cc2661f167c833770509a53049afa1c (identical — JCS absorbs key order) |
policy_bound_ref), six positives — every subject under both P and P':
| Subject | under P | under P' |
|---|---|---|
retention_chain_v0 | sha256:65390e374d9a3ec4ffe08a078c66c088da3c8a2c993a21885531e7e371a7e8b0 | sha256:7329a61c9b61e8d64cb8b141e15f7b1743c51d73a52c26404e18666ee241ea55 |
retention_chain_v1 | sha256:7a2d7b0464edadcee38151524e2d458f4396df4b3daeede329fb5a16006c12e2 | sha256:bf6bac1ce44f1dc8b0cfec04c1be3994ac70e6abad49634cb666019cf5218b90 |
settlement_action_binding_v1 | sha256:aaee2091799f376ee8cac802ea4920feaa4eca52950488a3e047ff82e6959a21 | sha256:e6629ede721146e62ce148fc25c52b79a58103a7476784397b328809e0f027e2 |
P, must reject under P') and two invariant assertions (key-order-invariance, subject-binding).
Adopters
If you build onalgovoi-policy-binding and verify against the canonical vectors, you qualify for a free v0 licence key for algovoi-mandate-auditor — AlgoVoi’s production-grade MiCA/DORA compliance audit service for payment mandate charge chains.
Qualification criteria (enforced by scripts/check_v0_adoption.py):
algovoi-policy-bindingdeclared as a dependency, pinned to a specific version (==0.1.0) — a bare version range is rejected- At least one canonical vector hash from
policy_binding_v1in your conformance tests - A
NOTICEfile preserving the Apache-2.0 attribution
NOTICE file. If all criteria are met, a v0 key is issued within one business day.
Relationship to the open substrate
Policy Binding sits directly on top of the open JCS Canonicalisation Substrate and composes with the Retention Chain and settlement-action binding. It uses the same RFC 8785 JCS and SHA-256 primitives — no additional cryptographic dependencies.policy_bound_ref mismatch — that is a runtime posture decision, not a property of the substrate itself.
Also available natively in the commercial Substrate 2 (substrate2.policy_binding), carried to adopters through the existing pin-and-licence channel.
Specification
The normative specification is IETF Internet-Draftdraft-hopley-x402-retention-chain-04 (AlgoVoi, sole authorship, 19 June 2026), which adds:
- Section 7.7 — Policy Binding: the
policy_ref/policy_bound_refconstruction and its invariants (Stability, Snapshot-binding, Rotation-detection, Subject-binding, Key-order-invariance) - Section 8.10 — Policy Binding Vectors: the exact preimage inputs, JCS canonical forms, and expected byte sequences for
policy_binding_v1