One app carried the Hanzo shell and twenty did not, so a reader crossing from
base.hanzo.ai to zen.hanzo.ai left the ecosystem and landed somewhere that only
resembled it. Five of those twenty had hand-rolled a footer of their own —
sixteen lines of copyright and a repo link, written five separate times.
Each app now loads the brand tokens before its own sheet, reports through
docs-analytics under its own product name, and renders HanzoFooter from
@hanzogui/shell — the same 6-column ecosystem footer, defined once, that
apps/docs already used.
A footer written inside a layout was chrome pretending to be content, and it is
gone. A footer written inside a page is content pretending to be chrome: those
keep their words and become sections, so each page has one contentinfo landmark
instead of two.
Three manifests listed @hanzo/font twice in the same object.
Builds verified across the four shapes this repo has: a static export, a
next.config.mjs app, a single-page app with no route groups, and one that
already reported analytics. Every one renders exactly one footer.
Co-authored-by: Hanzo Dev <[email protected]>
docs.hanzo.ai's AI chat now runs entirely on our own stack. The live
/api/chat route was already native (Hanzo gateway) but ungrounded — it
now retrieves from our rag-api index before answering, and cites sources:
- retrieval: rag-api /query — native index over the docs
- generation: Hanzo gateway (api.hanzo.ai/v1, zen-coder-flash)
- sources: provideLinks tool, populated from the indexed metadata
Purged Inkeep repo-wide (only our stack, one way):
- removed the dead third-party Inkeep handler (lib/inkeep -> lib/ai)
- widget credit "Powered by Inkeep AI" -> "Powered by Hanzo AI"
- create-app generator: dead `inkeep` provider -> native `hanzo`
(installs the ai/hanzo registry bundle; INKEEP_API_KEY -> HANZO_API_KEY)
- 4 legacy *-docs apps: de-Inkeeped schema, fixed dangling imports
Zero `inkeep` references remain in the codebase.