spec: name the target that writes the document

`make openapi` was renamed to `make describe` in e247e255 — correctly, since
the target now projects every app rather than only the spec — and 27 places
were left naming the old one. Two of them are FAILURE MESSAGES: a developer
whose golden is stale is told "run `make openapi`", which prints "No rule to
make target". A gate that says how to fix it, and names a command that does
not exist, is a gate that reads as broken tooling.

Comment-only apart from those two t.Fatalf strings; no target, no behaviour and
no artifact changes. `go build ./openapi/` and the four apps with the most
edits build with the tags hanzo.yml's own go-unit gate uses.

openapi/fleet.go also gains the projection it was missing. It lists four
projections of this API compared against each other by test; there is a fifth,
downstream and in another repo — hanzoai/openapi's hanzo.yaml, which every
published SDK is generated from — and it refutes itself against the LIVE
endpoint in that list, because that is the only one of the four a repo with no
checkout of this one can read.

Co-authored-by: Hanzo Dev <dev@hanzo.ai>
This commit is contained in:
Hanzo Dev
2026-08-04 01:45:57 -07:00
committed by hanzo-dev
parent f6c9605bd7
commit a6988db97e
22 changed files with 31 additions and 26 deletions
+1 -1
View File
@@ -615,7 +615,7 @@ type patchTargetIn struct {
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -47,7 +47,7 @@ import (
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -181,7 +181,7 @@ type ops struct{ s *cloud.Service[state] }
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -327,7 +327,7 @@ func Shutdown(context.Context) error {
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -45,7 +45,7 @@ import (
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -101,7 +101,7 @@ func Mount(app cloud.Router, deps cloud.Deps) error {
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -151,7 +151,7 @@ type ops struct{ s *cloud.Service[state] }
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -178,7 +178,7 @@ func Mount(app cloud.Router, deps cloud.Deps) error {
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -12,7 +12,7 @@ import (
// zipdoc lifts the doc comment off the typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -92,7 +92,7 @@ func Mount(app cloud.Router, deps cloud.Deps) error {
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document,
// the MCP tool list and the generated SDK — Go drops comments at compile time.
// Run by `make openapi` and by this app's own `make -C apps/content openapi`.
// Run by `make describe` and by this app's own `make -C apps/content openapi`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -153,7 +153,7 @@ func Mount(app cloud.Router, deps cloud.Deps) error {
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -156,7 +156,7 @@ type noInput struct{}
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -161,7 +161,7 @@ func Shutdown(ctx context.Context) error {
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -46,7 +46,7 @@ import (
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -40,7 +40,7 @@ import (
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -70,7 +70,7 @@ import (
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go — the ONLY way this prose reaches the published document and
// the MCP tool list (Go drops comments at compile time). Run by `make openapi`.
// the MCP tool list (Go drops comments at compile time). Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -36,7 +36,7 @@ import (
// zipdoc lifts the doc comment off each typed op and its In/Out fields into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -34,7 +34,7 @@ import (
// zipdoc lifts the doc comment off each typed op and each In/Out field into
// zipdoc_gen.go, which is the ONLY way that prose reaches the published document
// and the MCP tool list — Go drops comments at compile time. Run by `make openapi`.
// and the MCP tool list — Go drops comments at compile time. Run by `make describe`.
//
//go:generate go run github.com/zap-proto/zip/cmd/zipdoc
+1 -1
View File
@@ -114,7 +114,7 @@ test:
#
# It also pins FRESHNESS, which is why it earns its own entry rather than
# riding go-unit: the monolith is gone, so the woven document IS openapi.yaml —
# `make openapi` writes it through this same weave, and this verifies the
# `make describe` writes it through this same weave, and this verifies the
# committed subsets weave back to the committed golden byte for byte. A route
# change that regenerates one and not the other goes red here, in seconds,
# instead of shipping a wrong SDK. Links no subsystem and mounts nothing but
+1 -1
View File
@@ -61,7 +61,7 @@ openapi-weave: ## Weave the per-app subsets into the fleet spec and prove it equ
@$(GO) test -count=1 $(ROOT)/openapi $(if $(OUT),-weave="$(abspath $(OUT))")
# The exemptions are honoured HERE as well as in the gate, because the gate's
# own failure message says "fix: make openapi" — and that fix routed through this
# own failure message says "fix: make describe" — and that fix routed through this
# loop, which mounted kafka, which fails closed without a live broker. So the one
# command told to repair a red gate could not run at all. Each exemption is
# defined once and read everywhere it applies; a repair path that skipped fewer
+6 -1
View File
@@ -12,11 +12,16 @@ import (
// There are now four projections of this one API, and they are compared against
// each other by TEST:
//
// the woven golden openapi.yaml, written by the weave (make openapi)
// the woven golden openapi.yaml, written by the weave (make describe)
// each app binary's own subset `<app> openapi`, one file per app
// the woven fleet document Weave() over those subsets
// the live endpoint GET /v1/openapi.json
//
// And one projection OF the golden, downstream and in another repo:
// hanzoai/openapi's hanzo.yaml, which every published SDK is generated from.
// It refutes itself against the LIVE endpoint above (`publish.py --served`),
// because that is the only one of the four a repo without a checkout can read.
//
// An info block that differed between them would make two documents OF THE SAME
// API compare unequal for a reason that has nothing to do with the API — which
// would break the composition proof (weave_test.go) over a title string. So the
+5 -5
View File
@@ -7,7 +7,7 @@ package openapi_test
// that app's own binary from that app's own router (`<app> openapi`) — into the
// fleet document, and requires it to equal openapi.yaml byte for byte. There is
// no fully-mounted binary left to read: "compose the apps" and "the spec" are one
// statement. `make openapi` writes the golden through this same weave (-weave);
// statement. `make describe` writes the golden through this same weave (-weave);
// with no flag the same weave is the check.
//
// What it proves is COMPOSITION and only composition: that the subsets compose
@@ -36,7 +36,7 @@ import (
)
// weaveOut writes the woven document — the fleet spec the SDK repos pull. It is
// the SOLE writer of openapi.yaml now that the monolith is gone: `make openapi`
// the SOLE writer of openapi.yaml now that the monolith is gone: `make describe`
// regenerates each app's subset and then runs this with -weave to compose them
// into the golden. Without the flag the same weave is the drift gate.
var weaveOut = flag.String("weave", "", "write the woven document to this path (regenerate the golden)")
@@ -72,7 +72,7 @@ func fromTree(app string) []byte {
func TestFleetIsTheWeaveOfItsApps(t *testing.T) {
want, err := os.ReadFile(goldenPath)
if err != nil {
t.Fatalf("read %s: %v — run `make openapi`", goldenPath, err)
t.Fatalf("read %s: %v — run `make describe`", goldenPath, err)
}
subsets, err := openapi.Subsets(manifest.Names(), fromTree)
if err != nil {
@@ -87,7 +87,7 @@ func TestFleetIsTheWeaveOfItsApps(t *testing.T) {
}
// THE RATCHET, before anything is written: a regeneration that publishes less
// than the committed floor is refused in BOTH modes, so `make openapi` cannot
// than the committed floor is refused in BOTH modes, so `make describe` cannot
// be the thing that lands a shrunken document. See openapi/floor.go.
was, err := openapi.ReadFloor(floorPath)
if err != nil {
@@ -129,7 +129,7 @@ func TestFleetIsTheWeaveOfItsApps(t *testing.T) {
if !bytes.Equal(got, want) {
t.Fatalf("openapi.yaml is not the weave of its apps' subsets (%d paths woven now). A route was added, "+
"removed or renamed and either an app subset or the golden was not regenerated — the SDK repos pull "+
"this file. Run `make openapi` and commit the result.", len(woven.Paths))
"this file. Run `make describe` and commit the result.", len(woven.Paths))
}
t.Logf("woven %d paths / %d schemas / %d tags from %d apps — byte-identical to %s",
len(woven.Paths), schemaCount(woven), len(woven.Tags), len(manifest.Apps), goldenPath)