Picking up the claimType-by-claimType idea, here is a concrete BACKING schema to react to. It is scoped to credit-backed instruments (a promissory note, a receivables pool, a loan), it is a draft to put on the table rather than a finished thing, and it is CC0.
The one line that governs it: structure, not adequacy. The schema standardizes how a backing attestation is expressed, so any consumer parses it the same way. It does not decide whether the backing is enough. coverage carries the numbers; whether they clear a threshold is the consumer’s call. That is the two-layer split from the thread: the envelope and the field structure are reusable across every issuer, while the adequacy decision is issuer- and policy-specific and stays with the reader. A coverage figure is a measurement, not investment advice. Backing, not valuation.
Who attests vs. who records. A BACKING data block is meaningless without the attestor named in the envelope. For credit backings that attestor is an independent verification agent, distinct from the registry operator. The registry records the attestation; it does not attest adequacy or value, so the schema carries no attestor-identity field. The envelope already does, through attestorProfile and the on-chain signer.
Jurisdiction is a field, not baked in. instrument.jurisdiction is an ISO 3166-1 country code, so the same schema serves a receivables pool under one law and a note under another. The field descriptions carry the governing law so no field can be read as constituting or legitimating the right (the examples happen to be Colombian): recording a holder is not legitimation, and recording an encumbrance is not perfecting it.
The honest edge case. An encumbrance whose beneficiary is unknown is recorded as such (status, beneficiaryKnown), not smoothed over. A consumer reading status != NONE or beneficiaryKnown == false should treat the backing as not clean. The registry publishes the fact of the lock and stops, instead of inventing who holds the key.
The data schema (JSON Schema 2020-12):
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://registry.factos.co/schemas/erc8320/backing.credit.v1.json",
"title": "ERC-8320 BACKING data — credit-backed instrument (v1, candidate)",
"description": "Candidate structure for the `data` object of an ERC-8320 claim of type BACKING, for a credit-backed instrument such as a promissory note (pagaré) or a receivables pool. Structure only: it standardizes how a backing attestation is expressed so any issuer's payload parses and validates the same way. It does NOT encode adequacy; whether the coverage clears a threshold is the consumer's decision. It records facts AS ATTESTED by the party named in the ERC-8320 envelope; it does not certify that a right is valid or enforceable, nor legitimación cambiaria, nor the authenticity of who holds it. A `data` block is meaningless without that attestor: for credit backings the attestor is an independent verification agent, distinct from the registry operator, and the schema deliberately does not carry attestor identity because the envelope does.",
"type": "object",
"required": ["backingType", "instrument", "evidence", "encumbrance"],
"additionalProperties": false,
"properties": {
"backingType": {
"description": "What kind of backing is asserted to stand behind the instrument.",
"type": "string",
"enum": ["RESERVES", "COLLATERAL", "RECEIVABLES_POOL", "GUARANTEE", "OTHER"]
},
"instrument": {
"description": "The credit instrument being backed.",
"type": "object",
"required": ["type", "jurisdiction"],
"additionalProperties": false,
"properties": {
"type": {
"type": "string",
"enum": ["PROMISSORY_NOTE", "RECEIVABLES", "LOAN", "BOND", "OTHER"]
},
"jurisdiction": {
"description": "Governing jurisdiction of the instrument, ISO 3166-1 alpha-2.",
"type": "string",
"pattern": "^[A-Z]{2}$"
}
}
},
"evidence": {
"description": "Anchor to the off-chain evidence package that substantiates the backing. The hash binds this claim to that exact package; it is not a claim that the evidence proves the right.",
"type": "object",
"required": ["contentHash", "hashAlgorithm"],
"additionalProperties": false,
"properties": {
"contentHash": {
"description": "Hash of the evidence package, 0x-prefixed 32-byte hex.",
"type": "string",
"pattern": "^0x[0-9a-fA-F]{64}$"
},
"hashAlgorithm": {
"description": "Which hash produced contentHash. FACTOS uses SHA-256.",
"type": "string",
"enum": ["SHA-256", "KECCAK-256"]
},
"cid": {
"description": "Content-addressed locator (e.g., an IPFS CID) for retrieval.",
"type": "string"
},
"packageType": { "type": "string" },
"uri": { "type": "string" }
}
},
"coverage": {
"description": "The coverage figure, expressed as structure so any consumer parses it the same way. The schema carries the numbers; it does NOT decide whether they are adequate. The figures are asserted by the attestor named in the ERC-8320 envelope, an independent verification agent for credit backings, not the registry operator; FACTOS operates the registry and does not attest adequacy or value. A coverage figure is a measurement, not investment advice; whether it is adequate is the reader's decision. Amounts are decimal strings to avoid floating-point loss.",
"type": "object",
"required": ["backedAmount", "referenceAmount", "currency"],
"additionalProperties": false,
"properties": {
"backedAmount": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?$" },
"referenceAmount": { "type": "string", "pattern": "^[0-9]+(\\.[0-9]+)?$" },
"currency": {
"description": "ISO 4217 currency code.",
"type": "string",
"pattern": "^[A-Z]{3}$"
}
}
},
"encumbrance": {
"description": "Whether a competing charge sits on the right, as attested. Recording an encumbrance status is a record of an attested fact; it does not constitute, perfect, or make the charge opposable to third parties. Opposability follows the applicable law, for example registration of a security interest in the collateral registry (in Colombia, the RGMC under Ley 1676 de 2013) or, for a título valor, the endoso en garantía (C.Co. art. 659). An encumbrance whose beneficiary is unknown is recorded as such, not smoothed over; a consumer reading `status != NONE` or `beneficiaryKnown == false` should treat the backing as not clean.",
"type": "object",
"required": ["status", "beneficiaryKnown"],
"additionalProperties": false,
"properties": {
"status": {
"type": "string",
"enum": ["NONE", "PLEDGED", "SEIZED", "UNDER_DISPUTE", "UNKNOWN"]
},
"beneficiaryKnown": { "type": "boolean" },
"basis": {
"description": "Legal source of the charge, when known. Keeps the status jurisdiction-agnostic while letting the source be stated. SECURITY_INTEREST = registered security interest (e.g., garantía mobiliaria); PLEDGE_ENDORSEMENT = endoso en garantía on a título valor; JUDICIAL_MEASURE = court measure such as an embargo; DISPUTE = pending litigation.",
"type": "string",
"enum": ["SECURITY_INTEREST", "PLEDGE_ENDORSEMENT", "JUDICIAL_MEASURE", "DISPUTE", "OTHER"]
},
"ref": {
"description": "Optional 0x-prefixed 32-byte hex reference to an off-chain record of the charge.",
"type": "string",
"pattern": "^0x[0-9a-fA-F]{64}$"
}
}
},
"holderRef": {
"description": "Identifier of the party the registry has RECORDED as holder of the right. This is not legitimación cambiaria and does not substitute the instrument's law of circulation: for a pagaré a la orden, possession plus an unbroken chain of endorsements (C.Co. arts. 647, 661); for a nominative instrument, entry in the issuer's register plus the document text (C.Co. art. 648). Not a certification of ownership or identity. The value MUST be a salted, non-reversible commitment: a bare hash of a national ID such as a Colombian cédula is brute-forceable and remains personal data under Ley 1581 de 2012, so publish only a salted commitment.",
"type": "object",
"required": ["recordedHolderHash"],
"additionalProperties": false,
"properties": {
"recordedHolderHash": {
"description": "Salted, non-reversible commitment to the recorded holder. 0x-prefixed 32-byte hex.",
"type": "string",
"pattern": "^0x[0-9a-fA-F]{64}$"
}
}
}
}
}
A synthetic example payload (the ERC-8320 envelope wrapping a conforming data block):
{
"schemaId": "factos:backing.credit.v1",
"schemaVersion": "1",
"claimVariant": "backing.credit",
"assetId": "0x7e646f4f719d1da5c21d22509ef7c11e9e20934c981c2d8341f7ac31832a5474",
"claimVersion": 1,
"attestorProfile": "independent receivables-verification agent, not the registry operator",
"authoredAt": "2026-09-21T14:00:00Z",
"dataAppliesAt": "2026-09-20T00:00:00Z",
"accessClassification": "PERMISSIONED_DISCLOSURE",
"data": {
"backingType": "RECEIVABLES_POOL",
"instrument": { "type": "RECEIVABLES", "jurisdiction": "CO" },
"evidence": {
"contentHash": "0x1a3f9c2b7d4e5061728394a5b6c7d8e9f0112233445566778899aabbccddeeff",
"hashAlgorithm": "SHA-256",
"cid": "bafybeigdyrsyntheticexampleonly",
"packageType": "FACTOS-evidence-pack",
"uri": "ipfs://bafybeigdyrsyntheticexampleonly"
},
"coverage": { "backedAmount": "1200000000", "referenceAmount": "1000000000", "currency": "COP" },
"encumbrance": { "status": "NONE", "beneficiaryKnown": true },
"holderRef": { "recordedHolderHash": "0x9b2c4e6a8d0f1234567890abcdef1234567890abcdef1234567890abcdef1234" }
}
}
schemaHash = 0x0b88814b5dc3c18e868259d0dfcc701a4fa2d67e9792210e42615fc138a21d48, keccak256 over the exact bytes of the schema file, so a claim commits to one exact artifact and semantically equivalent but differently serialized files do not collide. The exact bytes are served so anyone can fetch and reproduce the hash: https://registry.factos.co/schemas/erc8320/backing.credit.v1.json (the schema’s $id), also at an immutable hash-addressed path under /schemas/erc8320/by-hash/.
The reuse test this sets up, which is the question you raised: two issuers populate backing.credit.v1 for two different instruments under two jurisdictions, and a single consumer parses both with the same code (resolve the payload, verify contentHash, read encumbrance and coverage, apply its own threshold). Everything up to the threshold is reused; only the threshold the consumer chose differs. That measures, concretely, how much consumer logic ERC-8320 makes reusable across issuers.
Open, for discussion:
- Is this the right small stable core, or is anything missing or over-specified?
jurisdiction as an ISO code keeps it issuer-agnostic. Is a finer legal-basis field wanted, or does encumbrance.basis already cover it?
- Should
coverage be optional, since some backings are not expressed as a ratio?