The problem
Somebody grants authority to somebody else. An acceptor relies on it. The question that eventually matters is whether the granting party had that authority to give.
This is the least examined link in every delegation chain. Acceptors check the grant. They verify a signature, they read the scope, they check the dates. What they almost never check is whether the granter's own entitlement covered what it granted. A granter who was entitled to delegate spending of one hundred in one category, and who granted five hundred across three categories, produces a grant that looks perfectly valid at the point of acceptance.
Name the parties. The granter asserts it was entitled. The grantee asserts it received a valid grant and acted properly. The acceptor asserts it relied reasonably on a signed instrument. The party who actually held the entitlement, which might be a principal, a licensor or a regulator, asserts it never authorised any of this. All four can be sincere.
Three specific failures make the chain break at this link.
The first is that the entitlement source is not comparable to the grant. Entitlements are written in prose, in contracts and charters and licences. Grants are written in structured fields. Nobody translates between them, so nobody compares them.
The second is the after the fact justification. When the question does get asked, someone goes and finds the entitlement, reads it, and writes a memo concluding that the grant was covered. That memo is genuinely useful analysis and it is worthless as evidence, because it was produced by an interested party after the outcome was known. There is currently no mechanical way to tell an entitlement check performed before a grant from one performed after it.
The third is the self check. The party whose authority is in question is usually the party who assesses it. A granter that qualifies its own grant has produced a document, not a check.
The confidentiality problem sits on top. Entitlement terms are commercially sensitive. Scope classes reveal business structure, quantities reveal capacity, and party identities reveal relationships. An instrument that requires all of that in the clear will not be shared with the acceptors who need it.
When granter and grantee are both autonomous, the chain gets longer and the check gets skipped more. Authority is delegated programmatically at machine speed. Nobody stops to read a charter.
What the receipt binds
The schema is at https://thehiveryiq.com/.well-known/schemas/authority-qualification-v1.json.
| Field | Meaning |
|---|---|
receipt_type | Fixed to authority.qualification. |
schema | Fixed to r1.0.0. |
qualification_id | Identifier of up to 256 characters from letters, digits, dot, underscore, colon and hyphen. |
granter | The granting party, as granter_commitment and salt_commitment. |
grantee | The receiving party, as grantee_commitment. |
entitlement | What the granter held. Carries a source_receipt naming an authority.entitlement receipt with its envelope digest and issuance instant, a granter_commitment, one to 64 scope_class_commitments, residual_minor_units, a residual_commitment, a numeraire_commitment, and not_before and not_after each carrying a UTC instant and a drift_seconds value. |
grant | What was granted. Carries a grant_receipt naming an authority.grantinstrument receipt with its envelope digest, a granter_commitment, a grantee_commitment, one to 64 scope_class_commitments, granted_minor_units, a granted_commitment, a numeraire_commitment, and an issuance_instant with its own drift. |
qualifier | Who checked. Carries a qualifier_commitment, a qualification_class of independent_registry_check, countersigned_source or self_asserted, a record_id, a record_sha256 and a qualification_instant with drift. |
containment | The four recomputed relations: scope_relation, quantity_relation, interval_relation and qualifier_relation. |
qualification | The verdict, one of qualified, unqualified or indeterminate. |
boundary | The fixed non attestation string. |
Every instant in this receipt is a pair of a UTC value and a drift_seconds bound up to 86400. Time is treated as an interval throughout, which is what makes the ordering comparisons defensible.
What is deliberately not in the signed body
No party is named. No scope class is named. No numeraire is named. Quantities appear both as integers in minor units and as commitments, which is a deliberate split: the integers let the containment comparison be checked by anyone holding the receipt, while the commitments bind those integers to the salt so they cannot be quietly restated in a related artifact.
Five commitments share one keyed construction in src/typed/authority-qualification.js. For a label, a salt commitment and a value, the commitment is HMAC-SHA256 keyed by the raw salt bytes over the concatenation of the UTF-8 label, a zero byte, the UTF-8 salt commitment, a zero byte and the UTF-8 value. The labels are:
partyover a party identifier, used for granter, grantee and qualifier alike.scope-classover one exact scope class name.numeraireover the exact numeraire label both sides must be denominated in.residual-minor-unitsover the decimal string of the entitled residual.granted-minor-unitsover the decimal string of the granted amount.
The salt commitment itself is a plain SHA-256 over the UTF-8 label authority-qualification-salt, a zero byte, and the raw salt bytes. The salt is disclosed to the verifier and does not live in the receipt.
Using one label for all three parties matters. It means a granter commitment and a qualifier commitment are computed identically, so comparing them for equality is a meaningful test of whether the qualifier is the granter. That is exactly what QUALIFIER_DISJOINT does.
Linked artifacts appear only as digests. The entitlement source, the grant instrument and the qualification record are each committed as a SHA-256 over the canonical body under the shared rule: keys sorted recursively, no whitespace, non ASCII escaped as lowercase \uXXXX. The receipt envelope uses the shared Ed25519 construction over the ASCII string hive-receipt <receipt_id> <payload_sha256> <ts>.
The gates
Verification runs in this order and stops at the first failure.
- SCHEMA. Validates the envelope against the authority qualification v1 schema. A failure means the artifact is malformed.
- ISSUER_KEY_MATCH. Resolves
key_idthrough the trusted issuer key resolver. A failure means no resolver was supplied, the key does not resolve, or resolution errored. - ENVELOPE_SIGNATURE. Runs the envelope crypto, covering the payload digest, the receipt identifier form and the Ed25519 signature. A failure names the inner gate.
- SALT_PRECOMMITMENT. Recomputes the salt commitment from the disclosed salt and requires it to equal
granter.salt_commitment. A failure means the disclosed salt does not open the published commitment. - PARTY_COMMITMENT_COHERENCE. Requires
granter.granter_commitment,entitlement.granter_commitmentandgrant.granter_commitmentto be identical, and requiresgrantee.grantee_commitmentto equalgrant.grantee_commitment. A failure means the granter differs between the two sides. - ENTITLEMENT_SOURCE_LINK. Requires the supplied entitlement source to be the one the receipt names. A failure means a substituted source.
- ENTITLEMENT_SOURCE_INTEGRITY. Requires the entitlement source envelope to pass its own verification. A failure means the source's own signature is broken.
- ENTITLEMENT_SOURCE_TERMS. Requires the source to publish
scope_class_commitments, requires the receipt's declared scope set to be the same set, and requires the source'sgranter_commitment,residual_minor_units,residual_commitmentandnumeraire_commitmentto equal the receipt's entitlement values. A failure names the mismatched field. - GRANT_INSTRUMENT_LINK. Requires the supplied grant instrument to be the one the receipt names.
- GRANT_INSTRUMENT_INTEGRITY. Requires the grant instrument envelope to pass its own verification.
- QUANTITY_COMMITMENT_RECOMPUTE. Recomputes the residual and granted commitments from the disclosed salt and the declared integers. A failure means the integers and the commitments disagree.
- NUMERAIRE_MATCH. Requires
entitlement.numeraire_commitmentto equalgrant.numeraire_commitment, on the stated ground that no quantity comparison between them is meaningful otherwise. - SCOPE_CONTAINMENT. Recomputes the scope relation as
granted_scope_within_entitled_scopewhen every granted scope class commitment appears in the entitled set, andgranted_scope_exceeds_entitled_scopeotherwise, then compares to the declared relation. - QUANTITY_CONTAINMENT. Recomputes the quantity relation over exact integers as
granted_within_residualwhen granted is at or below residual, andgranted_exceeds_residualotherwise, including when either value is not an integer. Compares to the declared relation. - ENTITLEMENT_INTERVAL_ORDER. Requires
entitlement.not_beforeto parse and be strictly earlier thanentitlement.not_after. A failure means the entitlement interval does not run forwards. - ENTITLEMENT_INTERVAL. Recomputes the interval relation. It reports
issuance_within_entitlement_intervalonly when the earliest possible issuance is at or after the latest possiblenot_beforeand the latest possible issuance is at or before the earliest possiblenot_after. It reportsissuance_outside_entitlement_intervalonly when the whole issuance interval falls clear of the nominal bounds. Anything overlapping isindeterminate. - QUALIFIER_DISJOINT. Recomputes the qualifier relation as
qualifier_disjoint_from_partieswhen the qualifier commitment equals neither the granter nor the grantee commitment, andqualifier_is_a_partyotherwise. Compares to the declared relation. - QUALIFICATION_RECORD_LINK. Requires a qualification record to be supplied, requires its
record_idto match, and requires its canonical digest to equalqualifier.record_sha256. A failure means the record supplied is not the record named. - QUALIFICATION_CLASS_CANDOUR. Requires the record's declared class and qualifier commitment to match the receipt. For
countersigned_sourceit requires the record to carry a countersignature. Forindependent_registry_checkit requires the record to name the registry it consulted. A failure means the class overstates what the record contains. - QUALIFICATION_PRECEDENCE. Requires the latest possible qualification instant to be strictly earlier than the earliest possible grant issuance instant. The failure message states the reason directly: otherwise the qualification cannot be distinguished from a justification written after issuance.
- CLOCK_CONSERVATISM. Fails when the recomputed interval relation is
indeterminatewhile the declared qualification is definite. A failure means a definite verdict was claimed over uncertain timing. - QUALIFICATION_RECOMPUTE. Recomputes the verdict and compares. The rule: an indeterminate interval relation gives
indeterminate; a qualification instant not strictly before issuance givesunqualified; aself_assertedclass givesunqualified; otherwisequalifiedrequires all four relations affirmative, and anything else isunqualified. - BOUNDARY_CONSTANT. Requires the boundary to equal the constant character for character.
The mint path refuses caller supplied values the service must derive, including the receipt type, the schema, the boundary, the containment block, the qualification verdict, the granter salt commitment, the entitlement source receipt reference, the grant receipt reference and the qualifier record digest.
The boundary
This receipt attests only that a named grant, a named entitlement source held by the granting party, and a named qualification record satisfy the stated deterministic containment and ordering procedure over disclosed commitments. It does not establish that the entitlement source is genuine, accurate, current, lawfully obtained, or sufficient under any contract, mandate, charter, licence, regulation, or statute. It does not establish that the qualifier is competent, diligent, independent in fact, or free of conflict. A qualification of qualified does not make the grant valid, enforceable, or binding, does not ratify the grant, and does not authorize the grantee to act. A qualification of unqualified does not make the grant void, does not establish fault, breach, negligence, or bad faith, and does not allocate risk, responsibility, liability, loss, or remedy. This receipt decides no contractual, statutory, regulatory, evidentiary, or legal consequence, and it authorizes no action, payment, sanction, denial, or remedy.
BOUNDARY_CONSTANT compares that text character for character.
The paragraph disclaims both verdicts symmetrically, and that symmetry is what makes the instrument usable by both sides. If qualified conferred validity, no granter would ever let one be minted against a grant it cared about. If unqualified established fault, no granter would participate at all. Because neither verdict carries a consequence, a granter can agree in advance to have every grant qualified, which is the only way this ever becomes routine.
The clause about the qualifier not being competent or independent in fact is the honest one. QUALIFIER_DISJOINT proves the qualifier commitment differs from the granter and grantee commitments. That is structural independence under one salt. It is not a statement that the qualifier is any good, or that it has no undisclosed relationship with either party. Saying so tells an acceptor exactly what further diligence is still theirs.
Enumeration narrows the dispute. An acceptor holding a qualified receipt has settled that the granted scope sat inside the entitled scope, that the granted quantity sat inside the residual, that the issuance fell inside the entitlement interval, that the checker was not one of the parties, and that the check predates the grant. Those five facts are usually the whole argument. Everything the boundary excludes is judgment about the entitlement's own validity, which was always going to be a legal question.
Adversarial cases
From test/authority-qualification.test.mjs.
SALT_PRECOMMITMENT rejects a salt that does not open the published commitment. Salt shopping is the first attack on any commitment scheme, and the salt has to hash to the value the receipt published.
PARTY_COMMITMENT_COHERENCE rejects a granter that differs between the two sides. Presenting one party's entitlement alongside another party's grant is the central forgery, and it fails before any containment is computed.
ENTITLEMENT_SOURCE_LINK rejects a substituted entitlement source, and ENTITLEMENT_SOURCE_INTEGRITY rejects a source whose own signature is broken. Both halves of the source are checked: that it is the one named, and that it stands on its own.
GRANT_INSTRUMENT_LINK rejects a grant the receipt does not name, and GRANT_INSTRUMENT_INTEGRITY rejects one whose signature is broken.
QUALIFICATION_RECORD_LINK rejects a record that is not the record named, and separately rejects a record about a different entitlement source. Reusing a favourable check from another matter does not work.
QUALIFICATION_CLASS_CANDOUR rejects an independent registry claim with no registry named. Claiming the strongest class without the evidence that class requires is caught.
A self asserted qualification cannot produce a qualified verdict. This is enforced in the recomputation rather than left to the reader. A granter checking itself gets unqualified, always.
A granted scope class outside the entitlement produces unqualified. A granted quantity above the entitled residual produces unqualified. A grant issued outside the entitlement interval produces unqualified. A qualifier that is a party to the grant produces unqualified. Each of the four relations independently sinks the verdict.
QUALIFICATION_PRECEDENCE refuses a qualification recorded after issuance. This is the after the fact memo, and it is the case the instrument exists for.
Overlapping clock uncertainty is not treated as precedence. The comparison uses the latest possible qualification instant against the earliest possible issuance instant, so two instants whose drift intervals overlap do not produce a precedence finding. Uncertainty resolves against the claim, not for it.
An entitlement interval that does not run forwards is refused by ENTITLEMENT_INTERVAL_ORDER.
NUMERAIRE_MATCH rejects a comparison across two different numeraires. Comparing a quantity in one unit against a residual in another is meaningless and the gate says so.
BOUNDARY_CONSTANT rejects a softened boundary sentence.
The minter refuses caller supplied verdicts and derived commitments, and refuses a salt that is not 32 bytes of lowercase hex.
Two positive cases anchor it: a grant contained inside an independently qualified entitlement is qualified, and the receipt verifies standalone against the linked artifacts.
Performance
From hive-verifier-api/benchmarks/results-latest.json, measured at 2026-08-09T22:28:01.099Z at commit e167719f7d815809c6f55c5dde4495edf1c5615f over 200 iterations:
| Measure | Value |
|---|---|
| Mint p50 | 6.703 ms |
| Mint p95 | 7.372 ms |
| Verify p50 | 5.872 ms |
| Verify p95 | 9.787 ms |
| Artifact size | 4162 bytes |
Local harness measurement on one machine and one Node version, recorded on Node v20.20.1, linux/x64, two Intel Xeon cores at 2.90 GHz. It is a reproducible measurement of this code, not a production latency guarantee.
How to run it
This type has no mint route. It is produced as an export by another route and only verified here, so there is nothing to authenticate against. The verify route takes no credentials.
- Host:
https://thehiveryiq.com/v1 - Verify route:
/verify/authority-qualification
curl -sS -X POST https://thehiveryiq.com/v1/verify/authority-qualification -H 'content-type: application/json' -d '{"receipt": <a receipt of this type>}'
Where it sits in the canon
Family: network authority. Category: typed receipt contract.
It sits above an authority.entitlement receipt and an authority.grantinstrument receipt, verifying both rather than trusting their references. Downstream it pairs with delegation.attenuation, which checks that each link in a delegation chain narrows rather than widens, and with authority.revocation, which classifies an action against a revocation. This receipt answers a question neither of those asks: whether the top of the chain was ever entitled.
It does not replace the entitlement source, the grant instrument, or legal advice about whether an entitlement covers a grant as a matter of law. The boundary rules all of that out in the signed bytes.
Status
production_deployed.