Developer guide

Unit identity that travels

Give each accepted unit a stable public ID so another system can refer to it without exposing the original identifier.

Updated September 1, 2026

"98 of 100 passed" is useful until another system needs to know which 98. A unitized Outcome Receipt gives every result a stable public identity.

In pseudonymous mode, that identity can travel with the receipt without publishing the original value or the private salt used to create it.

What unit identity means here

A unit is one independently checked item, such as one record in a dataset. When unit identity is configured, the agreement names the source key that identifies each unit and whether the receipt publishes a readable label or only a pseudonymous identifier.

Each unit result still carries its one-based unit, its verdict, and its reasons; the identity object (required id, optional label) lets a consumer bind that verdict to an item instead of relying on row position.

How the public ID is made

Spoolis hashes the source identifier with a secret salt. The receipt publishes only the resulting ID, not the original value or the salt.

In detail: each Spool that uses unit identity gets its own random 32-byte salt, stored with the Spool and following its retention and deletion lifecycle. Receipt creation prefixes the source value's bytes with that salt and hashes the combination with SHA-256; the lowercase 64-character digest becomes units.unit_results[].identity.id.

In label mode, the same result also publishes the original source value as identity.label. In pseudonymous mode, the label is omitted.

The salt is not part of the public Outcome Receipt. A consumer cannot reproduce a public ID by combining the Spool ID with a guessed label. The repository has a test for that exact failure case.

What travels and what stays private

Within one Spool, the same source value always produces the same public ID, so a consumer can compare the IDs it already holds. Across Spools the salt differs, so the same value produces different IDs; there is no global identity. A consumer with only the receipt cannot compute the ID for a guessed value.

Label visibility changes the boundary deliberately: a published identity.label is readable by anyone with the receipt, while pseudonymous visibility publishes only the digest.

Receipt containsReceipt does not contain
public unit IDprivate salt
unit verdictoriginal source value in pseudonymous mode
signed bindingproof that the source identity itself is true

Verify one unit from the receipt

An external party can verify a specific published unit result without access to Spoolis's database or the private salt:

  1. Verify the receipt's signature against a pinned trusted key.
  2. Locate the unit by its published identity.id (or identity.label in label mode).
  3. Read that unit's verdict and reasons.

The signed payload covers the unit results and their digest, so a verified receipt proves the published identity, verdict, and reasons belong together. The content-derived ID and digest mechanics live in verify a receipt.

The verifier checks the binding, not the underlying identity claim. In pseudonymous mode, the party must already know which published identity.id it is looking for. The receipt alone cannot prove that a private real-world value corresponds to that digest because the salt is absent. In label mode, the receipt supplies the label-to-verdict binding, but the signature still does not prove the label was truthful in the underlying evidence.

What the receipt does not establish

The public ID is a portable handle, not proof of real-world identity or truth. It does not prove who owns the underlying record, whether the source value was truthful, or whether two IDs from different Spools refer to the same entity.

For the adjacent mechanics, read pay per verified unit.

Unit identity that travels · Spoolis