Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Objects

Every protocol object is signed and transmitted in the same shape: the exact canonical bytes plus an Ed25519 signature over them. The only bytes ever signed or hashed are bcs(("tn-xxx-v1", body)) — a BCS body tagged with its object kind. Because the tag is inside the signed bytes, a signature over one object kind can never be replayed as another, and JSON renderings exist only for display.

Verification always runs over the bytes as transmitted and only then decodes them under the expected tag, so a single tampered byte fails the signature check before the payload is ever interpreted. The authoritative definitions are in crates/tenure-core, with a TypeScript twin.

Object catalogue

ObjectTagSignerPurpose
EmployerDescriptortn-employer-v1EmployerDeclares the employer key, KYB reference, enabled attestation types, dispute & recovery policy, mirror URLs
KybAttestationtn-kyb-v1KYB attesterBinds employer_pk to a legal entity + jurisdiction, with verification methods and an expiry
EpochOpentn-epoch-v1EmployerOpens an authority epoch: names the registrar key valid from a given seq, chains to the prior epoch head
EpochClosetn-epoch-close-v1EmployerCloses an epoch at a final seq + head hash
Delegationtn-delegate-v1EmployerGrants the registrar the right to mint specified types up to a daily cap, within a seq and time window
BatchManifesttn-batch-v1EmployerCarries Signer-computed aggregates + the raw batch hash for one issuance run
Attestationtn-attest-v1RegistrarOne signed claim about a worker, under a covering delegation
StatusChangetn-status-v1RegistrarCloses or reopens an employment period
Revocationtn-revoke-v1Registrar / EmployerRevokes one attestation, with a reason
FamilySupersedetn-family-supersede-v1RegistrarOne log entry that atomically retires every variant of a claim family
Reissuetn-reissue-v1RegistrarRe-points attestations to a fresh subject key during recovery
ShareGranttn-share-v1HolderThe worker’s consent record: which attestations, audience, scope, expiry
GrantRevoketn-grant-revoke-v1HolderWithdraws a ShareGrant
LogHeadtn-loghead-v1RegistrarA signed witnessed head: employer, epoch, seq, head hash
Checkpointtn-checkpoint-v1RegistrarA timestamped head mirrored externally; its published_at is the “not revoked as of” line

Two consequences are worth calling out. Consent is the worker’s own signature: ShareGrant and GrantRevoke are signed by the holder, not the registrar — not a server toggle. And the batch manifest’s aggregates are computed by the Signer, not the dashboard, so the registrar can cross-check them against the raw batch it received.

Claim schemas

An Attestation carries a typed claims body and, for income, a basis. There are seven claim types:

TypeClaims
employment_statusstatus (active / ended), start date, optional end date
tenure_datesstart date, optional end date
role_titletitle, optional department
income_exactexact cents, basis
income_bandfloor cents, ceiling cents, basis
income_threshold“at least” cents, basis
hours_classclass (full-time / part-time / variable)

The basis qualifies income figures as an annual_salary, the trailing_90d_annualized, or the trailing_12m. Income is never minted as a lone exact value: the exact figure and its derived band and threshold variants are minted together as one claim family.

What locates and bounds an attestation

Beyond its claims, an attestation carries the identifiers a verifier needs: an attestation_id, the family_id shared by every variant of one fact, the employer_id/epoch_no/log_seq that place it in the log, and the worker’s per-employer subject_pk. as_of is the moment the claim describes; valid_until is its optional expiry; supersedes_family points at the prior family it replaces.

A registrar’s signature on an attestation only counts if a covering delegation allows its type at that log_seq and its as_of falls inside the delegation’s time window — see Verification.