RecordWeb Protocol (RWP)

Draft Community Group Report,

More details about this document
This version:
https://recordweb.github.io/rwp/
Previous Versions:
Version History:
https://github.com/recordweb/rwp/commits/main/index.bs
Issue Tracking:
GitHub
Editor:

Abstract

This is the input for the proposed Community Group. The RecordWeb Protocol (RWP) is the normative technical specification for the creation, identification, versioning, linking, and cryptographic proof of Records in RWP-compliant systems. It defines the requirements a system must fulfil in order to create, manage, link, and prove Records in the sense of the RecordWeb Concept ([RWC]). RWP uses RFC 2119 compliance terminology and covers Record identity (DID), snapshot structure, payload validation, version graph (DAG), Case specification, integrity procedures, federation, and payload deletion across 14 chapters and three normative annexes.

Status of this document

1. Introduction and Scope

1.1. Purpose

The RecordWeb Protocol (RWP) is the normative technical specification for the creation, identification, versioning, linking, and cryptographic proof of Records in RWP-compliant systems.

The RecordWeb Concept ([RWC]) is an informative conceptual document. This specification defines the normative terminology and requirements for RWP conformance.

1.2. Scope

This document applies to:

This document does not apply to:

Standard Relationship
[DID-CORE] RWP uses DIDs as the identity mechanism; conformance with W3C DID Core 1.0 is REQUIRED
[PROVO] RWP lineage MAY be serialised as PROV-O. PROV-O serialisation is not required for RWP conformance.

1.4. Versioning of This Document

This document uses semantic versioning (SemVer): MAJOR.MINOR.PATCH.

The current version is 0.0.2 (Draft — not yet approved for production implementations).

2. The Record

