Capability Advertisement¶
Capability Advertisement is the Node-facing solution contract for communicating
what a peer can do right now, together with the passport-form evidence needed to
evaluate those claims without a Seed Directory lookup.
It is not a component. It is a protocol artifact and read-side presentation boundary used by Nodes, Seed Directories, and future discovery or routing surfaces.
Purpose¶
The artifact answers:
What capabilities does this Node present now, under which capability ids, wire-visible names, assertion kinds, and credentials?
It deliberately separates two layers:
capabilities/presented— the passport-form assertions and credentials,capabilities/core— the compatibility and routing projection derived from presented capabilities.
The projection is useful for fast matching. The presented passport assertions are the verification input.
Scope¶
This solution document covers:
- direct Node-to-Node capability exchange after handshake,
- datagram-style or broadcast capability publication where a transport permits it,
- responses to explicit capability queries,
- Seed Directory registration payloads that include the Node's capability advertisement,
- and custom or sovereign capabilities using the passport capability-id namespace.
It does not define:
- capability-specific wire protocols,
- federation recommendation policy,
- revocation transport beyond using passport and revocation artifacts,
- implementation-local host capabilities such as
recovery.signorcatalog.local.query.
Contract¶
Based on:
doc/project/40-proposals/014-node-transport-and-discovery-mvp.mddoc/project/40-proposals/024-capability-passports-and-network-ledger-delegation.mddoc/project/40-proposals/025-seed-directory-as-capability-catalog.mddoc/project/50-requirements/requirements-006-node-networking-mvp.mddoc/project/60-solutions/CAPABILITY-REGISTRY.md
Related schemas:
capability-advertisement.v1capability-schema.v1capability-schema-present.v1capability-passport.v1capability-passport-revocation.v1node-advertisement.v1peer-handshake.v1
Implementation Stratification¶
The implementation should keep the same layered boundary as the protocol model:
| Layer | Responsibility |
|---|---|
| Protocol | wire structs, validation, deterministic signing input, and message-kind constants |
| Capability | presented-capability assembly, core projection, sovereign capability-id parsing, and capability_id -> wire/name mapping |
| Signer | node-self signing through HostSigner under node.capability-advertisement.v1 |
| Network | encode/decode, schema-gated ingress/egress, Ed25519 sign/verify, and freshness checks |
| Schema store | resolving schema/ref to capability-schema.v1 artifacts |
| Daemon | orchestration, local advertisement build, schema-present request handling, cache replacement, and lifecycle triggers |
Layer direction is strict. The protocol layer treats passport bodies as opaque JSON; typed parsing, passport semantics, revocation, and local authority policy belong above the wire-contract layer.
Required Semantics¶
Passport-Form Presentation¶
Every capability advertisement must carry capabilities/presented.
Each presented capability carries at least:
capability/idwire/nameassertion/kindpassport
The passport field is the credential to verify. It may be a full
capability-passport.v1 or a profile-compatible passport assertion accepted by
the relevant capability profile.
Receivers must verify the presented credential under:
- the capability profile,
- issuer or self-issued assertion rules,
- revocation state,
- and local policy.
Routing Projection¶
capabilities/core is retained as a projection for compatibility and routing.
It should be derivable from:
capabilities/presented[*].wire/name
It must not be treated as the authoritative trust proof.
Messaging Accept Advertisement¶
Nodes that accept inbound messaging publish messaging.accept with wire name
app/messaging.accept only while the supervised messaging service is enabled
and the inbound message-envelope.v1 acceptor is ready. The advertisement is a
read-side routing signal, not the receive consent itself.
The advertised profile is tied to the canonical messaging-receive@v1 receive
passport profile. It declares the route kinds that may receive messages and the
default delivery privacy of private-direct. Contact Catalog lookup consumers
may use messaging.accept to filter candidate nodes before sending a
contact-request.v1, but receivers still verify the presented
messaging-receive passport and local contacts policy at admission time.
Assertion Kinds¶
The first assertion kinds are:
self-issued-passportissuer-passportfederation-endorsed-passport
self-issued-passport is sufficient for baseline protocol capabilities such as
core/messaging when local policy accepts self-issued claims.
issuer-passport is used when a capability profile requires another signer,
for example a sovereign operator or other accepted authority.
federation-endorsed-passport is used when the presented passport also carries
or references federation policy or endorsement material. The endorsement is a
policy input, not a replacement for the passport signature.
Custom Capabilities¶
Custom capabilities should not invent unscoped global names.
They should use the same namespace as capability-passport.v1, including
identity-anchored forms such as:
audio-transcription@participant:did:key:z...for an anchored compatibility claim that carriescapability/profile.compatible_with,~audio-transcription@participant:did:key:z...for an anchored custom protocol that does not claim a global formal meaning foraudio-transcription.
Their wire-visible projection uses:
sovereign/...
with anchor reconstruction rules defined by the capability registry and Seed Directory proposal.
The leading ~ remains in the canonical capability/id; it is not projected
into a separate wire prefix. A sovereign id without ~ is a compatibility
claim and should carry capability/profile.compatible_with. A sovereign id with
~ is a custom protocol/scheme and should carry its own schema/ref.
UI Presentation¶
Human-facing UI should display a capability by a short readable name, not by the
full capability/id string.
For identity-anchored custom capabilities, the UI should visibly mark that the shown name is scoped or sovereign and make the full identifier available through a link, copy action, pop-up hint, or detail drawer. The long identifier remains the protocol identity of the capability; the short name is only the display label.
Capability Profile Metadata¶
A presented capability may include profile metadata for human display and machine negotiation:
{
"capability/profile": {
"display/name": "Audio transcription",
"description": "Transcribes audio input into timestamped text segments.",
"lang": "en",
"doc/ref": "orbiplex:blob:sha256:...",
"doc/url": "https://example.org/capabilities/audio-transcription",
"schema/id": "urn:orbiplex:capability-profile:audio-transcription:v1",
"schema/ref": "orbiplex:blob:sha256:...",
"schema/media-type": "application/schema+json"
}
}
capability/profile is metadata. It helps UI, negotiation, validation, and
operator inspection, but it does not replace capability/id, passport
verification, revocation checks, or local policy.
The same metadata may also appear inside capability-passport.v1 as
capability_profile. When present in the passport, it is part of the signed
passport payload. When copied into capability-advertisement.v1, it is a
presentation summary.
doc/url is only a convenience mirror for humans. It must not be required for
protocol operation.
Capability Schema Artifacts¶
Machine-readable capability schemas are represented as capability-schema.v1
artifacts.
The stable identity of the contract is:
schema/id
The fetchable content-addressed reference is:
schema/ref
The schema/ref should use an Orbiplex content address such as:
orbiplex:blob:sha256:...
Receivers must treat schema/ref as the integrity anchor. A schema payload
fetched from any peer, cache, Seed Directory, or archivist surface is usable only
after its canonical content hashes to the advertised reference.
The first shape is:
{
"schema": "capability-schema.v1",
"schema/id": "urn:orbiplex:capability-profile:audio-transcription:v1",
"schema/ref": "orbiplex:blob:sha256:...",
"schema/media-type": "application/schema+json",
"capability/id": "~audio-transcription@participant:did:key:z...",
"wire/name": "sovereign/audio-transcription",
"display/name": "Audio transcription",
"description": "Transcribes audio input into timestamped text segments.",
"lang": "en",
"doc/ref": "orbiplex:blob:sha256:...",
"content": {
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:orbiplex:capability-profile:audio-transcription:v1"
},
"published-at": "2026-04-12T10:00:00Z",
"author/node-id": "node:did:key:z...",
"author/participant-id": "participant:did:key:z...",
"signature": {
"alg": "ed25519",
"value": "..."
}
}
The schema artifact may describe:
scopeshape,- request input shape,
- response output shape,
- expected error classes,
- retry and idempotency semantics,
- resource or artifact references used by the capability.
Peer Message Kinds¶
Capability schema retrieval uses the existing authenticated Node-to-Node peer message envelope. It does not require an HTTP URL.
Well-known message kinds:
| Message kind | Direction | Payload |
|---|---|---|
capability.schema.present.request |
requester -> provider | asks for one capability schema by schema/ref and optionally schema/id |
capability.schema.present.response |
provider -> requester | returns one capability-schema-present.v1 payload containing a capability-schema.v1 artifact or an error object |
Request payload:
{
"schema/ref": "orbiplex:blob:sha256:...",
"schema/id": "urn:orbiplex:capability-profile:audio-transcription:v1",
"accepted/media-types": [
"application/schema+json"
]
}
Response payload:
{
"schema": "capability-schema-present.v1",
"status": "ok",
"artifact": {
"schema": "capability-schema.v1"
}
}
Error payload:
{
"schema": "capability-schema-present.v1",
"status": "error",
"error": {
"kind": "schema-unavailable",
"detail": "local node cannot present requested capability schema"
}
}
Receivers should verify:
- the peer session identity,
- the response correlation id at the peer-message envelope layer,
- the
capability-schema.v1signature when present, - the content hash implied by
schema/ref, - and local policy for the capability profile.
Signing and Wire Invariants¶
Capability advertisements are node-self artifacts. They are signed by the Node identity through the generic host signer, using the domain tag:
node.capability-advertisement.v1
The signed bytes are the deterministic signing input for
capability-advertisement.v1: the signature-stripped payload encoded in the
canonical form used by the protocol crate, prefixed with the
capability-advertisement.v1 domain separator. Nested passports are included in
that signed payload.
The following invariants are mandatory:
capabilities/coreis derivable fromcapabilities/presented[*].wire/name; it is never an independent authority source.core/messagingis present in bothcapabilities/coreandcapabilities/presented.node/idin the advertisement matches the node-self signer identity.published-atis checked against the ingress freshness window defined by the networking requirements.- Formal non-sovereign
capability/idvalues must be registered and eligible incapability-registry.v1; unregistered or ineligible formal ids are rejected fail-closed. Sovereign/custom ids remain locally policy-gated. schema/refis an integrity anchor; fetched schema content is hash-verified before use.- The
capability_id -> wire/namemapping mirrors the capability registry.
Node Responsibilities¶
A Node that emits capability-advertisement.v1 should:
- sign the advertisement with its Node identity,
- include a current
published-at, - include transport profiles currently exposed,
- include
core/messagingas the minimal baseline wire projection, - include a matching
capabilities/presentedentry forcore/messaging, - avoid advertising capabilities not currently routable or usable,
- keep
capabilities/coresynchronized withcapabilities/presented, - include enough passport material for the receiver to evaluate the claim without a Seed Directory lookup,
- serve any advertised
schema/refit can resolve throughcapability.schema.present.request, unless local policy intentionally withholds that schema.
Receiver Responsibilities¶
A receiver should:
- validate the advertisement signature and freshness,
- treat
capabilities/coreas routing projection only, - verify each relevant presented passport assertion before trusting it,
- apply local policy to decide whether self-issued, issuer-issued, or federation-endorsed assertions are acceptable,
- check revocation state for passport-backed capabilities when the profile requires revocation awareness,
- and tolerate unknown capability ids by ignoring or quarantining them rather than failing the entire peer relationship.
Seed Directory Relationship¶
Seed Directory publication is optional for communicating capabilities.
The solution-level Seed Directory responsibilities are defined in
doc/project/60-solutions/031-seed-directory/031-seed-directory.md.
The same capability advertisement may be:
- exchanged directly after handshake,
- returned in response to a peer capability query,
- broadcast where the transport profile permits it,
- or embedded in
PUT /capregistration payloads.
The Seed Directory indexes capabilities it accepts under its own policy. It is a discovery and caching surface, not the only authority that makes a capability claim visible.
Hard-MVP Implementation Status¶
The Node implementation covers the hard-MVP baseline exchange:
- local advertisement assembly from passport-backed presented capabilities,
- routing projection derivation,
- HostSigner-backed node-self signing,
- schema-gated ingress and egress,
- outer signature verification,
- ingress freshness checks,
- schema-present request handling,
- monotonic cache replacement for peer advertisements,
- and Capability Registry-backed fail-closed admission for unregistered or ineligible advertised capability ids.
This is the done boundary for the hard-MVP Capability Advertisement solution:
receivers no longer treat loose capability labels as authority, advertisement
ingress and egress stay schema-gated, and Proposal 072 / Solution 037 supplies
the registry-backed fail-closed behavior for unregistered or ineligible formal
capability ids.
Post-MVP Hardening Edges¶
The following edges are intentionally deferred hardening, not blockers for the
hard-MVP done status:
- Per-passport ingress verification. The outer advertisement signature verifies the transport artifact. Each embedded passport still needs typed verification, delegated issuer proof handling when present, revocation checks, capability-profile authority checks, and receiver-local policy. The hard-MVP registry gate rejects unregistered or ineligible formal ids; richer passport quarantine and authority policy remain the next trust-policy layer.
- Pluggable schema store. The current daemon-local schema lookup is a
minimum store. A future store should key by
schema/ref, optionally index byschema/id, and leave hash verification to the consumer so the store remains a dumb cache. - Lifecycle-driven rebuilds. Rebuild and re-sign on startup, relevant transport/config changes, newly accepted or removed passports, revocations invalidating presented passports, and delegated signer rotation that changes inline issuer-delegation proofs. Startup and local advertisement refresh are covered by the current runtime; passport/revocation/signer-rotation-triggered rebuilds are post-MVP lifecycle hardening.
- Reusable outbound schema retrieval. The inbound
capability.schema.present.requestpath exists; reusable client-side request/correlation/hash-verification helpers should be factored when a second caller needs them. - Seed Directory reconciliation. Direct peer advertisements remain the live
presentation. Seed Directory
PUT /capandGET /capflows are indexing and discovery surfaces, not trust anchors. The current registry-backed admission rule comes from Proposal 072 / Solution 037; later Seed Directory reconciliation must preserve the same local verification model rather than treating directory presence as trust.
Consumes¶
capability-passport.v1capability-schema.v1capability-schema-present.v1capability-passport-revocation.v1peer-handshake.v1node-advertisement.v1
Produces¶
capability-advertisement.v1capability-schema.v1capability-schema-present.v1
Notes¶
This solution keeps the core small:
- capability identifiers live in the passport namespace,
- advertisements provide the live presentation,
- Seed Directory provides optional indexing,
- and consumers retain local policy authority over trust.