Schemas

What a schema is and why we use it

A schema is the human-readable contract that tells the PoV Gate exactly what evidence a pass requires—fields, formats, files, roles, freshness windows, and how to treat lists (sets vs sequences). It removes guesswork: operators collect the same facts; clients serialize them the same way (Canonical JSON); the chain hashes the same bytes; the Gate runs the same checks; and money moves only when the checklist passes.

One sentence: the schema defines what counts as proof; canonical JSON defines how it is serialized; hashing binds the two.

Naming & versioning

  • Name: TRADE.ON_BOARD.v1, TRADE.ARRIVAL_QA.v1, TOKENS.ENERGY.MWH.v1, TOKENS.CARBON.VCM.v1

  • Versioning: semantic—major (v2) = breaking change; minor (v1.1) = backward-compatible field additions; patch (v1.0.1) = clarifications (no field changes).

  • Freeze on publish: once a version is live it never mutates. New behavior ships as a new version.

Note: schema_id is part of the claim_id derivation. A major bump deliberately changes the claim domain; minor/patch do not.

Structure

A schema is a small JSON definition with five pillars: fields, files, roles, freshness, and sets/sequences.

  • Fields & formats: Required vs optional; type: string_id, decimal_string(precision=N), timestamp_rfc3339, boolean, enum.

  • Files (digests, not blobs): Each file is referenced as {name, sha256, size}. Schemas list required files and optional ones (e.g., bl.pdf, seal.jpg, temp_log.csv).

  • Roles & quorum: Which attestor roles must sign (e.g., ["TERMINAL","CARRIER"] for On-Board; ["INSPECTOR"] for Pre-Ship PSI). Minimum role diversity and count (e.g., at least 2 roles, 2 attestations).

  • Freshness windows: How recent each role’s attestation must be (e.g., BL within 48h of load; PSI within 10 days of ship date). Windows are enforceable bounds; governance can tighten within limits.

  • Sets vs sequences: Arrays tagged as SET must be sorted before hashing (e.g., container_ids), so order doesn’t affect the PoV hash. Arrays tagged as SEQ preserve order (e.g., temp_log[]) and must not be sorted.

Optional extras include Merkle fields (for big logs) and redactable paths for PII, requiring a salted-hash commitment in redactions[].

Examples

TRADE.ON_BOARD.v1 (excerpt)

{
  "schema_id": "TRADE.ON_BOARD.v1",
  "version": "1.0",
  "fields": {
    "bl_number":        {"type": "string_id", "required": true},
    "seal_number":      {"type": "string_id", "required": true},
    "container_ids":    {"type": "array|string_id", "required": true, "cardinality": "SET"},
    "load_port":        {"type": "string_id", "required": true},
    "voyage":           {"type": "string_id", "required": false},
    "created_at":       {"type": "timestamp_rfc3339", "required": true}
  },
  "files_required": [
    {"name":"bl.pdf"}, {"name":"seal.jpg"}
  ],
  "quorum": {
    "roles": ["TERMINAL","CARRIER"],
    "min_attestations": 2,
    "min_distinct_roles": 2
  },
  "freshness_hours": {
    "TERMINAL": 48,
    "CARRIER":  48
  }
}

TOKENS.CARBON.VCM.v1 (excerpt)

{
  "schema_id": "TOKENS.CARBON.VCM.v1",
  "version": "1.0",
  "fields": {
    "program":     {"type":"enum","values":["VERRA","GS"],"required":true},
    "project_id":  {"type":"string_id","required":true},
    "vintage":     {"type":"string_id","required":true},
    "unit_serial": {"type":"string_id","required":true}
  },
  "files_required":[{"name":"issuance_cert.pdf"}],
  "quorum":{"roles":["REGISTRY"],"min_attestations":1,"min_distinct_roles":1},
  "freshness_days":{"REGISTRY":30}
}

Validation

The client submits canonical JSON bytes and role-signed attestations. The Gate loads the schema (schema_id) and validates:

  • All required fields present, optional empties omitted (no null); formats match (IDs, decimals, timestamps).

  • Files listed with sha256 and size where required.

  • SET arrays sorted; SEQ arrays in given order.

  • Role quorum satisfied; keys active in the Attestor Registry.

  • Freshness windows met per role.

  • All counted attestations reference the same PoV hash.

  • One-Claim key derivable and free; funding present if the schema marks a post-production gate (Trade).

Failures return readable codes, e.g., E_FIELD_MISSING, E_FORMAT_INVALID, E_FILE_MISSING, E_SET_NOT_SORTED, E_QUORUM_MISSING, E_STALE_ATTEST, E_HASH_MISMATCH, E_ONECLAIM_TAKEN, E_PENDING_FUNDS.

Evolution

  • Minor updates add optional fields or files (v1.1). Older dossiers remain valid.

  • Major updates change required fields, formats, or quorum (v2). New claim domain; old versions remain valid for historical orders/listings.

  • Deprecation: governance publishes an end-of-acceptance date; Explorer shows warnings; the Gate refuses new uses after the date, but historic proofs remain valid.

Governance (EDM holders) approves new schemas/versions with a 72-hour timelock and visible diffs. They cannot weaken safety: no schema may bypass quorum, freshness, One-Claim, must-fund before shipping, or 50% burn enforcement.

API & discovery

  • GET /v1/schemas: List all schema ids, versions, status (active/deprecated), and diffs.

  • GET /v1/schemas/{schema_id}: Full JSON definition, examples, and test vectors.

  • GET /v1/schemas/{schema_id}/examples: Canonical dossiers for integration tests.

  • GET /v1/schemas/{schema_id}/diff/{from}/{to}: Machine-readable diff for upgrades.

SDKs ship with canonicalization helpers, validators, and test vectors so implementers can certify serializers in CI.

Conformance & tests

  • Canonicalization: key ordering, whitespace stripping, decimal strings, timestamp format.

  • SET/SEQ: re-ordering SET arrays keeps hash; re-ordering SEQ arrays changes hash.

  • Quorum/freshness: missing/late role → fail with correct error.

  • Files: missing digest or mismatched size → fail.

  • Claim id: stable derivation across languages.

We publish these vectors per schema; receipts link to the schema version used so audits can replay exactly.

Privacy & redaction

Schemas may mark paths as redactable (/evidence/warehouse_contact, /evidence/invoice_no) with allowed reasons (“PII”, “commercial”). The dossier omits the value and includes a salted-hash commitment in redactions[]. Regulators can verify off-chain without changing the PoV hash.

Operator checklist

Keep schemas readable for humans and strict for machines. That’s how you get clean PASS the first time.

  • Put the exact checklist you expect to see on the floor—no ambiguity, no free text.

  • Require files by digest, never inline; avoid optional fields unless you truly need them.

  • Mark list types correctly (SET vs SEQ); schemas decide the hashing behavior.

  • Set realistic freshness windows and quorum for the lane; don’t make ops guess.

  • Treat v1 as frozen; bump minor for additions; use v2 for breaking changes.

Drawing

Plain recap

Schemas are the checklists PoV enforces. They tell operators what to collect, clients how to serialize it, the Gate how to validate it, and auditors how to replay it. With schemas fixed, canonical JSON and hashing make the dossier deterministic; One-Claim makes it unique; and, once it passes, the rest of the rail can safely do its job—EMT, Locked→Unlocked EDSD, fee line, 50% burn, receipt.

Last updated