2.1. Definition {#record-definition}

For the purposes of this specification, Record has the meaning defined in [ISO15489], clause 3.14. A Record MUST have the identity, structure, payload, type, schema, state, version and integrity evidence required by this specification.

For semantic interoperability, a Record is a specialization of 'prov:Entity'. The term Record remains the primary term of this specification. The term 'prov:Entity' is used only for a [PROVO]-compatible semantic representation.

@prefix prov: <http://www.w3.org/ns/prov#> .
@prefix rw:   <https://w3id.org/recordweb/ontology#> .

rw:Record
  rdfs:subClassOf prov:Entity .

rw:InformationRecord
  rdfs:subClassOf rw:Record .

rw:RelationRecord
  rdfs:subClassOf rw:Record .

rw:SystemRecord
  rdfs:subClassOf rw:Record .

rw:CaseRecord
  rdfs:subClassOf rw:RelationRecord .

rw:AssertionRecord
  rdfs:subClassOf rw:RelationRecord .

rw:SchemaRecord
  rdfs:subClassOf rw:SystemRecord .

rw:MergeRecord
  rdfs:subClassOf rw:SystemRecord .

rw:DeletionRecord
  rdfs:subClassOf rw:SystemRecord .

rw:MigrationRecord
  rdfs:subClassOf rw:SystemRecord .

rw:ConformanceRecord
  rdfs:subClassOf rw:SystemRecord .

2.2. Record taxonomy {#record-taxonomy}

Every Record has one primary conceptual purpose. For the purposes of this specification, a Record is classified as an InformationRecord, a RelationRecord, or a SystemRecord, as described in [RWC].

Any concrete Record Type is defined by a SchemaRecord in accordance with Record Type Definition.

The taxonomy is normative for the interpretation of this specification. It MUST NOT be interpreted as a mandatory implementation inheritance hierarchy, a mandatory JSON type hierarchy, or a replacement for concrete Record Types and their SchemaRecords.

An InformationRecord is a Record whose primary purpose is to carry semantically autonomous institutional or domain information.

Every InformationRecord MUST conform to a concrete Record Type. This specification does not provide a list of InformationRecord Types.

A RelationRecord is a Record whose primary purpose is to establish, preserve, and make provable a meaningful relationship between Records.

A SystemRecord is a Record whose primary purpose is to define, document, or prove a RecordWeb system rule, operation, or capability.

A CaseRecord is a RelationRecord. It represents a persisted, governed view of linked Records. A CaseRecord MUST NOT be a container and MUST NOT contain the payload of the Records to which it relates. The protocol representation and validation requirements for CaseRecords are defined in CaseRecord Specification.

An AssertionRecord is a RelationRecord. It represents an attributable assertion that a subject resource stands in a specified relationship to an object resource. The protocol representation and validation requirements for AssertionRecords are defined in AssertionRecord Specification.

A SchemaRecord is a SystemRecord. It defines a concrete Record Type and its associated schema and validation requirements.

A MergeRecord is a SystemRecord.

A DeletionRecord is a SystemRecord.

A MigrationRecord is a SystemRecord.

A ConformanceRecord is a SystemRecord.

3. Record Identity (DID)

3.1. Requirements for Record Identity

Every Record MUST possess a globally unique, permanent identity.

This identity:

3.2. DID Format

The identity of a Record MUST be expressed as a Decentralized Identifier (DID) in accordance with [DID-CORE].

Normative format: did:rwp:{namespace}:{unique-id}

Component Requirement
did Literal; immutable
rwp DID method for RecordWeb Protocol; immutable
<namespace> Identifier of the organisation or system; MUST be uniquely registered. During the transition phase, a namespace MAY be formed on the basis of the DNS domain name of the organisation (e.g. did:rwp:bern.ch:<uuid>).
<unique-id> Unique identifier of the Record within the namespace; MUST be a UUID v4 or a cryptographically equivalent random value

Example: did:rwp:bern.ch:f47ac10b-58cc-4372-a567-0e02b2c3d479

3.3. DID Document

For every Record DID, a DID document MUST exist containing the following fields:

{
  "@context": "https://www.w3.org/ns/did/v1",
  "id": "did:rwp:bern.ch:f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "recordEndpoint": "https://records.bern.ch/api/v1/records/f47ac10b",
  "created": "2026-05-31T14:00:00Z",
  "updated": "2026-05-31T14:00:00Z",
  "currentVersion": "sha256:e3b0c44298fc1c149afb...",
  "controller": "did:rwp:bern.ch:controller-001",
  "verificationMethod": [
    {
      "id": "did:rwp:bern.ch:f47ac10b#key-1",
      "type": "Ed25519VerificationKey2020",
      "controller": "did:rwp:bern.ch:controller-001",
      "publicKeyMultibase": "z6MkhaXgBZDvotDkL..."
    }
  ]
}
Field Required Description
@context MUST W3C DID Context URI
id MUST DID of the Record; identical to the Record DID
recordEndpoint MUST URL at which the Record can be retrieved
created MUST ISO 8601 timestamp of DID creation
updated MUST ISO 8601 timestamp of last DID document update
currentVersion MUST Content hash of the current finalised version (empty for pure draft)
controller MUST DID of the controlling entity (organisation or person)
verificationMethod MUST At least one verification method for signature validation

The DID document MUST be updated when the physical storage location changes (recordEndpoint, updated, currentVersion). All other fields MUST NOT be changed.

3.4. DID Resolver Requirements

An implementation claiming the resolver role MUST provide a DID resolver that:

An implementation claiming another RWP profile or role MAY rely on a resolver operated by another conformant implementation. It is not required to operate a DID resolver itself unless it claims the resolver role.

A producer or custodian that creates or manages RWP Records MUST ensure that the associated Record DIDs remain resolvable in accordance with this specification.

4. Record Structure

4.1. Overview

Every Record MUST consist of exactly three components:

  1. **Identity** — the DID of the Record (Record Identity (DID))

  2. **Payload** — the content of the Record (Payload and Formats)

  3. **Metadata** — descriptive dimensions of the Record (Minimum Metadata Set)

Together, these three components form a snapshot — an immutable, versioned representation of the Record at a specific point in time.

4.2. Snapshot Definition

A snapshot is the atomic unit of versioning in RecordWeb.

A snapshot MUST fulfil the following properties:

4.3. Minimum Metadata Set

Every snapshot MUST contain the following metadata fields:

{
  "did": "did:rwp:bern.ch:f47ac10b-58cc-4372-a567-0e02b2c3d479",
  "snapshotHash": "sha256:e3b0c44298fc1c149afb4c8996fb924...",
  "recordType": "did:rwp:ech-standards.ch:schema-baubewilligung-antrag",
  "schemaVersion": "sha256:a665a45920422f9d417e4867efdc4fb8a...",
  "state": "finalized",
  "created": "2026-05-31T14:00:00Z",
  "finalized": "2026-05-31T15:30:00Z",
  "owner": "did:rwp:bern.ch:user-petra-muster",
  "parents": ["sha256:previousSnapshotHash..."],
  "classification": "internal",
  "retentionPolicy": "did:rwp:bern.ch:retention-bauakten-30y",
  "tags": ["building-permit", "parcel-451", "2026"],
  "accessPolicy": null,
  "payloadHash": "sha256:d2d2d2d2d2...",
  "payloadFormat": "application/pdf;profile=PDF-A-2b",
  "signature": "z3FttV7..."
}
Field Required Type Description
did MUST DID Identity of the Record
snapshotHash MUST SHA-256 Hash of this snapshot (incl. payload and metadata)
recordType MUST DID Reference to the SchemaRecord of the type
schemaVersion MUST SHA-256 Hash of the schema version against which this snapshot was validated
state MUST Enum draft or finalized; additional values permitted per type schema
created MUST ISO 8601 Timestamp of snapshot creation
finalized MUST (when finalized) ISO 8601 Timestamp of finalisation
owner MUST DID Responsible person or organisational unit
parents MUST Array<SHA-256> Hashes of predecessor snapshots; empty for first snapshot
classification SHOULD String Protection level per the organisation’s internal scheme
retentionPolicy SHOULD DID Reference to retention rule
tags MAY Array<String> Free-text markers for search and filtering
accessPolicy MAY Object|null Delegated authorisation model (Access Control Delegation Framework)
payloadHash MUST SHA-256 Hash of the payload
payloadFormat MUST MIME-Type Format of the primary payload incl. profiles
signature MUST (when finalized) Multibase Cryptographic signature of the record owner over the snapshot hash

4.4. Snapshot Hash Calculation

The snapshotHash MUST be calculated as follows:

  1. Serialise the metadata fields (without snapshotHash itself) as canonical JSON ([RFC8785])

  2. Concatenate: canonicalMetadataJSON || payloadBytes

  3. Calculate SHA-256 over the result

snapshotHash = SHA-256( canonicalize(metadata \ {snapshotHash}) || payloadBytes )

A system MUST verify the snapshotHash after every finalisation before the snapshot is accepted as valid.

5. Payload and Formats

5.1. Payload Definition

The payload of a Record is the content the Record carries, the actual information.

A payload:

5.2. Permitted Payload Types

RWP distinguishes three payload categories:

Category Description Examples
Structured Machine-readable, schema-validatable data JSON, XML, YAML
Documentary Human-readable documents with defined structure PDF/A, DOCX, ODT, Markdown
Binary Non-textual data with descriptive schema TIFF, JPEG 2000, MP4, ZIP

5.3. Multi-Representation

A snapshot MAY carry multiple representations of the same payload. This is provided in particular for the transition from working format (draft) to long-term format (finalised).

If a snapshot contains multiple representations, ALL of the following MUST apply:

{
  "payloadRepresentations": [
    {
      "format": "text/markdown",
      "hash": "sha256:aabbcc...",
      "primary": false,
      "role": "source"
    },
    {
      "format": "application/pdf;profile=PDF-A-2b",
      "hash": "sha256:ddeeff...",
      "primary": true,
      "role": "publication"
    }
  ]
}
Field Required Description
format MUST MIME type incl. profiles
hash MUST SHA-256 of this representation
primary MUST Exactly one representation MUST be true
role SHOULD Semantic role: source, publication, preview, archive

5.4. Format Requirements per State

The schema of a Record type MUST define the permitted payload formats for each state. If a schema contains no explicit format requirements, the following defaults apply:

State Permitted formats (default)
draft All MIME types not explicitly excluded in the schema of the Record type
finalized Only formats listed under RWP archival-grade formats

RWP archival-grade formats (normative):

MIME Type Format Suitability
application/pdf;profile=PDF-A-1b PDF/A-1b Documents without embedded multimedia
application/pdf;profile=PDF-A-2b PDF/A-2b Documents with embedded files
application/pdf;profile=PDF-A-3b PDF/A-3b Documents with arbitrary attachments
text/xml XML (well-formed) Structured data
application/json JSON Structured data (with schema reference)
image/tiff TIFF Raster images
image/jp2 JPEG 2000 Raster images (near-lossless)
text/plain;charset=UTF-8 Plain Text UTF-8 Pure text documents
text/markdown CommonMark Markdown Source format with publication representation

5.5. Conversion During Finalisation

When a system transitions a Record from state draft to finalized, it MUST:

  1. Validate the payload against the finalised format of the schema

  2. If the current payload is not in archival-grade format: convert automatically or request conversion from the operator

  3. Store both formats as multi-representation in the snapshot (SHOULD)

  4. Document the conversion act as metadata (conversionMethod, conversionTimestamp)

A system MUST NOT finalise a Record whose payload does not conform to the format defined for finalized and for which no archival-grade conversion is possible.

6. Record Types and Schemas

6.1. Record Type Definition

Every Record MUST be assigned to a Record type. A Record type:

6.2. SchemaRecord

A SchemaRecord is a specialised Record type that carries the definition of another Record type.

A SchemaRecord MUST:

Minimal SchemaRecord payload example:

{
  "rwpSchemaVersion": "0.1",
  "schemaId": "did:rwp:bern.ch:schema-building-permit-application",
  "displayName": "Building Permit Application",
  "allowedStates": ["draft", "finalized"],
  "stateTransitions": [
    { "from": "draft", "to": "finalized", "requiresOwnerSignature": true }
  ],
  "payloadFormats": {
    "draft": ["application/vnd.openxmlformats-officedocument.wordprocessingml.document",
              "text/markdown"],
    "finalized": ["application/pdf;profile=PDF-A-2b"]
  },
  "jsonSchema": {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    "type": "object",
    "required": ["parcelNumber", "applicant", "constructionProject", "date"],
    "properties": {
      "parcelNumber": { "type": "string" },
      "applicant": { "type": "string" },
      "constructionProject": { "type": "string" },
      "date": { "type": "string", "format": "date" }
    }
  }
}

6.3. Core Record Types

RWP defines the following core Record types (with DID Suffix):

The conformance requirements for these Record types are profile-, role-, and capability-specific. An implementation MUST support a core Record type only where this specification requires that support for a claimed profile, role, or exercised capability.

The capability-bound requirements are defined in Capability-bound requirements.

Additional Record types MAY be defined by organisations or standards bodies. They MUST be published as SchemaRecords and be resolvable via a DID.

6.4. Schema Versioning and Backward Compatibility

When a SchemaRecord is finalised in a new version, the following applies:

7. States and Transitions

7.1. State Model

Every Record snapshot has exactly one state. The state describes the validity and linkability status of the snapshot.

Core states (normative, for all Record types):

State Linkable Immutable Description
draft NO NO Being processed; content may change
finalized YES YES Complete; content cryptographically secured

Record types MAY define additional states. These MUST be specified in the SchemaRecord and MUST be reachable from one of the core states or lead into one.

Example of an extended state machine for type "contract":

draft → in-review → finalized
↓
rejected (terminal state, not linkable)

7.2. Linkability

A Record MUST be in the finalized state to be used as the target of a hard link.

A system MUST return an error when an attempt is made to set a hard link to a Record that is not in the finalized state.

Exception: Working references (soft links) per working-references MAY point to Records in any state, including draft Records.

7.3. Finalisation Requirements

A system MUST perform the following checks before finalising a snapshot:

  1. Schema validation: Payload conforms to the schema in the version defined for finalized

  2. Format validation: Payload format conforms to the payloadFormats.finalized requirements of the schema

  3. Mandatory field check: All MUST metadata fields are present and correctly typed

  4. Owner signature: If the schema defines signaturePolicy: owner, the record owner MUST have cryptographically signed the snapshot hash. For signaturePolicy: system, the signature MAY be generated by an authorised system key. For signaturePolicy: none, signature validation is omitted.

  5. Parent integrity: All referenced parent hashes are resolvable in the system

If any of these checks fails, the system MUST NOT finalise the snapshot and MUST return an error with a validation code.

7.4. Irreversibility of Finalisation

A finalized snapshot MUST NOT be reverted to the state draft.

Corrections, revisions, replacements, and other continuations of the same Record MUST be represented as a new snapshot of that Record.

Such a snapshot MUST:

An implementation MUST NOT represent a correction, revision, replacement, or continuation of the same Record as a new Record that is related to the earlier Record only through an AssertionRecord or another cross-Record relationship.

A new Record MAY be created where a new semantically autonomous information object arises. Such a Record MAY document derivation, source, or other relationships to an earlier Record through an AssertionRecord. It MUST NOT thereby be treated as a continuation in the version graph of that earlier Record.

8. Version Graph (DAG)

8.1. Graph Structure

The totality of all snapshots of a Record and their parent-child relationships forms the version graph.

The version graph MUST be a Directed Acyclic Graph (DAG):

A system MUST check upon receipt of a new snapshot whether adding its parent references would create a cycle. If so, the snapshot MUST be rejected.

8.2. Nodes

Every node in the version graph is a snapshot per Section 3.2.

Property Requirement
Unique identity SHA-256 of the snapshot (snapshotHash); MUST be unique
Immutability Finalised nodes MUST NOT be changed
Resolvability Every node MUST be retrievable in the system via its snapshotHash

8.3. Edges (Parent References)

An edge connects a snapshot (child) with its predecessor snapshot (parent).

Edge requirements:

8.4. Branches

A branch arises when two or more new draft snapshots with the same parent reference emerge from a finalized snapshot.

8.5. Merges

A merge snapshot is a snapshot with two or more parent references. It consolidates two branches.

Before a merge snapshot can be finalised, a MergeRecord MUST be created:

{
  "mergeRecord": {
    "mergedSnapshots": [
      "sha256:branch-a-snapshot-hash...",
      "sha256:branch-b-snapshot-hash..."
    ],
    "mergeReason": "Consolidation after coordination between departments",
    "mergedBy": "did:rwp:bern.ch:user-petra-muster",
    "mergedAt": "2026-05-31T16:00:00Z",
    "resultSnapshot": "sha256:merged-snapshot-hash..."
  }
}

The MergeRecord MUST be finalised before the merge snapshot can be finalised.

8.6. Cross-Record Merges

When a new Record arises from two or more existing finalized Records (cross-Record merge), the following MUST apply:

9. CaseRecord Specification

9.1. Case as a specialised Record Type {#case-type}

A CaseRecord is a RelationRecord and a concrete Record type. It is subject to all requirements that apply to Records and supplements them with the Case-specific requirements defined in this section.

A CaseRecord is a persisted, governed view of linked Records. It is itself a Record with its own identity, state, version history, schema association, metadata, and integrity evidence.

A CaseRecord MUST NOT be interpreted as a container into which Records are placed. A Record linked by a CaseRecord remains an independent Record and is not embedded in the CaseRecord payload.

9.2. Case Schema (normative)

A CaseRecord payload MUST contain the following fields:

{
  "recordDid": "did:rwp:bern.ch:f47ac10b-case-001",
  "caseType": "did:rwp:bern.ch:schema-building-permit-case",
  "title": "Building Permit Musterstrasse 12, Parcel 451",
  "trigger": {
    "type": "hard",
    "recordDid": "did:rwp:bern.ch:application-001",
    "snapshotHash": "sha256:application-finalized-hash..."
  },
  "context": [
    {
      "type": "hard",
      "recordDid": "did:rwp:bern.ch:zoning-plan-2024",
      "snapshotHash": "sha256:zoning-plan-hash...",
      "role": "Legal basis"
    },
    {
      "type": "hard",
      "recordDid": "did:rwp:bern.ch:case-planning-approval-001",
      "snapshotHash": "sha256:planning-approval-case-hash...",
      "role": "Related administrative proceeding"
    }
  ],
  "process": [
    {
      "type": "hard",
      "recordDid": "did:rwp:bern.ch:minutes-site-inspection",
      "snapshotHash": "sha256:minutes-hash...",
      "role": "Investigation"
    }
  ],
  "decision": null,
  "result": null,
  "merkleRoot": "sha256:case-merkle-root..."
}

9.3. Case Elements (normative)

A complete CaseRecord MUST contain all five Case elements. An element that permits an empty value is considered present when it is represented in the CaseRecord payload, even if its value is an empty array or null, as applicable. A Record MAY fulfil multiple elements.

Unless a CaseRecord schema defines more specific constraints, every Case element MAY link to any Record type, including another CaseRecord.

Element Required for finalisation Description
trigger MUST Exactly one Record that triggered the Case; MUST be a hard link
context SHOULD Information relevant to understanding and processing
process MAY (empty allowed) Documentation of processing steps
decision MAY (empty allowed) Record(s) documenting the decision; MUST be a hard link
result MUST (min. 1) At least one Record documenting the outcome; MUST be a hard link

Exception — ad-hoc Case: A CaseRecord schema MAY be marked as adhoc: true. Ad-hoc Cases have no mandatory fields other than trigger and recordDid. They MUST be marked in the metadata object as caseVariant: "adhoc".

A Case link MAY target any Record, including an InformationRecord, a RelationRecord (including another CaseRecord), or a SystemRecord.

A hard link points to one identified finalized snapshot of a target Record. A hard link MUST contain the target recordDid and snapshotHash.

A hard link is immutable after finalisation of the referencing CaseRecord.

A soft link is a working reference that points to a target recordDid without identifying a target snapshot. A soft link MAY point to a draft or finalized Record.

A CaseRecord containing one or more soft links MUST NOT be finalised. Every soft link MUST be converted to a hard link before finalisation of the CaseRecord.

A system MUST check during a CaseRecord finalisation attempt whether soft links are present. If soft links are present, the system MUST reject the finalisation and return the unresolved soft links.

A CaseRecord MAY link to another CaseRecord through a soft link or a hard link.

A hard link to a CaseRecord MUST identify a finalized snapshot of the target CaseRecord through its recordDid and snapshotHash.

During finalisation of a referencing CaseRecord, the system MUST resolve and validate every target CaseRecord snapshot referenced through a hard link, subject to the applicable federation and offline-validation rules.

The snapshotHash of a hard-linked target CaseRecord MUST be included in the Merkle root of the referencing CaseRecord.

A soft link MAY refer to a draft or finalised CaseRecord during work. A soft link to a CaseRecord MUST be converted to a hard link before finalisation of the referencing CaseRecord.

A link from CaseRecord A to CaseRecord B references only the identified snapshot of CaseRecord B.

A CaseRecord-to-CaseRecord link MUST NOT include, copy, inherit, or otherwise treat Records linked by CaseRecord B as direct members of CaseRecord A.

The referenced CaseRecord B snapshot and its Merkle root provide evidence of the Records directly linked by CaseRecord B at the time that snapshot was finalised. A Record is a direct member of CaseRecord A only if CaseRecord A links to that Record explicitly.

9.6. Case Merkle Root

The Merkle root of a CaseRecord MUST be calculated as follows:

  1. Collect the snapshotHash value of every hard link in the CaseRecord, including every hard link to another CaseRecord.

  2. Sort the collected snapshotHash values lexicographically by their canonical serialised value.

  3. Calculate the Merkle root over the sorted list using the Merkle Tree Algorithm.

merkleRoot = MerkleRoot( sort( [snapshotHash_1, snapshotHash_2, ... snapshotHash_n] ) )

The Merkle root of a CaseRecord MUST include the hash of each directly hard-linked target snapshot. It MUST NOT recursively include the individual hard-link hashes or linked Record snapshots contained in a referenced CaseRecord.

The Merkle root MUST be recalculated every time a hard link is added or removed. A system MUST verify the Merkle root before finalising the CaseRecord.

9.7. Case Completeness Check

A system SHOULD perform a completeness check on a CaseRecord at any time upon request and return:

{
  "recordDid": "did:rwp:bern.ch:f47ac10b-case-001",
  "complete": false,
  "missingElements": ["decision", "result"],
  "openWorkingReferences": ["did:rwp:bern.ch:expert-opinion-draft-001"],
  "merkleRootValid": true
}

10. AssertionRecord Specification

10.1. Purpose and scope {#assertionrecord-purpose}

An AssertionRecord is a RelationRecord that preserves an attributable assertion that a subject resource stands in a specified relationship to an object resource.

An AssertionRecord is itself a Record. It has its own identity, state, version history, schema association, metadata and integrity evidence. It does not modify, finalise, merge, delete, or otherwise change either the subject or the object to which it refers.

An AssertionRecord MAY refer to Records in the same namespace or in another namespace. Referencing a Record in another namespace MUST NOT imply acceptance, storage, reciprocity, modification, or any other obligation for the custodian of the referenced Record.

10.2. Assertion model {#assertionrecord-model}

An AssertionRecord expresses one directed relationship:

subject -- predicate --> object

The subject identifies the resource from which the relationship is asserted. The predicate identifies the semantics of the relationship. The object identifies the resource to which the relationship is asserted.

The subject and object MUST be resource reference objects containing an id field.

The id field MUST identify the referenced resource. It MAY contain an RWP DID, another DID, or an absolute IRI, subject to the constraints of the applicable predicate declaration.

A resource reference identifying an RWP Record MAY additionally contain a snapshotHash field.

Where snapshotHash is present:

Where snapshotHash is absent, the AssertionRecord refers to the identified Record or other resource independently of a specific version.

An AssertionRecord MUST NOT be interpreted as modifying the subject or object. It preserves only the assertion made by its asserting Agent.

10.3. Relationship predicate {#assertionrecord-predicate}

An AssertionRecord MUST contain a predicate field.

The value of predicate MUST be an absolute IRI conforming to [RFC3987]. The predicate IRI MUST identify a relationship term permitted by the Relationship Vocabulary.

The meaning of an asserted relationship MUST NOT be carried solely by unconstrained natural-language text. A human-readable predicate label MAY be provided as optional, localised presentation metadata. Such a label MUST NOT replace the predicate IRI and MUST NOT be used as the sole basis for semantic interpretation or validation.

The applicable predicate declaration MUST define the predicate’s semantics, direction, permitted subject kinds, permitted object kinds, version, and validation requirements.

10.4. Assertion payload {#assertionrecord-payload}

The payload of an AssertionRecord MUST contain subject, predicate, object, assertedBy, and assertedAt.

The value of assertedBy MUST identify the Agent responsible for the assertion. The applicable SchemaRecord MUST define the relationship between assertedBy, the Record owner, and the verification method used to finalise the AssertionRecord.

{
  "subject": {
    "id": "did:rwp:record-A",
    "snapshotHash": "sha256:..."
  },
  "predicate": "https://www.w3.org/ns/prov#wasDerivedFrom",
  "object": {
    "id": "did:rwp:record-B"
  },
  "assertedBy": "did:rwp:agent-...",
  "assertedAt": "2026-08-13T11:00:00Z"
}

The subject and object values MUST be identifiers that can be interpreted according to the applicable predicate and SchemaRecord.

10.5. Validation {#assertionrecord-validation}

An AssertionRecord MUST be validated against its SchemaRecord before it is finalised.

Validation MUST verify at least that:

  1. the predicate value is an absolute IRI;

  2. subject, predicate, and object are present;

  3. the subject and object satisfy the constraints declared for the predicate;

  4. the asserting Agent and time of assertion are available; and

  5. the AssertionRecord satisfies the normal Record integrity and finalisation requirements.

Where the target namespace exposes an LDN inbox, the asserting party MAY notify the target custodian that a new AssertionRecord refers to one of its Records. Such a notification is informational only. It MUST NOT create an obligation to store, mirror, accept or reciprocate the relationship.

An AssertionRecord MAY valid as an assertion even where a referenced external resource cannot be resolved, provided that the assertion identifies that resource unambiguously and the applicable SchemaRecord permits unresolved references. A failure to resolve a referenced resource MUST NOT be interpreted as a modification of, or rejection by, that resource’s custodian.

11. Relationship Vocabulary

11.1. Scope and conformance {#relationship-vocabulary-scope}

This section defines the controlled relationship vocabulary used by AssertionRecords.

A conforming AssertionRecord MUST use a predicate IRI that is either:

  1. an applicable PROV-O predicate defined by this specification; or

  2. a predicate explicitly permitted by the SchemaRecord that defines the concrete AssertionRecord type.

A Conformance Profile MAY require an implementation to create, validate, retain, or consume AssertionRecords using specified predicate vocabularies. A Conformance Profile MUST NOT itself define, broaden, reverse, or otherwise alter the semantics of a relationship predicate.

For provenance and version-lineage relationships, the applicable PROV-O predicate MUST be used where PROV-O expresses the intended semantics.

An AssertionRecord MUST NOT use a predicate whose semantics, direction, permitted subject and object kinds, version, and validation requirements are not declared by this specification or by an applicable conformance profile.

The use of an IRI alone does not make a relationship predicate conformant.

11.2. Provenance and version-lineage predicates {#provenance-and-version-lineage-predicates}

For provenance and version-lineage relationships, an AssertionRecord MUST use an applicable [PROVO] predicate where a PROV-O predicate expresses the intended relationship semantics.

The following PROV-O predicates are part of the RWP core relationship vocabulary:

An AssertionRecord using a PROV-O predicate MUST satisfy the semantic domain and range constraints of that predicate.

11.2.1. Relationship to the RWP version graph {#assertionrecord-version-graph}

The RWP version graph is the authoritative representation of version succession between snapshots of the same Record.

A conforming implementation MUST determine RWP snapshot ancestry, direct parentage, branches, and merge relationships exclusively from the parents field and the rules defined in Version Graph.

An AssertionRecord using prov:wasRevisionOf, prov:wasDerivedFrom, or another provenance predicate MUST NOT create, alter, replace, or repair a version-graph edge.

Where an AssertionRecord documents a relationship between snapshots of the same Record, it MAY provide additional attributable documentary evidence. It MUST NOT be used to infer a parent relationship that is absent from the version graph.

If an AssertionRecord and the version graph make incompatible statements about version succession, a conforming implementation MUST treat the version graph as authoritative for all RWP versioning, ancestry, finalisation, merge, and integrity decisions.

An AssertionRecord that conflicts with the version graph remains an attributable assertion. Its conflict with the version graph MUST NOT alter the integrity or history of either referenced Record.

In particular:

A Record is an Entity for the purposes of this section. A Record MUST NOT be used as the subject or object of a PROV-O predicate where the predicate’s declared semantics require an Agent or an Activity.

11.3. Contextual relationships {#contextual-relationships}

Institutional, functional, legal, subject-matter, and archival-context relationships are not necessarily provenance relationships. Such relationships MUST NOT be represented using a PROV-O predicate unless the PROV-O predicate expresses their intended semantics.

A contextual relationship predicate MAY be used only where it is explicitly permitted by the SchemaRecord that defines the concrete AssertionRecord type.

The applicable SchemaRecord MUST identify the permitted predicate IRIs, their applicable vocabulary versions, and the validation constraints that apply to them.

A conformance profile that permits a contextual relationship predicate MUST declare the predicate’s semantics, direction, permitted subject and object kinds, version, and validation requirements.

A profile MAY declare a contextual relationship predicate defined by [RICO]. Where it does so, the profile MUST identify the exact RiC-O predicate IRI and the applicable RiC-O version. The profile MUST NOT redefine, broaden, or contradict the semantics of the declared RiC-O predicate.

11.4. RiC-O contextual predicates {#rico-contextual-predicates}

[RICO] predicates MAY be used as predicate values in AssertionRecords only where they are explicitly permitted by an applicable conformance profile.

The use of a RiC-O predicate does not require an implementation to store, exchange, or process Records as RDF or JSON-LD. In an AssertionRecord, the RiC-O IRI identifies the semantics of the asserted relationship.

A conformance profile that permits a RiC-O predicate MUST declare:

  1. the exact predicate IRI;

  2. the RiC-O version to which the declaration applies;

  3. the semantics and direction of the predicate, with reference to the applicable RiC-O definition;

  4. the permitted subject kinds;

  5. the permitted object kinds;

  6. any additional RWP validation requirements; and

  7. the profile version in which the predicate is declared.

A profile MUST NOT permit a RiC-O predicate where an applicable PROV-O predicate expresses the intended provenance or version-lineage semantics.

A profile MAY impose constraints narrower than those of the declared RiC-O predicate. A profile MUST NOT broaden, reverse, or otherwise contradict the semantics or direction of the declared RiC-O predicate.

11.5. Schema predicate extensions {#schema-predicate-extensions}

A conformance SchemaRecord MAY define additional relationship predicates or permit the use of specifically identified external relationship predicates.

For each additional or externally permitted predicate, the SchemaRecord MUST declare:

  1. an absolute predicate IRI;

  2. a stable, versioned definition of its semantics;

  3. the relationship direction;

  4. the permitted subject kinds;

  5. the permitted object kinds;

  6. the required or permitted assertion metadata;

  7. the validation requirements; and

  8. the SchemaRecord version in which the predicate is declared.

For an externally defined predicate, the SchemaRecord MUST additionally identify the external vocabulary and its applicable version.

A SchemaRecord MUST NOT define or permit a predicate whose semantics duplicate an applicable PROV-O predicate. In that case, the applicable PROV-O predicate MUST be used.

A SchemaRecord MAY constrain the use of an external predicate more narrowly than the defining vocabulary permits. A SchemaRecord MUST NOT broaden, reverse, or contradict the semantics or direction defined by that vocabulary.

11.6. Predicate declarations {#predicate-declarations}

A predicate declaration MUST be versioned and resolvable through its IRI or through the applicable conformance profile.

The declaration MUST provide a human-readable definition. It SHOULD provide machine-readable representations where available, including RDF, JSON-LD, SHACL, JSON Schema, or equivalent validation artefacts.

A localised display label MAY accompany a predicate declaration. A display label is presentation metadata and MUST NOT replace the predicate IRI as the semantic identifier.

12. Integrity and Hashing Procedures

12.1. Hashing Procedure

RWP uses exclusively SHA-256 as the hashing procedure for:

A system MUST NOT use any hashing procedure other than SHA-256 for normative integrity proofs.

Note: A future version of RWP MAY permit SHA-3 or other procedures as an alternative if cryptographic weaknesses in SHA-256 become known. Until then, SHA-256 is the only permitted procedure.

12.2. Canonical JSON Serialisation

For all hash calculations over JSON objects, RFC 8785 (JSON Canonicalization Scheme, JCS) [RFC8785] MUST be used.

Requirements:

12.3. Snapshot Integrity

A system MUST check the integrity of a snapshot on the following events:

If the integrity check fails, the system MUST:

  1. Mark the snapshot as compromised

  2. Mark all dependent Records as integrity-warning

  3. Log the incident in the system log with timestamp and discrepancy

  4. Notify the responsible record owner via the DID (SHOULD)

The system MUST NOT automatically attempt to reconstruct the original content.

12.4. Signature Procedure

If the schema prescribes a signature (signaturePolicy: owner or signaturePolicy: system), the snapshot hash MUST be cryptographically signed during the finalisation act.

Requirements:

12.5. Merkle Tree Algorithm

For the calculation of the CaseRecord Merkle root, the following algorithm MUST be used:

function merkleRoot(hashes: SHA256[]) -> SHA256:
if hashes.length == 0: return SHA256("")
if hashes.length == 1: return hashes [0]

sorted = sort(hashes) // alphabetically by hex string

while sorted.length > 1:
nextLevel = []
for i in range(0, sorted.length, 2):
if i + 1 < sorted.length:
nextLevel.append( SHA256( sorted[i] || sorted[i+1] ) )
else:
nextLevel.append( sorted[i] ) // odd element carried over unchanged
sorted = nextLevel

return sorted[0]

13. Optional Ledger Anchoring

13.1. Purpose and Scope

Ledger anchoring is an optional extension of RWP. It enables the external, immutable proof of CaseRecord Merkle roots on a distributed infrastructure.

A system MUST be fully RWP-compliant without ledger anchoring. Ledger anchoring supplements the internal integrity assurance with an external proof independent of the operating organisation.

13.2. Requirements for the Ledger

If a system implements ledger anchoring, the ledger used MUST:

Recommended implementation: Hyperledger Fabric [HYPERLEDGER]. Other permissioned distributed ledger technologies MAY be used if they fulfil the above requirements.

13.3. Anchoring Protocol

When a finalised CaseRecord is anchored, the ledger entry MUST contain the following fields:

{
  "rwpAnchor": {
    "version": "0.1",
    "caseDid": "did:rwp:bern.ch:f47ac10b-case-001",
    "caseSnapshotHash": "sha256:case-finalized-snapshot-hash...",
    "merkleRoot": "sha256:case-merkle-root...",
    "anchoredAt": "2026-05-31T16:00:00Z",
    "anchoredBy": "did:rwp:bern.ch:controller-001",
    "ledgerTxId": "abc123..."
  }
}

The ledger entry MUST NOT contain any payload content, personal data, or classified information. Only cryptographic hash values and identifiers are permitted.

13.4. Anchoring Reference in the Case

When a CaseRecord has been anchored, the CaseRecord snapshot MUST be updated with an anchorReference field:

{
  "anchorReference": {
    "ledgerType": "hyperledger-fabric",
    "ledgerEndpoint": "https://ledger.bern.ch/api/v1",
    "txId": "abc123...",
    "anchoredAt": "2026-05-31T16:00:00Z"
  }
}

14. Access Control (Delegation Framework)

14.1. Scope and Principles

RWP deliberately defines no mandatory authorisation model. Data security and information protection are delegated to the implementing systems. This chapter defines an optional, interoperable delegation framework that compliant systems MAY implement.

The core principle: access control in RWP is attribute-based (ABAC) and delegatable. Rights are not assigned to roles in a fixed hierarchy, but expressed as verifiable claims attached to DIDs.

14.2. Access Policy Block

A Record snapshot MAY contain an accessPolicy block in the metadata:

{
  "accessPolicy": {
    "visibility": "restricted",
    "readAccess": [
      "did:rwp:bern.ch:unit-legal",
      "did:rwp:bern.ch:unit-planning"
    ],
    "writeAccess": [
      "did:rwp:bern.ch:user-petra-muster"
    ],
    "delegationAllowed": true,
    "expiresAt": null
  }
}
Field Required Description
visibility SHOULD public, restricted, or confidential
readAccess MAY Array of DIDs with read permission
writeAccess MAY Array of DIDs with write permission (draft state only)
delegationAllowed MAY Whether listed DIDs may further delegate access
expiresAt MAY ISO 8601 timestamp after which access policy expires

14.3. Delegation Chain

When delegationAllowed: true, a listed DID MAY issue a signed delegation token granting access to a third DID. The delegation token MUST:

Implementing systems MAY enforce delegation chains and MUST validate delegation token signatures before granting access.

15. Federation

15.1. Federation Model

RWP federation is modelled after the DNS architecture: a decentralised, hierarchical namespace model without a single point of failure.

Every RWP namespace (the <namespace> component of a DID, e.g. bern.ch) is operated by the owning organisation. Namespace resolvers are federated: each resolver knows its own namespace and can route resolution requests for unknown namespaces to peer resolvers.

15.2. Namespace Registry

The authoritative namespace registry is the subject of a future RWP extension. During the transition phase, the following applies:

15.3. Resolver Requirements

An RWP federation resolver MUST:

DNS TXT record format for resolver discovery:

_rwp-resolver.bern.ch. 300 IN TXT "v=rwp1;endpoint=https://resolver.bern.ch/api/v1"

15.4. Cross-Namespace Links

A Record in namespace bern.ch MAY contain hard links to Records in other namespaces (e.g. did:rwp:bag.admin.ch:guideline-001).

When resolving cross-namespace links, a system MUST:

  1. Extract the namespace component from the linked DID

  2. Discover the resolver endpoint via DNS TXT lookup (Resolver Requirements)

  3. Verify the snapshot hash of the linked Record after retrieval

  4. Cache the resolved snapshot locally with the original hash for integrity verification

16. Payload Deletion

16.1. Deletion Principles

RecordWeb’s immutability and data protection erasure obligations (GDPR, Swiss DSG) are in tension. RWP resolves this tension through a tiered deletion regime.

The applicable regime is declared in the deletionRegime field of the Record’s metadata at the time of creation. Implementations MUST respect this field and MAY enforce it at the infrastructure level.

16.2. Deletion Regimes

RWP defines three deletion regimes:

Regime Key Description When applicable
Payload deletion payload-only The payload is deleted; DID, metadata, and version graph are retained. The Record continues to exist as a provable "empty shell". Default. Where provenance continuity is legally required despite erasure (e.g. audit trails, public registers).
Full deletion full-delete The entire Record (including DID, metadata, and graph edges) is deleted. Where no retention obligation exists and the right to erasure is absolute (e.g. erroneously captured personal data with no public interest basis).
Deletion exemption exempt No deletion occurs. The statutory retention obligation is documented as metadata. Where a statutory retention obligation overrides the erasure claim (e.g. tax records, notarial acts, public register entries).

16.3. DeletionRecord Protocol

When a payload deletion is executed, a DeletionRecord MUST be created and finalised before the payload is removed.

The DeletionRecord MUST contain:

{
  "deletionRecord": {
    "targetDid": "did:rwp:bern.ch:f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "targetSnapshotHash": "sha256:snapshot-to-be-deleted...",
    "deletionRegime": "payload-only",
    "legalBasis": "GDPR Art. 17 — Right to erasure",
    "requestedBy": "did:rwp:bern.ch:user-max-mustermann",
    "approvedBy": "did:rwp:bern.ch:unit-legal",
    "deletedAt": "2026-06-01T10:00:00Z",
    "retainedFields": ["did", "metadata", "versionGraph"]
  }
}

After the DeletionRecord is finalised:

  1. The payload bytes are securely overwritten

  2. The payloadHash field in the snapshot is replaced with the string "deleted:<DeletionRecord-DID>"

  3. The DID document’s currentVersion field is updated

  4. The DID resolver MUST return HTTP 410 for full-delete regimes

16.4. Solid Pod Delivery (optional)

For Records whose primary subject is an individual citizen, RWP offers an optional delivery extension: delivery of finalised Records into a citizen’s Solid Pod.

When a system implements Solid Pod delivery, it MUST:

Typical use cases: driving licences, medical images, residence registration confirmations, diplomas, building permits (delivered to the applicant).

The citizen MAY present the Pod-held Record to any third party, who can independently verify its authenticity via the DID and cryptographic hash without querying the issuing authority.

17. Conformance and Implementation Claims

17.1. Scope of conformance {#conformance-scope}

Conformance in RWP applies to an identifiable software implementation or software component.

A conformance claim MUST identify:

A conformance claim applies only to the Records, Record types, operations, and responsibilities covered by the claimed profiles and roles. It MUST NOT be interpreted as a claim that an entire product, organisation, deployment, or source system fulfils all RWP requirements.

An implementation MAY claim multiple profiles and roles.

An implementation claiming an RWP Record profile MUST claim at least one role.

An implementation claiming only the resolver role MAY make a role-only claim without claiming an RWP Record profile.

17.2. Conformance terminology {#conformance-terminology}

17.2.1. Record validation {#record-validation}

Record validation determines whether a specific Record or snapshot satisfies the applicable structural, semantic, and cryptographic requirements.

Depending on the applicable profile and Record type, validation MAY include:

A Record validation result applies only to the tested Record or snapshot. A successful validation result MUST NOT be interpreted as an implementation assessment, attestation, or certification.

17.2.2. Implementation assessment {#implementation-assessment}

Implementation assessment determines whether a named implementation version fulfils all requirements of one or more claimed RWP profiles and roles.

An implementation assessment MUST include positive and negative test cases relevant to every claimed profile and role.

An assessment MAY use an official RecordWeb test suite, an independently developed test suite, or another documented assessment method.

The result of an implementation assessment MAY be documented in a ConformanceRecord.

17.2.3. Attestation {#conformance-attestation}

An attestation is a signed statement by an identifiable attester about an implementation assessment.

An attestation MAY be self-attested or independently assessed.

A ConformanceRecord is the RWP SystemRecord used to preserve such an attestation.

17.2.4. Certification {#conformance-certification}

Certification is an institutional process outside the base RWP protocol.

A certification scheme MAY use ConformanceRecords, test suites, and assessment reports as evidence. RWP does not define or require an accreditation authority, certification mark, liability regime, or certification revocation procedure.

The presence of a ConformanceRecord MUST NOT by itself be interpreted as certification.

17.3. Profiles {#conformance-profiles}

17.3.1. RWP Information Record Conformant {#information-record-profile}

An implementation claiming RWP Information Record Conformant MUST satisfy the applicable RWP requirements for InformationRecords according to its claimed roles.

A producer claiming this profile MUST be able to create and finalise InformationRecords with the required identity, schema association, metadata, payload validation, integrity evidence, and version graph.

A custodian claiming this profile MUST retain and make retrievable the InformationRecord snapshots for which it acts as custodian.

A consumer claiming this profile MUST retrieve and validate InformationRecords in accordance with Record validation.

17.3.2. RWP Case Record Conformant {#case-record-profile}

An implementation claiming RWP Case Record Conformant MUST satisfy the applicable RWP requirements for CaseRecords according to its claimed roles.

A producer claiming this profile MUST create and finalise CaseRecords in accordance with CaseRecord Specification.

A Case implementation MAY reference InformationRecords or other Records managed by another RWP implementation. It is not required to create, store, or own those linked Records.

A CaseRecord producer or consumer MUST apply the applicable hard-link, soft-link, target-validation, and Merkle-root requirements.

17.3.3. RWP Assertion Record Conformant {#assertion-record-profile}

An implementation claiming RWP Assertion Record Conformant MUST satisfy the applicable RWP requirements for AssertionRecords according to its claimed roles.

A producer claiming this profile MUST create AssertionRecords with a valid SchemaRecord, a permitted predicate IRI, valid subject and object references, an asserting Agent, a time of assertion, and the required Record integrity evidence.

A consumer claiming this profile MUST validate AssertionRecords in accordance with AssertionRecord validation and Relationship Vocabulary scope.

A custodian claiming this profile MUST retain and make retrievable the AssertionRecord snapshots for which it acts as custodian.

17.3.4. RWP Relation Record Conformant {#relation-record-profile}

An implementation MAY claim RWP Relation Record Conformant only if it also claims both RWP Case Record Conformant and RWP Assertion Record Conformant.

RWP Relation Record Conformant introduces no requirements beyond the combined requirements of those two profiles.

17.3.5. RWP Source Integration Conformant {#source-integration-profile}

An implementation claiming RWP Source Integration Conformant MUST provide a source-provenance statement for every source object that it exposes to, captures for, or transfers into an RWP context.

The source integration profile is independent of RWP Record production. A source-adapter MAY claim this profile without creating an RWP DID, Record, or snapshot.

If a source-adapter creates and finalises an RWP InformationRecord, it MUST additionally satisfy the applicable requirements of RWP Information Record Conformant.

A source-provenance statement MUST contain:

{
  "sourceSystem": "https://jira.example.org",
  "sourceId": "PROJ-1234",
  "sourceObjectType": "jira:Issue",
  "capturedAt": "2026-08-13T00:00:00Z",
  "capturedBy": "did:rwp:example.org:source-adapter-001",
  "sourceIntegrity": "platform-versioned"
}

The following fields are required:

The combination of sourceSystem and sourceId MUST identify the source object unambiguously within the source system.

A source-provenance statement MAY additionally contain sourceUrl, sourceVersion, sourceRevision, sourceETag, sourceModifiedAt, exportPayload, exportPayloadHash, and exportFormat.

The sourceIntegrity value MUST be one of:

A source-integrity value describes guarantees available about the source object before or at capture. It MUST NOT be interpreted as a statement about the integrity of a subsequently created RWP Record.

17.4. Implementation roles {#conformance-roles}

RWP defines the following implementation roles:

Role Responsibility
producer Creates a new Record or a new snapshot, including its finalisation where applicable.
custodian Retains, manages, and makes Records or snapshots retrievable.
consumer Retrieves and validates Records created or managed by another implementation.
resolver Resolves did:rwp identifiers and returns the associated DID documents.
source-adapter Obtains, normalises, and exposes source-provenance information from a non-RWP source system.
attester Creates and finalises a ConformanceRecord concerning an implementation assessment.

A role describes a responsibility. It does not imply that an implementation fulfils requirements outside its claimed profiles, roles, or exercised capabilities.

17.5. Capability-bound requirements {#capability-bound-requirements}

Support for a SystemRecord capability MUST be required only where an implementation claims or exercises that capability.

Capability Information Record Case Record Assertion Record Source Integration
Create a Record DID MUST for a producer MUST for a producer MUST for a producer Not required
Bind a created Record to a SchemaRecord MUST for a producer MUST for a producer MUST for a producer Not required
Create and validate immutable snapshots MUST for a producer and consumer MUST for a producer and consumer MUST for a producer and consumer Not required
Retain and retrieve snapshots MUST for a custodian MUST for a custodian MUST for a custodian Not required
Maintain a version graph MUST for Records it creates or custodises MUST for CaseRecords it creates or custodises MUST for AssertionRecords it creates or custodises Not required
Create and validate Case links Not required MUST for a producer and consumer Not required Not required
Create and validate Assertions Not required Not required MUST for a producer and consumer Not required
Validate external hard-link targets Not required MUST when finalising or validating a CaseRecord MUST when finalising or validating an AssertionRecord Not required
Provide source provenance MAY MAY MAY MUST
Support SchemaRecord MUST where Records are created or validated against a schema MUST where CaseRecords are created or validated against a schema MUST where AssertionRecords are created or validated against a schema Not required
Support CaseRecord Not required MUST Not required Not required
Support AssertionRecord MUST only when creating, validating, or consuming AssertionRecords MUST only when creating, validating, or consuming AssertionRecords MUST Not required
Support MergeRecord MUST only when creating a merge snapshot MUST only when creating a merge snapshot MUST only when creating a merge snapshot Not required
Support DeletionRecord MUST only when executing payload deletion MUST only when executing payload deletion MUST only when executing payload deletion Not required
Support MigrationRecord MUST only when performing a documented migration MUST only when performing a documented migration MUST only when performing a documented migration Not required
Support ConformanceRecord MUST only for an attester MUST only for an attester MUST only for an attester MUST only for an attester

A resolver claiming the resolver role MUST satisfy the DID resolution requirements defined in DID Resolver Requirements and, where applicable, Resolver Requirements .

An implementation MUST NOT claim support for a profile or role unless it fulfils all requirements applicable to that claim.

17.6. ConformanceRecord {#conformance-record}

A ConformanceRecord is a SystemRecord that preserves an attestation concerning an identifiable implementation version.

A ConformanceRecord MUST satisfy all normal Record requirements, including DID, schema association, snapshot integrity, finalisation, and the applicable signature requirements.

The owner of a finalised ConformanceRecord MUST be the attester identified in its payload.

The SchemaRecord for a ConformanceRecord MUST require at least the following payload structure:

{
  "subject": {
    "implementationDid": "did:rwp:example.org:implementation-001",
    "productName": "Example Product",
    "productVersion": "1.2.3"
  },
  "rwpVersion": "0.0.3",
  "claims": [
    {
      "profiles": [
        "RWP Information Record Conformant"
      ],
      "roles": [
        "producer",
        "custodian",
        "consumer"
      ]
    }
  ],
  "assessment": {
    "method": "self-attested",
    "testSuite": "did:rwp:recordweb.org:test-suite:0.0.3",
    "tool": "Example Validator",
    "toolVersion": "1.0.0",
    "testedAt": "2026-08-13T00:00:00Z"
  },
  "attester": "did:rwp:example.org:implementation-001",
  "issuedAt": "2026-08-13T00:00:00Z",
  "expiresAt": null,
  "evidence": [
    {
      "type": "test-report",
      "url": "https://example.org/conformance/report.json",
      "hash": "sha256:..."
    }
  ],
  "supersedes": []
}

The ConformanceRecord payload MUST contain:

Every claim entry MUST contain at least one role. A claim entry containing a profile MUST identify only profiles defined by this specification or by a versioned extension specification.

The value of assessment.method MUST be one of:

The value certified is reserved for use by an external certification regime. Its use MUST NOT imply that RecordWeb operates, endorses, or recognises that regime.

Each evidence entry MUST identify its type and MUST include either a resolvable url, a cryptographic hash, or both.

A ConformanceRecord MAY include expiresAt.

A newer ConformanceRecord MAY supersede an earlier ConformanceRecord. Supersession MUST NOT alter, invalidate, or remove the earlier attestation. A superseding ConformanceRecord MUST identify every superseded ConformanceRecord by DID.

17.7. Conformance claims and evidence {#conformance-claims}

An implementation MAY publish a ConformanceRecord.

An implementation claiming a profile or role SHOULD make its current ConformanceRecord or equivalent signed conformance statement discoverable.

A verifier or procuring organisation MUST evaluate a conformance claim according to its own trust policy, including the identity of the attester, the assessment method, the evidence, the implementation version, and the applicable RWP version.

A verifier MUST NOT treat self-attestation, independent assessment, and certification as equivalent assurance levels.

18. Annex A: Normative JSON Schemas

18.1. A.1 Snapshot Metadata Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://recordweb.github.io/rwp/schemas/snapshot-metadata.json",
  "title": "RWP Snapshot Metadata",
  "type": "object",
  "required": ["did","snapshotHash","recordType","schemaVersion","state",
               "created","owner","parents","payloadHash","payloadFormat"],
  "properties": {
    "did":             { "type": "string", "pattern": "^did:rwp:[^:]+:[^:]+$" },
    "snapshotHash":    { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
    "recordType":      { "type": "string", "pattern": "^did:rwp:" },
    "schemaVersion":   { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
    "state":           { "type": "string", "enum": ["draft","finalized"] },
    "created":         { "type": "string", "format": "date-time" },
    "finalized":       { "type": "string", "format": "date-time" },
    "owner":           { "type": "string", "pattern": "^did:rwp:" },
    "parents":         { "type": "array", "items": { "type": "string",
                         "pattern": "^sha256:[0-9a-f]{64}$" } },
    "classification":  { "type": "string" },
    "retentionPolicy": { "type": "string", "pattern": "^did:rwp:" },
    "tags":            { "type": "array", "items": { "type": "string" } },
    "accessPolicy":    { "type": ["object","null"] },
    "payloadHash":     { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
    "payloadFormat":   { "type": "string" },
    "signature":       { "type": "string" },
    "deletionRegime":  { "type": "string",
                         "enum": ["payload-only","full-delete","exempt"] }
  }
}

18.2. A.2 CaseRecord Payload Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://recordweb.github.io/rwp/schemas/case-record.json",
  "title": "RWP CaseRecord Payload",
  "type": "object",
  "required": ["recordDid","caseType","title","trigger","merkleRoot"],
  "properties": {
    "recordDid":  { "type": "string", "pattern": "^did:rwp:" },
    "caseType":   { "type": "string", "pattern": "^did:rwp:" },
    "title":      { "type": "string" },
    "trigger":    { "$ref": "#/$defs/hardLink" },
    "context":    { "type": "array", "items": { "$ref": "#/$defs/link" } },
    "process":    { "type": "array", "items": { "$ref": "#/$defs/link" } },
    "decision":   { "oneOf": [{ "$ref": "#/$defs/hardLink" }, { "type": "null" }] },
    "result":     { "type": "array", "items": { "$ref": "#/$defs/hardLink" } },
    "merkleRoot": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" }
  },
  "$defs": {
    "hardLink": {
      "type": "object",
      "required": ["type","recordDid","snapshotHash"],
      "properties": {
        "type":         { "const": "hard" },
        "recordDid":    { "type": "string", "pattern": "^did:rwp:" },
        "snapshotHash": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
        "role":         { "type": "string" }
      }
    },
    "link": {
      "type": "object",
      "required": ["type","recordDid"],
      "properties": {
        "type":         { "type": "string", "enum": ["hard","working"] },
        "recordDid":    { "type": "string", "pattern": "^did:rwp:" },
        "snapshotHash": { "type": "string", "pattern": "^sha256:[0-9a-f]{64}$" },
        "role":         { "type": "string" }
      }
    }
  }
}

18.3. A.3 DeletionRecord Payload Schema

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://recordweb.github.io/rwp/schemas/deletion-record.json",
  "title": "RWP DeletionRecord Payload",
  "type": "object",
  "required": ["deletionRecord"],
  "properties": {
    "deletionRecord": {
      "type": "object",
      "required": ["targetDid","targetSnapshotHash","deletionRegime",
                   "legalBasis","requestedBy","approvedBy","deletedAt"],
      "properties": {
        "targetDid":          { "type": "string", "pattern": "^did:rwp:" },
        "targetSnapshotHash": { "type": "string",
                                "pattern": "^sha256:[0-9a-f]{64}$" },
        "deletionRegime":     { "type": "string",
                                "enum": ["payload-only","full-delete","exempt"] },
        "legalBasis":         { "type": "string" },
        "requestedBy":        { "type": "string", "pattern": "^did:rwp:" },
        "approvedBy":         { "type": "string", "pattern": "^did:rwp:" },
        "deletedAt":          { "type": "string", "format": "date-time" },
        "retainedFields":     { "type": "array",
                                "items": { "type": "string" } }
      }
    }
  }
}

19. Annex B: Reference Implementation Notes (non-normative)

This annex is non-normative. It provides guidance for implementers and does not impose additional requirements.

19.1. B.1 Technology Choices

The following technology choices are recommended for a first RWP implementation:

Component Recommended Notes
DID method did:web or did:key during pilot Full did:rwp method requires resolver deployment
Storage PostgreSQL + object store (S3-compatible) Metadata in relational DB; payloads in object store
Hashing Node.js crypto.createHash('sha256') Standard library; no external dependency
Canonical JSON canonicalize npm package Implements RFC 8785
Signatures @noble/ed25519 Audited Ed25519 implementation
Schema validation AJV (JSON Schema validator) Supports JSON Schema 2020-12

19.2. B.2 Pilot Scope Recommendation

For a first pilot, the following Level 1 subset is recommended:

  1. Implement DID generation and the DID Format and DID Document requirements

  2. Implement snapshot creation with the Minimum Metadata Set

  3. Implement Snapshot Hash Calculation

  4. Implement the draftfinalized state transition with Finalisation Requirements

  5. Implement Graph Structure without branch detection initially

This covers the critical path: a Record can be created, finalised, and its integrity verified. Cases and federation can be added in a subsequent iteration.

Conformance

Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with class="example", like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with class="note", like this:

Note, this is an informative note.

Index

Terms defined by this specification

References

Normative References

[PROVO]
PROV-O: The PROV Ontology. URL: https://www.w3.org/TR/prov-o/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC3987]
Internationalized Resource Identifiers (IRIs). 2005. URL: https://www.rfc-editor.org/rfc/rfc3987

Non-Normative References

[DID-CORE]
Decentralized Identifiers (DIDs) v1.0. URL: https://www.w3.org/TR/did-core/
[HYPERLEDGER]
Hyperledger Fabric. URL: https://www.hyperledger.org/projects/fabric
[ISO15489]
Information and documentation — Records management, Part 1: Concepts and principles. 2016. URL: https://www.iso.org/standard/62542.html
[JSON-SCHEMA]
JSON Schema: A Media Type for Describing JSON Documents. 2020. URL: https://json-schema.org/draft/2020-12/json-schema-core
[RFC8037]
CFRG Elliptic Curves for JOSE and COSE (Ed25519). 2017. URL: https://www.rfc-editor.org/rfc/rfc8037
[RFC8785]
JSON Canonicalization Scheme (JCS). 2020. URL: https://www.rfc-editor.org/rfc/rfc8785
[RICO]
Records in Contexts Ontology (RiC-O). 2024-09-04. URL: https://www.ica.org/standards/RiC/RiC-O_1-0-2.html
[RWC]
RecordWeb CG. RecordWeb Concept (RWC). CG-DRAFT. URL: https://recordweb.github.io/rwc/