351 Commits
Author SHA1 Message Date
zeekayandHanzo Dev 88ea26b88c Go 1.27.1, and the code it can say more simply
spec sync / check (push) Canceled after 0s
Hanzo CI/CD / cicd (push) Failing after 58m41s
CI/CD / cicd (push) Failing after 58m40s
Modules declare go 1.27.1 and the build images follow. go fix had nothing to
change in the probe.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 18:52:40 -07:00
zeekayandHanzo Dev f5178906a8 go 1.26.8
One toolchain across the estate. The tree carried 1.26.0, .1, .3, .4 and .5
at once, so which compiler built a binary depended on which repo it came
from.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 23:56:01 -07:00
zeekayandHanzo Dev 82d7f4a22e ci: exercise the forge build lane through the system webhook
Empty on purpose: this push carries no tree change, only the delivery. The
forge's per-repo hooks all named cloud's /v1/git/webhook, which answers 204
without dispatching, so a push here has never built. Forge-wide system
webhook 3035 now delivers to platform's /v1/git-webhook instead.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 23:56:01 -07:00
zeekayandHanzo Dev 6954b249f3 Move the workflows to .github/workflows
The forge reads .github/workflows natively and github.com reads nothing else,
so one directory serves both planes instead of two conventions that disagree
about which one is live. The reusable in hanzoai/ci already lives there, so a
caller naming that path now resolves to a file that exists.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 19:01:00 -07:00
zeekayandHanzo Dev 02b454666c ci: a runner label names the platform, not the org
hanzo-build-linux-amd64, lux-build-linux-amd64, zoo-build-linux-amd64 and
every other org-prefixed spelling all meant the same machine. Which org a
job belongs to does not change which host can build it, so the org bought
one pool name per org per arch and each could go stale on its own -- the
evo host alone answered to fourteen names for one label.

One vocabulary now: linux-amd64, linux-arm64, macos-arm64, win-amd64. The
generic labels every plain workflow uses (ubuntu-latest, self-hosted) are
untouched, so naive CI keeps working.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 12:09:46 -07:00
zeekayandHanzo Dev 8a9edd9648 fix: call the pipeline at the address it actually lives
hanzoai/ci keeps the reusable at .github/workflows/build.yml — the one path
both planes resolve, since github.com reads a reusable only from there and the
forge reads it too. The v1 tag moved with it, so a caller still naming
.hanzo/workflows/build.yml asks for a blob that is not in the tree:

  InsertRun: read hanzoai/ci@v1:.hanzo/workflows/build.yml: object does not exist

The caller itself stays at .hanzo/workflows/cicd.yml on purpose: github.com has
no runner for these labels, so a caller placed there could never be scheduled.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-08 01:14:30 -07:00
zeekay 269cde6bd2 Generate dart into the repo that holds the dart client
The row pointed at hanzoai/dart-sdk, which is a 9KB landing page: four licence
files and a README saying the code lives in its language org and that nothing
is published from there. The client itself is hanzo-dart/sdk, 33MB of it, and
it had not been regenerated because the driver was writing next door.

hanzoai/dart-sdk is the shape the other ten should end up in.
2026-09-05 18:42:28 -07:00
zeekay 6cbbeec642 Regenerate the manifest at the document it now names
CAPABILITIES.md and .spec-lock are projections of hanzo.yaml, so re-pinning
the document moves them with it. compute takes visor's place, the names that
went singular follow, and the operation counts are the ones the current
routers register.
2026-09-05 18:09:23 -07:00
zeekay b530b386f3 Re-pin the document, and place the names the API grew
The pinned document was a month old and predated the compute migration, so
every SDK generated from it described /v1/visor — which the deployment no
longer serves at all. That is how a hand-written console client and a
generated one drifted the same way at the same time.

publish refused until the taxonomy could place what the API now serves. Most
of it was one migration: agents, channels, flags, functions, integrations,
projects and tools each went singular, and visor became compute. Placed the
three that are genuinely new by reading what they serve — ci alongside deploy,
space alongside s3 since it serves drives and files, and market with web3
rather than commerce, because it serves chains, pools and tokens.

