Appendix A - Normative Data Schemas
The schemas in this appendix are the common basis for protocol implementations, test vectors, and interface validation. Field names are governed by the actual JSON serialization result. Rust types, TypeScript types, and HTTP examples must not independently invent synonymous fields. If a field exists only in a reference implementation or a specific resource type, it should be explicitly marked as optional or as a profile extension. Schema versions, content digests, signature coverage, and unknown-field handling rules must remain consistent with Chapters 4 through 7, Chapter 15, and Chapter 24 of the main text.
A.1 DID Document Schema
The public Rust type for a did:oan DID Document contains @context, id, verificationMethod, authentication, assertionMethod, service, and the optional oanMetadata. The id must exactly match the DID being resolved. The id and controller of verification methods, their public-key material, and their reference relationships must support signature verification. Resource types, capability tags, use cases, protocol bindings, implementation links, and resource package information in oanMetadata are OpenAgenet (OAN) extensions; the specific fields are governed by the serialization definition in oan-core. Public keys, digests, and DIDs in the example are placeholder values. Registration and index validation should fail when id is missing, a verification-method reference cannot be resolved, a service endpoint is not a valid URI, or the resource type does not match the DID semantic code. The current public type does not include controller as a top-level DID Document field. If a DID profile uses this field, its compatibility scope must be documented separately; it must not be confused with verificationMethod.controller.
{
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/oan/v1"],
"id": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"verificationMethod": [{
"id": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"publicKeyMultibase": "zExamplePublicKey"
}],
"authentication": ["did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu#key-1"],
"assertionMethod": ["did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu#key-1"],
"service": [],
"oanMetadata": {
"subjectType": "skill",
"resourceType": "skill",
"resourceDescription": {
"name": "Example repository structure skill",
"description": "Searches a repository and summarizes its project structure.",
"capabilityTags": ["code-repository", "project-structure"],
"useCaseExamples": ["Summarize the layout of a source repository."]
},
"capabilityTags": ["code-repository", "project-structure"],
"authorizedDomains": ["software-development"]
}
}
| Validation item | Valid condition | Failure handling |
|---|---|---|
id |
Exactly matches the requested target DID and conforms to did:oan syntax |
Reject registration or indexing |
| Verification method | Public-key encoding, controller, and reference relationships support signature verification |
Return a key or signature-structure error |
oanMetadata |
subjectType and resourceType use the public resource-type enumeration |
Return a resource-type mismatch |
| Unknown extensions | Do not change the semantics of existing fields | Ignore or reject according to the schema version |
A.2 Resource Metadata Schema
The four resource types share information such as the resource DID, resource type, name, description, version, capability tags, use cases, endpoints, protocol bindings, and implementation links. However, the current public types carry this information at different levels: ResourceMetadata uses resourceDid, resourceType, subjectType, name, description, capabilityTags, authorizedDomains, protocolBindings, services, lifecycleState, packageVersion, hashes, and updatedAt; the DID Document expresses the corresponding information through oanMetadata.resourceDescription, capabilityTags, protocolBindings, and packageInfo. The enumeration values for the four resource types are agent_service, skill, mcp_server, and tool_api; the display name agent must not be used as a protocol value. Length, duplicate-item, and format restrictions for strings, arrays, and URIs should be supplemented by the specific profile or node validation rules. Unknown resource types, an empty DID, missing digests, or unresolvable endpoints must not be treated as complete metadata. New optional fields may be added compatibly; breaking changes should be handled through version management.
| Field | Type | Required | Constraint |
|---|---|---|---|
resourceDid |
string | Yes | Must be the DID of the resource itself |
resourceType |
enum | Yes | Public enumerations such as agent_service, skill, mcp_server, and tool_api |
subjectType |
enum | Yes | Consistent with the resource subject type |
name |
string | Yes | A direct field of ResourceMetadata; multilingual expressions are carried by the profile |
description |
string | No | Does not replace structured capability fields |
capabilityTags |
array[string] | No | Used for semantic governance and discovery; elements should be comparable |
authorizedDomains |
array[string] | No | Used for authorization-domain decisions; not equivalent to capability tags |
services |
array[ServiceEndpoint] | No | Each item contains id, type, and serviceEndpoint |
packageVersion |
string | Yes | Must remain consistent with the resource package version |
packageHash/metadataHash |
string | Yes | Digest references represented according to hashAlgorithm |
{
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"subjectType": "skill",
"name": "Repository analysis",
"description": "Searches a repository and summarizes its project structure.",
"capabilityTags": ["software-development", "code-analysis"],
"authorizedDomains": ["software-development"],
"packageVersion": "1.2.0",
"packageHash": "sha256:example-package-hash",
"metadataHash": "sha256:example-metadata-hash",
"hashAlgorithm": "sha256",
"lifecycleState": "active",
"updatedAt": "2026-09-07T01:02:08Z"
}
A.3 ResourcePackage Schema
A ResourcePackage is a verifiable, distributable versioned object defined by the current public oan-package types. Its fields include packageVersion, resourceDid, resourceType, the complete didDocument, didDocumentHash, metadataHash, packageHash, hashAlgorithm, metadata, rootProof, and createdAt. A resource package has no generic top-level manifest, contentDigest, or resourceMetadata fields. If a specific resource requires a file manifest, it should be placed in an agreed extension field or external resource material, with the profile made explicit. Package digests currently cover the DID Document, resource metadata, and package declaration separately. The ResourcePackage version cannot replace the DID Document or resource version. Validation must be rejected when the resource DID, version, digest, metadata, or Root proof from the Root platform is missing; when digests do not match; or when resource types do not match.
{
"packageVersion": "1.2.0",
"resourceDid": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"resourceType": "skill",
"didDocument": {
"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/oan/v1"],
"id": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"verificationMethod": [{
"id": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu#key-1",
"type": "Ed25519VerificationKey2020",
"controller": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"publicKeyMultibase": "zExamplePublicKey"
}],
"authentication": ["did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu#key-1"],
"assertionMethod": ["did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu#key-1"],
"service": []
},
"didDocumentHash": "sha256:example-did-document-hash",
"metadataHash": "sha256:example-metadata-hash",
"packageHash": "sha256:example-package-hash",
"hashAlgorithm": "sha256",
"metadata": {
"resourceDid": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"resourceType": "skill",
"subjectType": "skill",
"name": "Repository analysis",
"description": "Searches a repository and summarizes its project structure.",
"capabilityTags": ["software-development", "code-analysis"],
"authorizedDomains": ["software-development"],
"lifecycleState": "active",
"packageVersion": "1.2.0",
"packageHash": "sha256:example-package-hash",
"metadataHash": "sha256:example-metadata-hash",
"hashAlgorithm": "sha256",
"updatedAt": "2026-09-07T01:02:08Z"
},
"rootProof": {
"rootDid": "did:oan:INRT:7YpQm9Kx2VnRb6Ts3WfHa4Cd5Ej8LgNz",
"packageClaims": {
"resourceDid": "did:oan:SKLG:5HkPq7Vm3RdT9Ya2WcX8Ns4Bf6GjLeZu",
"resourceType": "skill",
"version": "1.2.0",
"didDocumentHash": "sha256:example-did-document-hash",
"metadataHash": "sha256:example-metadata-hash",
"packageHash": "sha256:example-package-hash",
"hashAlgorithm": "sha256",
"lifecycleState": "active",
"authorizedDomains": ["software-development"]
}
},
"createdAt": "2026-09-07T01:02:08Z"
}
Publication validation is performed in the following order:
- Parse the package version, resource type, and required structure.
- Validate consistency among the resource DID, DID Document, metadata, and package declaration.
- Recalculate content digests according to the normalization rules.
- Verify the Root proof before entering the distribution or discovery process.
A.4 Root proof Schema
The Root platform trusted publication proof contains at least rootDid in the current public RootProof type and may contain bulletinEventHash, signature, packageClaims, proof, cryptoSuite, and hashAlgorithm. The resource DID, resource type, version, DID Document digest, metadata digest, package digest, lifecycle state, and authorized domains are primarily located in packageClaims, rather than being required as flat fields at the top level of the proof object. The issuer must be a Root platform identity currently authorized to perform Root platform publication. Verifiers should check the Root platform signature, claim scope, hash bindings, version relationships, bulletin event reference, and governance status, rather than checking only that JSON fields exist. When the proof is invalid, digests do not match, the issuer is unauthorized, or the target version has been revoked, the Discovery node must not treat the corresponding package as a currently valid resource.
| Field | Fact proven | Verification focus |
|---|---|---|
rootDid |
Which Root platform identity formed the proof | Root platform DID Document and authorization status |
resourceDid |
The corresponding resource | Consistency with the package and DID Document |
packageClaims.packageHash |
The specific published content | Equal to the resource package digest |
packageClaims.version |
The resource package version | Consistent with packageVersion |
bulletinEventHash |
The corresponding Root platform bulletin event | Bulletin chain and event order are verifiable |
proof/signature |
Claim integrity | Suite, signature input, and issuer public key |
A.5 Registration VC Schema
The public response for a registration VC uses the W3C-style type, issuer, issuanceDate, credentialSubject, credentialStatus, and proof to express the registration fact issued by the Registrar node. The public Rust credential model also provides internal structures in the forms of subject, status, issuedAt, expiresAt, and claims; the two forms must not be mixed within the same profile. The registration VC currently returned by the official Registrar node uses claims such as credentialSubject.resourceDid, resourceType, didDocumentHash, metadataHash, packageHash, packageVersion, hashAlgorithm, authorizedDomains, and lifecycleState. It proves that the Registrar node accepted the registration request and issued a registration credential; it does not automatically prove that the Root platform has published the resource or that the resource endpoint is available. Verification fails when the issuer, target DID, claim bindings, or proof is missing. When a VC is empty, expired, revoked, or has an unknown status, callers should distinguish among incomplete, invalid, and temporarily indeterminate states.
{
"@context": ["https://www.w3.org/2018/credentials/v1", "https://openagenet.org/credentials/v1"],
"type": ["VerifiableCredential", "OANResourceRegistrationCredential"],
"issuer": "did:oan:INRG:RegistrarExample",
"issuanceDate": "2026-09-07T00:00:00Z",
"credentialSubject": {
"id": "did:oan:SKDM:ExampleResourceDid",
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"didDocumentHash": "sha256:example-did-document-hash",
"metadataHash": "sha256:example-metadata-hash",
"packageHash": "sha256:example-package-hash",
"packageVersion": "1.2.0",
"hashAlgorithm": "sha256",
"authorizedDomains": ["software-development"],
"lifecycleState": "active"
},
"credentialStatus": {
"type": "OANResourceRegistrationStatus",
"status": "active"
},
"proof": { "type": "DataIntegrityProof", "proofValue": "..." }
}
A registration VC proves that the Registrar node accepted the registration and issued a registration credential. A resource can be used as a network-wide discoverable resource only when both the Root platform publication proof and the Discovery node index status meet the requirements.
A.6 Node Authorization VC Schema
In the public credential model, a node authorization VC expresses node eligibility through credential_type, issuer, subject, role, status, issuedAt, optional expiresAt, claims, and proof. After JSON serialization, the field names are respectively type, issuer, subject, role, status, issuedAt, expiresAt, claims, and proof. Authorized domains and capability scope are normally located in claims, rather than being fixed flat fields. Role values should be consistent with the node-role enumeration and deployment profile. Authorized domains and capability scope should use comparable structured values. Verifiers must check the credential signature, governance status, and current validity period together; the existence of a historical VC must not cause suspension or revocation events to be ignored. The credentialSubject, validFrom, and other fields below are provided only as display-layer compatibility examples; when using the public credential model, the fields above should be used.
{
"type": "NodeAuthorizationCredential",
"issuer": "did:oan:INRT:RootPlatformExample",
"subject": "did:oan:INDS:DiscoveryNodeExample",
"role": "discovery",
"status": "active",
"issuedAt": "2026-09-01T00:00:00Z",
"expiresAt": "2027-09-01T00:00:00Z",
"claims": {
"authorizedDomains": ["software-development"],
"capabilities": ["query", "index", "serve_public_results"]
},
"proof": { "type": "DataIntegrityProof", "proofValue": "..." }
}
A.7 Governance Event Schema
The public bulletin model for governance events consists of Bulletin, BulletinEvent, and BulletinEventCore. The event core fields are sequence, previousHash, eventType, subjectDid, actorDid, payload, and createdAt. The event body additionally contains eventHash and signature, as well as the optional proof, cryptoSuite, and hashAlgorithm. Current event types include Root platform initialization, content distribution platform information updates, authorization/revocation of Registrar nodes, authorization/domain updates/revocation of Discovery nodes, node revocation, and capability-tag tree updates. An off-chain projection may additionally record receipt time, projection time, a cursor, and errors, but these are not public core fields of BulletinEvent. The original on-chain or bulletin-chain event is the source of truth; page display text and projection status are derived information. When an event lacks a sequence, previous hash, signature, or target subject, or when projection order is discontinuous, authorization status must not be silently updated. The anomaly should be retained until the missing events are filled.
{
"sequence": 1842,
"previousHash": "sha256:example-previous-event-hash",
"eventType": "DISCOVERY_NODE_AUTHORIZED",
"subjectDid": "did:oan:INDS:DiscoveryNodeExample",
"actorDid": "did:oan:INRT:RootPlatformExample",
"payload": { "authorizedDomains": ["software-development"] },
"createdAt": "2026-09-07T01:02:03Z",
"eventHash": "sha256:example-event-hash",
"signature": "zExampleSignature",
"cryptoSuite": "ed25519-sha256",
"hashAlgorithm": "sha256"
}
A.8 Registration Request and Response Schema
The current official Registrar node browser/client entry point is POST /resources/register. The request is deserialized as ResourceRegistrationSubmission and contains resourceDid, resourceType, didDocument, didDocumentHash, metadata, packageVersion, packageHash, metadataHash, hashAlgorithm, nullable registrationCredential, and subjectControlProof. Only when forwarding to the Root platform internally does the node wrap the request with registrarDid and upstreamAuth, using POST /root/resources/verify-and-publish. Therefore, the internal forwarding package must not be treated as a public registration request. The response usually contains status, resourceDid, resourceType, registrationCredential, and rootResponse; different deployments may add status or correlation identifiers. Whether retries with the same DID, version, and digests are fully idempotent depends on the node storage and Root platform implementation. A valid registration must not be written when the control proof is missing, fields are incomplete, or the previous version does not match.
POST /resources/register
Content-Type: application/json
{
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"didDocument": {},
"didDocumentHash": "sha256:example-did-document-hash",
"metadata": {
"resourceType": "skill"
},
"packageVersion": "1.2.0",
"packageHash": "sha256:example-package-hash",
"metadataHash": "sha256:example-metadata-hash",
"hashAlgorithm": "sha256",
"registrationCredential": null,
"subjectControlProof": {
"challenge": {},
"proof": {}
}
}
| Situation | Response status | Handling |
|---|---|---|
| Validation passes and upstream processing completes | 2xx |
Return the registration result, registration VC, and Root platform response |
| Request body cannot be deserialized or shape validation fails | 400 |
Correct the DID, digests, control proof, or required fields |
| Upstream Root platform rejects the request | Node-specific mapping | Handle according to the returned error code; do not treat failure as registered |
| Network failure or upstream temporarily unavailable | 5xx or connection error |
Query by request DID, version, and digests before deciding whether to retry |
A.9 Discovery Request and Response Schema
The fields of the public ResourceDiscoveryQuery are optional query, resourceType, capabilityTags, protocol, and version, together with versionMode and limit, which have default values. Exact queries by complete DID, structured-condition queries, tag queries, and natural-language queries are ways for the node to use these fields; they are not separate core queryType fields. Pagination and freshness fields may appear in a node read model or an extended profile. The public ResourceDiscoveryResponse contains the Discovery node DID, a candidate array, a creation time, and an optional response proof. A candidate contains the resource DID, resource type, score, version, lifecycle, capability tags, authorized domains, services, protocol bindings, resource package information, and a reference to the Root proof. Index time, source descriptions, and query explanations are node- or official-website-derived display information. Semantic scores cannot replace trusted evidence. Unknown conditions, invalid DIDs, expired cursors, or unavailable query services should return identifiable errors rather than hiding failure behind an empty result.
{
"query": "I need a tool that can search code repositories and summarize the project structure.",
"resourceType": "tool_api",
"capabilityTags": ["code-analysis", "repository-search"],
"protocol": "https",
"versionMode": "latest",
"limit": 20
}
{
"discoveryDid": "did:oan:INDS:DiscoveryNodeExample",
"candidates": [{
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"score": 0.94,
"version": "1.2.0",
"lifecycleState": "active",
"capabilityTags": ["code-analysis", "repository-search"],
"authorizedDomains": ["software-development"],
"services": [],
"protocolBindings": [],
"packageInfo": { "packageHash": "sha256:example-package-hash" },
"rootProof": { "rootDid": "did:oan:INRT:ExampleRootDid" }
}],
"createdAt": "2026-09-07T01:02:08Z",
"proof": null
}
A.10 Error Response Schema
The current public error structure of nodes is based on { "error": "machine_readable_error_code" }; a trusted-call rejection may also include reason. Future or specific gateways may extend this to an object containing a message, a correlation request identifier, and retry guidance, but these are not fields currently guaranteed by all nodes. Error codes should distinguish input errors, signature/credential errors, unauthorized access, not found, duplicates, version conflicts, unavailable dependencies, synchronization lag, and internal errors. Public-facing messages must not disclose private keys, databases, or internal configuration. Clients receiving an unknown error code should handle it as a failure rather than defaulting to success.
{
"error": "sync_stale",
"reason": "discovery_index_behind_publication"
}
If a gateway uses an extended error object, the client should first determine whether error is a string or an object, and then read optional fields. It must not assume an object shape or treat the HTTP status code alone as the business error code. The Registrar node currently maps some upstream errors to its own HTTP error responses; callers should retain both the HTTP status and the response body.
A.11 Node Authorization and Governance Status Schema
Node authorization status and governance status are usually formed as read-side projections by an off-chain trust indexer or a node status interface. They are not equivalent to the NodeAuthorizationCredential or the bulletin event body. A projection may contain the node DID, node role, authorized domains, current status, status reason, validity period, most recent governance event, event sequence, synchronization cursor, data time, and freshness. The specific fields are governed by the corresponding interface. Status values should at minimum distinguish active, suspended, revoked, expired, unknown, and syncing. When the governance source is missing or the indexer is behind, an active status must not be fabricated. For sensitive write actions, use a reject or manual-confirmation policy when the status is unknown or exceeds the freshness permitted by the deployment. A display interface may separately mark the delay.
| Status | Permitted read-only uses | Effect on write or authorization operations |
|---|---|---|
active |
May be displayed and enter normal validation | Allowed within the capability scope |
suspended |
May display historical status | Reject new sensitive operations |
revoked |
Retain only for audit and historical references | Reject all operations requiring current authorization |
expired |
May indicate that authorization has expired | Must not be used as the basis for current authorization |
unknown/syncing |
May display only the uncertain status | Wait for confirmation; do not allow sensitive operations |
A.12 Distribution Manifest and Synchronization Cursor Schema
The current public structures on the distribution side fall into two categories. A content distribution platform index response uses items, count, afterCursor, nextCursor, and hasMore, with each item containing cursor and a complete ResourcePackage. A batch notification sent by the Root platform to a Discovery node uses a batch identifier, Root platform DID, target Discovery node DID, authorized domains, a sequence range, items, a content distribution platform manifest address, an update address, and proof. An item additionally carries the resource DID, operation, resource package version, DID Document digest, metadata digest, package digest, hash algorithm, lifecycle state, bulletin sequence, and bulletin event hash. Manifest version, generation time, error, or confirmation fields may be added by a specific interface; fields from one interface must not be applied directly to another. Cursors must advance monotonically, repeated batches must be safely replayable, and processing of an item must be paused when there is a sequence gap or digest mismatch. A cursor is transmission progress; it does not mean that the resource has already been indexed by the Discovery node.
{
"items": [{
"cursor": 1842,
"package": {
"packageVersion": "1.2.0",
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"didDocument": { "id": "did:oan:SKDM:ExampleResourceDid" },
"didDocumentHash": "sha256:example-did-document-hash",
"metadataHash": "sha256:example-metadata-hash",
"packageHash": "sha256:example-package-hash",
"hashAlgorithm": "sha256",
"metadata": {
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"subjectType": "skill",
"name": "Repository analysis",
"lifecycleState": "active",
"packageVersion": "1.2.0",
"packageHash": "sha256:example-package-hash",
"metadataHash": "sha256:example-metadata-hash",
"hashAlgorithm": "sha256",
"updatedAt": "2026-09-07T01:02:08Z"
},
"rootProof": { "rootDid": "did:oan:INRT:ExampleRootDid" },
"createdAt": "2026-09-07T01:02:08Z"
}
}],
"count": 1,
"afterCursor": 1800,
"nextCursor": 1842,
"hasMore": false
}
The minimum-shape example for a Root platform notification item is:
{
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"resourceType": "skill",
"operation": "upsert",
"packageVersion": "1.2.0",
"didDocumentHash": "sha256:example-did-document-hash",
"metadataHash": "sha256:example-metadata-hash",
"packageHash": "sha256:example-package-hash",
"hashAlgorithm": "sha256",
"lifecycleState": "active",
"bulletinSequence": 1842,
"bulletinEventHash": "sha256:example-event-hash",
"capabilityTags": ["software-development"],
"authorizedDomains": ["software-development"]
}
Manifest/notification -> validate digest, proof, sequence, and authorization domain -> confirm transfer progress -> create or update the discovery index
A.13 Search Explanation and Evidence Schema
Search explanations should state the query type, parsed conditions, matched capability tags or use cases, structured filters, relevance score, result source, version, resource status, index time, Root proof, and freshness. An explanation is derived information that helps callers understand the result; it cannot serve as signature or authorization evidence. When fields are missing, the semantic-model version is incompatible, or the source cannot be verified, the result should be explicitly marked as unknown or incomplete rather than supplemented with speculative reasons.
| Explanation layer | Content that may be expressed | Evidence it cannot replace |
|---|---|---|
| Query parsing | Query type, normalized conditions, tags, and use-case matches | Resource control |
| Relevance | Score, matched fields, and reason for ordering | Root platform publication proof |
| Source | Discovery node, index time, and index version | Current node authorization status |
| Trust status | VC, Root proof, governance status, and freshness | Guarantee of actual invocation results |
{
"queryExplanation": {
"queryType": "semantic",
"normalizedIntent": "repository structure summarization",
"matchedTags": ["code-analysis", "repository-search"],
"filtersApplied": { "resourceTypes": ["skill", "tool_api"] },
"modelVersion": "semantic-index-v1"
},
"evidence": {
"resourceDid": "did:oan:SKDM:ExampleResourceDid",
"rootPublication": "verified",
"governance": "active",
"indexedAt": "2026-09-07T01:02:08Z",
"freshness": "current"
}
}
References
| Source | Type | Link |
|---|---|---|
oan-protocol-common |
Code repository: normative data structures and schemas | https://github.com/wolfbrother/oan-protocol-common |
oan-sdk-ts |
Code repository: TypeScript data types and client validation | https://github.com/OpenAgenet/oan-sdk-ts |
did:oan DID Method Specification |
Standard/method specification: DID Documents and identifier data structures | https://github.com/OpenAgenet/oan-public-docs/blob/main/did-oan-specs/doc/OAN DID Method Specification.md |
| OAN Resource Identity and Discovery | IETF draft: resource identity data structures | https://datatracker.ietf.org/doc/draft-xu-oan-resource-identity-discovery/ |