Chio/Docs

Capability Discovery

Discovery in chio is layered. A tool server registers a signed manifest with one kernel; that registration is local. A marketplace surface in chio-listing publishes the operator's signed listing and pricing hint so other operators can search by scope, price, and freshness. There is no global registry; cross-org reach is driven by bilateral federation. The protocols below are honest about what is shipped today and what is planned.

Registration With a Kernel

Tool servers join a kernel by presenting a SignedManifest. The kernel validates the structure, verifies the Ed25519 signature against a registered public key, and registers the tools (see Signed Tool Manifests).

  • Registration is per-kernel and out-of-band. The operator decides which servers to admit through configuration or a control-plane API.
  • The manifest is the source of truth for tool schemas, side-effect flags, latency hints, required permissions, and advertised pricing.
  • Updates require a fresh signed manifest. There is no partial-update path.

Marketplace Listing Surface

Beyond kernel-local registration, chio ships a marketplace listing layer in the chio-listing crate. Operators publish signed listings into a generic registry; a sidecar ListingPricingHint attaches price and SLA without coupling to listing publication.

Generic Listing

The base record is a GenericListing with schema chio.registry.listing.v1. Each listing has a status (Active, Suspended, Superseded, Revoked, Retired), an actor kind (ToolServer, CredentialIssuer, CredentialVerifier, LiabilityProvider), and an explicit GenericListingBoundary that defaults to:

chio-listing/src/registry.rs
GenericListingBoundary {
    visibility_only: true,
    explicit_trust_activation_required: true,
    automatic_trust_admission: false,
}

The boundary is enforced by the listing crate's validate: a listing that drops these guarantees is rejected. The marketplace is visibility-only; it never auto-admits trust.

Signed Pricing Hint

The pricing hint attaches price-per-call, SLA, recent receipt volume, and revocation rate to a published listing. It is signed by the provider's key, not the registry owner's, so listing publication and pricing can rotate independently.

chio-listing/src/discovery.rs
pub struct ListingPricingHint {
    pub schema: String, // chio.marketplace.listing-pricing-hint.v1
    pub listing_id: String,
    pub namespace: String,
    pub provider_operator_id: String,
    pub capability_scope: String,
    pub price_per_call: MonetaryAmount,
    pub sla: ListingSla,
    pub revocation_rate_bps: u32,
    pub recent_receipts_volume: u64,
    pub issued_at: u64,
    pub expires_at: u64,
}

Searching Listings

The search entry point is chio_listing::discovery::search. It takes a slice of GenericListingReport replicas, a slice of SignedListingPricingHint, a ListingQuery, and the current time. It returns a signed ListingSearchResponse.

chio-listing/src/discovery.rs
pub struct ListingQuery {
    pub capability_scope_prefix: Option<String>,
    pub namespace: Option<String>,
    pub actor_kind: Option<GenericListingActorKind>,
    pub max_price_per_call: Option<MonetaryAmount>,
    pub provider_operator_id: Option<String>,
    pub require_fresh: bool, // defaults to true
    pub limit: Option<usize>,
}

Filtering rules from the shipped function:

  • Listings without a matching, signed, non-expired pricing hint are dropped.
  • Listings whose pricing hint fails validate() or signature verification are dropped; the error is recorded in ListingSearchResponse.errors.
  • When max_price_per_call is set, listings with a different currency or higher price are dropped.
  • When require_fresh is true (the default), listings whose freshness is Stale or Divergent are dropped.
  • The default actor kind filter is ToolServer.
  • Limit defaults to 100 and is clamped to MAX_MARKETPLACE_SEARCH_LIMIT (which equals MAX_GENERIC_LISTING_LIMIT = 200).

The signed response carries one row per surviving listing, in rank order, plus any errors that surfaced while verifying hints. Each row pairs the signed listing, the verified pricing hint, the publisher, and the freshness record. A normalization helper compare projects a set of Listing entries into a ListingComparison with a price index in basis points so callers see relative cost at a glance.


Search by Dimension

The shipped query dimensions cover the operational basics.

DimensionFieldNotes
Capability scopecapability_scope_prefixLiteral prefix match against the hint's declared scope, e.g. tools:search:.
NamespacenamespaceSame normalization as GenericListingQuery.
Actor kindactor_kindDefaults to ToolServer; can also filter to issuers, verifiers, or liability providers.
Price ceilingmax_price_per_callCurrency-strict; mismatched currencies fall out.
Providerprovider_operator_idMatch on hint and listing publisher together.
Freshnessrequire_freshWhen true, drops Stale and Divergent listings.

Jurisdiction is not a built-in filter

