Attachment
org.hypercerts.context.attachment
Overview#
An attachment connects material such as reports, photos, datasets, audits, or links to the records it concerns. It is a record of its own, so anyone can publish one about an activity, collection, measurement, evaluation, or another attachment, without editing the record it points to.
An attachment gives readers something to inspect. It does not by itself prove anything about its subjects: a plan explains intent, a progress report describes work, and an audit is one party's review. For the concepts behind it, see Evidence and Measurements in the Guide.
How it's used#
- A project documents its work. The team publishes an installation report, progress photos, or a dataset and lists the activity in
subjects. - Third parties add material. An auditor, partner, or community member publishes an attachment in their own repository pointing at someone else's activity. It stays associated with its publisher, not with the owner of the activity.
- One attachment, several subjects. The same report can give context to several activities, or to an activity and the evaluation that relied on it.
- Authors post updates. A person or organization posts a standalone update, one not about any particular project, as an attachment whose
subjectspoint at the author's own profile. A project update is the same record withsubjectspointing at the project. There is no separate post record. - Material can come first.
subjectsis optional, so a file can be published before the record it will support exists. - Applications find attachments by indexing. Records don't list their attachments. An indexer finds attachments by looking for records whose
subjectspoint to a given record.
Only title and createdAt are required. Add subjects, content, and a description when they help readers understand what they are looking at.
Schema#
Record key: tid · Lexicon version: 1.6.0 · View the schema
Required properties#
| Property | Type | Description |
|---|---|---|
title | string | Display title for this attachment (e.g. 'Impact Assessment Report', 'Audit Findings') maxLength: 256 |
createdAt | string (datetime) | Client-declared timestamp when this record was originally created. |
Optional properties#
| Property | Type | Description |
|---|---|---|
subjects | array of strongRef | References to the subject(s) the attachment is about: an activity claim, a collection, a measurement, an evaluation, another attachment (for a comment on it), or an account profile (app.certified.actor.profile). A standalone update by its author points at the author's own profile: it is an update about the author. Optional: omit it only when the attachment is recorded before the claim it will support. maxItems: 100 |
contentType | string | The type of attachment. Values beyond the known set are permitted. maxLength: 64 Known values: update, report, audit, evidence, testimonial, methodology. |
content | array of union: org.hypercerts.defs#uri, org.hypercerts.defs#smallBlob | The files, documents, or external references included in this attachment record. maxItems: 100 |
shortDescription | string | Short summary of this attachment, suitable for previews and list views. Rich text annotations may be provided via shortDescriptionFacets. maxLength: 3000 maxGraphemes: 300 |
shortDescriptionFacets | array of richtext facet | Rich text annotations for shortDescription (mentions, URLs, hashtags, etc). |
description | union: org.hypercerts.defs#descriptionString, Leaflet linear document, strongRef | Long-form description of the attachment. An inline string for plain text or markdown, a Leaflet linear document for rich-text content, or a strong reference to an external description record. |
langs | array of string (language) | Human language(s) of this record's text fields, as BCP-47 language tags (e.g. 'es', 'pt-BR'); up to three for mixed-language text. Set by the writing app from the text the author wrote, with the author able to correct it; never from the interface language or a profile preference alone. A hint for readers, not a guarantee: consumers must not hide a record because it lacks this field. maxItems: 3 |
location | strongRef → app.certified.location | A strong reference to the location where this attachment's subject matter occurred. The record referenced must conform with the lexicon app.certified.location. |
tags | array of strongRef → org.hypercerts.vocab.tag | References to org.hypercerts.vocab.tag records classifying this record. All listed tags apply simultaneously (logical AND); the array carries no ordering, weighting, negation, inheritance, or rule logic, and never will — any future expression logic must arrive as a new field and must never reinterpret this one. maxItems: 20 |
capturedAt | string (datetime) | Client-declared time when the attached material was captured (e.g. when a photo was taken), as distinct from createdAt. Omit if capture time is unknown, if only a local time without timezone offset or only a date is known, or if no single capture time applies. Not a coverage interval. |
signatures | app.certified.signature.defs#list | Optional cryptographic signatures attesting to this record's content. |
Example#
A community energy project attaching its installation report and a photo album to the phase 1 activity:
{
"$type": "org.hypercerts.context.attachment",
"title": "Installation and commissioning report, phase 1",
"contentType": "report",
"subjects": [
{
"uri": "at://did:plc:4yyb5gyoxl3sqdlqrvuxshkp/org.hypercerts.claim.activity/3lx2k9q7mfd2c",
"cid": "bafyreie6mq3tzkxv7hnw4dlpc2ysrb5fja7geo3wuxzm6ntkc2hdv4pqye"
}
],
"content": [
{
"$type": "org.hypercerts.defs#smallBlob",
"blob": {
"$type": "blob",
"ref": {
"$link": "bafkreihdwdcefgh4dqkjv67uzcmw7ojee6xedzdetojuzjevtenxquvyku"
},
"mimeType": "application/pdf",
"size": 2418762
}
},
{
"$type": "org.hypercerts.defs#uri",
"uri": "https://photos.example.org/village-hall-solar/phase-1"
}
],
"shortDescription": "Installer's report covering panel layout, inverter setup, and the grid connection test.",
"description": {
"$type": "org.hypercerts.defs#descriptionString",
"value": "Prepared by the electrical contractor after commissioning on 28 June 2026. The PDF includes the as-built drawings and the signed grid connection certificate. The linked album has progress photos from each week of installation."
},
"location": {
"uri": "at://did:plc:4yyb5gyoxl3sqdlqrvuxshkp/app.certified.location/3lx2k7p4hvc2a",
"cid": "bafyreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy"
},
"createdAt": "2026-07-04T13:40:00.000Z"
}
Rules and best practices#
- Title and describe the material. Readers often see only the title and short description in a list. Say what the material is and who prepared it, so a plan isn't mistaken for a report of completed work.
- Use
contentTypeto say what kind of material it is. The known values areupdate,report,audit,evidence,testimonial, andmethodology; other values are allowed. Useupdatefor narrative updates. The label describes the material but doesn't verify it: an attachment labelledauditdoes not make its subject audited. - Prefer uploaded files for material that must not change. A
smallBlobitem is stored in the publisher's repository and addressed by its content hash, so the record's CID commits to those exact bytes. Auriitem points somewhere else, and the content there can change or disappear. Applications can show readers which kind each item is. - Mind the size limit. Each blob item is limited to 10 MB (the
smallBlobdefinition). Link to larger files with auriitem instead. - Match profile subjects by URI. Profiles are edited, so a strong reference to a profile soon pins an older version. When collecting an account's updates, take attachments published in that account's own repository and match the subject's
uri, not itscid. Anyone can publish an attachment about a profile, so matching the URI alone would include third-party attachments. - Strong references pin a version. Each entry in
subjectspoints to a specific version of the subject. If the subject is edited, the attachment still refers to the version it was written about. - Don't edit an attachment to swap its material. Other records may point to a specific version of the attachment. To publish revised material, create a new attachment.
- Link material that came first. If you published an attachment before its subject existed, publish a new attachment naming the subject once it does, rather than editing the original.
- Use
locationfor where the subject matter happened. It points to anapp.certified.locationrecord, for example the site where photos were taken. - Render any attachment from its title. Applications can display an attachment from
titleandcreatedAtalone. Don't hide it because a subject can't be resolved or its content can't be fetched. - Use the inline description unless you need structure.
descriptionStringis the simplest variant and the one applications are most likely to render. The Leaflet document and strong-reference variants are for rich or externally maintained descriptions. - Declare the text's language with
langs. List up to three BCP-47 tags (such asesorpt-BR) for the language the author actually wrote in, and let the author correct it. Don't derive it from the interface language or a profile preference. Readers treat it as a hint: don't hide a record because it has nolangs.
Related#
- Activity Claim: the most common subject of an attachment.
- Measurement: quantitative observations, when the material is a number with a unit.
- Evaluation: assessments that often rely on attachments.
- Shared Definitions: the
uri,smallBlob, anddescriptionStringobjects. - Location: the record
locationpoints to. - Guide: Evidence and Measurements, Records That Change Over Time, Validation and Interpretation.