Close the loop the docs deploy was missing: push -> build -> TEST -> deploy ->
re-index, no human in it.
- Test gate validates the export (index.html, docs/index.html, docs/services/
index.html, >=50 pages, /docs carries nav) BEFORE anything ships — exactly the
empty-export and trailingSlash failures that reached prod before.
- Deploy is operator-driven: patch App/docs .spec.image.tag to the immutable
built SHA; hanzo-operator reconciles. No floating tag in the cluster, no CI
kubectl on Deployments. In-cluster runner SA scoped by k8s/docs-cd-rbac.yaml
to get+patch ONLY app/docs (patch deploy = denied).
- Re-index posts to /v1/index-docs so search + zen-coder-flash chat answer from
the shipped content (best-effort, never blocks).
- Rips the Cloudflare Pages + docs-router worker path: docs.hanzo.ai serves
from the in-cluster App via the universe file-provider route. One way.
docs.hanzo.ai is now an App CR (like bot-docs/team-docs/analytics) reconciled
by hanzo-operator into Deployment+Service+Ingress. The hand-rolled
docs-landing manifest is superseded: its ingress was never admitted (the
controller routes via the universe file-provider config, not loose ingresses)
and it hard-coded a probe/port the operator derives. Pinned to the built SHA;
CD bumps .spec.image.tag.
The native serve 404'd on every /docs/* route: the trailingSlash:false export
writes docs.html AND a docs/ dir, so hanzoai/static opens the dir, finds no
docs/index.html, redirects /docs -> /docs/, and dead-ends 404. CF Pages
tolerated flat .html via its own router; a plain file server needs the
directory-index convention. trailingSlash:true -> docs/services/index.html,
which static resolves in place. One convention, portable across any file server.
Probe hit /health (no such file -> 404 -> httpGet treats 4xx as failure ->
pod killed every ~90s). Point it at / (200, or 301->200) so it passes.
The native docs pod CrashLoopBackOff'd: the 0.4.1 static binary has no -404 flag
(flags are -port/-root/-s3-*/-spa), so '/static ... -404 404.html' printed usage and
exited. Serve with '/static -port 3000 -root /public'. Image pulls + starts clean now.
The cross-org push to ghcr.io/hanzoai/docs failed ('permission_denied: The requested
installation does not exist') — the workflow GITHUB_TOKEN can only write packages in
its OWN org (hanzo-docs), not hanzoai. Push to ghcr.io/hanzo-docs/docs instead (same
org as the repo — conventional, self-contained) and point the docs-landing Deployment
at it. Base pull (hanzoai/static:0.4.1, now public) already works; this clears the push.
The native docs image build failed at 'ghcr.io/hanzoai/static:v0.3.1: not found'.
hanzoai/static is public, but there is no v0.3.1 tag — the real tags are 0.3.0 /
0.4.0 / 0.4.1 / latest (no 'v' prefix). Pin the base to 0.4.1 (newest multi-arch
stable) in both the repo Dockerfile and the CI Dockerfile.serve. With this + the bun
fix + public bases, ghcr.io/hanzoai/docs finally builds with real content for the
docs-landing native serve.
Migrate docs.hanzo.ai to the native stack: after the export build, package apps/docs/out
into hanzoai/static and push ghcr.io/hanzoai/docs:{latest,sha} — built on the self-hosted
hanzo-docs-build runner (docker present; 'no GitHub builders' = no GitHub-HOSTED runners).
The in-cluster docs-landing Deployment behind hanzoai/ingress serves docs.hanzo.ai; no
Cloudflare Pages, no docs-router worker (now continue-on-error — being retired; its deploy
token lacks Workers perms anyway). Mirrors the proven deploy-liquid-docs image pattern.
Same recipe generalizes to every doc site: static→hanzoai/static, SPA→hanzoai/spa, behind
hanzoai/ingress via the operator. Pairs with the bun fix that stopped the image /public
from being empty.
The platform-native docs image (ghcr.io/hanzoai/docs, served by hanzoai/static behind
the docs-landing ingress) shipped with an EMPTY /public — every path 404'd. Cause: the
build stage runs 'pnpm build --filter=docs' → build:pre → 'bun ./scripts/*.ts', but
node:22-alpine has no bun, so the Fumadocs export silently produced nothing. Bring the
musl bun binary in from oven/bun:1-alpine (+ libstdc++/libgcc). Same root cause as the
CI bun fix — this is the native-PaaS path (no Cloudflare) for docs.hanzo.ai.
Now that the deploy is unblocked and the Jul-8 'Browse by product' redesign is live,
a rendering bug is visible: every <Cards> grid collapsed to a wall of run-on
sentences (titles, links, and boxes gone). getMDXComponents registered Tabs/Steps/
Files/Accordions but NOT Card/Cards, so MDX rendered them as unknown elements and
kept only the child text. Import Card/Cards from @hanzo/docs-base-ui/components/card
(the path the page already uses) and add them to the component map — the product
card grids on /docs/services and everywhere else now render.
Second blocker on the frozen docs deploy: apps/docs 'build:pre' runs
'bun ./scripts/gen-services-nav.ts && bun ./scripts/pre-build.ts', but the
containerized hanzo-docs-build scale-set runner has no bun preinstalled and the
workflow never set it up — so 'next build' never even started (instant exit 1, no
output, right after 'cache miss, executing'). The sibling deploys (deploy-bot-docs
etc.) already 'uses: oven-sh/setup-bun@v2'; match them. Together with the
best-effort swap fix, this unblocks the whole docs build → the Jul-8 card redesign
finally ships to docs.hanzo.ai.
docs.hanzo.ai has been frozen on pre-Jul-6 content for ~2 weeks: every deploy since
failed at 'Extend swap for large build' (exit 255) — the containerized
hanzo-docs-build scale-set runner can't sudo a swapfile (fallocate fails), which
blocked the build + Cloudflare Pages deploy entirely. So the Jul-8 'Stripe-style
Browse by product' redesign + every doc since never shipped.
Make the swap step best-effort: continue-on-error + '|| true' on each op + a dd
fallback + 'free -h'. The build already caps Node heap at 16 GB and has a 60-min
timeout, so swap is a bonus, not a hard requirement. This unblocks the whole
backlog of committed-but-unshipped docs content.
* docs(architecture): add the platform algebra + redirect collapsed product slugs
New page /docs/architecture/algebra — the compositional lens beside philosophy:
the ~11 primitives (Principal, Tenant, Resource, Policy, Ledger, Meter,
Schedule, Bus, Gateway, Store, Money) every capability composes from, the
declare-a-schema -> inherit persistence/tenancy/audit/metering model on one ORM
+ ZAP, iam2 as the proof (a Principal on ORM+ZAP), and the agent (engine) vs
agents (OSS set) naming distinction. Added to the Architecture nav after
philosophy.
Redirect collapsed/renamed product slugs whose canonical page exists, so no
console deep-link 404s post-merge: featuregate->flags, cron->tasks,
tracker->analytics, connectorruntime->services/auto. ads->marketing and
cms->content omitted until those pages are authored (a 301 to a missing page is
still a dead end).
* docs(redirects): drop tracker->analytics — tracker is a distinct issue-tracker product
clients/tracker is a per-org issue tracker (projects/issues, Linear-style; the
durable replacement for the hanzo.team tracker), not an event/analytics tracker.
It keeps its own /docs/tracker and is not a collapse into analytics. The other
three collapse redirects (featuregate->flags, cron->tasks, connectorruntime->auto)
stand.
The insights-docs product pages told developers to call posthog.init/capture/
getFeatureFlag — a global that DOES NOT EXIST. Our SDK's browser global is
'insights' (@hanzo/insights). Every example was broken; now insights.*.
Also:
- 'The ingest edge accepts PostHog-compatible payloads' -> the standard Insights
event payload. Capture serves ONLY /v1/e, /v1/s, /v1/ai now — the legacy paths
were removed, so the compatibility claim was stale.
- flags: 'Semantics are PostHog-compatible' -> 'stable and fully specified'
(deterministic rollout hash, property operators, variants, payload shapes);
'/v1/flags/decide is an alias for PostHog /decide-style consumers' -> '/decide-
style consumers'.
- infisical example secret POSTHOG_HOST -> INSIGHTS_HOST.
Deliberately NOT changed:
- skills/hanzo-brand.mdx: the naming table names each upstream on purpose
('Not "ComfyUI"', 'Not "Langflow"', 'Not "PostHog"') — it is the doc that
tells writers not to use the upstream name.
- projects/hanzoai/o11y/config/web-settings.json: 'posthog' is a REQUIRED key in
o11y's config schema (a real telemetry integration in the o11y fork). Renaming
the doc without fixing o11y would make the doc lie. Tracked separately.
One root Dockerfile the platform fabric (/v1/runner buildkit) builds: pnpm
NEXT_EXPORT=1 static export → ghcr.io/hanzoai/static:v0.3.1 runtime
(clean-URL .html fallback, -404 404.html, :3000). Replaces the stale
apps/docs nginx wrapper (nginx is banned from the stack) and the retired
GitHub-Actions → Cloudflare Pages deploy path.
Native git.hanzo.ai/hanzo/docs and github.com/hanzo-docs/docs carried the
SAME work on rewritten SHAs (split-brain from parallel pushes). Every native
commit's content already exists on this line; -s ours joins the histories
without changing a byte, so native main can fast-forward and stay canonical.
ARC scale-set runners are org-scoped: the hanzoai pool can never pick up
hanzo-docs jobs, so every deploy queued forever. Point all workflows at the
new hanzo-docs-build-linux-amd64 set (universe infra/k8s/arc/
values-hanzo-docs-build-amd64.yaml).
cloud split the noun: /v1/bots is the run the bot runtime executes, and a
kind=bot machine plus its agent binding is compute, under visor's namespace.
These published specs described the machine at the run's path.
Applied surgically rather than re-copied from hanzoai/openapi: these snapshots
have drifted from that source, so a wholesale copy would sweep in unrelated
changes.
The Smart-routing page closed with "For the methodology and full numbers:" and a
card linking papers.hanzo.ai/hanzo-router. That URL 404s, and no such paper
exists: ~/work/hanzo/papers holds 25 sources, none about routing, and the 77
papers published on papers.hanzo.ai contain nothing on routing, model selection
or routing cost.
So the sentence "We never publish fabricated benchmarks" was followed by a link
to a fabricated citation. The card is removed and the lead-in now says what is
actually true of each number on the page: the 89% mix is a worked illustration,
the RouterBench figure is a third-party public result, and there is no Hanzo
paper to cite.
The zen-router model card stays — huggingface.co/zenlm/zen-router resolves (200).
The generator's contract is that it never breaks the build: if the catalog is
unavailable it keeps the committed meta.json and exits 0. The guard tested the
wrong thing — that `import("@hanzo/products")` resolved — so it only held when
nothing was installed.
`@hanzo/products` on the public registry is an unrelated package (a Svelte
component library), which resolves fine and exports no catalog. The import then
succeeded, `docsCoverage` destructured to undefined, and `build:pre` died with
`TypeError: docsCoverage is not a function` — taking the whole docs build with
it, since it is the first command in the chain.
Checking the API the generator actually calls makes the guard match its contract
for both cases: absent, or present but not the catalog.
Note for whoever owns the catalog: apps/docs declares `@hanzo/products: ^0.1.0`,
which resolves to that unrelated third-party package. Nothing else imports it.
It cannot supply the taxonomy this script wants, so the dependency is worth
removing or repointing at the real catalog — a call for the dependency owner,
not this fix.
turbo runs tasks in strict env mode (2.x default): a task only sees the env
vars declared for it. `build` declared none, so every var the deploy workflow
exports was dropped before the build ran:
NEXT_EXPORT -> next.config gates `output: 'export'` on it. Stripped, the
build emits no out/, and the next workflow step is
`wrangler pages deploy out`.
HANZO_DOCS_SYNC -> pre-build gates the project-docs sync on it. Stripped, the
sync runs — the workflow sets it to 0 precisely so the
committed snapshot is used instead.
NODE_OPTIONS -> the heap ceiling the workflow raises for this build.
`turbo run build --filter=docs --dry=json` reported envMode "strict" with
configured [] and passthrough null; it now lists NEXT_EXPORT, HANZO_DOCS_SYNC
and NODE_OPTIONS.
This regressed in 6167d746c, which moved NEXT_EXPORT and NODE_OPTIONS out of the
app's build script — where they were inline and immune to turbo's env filter —
into the workflow's env block.
The two vars that select what is built (NEXT_EXPORT, HANZO_DOCS_SYNC) belong in
`env`, where they also key the cache: a non-export build and an export build are
not interchangeable artifacts. NODE_OPTIONS only shapes how the build runs, so
it is passThroughEnv and stays out of the hash. The wildcards cover the rest of
the HANZO_DOCS_*/HANZO_SEARCH_* knobs the build scripts read, so the next one
added does not silently vanish.
hanzo.ai's Network, Node and Cloud CTAs link bare paths on docs.hanzo.ai that
never had pages: /network, /network/quickstart, /node, /node/quickstart and
/self-host all 404. Route them to their canonical pages through _redirects, the
one mechanism this site has for HTTP redirects (the static export ignores
next.config redirects()), extending the existing bare-product-path list rather
than adding thin duplicate pages.
The network and self-host story is the same page — content/docs/network.mdx,
"the AI cloud you can run yourself". Running a node is the Node Operator Guide
under proof-of-ai, the one node doc whose live/roadmap table matches the shipped
source. Neither product has a separate quickstart page and neither has a
verified standalone start sequence to write one from, so the guessed /quickstart
children resolve to the canonical page, which opens with its own start steps.
Every target in the file is verified to resolve to real content.
luxfi/aml is a CLEAN-ROOM Go reimplementation — NOT a fork of Jube (third-party C#).
The projects/hanzoai/jube-fork tree (911 files/93M, never published) is Jube's own
docs; hosting it mislabels our work as a fork and contaminates the clean-room
boundary. Remove the tree + its meta.json entry + index.mdx link.
luxfi/aml is a CLEAN-ROOM Go reimplementation — NOT a fork of legacy (third-party C#).
The projects/hanzoai/legacy-fork tree (911 files/93M, never published) is legacy's own
docs; hosting it mislabels our work as a fork and contaminates the clean-room
boundary. Remove the tree + its meta.json entry + index.mdx link.
Ground docs.hanzo.ai in HIP-0127 (V8 · Open Edition). The spine: "the AI cloud
you can run yourself" — one unified binary, hanzo.network is the cloud, category-
first descent by the eight movements, API reference as its own separated surface.
- Sidebar (content/docs/meta.json): flat ~85-item dump with overlapping
ad-hoc labels → the eight canonical movements from openapi/capabilities.yaml
(Identity & Trust · Intelligence · Data · Streams · Observability · Commerce ·
Platform · Applications), as icon-bearing separators (---[Icon]Name---). Files
stay flat — no URL/back-link breakage. openapi/sdks/api removed from the root
descent; they remain the dedicated top-nav surfaces.
- Top nav (components/layouts/shared.tsx): add Docs + Network; API and SDKs kept
as separated surfaces.
- Landing (app/(home)/page.tsx): hero → decentralized spine; ecosystem grid →
the eight movements (category-first); breadth stats bar + models/SDKs/MCP
panels making the full surface visible. Every number traces to a source:
67 caps / 8 movements (capabilities.yaml), 157 models (ai/conf/models.yaml),
706 connectors (cloud/.../catalog.json), 6 SDK langs (openapi/CLAUDE.md).
- Docs home (content/docs/index.mdx): 69-services pitch → the run-it-yourself
spine + the eight-movements grid.
- New content/docs/network.mdx: hanzo.network / self-host — one binary, BYO GPU
or K8s, mine on any device (TEE/CC), free for public+OSS, the language seam is
the wire not FFI.
- New content/docs/architecture/philosophy.mdx: the engineering pedagogy —
one-and-one-way, decomplect, one contract → N SDKs → thin CLIs, ZAP-native.
- architecture/index.mdx: "ten categories" → the eight movements; link
philosophy + network.
Content review only — do not merge yet.
Ground docs.hanzo.ai in HIP-0127 (V8 · Open Edition). The spine: "the AI cloud
you can run yourself" — one unified binary, hanzo.network is the cloud, category-
first descent by the eight movements, API reference as its own separated surface.
- Sidebar (content/docs/meta.json): flat ~85-item dump with overlapping
ad-hoc labels → the eight canonical movements from openapi/capabilities.yaml
(Identity & Trust · Intelligence · Data · Streams · Observability · Commerce ·
Platform · Applications), as icon-bearing separators (---[Icon]Name---). Files
stay flat — no URL/back-link breakage. openapi/sdks/api removed from the root
descent; they remain the dedicated top-nav surfaces.
- Top nav (components/layouts/shared.tsx): add Docs + Network; API and SDKs kept
as separated surfaces.
- Landing (app/(home)/page.tsx): hero → decentralized spine; ecosystem grid →
the eight movements (category-first); breadth stats bar + models/SDKs/MCP
panels making the full surface visible. Every number traces to a source:
67 caps / 8 movements (capabilities.yaml), 157 models (ai/conf/models.yaml),
706 connectors (cloud/.../catalog.json), 6 SDK langs (openapi/CLAUDE.md).
- Docs home (content/docs/index.mdx): 69-services pitch → the run-it-yourself
spine + the eight-movements grid.
- New content/docs/network.mdx: hanzo.network / self-host — one binary, BYO GPU
or K8s, mine on any device (TEE/CC), free for public+OSS, the language seam is
the wire not FFI.
- New content/docs/architecture/philosophy.mdx: the engineering pedagogy —
one-and-one-way, decomplect, one contract → N SDKs → thin CLIs, ZAP-native.
- architecture/index.mdx: "ten categories" → the eight movements; link
philosophy + network.
Content review only — do not merge yet.
- services/index.mdx rebuilt as a Stripe-'Browse by product'-style grid: a
one-binary hero (One API key. One binary. api.hanzo.ai) + get-started cards,
then 10 canonical category sections (AI & Models, Compute, Data, Network,
Security & Identity, Observability, Platform, Web3, Apps, Developer Tools),
45 product cards. Names + one-line descriptions are DERIVED from the canonical
console product registry (@hanzo/products) so docs align with console + hanzo.ai.
All 44 internal links verified to resolve; OSS/standalone forks link out.
- Naming fix (per CTO): 'Hanzo DB' -> 'Hanzo SQL'. Renamed services/db.mdx ->
services/sql.mdx (git mv, /docs/services/sql), title + body normalized, 0
residual 'Hanzo DB'; meta.json 'db' -> 'sql'.
- Removed the duplicate 'Getting Started' (section header + page): the page title
is now 'Introduction' under the 'Getting Started' section.
Follow-ups (scoped, not in this PR): top-nav header (Fumadocs layout), authoring
the ~10 canonical products with no page yet (playground, secrets, projects, ...),
per-OSS-fork external doc merges, and de-duping the top-level vs services/ pages.
Co-authored-by: Hanzo AI <ai@hanzo.ai>
- services/index.mdx rebuilt as a Stripe-'Browse by product'-style grid: a
one-binary hero (One API key. One binary. api.hanzo.ai) + get-started cards,
then 10 canonical category sections (AI & Models, Compute, Data, Network,
Security & Identity, Observability, Platform, Web3, Apps, Developer Tools),
45 product cards. Names + one-line descriptions are DERIVED from the canonical
console product registry (@hanzo/products) so docs align with console + hanzo.ai.
All 44 internal links verified to resolve; OSS/standalone forks link out.
- Naming fix (per CTO): 'Hanzo DB' -> 'Hanzo SQL'. Renamed services/db.mdx ->
services/sql.mdx (git mv, /docs/services/sql), title + body normalized, 0
residual 'Hanzo DB'; meta.json 'db' -> 'sql'.
- Removed the duplicate 'Getting Started' (section header + page): the page title
is now 'Introduction' under the 'Getting Started' section.
Follow-ups (scoped, not in this PR): top-nav header (Fumadocs layout), authoring
the ~10 canonical products with no page yet (playground, secrets, projects, ...),
per-OSS-fork external doc merges, and de-duping the top-level vs services/ pages.
Co-authored-by: Hanzo AI <ai@hanzo.ai>
Corrects the plugin-platform + architecture-index pages on two axes:
1. One-binary reality. The pages framed Hanzo Cloud as 'many services, each its
own repo/image, deployed independently, behind a gateway/ingress tier.' That
is the pre-unification story. hanzoai/cloud is ONE Go binary (cmd/cloud): IAM,
KMS, ingress, billing, MPC, o11y, agents, etc. are native clients/* subsystems
compiled in, served under /v1, mapped to hanzoai/openapi — no separate gateway
(there is no clients/gateway; routing is native clients/ingress). This is the
unified cloud binary (HIP-0106), already substantially shipped. The plugin
platform is reframed as NOT a re-layering: same one binary; plugins just become
PLACED so nodes specialize (run a dynamic subset) — horizontal scale without
fragmenting back into services. Remaining standalone apps (Sign/Dataroom/
Captable) noted honestly as being absorbed, not the end state.
2. Fault model corrected to N=7 / 5-of-7 quorum / f=2 (matches the fixed HIP-0125
+ LaTeX paper + shipped controlplane's 1-based N=7). Fixes the impossible
'five-voter tolerating two failures' (BFT needs N>=3f+1=7, quorum 2f+1=5).
3. Faithful proposed-vs-shipped: the Quasar engine + seven-voter ceremony are
built and tested but deliberately kept OUT of the live serving path (behind
-tags controlplane); placement does not yet drive serving; no cloud.Register
runtime yet. Added a 'dynamic scaling lives in the data plane, voter set is
fixed by design' explanation (BFT cost grows with voters; N data nodes scale
unbounded).
Co-authored-by: Hanzo AI <ai@hanzo.ai>
Corrects the plugin-platform + architecture-index pages on two axes:
1. One-binary reality. The pages framed Hanzo Cloud as 'many services, each its
own repo/image, deployed independently, behind a gateway/ingress tier.' That
is the pre-unification story. hanzoai/cloud is ONE Go binary (cmd/cloud): IAM,
KMS, ingress, billing, MPC, o11y, agents, etc. are native clients/* subsystems
compiled in, served under /v1, mapped to hanzoai/openapi — no separate gateway
(there is no clients/gateway; routing is native clients/ingress). This is the
unified cloud binary (HIP-0106), already substantially shipped. The plugin
platform is reframed as NOT a re-layering: same one binary; plugins just become
PLACED so nodes specialize (run a dynamic subset) — horizontal scale without
fragmenting back into services. Remaining standalone apps (Sign/Dataroom/
Captable) noted honestly as being absorbed, not the end state.
2. Fault model corrected to N=7 / 5-of-7 quorum / f=2 (matches the fixed HIP-0125
+ LaTeX paper + shipped controlplane's 1-based N=7). Fixes the impossible
'five-voter tolerating two failures' (BFT needs N>=3f+1=7, quorum 2f+1=5).
3. Faithful proposed-vs-shipped: the Quasar engine + seven-voter ceremony are
built and tested but deliberately kept OUT of the live serving path (behind
-tags controlplane); placement does not yet drive serving; no cloud.Register
runtime yet. Added a 'dynamic scaling lives in the data plane, voter set is
fixed by design' explanation (BFT cost grows with voters; N data nodes scale
unbounded).
Co-authored-by: Hanzo AI <ai@hanzo.ai>
Bring the docs API reference in line with the source of truth
(hanzoai/openapi): 69 services, zero `/v1/*svc` paths, unified `cloud`
binary (HIP-0106). The committed openapi-specs snapshot had drifted to
38 services because the `openapi-specs/` .gitignore rule silently hid
newly-synced specs from git — CI cannot clone the private openapi repo
and falls back to this checked-in snapshot, so it must be tracked and
complete.
- Sync openapi-specs/ from hanzoai/openapi via scripts/sync-openapi.sh:
31 new service specs (admin, affiliates, agents, authors, authz,
automations, billing, crm, do, eval, exec, framework, functions, git,
graph, integrations, kb, notify, observe, plan, plugin, product,
projects, prompts, provisioning, referrals, security, tasks, templates,
tracker, websearch) + 6 refreshed (cloud, hanzo, platform, pubsub,
visor, zt). All 69 now tracked as the CI snapshot.
- Regenerate the API reference index (meta.json) via
scripts/gen-openapi-pages.ts — 69 pages; the per-service .mdx stay
gitignored (CI regenerates them from the committed specs).
- Add curated cards for all 31 new services to content/docs/openapi/index.mdx
and fix the 38-services counts to 69.
- Cross-link the new agents/functions/tasks guides to their API reference
(scripts/link-api-refs.ts).
- Fix stale service-surface counts in prose: docs index (33+→69),
services index (40+→69), hanzo-openapi skill (26→69, drop stale
33KB/v4.0.0 claims).
- Stop ignoring openapi-specs/: these are the committed CI snapshot;
ignoring them is what caused the drift.
Verified: zero kmssvc/paassvc/projectsvc/s3svc and zero /v1/*svc across
docs; specs==meta==source of truth==69; all 70 specs parse; generator
runs clean and deterministic.
Bring the docs API reference in line with the source of truth
(hanzoai/openapi): 69 services, zero `/v1/*svc` paths, unified `cloud`
binary (HIP-0106). The committed openapi-specs snapshot had drifted to
38 services because the `openapi-specs/` .gitignore rule silently hid
newly-synced specs from git — CI cannot clone the private openapi repo
and falls back to this checked-in snapshot, so it must be tracked and
complete.
- Sync openapi-specs/ from hanzoai/openapi via scripts/sync-openapi.sh:
31 new service specs (admin, affiliates, agents, authors, authz,
automations, billing, crm, do, eval, exec, framework, functions, git,
graph, integrations, kb, notify, observe, plan, plugin, product,
projects, prompts, provisioning, referrals, security, tasks, templates,
tracker, websearch) + 6 refreshed (cloud, hanzo, platform, pubsub,
visor, zt). All 69 now tracked as the CI snapshot.
- Regenerate the API reference index (meta.json) via
scripts/gen-openapi-pages.ts — 69 pages; the per-service .mdx stay
gitignored (CI regenerates them from the committed specs).
- Add curated cards for all 31 new services to content/docs/openapi/index.mdx
and fix the 38-services counts to 69.
- Cross-link the new agents/functions/tasks guides to their API reference
(scripts/link-api-refs.ts).
- Fix stale service-surface counts in prose: docs index (33+→69),
services index (40+→69), hanzo-openapi skill (26→69, drop stale
33KB/v4.0.0 claims).
- Stop ignoring openapi-specs/: these are the committed CI snapshot;
ignoring them is what caused the drift.
Verified: zero kmssvc/paassvc/projectsvc/s3svc and zero /v1/*svc across
docs; specs==meta==source of truth==69; all 70 specs parse; generator
runs clean and deterministic.
The unified-architecture + openapi content branches added workspace deps
(openapi-sampler, @hanzo/docs-base-ui in packages/openapi) and three new
apps (engine-docs, ml-docs, router-docs) without updating the lockfile,
which broke `pnpm install --frozen-lockfile` used by every deploy-*.yml.
Regenerated with the pinned pnpm@11.1.0 (lockfile-only); frozen validation
now passes.
Claude-Session: https://claude.ai/code/session_01XsNmNwzHUSKXfN7gYruUsM
The unified-architecture + openapi content branches added workspace deps
(openapi-sampler, @hanzo/docs-base-ui in packages/openapi) and three new
apps (engine-docs, ml-docs, router-docs) without updating the lockfile,
which broke `pnpm install --frozen-lockfile` used by every deploy-*.yml.
Regenerated with the pinned pnpm@11.1.0 (lockfile-only); frozen validation
now passes.
Claude-Session: https://claude.ai/code/session_01XsNmNwzHUSKXfN7gYruUsM
* docs: redirect /docs/{startups,deploy} → real pages (QA 404 fix)
getting-started references /docs/startups + /docs/deploy but those slugs 404
(the mdx pages didn't survive an earlier merge). Redirect to the pages that
carry the content: getting-started ($5/startup on-ramp) + services/paas (deploy).
* docs: unified docs architecture — hub + hanzo-docs/<team> submodule pattern
Ratify docs.hanzo.ai as the single unified-build hub and define the one way
content joins it, by kind:
- authored -> content/docs/<section> (in-hub or hanzo-docs/<team> submodule)
- generated -> openapi + ZAP SDK generators, gitignored, never hand-written
- ported -> sync-project-docs mirror + upstream attribution
Changes:
- ADR as a rendered docs page (content/docs/contributing/docs-architecture.mdx)
+ nav entry; LLM.md canonical model + dedup/rollout debt.
- Wire hanzo-docs/studio-docs as the reference exemplar: git submodule at
content/docs/studio/ (was a single tracked file). deploy-docs.yml checkout
now fetches submodules recursively.
- Security: cf-pages-deploy.mjs no longer hard-codes a Cloudflare API token;
it is required from env/KMS and fails fast (token must be rotated).
Standalone-vs-hub criteria, API-ref-from-openapi, and SDK-slot wiring are all
documented in the ADR. Aggregation proven: 38 API-ref pages generated from 36
openapi specs; studio section resolves from the submodule on disk.
---------
Co-authored-by: hanzo-dev <dev@hanzo.ai>
* docs: redirect /docs/{startups,deploy} → real pages (QA 404 fix)
getting-started references /docs/startups + /docs/deploy but those slugs 404
(the mdx pages didn't survive an earlier merge). Redirect to the pages that
carry the content: getting-started ($5/startup on-ramp) + services/paas (deploy).
* docs: unified docs architecture — hub + hanzo-docs/<team> submodule pattern
Ratify docs.hanzo.ai as the single unified-build hub and define the one way
content joins it, by kind:
- authored -> content/docs/<section> (in-hub or hanzo-docs/<team> submodule)
- generated -> openapi + ZAP SDK generators, gitignored, never hand-written
- ported -> sync-project-docs mirror + upstream attribution
Changes:
- ADR as a rendered docs page (content/docs/contributing/docs-architecture.mdx)
+ nav entry; LLM.md canonical model + dedup/rollout debt.
- Wire hanzo-docs/studio-docs as the reference exemplar: git submodule at
content/docs/studio/ (was a single tracked file). deploy-docs.yml checkout
now fetches submodules recursively.
- Security: cf-pages-deploy.mjs no longer hard-codes a Cloudflare API token;
it is required from env/KMS and fails fast (token must be rotated).
Standalone-vs-hub criteria, API-ref-from-openapi, and SDK-slot wiring are all
documented in the ADR. Aggregation proven: 38 API-ref pages generated from 36
openapi specs; studio section resolves from the submodule on disk.
---------
Co-authored-by: hanzo-dev <dev@hanzo.ai>
getting-started references /docs/startups + /docs/deploy but those slugs 404
(the mdx pages didn't survive an earlier merge). Redirect to the pages that
carry the content: getting-started ($5/startup on-ramp) + services/paas (deploy).