Open Index Protocol 1.0
Specification edition: 1.0, 26 September 2026
Status: Proposed normative specification for the OIP / Alexandria / HYPATIA ecosystem
Scope: Records, publisher identity, templates, references, files, offline interchange, indexing contracts, private storage, migration, and an optional Bitcoin publication profile
This document defines a new protocol. It does not claim that the existing implementations conform, that its new DID method is registered or W3C-endorsed, or that interoperability or security audits have already occurred. Its normative rules are complete within the profiles defined here; implementation and independent review remain necessary before a production release.
Contents
- Purpose, boundaries, and conformance
- Data model and terminology
- Serialization, primitives, and hashes
- Signed objects
- Native OIP DIDs and publisher registration
- Record revisions and state
- DREFs, embedded parts, and selectors
- Templates and Schema.org
- Files, representations, and provenance
- Standard record templates
- Local storage and portable packages
- Private data, sharing, and Solid
- Indexing and retrieval contracts
- Public distribution and Bitcoin commitments
- Import and migration
- Extension boundaries
- Security and resource limits
- Conformance scenarios
- Worked examples
- Design rationale and source assessment
- References and standards status
1. Purpose, boundaries, and conformance
1.1 Purpose
OIP is a format and verification protocol for a typed, referenceable information graph. The same format supports public knowledge, private memory, shared collections, and entirely disconnected archives. A publisher can create an identity, define a template, create and revise records, attach files, exchange packages, and rebuild a search index without contacting a blockchain, a website, or a vocabulary server.
Bitcoin is an optional publication-order and commitment layer. Solid is an optional storage and authorization adapter. Neither changes the signed OIP record format. A public record prepared and used locally can subsequently be committed without changing its identity, revision, or file hashes.
The protocol distinguishes these assertions:
- A record has valid structure.
- A particular key signed particular bytes.
- That key was authorized under a specified identity state.
- The object has an independently verified public commitment.
- Its referenced bytes are available from a particular source.
- A statement in the record is supported or disputed by evidence.
None implies all the others. A valid signature does not establish factual truth; a commitment does not establish availability or rights to distribute a file.
The following diagram is informative:
flowchart LR
A[Publisher DID Document] --> B[Signed OIP records and files]
B --> C[Local durable store]
C --> D[Rebuildable graph and search indexes]
D --> E[Alexandria, HYPATIA, or private assistant]
C <-->|Authorized private sync| F[Solid adapter]
B -->|Explicit public submission| G[Public record distribution]
G --> H[Commitment batch]
H --> I[Bitcoin root commitment]
I -->|Separate publication evidence| D
1.2 Normative language
MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, and MAY have the meanings in RFC 2119 and RFC 8174. Tables of fields and processing rules are normative unless explicitly labeled informative. Examples using angle-bracket placeholders are illustrative and are not byte-level test vectors.
Unless stated otherwise, an object has exactly the listed members. Optional members are omitted when absent; they are not interchangeable with null. Extensions appear only in explicitly provided extension maps. A closed object with unexpected members is invalid. Application payload maps and DID Documents have their own extension rules.
Unless a section specifies another order, sorted strings use lexicographic UTF-8 byte order, and sorted structured items use lexicographic J(item) byte order. Set-like arrays reject duplicates after the semantic normalization expressly required for that field. These sorting rules do not reorder arbitrary payload arrays or JCS object properties.
1.3 Conformance profiles
| Profile | Required behavior |
|---|---|
| Core | Parse, hash, sign or verify as appropriate to role; native DID identity and record rules; DREF parsing; templates; immutable revision validation; no network dependency |
| Local Store | Core, durable records/files, import/export, integrity checks, reconstruction of manifests and indexes |
| Graph Index | Core, deterministic edge extraction, forward/reverse traversal, revision-aware citations, access-scoped query results; Section 13 |
| Public Publisher | Core, public disclosure checks, transport-independent signed submission; may outsource Bitcoin anchoring |
| Bitcoin Publisher / Verifier | Core plus the exact commitment, proof, ordering, and reorganization rules in Section 14 |
| Solid Adapter | Local Store semantics plus the byte-preserving mapping and authorization boundary in Section 12 |
| Encrypted Store | The authenticated encryption format in Section 12.5 |
| Migration Adapter | The evidence-preserving conversion contract in Section 15 plus an identified source-format profile |
A read-only verifier need not hold private keys. A writer MUST emit objects that a Core verifier can verify. Unsupported optional profiles MUST be reported explicitly. A claim of “OIP 1.0” MUST name the role and profiles implemented. A local implementation is fully conforming without Bitcoin, Solid, vectors, or an AI model.
1.4 Boundary with the ecosystem
This specification defines records that can describe commercial offers, policies, and service evidence. It does not define ALT issuance or supply, elections, subsidy schedules, slashing, rights adjudication, payment settlement, storage reward eligibility, or an inference marketplace. Those require separately versioned specifications. No unresolved economic rule is a prerequisite for Core validity.
Ranking, interpretation, model choice, interface design, retention policy, and resource admission policy remain application decisions. An application MUST NOT represent its policy rejection as cryptographic invalidity.
2. Data model and terminology
| Term | Meaning |
|---|---|
| Publisher | An identity authorized to issue a record; distinct from a payer, relay, source author, or rights holder |
| Identity state | An immutable, authorized operation containing a complete DID Document |
| Record | A continuing OIP information object with a stable DID |
| Revision | One immutable record body, identified by its body hash |
| Signed object | A body, its revision hash, and one or more authorization proofs |
| Object hash | Hash of the complete signed object, including its particular proof set |
| Node | The root semantic node of a record, or a named embedded part |
| DREF | A typed reference value containing a DID or DID URL, optionally with integrity constraints |
| File | An exact byte sequence, independently identified by a raw-byte hash |
| Locator | A possible route to retrieve bytes; not their identity |
| Template | An immutable, version-addressed validation contract using existing vocabulary where suitable |
| Local view | Verified objects available to an authorized local collection, with its explicit identity-branch selections |
| Public view | State obtained from qualifying public objects in Bitcoin order on a stated validated chain tip |
| Publication position | A Bitcoin block/transaction/output/batch-entry ordering coordinate |
| Projection | Rebuildable data such as a search index, RDF view, thumbnail, or cached resolution result |
A record DID identifies the OIP information object, not automatically the real-world person or place it describes. Two publishers can describe the same person in different records. Entity equivalence is a sourced claim; it is not inferred from matching names.
Files may be described inside a record without receiving separate record DIDs. An article can contain an ImageObject part and its file descriptor. Another article can reference that part directly.
3. Serialization, primitives, and hashes
3.1 JSON and canonical bytes
The logical representation is JSON. Canonical bytes are UTF-8 JSON Canonicalization Scheme bytes under RFC 8785. Implementations MUST use that algorithm, not a language-specific approximation based only on sorting keys. Input MUST reject duplicate object keys, invalid Unicode, non-finite numbers, and values outside its supported interoperable numeric domain before hashing. JSON-LD expansion and RDF canonicalization are not part of OIP hashing.
OIP additionally restricts integer-valued JSON numbers to [-9007199254740991,9007199254740991]. Exact larger integers and arbitrary-precision decimal quantities MUST use template-declared strings. Strings are not Unicode-normalized or trimmed during hashing. Dates and units are not silently converted. Array order is preserved; explicitly set-like protocol arrays have separate ordering requirements below. Canonical files contain no BOM or trailing newline.
An importer MAY accept differently formatted JSON, then compute the canonical form. Original imported bytes, if relevant as evidence, are retained separately. Unknown properties inside allowed payload/extension maps participate in hashes.
3.2 Primitive types
| Name | Exact representation |
|---|---|
Hash |
sha256: followed by exactly 64 lowercase hexadecimal digits |
Digest |
Exactly 32 decoded bytes; displayed as 64 lowercase hex digits when a field specifies hex |
B64u |
RFC 4648 URL-safe base64 without padding; noncanonical encodings rejected |
Nonce |
B64u of 32 cryptographically random bytes |
Time |
UTC RFC 3339 YYYY-MM-DDTHH:mm:ss.sssZ, valid Gregorian date, seconds 00–59 |
Date |
Valid YYYY-MM-DD; not converted to midnight |
Name |
ASCII [A-Za-z][A-Za-z0-9_-]{0,63}; case-sensitive |
IRI |
Absolute IRI or an allowed compact term from Section 8.1 |
DID |
DID Core syntax, without path, query, or fragment |
DIDURL |
DID Core URL syntax; method-specific processing remains necessary |
Count |
JSON integer from 0 through 9007199254740991 |
Visibility |
Exactly private, shared, or public |
Protocol times are issuer claims unless accompanied by independently verified evidence. Domain payloads can use dates, durations, and less precise times declared by their templates. Leap-second source timestamps MAY be retained as source strings; they MUST NOT be coerced silently into protocol Time values.
3.3 Hash domains
Let J(X) be canonical bytes, H be SHA-256, || mean byte concatenation, and 0x00 mean one zero byte. Domain labels below are literal ASCII, excluding quotation marks.
| Value | Computation |
|---|---|
| Identity DID suffix | hex(H("OIP1-ID-I" || 0x00 || J(identityGenesis))) |
| Record DID suffix | hex(H("OIP1-ID-R" || 0x00 || J(recordGenesis))) |
| Revision | "sha256:" + hex(H("OIP1-BODY" || 0x00 || J(body))) |
| Signed object hash | "sha256:" + hex(H("OIP1-OBJECT" || 0x00 || J(signedObject))) |
| File / original source bytes | "sha256:" + hex(H(bytes)) |
| Package manifest digest | "sha256:" + hex(H("OIP1-PACKAGE" || 0x00 || J(manifest))) |
The context determines the hash domain. A raw file hash MUST NOT be substituted for a revision or signed-object hash. Neither a revision nor an object hash appears inside its own hash input. A revision covers the complete body, including file hashes and provenance, but excludes proofs, storage receipts, index scores, and Bitcoin proofs.
4. Signed objects
4.1 Envelope
{
"body": { "oip": "1.0", "kind": "record", "...": "body fields" },
"revision": "sha256:<body digest>",
"proofs": [ { "statement": {}, "jws": "<protected>..<signature>" } ]
}
The three members are REQUIRED. proofs contains 1–32 proofs sorted by the UTF-8 bytes of J(statement) and then by ASCII jws; exact duplicates are prohibited. Changing the proof set changes the object hash but not the revision. This permits renewed authorization of an unchanged record after key rotation. Reauthorization cannot repair an invalid body or give a different publisher ownership of its DID.
Unsigned application drafts MAY exist outside this envelope. They MUST NOT be represented as verified OIP objects, distributed as public OIP publications, or confused with signed assertions. Signing locally is possible without a registration service.
4.2 Authorization statement
Every proof statement contains exactly:
| Member | Type | Rule |
|---|---|---|
oip |
string | 1.0 |
kind |
string | authorization |
revision |
Hash | Equal to envelope revision |
issuer |
DID | Native identity DID responsible for this proof |
identityState |
Hash or string | Identity operation revision; literal genesis only for identity creation |
verificationMethod |
DIDURL | Exact absolute method identifier under issuer |
purpose |
enum | assertion, update, or recovery |
A proof is a detached-payload compact JWS. Its payload is J(statement). Its protected header contains exactly alg, kid, and typ; kid equals verificationMethod, typ is oip-authorization+jws. The protected header itself MUST be JCS-canonical before base64url encoding. The signing input is the ordinary JWS protected-header encoding, a period, and the base64url encoding of the payload; the serialized middle component is empty. Unprotected headers, none, embedded private keys, remotely fetched header keys, and b64:false are forbidden. See RFC 7515.
4.3 Mandatory cryptographic suite
Core writers and verifiers MUST support alg: EdDSA with Ed25519 only, using RFC 8032 and RFC 8037. The public JWK is exactly {"kty":"OKP","crv":"Ed25519","x":"<32-byte B64u>"}. DID verification methods use type: JsonWebKey2020 and publicKeyJwk. Signatures are 64 bytes before encoding. A verifier MUST validate the key and signature encoding, including the Ed25519 scalar and point checks required by its specification. Ed448 is not selected implicitly by the same algorithm name. RFC 8032, RFC 8037
Implementations MAY support separately identified algorithm profiles, but an unsupported proof cannot satisfy a required threshold. Core-native identities MUST retain enough mandatory-suite keys to meet their policy thresholds. A new mandatory suite requires a protocol version change.
4.4 Verification outcomes
Verification reports separate fields, never one overloaded verified boolean:
structure:valid,invalid,unsupported;integrity:valid,invalid;signature:valid,invalid,unsupported,missingDependency;authorization:validAtState,currentInView,stale,conflict,missingDependency,invalid;template:valid,invalid,missingDependency,unsupported;publication:local,unanchored,provisional,confirmed,orphaned,inclusionOnly;availability:complete,partial,missing,notChecked.
The report identifies the identity state, collection/view, chain checkpoint if any, and validation profile versions. Missing identity history MUST NOT be treated as signature success. A network error MUST NOT turn rejection into acceptance. Original bytes may be quarantined for later processing.
5. Native OIP DIDs and publisher registration
5.1 Method decision and syntax
OIP defines the oip DID method because its required native identity must have no domain-name, blockchain, or online registry prerequisite, must support updates and recovery, and must survive movement between local storage, Solid, and public distribution without changing its identifier.
did:key supports useful offline verification but not mutable DID Documents. did:web and did:webvh are valuable external methods, but their naming/resolution models include web locations. They remain interoperable references; their rules are not redefined by OIP. did:key, did:web, did:webvh 1.0
The method-specific identifier is exactly one of:
did:oip:i:<64 lowercase hexadecimal digits> publisher identity
did:oip:r:<64 lowercase hexadecimal digits> record
The suffix is computed from the appropriate genesis descriptor. Neither timestamps nor blockchain addresses are encoded in the suffix. Creation is local and self-certifying: the descriptor authenticates the name, while signatures authenticate the operation. The descriptor is not itself a DID Document.
The method namespace and OIP URNs in this document are proposed protocol identifiers. Deployments MUST publish this method specification and MUST NOT claim existing universal resolver support or standards-body registration.
5.2 Identity genesis descriptor
{
"oip": "1.0",
"kind": "identityGenesis",
"nonce": "<32 random bytes, base64url>",
"update": {
"threshold": 1,
"keys": [{ "name": "manage-1", "jwk": { "kty": "OKP", "crv": "Ed25519", "x": "<public key>" } }]
},
"recovery": {
"threshold": 1,
"keys": [{ "name": "recover-1", "jwk": { "kty": "OKP", "crv": "Ed25519", "x": "<different public key>" } }]
}
}
Both policies are REQUIRED. Each has 1–16 keys sorted by name, unique names and public keys, and a threshold from 1 through its key count. The two sets MUST be disjoint. A key name is a Name. Every key uses the mandatory suite. The genesis descriptor never contains a private key, seed, mnemonic, or xprv.
The initial registration is an identity operation whose document is a complete DID Document, not a flattened collection of stringified DID fields or a set of separately published verification-method records.
5.3 Identity operation body
| Member | Type | Rule |
|---|---|---|
oip |
string | 1.0 |
kind |
string | identity |
id |
DID | Derived identity DID |
genesis |
object | Exact genesis descriptor; repeated unchanged in all operations |
operation |
enum | create, update, recover, deactivate |
sequence |
Count | 0 for create; predecessor sequence + 1 otherwise |
previous |
Hash or null | Null for create; exact predecessor identity revision otherwise |
createdAt |
Time | Issuer-claimed operation time |
visibility |
Visibility | Disclosure intent for this operation |
document |
object or null | Complete DID Document; null only for deactivate |
policy |
object | Exactly update and recovery policies of the shape in 5.2 |
extensions |
object, optional | IRI-keyed, non-authoritative annotations |
For create, policy equals genesis policies. The DID Document id equals body id; controller equals that same DID. Self-control here means control under the method's threshold policy, not an authorization to trust arbitrary self-asserted keys.
Native identity Documents MUST include verificationMethod, assertionMethod, and capabilityInvocation. Each policy key appears as an inline method with ID <identity DID>#<name>, controller equal to the identity DID, and its matching JWK. capabilityInvocation contains exactly the update-policy key IDs. Recovery key IDs appear in oip:recoveryMethod; oip in the DID context denotes urn:oip:term:. Their recovery authority comes from the method policy, not from a new DID Core verification relationship. There MUST be at least one separate operational Ed25519 key in assertionMethod; management/recovery keys MUST NOT be assertion or authentication keys. Authentication and key-agreement keys MAY additionally be present and MUST NOT use recovery key material.
Method IDs are absolute, unique, and remain bound to the same public key forever. A removed name MUST NOT later be reused for different key material. Relationships reference methods present in that Document. External controller delegation is not implicit. Additional DID Core properties and namespaced extensions MAY be present if they do not contradict these constraints. service and profile references are signed data; indexers MUST NOT rewrite them.
JSON Documents use the DID Core 1.1 representation rules. When @context is present it begins with https://www.w3.org/ns/did/v1.1 and includes the definitions needed for JsonWebKey2020, publicKeyJwk, and OIP terms. Offline implementations bundle the exact contexts they use; context retrieval is never needed to verify JCS signatures. An equivalent JSON-LD projection MUST NOT replace the signed JSON bytes. DID Core 1.1
5.4 Authorization of identity operations
| Operation | Required proof authority | Policy change allowed |
|---|---|---|
| create | Genesis update threshold, purpose update, state genesis |
None beyond genesis |
| update | Predecessor update threshold, purpose update, state predecessor revision |
Update keys/threshold and ordinary Document fields; recovery policy unchanged |
| recover | Predecessor recovery threshold, purpose recovery, state predecessor revision |
Replace both policies and operational Document; rotate compromised keys |
| deactivate | Predecessor recovery threshold, purpose recovery, state predecessor revision |
None; document null, policies equal predecessor |
Signers are counted by distinct authorized public key, not number of signatures. Proofs must all refer to this operation revision. Only proofs with the appropriate issuer, state, and purpose count; invalid extra proofs make the envelope invalid. Valid additional proofs that do not count toward the threshold MAY be retained.
An identity is terminal after deactivation: further operations are invalid in that branch. Historical Documents remain retrievable. Recovery extends the accepted current operation; it does not rewrite previously issued objects or retroactively make forged content true. If management keys are compromised, a controller can recover from the latest accepted head with independent recovery keys. If recovery keys or enough shares are lost, Core provides no administrative backdoor.
5.5 Branches, rotation, and freshness
An operation's hash and signature can be checked against its explicit predecessor even offline. If two authorized children of the same predecessor are known locally, the identity is conflicted. Automatic current-key authorization stops until an explicit collection policy selects a branch or a public view determines one. The selection and rejected alternatives MUST remain auditable. Self-declared timestamps, arrival order, and numerically larger derivation indexes MUST NOT silently resolve identity conflicts.
In the public view, operations are processed in Section 14 order. The first qualifying create establishes the public genesis operation; thereafter only an operation extending the current accepted head can change public identity state. A conflicting operation's inclusion proof remains valid, but it has no public state effect. A recovery MUST extend the current public head; it can be resubmitted against a newer head if a concurrent update wins first. Recovery is therefore not a promise of instantaneous takeover under continuous censorship or race conditions.
Removing an assertion key makes it unusable for new current-view authorizations. Historical proofs remain mathematically verifiable at their named state. They MUST NOT be labeled fresh simply because an old Document still contains the key. Public authorization is evaluated at publication position; an old locally signed object delayed until after rotation needs new authorization to qualify publicly. Local disconnected verification reports its known state and cannot assert absence of unseen revocations.
5.6 Key derivation, delegation, and profiles
Randomly generated keys and hardware-held keys are first-class. HD derivation is a wallet choice and is not necessary for conformance. A master private key MUST NOT be used for routine publishing, exported to a relay, or included in an OIP object. Key roles SHOULD use separate derivation branches when derived from one seed.
Published xpub derivation is OPTIONAL and is not a Core verification method. A future xpub profile MUST define its curve, public derivation, index algorithm, collision behavior, signature encoding, authorization scope, revocation, and test vectors. It MUST NOT combine hardened Ed25519 derivation with public child derivation or treat a payload-hash-derived index as a monotonically increasing clock. Core accommodates HD wallets by publishing ordinary authorized leaf public keys. No unimplemented xpub mode is advertised as usable Core behavior.
For Core delegation, the identity controller authorizes another device's or agent's ordinary public key in a Document's assertion or authentication relationship. This grants the corresponding identity-wide authority. Fine-grained capabilities require a separate profile; applications MUST NOT infer restrictions that the verifier cannot enforce. Distinct publisher identities SHOULD be used when identity-wide authority would be too broad.
5.7 DID resolution and native record DID Documents
Bare native identity DIDs resolve to their selected Document. Bare record DIDs resolve to a derived Document identifying the record and its publisher as controller, with a service:
{
"id": "<record DID>#record",
"type": "OipRecordService",
"serviceEndpoint": "<record DID>/record"
}
The complete derived Document has id, controller, and service; JSON-LD representations additionally declare the DID and OIP terms. It asserts no independent signing keys. Its metadata identifies the record revision/view used. The /record method path dereferences the OIP record; it does not recursively resolve this service back to itself.
versionId selects an exact identity operation revision for an identity DID, or record revision for a record DID. Values are percent-encoded Hash strings. Native identity URLs have no method path; their optional fragment selects an identified DID Document resource. Native record paths are limited to those in Section 7.2. For all native URLs, the only supported query parameter is versionId, occurring at most once. versionTime, service, and other query selectors are unsupported in this profile; direct method paths provide record/file access. Issuer timestamps do not establish an unambiguous version order. Unsupported selectors return an explicit error. A bare DID always denotes the subject; a /record URL denotes its OIP representation.
Resolvers return didResolutionMetadata, didDocument, and didDocumentMetadata; metadata includes the selected versionId, deactivated, oip:view, identity branch/conflict status, and any chain checkpoint. created/updated are labeled issuer-claimed times unless backed by independent evidence. OIP does not infer trustworthy wall-clock signature time from those fields. Native errors include invalidDid, notFound, notAuthorized, versionNotFound, conflict, unsupported, and missingDependency; an access-denied service MAY collapse private existence into notFound. The adapter maps these into its selected DID Resolution API representation. DID Resolution
Resolution first searches the authorized local registry of signed objects. Network-enabled resolvers MAY consult configured mirrors, Pods, peers, or gateways. Every result must still validate from genesis. A routing hint is not a trust anchor. Offline mode MUST NOT perform network discovery, DNS, context retrieval, or background fallback.
6. Record revisions and state
6.1 Record genesis descriptor
A record genesis descriptor contains exactly oip: "1.0", kind: "recordGenesis", nonce: Nonce, and publisher: DID. The publisher is a native OIP identity DID. The descriptor derives the record DID and is repeated unchanged in every revision. The publisher's operational keys can rotate without changing the record DID.
Core requires native publisher identities so every verifier can reproduce authorization offline and in Bitcoin order. Other DID methods are usable as subjects and DREF targets. A non-native publisher-signing profile requires its own historical-authorization and public-order rules; merely placing an external DID in publisher does not make a Core record valid. An existing external identity can establish a native OIP publishing identity and issue a separately verified binding claim.
The record controller is its publisher for its entire lifetime. Ownership transfer to another identity is outside Core; publication of a successor record with an explicit relationship is supported. This does not prevent another publisher from describing or disputing the same real-world subject.
A publisher MUST NOT repurpose a continuing record DID to describe an unrelated subject or work. Corrections, additional detail, changed assertions, and template evolution are permitted; unrelated objects receive new genesis descriptors. This is a semantic publishing obligation, not something cryptography can fully adjudicate.
6.2 Record body
| Member | Required | Type and rule |
|---|---|---|
oip |
yes | 1.0 |
kind |
yes | record |
id |
yes | Derived record DID |
genesis |
yes | Record genesis descriptor |
sequence |
yes | 0 for a root revision; otherwise 1 + maximum parent sequence |
parents |
yes | Sorted unique array of 0–64 revision hashes, all for this record |
issuedAt |
yes | Time claimed by publisher for this revision |
visibility |
yes | Visibility |
status |
yes | active or retracted |
node |
yes | Root semantic node, Section 6.3 |
parts |
yes | Map from Name to semantic node; may be empty |
files |
yes | Map from Name to file descriptor; may be empty |
provenance |
yes | Provenance object, Section 9.3 |
extensions |
no | IRI-keyed JSON annotation map |
The revision is a full snapshot, not a patch. Null property values are allowed only when the node's template permits them. Empty parts, files, parents, and provenance sources are explicitly represented. Every parent MUST be integrity-verified and authorized for the same genesis. Duplicate parent hashes and parent cycles are invalid. A missing parent yields missingDependency, not an invented root.
At least one envelope proof MUST have issuer equal to genesis publisher, purpose assertion, and a verification method in assertionMethod at its named identity state. Core record publishing requires one such key; identity management thresholds do not multiply routine record signatures. An application requiring multiple approving publishers uses explicit attestation records or a separate profile.
An identity operation is not wrapped inside a record to acquire validity. This avoids circular bootstrap requirements between identity registration, publisher registration templates, and signatures.
6.3 Semantic nodes
A node contains exactly:
| Member | Type | Meaning |
|---|---|---|
types |
nonempty sorted unique array of IRIs | Semantic types, normally Schema.org types |
template |
TemplateRef | Immutable validation contract |
data |
object | Predicate/value map, with vocabulary terms as keys |
A root node's citation address is <record DID>/record. A named part's address is <record DID>/record#<part name>. Parts do not have their own publisher, revision chain, signature, or blockchain transaction. They inherit their containing record's authorization, revision, visibility, and retention context. Changing any part changes the containing revision.
Payload values can be JSON primitives, arrays, ordinary value objects, DREFs, or FileRefs. Ordinary object keys at any nesting depth in data are vocabulary terms, except explicitly prescribed structured values in this specification (DREF, FileRef, selector, policy entry, migration structures, and template definitions). Custom templates MAY prescribe further opaque structured values; their internal member names need not be predicates. An array's order is meaningful unless its template explicitly declares set semantics; even then its serialized order remains signed. Graph extraction still detects explicit DREF values inside prescribed/custom structures unless a field is expressly opaque schema/code data.
6.4 Revision graph and current state
Each record has a directed acyclic revision graph. Multiple root revisions using one genesis descriptor are permitted as an explicit fork, not merged silently. A head is a valid revision with no valid descendant in the selected view. Multiple signature envelopes for one revision do not create multiple heads.
With one head, current-record lookup returns that revision. With several heads, it returns conflict and the head list. A caller MAY request a specific head or an explicitly named application selection policy, but the response MUST disclose the conflict. Timestamps and ingestion order do not discard alternatives.
A publisher resolves a fork by issuing a full revision listing the intended heads in parents. The result is a new head. A revision omitting an unrelated head does not resolve that head. Applications SHOULD merge all known heads; applications with more than 64 heads can create intermediate merges. A malicious publisher can keep creating conflicts in its own record, but cannot change another publisher's record.
In a public view, only publicly qualified revisions and their publicly qualified parents participate. An unanchored edit MUST NOT replace a public head without being labeled as a local/unanchored view. Public ordering determines which objects were published first; it does not turn conflicting content into canonical truth.
6.5 Retraction and deletion
A retraction is a signed revision with status: retracted, one or more relevant heads as parents, and a provenance.reason string. It MUST contain the same root node, parts, and file descriptors as at least one parent; it cannot introduce new substantive content while retracting it. No active revision may descend from a retracted revision. Further retracted merge revisions MAY include retracted and active heads to consolidate newly discovered forks, preserving the same payload constraint. If other active heads remain, the record is conflicted, not globally retracted. This permits a later complete retraction without allowing a retracted branch to be silently revived.
When the sole head is retracted, current resolution reports deactivation and does not return its content by default. Historical revision retrieval remains possible subject to access and retention policy. A record's DID Document metadata reports deactivated: true in that view. A new successor record can link to the retracted object.
Local erasure is a storage action, not a revision. A private store MUST support deleting local originals, derived indexes, previews, and keys according to user policy. A synchronization suppression marker MAY prevent accidental re-import; it is private local metadata. No protocol can promise deletion from every previously authorized recipient or a public network. Provider refusal is represented by a separate Tombstone, not a forged publisher retraction.
7. DREFs, embedded parts, and selectors
7.1 DREF value
{
"dref": "did:oip:r:<digest>/record?versionId=sha256%3A<revision>#hero",
"integrity": "sha256:<optional full record revision>",
"mediaType": "application/vnd.oip.record+json"
}
dref is REQUIRED; integrity and mediaType are optional. No other members are allowed. An absolute value is a DID or DIDURL. Within a record, a relative DREF is only #<Name>; it selects a part of the same containing revision, never whatever happens to be current later. Empty references, bare database IDs, guessed DID prefixes, and arbitrary relative filesystem paths are invalid.
For native /record references, integrity, if supplied, is the selected whole-record revision, not a hash of the part and not an envelope hash. It MUST agree with versionId when both exist. For native /files/<Name>, integrity is the file's raw-byte hash and MUST agree with the selected descriptor; versionId still selects the containing record revision. On native bare-DID/DID-Document references, integrity is forbidden; use versionId to select an authenticated operation/revision instead. For an external DID resource, integrity is the raw-byte hash of its dereferenced primary resource, before fragment selection. Its adapter MUST identify that primary representation and media type; otherwise integrity-constrained dereferencing is unsupported. A fragment reference without verifiable containing bytes MUST NOT be presented as independently verified content.
mediaType constrains the primary representation. Native /record returns canonical record-body JSON as application/vnd.oip.record+json, whose fragment contract is defined in 7.6. DREF metadata such as confidence or a relation's time belongs to an Assertion or other containing node, not to extra DREF members.
7.2 Identity, version, part, and file are separate selectors
| Address | Result |
|---|---|
did:oip:i:<h> |
Publisher DID Document |
did:oip:i:<h>#sign-1 |
Verification method or other identified resource in that Document |
did:oip:r:<h> |
Derived record DID Document |
did:oip:r:<h>/record |
Current record body in the requested view |
did:oip:r:<h>/record?versionId=sha256%3A<v> |
Exact record body |
did:oip:r:<h>/record#hero |
Named part in the current record body |
did:oip:r:<h>/record?versionId=sha256%3A<v>#hero |
Named part in an exact record revision |
did:oip:r:<h>/files/hero-file?versionId=sha256%3A<v> |
Exact bytes identified by file descriptor hero-file in that revision |
These are OIP method resource paths; they are not assertions that every DID method recognizes /record or /files. DID Core fragments can refer into DID Documents or dereferenced resources, but the resource's semantics must be specified. OIP's fragment processing for /record is the parts lookup above, applied by an OIP-aware DID URL dereferencer to the OIP record media type. It does not assign fragment semantics to arbitrary application/json on the Web. DID URL syntax
For native record paths, the only supported query member is versionId. Duplicated parameters, unknown parameters, invalid percent encoding, extra path segments, and a fragment on /files/<Name> are invalid in Core. Selectors for portions of media are modeled as named parts below. Parameter values are percent-decoded once and validated; + is not interpreted as space. Native generated links MUST use the canonical spelling shown, including %3A in hashes. An accepted equivalent spelling is normalized for indexing while the originally signed string is preserved.
A missing named part returns partNotFound; it MUST NOT fall back to the whole record or another revision. A name MUST NOT be reassigned to an unrelated component in a descendant. Publishers SHOULD use meaningful permanent names or random Name-safe labels. Positional array indexes are not stable part identities.
7.3 Embedded-image reuse
Article A includes parts.hero describing an image and a file descriptor for the image bytes. Article B sets its schema:image to a DREF of Article A's /record?...#hero. No separate image record or publication transaction is required. To retrieve the image, the client resolves the part, interprets its schema:contentUrl FileRef, then retrieves verified bytes from the containing revision's file descriptor.
For durable reuse and evidence, Article B SHOULD pin Article A's revision. A floating reference deliberately follows later revisions; the authoring interface SHOULD explain that choice. A public part cannot be independently made private while its containing public revision remains available. Content needing different permissions must be separated before disclosure.
7.4 Passages, regions, pages, and time ranges
Core provides the built-in Selector template. A named Selector part contains a source DREF or FileRef and exactly one of:
| Selector | Required data and interpretation |
|---|---|
text |
start, end: Count, zero-based Unicode scalar offsets, half-open [start,end) into a pinned UTF-8 text representation; optional exact must equal selected text |
pages |
start, end: positive integers, one-based inclusive PDF page range |
time |
startMs, endMs: Count, half-open millisecond interval in the pinned media representation |
region |
x, y, width, height: Count, positive width/height, pixels in the decoded image after declared EXIF orientation is applied |
The selector object is exactly { "type": <enum>, <required members>, <optional exact> }. Bounds must be valid for available source data; missing bytes yield pending bounds validation. The source MUST be integrity-pinned: a FileRef binds a file hash, or a DREF binds an exact native revision/external integrity hash. Extracted text requires its own file hash and extraction provenance; offsets never refer vaguely to “the PDF text.” Selector failure is reported, not heuristically relocated. Quote reanchoring and alternative selector standards MAY be offered as derived application features with separately recorded results.
This profile supports the same broad uses as Web Annotation and Media Fragments while defining exact OIP storage and indexing behavior. Adapters MAY project to those standards where their semantics agree. Web Annotation, Media Fragments
7.5 External DIDs and ordinary locators
DREF parsers MUST accept syntactically valid external DID methods without requiring them to be installed. Resolvers report unsupportedMethod, offlineUnavailable, missingDependency, or a verified result. For did:web, follow the method's mapping to a DID Document; do not mechanically convert an article URL into a did:web that purports to identify the article. Existing methods for blockchain accounts, decentralized networks, or content resources may be used with their precise method definitions and adapter versions.
A Bitcoin address identifies an account/address under an appropriate method, not the OIP record committed by a transaction. A transaction ID, Arweave identifier, IPFS CID, magnet URI, HTTPS URL, or local file path is not automatically a DID. Ordinary HTTP/IPFS/Arweave/BitTorrent addresses belong in locator fields or URI-valued Schema.org properties. An external information resource needing a native DREF can be described by an OIP record. Legacy did:arweave strings are preserved as legacy identifiers unless a specific method profile establishes their semantics.
External reference support never implies external controller authority, identity equivalence, safe fetching, or availability. Local caches MAY resolve verified external resources offline, with their captured version and freshness limits disclosed.
7.6 OIP record representation and media type
application/vnd.oip.record+json is the proposed media type for the record body in Section 6.2. This document defines its use between OIP implementations; it does not claim that an IANA registration already exists. The registration specification is: type application, subtype vnd.oip.record+json, no required or optional parameters, UTF-8 JSON encoding, security considerations as Section 17, no magic number, and suggested extension .oip.json. The +json suffix permits generic JSON processing but does not make a generic JSON client an OIP verifier.
An absent fragment selects the full body. A nonempty fragment MUST match Name exactly and selects parts[fragment]; other fragment forms, percent-encoded alternative spellings, and an empty # are invalid. The selected node is returned with the containing DID/revision in dereferencing metadata; it does not acquire an independent signature. Fragment behavior is identical for pretty-printed and canonical serializations of the same body. Alternate record representations must preserve this named-part behavior to claim compatibility.
Signed envelopes and batch manifests use application/json; their API routes/content kind identify them. DID Documents use application/did under DID Core 1.1. A transport returning a native record body as generic JSON must additionally identify the OIP record profile before fragment processing; clients MUST NOT guess it for unrelated JSON. Registration of the new media type is a release-process task, not a requirement for local creation or hashing.
8. Templates and Schema.org
8.1 Vocabulary
Core recognizes the following fixed compact prefixes in node types and predicate keys:
| Prefix | Expansion |
|---|---|
schema: |
https://schema.org/ |
oip: |
urn:oip:term: |
prov: |
http://www.w3.org/ns/prov# |
oa: |
http://www.w3.org/ns/oa# |
rdf: |
http://www.w3.org/1999/02/22-rdf-syntax-ns# |
xsd: |
http://www.w3.org/2001/XMLSchema# |
Other terms MUST be absolute IRIs. Unknown compact prefixes are invalid. A full IRI and its permitted compact equivalent have the same indexed semantic meaning but different signed bytes. A payload object MUST NOT contain two keys that expand to the same predicate. Types are sorted and deduplicated by expanded IRI; producers emit permitted compact forms where available. Templates cannot redefine these prefixes. No global @context or network request is needed to interpret them.
When Schema.org supplies the intended type/property, templates MUST use it rather than invent an equivalent OIP name. Extensions remain allowed where semantics differ or are absent. schema:author must not be used to mean the agent that indexed a file; schema:sameAs must not be used to mean a weak possible match. The vocabulary provides meaning; OIP templates supply the stricter constraints needed for validation. Schema.org data model
8.2 Template references and bootstrap
A TemplateRef is either:
- A built-in identifier
urn:oip:template:1.0:<Name>defined in Section 10; or - A DREF to the root of an OIP Template record, using
/record?versionId=<Hash>and no fragment.
Built-in identifiers are immutable contracts defined by this edition, usable offline without prior publication. Their names are case-sensitive. They are not mutable pointers to the latest hosted schema. Custom templates are ordinary signed Template records. A template can be authored and used privately/offline and later published publicly, subject to its disclosure policy.
A public record's custom templates and their transitive schema dependencies MUST themselves be publicly available qualifying revisions at earlier public positions before the record can become template-qualified. This is independent of whether the referenced subject records or media have been fetched. A locally validated record may use local templates before anchoring.
8.3 Template definition
The Template node has type oip:Template, uses built-in Template, and its data contains:
| Predicate | Required | Meaning |
|---|---|---|
schema:name |
yes | Human-readable string; not a unique global key |
schema:description |
yes | Meaning and intended usage |
oip:definition |
yes | Definition object below |
schema:version |
no | Human-readable release string; revision hash remains authoritative |
schema:license |
no | Absolute license URI |
The definition object contains exactly:
schemaVersion:2020-12;schemaOrgRelease: string identifying a pinned Schema.org release/snapshot, ornoneif no Schema.org terms occur;requiredTypes: sorted unique expanded IRIs;dataSchema: JSON Schema 2020-12 applying to the node'sdata;dependencies: array of{ "uri": <absolute URI>, "hash": <raw file Hash> }, sorted by URI, unique;terms: map of custom expanded IRIs to{ "kind": "type" | "property", "description": <string> };indexHints: optional object withtext,names,time, andgeo, each an array of JSON Pointers relative todata.
JSON Schema handles shape validation; semantic requirements in this specification are additional checks. $ref and $dynamicRef outside the root schema MUST resolve only through the exact dependency table. All transitive dependencies must be listed, locally available, and hash-verified. Live fetching during validation is prohibited. A schema MUST NOT execute code, access a filesystem, or make network calls. format is treated as an annotation unless this specification independently requires its syntax. JSON Schema 2020-12
Custom property definitions MUST describe their meaning; descriptions do not override existing vocabulary semantics. Template authors SHOULD document mappings to established vocabularies where possible. A template may specialize several types, combine reusable schema constraints, or allow additional namespaced properties. A new template revision MUST receive a new pin; indexers MUST NOT reinterpret old records using the newest similarly named template.
8.4 Validation and indexing independence
Every node MUST pass its pinned template and global typed-value rules. A node with an unavailable custom template remains stored as missingDependency; an index MAY expose its text as explicitly unvalidated material to authorized users. It MUST NOT assert full template validity. Unsupported JSON Schema vocabularies likewise return unsupported, not success.
Index hints are suggestions, not authority to read files, disclose data, or skip mandatory edges. Graph extraction is defined by the DREF object shape, even for unknown templates. Template names need no central reservation. Two templates named “Article” with different DIDs are different contracts.
9. Files, representations, and provenance
9.1 File descriptors and FileRefs
A FileRef is exactly { "file": "<Name>" }, identifying a descriptor in the same containing record revision. It works equally from the root or a part. It is not a local path.
Each files member contains:
| Member | Required | Type and meaning |
|---|---|---|
hash |
yes | Raw-byte Hash |
size |
yes | Count of bytes |
mediaType |
yes | Lowercase MIME type; parameters if necessary have explicit values |
locators |
yes | Array, possibly empty, of absolute transport URI strings |
name |
no | Display filename, never a path to execute or write |
role |
no | IRI identifying original, extracted text, thumbnail, transcript, etc. |
derivedFrom |
no | Array of FileRefs or pinned DREFs |
processing |
no | Provenance object for this representation |
Every FileRef MUST name an existing descriptor. Local storage finds bytes by hash, never by a signed absolute filesystem path. file: URLs, embedded access tokens, credentials, and private machine paths MUST NOT occur in public locators. Public locators are advisory: returned bytes MUST match size and hash. Matching content at a new locator is the same file; different encodings/transcodes are different files with derivedFrom relationships.
Local or provider locator catalogs MAY add retrieval locations without revising the record. Such catalogs are routing hints outside the signed semantic record and require byte verification. A signed change to a descriptor or its original locator list requires a new record revision. IPFS CIDs and BitTorrent piece hashes are transport checks; the descriptor's raw-byte hash checks the extracted file itself. An IPFS directory or torrent collection needs an unambiguous member path in its transport adapter.
/files/<Name> returns only hash-verified bytes from the selected record revision. For large streaming responses, the client MAY provide unverified streaming with an explicit status, but MUST NOT label the complete asset verified until its full hash matches. A chunk-verification extension can improve this without altering file identity.
9.2 Local availability and retention
A local-only file has an empty locator array and remains retrievable from the local content-addressed store. A disconnected graph may contain metadata for missing files; this is valid but not a complete offline collection. Applications MUST distinguish complete packages from metadata-only and partial packages.
Hashes prove byte identity, not lawful ownership or factual accuracy. Deduplication SHOULD stay within a permission domain. Public APIs MUST NOT expose whether another user's private store already contains a requested hash. Local artifact paths, previews, OCR text, transcripts, and embeddings inherit the source's access restrictions.
9.3 Provenance object
A provenance object contains exactly the following members when present:
| Member | Required | Meaning |
|---|---|---|
sources |
yes | Array of DREFs and/or FileRefs; evidence inputs, normally pinned |
activity |
no | IRI naming capture, extraction, transcription, import, authored content, observation, or analysis |
agent |
no | DREF for person, organization, software, or model that performed activity |
method |
no | String or absolute URI naming the method |
software |
no | Object exactly { "name": string, "version": string } |
observedAt |
no | Time claimed for observation |
generatedAt |
no | Time claimed for generation |
confidence |
no | Number from 0 to 1; issuer's estimate, not protocol trust |
reason |
no | String; required on retraction |
extensions |
no | IRI-keyed annotations |
Record issuedAt, source publication time, capture time, event/valid time, local ingestion time, and Bitcoin inclusion position are distinct. Local ingestion times and search scores are index metadata, not silently inserted into signed bodies.
Source and Web Capture records preserve received material. AI summaries, extracted assertions, entity matches, and change analyses SHOULD be separate Analysis/Assertion records linking exact source revisions and associated source files. Altering a source to incorporate a model's interpretation loses this distinction and MUST NOT be represented as an unchanged source.
10. Standard record templates
10.1 Common conventions
Every built-in below has ID urn:oip:template:1.0:<name>. A table row defines minimum node types and REQUIRED data fields. Optional fields are listed where they have OIP-specific behavior. Other vocabulary-keyed properties are permitted if they satisfy global JSON/typed-value rules; they do not change the meaning of the required fields. Extra OIP predicates not defined here are preserved as unknown annotations, not new executable protocol rules.
Type notation: S = nonempty string; N = finite number; B = boolean; D = DREF; F = FileRef; U = absolute URI string; T = protocol Time; L(X) = array of X; Q = { "schema:value": <decimal string>, "schema:unitCode": <IRI or unit-code string> }. Decimal strings follow -?(0|[1-9][0-9]*)(\.[0-9]+)?; no exponent or leading plus. Array fields allow empty arrays unless + is indicated. Full IRI predicate spellings equivalent to the compact spelling are accepted. Required semantic fields may not be null.
These built-ins provide a usable initial corpus without claiming to exhaust Schema.org. Specialized domains publish custom templates. A requirement to include a Schema.org type does not prohibit more specific compatible types.
10.2 General and knowledge templates
| Name | Required types | Required data | Selected optional data / rules |
|---|---|---|---|
Generic |
Any nonempty types | None | General vocabulary-shaped node; custom template preferred for reusable specialized validation |
Entity |
At least one Schema.org type | schema:name: S |
schema:alternateName: L(S), schema:sameAs: L(D or U); no automatic identity merging |
Person |
schema:Person |
schema:name: S |
schema:alternateName, schema:email, schema:telephone, schema:birthDate: Date; private by default in personal memory |
Organization |
schema:Organization |
schema:name: S |
schema:url: U, schema:member: L(D) |
Place |
schema:Place |
schema:name: S |
schema:geo value object with schema:latitude: N in [-90,90], schema:longitude: N in [-180,180]; WGS84 |
Episode |
schema:Event |
schema:name: S, schema:startDate: T or Date |
schema:endDate, schema:location: D, schema:attendee: L(D); end not earlier than start when comparable |
Assertion |
schema:Claim, oip:Assertion |
oip:subject: D, oip:predicate: IRI string, oip:object: JSON value, schema:text: S |
oip:validFrom/validUntil: T, oip:assertionMode: explicit/inferred/extracted, oip:confidence: N in [0,1]; object DREF is explicit, literal string is not a link |
Observation |
schema:Observation |
schema:observationAbout: D, schema:measuredProperty: IRI string, schema:value: Q or non-null JSON primitive, schema:observationDate: T, oip:observer: D, oip:source: D or U, schema:measurementMethod: S |
schema:unitCode: S, oip:response: F, oip:freshUntil: T, schema:location: D; freshness is a source/application claim |
Source |
schema:CreativeWork or a Schema.org subtype of it |
schema:name: S, oip:content: F or D |
schema:author: D or S, schema:url: U, schema:datePublished: T or Date, schema:license: U |
Analysis |
schema:CreativeWork, oip:Analysis |
schema:name: S, oip:inputs: L+(D), oip:method: S, oip:generatedAt: T, oip:agent: D, schema:text: S or F |
AI analysis additionally requires oip:model: D pinned to model revision and oip:modelVersion: S; oip:confidence in [0,1] |
Artifact |
schema:MediaObject or a Schema.org subtype |
schema:name: S, schema:contentUrl: F |
Captures file identity through the FileRef; encoding metadata MUST agree with descriptor |
Selector |
oip:Selector |
oip:source: F or D, oip:selector: selector object |
Section 7.4 constraints |
EvidenceTrail |
schema:CreativeWork, oip:EvidenceTrail |
schema:name: S, oip:evidence: L+(D), schema:text: S |
All evidence references pinned; ordered array represents the trail |
Schema.org subtype validation for built-ins uses Schema.org 30.1, the frozen vocabulary release published 16 September 2026. Mandatory simple types listed explicitly here MUST be recognized without remote lookup. Implementations bundle this vocabulary; a custom template can pin a different snapshot. Built-in Source and Artifact also accept explicit base types alongside a newer subtype, allowing old readers to validate the base without guessing a new hierarchy. Observation uses Schema.org's observationAbout, measuredProperty, value, observationDate, and measurementMethod terms rather than OIP synonyms. Observation vocabulary
Assertion predicates and objects are separate from truth status. oip:contradicts, oip:supports, oip:supersedes, and oip:possibleSameEntity have DREF-valued meanings of the corresponding named relationship. possibleSameEntity MUST NOT collapse entity identities. Assertions from different publishers coexist.
10.3 Sources, media, and captures
| Name | Required types | Required data | Additional rules |
|---|---|---|---|
Article |
schema:Article |
schema:headline: S, schema:articleBody: S or F |
schema:image: D or L(D), schema:author: D or S, schema:citation: L(D or U) optional |
Image |
schema:ImageObject |
schema:contentUrl: F |
schema:caption: S, schema:width/height: Count, schema:license: U optional |
Audio |
schema:AudioObject |
schema:contentUrl: F |
schema:transcript: S or F optional |
Video |
schema:VideoObject |
schema:contentUrl: F |
schema:transcript: S or F, schema:thumbnail: D optional |
MediaObservation |
schema:Observation, oip:MediaObservation |
oip:media: F or D, oip:observer: D, schema:observationDate: T |
Optional oip:credentials: L(F or D), oip:credentialFormat: S, schema:location: D; credential validation reported independently |
WebSource |
schema:WebPage, oip:WebSource |
schema:url: U, schema:name: S |
A continuing source, not an immutable capture; URL equality alone is not entity identity |
WebCapture |
schema:CreativeWork, oip:WebCapture |
oip:source: D, oip:observedUrl: U, oip:capturedAt: T, oip:captureAgent: D, oip:captureVersion: S, oip:representations: L+(F) |
oip:canonicalUrl: U, oip:redirects: L(U), oip:outboundLinks: L(U or D), stated author/date optional |
WebChangeAnalysis |
schema:CreativeWork, oip:Analysis, oip:WebChangeAnalysis |
All Analysis fields plus oip:before: D, oip:after: D |
Before/after pinned captures; comparison method/version stated; does not modify captures |
A capture representation can be raw response bytes, WARC, HTML, screenshot, extracted text, or another explicitly typed file. “Normalized text” is not a universal protocol equivalence rule: a normalization algorithm and version MUST be recorded in the representation's processing provenance. Equal raw hashes establish byte equality; equal normalized hashes establish equality only under the same identified procedure. HTTP headers containing secrets, authenticated page context, private notes, and browser session information MUST be excluded from public exports by default.
C2PA or other media credentials are retained as exact evidence files or references. A valid credential is evidence of the credential's assertions, not a protocol declaration that a depicted event occurred or that its coordinates are correct. Public rights metadata does not itself authorize reproduction.
10.4 Models and system records
| Name | Required types | Required data / semantics |
|---|---|---|
Model |
schema:SoftwareApplication, oip:Model |
schema:name: S, schema:softwareVersion: S, oip:artifacts: L+(F or D), oip:modalities: L+(S), schema:license: U; optional exact decimal parameter count, quantization, context limit, runtime and hardware constraints under OIP predicates |
ModelPerformanceObservation |
schema:Observation, oip:ModelPerformanceObservation |
oip:model: D pinned, oip:hardware: D pinned, oip:runtime: S, oip:runtimeVersion: S, oip:benchmark: D pinned, oip:metrics: object of IRI to Q, oip:observer: D, schema:observationDate: T |
Template |
oip:Template |
Section 8.3 |
PolicyList |
schema:CreativeWork, oip:PolicyList |
schema:name: S, schema:version: S, oip:entries: L(policy entry); entry exactly { "target": D or Hash, "reason": IRI, "action": "refuse" or "warn" }; operator chooses whether to adopt it |
Tombstone |
oip:Tombstone |
oip:target: D, oip:policy: D pinned, oip:reason: IRI, oip:provider: D, oip:effectiveAt: T; author must be provider identity to claim that provider's action; no target bytes required |
MigrationReceipt |
oip:MigrationReceipt |
Section 15 |
PrivatePublicBridge |
oip:PrivatePublicBridge |
oip:private: D, oip:public: D, oip:relationship: S; body visibility MUST be private or shared, never public |
OIP properties for model recommendations, rewards, or provider quality are descriptive claims. They do not execute models, allocate tokens, or establish economic eligibility.
11. Local storage and portable packages
11.1 Durable versus derived state
A Local Store MUST retain canonical signed objects and required file bytes independently of its search database. It MUST be able to rebuild record heads, identity histories, template catalogs, file associations, forward/reverse edges, and text indexes from those durable objects plus explicitly retained local policy. Deleting a search database must not delete durable memory.
A conforming implementation can use directories, an object store, or a transactional database. The following portable directory layout is REQUIRED for directory export, not for internal implementation:
oip-package/
manifest.json
objects/sha256/<first-two-hex>/<remaining-62-hex>.json
files/sha256/<first-two-hex>/<remaining-62-hex>
evidence/sha256/<first-two-hex>/<remaining-62-hex>
Object paths use signed-object hashes; file/evidence paths use raw-byte hashes. File extensions and display names are not part of canonical storage addresses. Evidence includes captured legacy bytes, template dependency documents, and canonical JSON publication-proof files. The package manifest supplies the role of each item. No file may be loaded from outside the package merely because its name resembles a locator.
Internally, a store SHOULD also maintain:
- a reconstructable DID-to-revision/envelope catalog;
- content-addressed canonical objects, with multiple envelopes per revision;
- content-addressed files;
- encrypted or access-controlled local policy, locator maps, identity branch choices, and export consent state;
- rebuildable text, name, edge, temporal, geospatial, and optional vector indexes.
Local branch choices and authorization policy are durable private configuration; they are not inferred from arbitrary directory modification times. Portable export MUST state when such configuration is omitted and current-state interpretation will require a recipient's own policy.
11.2 Package manifest
manifest.json is canonical JSON with exactly:
| Member | Type | Meaning |
|---|---|---|
oip |
string | 1.0 |
kind |
string | package |
roots |
sorted array | { "id": DID, "revision": Hash } records/identity states selected for transfer |
objects |
sorted unique Hash array | Signed objects physically present |
files |
sorted array | { "hash": Hash, "size": Count, "mediaType": string } files physically present |
evidence |
sorted array | { "hash": Hash, "size": Count, "mediaType": string, "role": IRI } items physically present |
omissions |
sorted array | { "kind": "object" or "revision" or "file" or "reference", "id": string, "reason": "notSelected" or "unavailable" or "withheld" } |
scope |
enum | selfContained or partial |
Arrays of objects sort by J(element) bytes. Manifest roots need not expose a floating “current” choice; every root is revision-pinned. Manifest checksums verify the transfer, not publisher authority. Each signed object is independently verified. A manifest MAY have a detached signature in a separate transport wrapper, but Core does not require that extra signature.
For selfContained, all roots, their entire parent histories, required identity genesis/authorization chains, templates, schema dependencies, and every file referenced by those included revisions MUST be present. DREFs to unrelated graph subjects need not be recursively closed; each absent target is listed as a reference omission. Named parts and internal FileRefs cannot be omitted independently of their containing body. A package can therefore be self-contained for validation and files while declaring graph boundaries. partial is required for any missing validation or file dependency.
11.3 Import transaction and integrity
Importers MUST validate manifest paths, size/hash bindings, JSON syntax, object/revision hashes, signatures, available dependencies, and extraction limits before admitting an item to verified state. Verification of one item MUST NOT authorize another item merely because they share a package. Unresolved items may be retained in quarantine with their errors.
Writes MUST be atomic per content-addressed object. A store MUST not overwrite verified immutable bytes with different bytes at the same hash path. Mutable manifests/index pointers update only after durable writes succeed. An interrupted import must be restartable and deduplicate identical objects. Two offline devices may contribute different heads; import retains both and invokes the conflict rules, rather than last-write-wins filesystem replacement.
A portable archive wrapper MAY contain this directory layout. Archive implementations MUST reject symlinks, absolute paths, .. traversal, duplicate member names, invalid hash filenames, and decompression bombs. Unknown non-manifest files MUST NOT be executed or interpreted as policy.
11.4 File and record retrieval
A local retrieval request resolves a record or exact revision, a part if requested, then a FileRef if appropriate. It locates file bytes through a permission-scoped hash catalog. The returned object includes its source record revision and integrity status. Network retrieval is an explicit policy-controlled fallback; local offline retrieval MUST work without even attempting that fallback.
Exporting an article for offline reuse SHOULD offer its exact parts and associated original/derived files, referenced templates, and publisher verification history. An article's metadata alone does not make its remotely referenced image available offline.
12. Private data, sharing, and Solid
12.1 One semantic record format
Public, shared, and private records use identical envelopes, node formats, templates, DREFs, hashes, and signatures. visibility is signed disclosure intent, not a substitute for authorization. It does not grant access merely by being present.
private objects are restricted to their owning authorization domain. shared objects may be disclosed to explicitly authorized recipients. public objects are eligible for public distribution. Creating or signing any object locally MUST NOT itself trigger network publication. Sending a signed public object to a public relay or exporting it for public publication is a separate deliberate operation.
The default for a personal-memory writer is private. Authorization applies before lookup, expansion, search ranking, result counts, reverse-reference enumeration, file resolution, and export. A public search endpoint MUST NOT disclose private incoming edges, counts, private identifiers, snippets, hashes, embedding neighbors, or existence through errors.
12.2 Controlled public derivation
The default private-to-public operation creates:
- A new public record genesis descriptor with a fresh nonce and new DID.
- A selected/redacted public payload, parts, files, and provenance.
- A public publisher identity appropriate to the disclosure, separate from the private identity and using distinct key material by default.
- A new public root revision with no private parents.
- Optionally, a PrivatePublicBridge retained only in the private domain.
No private source DID, private revision hash, parent chain, local pathname, private publisher identity, secret locator, or private note is copied automatically. Redaction includes hidden file metadata and derived representations. Deliberately preserving an identity/history requires explicit user selection and disclosure review; adapters MUST NOT accomplish it by quietly changing a visibility field in old signed bytes.
Such an explicit selection still cannot override the public profile's signed-visibility rules. An already-public-eligible identity/history that was merely stored locally can be published unchanged. A history signed private/shared is retained privately and represented publicly by newly signed source/derivation records with only deliberately disclosed evidence; private envelopes do not become qualifying public objects by relabeling a transport request.
New identifiers reduce identifier-based linkage; they do not guarantee anonymity when public content repeats identifying private content. Identical disclosed file bytes have identical raw hashes. Implementations MUST describe this fact when claiming concealment and MUST NOT promise cryptographic unlinkability for repeated content. Private storage encryption uses randomized ciphertext to avoid disclosing plaintext-hash equality to untrusted storage providers.
12.3 Sharing and revocation
Access policy is stored separately from immutable semantic objects. It can grant read, write/import, append, and publication capabilities independently. Read permission is not permission to republish. Revocation prevents future authorized retrieval where the enforcement layer can enforce it; it cannot make a recipient forget previously obtained plaintext.
Private references to public entities remain private edges. A local equivalence claim is not exported with the public entity. For shared records, references to withheld dependencies remain unresolved for unauthorized recipients; the implementation must not fetch them with another user's credentials.
12.4 Solid adapter profile
Solid is a resource storage, identity, and authorization system, not an alternative OIP canonicalizer. The OIP adapter stores exact canonical object bytes and files as non-RDF resources, typically using application/octet-stream for the protected OIP object resource. It MAY expose separate RDF/JSON-LD discovery projections. Converting JSON into RDF and back MUST NOT be used as the authoritative signature round trip. The Solid protocol supports HTTP resource operations and permission-controlled storage; its evolving specification status is independent of OIP. Solid Protocol
The adapter MUST implement this mapping:
| OIP concern | Solid mapping |
|---|---|
| Signed object | Immutable binary resource containing canonical envelope bytes, or encrypted container |
| File / evidence | Immutable binary resource containing exact bytes, or encrypted container |
| Object inventory | Private discovery resource mapping opaque resource names to object/file hashes and media types |
| Heads and sync state | Mutable private projection; never authoritative over verified histories |
| Semantic interoperability | Separate private RDF/JSON-LD projection with links to canonical resources |
| Publisher DID | Cryptographic OIP identity; not automatically the Pod login identity |
| Pod access | Solid server's supported authentication/authorization mechanism |
Resource names SHOULD be random opaque labels. If content-hash paths are used, the user must accept the resulting hash-equality disclosure. Private identifiers and indexes MUST NOT be placed in publicly readable container metadata. A Pod WebID and an OIP DID are distinct identifiers. Any binding claim must be independently established; ownership of a Pod URL alone does not prove control of an OIP publishing key.
The adapter uses authorized HTTP GET/HEAD and PUT/POST/DELETE as supported by its server. New immutable resources MUST use a create-only precondition such as If-None-Match: *; conflicting existing resources are read and checked, never blindly overwritten. Mutable inventory changes MUST use a server-supported concurrency precondition such as a strong ETag with If-Match. If safe concurrent replacement is unavailable, the adapter stores append-only inventory fragments and merges locally. A failed precondition triggers refresh/merge, not overwriting another client's state.
The adapter MUST discover and obey the Pod's authorization mechanism, such as WAC or ACP; it MUST NOT assume these are interchangeable. Tokens and authentication secrets are never stored inside public OIP objects. Sharing must protect containers, inventories, canonical objects, derived text, and files consistently. RDF projections can be less complete than canonical records; they MUST NOT claim lossless reconstruction unless their mapping actually preserves all signed information.
Disconnected clients retain local objects and queue synchronization. After reconnection, incoming bytes pass Core verification and concurrent revisions remain visible. A Pod location change updates the private locator inventory, not the record DID. A private client need not run a Solid server to create or search local OIP records.
12.5 Optional encrypted-store format
The Encrypted Store profile uses compact JWE with alg: dir, enc: A256GCM under RFC 7516/7518. A new random 256-bit content key MAY be used per item; a managed store key MAY be reused only with a fresh unpredictable 96-bit IV for every encryption under that key. The authentication tag is 128 bits. The protected header contains exactly alg, enc, kid, and cty; kid is an opaque local key identifier and cty is application/octet-stream. No plaintext hash, DID, name, or unencrypted custom metadata is included in the header. JWE, JWA
The encrypted plaintext is canonical JSON exactly:
{
"oip": "1.0",
"kind": "sealedItem",
"itemType": "object",
"hash": "sha256:<logical object or file hash>",
"mediaType": "application/json",
"bytes": "<B64u of canonical object or exact file bytes>"
}
itemType is object, file, or evidence. After authenticated decryption, the receiver verifies the logical hash using the matching domain. Ciphertext storage can have its own raw-byte hash; it MUST NOT replace the semantic plaintext hash. Re-encryption changes ciphertext identity, not OIP identity.
Key distribution and recovery use an authorized private key store or a separately negotiated wrapping profile; this profile does not expose keys through signed records or derive encryption keys from public xpubs. A Pod can enforce access without seeing plaintext when this profile is used, but access metadata and ciphertext sizes remain observable. Native filesystem/OS encryption MAY protect local stores independently; it is not automatically the interoperable Encrypted Store wire format.
13. Indexing and retrieval contracts
13.1 Rebuildable projections
A Graph Index MUST separate signed data from derived fields. Ingest never modifies an original record to add resolved DREF content, a generated handle, a provider URL, a score, or a model summary. Such information belongs in a projection or separately signed record.
An interoperable index tracks at least:
- record DID, revision, envelope hashes, publisher, types, template pin, visibility, and status;
- each named part and its template/types;
- every explicit DREF, including source revision and source JSON Pointer;
- original reference string, normalized target DID/path/version/fragment, expanded predicate, and resolution status;
- file associations and verification/availability status;
- issuer times, domain event/valid times, and independently observed publication positions separately;
- source/provenance relationships;
- template, identity, and chain validation state.
13.2 Edge extraction
For each root and part node, recursively walk data. Upon encountering a DREF-shaped object, emit an edge from that node's address. The predicate is the nearest enclosing vocabulary-keyed property, expanded to its IRI; crossing array elements does not change it. Preserve the entire JSON Pointer to the DREF. Do not recurse inside DREF or FileRef reserved objects. Primitive strings that happen to contain did: do not become edges.
For top-level provenance, emit source edges under urn:oip:term:source, agent edges under http://www.w3.org/ns/prov#wasAssociatedWith, and file-association entries for FileRefs. File descriptor derivedFrom emits http://www.w3.org/ns/prov#wasDerivedFrom associations scoped to that file; descriptor processing provenance follows the same rule. A Template definition's opaque JSON Schema is never scanned for data edges.
The edge identity is (source DID, source revision, source node, source JSON Pointer, target reference). Duplicate target values in an array remain distinct signed occurrences. A reverse index is a projection of these edges, not an extra unsigned claim inserted into the target record.
An Assertion creates the explicit subject and object DREF edges. It MAY additionally create a derived relation (subject, predicate, object) for traversal, but this relation MUST carry the asserting record/revision, publisher, provenance, confidence, and valid-time bounds. It MUST NOT be indistinguishable from a direct assertion made by the subject's publisher. Contradictory relations remain representable.
Pinned target queries match only the requested revision. Floating target queries operate in a declared view and return actual resolved revision(s). Reverse queries for an embedded part MUST distinguish that part from its whole containing record; a caller MAY explicitly request whole-record aggregation. Historic-source edges and current-head edges are distinct query modes.
13.3 Retrieval interface semantics
This is a capability contract, not a mandatory database or HTTP product API. A conforming Graph Index supports:
| Capability | Required semantics |
|---|---|
| Lookup | DID/record path, exact revision, part and file selection; explicit view and conflict result |
| Lexical search | Search authorized text/name fields, with source revision and matching field returned |
| Name/entity search | Names and aliases with type constraints; candidates do not imply identity equality |
| Forward traversal | Outgoing explicit and optionally derived edges, with predicate filters |
| Reverse traversal | Incoming edges from authorized source revisions, with exact/floating/part distinction |
| Time filtering | Select the intended time axis: issued, observed, valid/event, ingestion, or publication |
| Geographic filtering | WGS84 point bounding-box and radius queries over indexed valid locations; missing precision is disclosed |
| Provenance filtering | Publisher, source, activity, model/method, verification and publication state |
| Associated files | Source and derived file descriptors, permission and availability status, verified retrieval |
| Optional semantic search | Embedding model/version, revision, access scope, and metric identified |
Geographic bounding boxes crossing the antimeridian are the union of [west,180] and [-180,east]; otherwise west must not exceed east. Latitude minimum must not exceed maximum. Radius comparisons in this profile use a sphere of radius 6,371,008.8 meters and great-circle distance, including boundary points. Other geospatial models must identify themselves. A coarse place label MUST NOT be silently converted into an exact observed coordinate.
Each retrieval result identifies (record DID, revision, node/part, source pointers) and, when applicable, exact file hashes and selectors. It includes the view and verification status. Ranking scores are implementation-specific. Traversal MUST enforce caller-specified budgets, access checks, cycle detection by (DID,revision,node), and a bounded result count. Reaching a budget returns a partial/truncated indicator. A missing target never implies permission to publish a guessed replacement record.
Protocol query time intervals are half-open [from,until), with an omitted endpoint unbounded. A point time matches when it lies in that interval; a stored valid-time interval matches when the intervals overlap. validUntil MUST exceed validFrom when both are given. Event endpoints follow the event template, including zero-duration events. Date-only values retain calendar-date precision; a query needing an instant conversion must declare a timezone/conversion policy and return that it was inferred. Relevance boosts do not override explicit time or access filters.
An AI retrieval system can combine these capabilities using any ranking strategy. It MUST retain enough citation context to return to the exact evidence bytes. Embeddings are optional and rebuildable; they MUST NOT be the sole durable memory. Retrieval does not authorize sending private results to a remote model. Model/tool execution and context disclosure require their own application authorization.
14. Public distribution and Bitcoin commitments
14.1 Publication lifecycle
The operations are separate:
- Create: create identity, template, record, or revision locally.
- Sign: obtain an independently verifiable object; return/export it without submission if requested.
- Store/index: use it in the local authorized graph.
- Distribute: submit exact signed objects and selected files to chosen recipients or public relays.
- Commit: include signed-object hashes in a batch anchored to Bitcoin.
- Verify: check inclusion, chain evidence, dependencies, authorization, and publication order.
A payer or relay need not be the publisher. A relay MUST accept a pre-signed object without requiring the publisher's private key. It MAY charge for service or reject according to a declared admission policy. A different relay or self-batching publisher can carry the same object. Transport fees, payment receipts, confirmation counts, and relay acknowledgments MUST NOT be inserted into the signed body.
Objects with visibility other than public MUST NOT be submitted to the public OIP commitment/distribution profile. That includes plaintext hashes of private objects: a public hash may disclose equality or permit guessing of low-entropy content. A future privacy-preserving timestamp profile must define its own hiding commitment; this profile does not silently anchor private hashes.
Public distribution has no mandatory central registry. Signed objects and files can be exchanged through packages, HTTP services, peer transports, or storage networks. Discovery and replication are distinct from validation. To advertise a retrievable object, a service provides its signed-object hash and at least one retrieval route or a portable package. Recipients validate bytes independently of the route.
14.2 Optional HTTP exchange binding
Implementations MAY expose this exact binding at a chosen base URL. The binding is not required for offline Core:
| Operation | Request | Response |
|---|---|---|
| Retrieve object | GET objects/sha256/<hex> |
Canonical envelope JSON; verify object hash |
| Retrieve file | GET files/sha256/<hex> |
Exact bytes; verify raw hash and expected descriptor size |
| Retrieve batch | GET batches/sha256/<roothex> |
Canonical manifest from 14.3 |
| Submit signed object | POST objects with canonical envelope JSON |
Canonical receipt below; no signing secret |
An accepted submission returns HTTP 202 and { "oip":"1.0", "kind":"receipt", "object":Hash, "state":"received" }. HTTP 200 with the same receipt and state alreadyPresent means idempotent storage. Neither is an inclusion proof or promise of public qualification. HTTP 400 means malformed object, 422 invalid integrity/authorization, 409 unresolved conflict, 424 missing dependency, 413 resource limit, 401/403 access policy, and 503 temporary unavailability. A service MAY use 404 to conceal private existence. Error responses contain { "error": <code>, "message": <string> } without secrets. A separate fee negotiation or authenticated transport MAY precede acceptance.
Submission requires an explicit action; simply GETting/resolving a reference MUST have no publication side effect. Public endpoints MUST not use private credentials or inventories to satisfy requests. Endpoint naming conveys no trust; bytes still undergo verification.
14.3 Commitment Batch manifest
{
"header": {
"oip": "1.0",
"kind": "batch",
"network": "<Bitcoin network genesis block hash in conventional display hex>",
"count": 3
},
"objects": ["sha256:<object 0>", "sha256:<object 1>", "sha256:<object 2>"]
}
The header has exactly the four members shown. The manifest has exactly header and objects. Count is 1–65,535 and equals array length. Entries are unique signed-object hashes in the batcher's chosen order; sorting is not required. Dependency-first ordering is necessary for public qualification. No batcher identity or signature is required for inclusion validity; the committed root authenticates the manifest. A signed commercial receipt can describe the service separately.
network MUST equal the genesis hash of the Bitcoin network whose chain validates the anchor. Mainnet, test networks, signets, and local regtest deployments are distinct publication namespaces. OIP object identities remain network-independent; their public publication status is network-specific.
14.4 Merkle construction
All hash values in this subsection are raw SHA-256 digests. The tree has N = count + 1 leaves. Header leaf:
L[0] = H(0x00 || ASCII("OIP1-BATCH") || 0x00 || J(header))
For manifest object index i, starting at zero:
L[i+1] = H(0x00 || ASCII("OIP1-ENTRY") || 0x00 || uint32be(i) || raw(objectHash[i]))
raw decodes the 64 hex digits after sha256:; it does not hash the textual identifier. uint32be is exactly four unsigned big-endian bytes.
The tree root function on an already hashed leaf list is:
- One leaf: return that leaf.
- More than one leaf: let
kbe the largest power of two strictly smaller than the leaf count; returnH(0x01 || root(first k leaves) || root(remaining leaves)).
There is no odd-leaf duplication and no empty batch. This uses a standard split-tree construction with OIP-specific leaf messages; it is not a Certificate Transparency log or its wire protocol. RFC 9162
The batch identifier is sha256:<roothex>. It is a Merkle-root identifier, distinct from a raw hash of the JSON manifest. Recomputing the manifest root must reproduce it exactly.
14.5 Bitcoin output encoding
The payload is exactly 37 bytes:
offset length value
0 4 4f 49 50 31 ASCII OIP1
4 1 01 commitment profile version
5 32 Merkle root bytes
The scriptPubKey is exactly:
6a 25 4f 49 50 31 01 <32 root bytes>
6a is OP_RETURN and 25 is the direct 37-byte push. Additional opcodes, trailing bytes, nonminimal pushes, or different versions do not match this 1.0 profile. Output value is zero satoshis. If a transaction contains multiple qualifying outputs, each is processed by output index. The application must still satisfy the Bitcoin network's consensus and relay/mining policies; OIP does not alter them or guarantee fee-free inclusion. Bitcoin transaction reference
Transaction construction, fee negotiation, batch cadence, and Lightning settlement are service choices. A batcher can withhold or fail to anchor; the publisher can resubmit to another batcher. A mempool transaction is not a confirmed anchor.
14.6 Portable inclusion proof
A proof file is canonical JSON with exactly:
| Member | Type |
|---|---|
oip |
1.0 |
kind |
bitcoinProof |
network |
Network genesis display hash |
header |
Batch header |
root |
Merkle-root Hash |
object |
Signed-object Hash |
index |
Zero-based object index, below count |
objectPath |
Array of 64-hex sibling digests, bottom-up |
headerPath |
Array of 64-hex sibling digests, bottom-up |
transaction |
Lowercase hex of the complete serialized Bitcoin transaction |
outputIndex |
Count selecting the qualifying output |
blockHeader |
Lowercase hex of the 80-byte Bitcoin block header |
transactionIndex |
Zero-based transaction position in block |
transactionCount |
Positive transaction count in block |
transactionPath |
Bitcoin txid Merkle siblings, bottom-up, conventional display hex |
For an OIP inclusion path at tree position j with size N, recursively use the split rule from 14.4: descend left if j < k, otherwise right with j-k; consume each sibling as recursion unwinds, hashing in the left/right order implied by that descent. The verifier derives directions and expected path length from j,N, rejects extra/missing siblings, and verifies the root. Header proof uses j=0; object proof uses j=index+1. Both are REQUIRED so that network/count are bound even without the full manifest.
Bitcoin transaction inclusion uses Bitcoin's txid tree, not the OIP tree: calculate txid from serialization without witness, reverse display hashes into internal digest bytes for hashing, apply double SHA-256 and Bitcoin's odd-node duplication rule, and match the block header Merkle root. Transaction position/count MUST be corroborated against a consensus-validated block or a trusted validating-node result before asserting canonical order. A bare Merkle path does not independently authenticate the total transaction count or rule out all Bitcoin Merkle-tree ambiguities.
The verifier checks transaction parsing, selected script/value, root bytes, both OIP paths, block membership, and that the block belongs to its selected validated Bitcoin chain with the stated network genesis. Full consensus validation or an explicitly trusted validating node is REQUIRED for a confirmed public-order claim. Header-only/SPV verification MAY report inclusionOnly with its trust assumptions. The file does not purport to contain the full blockchain; offline verification requires a previously validated chain/checkpoint and sufficient cached block evidence.
Membership proofs alone do not establish that every manifest entry is unique or that the complete manifest conforms. A publication-qualified batch additionally requires the full manifest, validated count/uniqueness, and a recomputed root. Without that manifest, a client can report confirmed cryptographic inclusion under a validated block, but MUST retain authorization/batch qualification as pending rather than implying a fully accepted public object.
14.7 Ordering, duplicates, and confirmation
On one selected Bitcoin chain, positions sort lexicographically by:
(block height, transaction index, output index, object index within batch)
The header leaf is not an object and has no object index. Block height is derived from the validated chain, not trusted from a submitted proof. Chain tip hash and height accompany every ordering result. For the default public profile, fewer than six confirmations is provisional; six or more is confirmed. Confirmation depth is tipHeight - anchorHeight + 1. An application MAY demand more confirmations but must identify its policy; probabilistic finality is never described as irreversibility.
All inclusion occurrences remain evidence. An envelope's first public position is its earliest qualifying inclusion. A record revision's first qualified publication is the earliest inclusion of any envelope for that revision that satisfies the public authorization/dependency rules. Multiple envelopes, fee payers, relays, or batchers do not create new record identities or duplicate revision heads.
Bitcoin block header timestamps are not precise creation timestamps. A commitment supports existence by its inclusion under the stated chain assumptions; it does not establish the claimed event date, capture date, or exact signing time.
14.8 Qualification and public state replay
Replay orders available manifest entries by publication position. To qualify a public object at a position:
- Verify its object/body hashes, structure, public visibility, and cryptographic proofs.
- For identity create, validate the self-certifying genesis and threshold. For other identity operations, require a predecessor already accepted as the identity's current public head, and apply Section 5.4.
- For a record, require its publisher's accepted public identity state to equal the state in at least one valid assertion proof at this position. A proof against a stale state does not qualify even if the key bytes also occur in the new state.
- Require all record parents to have already qualified publicly. Roots have none. Apply record ancestry/status rules.
- Validate the pinned template and required dependency bytes. Custom template records and their custom template dependencies must have qualified at earlier positions. Built-ins have no publication prerequisite. Schema file bytes must match their committed dependency hashes.
- Require no private/shared OIP validation dependency in the public lineage. Ordinary external graph targets and media need not be present for publication qualification; mark their availability separately.
An unavailable object or dependency is pending, not definitively invalid. When bytes arrive later, replay from the affected earliest position and recompute state. No rule depends on the indexer's arrival order. An invalid payload's inclusion evidence may be retained, but it does not become a valid public record or identity operation.
The rules define a deterministic public view for a given validated chain and available corpus. A root commitment cannot prove that all prior data has been disclosed. A provider unable to inspect earlier recognized batches/objects MUST report incomplete coverage and MUST NOT claim globally complete identity freshness or universally earliest publication. Even an authenticated later identity chain cannot by itself prove absence of an earlier competing committed operation. Public verification reports therefore include scanned chain range, missing manifests/objects, and completeThrough only for a prefix whose recognized batches and objects have actually been processed.
Missing data does not stop local use, proof verification, or publication of unrelated objects. It limits the strength of “current” and “earliest” claims. Distribution, availability monitoring, and future service/witness profiles can improve that assurance; this specification does not invent an availability guarantee from a hash. Applications can use a declared partial view, but cannot hide that choice behind a global-canonical label.
14.9 Reorganizations
When the validated best chain changes, detach orphaned positions, recompute confirmations, and replay affected identity/record state in new chain order. Objects remain immutable and locally retained unless separate policy removes them. Their status can change from confirmed to provisional, unanchored, or orphaned; conflicting identity branches can change acceptance. An object's alternate anchor on the surviving chain may become its earliest occurrence.
Indexes and user interfaces MUST be able to reverse derived state. A stored firstPublished timestamp or a head selected under an old chain MUST NOT become immutable protocol truth. Offline clients report the checkpoint they know rather than implying a current network view.
15. Import and migration
15.1 General adapter contract
Migration supports any documented historical OIP version or external format. It is not limited to v0.8/v0.9/Alfred. Each adapter has an immutable profile identifier, version, supported source dialects, detection rules, template mappings, reference mappings, verification procedures, and information-loss policy.
Import MUST preserve original source bytes before normalization, their raw hash, source identifiers, declared format/version, and available signature/transaction evidence. It then produces new v1.0 objects under the importer's authority, with explicit provenance. The original author MUST NOT be represented as having signed the newly transformed bytes. Conversion is a signed statement by the importer about the source.
Unknown or ambiguous versions are quarantined or retained as Source/Artifact records. Guessing a modern signature scheme from a version string, accepting a prefix as proof of a DID method, or passing unverifiable legacy records through as “verified” is prohibited.
15.2 Migration receipt
A MigrationReceipt uses its built-in template and contains:
| Predicate | Type and rule |
|---|---|
oip:profile |
Absolute URI identifying the exact adapter profile |
oip:profileVersion |
Nonempty string |
oip:sourceFormat |
Nonempty string |
oip:sourceVersion |
Nonempty string, or literal unknown |
oip:original |
FileRef to original bytes |
oip:sourceIdentifiers |
Array of original identifier strings |
oip:outputs |
Nonempty array of pinned DREFs to converted records |
oip:mappings |
Array of objects exactly { "source": string, "target": DREF } |
oip:verification |
Object exactly { "status": enum, "method": string, "evidence": array of FileRefs/DREFs } |
oip:losses |
Array of nonempty strings describing unsupported/omitted/ambiguous information |
Verification status is verifiedOriginal, signatureOnly, transportEvidenceOnly, unverified, or invalidOriginal. These describe the source, separately from the valid signature on the migration receipt. Receipt creation can follow output creation: outputs cite retained original files, and the receipt lists outputs, avoiding a circular hash dependency. A private receipt stays private when it would expose private source identity or history.
15.3 Identity and identifier mappings
Migration creates new native IDs and retains an adapter-managed mapping keyed by (source namespace, source version/dialect, original identifier). Repeating an import SHOULD reuse that mapping and deduplicate exact source hashes. The mapping is durable exportable private metadata when the source is private. Independent importers may produce distinct OIP records describing the same original; byte/provenance equality can be discovered without granting shared editorial authority.
Legacy references map to pinned v1.0 references only when the target is known. Otherwise preserve the original identifier in provenance and record an unresolved mapping; do not fabricate an OIP DID. Proven legacy controller bindings MAY establish an explicit cross-identity claim, but alsoKnownAs and name matching alone do not transfer authority.
15.4 Baseline source profiles
| Source | Preserve and verify | v1.0 transformation |
|---|---|---|
| OIP v0.8 Arweave records | Original transaction data, ordered tags, creator registration, exact template IDs, Arweave transaction evidence and original CreatorSig procedure | Expand numeric fields with the referenced historical template; map known terms to Schema.org; retain original bytes and transaction IDs; sign conversion as importer |
| OIP v0.9 / oip-lite | Exact signed payload, fragments, tags, PayloadDigest, KeyIndex, xpub/VM history, DID Document representation and transport evidence | Verify the actual dialect's payload digest and non-hardened secp256k1 derivation where sufficient evidence exists; convert identities through explicit bindings and new native registration |
| Alfred OIP-local | Every revision JSON, manifest, raw artifacts, original did:memory IDs and historical hash procedure |
Convert five primitives to standard templates, reconstruct available parents, move local file paths to private locator inventory, retain original revision hashes as migration evidence |
| Earlier OIP/FLO or other archives | Exact source objects, templates, identifiers, signatures, block evidence if available | Adapter-specific, version-pinned mappings; no invented verification guarantee |
| Non-OIP JSON/RDF/files | Original bytes and available provenance | Source/Artifact plus explicitly sourced Entity/Assertion/Analysis records |
The baseline table defines mapping requirements, not a claim that every historical dialect is already fully documented. An adapter MUST publish exact source-verification rules before emitting verifiedOriginal. A Core importer can always preserve a source as unverified evidence without implementing every historical verifier.
For v0.8, record and template signing input orders differ in the reviewed implementation. Template-name “canonical” remapping must not overwrite historical template identity. For v0.9, the reviewed implementation uses a payload digest rather than a future transaction ID to derive a key index; source verification must follow the source dialect, not a contradictory feature proposal. Verification stubs or catch-and-continue paths are not valid evidence.
For Alfred, the historical canonicalizer replaces properties named revision and normalizes certain timestamp strings. A migrated object's v1.0 revision therefore MUST NOT be expected to equal its legacy hash. did:memory:<id>#sha256:<digest> is parsed as a legacy revision pin, then converted into a native /record?versionId=... reference. Unpinned legacy references remain floating unless the importer has evidence for a specific intended revision. Unsigned private memories remain attributed as imported observations/assertions, not retroactively signed original memories.
15.5 Migration safety
Mapping a field's spelling does not justify changing its semantics. Unknown fields stay in an explicitly documented custom template or original evidence; losses are listed. Rebuilding an index must not require re-running a nondeterministic AI interpretation. AI-assisted migration creates separately identified analysis with its inputs and model metadata retained.
No existing client compatibility is required for v1.0 serialization. Legacy write encodings are not emitted as a hidden compatibility mode. Future changes use explicit versions and migration profiles.
16. Extension boundaries
16.1 Extension mechanism
Extensions use globally unambiguous IRIs and immutable specifications. Unknown annotations are preserved and hashed but never executed. An extension changing verification, identity authority, canonicalization, or public state transition is not a harmless annotation: it needs an advertised profile or a new protocol version. Core consumers MUST return unsupported when validity depends on semantics they do not implement.
Template evolution, new Schema.org types, additional application templates, and new file locators need not change the core envelope. A transport adapter defines how its locators retrieve exact bytes and how it behaves offline; it cannot redefine OIP hashes. A DID adapter defines method resolution and trust; it cannot reinterpret arbitrary strings as authorized identities.
16.2 Ecosystem record families
The following families use Generic or publicly published custom templates until their separate profiles are finalized:
| Family | Data the graph can describe | Explicitly outside Core |
|---|---|---|
| Commercial offer | Schema.org Offer/Product/CreativeWork, seller DID, rights evidence, price/currency, access terms, payout/Storefront/Promoter terms, expiry | Settlement, enforcement, attribution disputes, fee curves, entitlement delivery |
| Verified publisher | Evidence of identity or rights-holder authorization, issuer, scope, validity period | A universal authority deciding ownership; publishing permission for ordinary descriptive records |
| Commerce report | Offer revision, service identity, amounts, currency, settlement evidence, time | Declaring an unverified payment successful or exposing customer identity by default |
| Retention/availability evidence | Provider, object/file hashes, challenge, response, observation time, retrieval evidence | Reward eligibility, independence/Sybil assessment, challenge randomness, bond/slashing rules |
| Corpus growth | Citations, incoming references, evidence trails, declared use, duplicate-content evidence | A canonical usefulness/truth score or reward lottery |
| ALT/governance | Proposals, ballots, delegations, budgets, decisions, asset references | Supply, elections, voting weight, treasury authority, securities treatment |
| Compute | Model artifacts, hardware, benchmark observations, provider descriptions | Work scheduling, confidential execution guarantees, accounting, staking allocation |
| C2PA/media provenance | Credential bytes, validation observations, signers and media hashes | Declaring a valid credential to prove factual truth |
These families must not introduce dependencies on ALT, payments, a Council, Akash, OpenClaw, HYPATIA, or Alexandria.io for ordinary record creation or verification. Policy Lists and Tombstones describe operator decisions without globally erasing publication evidence.
17. Security and resource limits
17.1 Core interoperability limits
An object exceeding these limits is outside the Core profile, not silently truncated:
| Item | Limit |
|---|---|
| Canonical signed-object size | 16 MiB |
| JSON nesting | 64 containers, counting root as 1 |
| Parents | 64 |
| Proofs per envelope | 32 |
| Keys per identity policy | 16 |
| Named parts per revision | 4,096 |
| File descriptors per revision | 4,096 |
| Individual DREF/locator URI | 8,192 UTF-8 bytes |
| Template dependencies | 256 per definition, including transitive dependencies |
| Dependency schema size | 4 MiB each |
| Commitment Batch objects | 65,535 |
Files have no protocol byte-size cap beyond Count representation. Services MAY impose smaller admission quotas and stream large files. A lower local quota is resourceLimit, not a claim that a globally conforming object is invalid. Applications SHOULD bound schema evaluation, graph traversal, proof/dependency expansion, parsing time, and total package extraction bytes.
17.2 Required safeguards
- Verify before trusting: distinguish key possession from authorization and authorization from truth.
- Reject algorithm confusion, malformed/duplicate JSON keys, mismatched proof states, reused key IDs with changed material, and hash-domain substitutions.
- Do not execute code, templates, browser scripts, model instructions, or commands merely because they appear in a record. Retrieved content is data, not authority over the agent.
- Do not fetch localhost, private-network, cloud-metadata, or credential-bearing endpoints through public untrusted locators without explicit local policy. Validate redirects and transport schemes at every hop.
- Preserve signed bytes separately from display-safe rendering; escape untrusted text in interfaces.
- Protect authorization before search and before every graph/file expansion; filter derived results too.
- Keep seed/private/recovery material out of DID Documents, records, logs, relays, package manifests, and public proofs.
- Keep historical verification evidence; do not “verify” an old signature with whichever key is current now.
- Report incomplete corpus/chain coverage, missing templates, missing files, revocation uncertainty, and conflicting identity histories precisely.
- Treat publicly disclosed hashes and repeated bytes as potential correlation signals.
17.3 Limits of guarantees
No standalone offline store can know all unseen updates, prove public nonexistence, or establish a globally current chain tip. No commitment restores deleted bytes. No signature proves the truth of a claim. No storage authorization prevents all misuse after plaintext disclosure. No fragment retrieves a file if every copy of its containing record or bytes is gone. Conforming responses expose the applicable uncertainty rather than replacing it with a success flag.
18. Conformance scenarios
An implementation claiming the named profile MUST demonstrate the following outcomes. These are behavioral requirements for independent test suites, not a supplied application implementation.
| ID | Scenario | Required outcome |
|---|---|---|
| C01 | Fresh installation, all network access denied | Create identity, verify registration, create signed record, store file, query locally |
| C02 | JSON properties reordered / whitespace changed | Same canonical body and revision; invalid duplicate keys rejected |
| C03 | Nested payload property named revision changes |
New body hash; no blanket removal of matching property names |
| C04 | Proofs replaced by valid current-key authorization | Same body revision, different signed-object hash |
| C05 | Creator signs offline; another actor pays relay/Bitcoin fees | Original publisher remains authorizing identity; unchanged envelope verifies |
| C06 | Identity create includes unbound operational key without management threshold | Reject registration |
| C07 | Routine assertion key attempts identity recovery | Reject operation |
| C08 | Old identity state supplied after key rotation | Historical signature can verify; current/public authorization is stale unless valid at publication position |
| C09 | Two offline identity updates from same parent | Report conflict; no timestamp or arrival-order winner |
| C10 | Two record edits from same parent, then merge | Preserve both heads; explicit merge creates one head |
| C11 | Article B references A's pinned image part | Resolve containing revision, image node, and exact local bytes without standalone image record |
| C12 | A changes image; B has pinned and floating references | Pinned returns old bytes; floating reports new resolved revision or conflict |
| C13 | Named part absent in selected revision | partNotFound; no whole-record fallback |
| C14 | Unknown external DID method | Preserve DREF and edge; report unsupported resolution |
| C15 | Custom template unavailable offline | Store pending; never claim full template validation |
| C16 | Template with same name revised | Previously pinned records retain old validation semantics |
| C17 | Source file copied between disks or Pod locations | Same bytes/hash and record identity; local locator changes only |
| C18 | Solid RDF projection round-trips with different ordering | Canonical binary object remains authoritative and unchanged |
| C19 | Concurrent Pod inventory update | Conditional-write failure and merge; no lost object/revision |
| C20 | Private source has public incoming/outgoing relationships | Public query exposes no private edges, counts, names, hashes, or existence |
| C21 | Private capture becomes public | New DID/root and selected content; default public bytes contain no private lineage |
| C22 | Encrypted item re-encrypted with new IV/key | Ciphertext changes; decrypted logical identity is unchanged |
| C23 | Search database deleted | Reconstruct records, parts, edges, file links, and indexes from durable store |
| C24 | Package omits associated media | Declare partial unless media belongs only to an external reference boundary |
| C25 | Byte of object, file, proof, or header tampered | Corresponding hash/signature/inclusion verification fails |
| C26 | Odd-size OIP Merkle tree | Split-tree algorithm; no Bitcoin-style odd-leaf duplication |
| C27 | Header/count/network changed with object path unchanged | Header inclusion proof or anchor network check fails |
| C28 | Same revision anchored by several batchers | One revision; all receipts retained; earliest qualifying occurrence reported within coverage |
| C29 | Bitcoin reorganization removes anchor | Recompute status, identity branches, heads, and earliest occurrence |
| C30 | Hidden/unavailable earlier batch | Report incomplete public coverage; no globally complete freshness claim |
| C31 | Legacy record with unverifiable CreatorSig | Original evidence retained, source marked unverified; importer signature not confused with original author |
| C32 | Text selector applied to different extraction version | Integrity/bounds mismatch; no silent quote relocation |
| C33 | Model-generated claim contradicts source | Separate records and provenance; source not rewritten |
| C34 | Retraction and provider Tombstone | Distinct authority and state effects; neither pretends public historical bytes vanished |
19. Worked examples
19.1 Article with an embedded reusable image
The following is a body illustration; placeholders stand for correctly computed IDs/hashes. A complete signed, reproducible version appears in the normative vector companion.
{
"oip": "1.0",
"kind": "record",
"id": "did:oip:r:<article-A-genesis-digest>",
"genesis": {
"oip": "1.0",
"kind": "recordGenesis",
"nonce": "<32 random bytes, base64url>",
"publisher": "did:oip:i:<publisher-genesis-digest>"
},
"sequence": 0,
"parents": [],
"issuedAt": "2026-09-26T12:00:00.000Z",
"visibility": "public",
"status": "active",
"node": {
"types": ["schema:Article"],
"template": "urn:oip:template:1.0:Article",
"data": {
"schema:headline": "The harbor restoration",
"schema:articleBody": "A report on the restored harbor.",
"schema:image": { "dref": "#hero" }
}
},
"parts": {
"hero": {
"types": ["schema:ImageObject"],
"template": "urn:oip:template:1.0:Image",
"data": {
"schema:caption": "The restored harbor",
"schema:contentUrl": { "file": "hero-file" }
}
}
},
"files": {
"hero-file": {
"hash": "sha256:<image-byte-digest>",
"size": 12345,
"mediaType": "image/jpeg",
"locators": []
}
},
"provenance": { "sources": [], "activity": "oip:authored" }
}
Article B's image property is:
{
"schema:image": {
"dref": "did:oip:r:<article-A-genesis-digest>/record?versionId=sha256%3A<article-A-revision-digest>#hero"
}
}
The agent's path is Article B → Article A's pinned hero part → hero-file descriptor → local file hash. If the file is later offered through IPFS or HTTP, a locator catalog can supply that route without changing either citation. Article A can later change while B continues to resolve the exact old image. A public reverse-reference query for A's image can discover B; private referencing articles remain hidden.
19.2 A custom template without an online registry
A laboratory can create a Template record with requiredTypes including schema:Observation and an additional absolute IRI for its assay type. Its JSON Schema requires schema:observationAbout, schema:measuredProperty, schema:value, and the laboratory-specific calibration fields. It includes immutable dependency-file hashes and describes its custom terms. The local client signs the template and then signs a measurement record pinned to that template revision.
Both records validate offline. Later, the lab may publish the template followed by the measurement in one ordered Bitcoin batch. Another node receives the exact template and schema dependency bytes and can reproduce validation. No globally unique template name, central schema service, or live Schema.org lookup is required.
19.3 Private memory with public context
A private Person record describes a colleague. A private Episode describes a meeting. A private Assertion records a relationship between that colleague and a project. A DREF points to the colleague's public Organization record. The local index can traverse both directions within the user's authorized corpus and retrieve associated meeting audio or notes by file hash.
The public Organization receives no private back-link. A public Organization search does not reveal that the private meeting exists. If the user later publishes a sanitized summary, it has a new public DID/root, a public publisher, selected public references, and no private parents. The private store can retain the bridge for future personal retrieval.
19.4 Record authorization and later anchoring
A user signs a public-eligible record against identity state S1 while offline. The record is immediately usable locally. If S1 is still the accepted public identity state when its envelope is anchored, it can qualify at that position. If a public rotation to S2 happened first, the old proof remains verifiable at S1 but is stale for new publication. A new S2 proof over the same revision produces another envelope without changing the record's content revision. The relay can anchor the new envelope, paid for by anyone.
This prevents a delayed signature from silently bypassing rotation while preserving the distinction between content identity and publication authorization.
19.5 Reproducible vectors
The companion includes a complete publisher registration, two signed articles sharing one embedded image, expected identity/revision/object hashes, image bytes, a batch manifest, its leaves and inclusion paths, and exact OP_RETURN script bytes. It uses publicly documented test-only key material and has no real blockchain transaction or publication claim. Its expected values are normative examples of Sections 3–5, 7, and 14. The conformance scenarios cover behavior beyond those vectors; the vectors are not a substitute for an independent interoperability/security test suite.
20. Design rationale and source assessment
This section is informative. It records why the specification retains some concepts and deliberately changes others. It describes a source-code/design review, not a runtime certification of the existing systems.
20.1 Reconciliation of the three implementations
| Source | Useful foundation retained | Behavior deliberately changed |
|---|---|---|
| oip-arweave-indexer / v0.8 | Published templates, typed/repeated DREFs, creator attribution, media transport diversity, expanded searchable records | Record identity no longer depends on transaction submission; one canonical body/signature procedure replaces different tag/data concatenations; template revisions remain pinned rather than interpreted by a mutable canonical-name configuration |
| oip-lite / v0.9 | Publisher/fee-payer separation, pre-signed submission, DID Document identity direction, purpose-separated keys | Complete inline publisher Documents and explicit native method rules replace flattened assembly assumptions; unfinished binding verification and legacy passthrough are not normative; optional xpub profiles cannot weaken baseline authorization |
| Alfred OIP-local | Stable IDs, immutable revisions, content-addressed source files, typed memory, lexical/name/graph retrieval, rebuildable indexes | JCS replaces its application-specific canonicalizer; revision query and part fragment are separate; signatures and identity history become portable; private/public permissions govern every projection; templates become portable published contracts |
The actual Alfred answer path reviewed combines lexical retrieval, name/entity seeds, relationship recall, and bounded graph expansion. Its vector visualization does not make all described future retrieval capabilities already implemented. The v1.0 Graph Index contract explicitly includes geographic and provenance capability requirements rather than claiming the current code already satisfies them.
20.2 Feature request dispositions
| Requested capability/proposal | Disposition |
|---|---|
| Another actor pays for a message | Supported; payer/relay identity does not replace publisher proof |
| Create and sign without sending | Supported; no network dependency in signing or local indexing |
| Submit an already signed message | Supported; exact envelope is the submission unit |
| Chain-independent signing | Required; envelope proofs are separate from blockchain transaction signatures |
| Verify against registered creator keys | Required at an explicit identity state and appropriate assertion relationship |
| Update creator records / several keys | Full DID Document operations, distinct key IDs, update threshold, independent recovery |
| Message-server addresses | Signed DID service endpoints; no forced rewrite by an indexer |
| Root/master wallet use | No routine use or publication of private root material |
| HD branches/xpubs | Wallet-compatible ordinary public keys in Core; xpub derivation remains optional profile work |
| Automatically burn earlier indexes on higher-index use | Not adopted; unsafe as a global ordering rule for hash-derived indexes or concurrent/offline writers |
| Derive signing index from eventual transaction ID | Not adopted; creates a circular dependency and a blockchain prerequisite |
| Mutable identity rooted directly in did:key | Not adopted as an override of did:key semantics; native updatable identity method instead |
The source feature document combines secp256k1, Ed25519/SLIP-0010, hardened leaves, xpub verification, multiple path conventions, and different rotation proposals. Those are not one interoperable cryptographic scheme. In particular, standard SLIP-0010 Ed25519 cannot publicly derive non-hardened child keys. The protocol preserves the goals without treating contradictory proposals as implementation requirements. SLIP-0010, BIP-32
20.3 Draft 0.6 alignment
The specification preserves the ecosystem draft's separation of deterministic evidence and analysis; Source/Analysis/Observation/Web Capture record families; Schema.org-first vocabulary; stable identity and exact revisions; public/private graph bridges; source files; reverse references; Bitcoin commitments outside record storage; permissionless batchers; transparent policy omissions; and the ability to build interfaces and retrieval before blockchain integration.
It makes six additional boundaries explicit:
- A protocol format is common to public and private data, even though the public network and private authorization domains differ.
- A DID Document is an identity/control document, not automatically the article it identifies or locates.
- Canonical record validity, public inclusion, current authorization, and data availability are separate states.
- Public publication must not silently disclose private lineage.
- Search/ranking and AI inference do not become consensus or truth adjudication.
- Economic/governance profiles can evolve without blocking offline records or core interoperability.
20.4 Local source references
- Ecosystem draft 0.6
- Feature request
- v0.8 publishing and serialization
- v0.8 indexing and legacy verification paths
- Historical template-name mapping
- v0.9 key derivation
- v0.9 signing
- v0.9 verification
- v0.9 pre-signed publishing
- v0.9 DID rendering
- Alfred memory description
- Alfred record envelope
- Alfred canonicalizer
- Alfred package store
- Alfred DREF behavior
- Alfred retrieval
These filesystem links document the reviewed workspace; they are not runtime protocol dependencies.
21. References and standards status
The OIP choices in this document are new normative protocol rules, not claims that external standards already define OIP. The following dated versions govern where incorporated. Later external drafts do not silently change this edition.
21.1 Incorporated standards
- RFC 2119 and RFC 8174: requirement language.
- RFC 8259 and RFC 8785: JSON and canonicalization.
- RFC 4648: base64url; OIP prohibits padding.
- RFC 3339: timestamps, narrowed by the OIP Time type.
- RFC 3986, RFC 3987, and RFC 6901: URIs, IRIs, JSON Pointers.
- DID Core 1.1, 5 March 2026 Candidate Recommendation Snapshot: identity data model and DID syntax. This is a Candidate Recommendation, not a claim of final W3C Recommendation status.
- DID Resolution 1.0, 28 August 2026 Candidate Recommendation Draft: resolution/dereferencing interfaces, with OIP-specific rules stated here. DID Core 1.1's older reference to resolution 0.3 does not rename this newer draft.
- RFC 7515, RFC 7517, RFC 8032, and RFC 8037: JWS, JWK, Ed25519, and JOSE mapping.
- JSON Schema 2020-12 Core and Validation: custom-template constraints.
- Schema.org 30.1: default semantic vocabulary, with OIP-specific template constraints.
- RFC 7516 and RFC 7518: optional encrypted-store profile.
21.2 Profile and informative references
- Solid Protocol: storage adapter interoperability. An adapter MUST declare the Solid protocol and authorization specification versions it implements; the core signed bytes do not depend on their evolution.
- Bitcoin transaction format: Bitcoin serialization context; consensus validation remains Bitcoin's responsibility.
- RFC 9162: Merkle construction precedent; OIP defines its own leaf encodings.
- did:key, did:web, did:webvh 1.0: external method behavior and design comparison.
- Web Annotation Data Model and Media Fragments URI 1.0: selector interoperability context.
- BIP-32 and SLIP-0010: optional wallet derivation context, not Core key-generation requirements.
No external account, DNS lookup, token purchase, or live standard-document download is required to use the Core profile offline.