Files
cli/scripts/generate.sh
zeekay d64c5220ca the pin moves by pulling, because nothing could ever push it
`repository_dispatch: spec-update` was described as the coupling that carries a
hanzoai/cloud release into this repo. It carried nothing, and could not: the CLI
has no `.github/workflows`, so GitHub recorded the event and ran nothing; the
forge has no repository_dispatch endpoint to send it to; and a push here puts
hanzoai/ci's client lane in check-only at the LOCKED ref, so even a delivered
event could not have written a new one. Across 104 runs the pin moved exactly
once, by hand. The trigger is deleted rather than repaired — there was nothing at
either end of it.

The nightly drift job asks instead. It already runs on the forge, on a schedule,
with the network and the toolchain; reading hanzoai/cloud's newest tag, fetching
the document at it, writing the lock and regenerating costs it one step and needs
no dispatch and no new secret. It runs even when `live-check` failed, because
production having moved under the committed evidence is exactly when the pin wants
moving.

It opens a patch rather than landing one. A tag exists the moment it is cut and
production deploys it later, so the newest document can name a route the running
server does not serve yet — which the gate calls a phantom, correctly. Measured
while writing this: v1.801.495 is tagged, production answers x-api-version
sha-716c08370361, and GET /v1/commerce/org, which .495 adds, 404s against a
/v1/commerce/<nonsense> control that also 404s. The prefix discriminates, so the
denial is real, and that is a wait rather than a defect. This tree stays pinned at
v1.801.492 for that reason.

The lock's writer moves with it: generate.sh and hanzo.yml both named the client
lane as the one writer of .spec-lock on the strength of the dispatch, which means
for 104 runs it had no writer at all. It says the nightly now.
2026-08-08 06:16:30 -07:00

59 lines
3.2 KiB
Bash
Executable File

#!/usr/bin/env sh
# The CLI's projection of the Hanzo Cloud API document — the same call site every
# other client repo has, so hanzoai/ci's `client:` lane drives all eight the same
# way.
#
# ONE INPUT, by value:
# $SPEC the document itself, already fetched at a pinned ref and already
# digest-checked by the lane. Never a live host: at generation time
# the deploy this describes has already happened, and asking
# api.hanzo.ai instead would name whatever it is serving now rather
# than the release that handed us this file.
# $SPEC_REF which ref that was. genspec stamps it, with the document's own
# sha256, into the spec's provenance — so `spec/cloud.json` can
# always answer "which release am I?".
#
# One optional argument: `--check` re-asks instead of rewriting (exit 1 on any
# delta). Same binary, same derivation — which is what keeps the gate from
# testing a different generation than the one that writes the file. It is an
# argument and not an env var because that is the spelling every other client
# repo's call site already uses, and one spelling of one idea is the point.
#
# THE SECOND INPUT IS GONE, and with it the clone and the credential. This script
# used to fetch hanzoai/openapi and pin it in `.spec-lock` beside the document,
# because the hand-authored master `hanzo.yaml` was the last source of
# request-body and query SHAPE for cloud's untyped handlers. It had stopped being
# only that: 71 operations entered `spec/cloud.json` on the master's word alone —
# two addressing nothing at all, and sixty-six "confirmed" only by a
# `{wildcardN}` relay door, which answers identically for a real path and an
# invented one. A second authority over what EXISTS is how a CLI grows commands
# no server serves. The document decides existence, prose and shape alike now, so
# there is nothing left to clone and no SPEC_TOKEN to hold.
set -eu
cd "$(dirname "$0")/.."
# An apostrophe inside ${VAR:?word} opens a quote the parser never closes, and
# the whole script then fails to parse rather than this line failing to run.
[ -n "${SPEC:-}" ] || { echo "generate.sh: SPEC must name the cloud API document; the client lane in hanzoai/ci sets it" >&2; exit 1; }
export HANZO_REGISTRY="$SPEC" HANZO_SPEC_REF="${SPEC_REF:-unpinned}"
if [ "${1:-}" = "--check" ]; then
cargo run --quiet --features maintainer --bin genspec --locked -- --check
exit 0
fi
cargo run --quiet --features maintainer --bin genspec --locked
cargo run --quiet --features maintainer --bin genproduct --locked
# `.spec-lock` has ONE writer — the nightly re-pin in `.hanzo/workflows/drift.yml`,
# which reads hanzoai/cloud's newest tag, fetches the document at it, and records
# the ref beside the digest of the bytes it actually read. It used to be named as
# hanzoai/ci's client: lane, on the strength of a `repository_dispatch` a cloud
# release was supposed to send; nothing was ever delivered, and on a push that lane
# is check-only at the LOCKED ref, so for 104 runs the lock had no writer at all
# and moved once, by hand. This script writes no half of it: it used to append a
# second (`master=`, the hanzoai/openapi commit it generated against), and there is
# no second half.