CfMetadata
Off-chain ContributionFingerprint metadata anchored on-chain by ContributionFingerprintRegistry.
A document of this kind carries a schema field matching xny://schemas/cf-metadata/<major>.<minor> — the version is part of the URI, and it is the only place a document's version is recorded.
Off-chain ContributionFingerprint metadata anchored on-chain by ContributionFingerprintRegistry. Describes the CF payload's storage location: inline (≤69,120 B raw), or external producer-managed object storage (GCS/S3). MAX_INLINE_RAW = 69,120 B (floor((102,400 − 10,240) × 3/4)).
Fields
| Field | Type | Required | Description |
|---|---|---|---|
schema | string | yes | Per-kind versioned schema identifier. Format: xny://schemas/cf-metadata/<major.minor>. This is the single source of truth for document version; do not use schema_version. |
kind | string | yes | Document kind discriminator. Always 'cf-metadata' for this schema. |
publisher | string | yes | DID of the entity that published this document. Pseudonymous identifier written to the permanent Arweave layer. DID-to-identity mapping exists only in an off-chain deletable layer (GDPR note: deletion right does not cover this field). |
published_at | string | yes | RFC 3339 / ISO 8601 UTC timestamp of document publication. |
tags | object | yes | Free-form key-value metadata tags for indexing and filtering. Bounded to 32 entries with keys up to 64 characters — conservative structural limits to keep the anchored document small, not a semantic constraint on tag content. Values are permanently written to Arweave alongside the rest of this document: do not put personal data in a tag (see CONVENTIONS.md's GDPR Note). |
submission_id | string | yes | Off-chain submission identifier (e.g. a snowflake or slug), assigned before this document is published. This is NOT the on-chain id: ContributionFingerprintRegistry derives the on-chain bytes32 cfId as keccak256(abi.encodePacked(bytes32 metadataHash, uint128 contributorDidId, bytes32 taskId[, bytes32 parentCfId])), where metadataHash is the keccak256 of THIS document's own bytes — so the on-chain cfId is content-derived and can, by construction, never appear inside the document itself. Note the packed widths: contributorDidId is 16 bytes (uint128), the rest are 32 bytes each. (Unlike frontier/campaign/task, whose on-chain id is keccak256 of their id string.) Renamed in place from cf_id — no version bump, since nothing is in production yet. |
task_id | string | yes | Task the CF was submitted under. |
contributor_did_id | string | yes | uint128 DID id of the contributor, serialised as decimal string. |
uploader | string | — | DID of the entity that performed the upload (may differ from contributor). Pseudonymous; same GDPR note as 'publisher'. |
payload_location | inline | external | yes | Routing discriminator. 'inline' = raw payload base64-encoded in inline_data (MAX_INLINE_RAW = 69,120 B). 'external' = payload held on centralized object storage (GCS / AWS S3) managed by the producer; see external object. A payload larger than MAX_INLINE_RAW therefore routes to 'external': the former 'filecoin' value and its envelope were removed, because per-CF Filecoin archival is deferred and has no schema home. |
size_bytes | integer | yes | Raw (pre-encoding) byte length of the CF payload. |
inline_data | string | — | Base64-encoded raw payload. Present only when payload_location = 'inline'. After decoding, byte length must equal size_bytes. |
external | object | — | Centralized object-storage envelope (GCS / AWS S3). Present only when payload_location = 'external'. The sha256 field is the cross-provider integrity anchor, since the uri alone is a mutable reference to the object. |
Example
6 rejection cases are kept alongside the schema in docs/schemas/examples/, exercised by validate_schemas.py.
Last updated