EconomyTools
Capability Discovery
How a signed tool manifest becomes a searchable, priced listing and reaches other organizations through bilateral federation.
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 specifies 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 listings
Beyond kernel-local registration, the implementation provides marketplace listing types 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 GenericListingArtifact 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:
impl Default for GenericListingBoundary {
fn default() -> Self {
Self {
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. Marketplace listings remain visibility-only until local trust activation.
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. Its schema is chio.marketplace.listing-pricing-hint.v1 (LISTING_PRICING_HINT_SCHEMA).
pub struct ListingPricingHint {
pub schema: String,
/// Listing this hint applies to.
pub listing_id: String,
/// Namespace of the listing (must match the listing body).
pub namespace: String,
/// Provider / operator advertising the price (must match the listing
/// publisher).
pub provider_operator_id: String,
/// Capability scope prefix covered by this hint (e.g.
/// `"tools:search"` or `"tools:search:*"`). Queries filter against this.
pub capability_scope: String,
/// Fixed price charged per invocation under the advertised scope.
pub price_per_call: MonetaryAmount,
/// Advertised SLA for invocations under this hint.
pub sla: ListingSla,
/// Rolling revocation rate over recent invocations, in basis points.
/// `0` means "no revocations in the window"; `10_000` means "100%".
pub revocation_rate_bps: u32,
/// Number of receipts the provider has produced in the recent window.
pub recent_receipts_volume: u64,
/// Unix seconds when the hint was issued.
pub issued_at: u64,
/// Unix seconds when the hint expires. Past expiry, the hint is stale
/// and the listing falls out of the marketplace.
pub expires_at: u64,
}Local trust activation
A visible listing requires a GenericTrustActivationArtifact (schema chio.registry.trust-activation.v1). It is the single-operator admission-review mechanism. Cross-organization activation uses FederationActivationExchangeArtifact used between federated peers.
Each activation carries a GenericTrustAdmissionClass (PublicUntrusted, Reviewable, BondBacked, RoleGated), a GenericTrustActivationDisposition (PendingReview, Approved, Denied), a GenericTrustActivationEligibility block (allowed actor kinds, publisher roles, statuses, bond-backing and freshness constraints), and a review context pinning the publisher and replica freshness at review time.
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.
pub struct ListingQuery {
/// Capability scope prefix to match against the hint's
/// `capability_scope`. Matching is a literal prefix match after trim.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub capability_scope_prefix: Option<String>,
/// Namespace filter. Same normalization as [`GenericListingQuery`].
#[serde(default, skip_serializing_if = "Option::is_none")]
pub namespace: Option<String>,
/// Actor-kind filter. Defaults to `ToolServer` when unset.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub actor_kind: Option<GenericListingActorKind>,
/// Only return listings whose price per call is less than or equal to
/// this ceiling. Currency must match; listings with differing currency
/// are filtered out.
#[serde(default, skip_serializing_if = "Option::is_none")]
pub max_price_per_call: Option<MonetaryAmount>,
/// Require a specific provider operator id (matches hint and publisher).
#[serde(default, skip_serializing_if = "Option::is_none")]
pub provider_operator_id: Option<String>,
/// Require fresh listings only. When set to `true` any stale/divergent
/// listing is rejected. Defaults to `true`.
#[serde(default = "default_require_fresh")]
pub require_fresh: bool,
/// Maximum number of results to return.
#[serde(default, skip_serializing_if = "Option::is_none")]
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 inListingSearchResponse.errors. - When
max_price_per_callis set, listings with a different currency or higher price are dropped. - When
require_freshis true (the default), listings whose freshness isStaleorDivergentare dropped. - The default actor kind filter is
ToolServer. - Limit defaults to 100 and is clamped to
MAX_MARKETPLACE_SEARCH_LIMIT(which equalsMAX_GENERIC_LISTING_LIMIT= 200).
The signed response carries one row per surviving listing, in rank order, plus errors from 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.
| Dimension | Field | Notes |
|---|---|---|
| Capability scope | capability_scope_prefix | Literal prefix match against the hint's declared scope, e.g. tools:search:. |
| Namespace | namespace | Same normalization as GenericListingQuery. |
| Actor kind | actor_kind | Defaults to ToolServer; can also filter to issuers, verifiers, or liability providers. |
| Price ceiling | max_price_per_call | Currency-strict; mismatched currencies fall out. |
| Provider | provider_operator_id | Match on hint and listing publisher together. |
| Freshness | require_fresh | When true, drops Stale and Divergent listings. |
Jurisdiction is not a built-in filter
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) inform how an operator decides whether to trust a listing.
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 record is FederationActivationExchangeArtifact, which bundles a listing reference, a trust scope, delegation controls, and import controls. The trust control plane stores and signs this record when an operator approves a partner listing for local use.
Accessing search
There is no chio listing subcommand. The search and compare functions are reached in two ways: in-process by calling chio_listing::discovery::search and chio_listing::discovery::compare directly against local replicas and pricing hints, or over HTTP through the trust-control public registry endpoint.
The network endpoint GET /v1/public/registry/listings/search takes a GenericListingQuery as query parameters and returns a signed GenericListingReport:
$ curl "$REGISTRY_URL/v1/public/registry/listings/search?actorKind=tool_server&namespace=tools.search&limit=25"
# Returns a signed GenericListingReport of the surviving listings for
# the query. The public endpoint filters on listing metadata only:
# namespace, actorKind, actorId, status, limit. The query type renames
# to camelCase, so a snake_case parameter is simply not read.The richer, pricing-hint-joined filtering described above ( capability-scope prefix, price ceiling, currency-strict matching, and the freshness gate) lives in the in-process search function, which pairs each listing with its verified SignedListingPricingHint before ranking. compare normalizes a set of Listing entries into a ListingComparison with a basis-point price index so callers see relative cost at a glance.
Open-market economics and abuse enforcement
Listings make capabilities discoverable; the chio-open-market crate defines the economics and abuse enforcement that sit on top of a decentralized marketplace. It is the top of the economic stack: fee schedules, bond requirements, and penalty enforcement for a namespace of listings.
An OpenMarketFeeScheduleArtifact is a signed fee schedule scoped to a namespace, defining four charge types: a publication_fee, a dispute_fee, a market_participation_fee, and a list of bond_requirements (per-bond-class collateral amounts, each with a configurable slashable flag).
Misbehavior is penalized through an OpenMarketPenaltyArtifact carrying an OpenMarketAbuseClass ( SpamPublication, FraudulentListing, ReplayPublication, or UnverifiableListingBehavior) with explicit bond actions (HoldBond, SlashBond, ReverseSlash). The pure function evaluate_open_market_penalty gates enforcement behind nine validation conditions before any bond is touched:
- Each signed record (listing, fee schedule, charter, governance case, activation, penalty) has a valid signature.
- Namespace consistency across those records.
- Operator authority consistency.
- Fee-schedule scope matching (operator ids, actor kinds, admission classes).
- Temporal validity: fee schedule, charter, case, and penalty are not expired.
- Bond-requirement matching for the penalty's bond class.
- Governance case-kind validity: sanctions require an enforced sanction case; reverse-slash requires an appeal case.
- Prior-penalty validity for reverse-slash operations.
- Currency and amount coherence.
Enforcement is not self-contained: the crate integrates with chio-governance for charter-based authority scoping and case management. Sanctions and appeals flow through the governance layer before an economic penalty is enforced.
Capability marketplace bidding
Search and compare are the read side of the marketplace. The write side, turning a listing into a purchased, time-bounded capability, is the bid, ask and accept protocol in chio-open-market's bidding module. It is a library interface: a caller links the crate and passes signed records in memory.
A BidRequest (schema chio.marketplace.bid-request.v1) is an agent's signed offer to buy a capability under a published listing. bid() resolves the listing through chio_listing::search, applies the discovered pricing hint, mints a scoped CapabilityToken, and returns a signed AskResponse (chio.marketplace.ask-response.v1) whose token_offer binds the ask to the quote. accept() signs an AcceptedBid (chio.marketplace.accepted-bid.v1) against a VerifiedReservationReceipt, a funds reservation (chio.marketplace.reservation-receipt.v1) whose signature is checked against the expected reservation authority before acceptance, so a settlement layer can verify the canonical bid/ask/accept triple.
pub fn bid(
request: &SignedBidRequest,
context: BidMintContext<'_>,
) -> Result<SignedAskResponse, BiddingError>;
pub fn accept(
ask: &SignedAskResponse,
reservation: &VerifiedReservationReceipt,
acceptor_keypair: &Keypair,
accepted_at: u64,
) -> Result<SignedAcceptedBid, BiddingError>;bid() refuses to mint when the resolved listing is not Active (revoked, retired, suspended, superseded), when its pricing hint is stale past expires_at, or when its freshness window has elapsed. It rejects a bid whose currency does not match the advertised pricing, whose ceiling is below the quoted price, whose requested scope falls outside the listing's capability scope, or whose listing, pricing, or issuer authority is not bound to the same provider. The BiddingError enum enumerates each refusal. The protocol carries sixteen integration tests plus an in-crate unit-test module.
Where the bidding protocol runs
chio subcommand, so a deployment that wants it over the network carries its own transport and decides for itself what the wire looks like.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_athas 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
Divergentfreshness state. Withrequire_fresh = true, such listings drop out. - Listing status not Active:
Suspended,Superseded,Revoked, orRetiredlistings do not surface in marketplace results.
Related
- Signed Tool Manifests defines the manifest referenced by each listing.
- Pricing Models covers the price block on the manifest and the listing.
- Bilateral Federation covers the per-pair contract that controls cross-org listing import.