crm is grouped nowhere now only because it serves no route yet; the file can
only arrange what the router answers for. It comes back when it does.
2026-09-05 15:16:47 -07:00
zeekayandHanzo Dev 4b1e25da38 chore: symlink AGENTS.md + GEMINI.md + CLAUDE.md -> LLM.md
Co-authored-by: Hanzo Dev <[email protected]>
2026-09-02 01:08:34 -07:00
zeekay d6d1e8c59e Name Zen in the hero card's font stack
The social card asked for Inter first. That is not a face this estate
licenses, ships or ever drew, so a renderer with Inter installed painted
the wrong face and one without it silently fell through to system-ui.
Zen leads now; the same tail follows it.

(cherry picked from commit 900a1763cddeabf938859fce1d3ccd200684996d)
2026-08-29 13:21:33 -07:00
zeekay 2244adee60 The Go probe reads the answer through its type
It used to take resp.Body and hand-decode an anonymous struct, because there
was nothing else available: the document declared no response for /v1/models,
so the generator gave GetModels a bare *http.Response and every caller had to
know the shape by heart.

Reading through the generated AiModelList is the assertion. It only compiles if
the shape crossed from hanzoai/ai, through cloud's relay, into the document
this client was projected from — the whole chain, checked by the compiler
rather than by a comment.
2026-08-28 15:55:09 -07:00
zeekay 8e00304bca e2e: run the clients against a real cloud
Every gate in this repo compares a client to the document, and every build
proves the client is well-formed. Neither answers the question a user actually
has: does it work against a server. Seven languages now answer it -- go, python,
typescript, dart, php, ruby, rust -- against the local cloud by default and
against anything HANZO_BASE_URL names.

Each probe asserts a 200 whose body decodes AND a 403 that arrives as an error,
because a client that swallows a refusal and returns a zero value looks exactly
like one that works.

It earned its place on the first run: GET /v1/models is AiAPI.GetModels in Go
and ai_api::get_models in Rust but ModelsApi.getModels in TypeScript. One
document, three groupings, and nothing but a call finds it.
2026-08-28 12:14:01 -07:00
zeekay 432d47359a go: the generator writes the /v8 import path
git-repo-id composes the path in every generated doc as
github.com/<git-user-id>/<git-repo-id>, and the Go client's module gained a /v8
suffix so its 8.x tags are publishable at all. Without this the next
regeneration would put 2,272 references to the bare path back into the docs and
tell a reader to import something the module proxy refuses to serve.
2026-08-28 11:19:47 -07:00
zeekay 7cbd022c2f republish at cloud 529be4ccb9: search names Fusion and Provenance 2026-08-28 08:12:59 -07:00
zeekay d2904162fd republish at cloud 92604dd76f: 1624 paths, 2272 operations 2026-08-27 20:40:23 -07:00
zeekay d01e4b0e30 republish at cloud a48ddfb315 2026-08-27 19:43:27 -07:00
zeekay 960377dea6 republish at cloud 16e3b9cef1 2026-08-27 17:17:56 -07:00
zeekay 07b3f0e1ac republish at cloud 03cd1b9b10: 1623 paths, 2270 operations 2026-08-27 16:50:22 -07:00
zeekay 998a87f474 republish: 1623 paths, 2270 operations
One operation more than the last projection: an agent run now reports how far
along it is, and says that the figure is an estimate.
2026-08-27 16:02:30 -07:00
zeekay e705ab2436 republish at the release that renamed the examples
Same 1622 paths and 2269 operations. What moved is prose the apps emit: the
company and legal examples, and the GitHub webhook's account of what a
repository event does.
2026-08-27 15:14:06 -07:00
zooqueen 6b8612eb74 two red gates, neither of them about the artifact
--check asks one question: is hanzo.yaml what its own pinned input projects to?
It answers that at the ref .spec-lock NAMES, so which remote is cloud's main
cannot change the answer — and it was resolving that remote anyway, before
anything read it, and dying there. Measured on main: it exited on `forge/main,
forgeinc/main, inc/main each carry openapi.yaml and have diverged` while the
artifact it was asked about was byte-for-byte correct. The branch is resolved
only where it is used now — `--current`, whose whole question is whether the tip
moved past the pin, and a re-pin with no `--ref` to say where.

The ambiguity itself is real and stays refused. Three remotes carry the document
and none contains the rest; guessing between them is how a projection gets
published from the wrong lineage.

