Engineering Philosophy

The principles behind Hanzo V8 โ€” one and one way, decomplect, ZAP-native, the language seam is the wire not FFI, one contract to N SDKs to thin CLIs.

Good engineering is mostly subtraction. Hanzo V8 ยท Open Edition is a small set of decisions, applied everywhere, until the whole cloud is simple enough to hold in your head: one binary, one contract, and a clean wire between languages instead of a tangle inside one. No consumer ever needs to know or care which part is Go and which is Rust. This page is the why โ€” the design pedagogy. The canonical, normative version lives in HIP-0127.

One rule ties the whole platform together: one contract, many bindings, thin clients, and a wire โ€” never FFI โ€” between languages.

One and one way

There is exactly one way to do everything, by construction. A capability is one name = one /v1/<name> = one self-contained spec โ€” no svc suffix, no singular/plural twins, no facade. The capability manifest (capabilities.yaml) is the single registry: every spec must appear there exactly once, in exactly one of the nine domains. The build fails on an orphan spec, an unlisted spec, or a name in two places. Orthogonality is a build invariant, not a hope.

The same rule governs distribution: one contract, one client core per stack, one distribution harness. Every SDK and CLI is derived from the contract โ€” none is hand-forked.

Decomplect โ€” values, not places

Following Rich Hickey: a capability is named by its value (its /v1 route), not by its place (which repo, language, or pod implements it). We decomplect โ€” unbraid โ€” the things that naive designs fuse together.

Values, not placesA capability is its route, not its host. Callers bind to /v1/<name>, never to a machine, a process, or a language.
One concern per binaryThe Go/Rust boundary is a value boundary (ZAP frames), not a place boundary (FFI in one address space). Each box does one thing.
Easy โ‰  simpleFFI is easy โ€” one repo, one process โ€” but complects two toolchains. The wire seam is simpler: independent, composable, language-free at the edge.
Compose, don't inheritCapabilities are composed over a uniform wire, not extended through shared implementation. Orthogonal and independently complete.

One binary, one contract

The application cloud is one Go binary (cloud, CGO_ENABLED=0, static), embedding the platform's subsystems and mounting them behind a single public surface: /v1/<capability> over HTTP + ZAP. That is the ONE contract every consumer speaks. Capabilities are grouped into the nine domains of the manifest; each is one name, one route, one spec.

Keeping it pure Go with no cgo is what preserves the single static binary โ€” the thing that makes "run the whole cloud anywhere" true.

The language seam is the wire, never FFI

Hanzo is Go and Rust. The cloud is Go; the engine, the dev agent, and the ML kernels are Rust. They compose over ZAP โ€” network or local socket โ€” each a clean single-language binary. Go cloud and the Rust components never link each other's code; they exchange ZAP frames whose schema lives beside the product that implements it.

Two naive urges, both rejected:

Don't fuse over FFIcgo/uniffi in one process destroys the CGO_ENABLED=0 static binary and complects two toolchains. Rejected.
Don't split orgs by languageNo hanzo-go / hanzo-rs. That leaks an implementation detail into the org and forces users to know which half a capability lives in. Rejected.

Everything canonical lives under hanzoai/<product> โ€” organized by capability, not by language. Users never know which language answered, because the org is product-first and the wire is uniform โ€” not because the languages are fused.

One contract โ†’ N SDKs โ†’ thin CLIs

Distribution is a single derivation tree. The one contract generates the language bindings and the wire types; the clients are thin frontends over a shared core.

openapi.yaml          the ONE contract โ€” /v1 over HTTP + ZAP
   โ”‚  generate โ†“
 go-sdk ยท rust-sdk ยท js-sdk        language bindings (derived)
 zap-spec                          the ZAP wire types
   โ”‚
 hanzo-client (Rust: ZAP bridge + hanzo.id auth + rust-sdk)
   โ”œโ”€โ”€ hanzo   โ€” the control CLI        โ†’ @hanzo/cli
   โ””โ”€โ”€ dev     โ€” the coding agent       โ†’ @hanzo/dev
  • The CLI is a client, never the server. It speaks ZAP (or its SDK) to a live cloud โ€” production, a laptop, or a self-host โ€” and never imports the cloud. That coupling is the trap that bloats a client to hundreds of megabytes.
  • One client core, two thin frontends. hanzo (the control CLI) and dev (the coding agent) share one Rust hanzo-client: one auth stack, one ZAP client, one SDK. The result is a ~15 MB binary โ€” small enough to ship over npm.
  • One harness, many channels. Per-platform prebuilt binaries on GitHub Releases fan out to @hanzo/cli / @hanzo/dev (npm), hanzo.sh (curl | sh), Homebrew, and go install. One binary per tool, N channels.

.zap and OpenAPI are two transports of the same /v1 contract โ€” both derived from the per-service spec, never hand-maintained separately. One contract โ†’ HTTP + ZAP + SDKs, all generated.

Deploy: native PaaS, no second deployer

Deploys go through the native PaaS (hanzoai/platform), which merge-patches the operator's Service resource; the operator reconciles the rollout. No second deployer. It is driven by the hanzo CLI or the platform UI โ€” the same one contract, all the way to production.

Read the specs

Was this page useful?
Last updated Oct 15, 2026