The shipped query does not have a jurisdiction field. Operators encode regulatory scope through the listing namespace and the policy reference attached to the underlying trust scope. A jurisdictional filter typically lives a layer up, in the operator's own catalog UI, on top of these primitives.

Reputation Aggregation Across Listings

The pricing hint carries two reputation-adjacent signals directly: revocation_rate_bps (rolling rate over recent invocations in basis points) and recent_receipts_volume (count of receipts in the recent window). Together they let a caller filter on operator activity without contacting any third party.

  • A listing whose hint advertises high recent volume and a low revocation rate is operationally healthy.
  • A listing with zero recent receipts but a long-lived hint is a quiet operator; the caller may still admit it but with smaller initial budget.
  • Native reputation projections (see Reputation) feed back into how an operator decides to trust a listing in practice.

Revocation rate and receipt volume are operator-attested, signed by the provider's key. They are not third-party verified scores; they are claims an auditor can compare against the issuing operator's receipt log.


Federation Discovery

Cross-org reach is peer-to-peer through pinned bilateral federation peers (see Bilateral Federation). There is no central directory linking operators.

  • Per-pair listings: a peer can publish listings into the other's registry replica through normal generic-listing publication, subject to the bilateral FederationImportControl.
  • Visibility-only by default: imported listings stay visibility-only until the operator explicitly activates them. Discovery does not silently widen runtime authority.
  • No transitive pull: a listing from Org A's peer Org B does not become visible to Org A's peer Org C just because B and C are also peers. Each pair carries its own evidence.

The activation surface is FederationActivationExchangeArtifact, which bundles a listing reference, a trust scope, delegation controls, and import controls. The trust control plane stores and signs this artifact when an operator approves a partner listing for local use.

rendering…
Tool server registers a signed manifest with its kernel. The operator publishes a signed listing and pricing hint. A peer operator imports the listing through a bilateral federation activation exchange and may activate it after manual review.

Discovery From the CLI

The shipped CLI exposes the listing search surface through the evidence and trust subcommands. A typical query for tool servers within a price ceiling:

listing-search.sh
$ chio --json listing search \
    --capability-scope-prefix "tools:search:" \
    --max-price-per-call '{"units":50,"currency":"USD"}' \
    --require-fresh true \
    --limit 25 \
    --reports ./registry-replicas/*.json \
    --pricing-hints ./pricing-hints/*.json

# Output: ListingSearchResponse with one row per surviving listing,
# plus errors[] for any hints that failed signature verification.

For comparing a small set of listings side by side, the normalizing helper produces a price-indexed comparison:

listing-compare.sh
$ chio --json listing compare \
    --listings ./candidates.json \
    --now $(date +%s)

# Output: ListingComparison with rows[].price_index_bps where
# 10_000 means "equal to the row with the lowest price_per_call
# in the same currency".

Future Direction: Capability Marketplace

The shipped surface gives operators a search-and-compare layer over signed listings. The roadmap document docs/protocols/FUTURE-MOATS-AND-RESEARCH.md section 7 sketches a fuller capability marketplace built on the same primitives. Quoted from the roadmap (medium-term, not yet shipped):

  • Discovery and bidding endpoints: POST /marketplace/discover for scope+price+QoS+reputation queries, POST /marketplace/bid for auction-priced listings.
  • Pricing model expansions: per-call, metered, auction, subscription, and free-tier variants beyond the four currently in chio.manifest.v1.
  • Receipt-based settlement lifecycle: aggregate receipts during a billing period, settle through chio-settle, dispute via Merkle proofs against specific receipts.
  • Quality-of-service on the listing: a richer QualityOfService struct alongside the current ListingSla, and a ProviderReputation summary derived from receipt history.

Honest about shipped vs roadmap

The marketplace as described in section 7 of the moats document is roadmap, not current behavior. The crates it builds on (chio-listing, chio-market, chio-metering, chio-settle, chio-manifest) all ship today. The discovery and bidding protocol layered on top is the new work.

Failure Modes

  • Pricing hint signature invalid: listing is dropped from the result and the verification error is recorded in ListingSearchResponse.errors.
  • Stale hint: hint expires_at has passed; the listing falls out of the marketplace until a fresh hint is published.
  • Currency mismatch: a price ceiling in USD against an EUR-priced hint is dropped silently from the result; callers should issue a separate query in the other currency or rely on cross-currency conversion at the consuming layer.
  • Divergent freshness: replica disagreement between mirrors triggers a Divergent freshness state. With require_fresh = true, such listings drop out.
  • Listing status not Active:Suspended, Superseded, Revoked, or Retired listings do not surface in marketplace results.

Capability Discovery · Chio Docs