test_flows.py named four operations the document does not have. The keys route
answers under the app that owns it, and the store plane moved again: this file
said /v1/instances/kv, and that address is now 404 with a 404 control, which is
this repo's own definition of refuted. /v1/provisioning/kv answers 403 with a
404 control — served. The notes carried the old probe as if it still held, so
they are re-measured rather than re-worded, and they now say what the bare
/v1/kv actually is: a separate bucket-keyed value plane whose root answers 200
to anyone, which is the one shape a round-trip must not be built on.

Every flow renders into every SDK's examples, so an id here that the document
lacks is a broken example in eight languages.

hanzo.yaml, CAPABILITIES.md and .spec-lock are untouched. The pin stays where it
is: at 22aedc87 the deployment fails to answer for 16 published operations, and
at cloud's main it is 351 — the pin is the newest release api.hanzo.ai answers
for, not the newest release.
2026-08-27 14:39:10 -07:00
zeekay 0991117a8c republish: 118 capabilities in 9 domains, 1622 paths, 2269 operations
The routes consolidated and the map did not follow. chains, rpc and tokens are
all /v1/web3/* now and tag themselves web3; indexers and oracles read back
through explorer; connectors moved under integrations; and the bare-/v1
inference surface -- /v1/chat/completions, /v1/models, /v1/embeddings -- tags
itself ai, with the long tail apps/ai used to hand-declare gone exactly the way
this file said it would go once apps/ai projected its mounted registry.

Sixteen names arrived as the singular of a plural that left with its routes.
Four are placed for the first time: trust beside the audit and compliance it
publishes, graph beside the stores it is one of, node beside the fabric rather
than beside exec, and standing beside company.
2026-08-27 14:00:30 -07:00
zeekay 5b4379a876 name the repository that holds the document
The receipt is a coordinate a consumer resolves -- <repo>@<ref>:<path> -- and
it named a repository whose main is a different lineage, one that does not
contain the ref. Nothing could re-derive this artifact from that coordinate.

The constant now carries a note saying why it reads the way it does, because
it is the string a prose sweep reaches for first and a comment-only edit is
how it last moved.
2026-08-27 14:00:28 -07:00
zeekay 0b132a8881 Name the thing instead of calling it a door
One word stood for several: the MCP server, one address that accepts requests,
the single way in, and the boundary a credential is validated at. Each site now
names its own sense — endpoint, entry point, the MCP server, the edge, address,
relay — or, where none of those fit, takes the word the surrounding code already
uses.

Prose and comments only, 1:1 line for line. Identifiers keep their names: CSS
classes, DOM ids, struct fields, enum variants, config values and the doc
comments that must open with the identifier they document.
2026-08-23 13:49:39 -07:00
zeekay 9c0d8b259a Stop naming a generator we do not use
The SDK generation heading carried "(Stainless RETIRED, 2026-07)". Retiring
something is worth recording once; carrying the name in a section title keeps it
on the page forever, and this was the last mention of it anywhere in the clients
or the driver.

The section says what the one way IS — hanzo.yaml, openapi-generator, one
invocation in generate.py. That is the whole fact.
2026-08-23 11:38:08 -07:00
zeekay a9d71bcea8 Revert the README count stamp — the count should not be there at all
I added a generator step to keep "N operations over M paths, grouped into K
services" fresh in every SDK README. The right fix was to delete the sentence. A
developer opening a client does not need its inventory; the number tells them
nothing they can act on, and keeping it true costs a generator step, a marker
convention and a parse of the document on every build.

Stamping a number that should not exist is a more elaborate way of being wrong.
2026-08-23 11:05:22 -07:00
zeekay ab911f5a38 Stamp the README counts from the document, because typed ones go stale
Seven SDK READMEs opened by telling a developer the client covers "2,479
operations over 1,814 paths, grouped into 192 services". The document serves
2,259 over 1,620 in 117 — every number wrong, in the first paragraph of the page
each language's users land on. Nobody mistyped them; they were true once and the
document moved, which is what a hand-written count does.

So the numbers are no longer written. A `<!--counts-->` span in the README is
rewritten from the spec the client was actually generated from, on every
generate — the sentence around it stays the repo's own voice, and a README with
no markers is left untouched, so adopting it is per-repo rather than a surprise
rewrite.

Measured by PARSING the document, not by matching it. The first version counted
`^      operationId:` and `^  /`, which is true of cloud's YAML and of nothing
else — this driver hands the generator a JSON copy, so every count came out zero
and stamped "0 operations over 0 paths" into the README it was added to fix. It
also disagreed with itself about services: the regex said 148, the parse says
117, and only one of those is the number of distinct tags on an operation.
2026-08-23 10:39:53 -07:00
zeekay 3cd4ba7648 A language may pin past the fleet when the fleet cannot emit it
dart emitted NOTHING for four releases. openapi-generator 7.14.0, the version
sdks.yaml pins for every language, dies in AbstractDartCodegen.fromProperty with
`JsonSchema cannot be cast to ComposedSchema` on our polymorphic request bodies —
so every run produced an exception and no files, and the drift check reported no
change because there was nothing to compare.

7.19.0 emits it cleanly: measured, 117 api files, no exception. The choice was
to move the fleet or to pin the one language, and moving the fleet regenerates
twelve working clients to repair one — none of which have CI to catch a
regression. So the pin sits where the defect is, and says when to remove it.

One generator stays the rule; `generator_version` is the exception, and an
exception that names its own expiry is cheaper than the churn it avoids.
2026-08-22 07:26:39 -07:00
zeekay 642dc0fa53 drop the IAM operations that describe a verb in a path
hanzoai/iam retired every verb segment from its addresses: a single item is
read, updated and deleted at /v1/iam/<entity>/{owner}/{name}, with the method
carrying the verb. The 45 operations here described /get, /update and /delete
leaves, which nothing serves.

They need no replacement. This document is the source of request-body and
query-parameter shape for the UNTYPED majority of the surface; IAM's operations
are typed in their own repo and carry their schemas through the graft, so the
live table already describes them better than an authored copy can.

Measured on the parsed document rather than the diff: 1796 paths -> 1751, 45
removed, 0 added, and every removed key is a retired IAM address.
2026-08-21 11:40:55 -07:00
zeekay c157c9250b images resolve at oci.hanzo.ai 2026-08-21 09:42:03 -07:00
zeekay 5c2687eb3d spec: name oci.hanzo.ai in the SBOM example and the mirror note
oci.hanzo.ai is the host for images and charts.
2026-08-21 09:39:00 -07:00
zeekay f44c157923 carry the 1 commits stranded on hanzo/openapi
hanzo/openapi has no push mirror, so these never left that host. Merging rather than dropping them; hanzoai/openapi keeps the image.
2026-08-21 09:26:46 -07:00
zeekay b8b05087c9 carry the github copy onto the forge
Both hosts had moved. Resolved each file on what api.hanzo.ai actually serves:

- hanzo.yaml keeps this host's /v1/sentinel/{project}/envelope/. Measured: that
  path answers 403 with and without a trailing slash, /v1/event/{project}/envelope
  answers 404 both ways, and every other sentinel operation in the served document
  is tagged o11y. The published document still names the event path, so it
  describes a route nothing answers.
- publish.py and its test come from github, the only side that defines the
  security scheme it requires. Its literal for the document's repo is corrected to
  hanzo-inc/cloud, which is where the document is held — this host settled that in
  'the lock names the repo that holds the document'.
- capabilities.yaml is the union of both tag sets across all nine domains, 213
  tags from 191 and 120. github's commands and replay are real (GET /v1/commands
  answers 200); this host's leaderboard, treasury, visor and the rest are kept.

pytest: 27 passed.
2026-08-20 21:25:28 -07:00
zeekayandHanzo Dev 6225c15998 one address for the document, in both files that read it
publish.py already knew it: api.hanzo.ai/v1/openapi.json, cloud's own emission
from the process that is actually up. generate.py asked git.hanzo.ai at a locked
ref instead, so two files in one repo named two sources for one document, and
the one every SDK generates through needed HANZO_GIT_TOKEN to read a private
repo.

hanzoai/ci's lane reads the served document and hands it to the generator as
$SPEC, so in CI this path never ran. It ran for people, and it ended at a
credential a contributor could not be given.

.spec-lock still records which document a tree was generated from. A digest that
differs now says cloud has shipped since, rather than refusing — regenerating
onto what production serves is why the function runs.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-20 20:05:08 -07:00
zeekayandHanzo Dev f421a73156 follow the release pointer the rest of the fleet follows
This repo sat on ci v1.0.49 while the fleet moved thirty releases past it.
hanzoai/ci proves each release on its own gate before @v1 follows, so an exact
pin here buys nothing and needs moving by hand to get anything.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-20 19:59:40 -07:00
zeekay 52d313315e the publication pins the live release: v8.5.90, tagged by capability
hanzo.yaml derives from public.yaml at the release api.hanzo.ai serves —
120 capabilities in nine domains, the tag the app that answers. The store
journey speaks the provisioning plane's served ids, and the security gate
asserts the requirement names a defined scheme instead of a spelling.
2026-08-20 19:55:05 -07:00
zeekay fb3721e91c the vocabulary is the capability — held for the release that serves it
capabilities.yaml groups the 116 capabilities (the apps, HIP-0139) into the
nine domains, replacing the 191 path-segment names; the store journey moves
to its served address (/v1/instances/kv, probed 403-vs-404 against the
-zzq9 control). Inert until the pin moves: the both-ways gate compares this
file to the pinned document, and the pinned release still tags by segment.
The re-derive lands when --served accepts the release that tags by app.
2026-08-20 17:47:28 -07:00
zeekayandHanzo Dev 92a8ea9a7d python: take the package path the generator writes, not the spec repo
`packageName: hanzoai.cloud` makes the generator emit `hanzoai/cloud/`, and
python-sdk tracks it at `pkg/hanzoai/cloud`. Neither half is a repository name.
The rename that pointed every DOCUMENT reference at hanzo-inc/cloud swept this
line up too, because a package path with a slash in it reads like one.

Since then the python projection has emitted nothing: the generator wrote
hanzoai/cloud and `take` went looking for hanzo-inc/cloud, so `generate.sh`
failed with "generator emitted no hanzo-inc/cloud" -- which names the repo and
sounds like a fetch problem. Every other language kept working, so the failure
looked specific to python rather than to one substitution.

Verified: with this, python regenerates +25 -114 ~33, the same shape js and
rust produce from the same document.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-20 09:44:50 -07:00
zeekayandHanzo Dev 1b454d99aa say where HANZO_GIT_TOKEN lives, so sealing it once is not half a fix
hanzoai/ci's client lane takes that credential from KMS. This workflow is not
that lane and cannot reach KMS without a second copy of the login, so it takes
an org Actions secret — two homes for one value, and a reader who seals the KMS
one and watches this stay red has been misled by a message that only said
"seal it".

So the message says which is which. The end of it is `--check` moving into
hanzo.yml's `test:` block, where the lane already exports the value into the job
environment and `served` already runs: one credential, one home, one lane, and
this file goes.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-19 23:46:25 -07:00
zeekayandHanzo Dev 170d925a6e the record says why the gate could not run
The gates table's `needs` column carried a diagnosis that had been overtaken by
events, and a wrong diagnosis in the durable record is worse than none: it
blamed a GitHub plan tier and a repo secret named SDK_DISPATCH_TOKEN for
`publish.py --check` never running. Neither is why. The workflow asked
hanzoai/cloud, which is the re-rooted OSS core — twelve commits, no
`openapi.yaml` — and being PUBLIC, the checkout succeeded and the failure
surfaced a step later, where the step's own canned message relabelled it as a
hand edit of hanzo.yaml.

What is still open is the credential, and it is a different sentence.
hanzo-inc/cloud is private and in another org, and the per-job token Hanzo Git
mints reads the run's own repository and anything public — nothing else,
measured on hanzoai/python-sdk run 91449 and again on this repo's own spec sync,
which now names HANZO_GIT_TOKEN and stops there in a second.

Two smaller ones follow the same rule. `--current`'s paragraph explains that the
remote is discovered and never named, then names one; it says which host now.
And `generate.py`'s read takes the fleet's one name for a credential that reads
git.hanzo.ai, so a hand run and hanzoai/ci's client lane ask for the same thing.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-19 23:41:03 -07:00
zeekayandHanzo Dev 98ab849342 publish the release api.hanzo.ai actually serves
The pin was 132 cloud commits old and published three speech routes the running
deployment refutes — GET /v1/generate-text-to-speech-audio-stream, POST
/v1/generate-text-to-speech-audio, POST /v1/process-speech-to-text. skills.py
turns a published operation into a SKILL.md, so those three were live
instructions to an agent to call an address that answers 404.

Cloud's main is not the answer to that. It runs 108 commits ahead of what is
deployed and carries 60 operations api.hanzo.ai does not answer for — the
/v1/instances/*, /v1/sentinel/* and /v1/sites/* families — so re-pinning there
trades three dead endpoints for sixty. The rule is the one `--served` already
states: the newest release the deployment fully answers for. That is
cfc36010d03b, where all 2471 published operations are served and 23 more are
served and not yet published.

Two capabilities arrive with it and had to be placed, which is the one editorial
decision this file keeps. `allowance` is what a plan lets you do before money
moves, so it reads beside `plans` and `pricing`; Observability's `usage` is the
other half and a different question — usage counts what happened, allowance
states what was bought. `edge` is served by the package that serves `projects`
and `sites` and asks what follows a deploy, whether a publish reaches readers
rather than whether it was accepted, so it sits with what does the hosting.

The three speech names leave capabilities.yaml with the routes that carried
them. A capability appears the release it starts being served and leaves the
release it stops.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-19 23:37:38 -07:00
zeekayandHanzo Dev 0df9fb2432 spec sync asks the repository that holds the document
hanzoai/cloud is the re-rooted OSS core: a twelve-commit line sharing no
ancestor with the product and carrying no openapi.yaml at all. It is PUBLIC, so
the workflow's checkout succeeded and publish.py failed one step later with "no
remote of .cloud carries openapi.yaml on `main`" — which the step then threw
away, printing instead its own fixed sentence, that hanzo.yaml had been
hand-edited. It had not: re-derived at its own pinned ref, the committed
artifact is byte-for-byte what that ref projects to. Every push and every hourly
run has reported a drift that never existed.

So the address is the value it always should have been. SPEC_REPO names
hanzo-inc/cloud — where every ref this repo and every SDK has pinned resolves,
and hashes to the digest its lock already carries — and .spec-lock, info.x-spec
and CAPABILITIES.md's header follow it rather than restating it. The receipt was
repointed on its own once and the artifact, the receipt and the test then named
three different repositories; test_the_artifact_names_the_release_it_came_from
now asserts the three AGREE instead of repeating the string a fourth time.

Both canned ::error:: wrappers are gone. A step that replaces a precise
diagnosis with a fixed sentence is worse than a step with no message: publish.py
already says what is wrong and which command fixes it, and `set -e` fails the
step.

hanzo-inc/cloud is private, and the per-job token Hanzo Git mints reads the
run's OWN repository and anything public — nothing else. Measured on
hanzoai/python-sdk run 91449, which named the right repo and still took
`curl: (22) ... 404`. The checkout therefore takes HANZO_GIT_TOKEN, the one name
in this fleet for a credential that reads git.hanzo.ai, and the job says which
credential is missing before actions/checkout can report a private repo as
"repository not found". generate.py's own fetch takes the same name, so one read
needs one credential.

Cloud declares its own `bearer` scheme now, and the projection's addition
stopped adding and started corrupting: setdefault no longer fired while the
document-level `security` it wrote still did, so the published document required
`bearerAuth` and defined nothing by that name. Generated typescript, measured:
2498 bearer call sites from cloud's document, 0 from the projection, leaving 191
files importing a credential helper none of them called. The rule is gone —
cloud says both halves — and test_a_client_can_authenticate refuses a document
that requires a scheme it does not define, whoever supplies it.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-19 23:33:15 -07:00
zeekay bdd7349a84 read git.hanzo.ai with the token it already issues
FORGE_TOKEN was a hand-provisioned PAT kept as an org-wide Actions secret. Hanzo
Git hands every job a token — checkout writes it into http.extraheader with no
secret involved — so this was a second credential home beside KMS that rotted on
its own schedule and bought nothing.

Now GIT_TOKEN, from github.token.
2026-08-19 22:33:19 -07:00
zeekay 00ffd36ab1 say Hanzo Git, which is what it is
"Forge" named nothing in this estate. The product is Hanzo Git, the address is
git.hanzo.ai, and the in-cluster service is hanzo-git.hanzo.svc. A generic word
invented for it sends a reader looking for a system that does not exist.

Comments only. ("unforgeable" stays — different word.)
2026-08-19 22:28:04 -07:00
zeekayandHanzo Dev dae954712a the lock names the repo that holds the document
Every SDK locked its spec to hanzoai/cloud. That repo is an empty mirror shell —
864K on disk, no refs — so the raw fetch answered 404 and the client lane has
failed on every push since. The document is in hanzo-inc/cloud: the locked ref
resolves there, and openapi.yaml at it hashes to exactly the sha256 this lock
already names.

Only the address was wrong. The lane's own digest gate proves the bytes are
unchanged.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-19 20:56:17 -07:00
zeekay 5ca53ab23f the receipt names a commit, and the projection catches up to it
hanzo.yaml described cloud@613cc065 while cloud's main had moved to 38a803e4, so
every SDK and doc page generated from it described a router that had changed.
Re-derived at the tip.

publish.py resolved `ref` to a commit only when one was handed to it; a default
run left the remote-tracking branch it discovered. That name went into
`x-spec.ref`, into CAPABILITIES.md, and into `.spec-lock` — and a branch is not
resolvable in the CI clone that re-derives the artifact, which has no remotes.
Resolving once, before anything reads it, is what makes those three name one
thing and keeps --check able to answer.
2026-08-14 22:36:14 -07:00
zeekay 576b41357a a runtime that cannot run the default client earns a row; twelve others do not
openapi-generator offers thirteen TypeScript and JavaScript targets. Two of
them serve an audience `hanzoai` cannot reach, and the rule that admits them is
stated where the rows are so the other eleven stay refused for a reason rather
than by omission.

fetch: axios brings 27 packages and 4.1 MB; this client declares none, because
`fetch` is the host's. It also hands back the `Response`, so a stream is
readable. `importFileExtension` is what makes its ESM half load in Node, Deno
and a Worker instead of only in a bundler — measured by importing it.

angular: the framework owns the transport and the return type, so an axios
client cannot be made idiomatic there at all — no interceptors, no HttpContext,
no cancellable Observable, no testing backend. `serviceSuffix: Api` is forced:
the API has a product called `base`, whose default class name is the generated
transport's own parent.
2026-08-14 21:11:25 -07:00
zeekay 7839ae66d2 the swift template preserves a branch, not bytes
"the Apple output is byte-identical to the jar's" is not what the override does
and not what was measured: the emitted URLSessionImplementations.swift hashes
differently from the jar's, because it IS the changed file. What the three
canImport guards preserve is which branch each Apple platform compiles — with
one addition, macOS importing MobileCoreServices, which is present there and
whose symbols the pre-11 branch already calls unguarded.
2026-08-14 20:52:31 -07:00
zeekayandHanzo Dev 384cc08eba cpp is a row, and the version floor it left over was a fact about a document
C++ was the last language owning its own invocation, and it gave two reasons.
`templates:` retired the first one for rust already; this retires the second,
which needs saying precisely because it was true when it was written.

The floor said generator 7.24.0 against the 7.14.0 pinned here, because on
7.14.0 ten translation units would not compile through two defects in the
generator's type resolution that no template reaches — mustache interpolates the
strings resolution produces, it cannot recompute a type. Both defects were real.
Both lived in SCHEMAS THE DOCUMENT NO LONGER CARRIES: vector_NamedVectors /
vector_DenseVector under additionalProperties (9 TUs), and an integer-backed
enum declared over utility::string_t and defined over int32_t,
framework_Document.docstatus (1 TU). Neither schema exists at the ref this fleet
reads, so neither defect is reachable and the floor expired with its cause.

Re-measured rather than argued: at cloud@49389cf9, ignoring blank lines and the
generator string each file's header carries, exactly one of 5327 files differs
between 7.14.0 and 7.24.0 — a doc comment on ConsoleSettings::getOidcConfig. On
7.14.0 the library builds with 0 errors (2663 sources, 192 API classes, 2462
models, 2502 operations) and the six example flows build with 0 errors, on
aarch64 Ubuntu 24.04 with g++ 13.3. So the row needs no version of its own and
this does not raise the pin.

The four cpp-restsdk overrides move here as templates/cpp-restsdk/, next to the
flags they go with. They are load-bearing and measured: generating without them
fails with 8 errors, all in ModelBase.h.

One flag, and it is the one six other rows already carry.
o11y.GettableAgentCheckIn publishes integration_config beside integrationConfig
and removed_at beside removedAt so older agents keep working; C++ camel-cases a
property into its accessor, so each pair declared one method twice. Renaming the
accessor keeps both wire keys — measured, all four are present in the emitted
model, each under the document's own name.

`take` is include/ and src/. The generator's CMakeLists.txt, Config.cmake.in,
git_push.sh and README.md sit at the output root under neither, so they are
never copied and need no `drop` entry — the repo keeps its own build contract.

Verified against the tree the departed script produced: `generate.py cpp --check`
reports clean, byte for byte, 5327 files.

Co-authored-by: Hanzo Dev <[email protected]>
2026-08-14 20:37:43 -07:00