Three hand-maintained capability registries drifted (8 vs 9 vs hardcoded) — a
one-and-one-way violation. Collapse to ONE machine-readable source, everything
else derived.
Before: 3 sources
- capabilities.yaml (structured manifest, read by nothing)
- CAPABILITIES.md (10KB hand-written index, wrongly called canonical)
- merge.py GROUPS dict (hardcoded, "mirrors CAPABILITIES.md by hand" — the
only one that actually drove x-tagGroups)
After: 1 source + 2 derivations
- capabilities.yaml is the ONE source of truth
- merge.py READS it (GROUPS dict deleted) → hanzo.yaml x-tagGroups (domain
titles + Core) AND generates CAPABILITIES.md (now GENERATED — DO NOT EDIT)
Build invariant enforced (fail loud, was only promised): every present
<svc>/openapi.yaml dir maps to exactly one entry across domains∪core (orphan /
unlisted / double-listed → sys.exit); collapsed name must have no spec dir;
internal excluded from master + x-tagGroups.
Reconciled capabilities.yaml so the build PASSES without losing capability,
grounded in `ls */openapi.yaml`:
- app → applications, do → platform (grouped, not folded; review notes kept)
- world → applications (dir exists, was unlisted)
- s3 → data, observe → observability (dirs exist → moved out of `collapsed`,
which requires no dir; fold-later intent preserved in `review`)
- team/wallets/treasury: no spec dir → dropped from domains, kept in `pending`
hanzo.yaml aggregation unchanged in substance: 1793 paths / 999 schemas / 150
responses / 39 params / 68 tags — zero added, zero removed. Only x-tagGroups
names change (8 → 9 groups, using domain titles).
Also: gitignore __pycache__/ (was polluting the tree).
4.8 KiB
openapi
OpenAPI 3.1 specifications for all Hanzo services. v1.0.0 lock-in as of
2026-05-31. No backwards compatibility, no /api/ prefixes, no cross-brand
references.
Layout
capabilities.yaml— the ONE canonical registry: every capability name, in exactly one domain (orcore), plusinternal/collapsed/pending/review. This is the single source of truth —merge.pyREADS it. Edit this, then runpython3 merge.py.CAPABILITIES.md— GENERATED fromcapabilities.yamlbymerge.py. A derived human index; never hand-edit (it carries aGENERATED — DO NOT EDITheader).hanzo.yaml— unified master, aggregated from the per-service specs and grouped (x-tagGroups) bymerge.pystraight fromcapabilities.yaml.<service>/openapi.yaml— one self-contained spec per service.shared/— shared schemas usable by individual specs in theircomponents.README.md— service index and usage.CHANGELOG.md— v1 lock-in entry.
merge.py enforces one-and-one-way as a build invariant: every present
<service>/openapi.yaml dir MUST map to exactly one entry across
domains ∪ core in capabilities.yaml (orphan / unlisted / double-listed →
build fails); a collapsed name must have NO spec dir; internal services are
excluded from the master and x-tagGroups.
Conventions
- Routing: every route is
/v1/<service>/<resource>. - IAM additionally exposes
/oauth/*and/.well-known/*. - Security: every operation uses
BearerAuth(JWT fromhttps://hanzo.id). info.version: 1.0.0on every spec.- No cross-file
$ref. Each spec is self-contained. - No
deprecated: true. Forward-only. - No
/api/prefix anywhere. - Master grouping:
merge.pyemitsx-tagGroupsfrom the domains incapabilities.yaml(theirtitle) plus aCoregroup; every present spec must belong to exactly one group or the merge fails.
Validate
python3 -c "import yaml, glob; [yaml.safe_load(open(s)) for s in glob.glob('*/openapi.yaml') + ['hanzo.yaml']]; print('OK')"
When changing a spec
- Bump nothing — version stays at
1.0.0. - Add new resources under
/v1/<service>/<resource>. - Add components in the spec's own
components.schemas. No$refto other service yamls. - Examples must come from real responses.
- If you add or remove a
<service>/openapi.yamldir, add/remove its name incapabilities.yaml(exactly one domain, orcore) — the merge FAILS otherwise. - Update
CHANGELOG.mdwith a dated entry under the v1.0.0 heading. - Run
python3 merge.py(regenerateshanzo.yamlANDCAPABILITIES.md) and commit all three.
SDK generation — the ONE way (Stainless RETIRED, 2026-07)
The one interface is hanzo.yaml; the generator backend is
openapi-generator for EVERY language — no Stainless, no API key. Each
language repo owns its generation via a scripts/generate.sh that runs
openapi-generator against this hanzo.yaml, plus a generate.yml workflow
that regenerates + opens a PR on the spec-update repository_dispatch fired
by this repo's regenerate-sdks.yml.
| Lang | Repo | Generator | Package | Publish |
|---|---|---|---|---|
| Python | hanzoai/python-sdk (pkg/hanzoai) |
python (urllib3, pydantic v2) |
hanzoai on PyPI |
tag v* → twine |
| Go | hanzoai/go-sdk |
go (package hanzoai) |
github.com/hanzoai/go-sdk |
tag v* → pkg.go.dev |
| TypeScript | hanzoai/js-sdk |
typescript-axios |
hanzoai on npm |
tag v* → npm publish |
| C++ | hanzoai/cpp-sdk |
cpp-restsdk |
— | artifact (this repo's matrix) |
| Dart | hanzoai/dart-sdk |
dart-dio |
— | artifact (this repo's matrix) |
| Rust | hanzoai/rust-sdk |
hand-written | hanzo crate |
reconcile (openapi-generator emits no Rust) |
Generator version pinned to 7.14.0 everywhere. The merged surface is
verified codegen-clean AND compile-clean for go / python / typescript-axios
(spec fixes that made it so: pubsub ack_wait int64; platform DeployJob /
CancelDeploymentJob oneOf → named subschemas; merge.py namespaces operation
tags + discriminator mappings per-service and collapses to one primary tag).
There is NO unified hanzoai/sdk multi-lang monorepo generator — that repo's
gen/ is the retired SECOND way; hanzoai/sdk is CLI-only now.
Remaining spec-coverage gaps (SDKs cover the spec faithfully; the spec
lacks these live prefixes — author from the Go routes, then the SDKs pick them up automatically on the next regeneration):
/v1/memoryand/v1/videosare LIVE (cloud binary) but have no paths inhanzo.yamlyet.- The broader "author the remaining
/v1product specs fromcloud/clients/<x>/*.go" backlog still applies for any prefix not yet present in the per-service specs.
The SDK-generation surface is the FUSED api.hanzo.ai/v1 binary. merge.py
unions the per-service specs into it.