11. Discovery Protocol and Query Semantics
This chapter explains how a discovery service node processes exact DID queries, structured queries, tag queries, text queries, and semantic queries from a local index that has been verified and filtered by the applicable authorization scope. It covers query input, version selection, provenance and freshness, result deduplication, pagination, explanations, errors, and degradation boundaries. A discovery response is explicitly a candidate result produced from a node’s index; the caller must still perform pre-invocation verification based on the DID, credentials, root platform trusted publication proof, governance status, and endpoint information.
11.1 Discovery Objectives and Query Types
A discovery service node provides five query paths for resources that have entered its local index: exact lookup by a complete resource DID; structured queries by resource type, version, protocol, and capability tags; tag queries by capability tags; text or natural-language queries based on resource names, descriptions, tags, use cases, and protocol materials; and combined queries that join natural-language and structured conditions. Query results are derived responses from the discovery service node rather than the root platform’s publication records. The response should retain the resource DID, resource type, version, lifecycle state, provenance, and necessary verification references.
The current reference implementation accepts a unified query object through POST /discovery/resources/query. When the query text is a complete, whitespace-free did:oan: identifier, it enters the exact DID branch; other text and explicit fields enter structured, lexical, or semantic paths. The query node constructs candidates only from locally indexed material. It must not directly forward the query to a registration service node or the root platform to manufacture a temporary result.
Before retrieval begins, query input should pass boundary validation and then be converted into an internal query object. resourceType, capabilityTags, protocol, and version form explicit conditions; versionMode specifies the version selection method; limit restricts the response size; and query carries a DID or a text/natural-language query. When text and structured fields are supplied in the same request, text performs recall and ranking while structured fields narrow the candidate set. The two kinds of conditions must not override each other.
{
"query": "I need a tool that can search code repositories and summarize the project structure.",
"resourceType": "tool_api",
"capabilityTags": ["code-repository"],
"protocol": "MCP",
"versionMode": "latest",
"limit": 10
}
The query text, tags, protocol, and limit in the example illustrate a combination of fields. The actual resource types and tags must follow the protocol values accepted by the target discovery service node. The score in a response candidate is a query-relevance result, not a resource trust level.
11.1.1 Exact DID Discovery
A complete resource DID must be interpreted as an exact lookup condition. It must not degrade into a name, prefix, or semantic-similarity search. The node should read the local index object corresponding to the DID and continue checking explicit conditions, lifecycle state, and the node’s authorization scope.
11.1.2 Structured-Condition Discovery
Fields such as resource type, version, protocol, and capability tags should be converted into reviewable filter conditions. Multiple explicit conditions use intersection semantics by default. An invalid enumeration, an unresolvable version mode, or an unsupported protocol value should produce a clear request error.
11.1.3 Capability-Tag Discovery
Capability-tag queries use capabilityTags in the resource metadata. Parent-child relationships, aliases, and extension tags in the tag tree may participate in the query projection, but the original tags and their sources must be retained. A tag match does not represent control or invocation authorization.
11.1.4 Text and Semantic Discovery
Text and natural-language queries may use lexical retrieval, vector retrieval, or a hybrid of both. When the semantic index is unavailable, the node may fall back to lexical and structured paths, but the query explanation or diagnostic information should state which backend was actually used.
11.1.5 Combined-Condition Discovery
A combined query should first apply authorization-scope, lifecycle, and explicit structured-condition filters, and then rank the remaining candidates lexically or semantically. Relevance must not remove hard filters or allow unpublished or unauthorized resources to enter a trusted result.
11.2 Exact DID Queries
An exact query first validates the DID method syntax and resource-type semantics, and then reads the resource package from the local index. A hit must use the DID document, metadata, endpoint, hash, and root platform proof reference for the same resource version. A miss must not be interpreted simply as proof that the resource does not exist on the entire network, because it may not yet have propagated to this node or may have been filtered by the authorization scope. The node should distinguish the following results:
| Result | Explanation | Caller handling |
|---|---|---|
| Candidate returned | This node has a visible indexed object that satisfies the conditions | Continue verifying the DID, proof, and endpoint |
| Empty candidates | The resource does not exist here, has not been indexed, or is outside this node’s authorization scope | Do not infer that it does not exist network-wide |
| Suspended/revoked | The indexed object exists, but its current state restricts use | Do not invoke it as a currently valid resource |
| Service error | The database, index, or governance read model is temporarily unavailable | Retry or degrade according to temporary-failure handling |
The current exact-query implementation identifies a DID through the query field and passes the remaining explicit conditions to resource-type, version, capability-tag, and protocol matching. Therefore, a query containing a DID may still return empty candidates when its version or authorization-scope conditions are not satisfied. An exact hit only means that the discovery service node has a visible index record. The caller must still obtain the complete DID document and proof materials for pre-invocation verification.
The result boundary of an exact DID query can be checked using the following table. Here, “not found” means the result under the current index and authorization scope of this node; it is not a statement about the state of the Internet of Agents.
| Query stage | Object to check | Meaning of the result |
|---|---|---|
| Input identification | Whether query is a complete did:oan: string |
Determines whether the exact path or the ordinary retrieval path is used |
| Index read | Whether this node has an indexed resource-package record | Reflects only whether this node has stored the record |
| Condition matching | Explicit conditions such as version, resource type, protocol, and capability tags | Any unsatisfied hard condition can produce empty candidates |
| Visibility check | This node’s authorization scope and the resource lifecycle | An invisible, suspended, or revoked resource must not be returned as an ordinary candidate |
| Pre-invocation decision | DID document, registration credential, root platform trusted publication proof, and endpoint | Performed by the caller; not replaced by score or an index hit |
11.3 Structured Resource Queries
A structured query maps fields in the request to database or in-memory filter conditions. The current reference implementation filters by resource lifecycle, resource type, version, capability tags, and protocol. For an ordinary query without an explicit resource type, it uses a default scope oriented toward resources intended for user consumption. Explicit capability tags require the resource to contain all requested tags. A protocol condition requires the resource service endpoint or protocol binding to declare or explain that protocol. An empty query with structured conditions may be executed, while a query with no conditions at all should be constrained by result count and resource scope limits.
After filtering, results still pass the node’s authorization-scope check and latest-valid-version selection. Display names, descriptions, and retrieval scores are index fields; they are not evidence of identity, publication, or governance.
Explicit filters should be applied before candidates enter relevance ranking. The current implementation performs resource-level matching for resourceType, version, capabilityTags, and protocol. Capability tags use intersection matching against the requested set; a protocol may match through a protocol binding or a service endpoint declaration. A missing field is not automatically a wildcard, and an unresolvable request value must not be silently converted into another condition.
Structured filtering must be reviewable: request fields, resource fields, and the decision should correspond item by item. For example, if a request specifies both resourceType = "mcp_server" and capabilityTags = ["file.search", "desktop.automation"], a candidate must first be of the requested resource type and contain both tags before it participates in text-relevance ranking. A candidate that is semantically close to “file search” but has the wrong resource type must not enter the result through ranking. If a field is absent from the resource package, that condition should be treated as unsatisfied rather than as an arbitrary match.
For unknown enumerations, blank fields, duplicate tags, and conflicting version conditions, the node should define deterministic handling during request parsing. Duplicate tags may first be normalized into one condition; an unknown resource type or an unresolvable version mode should be a request error; and a conflict between version and lifecycle should narrow the result under version-selection and state rules rather than be relaxed by the retrieval score.
11.4 Capability-Tag Queries
Capability tags are declarations by a resource provider that classify the resource’s capabilities. The root platform capability-tag tree provides governance context for tag identifiers, hierarchy, aliases, and versions. A discovery node may project aliases in a query to canonical tags or maintain local retrieval aliases, but the response should retain the resource’s original tags and the tags that actually matched. Whether a parent tag covers a child tag and whether an extension tag enters the trusted index must be defined by the tag-tree version and node configuration, not implicitly determined by model relevance.
A tag query should distinguish three kinds of information: the resource’s original capabilityTags; the retrieval terms produced by expanding aliases in query text or explicit parameters; and the tags ultimately used to explain the match. Alias expansion can improve recall, but it must not modify the resource’s original declaration. If an extension tag is not supported by the current node’s tag tree or configuration, it should be treated as an ordinary miss rather than inferred to be a parent tag or synonym.
11.5 Text and Semantic Queries
Semantic queries may retrieve public information such as resource names, descriptions, capability tags, use cases, protocol bindings, and resource types. The reference implementation may organize resource material into tag, context, and intent views, and combine vector, lexical, and structured scores to rank candidates. score expresses relevance to the current query and index snapshot; it does not express a trust level, service quality, or security level.
When the semantic index, embedding service, or pgvector is unavailable, the node may fall back to lexical and structured queries. Degradation must not relax authorization-scope, lifecycle, or explicit conditions. Empty text should not force a semantic backend call. Input that is too long, cannot be encoded, or uses an unsupported language should produce a clear error or an explainable degraded result.
The current semantic implementation projects resource type, protocol, capability tags, and query text into retrieval terms, and constructs search documents from public material such as resource names, descriptions, tags, context, examples, and use cases. When the semantic backend is available, results may combine BM25-like lexical scores, tag scores, context scores, intent scores, and structured scores. These internal scores are used for ranking and explanation and must not be treated by external callers as a governed quality assessment.
Text used to build a semantic index must come from resource description material that has already been made public. Index construction should retain the association among the resource DID, resource-package version, and semantic source content so that the corresponding index can be rebuilt after a resource update and old descriptions do not continue to produce highly relevant results. Multilingual queries may improve recall through normalization, aliases, or embedding models, but a model’s inferred capability must not be written back into resource metadata, and model similarity must not replace resource control, a registration credential, or the root platform trusted publication proof.
A discovery node should be able to distinguish the semantic backend, lexical path, and structured path through runtime logs or a diagnostic interface. For the same hard conditions, a semantic-service failure may change candidate recall and ranking quality only. If the index database, authorization-scope read model, or resource-package read fails, the failure must be handled as unavailable data or a service error rather than returning an apparently normal but incomplete empty result.
11.6 Combined Semantic and Structured-Condition Queries
A combined query can be abstracted into the following processing order:
visible = authorizedDomain AND active AND explicitFilters
ranked = rank(queryText, visible)
result = stableSort(ranked)[0:limit]
Here, explicitFilters includes resource type, version, protocol, and explicit capability tags; rank may use lexical, vector, or hybrid retrieval; and stableSort must retain a stable secondary key. If no resource satisfies the hard conditions, the node should return empty candidates rather than a “similar” resource that does not satisfy them.
An important boundary of combined queries is that semantic results must still pass resource-package validity, lifecycle, and authorization-scope checks at the node. A record in the semantic index does not mean that it is visible at the time of the query. For implicit natural-language requirements such as “latest”, “trusted”, or “callable”, the node may convert the portion that maps to protocol fields into structured conditions. A portion that cannot be mapped to fields may be used only as ranking or explanation information; it must not automatically produce an authorization conclusion.
A minimal reproducible example of combined-query processing is:
{
"query": "I need a tool that can search code repositories and summarize the project structure.",
"resourceType": "tool_api",
"protocol": "MCP",
"capabilityTags": ["code-repository"],
"versionMode": "latest",
"limit": 10
}
A qualifying result for this request must satisfy the resource type, protocol, and capability-tag conditions simultaneously. Natural language only supplements relevance judgments over names, descriptions, use cases, and related fields. If the query text expresses “trusted” or “callable”, the node may make the corresponding decision only when the relevant structured fields and verifiable facts exist. Otherwise, it should preserve the phrase as retrieval intent and leave the subsequent decision to the caller’s verification stage.
11.7 Authorization-Scope Filtering
A discovery node obtains its own authorization scope from its DID document or governance read model and compares it with authorizedDomains in resource metadata. The resource domain must be covered by a domain for which the node is authorized. A domain mismatch must keep the resource out of the query result. This filter determines discovery visibility provided by this node to the caller; it does not change the resource DID control relationship or mean that the resource is invisible at other discovery nodes. When governance status or node authorization cannot be confirmed, ordinary display should mark the result as not fresh, while sensitive queries and pre-invocation verification should apply restrictive handling.
11.8 Latest Valid Version Selection
By default, a query selects, for each resource DID, the latest version that satisfies the node’s authorization scope, has an active lifecycle state, has completed the necessary validation, and has a confirmable synchronization position. Version selection for the same DID should consider the resource-package version, root-platform publication cursor, package hash, predecessor relationship, and governance state. It must not rely only on update time or query arrival order. If a discovery node is behind, it may return a verified older version for limited display, but it must include freshness and synchronization position and must not claim that version to be the network latest.
Version selection must verify at least three conditions: the candidate belongs to the same resource DID; its version satisfies the requested versionMode and version conditions; and its lifecycle and governance state still allow discovery. For a latest query, the selected item is the latest currently verifiable valid version, not the record most recently written to the database. For a specified-version query, a missing version record, inconsistent hash, or unconfirmable state should produce an empty result or a clear data-unavailable error; it must not silently substitute another version.
A reproducible check can use two records with the same DID: record A has an earlier publication sequence but an active state, while record B has a later update time but is suspended. A conforming implementation should select record A or return a restricted result; it must not treat B as the latest valid version merely because its timestamp is newer. The check should also verify that repeated queries over the same index snapshot return the same resource DID, version, and state, while retaining the publication sequence, package hash, and state source as decision evidence.
11.9 Search Ranking and Deterministic Result Ordering
11.9.1 Matching Conditions
Matching conditions are the first basis for candidate ranking. Explicit conditions such as resource type, version, protocol, and capability tags are hard filters. Text matches in names, descriptions, use cases, and protocol materials are relevance signals. A candidate must satisfy explicit conditions before it participates in relevance ranking. A resource that is textually similar but has the wrong resource type or version must not enter the result.
11.9.2 Trust and Governance State
Only candidates with completed root-platform trusted publication, valid governance state, and confirmable node authorization may enter a trusted discoverable result. Trust and governance state are not ordinary features that merely increase a retrieval score; they determine whether the candidate is eligible to be returned. A candidate with unknown state, missing proof, or suspended or revoked status should be filtered out or returned with an explicit restricted state. High relevance must not conceal these conditions.
11.9.3 Version and Freshness
By default, only the current valid version of a resource DID is retained. When several candidates have similar relevance, the node should prefer the newer valid version whose publication sequence and governance state can both be confirmed. Freshness describes how far the index is from publication and governance facts; it must not be equated with retrieval relevance. An old snapshot may be used for limited display, but it must carry stale or an equivalent state.
11.9.4 Ranking Stability
Under the same index snapshot, authorization scope, and query conditions, ranking should produce repeatable results. Ranking first uses the actually enabled relevance combination and then uses a deterministic resource DID, version, publication sequence, or other stable key as a secondary key. The node should not use database natural order, concurrent completion order, or random perturbation as an implicit ranking rule; otherwise pagination and client-side deduplication cannot work reliably.
11.9.5 Duplicate-Result Handling
Resource-identity deduplication must occur either before or after ranking; duplicate synchronization records for the same DID must not occupy multiple result positions. Deduplication retains the current valid version, the newer publication sequence, and the record with more complete verifiable evidence, while retaining the source node and duplicate diagnostics. If duplicate records have conflicting hashes or governance states, they must enter exception handling rather than being arbitrarily selected as a trusted result.
11.10 Search Explanations and Evidence Display
11.10.1 Match Reasons
Match reasons should point, as far as possible, to observable fields such as capability-tag intersection, resource-type match, protocol match, text-field match, or natural-language intent match. An explanation may be a summary and need not expose the internal model or index implementation, but it must not invent a capability that the resource did not declare. When a query uses a lexical, vector, or hybrid path, the response should identify the actual path or at least state the determinacy boundary of the explanation.
11.10.2 Resource Provenance
The result should identify the discovery service node, index update time, resource source node or source reference, and available publication sequence and resource-package hash. Provenance fields trace where a fact was synchronized from; they do not mean that the source node guarantees the resource’s business quality. When the resource is obtained through a content distribution platform, the response should retain the reference relationship to the root platform publication material rather than recording only a cache address.
11.10.3 DID, VC, and Root Platform Proof
The resource DID identifies the resource; the DID document provides public keys, service endpoints, and resource metadata; the registration credential expresses the registration service node’s processing of a registration fact; and the root platform trusted publication proof expresses the root platform’s verifiable validation and publication fact for a particular resource version and its materials. A discovery response may return summaries or references to these pieces of evidence, but before connecting, the caller must obtain and verify the complete materials. No reference field alone constitutes completed verification.
Response fields should be understood in two layers: “index display” and “verifiable evidence”. resourceDid, resourceType, score, version, tags, and endpoints are candidate-display information. The DID document, registration credential, root platform trusted publication proof, and their signature materials are the basis for the caller’s verification of identity, control, and publication facts. A discovery node returning a candidate does not mean that it has performed endpoint connectivity testing, business compatibility assessment, or authorization on behalf of the caller.
11.10.4 Governance State and Version Information
The explanation area should display the resource lifecycle, resource version, publication sequence, governance state, and index freshness together, allowing the caller to distinguish “highly relevant” from “currently verifiable”. Governance state comes from a governance-event projection or another explicit fact source, while version information comes from the resource publication chain. When they conflict, the response should mark the conflict and apply restrictive handling; a newer display time must not override a revocation or suspension fact.
Search explanations should keep verifiable facts and retrieval inferences separate. matchReason, tag intersection, resource-type match, and protocol match are query explanations. The DID document, public key, registration credential, root platform trusted publication proof, publication sequence, and governance state are verification materials. The former answer “why did this appear in the result?”; the latter answer “which facts can the caller use for the next decision?” They must not be merged into one recommendation score.
11.11 Discovery Response Model
A discovery response should allow the caller to identify at least four things: which discovery service node processed the query, which resource DID corresponds to each candidate, which index state produced the candidate, and why the candidate was returned. A reference implementation response may contain top-level fields such as discoveryDid, candidates, createdAt, and proof. A candidate should include the resource DID, resource type, retrieval score, version, lifecycle state, capability tags, authorization domains, service endpoints, protocol bindings, resource-package information, and root platform proof reference. A deployment may add fields, but display fields must not be mistaken for proof fields.
{
"discoveryDid": "did:oan:...",
"createdAt": "2026-09-07T10:00:00Z",
"candidates": [
{
"resourceDid": "did:oan:...",
"resourceType": "skill",
"score": 0.87,
"version": "1.0.0",
"lifecycle": "active",
"capabilityTags": ["code-repository", "project-structure"],
"serviceEndpoints": ["https://example.invalid/endpoint"],
"protocolBindings": ["MCP"],
"rootProofRef": "...",
"freshness": {
"publicationSequence": 42,
"indexUpdatedAt": "2026-09-07T09:59:30Z"
}
}
]
}
proof or rootProofRef means only that the response or candidate refers to proof material. The caller must still obtain and verify the corresponding content according to Chapters 7 and 9. When a field is missing, the node should explicitly return “unavailable” or omit the field; it must not insert an unverified default value. Unknown extension fields should be safely ignorable by compatible clients, while core identity, state, and provenance fields must not be renamed in a way that changes their meaning.
The minimum response skeleton corresponding to the current protocol structure is discoveryDid, candidates, createdAt, and optional proof. In a candidate, resourceDid, resourceType, score, version, lifecycleState, capabilityTags, authorizedDomains, services, protocolBindings, packageInfo, and rootProof respectively provide display responsibilities for identity, retrieval, state, capability, scope, service, and proof references. The current interface may not return a separate matchReason or a complete freshness object. A client must not fill absent fields with facts that have supposedly been verified.
The current discovery-query entry point is POST /discovery/resources/query, and its request body corresponds to ResourceDiscoveryQuery. This type may contain query, resourceType, capabilityTags, protocol, version, versionMode, and limit; limit defaults to 10 and versionMode defaults to latest. The response corresponds to ResourceDiscoveryResponse, whose candidates use ResourceDiscoveryCandidate. The returned score is a relevance score, not an authorization or trust level.
POST /discovery/query/explain also accepts ResourceDiscoveryQuery, but returns dynamic explanation JSON, including matched resource DIDs, resource types, match flags, scores, tag overlap, resource-type and protocol match status, and semantic-search status. The explanation response is for diagnosing the retrieval process. It is not an ordinary discovery result and cannot replace verification that the resource control relationship or publication proof is valid.
Field names in the current public protocol should be treated as the compatibility baseline for clients. When a resource candidate uses fields such as lifecycleState, services, packageInfo, and rootProof, clients should treat optional information according to field presence. Fields such as lifecycle, serviceEndpoints, rootProofRef, or freshness in examples are illustrative extensions; they must not be used to claim that all current deployments return those names. New response fields should preserve the ability of older clients to ignore unknown fields and should describe the source and verification method of each fact.
11.12 Discovery-Result Freshness and State
The freshness of a discovery result is described jointly by the index update time, the processed publication cursor, the governance-event sequence, and the local error state, rather than by the HTTP response time alone. A response should provide, where possible, createdAt, index update time, publication sequence or synchronization cursor, governance-state read position, and source-node DID. The caller uses these values to determine whether the result is a current snapshot, an acceptable old snapshot, or a partially available result.
| State | Meaning | Permitted use |
|---|---|---|
| current | Necessary publication and governance-state synchronization is complete, with no known update gap | May proceed to pre-invocation verification |
| stale | A verifiable local snapshot remains, but publication or governance synchronization is behind the permitted range | Read-only reference with an explicit freshness mark; state must be reconfirmed before invocation |
| partial | Some resources or index shards are available, and the completeness scope has been reduced | Use only within the scope stated by the response; do not claim a full result set |
| unknown | Synchronization position, governance state, or proof freshness cannot be confirmed | Must not be used as a trusted basis for sensitive actions |
When version state and governance state conflict, restrictive states such as revocation, suspension, or loss of node authorization take precedence over relevance and time ordering. A discovery service node may retain historical snapshots to improve access during network failures, but it must mark the snapshot state explicitly and must not describe a cache hit as the network latest state.
State judgment for a discovery result should be based on local index material and its synchronization records. createdAt represents only the time when the response was generated; it is not the resource publication or index-application time. The publication cursor represents propagation position, the index update time represents processing time at this node, and the governance-event sequence represents the position of the governance read model. The caller must compare these sources and positions to determine whether the result may be behind.
An error response should allow the caller to distinguish a request error, a resource miss, a temporarily unavailable index, and a temporary backend failure. An invalid DID format, an unknown resource type, an unresolvable version mode, or an excessive query limit is a request-side error. A legal query with no visible candidate is an empty result. A database, semantic-index, governance-read-model, or upstream-synchronization failure is a service- or data-side error. The error should contain a machine-readable category, a request identifier, and necessary retry guidance, but should not disclose detailed information about restricted resources.
{
"error": {
"code": "INDEX_STALE",
"message": "The discovery index is temporarily behind the publication cursor.",
"requestId": "...",
"retryable": true
},
"freshness": {
"status": "stale",
"lastKnownPublicationSequence": 41
}
}
When the semantic backend is unavailable, the node may fall back to lexical and structured paths. The fallback changes ranking capability only; it must not relax resource type, lifecycle, authorization scope, version, or explicit tag conditions. If the base index itself is unavailable, the node must not use an empty array to pretend that there are “no resources”. It should return an identifiable service error or a partial result with an explicit scope. The client should retry based on retryable, backoff guidance, and its own request budget; the node must not amplify requests through automatic retries.
Error handling should preserve the boundary between “invalid request” and “data temporarily unavailable”. A format error, unknown enumeration, or excessive parameter must not cause the same request to be retried. A temporary semantic-backend failure may use lexical degradation under the same hard conditions. If the base index or governance state cannot be read, a partial result must state its scope and state explicitly. A discovery node may record query statistics and backend names for operations, but its public error must not disclose the existence of resources outside the authorization scope.
Error handling for the discovery interface should keep the response structure stable and allow clients to decide whether to correct the request, wait and retry, or stop using the result. The following boundary may be used:
| Error category | Typical cause | Client action |
|---|---|---|
| Invalid request | DID format, resource type, version mode, or limit is invalid |
Correct the request and issue it again; do not repeat the original request |
| No visible result | The conditions are valid, but this node has no candidate that both satisfies them and is visible | Adjust the query conditions if appropriate, but do not infer that the resource does not exist network-wide |
| Semantic degradation | The semantic index or embedding service is temporarily unavailable while the base index remains readable | Accept lexical/structured results and lower expectations for relevance |
| Index unavailable | The resource index, database, or necessary governance read model cannot be read | Handle as a service error, wait for recovery, or switch to a known node |
| Synchronization lag | The local publication cursor is behind or the snapshot is incomplete | Use only within the scope marked by the response and retry later if necessary |
Semantic degradation and base-index failure must be distinguished in implementation and operational observation. The former can usually still return candidates satisfying hard conditions, with reduced relevance-ranking capability. The latter cannot establish that the candidate set is complete or that visibility was correctly determined and must not be disguised as an ordinary empty result. Error logs may record the backend, latency, candidate count, and failure reason, while the public response should contain only the minimum information needed for client handling.
11.13 Discovery Errors and Degraded Responses
The fact that a resource is reachable through an HTTP endpoint means only that the endpoint is reachable for the current request. Entering a discovery index means that a discovery service node has stored a corresponding index record. Having a root platform trusted publication proof means that the root platform has formed a verifiable publication fact for a particular version and its materials. Passing pre-invocation verification additionally requires the caller to recheck the DID control relationship, proof, governance state, endpoint, and its own business policy. These are progressively stronger facts; no level automatically replaces another.
| Fact | Primary source | Conclusion that cannot be drawn |
|---|---|---|
| Endpoint is reachable | Resource service endpoint | The resource is registered or trustworthy |
| Entered a discovery index | Discovery service node index | The resource is network-latest or permitted for invocation |
| Has a root platform trusted publication proof | Root platform publication material | The business endpoint is necessarily available or suitable for a particular scenario |
| Passed pre-invocation verification | Caller and its verification components | The caller has obtained all business permissions |
A public discovery response may display the necessary DID, resource summary, endpoint, and proof reference. For a restricted resource, it should return only the minimum summary within the authorized scope. Before establishing a connection, the caller should obtain or verify the complete DID document, registration credential, root platform trusted publication proof, latest governance state, and endpoint declaration according to the risk of the resource.
Public visibility is jointly determined by the current authorization scope and index state of the discovery service node. A resource absent from public results may not yet be synchronized, may have been filtered, may be suspended, or may be affected by an unavailable index. An empty result alone cannot establish that the resource does not exist. When the caller needs a deterministic conclusion, it should use an exact DID query, read state information, and perform complete pre-invocation verification instead of inferring a hidden inventory from tag enumeration or paginated results.
Visibility involves at least three independent questions: whether the resource has been registered, whether it has propagated to this node, and whether the current caller can see it. A discovery service node can answer only from locally verifiable index material and authorization scope. Therefore, “candidate returned” means that the resource has a discovery record within the visible scope of the current node, while “not returned” means only that the current query did not produce a visible candidate. For sensitive resources, success, empty results, and permission filtering must not reveal additional information through error codes, field counts, or response latency.
Trusted discoverability also requires the candidate to have a DID document, registration credential, or root platform trusted publication proof reference corresponding to the current version, with no known suspension, revocation, or authorization-loss state. The discovery node provides an index and an evidence entry point. Whether the caller accepts the resource also depends on its own risk policy and its verification of control, proof validity, endpoint security, and business authorization.
11.14 Public Visibility and Trusted Discoverability
11.15.1 DID-Level Deduplication
Within one query response, the same resource DID should normally have only one representative record. The representative should be a current valid version with a newer publication sequence, while retaining a traceable source node, root platform proof reference, and synchronization position. If governance states conflict between records, the response should retain conflict diagnostics and use a restrictive state; arbitrary ordering must not hide the conflict.
11.15.2 Version-Level Deduplication
Different valid versions of the same DID should be returned together only when the query explicitly requests historical versions or specifies a version constraint. A default query returns the current valid version. A historical query should include the version identifier, predecessor version, and publication sequence so that the client cannot mistake a historical record for the current version. The same version identifier with different package hashes is a consistency anomaly; the records should not be merged and should enter diagnostic or quarantine handling.
11.15.3 Duplicate Records from Registration Nodes
Repeated submission of the same resource to one or more registration service nodes must not create multiple resource identities. A discovery node should deduplicate according to the root platform publication fact, resource DID, version, and package hash. A registration service node’s local acceptance record may be retained for source auditing, but it must not by itself create a public candidate. Whether a repeated submission causes a new registration credential to be issued is a registration-protocol behavior and does not change discovery-side resource-identity rules.
11.15.4 Handling Identical Content with Different DIDs
Records with the same content, name, or endpoint but different DIDs remain different resource identities and must not be merged solely because their content hashes match. A node may indicate content similarity or a shared package hash in an explanation field, but it must display each control relationship, registration state, version, and root platform proof separately. Whether the same content may be represented by multiple DIDs is determined by the resource controller and governance rules.
The primary deduplication key is the complete resource DID. Records from multiple registration service nodes, content distribution platforms, or synchronization batches are normally the same resource identity when they point to the same resource DID. If records also contain versions, the resource DID and version identify the version. Package hashes, root-platform publication sequences, and source nodes are used to confirm content consistency and retain evidence; records must not be incorrectly merged merely because they have the same name or similar descriptions.
A deduplication decision should retain the “basis for merging” and the source of each discarded record so that the reason a candidate appears only once can be explained. A default query may use the following priority when selecting a representative record: first exclude records with restricted lifecycle states, mismatched authorization scopes, or unverifiable proofs; then compare the requested version mode and publication sequence; finally use package hash, source node, and deterministic DID order to resolve ties. This priority only constructs the discovery result. It does not change the original acceptance records of a registration service node or delete historical audit material.
| Record relationship | Discovery-result handling | Evidence that must be retained |
|---|---|---|
| Same DID, same version, same package hash | Merge into one candidate | Source nodes and synchronization batches |
| Same DID, different versions | Select or return separately according to versionMode |
Version, publication sequence, and predecessor relationship |
| Same DID, same version, different package hashes | Do not automatically merge into a trusted record | Conflicting hashes, sources, and diagnostic state |
| Different DIDs, identical content | Return as different resources | Each DID, control relationship, and proof |
Deduplication must occur before pagination. Otherwise, duplicate records for the same resource consume multiple result positions and cause omissions when the client merges pages. Historical-version queries are an exception: they may return multiple versions of the same DID, but every version must carry an explicit version and state so that the client cannot mistake a historical candidate for the current valid version.
11.15 Result Deduplication and Resource-Identity Matching
A node should limit query-text length, the number of structured conditions, the number of results returned per request, and semantic-retrieval resource consumption. limit must be validated against a server-side maximum; a client must not bypass the limit through repeated requests or abnormal parameters. An invalid, expired, or query-mismatched cursor should produce a clear error rather than silently returning the first page, so that the client does not mistake an incomplete pagination result for a complete one.
Within one index snapshot, pagination must use the same filtering, deduplication, and ranking rules. Ranking should include at least the retrieval score and a deterministic resource DID or other stable key. It must not use a random value per request, undefined database natural order, or unstable concurrent completion order. If the snapshot changes during pagination, the response should communicate this through a snapshot identifier, cursor invalidation, or freshness field so that cross-snapshot duplicates or omissions are not mistaken for a protocol error.
| Situation | Recommended handling |
|---|---|
Results are fewer than limit |
Return all visible candidates that satisfy the conditions and indicate that no more results are available |
| Results reach the limit | Return a stable pagination cursor and current snapshot information |
| Query exceeds length or resource budget | Return a non-retryable request error |
| Cursor cannot be parsed or does not match the query | Return a cursor error and require the client to start the query again |
| Index updates during pagination | Continue using the original snapshot or explicitly invalidate the cursor |
Pagination solves only transport and display scale. It does not change authorization scope or trusted-discoverability decisions. When merging pages, a client should use resource DID and version as deduplication keys and retain the source and snapshot information for each page.
11.16 Query Limits, Pagination, and Result Stability
Authorization-scope filtering must be completed before results are returned, rather than returning candidates first and relying on the client to hide them. For resources outside the requester’s or node’s authorization scope, the node must not disclose their existence through names, tags, endpoints, proof references, or error differences. A management interface that needs to distinguish insufficient permission from a missing resource may provide more detailed reasons to an authorized administrator. A public query should by default return only the minimum necessary fields of resources that are published, discoverable, and within this node’s service domain.
Index material should be classified by field sensitivity. Resource DID, resource type, and a public capability summary may enter public results. Private endpoints, internal tags, sensitive configuration other than the control public key, the submitter’s private identity information, and unpublished proof material must not be exposed through semantic indexing. Vector indexes, lexical indexes, and query logs must follow the same authorization boundary; a retrieval backend’s need for text does not justify copying content that should not be public.
Query logs should minimize storage of original natural-language input, caller identifiers, and filter conditions, and should use the deployment’s privacy policy to define retention, access control, and redaction. A requester must not infer the complete inventory of restricted resources by enumerating DIDs, tag combinations, pagination cursors, or error responses. During propagation of authorization-scope changes, resource revocation, or node suspension, the discovery node should restrict visibility first and retain the state source and processing time for audit.
This flow expresses the order of processing responsibilities: input validation and hard filtering precede relevance ranking; version selection and deduplication precede pagination; and provenance, proof, and freshness are returned with the response. Use of a semantic backend provides ranking capability and must not change the preceding identity, authorization, or lifecycle decisions. Every degradation path must state which validations it completed and which validations it did not complete.
| Check item | Conformance criterion |
|---|---|
| DID query | A complete resource DID uses the exact path and does not degrade into fuzzy search |
| Structured filtering | Resource type, version, protocol, capability tags, and lifecycle conditions use explicit intersection semantics |
| Authorization scope | Unauthorized resources do not appear in public results; an unknown scope state is handled restrictively |
| Relevance explanation | The retrieval score expresses relevance only and is not called a trust level or invocation permission |
| Version selection | The default returns the current valid version; historical-version queries do not confuse historical state with current state |
| Deduplication | The same DID does not create duplicate candidates through multi-node synchronization or repeated registration |
| Response provenance | The result can point to the discovery service node, index state, publication sequence, and proof reference |
| Freshness | Old snapshots, partial results, and unknown governance state are explicitly marked |
| Error degradation | Semantic-backend failure does not relax hard conditions, and base-index failure is not disguised as an empty result |
| Pagination stability | Ordering is stable within one snapshot, and the cursor is bound to the query and snapshot |
| Privacy boundary | Queries, indexes, and error responses do not disclose sensitive information about resources outside the authorization scope |
| Pre-invocation verification | The discovery result is only candidate input; the caller re-verifies identity, proof, and business permissions |
11.17 Discovery Privacy and Authorization-Scope Visibility
Authorization scope is the boundary of discovery visibility, not a substitute for resource control or invocation permission. A discovery service node should first determine whether a candidate is visible by comparing the node’s authorized service domains with authorizedDomains in the resource package, and then perform structured and semantic processing only over visible candidates. If the resource and node domains do not intersect, the candidate must be filtered before the public response. A caller must not infer detailed information about a filtered resource from its name, tags, endpoint, result count, or error differences.
Indexing and display should follow minimum disclosure. A public candidate may provide the resource DID, resource type, public capability tags, necessary service endpoints, version, and proof references. Control private keys, the registrant’s local identity backup, internal governance materials, unauthorized endpoints, and configuration outside the public resource package must not enter the index or query response. Text, tag aliases, and vector representations used by semantic indexing inherit the authorization boundary of the original fields; entering a retrieval backend must not expand visibility.
While authorization scope, lifecycle, or governance state is synchronizing and the local node cannot confirm the latest state, public visibility should be restricted. For management and audit purposes, a controlled interface may record the filtering reason, source node, governance-event sequence, and processing time. For ordinary discovery requests, it should return only a uniform result that does not disclose the existence of a restricted resource. Query logs should also be retained according to minimum-necessary principles, with limits on access to and retention of the original natural-language input, caller information, and query conditions.
| Information category | May enter a public discovery result | Handling requirement |
|---|---|---|
| Resource identity | Resource DID and resource type | Bind to the currently visible version |
| Capability description | Public capability tags, name, and summary | Must not expand into a capability the resource did not declare |
| Service information | Service endpoints and protocol bindings within the authorized scope | The endpoint must still be verified before invocation |
| Trust material | Necessary reference to the root platform trusted publication proof | Do not treat a reference as completed verification |
| Private material | Private keys, local identity backup, internal configuration, and unpublished proof | Must not enter public indexes, responses, or error details |
References
| Source | Type | Link |
|---|---|---|
oan-discovery-node |
Code repository: synchronization, indexing, structured queries, and semantic queries | https://github.com/OpenAgenet/oan-discovery-node |
oan-protocol-common |
Code repository: discovery request, response, and query types | https://github.com/wolfbrother/oan-protocol-common |
oan-sdk-ts |
Code repository: discovery client and query-result handling | https://github.com/OpenAgenet/oan-sdk-ts |
| GRAIL Semantic Discovery Paper | arXiv paper: hybrid semantic retrieval and discovery explanations | https://arxiv.org/abs/2605.02489 |
| Efficient Agent Discovery Profile | IETF draft: agent-discovery metadata and query configuration | https://datatracker.ietf.org/doc/draft-xu-efficient-agent-discovery-profile/ |