Files
HIPs/HIPs/hip-1156-template-starter-gallery.md
zeekay ad5a010f79 Three words for what a proposal is, and a generator that refuses
The same fact lived in nine hand-kept places and they disagreed about 58
proposals. This makes the file the only authority and everything else a
projection of it.

ONE VOCABULARY, in vocabulary.json, read by the lint, the generator and the
doc site. Three words, each answering "can I rely on this?" and nothing else:

    Draft    nothing implements it yet, or its own text says the work is ahead
    Final    the thing it specifies exists in the code
    Living   governance and process: amended in place, never finished

Eight spellings folded in. `Active` was the one doing real damage: on four Meta
and Process HIPs it meant living, on 48 others it meant shipped, and one word
doing two jobs is why nothing agreed. `Review` and `Last Call` described a
queue rather than a document, and a proposal under review is still one you
cannot build against.

STATUS IS EARNED, not declared. Every Standards Track proposal was checked
against the estate: 235 have their implementation, and eight do not and say so.
HIP-0095 carries a twelve-week plan ending at "mainnet launch" and has no code.
HIP-0525 specifies an all-machine meeting while apps/meet refuses a machine a
seat. HIP-0078 names a prover at a "planned location" that does not exist.
HIP-0114 is the cog.* procedure set, and that procedure set returns nothing.
HIP-0003, HIP-0102, HIP-0305 and HIP-0901 likewise: looked, found nothing.

SIXTEEN TOMBSTONES DELETED rather than statused. A dead document kept alive in
the index is one concept wearing two names. Each successor exists and carries
the text, and the 90 references that pointed at a tombstone now point at it --
whole markdown links at once, so link text cannot outlive its target. Three of
the sixteen were pure compatibility: HIP-0028 specified a migration off a
Bitnami chart, HIP-0029 dual-engine MySQL, HIP-0030 a schema-deprecation
policy. We ship no backwards compatibility, so we do not specify it.

Nine links were already broken and had been since the corpus was renumbered:
short-form ./hip-5.md paths that never existed. Two named the wrong proposal --
one cited "HIP-1: Hanzo Multimodal Models" where multimodal is HIP-0003.

THE GENERATOR REFUSES more often than it writes, because a short table looks
exactly as authoritative as a complete one. Rows must equal files; a shrinking
index must say by how much; a section whose input is missing is an error, not
an omission; nothing is written until all of it validates. Its self-test breaks
the corpus eleven ways and requires each to refuse AND leave README byte-
identical -- a guard that reports after half-writing has protected nothing.
The lint's second implementation of the same comparison is gone.

The site rendered 52 proposals with a fallback grey badge and counted them
toward none of its three stat tiles, because docs/lib/source.ts declared a
status union by hand: it admitted a `Stagnant` no file has ever carried and
omitted the one 52 files did. Five components each kept their own copy of the
colours. All six now read vocabulary.json.
2026-08-28 18:05:41 -07:00

5.1 KiB

hip, title, author, type, category, capability, status, created, requires
hip title author type category capability status created requires
1156 Template — A Deploy Cut From a Catalog Hanzo AI Standards Track Interface template Final 2026-08-20 HIP-0026, HIP-0106, HIP-0139

HIP-1156: Template — A Deploy Cut From a Catalog

Abstract

/v1/template is a gallery of starter kits you can deploy as they come, in two layers that never mix: the public catalog of deployable scaffolds, vendored from hanzoai/gallery and shipped embedded in the binary, and a customer org's own templates, private to that org. It is implemented in hanzoai/cloud at apps/template. One template is one entry; the shapes it ships in — format, page, theme — are Variants inside that entry, chosen at fork time.

Motivation

Variants exist because the alternative already happened: one portfolio design read as 26 templates and one dashboard as 2, because every format and page was a catalog row of its own. A variant is an option resolved at fork time, never a row. The value is named StarterKit rather than Template because the fleet's schema namespace is flat and another app already publishes a Template with a different shape — one name with two shapes would make every generated SDK bind whichever it read last, so the name not yet published is the one that yields (apps/template/templates.go).

Specification

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

The store, and the layer that is not in it

The store holds ONLY private templates: one encrypted SQLite file (cek.Open(namespace.System(), "templates", dir), apps/template/store.go:39), each row keyed by the gateway-minted org, the whole StarterKit as one JSON document so a row can never drift from the shape the API serves, with (org, slug) — the only things ever queried on — as real columns.

The public catalog is deliberately NOT in that table. It is the embedded catalog.json — reference content, immutable, with NO write route, so nothing a customer does can add to it. Two containers rather than one visibility flag is the whole safety argument: a private template cannot surface in the public catalog by CONSTRUCTION, not by a filter every future reader has to remember.

The address

Five operations under /v1/template: list (public catalog plus, for a validated caller, that org's own), get one by slug (the caller org's own, else public), publish (201, private to the caller's org), replace, and delete. All are typed except the delete, which answers 204 with no body — there is no value to type. An anonymous GET never touches the store at all.

The slug is single-valued

A slug names exactly one template across both layers: publishing over a public slug MUST be refused (409), so no org can shadow the gallery. The slug shape is the same DNS-ish label a project uses, so a template slug can always become the forked project's slug.

Curation is not writable

Tier and Rating are public-gallery curation carried verbatim from the embedded catalog. No request can set them — neither write body has the fields and neither write path builds a kit carrying one — so they are absent on every customer-published kit, and the console's "yours" badge keys on the server- stamped owner, never on a request field.

Tenancy

The org is principal.Org, minted from the validated bearer (HIP-0026), never a request field; every read of the private table binds it.

Money, events, observability, stage

It is free — the surface declares cloud.Free (plugin/template/main.go). It publishes nothing on the bus and emits nothing beyond the request span every route gets. The stage is ga: the gallery is the entry point of the deploy path, part of the self-service platform core.

Upstream

The public catalog's source of truth is hanzoai/gallery — the fleet's own repository — vendored as the embedded catalog so the unified binary ships it with no external dependency. No third-party OSS is forked or embedded.

Rationale

The alternative to two containers is one table with a public flag, which makes every future query one missing predicate away from leaking a customer's private template into the catalog every visitor browses. Embedding the catalog trades freshness for immutability — updating it is a release — and that is the right trade for reference content whose integrity is the product.

Security Considerations

The exposures are impersonation-shaped rather than data-theft-shaped. A private template surfacing publicly leaks a customer's product scaffolding; the container split closes it structurally. An org shadowing a public slug would let an attacker serve their own kit under a name the gallery made trustworthy — the 409 closes it. Writable curation fields would let anyone mint a top-tier rating for their own kit; keeping Tier and Rating catalog-only closes it. The remaining boundary is the org bind on every private read, from the validated principal only.

References

  • HIP-0026 — Identity and Access Management
  • HIP-0106 — The Hanzo Plugin Contract
  • HIP-0139 — Capability

Released under CC0 1.0 Universal Public Domain Dedication.