# Consensus-Backed Plugin Platform

URL: https://docs.hanzo.ai/docs/architecture/plugin-platform

> The architecture direction for Hanzo Cloud — plugins as the unit of deployment, a small consensus control plane over placement, and ZAP-native authoring. Specified in HIP-0125 (Draft).

> This page describes a **design direction**, not a shipped feature. The runtime it describes is specified in \*\*HIP-0125 (Draft)\*\*. Foundational pieces exist — the Quasar post-quantum BFT consensus engine is implemented, and the seven-voter placement ceremony has been built and tested — but they are deliberately kept **out of the live serving path**: placement does not yet decide where traffic goes, and there is no `cloud.Register` plugin runtime to deploy against. It is published so the design can be reviewed. This page is about where the platform is headed and why.
>
> **If you came here to build something, you want [Extend](https://docs.hanzo.ai/docs/extend)** — the shipped extension contract, with the three ways to add a tool today. For the rest of what runs, see the product pages under [Platform & Services](https://docs.hanzo.ai/docs/openapi).

Hanzo Cloud is **one contract**. Every subsystem — IAM, KMS, ingress, billing, MPC, observability, agents, and the rest — is written in Go against the same request tier and served under a single `/v1` surface described by the document the binary emits, [hanzoai/cloud](https://github.com/hanzoai/cloud)'s `openapi.yaml`. Routing and ingress are themselves native subsystems, so the design point is that **one entry point answers everything** — not a stack of gateway and ingress tiers layered in front of it.

How that surface is _packaged_ has already moved once. HIP-0106 collapsed the former per-service fleet into a single fused binary; that binary is now gone in turn, and the shipped shape is a light host that mounts each subsystem as **its own process**, started on the first request that reaches it (`cmd/cloud/main.go`). The host knows where each app lives and what path it answers, never what the app does, so a subsystem changing rebuilds only itself.

What the plugin platform adds is the **next** step, and it is _not_ a re-layering: one entry point stays one entry point. Each subsystem becomes a **placed plugin** so that nodes **specialize** — every node can serve any subsystem, but each runs a dynamic _subset_ of them rather than all — with a **small consensus control plane** deciding where each plugin's write side lives. The goal is that a subsystem author writes almost none of the hard parts — placement, failover, replication, high availability — and inherits them from the platform.

The design rests on one principle: \*_consensus orders decisions, not bytes._\*

## The unit is a plugin

In the proposed model (HIP-0105, _In-Process Extension Runtime Standard_), a service registers itself with a single call:

```go
// Proposed API (HIP-0105) — not yet available.
func init() {
    cloud.Register("kms", 500, mount)
}
```

A plugin is the unit the platform places and scales. The `cloud` binary loads a set of registered plugins; **nodes specialize** by running a dynamic subset of them rather than every node running everything. That makes the runtime one deployable artifact whose behavior on each node is data — the placement decision — rather than a per-service build.

Existing subsystems — KMS, IAM, ingress, billing, MPC, observability — already ship as **separate processes** behind one host, and are already started on demand rather than all at once. What they are **not yet** is independently _placed_: which node runs which subsystem is not a decision anything makes, and there is no writer lease behind it. The plugin model makes each subsystem a unit the control plane can place, so nodes specialize instead of every node running everything.

## Consensus orders decisions, not bytes

The platform splits into two planes that are deliberately kept separate.

**Control plane — a small, fixed quorum.** Seven voter nodes run a post-quantum BFT consensus engine (the **Quasar** engine from Lux, with a post-quantum certificate profile), reaching agreement on a **five-of-seven** Byzantine quorum. Seven is the smallest voter set that tolerates two simultaneous faults ($N \ge 3f+1$, with a $2f+1 = 5$ quorum at $f = 2$). Its replicated log orders only tiny metadata:

- cluster membership,
- the **placement map** — which node holds the writer for each `(plugin, shard)`, and its followers,
- **writer leases** with fencing epochs, so there is exactly one writer per shard per epoch.

**Data plane — reuse what exists.** The bytes do not go through consensus. The data plane reuses the existing streaming replication (HIP-0107) that already backs the platform's storage — the S3 / ZapDB log-ship. The only change is the write fence: instead of asking "do I hold a Kubernetes lease?", a writer asks "does the control plane grant this shard's lease at the current epoch?"

The consequence is the important part:

> **Consensus sits off the data path.** If the control-plane quorum is lost, placement and failover freeze — but serving does not stop. Every current writer keeps its lease and keeps writing; readers keep reading. Losing quorum degrades **failover**, not availability. This is the Chubby / etcd shape applied to the Hanzo runtime.

## Scaling to N nodes

Dynamic scaling lives in the **data plane**, not the voter set. The two planes are sized by different rules, on purpose:

- **7 voters** run the control plane, agreeing on a five-of-seven quorum. This set is **small and fixed by design** — BFT agreement cost grows with the number of voters (quadratic message complexity), so a fixed small quorum keeps decision latency constant no matter how large the fleet becomes. Seven is a _fault-tolerance_ parameter (tolerates $f = 2$ at $N \ge 3f+1$), **not a capacity ceiling**; you don't add voters to handle more load.
- **N data nodes** host plugin shards, serve or proxy requests, and each follow a read-only copy of the placement map. They carry **no consensus weight**, so `N` grows without bound — this is where planet-scale happens.

So the fleet scales freely: you add data nodes, split plugins into per-tenant shards, and move writers — all dynamically, all in the data plane. The voter set stays fixed because it orders _decisions_, not _bytes_, and decisions are tiny. Changing the voter count (say, to tolerate more faults) is a deliberate, consensus-ordered reconfiguration, not an automatic response to load.

Within that topology:

- **Pinned writers** — each shard has one writer node, assigned by the placement map, so writes have a single owner and never conflict.
- **Per-connection pinning** — a client's connection is routed to the node that currently owns the shard it is talking to, so reads and writes land on the right replica.
- **Per-tenant sharding** — the write side can be split by tenant, down to a `(plugin, org)` shard, so a single busy organization gets its own writer. Fine per-tenant sharding is a **later stage** of the proposal; the earlier stages run one writer per plugin.

## ZAP-native, easy plugin authoring

The payoff is the developer experience. Under HIP-0105 and HIP-0114, a plugin author implements one small interface and calls `cloud.Register`. In return the platform supplies placement, per-tenant scale, replication, per-connection pinning, and high availability — none of which the author writes.

```go
// Proposed authoring model (HIP-0105 / HIP-0125) — illustrative, not yet available.
// The author writes the handler; the platform supplies placement + replication + HA.
func mount(deps cloud.Deps) http.Handler {
    db := deps.OpenShard("kms")     // the placement-assigned shard for this node
    return newHandler(db)           // ...just serve requests
}

func init() { cloud.Register("kms", 500, mount) }
```

The default wire is **ZAP** (Zero-Copy App Proto, HIP-0114) — the same high-performance, post-quantum transport documented in the [ZAP section](https://docs.hanzo.ai/docs/zap). Every plugin registered through `cloud.Register` speaks ZAP with no extra work, so cross-plugin and inter-node calls get zero-copy performance by default rather than as an opt-in.

> The snippets above show the **proposed** shape of the API to illustrate the direction. They are not a tutorial for a runtime that exists today — there is no `cloud.Register` plugin runtime to deploy against yet. Treat them as design, pending ratification of HIP-0125.

## Where this is specified

The plugin platform is defined across a set of Hanzo Improvement Proposals. Statuses are as of writing and may change — track them at [hips.hanzo.ai](https://hips.hanzo.ai) and [github.com/hanzoai/hips](https://github.com/hanzoai/hips).

| HIP      | Title                                      | Status |
| -------- | ------------------------------------------ | ------ |
| HIP-0125 | Consensus-Backed Plugin-Placement Platform | Draft  |
| HIP-0105 | In-Process Extension Runtime Standard      | Draft  |
| HIP-0106 | Unified Hanzo Cloud Binary                 | Draft  |
| HIP-0107 | Streaming Replication over VFS             | Draft  |
| HIP-0112 | Cloud Infrastructure Topology Standard     | Active |
| HIP-0114 | ZAP — Inter-VM Cognitive Transport         | Draft  |

## Next Steps

- [Architecture Overview](https://docs.hanzo.ai/docs/architecture): How Hanzo Cloud is built today, and the direction it is evolving toward.
- [ZAP Protocol](https://docs.hanzo.ai/docs/zap): The zero-copy transport plugins default to.
- [Platform & Services](https://docs.hanzo.ai/docs/openapi): The services that run today, behind one api.hanzo.ai.
