Hanzo

Skills

Skills — reached at /.well-known/agent-skills/; not in the public REST contract.

Skills ships in every Hanzo cloud. It carries no operations in the public API document, so it has no generated REST reference — it is reached another way.

Reached at/.well-known/agent-skills/ — the Agent Skills discovery convention, GET-only
In the public contractno — see below

Why there is no reference here

This reference is generated from the public API document, one page per operation. This capability contributes no operation to that document — which is a fact about its door, not about whether it is finished. It is GA and it runs in every deployment. It is reached at /.well-known/agent-skills/ — the Agent Skills discovery convention, GET-only.

Specification

HIP-1322 · Skills — The Discovery Catalogue — Draft · read the specification →

/.well-known/agent-skills/ is the catalogue an AI client reads to learn what this deployment can do. It is implemented in hanzoai/cloud at apps/skills (HIP-0106) and serves two public GET routes from a catalogue embedded in the one cloud binary.

This HIP states why the catalogue is generated rather than authored (§2), which brand a request is answered for (§3), and why these two routes sit at the root rather than under /v1 (§4).

Motivation

An agent that must be told what a platform offers is an agent someone has to keep telling. The discovery convention answers that once, at a fixed address, in a document the agent can fetch before it holds any credential.

The catalogue's danger is not that it is missing but that it is confidently wrong. A skill document is read as live instruction: it tells an agent an address answers and what to send there. An authored catalogue drifts from the router the moment either moves, and drift here does not degrade gracefully — it hands an agent an address that 404s and a reason to keep trying.

Specification

The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted as in RFC 2119.

§1 The surface

Two routes, public, GET only:

RouteAnswer
GET /.well-known/agent-skills/index.jsonthe brand's master catalogue
GET /.well-known/agent-skills/{skill}/SKILL.mdone skill document

The discovery surface carries no secrets and MUST NOT require a bearer. Neither route can be a typed op, so both declare their prose through the registry the router projection consults — which is why they render only while they are served, and why the generated SDKs and the spec-derived CLI carry the same sentence the document does.

§2 Generated from the router, never authored

The catalogue is generated by plugin/gen-skills from each app's own plugin/<app>/openapi.json — the app binary describing its own live router, which is the same input the fleet catalogue and openapi.yaml are built from — and embedded as catalog/.

This package MUST NOT re-derive skills at request time. It serves the embedded bytes, so the sha256 digests in index.json match the served SKILL.md exactly, and a catalogue cannot describe a route the binary does not serve.

The rule earns its place from a measured failure: the lane that built this catalogue in hanzoai/openapi projected authored intent rather than served routes and had no liveness filter, so it shipped skills for /v1/balancers and /v1/builds — which production 404s — as live instructions to an agent. The generator moved to cloud, beside the routes, for that reason.

§3 White-label: the brand is the Host

The brand is decided per request from the Host header, mirroring getWhiteLabelBrand: api.hanzo.ai serves the Hanzo catalogue, api.lux.network the Lux one, api.zoo.ngo the Zoo one. Hanzo branding MUST NOT appear on a Lux or Zoo surface.

A Host resolving to a brand with no embedded catalogue falls back to the deployment brand (CLOUD_BRAND), then to hanzo. Falling back is not guessing — every fallback is a catalogue that exists.

§4 The address is the convention's, not ours

These two routes live at the root because /.well-known/ is registered by RFC 8615 and the discovery convention names the path. HIP-0139 §3 permits an app to answer at an address not named for it exactly where an outside convention fixes the address, and this is such a case: an agent looks under /.well-known/agent-skills/ or it does not find us.

Registration order matters and is part of the contract: these routes are mounted at order 8, BEFORE IAM's /.well-known/* catch-all at order 50 and before the console's /*, so a first-match scan reaches them.

§5 The boundary against tools

  • tools (HIP-1213) is the per-tenant tool plane an agent calls through, authenticated and scoped to an org.
  • skills is the unauthenticated description of what exists, read before any call.

One is the shelf, the other is the sign on the door. A skill document MUST NOT be the only place a capability's contract is written; it points at the served document, which HIP-1030 specifies.

Rationale

skills was briefly treated as having folded into tools, and the corpus recorded it as no longer a capability. It had not folded: apps/skills is its own package with its own row in manifest/apps.go and its own two served routes, and it answers a question tools does not — what exists, to a caller who has not authenticated. The record is corrected here.

Security Considerations

The catalogue is public by design, so it MUST carry nothing an unauthenticated reader may not have: no org names, no tenant addresses, no credentials, no internal hostnames. Because it is generated from each app's own router description rather than from a tenant's state, it has no tenant state to leak.

The digest in index.json is the integrity claim a client can check, and it holds only because the same bytes are embedded and served. A future lane that re-derived a skill at request time would break that claim silently, which is why §2 forbids it.


All Hanzo capabilities · Interactive reference

How is this guide?

On this page