Skip to content
View raw

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 subjects point at the author's own profile. A project update is the same record with subjects pointing at the project. There is no separate post record.
  • Material can come first. subjects is 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 subjects point 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#

PropertyTypeDescription
titlestringDisplay title for this attachment (e.g. 'Impact Assessment Report', 'Audit Findings') maxLength: 256
createdAtstring (datetime)Client-declared timestamp when this record was originally created.

Optional properties#

PropertyTypeDescription
subjectsarray of strongRefReferences 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
contentTypestringThe type of attachment. Values beyond the known set are permitted. maxLength: 64 Known values: update, report, audit, evidence, testimonial, methodology.
contentarray of union: org.hypercerts.defs#uri, org.hypercerts.defs#smallBlobThe files, documents, or external references included in this attachment record. maxItems: 100
shortDescriptionstringShort summary of this attachment, suitable for previews and list views. Rich text annotations may be provided via shortDescriptionFacets. maxLength: 3000 maxGraphemes: 300
shortDescriptionFacetsarray of richtext facetRich text annotations for shortDescription (mentions, URLs, hashtags, etc).
descriptionunion: org.hypercerts.defs#descriptionString, Leaflet linear document, strongRefLong-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.
langsarray 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
locationstrongRef → app.certified.locationA strong reference to the location where this attachment's subject matter occurred. The record referenced must conform with the lexicon app.certified.location.
tagsarray of strongRef → org.hypercerts.vocab.tagReferences 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
capturedAtstring (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.
signaturesapp.certified.signature.defs#listOptional 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:

JSON
{
  "$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 contentType to say what kind of material it is. The known values are update, report, audit, evidence, testimonial, and methodology; other values are allowed. Use update for narrative updates. The label describes the material but doesn't verify it: an attachment labelled audit does not make its subject audited.
  • Prefer uploaded files for material that must not change. A smallBlob item is stored in the publisher's repository and addressed by its content hash, so the record's CID commits to those exact bytes. A uri item 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 smallBlob definition). Link to larger files with a uri item 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 its cid. 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 subjects points 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 location for where the subject matter happened. It points to an app.certified.location record, for example the site where photos were taken.
  • Render any attachment from its title. Applications can display an attachment from title and createdAt alone. 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. descriptionString is 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 as es or pt-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 no langs.