api.mzizi.dev is the registry API. It is served by
mzizi-dev/mzizi-api-gateway, a
Hono Cloudflare Worker written in TypeScript. It has no origin, no
database and no Supabase. Everything it serves is a file from the registry repository,
bundled into the Worker when it is built.
It has served api.mzizi.dev since 29 September 2026, when it took over from the
registry’s own Worker.
An earlier plan for this repository was a pure-Rust
workers-rs proxy in front of the
registry’s Next.js handlers. That proxy is retired. The gateway is Hono, and it implements
the whole public /v1 API itself, from files.Using it
GET handler answers OPTIONS
with 204, and every other method with 405. Both /v1/... (canonical) and /api/v1/...
answer. api.mzizi.dev/v1/* redirects here.
Every response carries a header naming the Worker and the registry commit it was built from:
How the data flows
- The registry’s files are the data layer. Components, doctrine, brand, changelog,
skills and samples are files in
mzizi-dev/mzizi-registry. The gateway reads them at build time, not at request time. - The shapes are the registry’s own. The build calls the registry’s readers rather than reimplementing them. The Supabase client is replaced with a stub that throws, so a reader that reached for a database would fail the build instead of shipping an empty answer.
- A registry change reaches the API only through a commit. Moving to newer registry content means changing the pin, which CI checks. Wiring the registry to open that pull request automatically is planned, not built.
What it answers besides data
308for renamed components. Formernyuchi-*names redirect to theirmzizi-*names on/v1/uiand/v1/rs, keeping the sub-path and query. For example,/v1/ui/nyuchi-sidebaranswers308to/v1/ui/mzizi-sidebar.410 Gonefor retired routes:/v1/docs, and the retired axis and layer models under/v1/architecture/.308 /mcptohttps://mcp.mzizi.dev/mcp./.well-known/security.txt, with the contactsecurity@bundu.org.
Four routes answer 503
/v1/ui/{name}/docs, /v1/ui/{name}/versions, /v1/search and
/v1/ai/instructions/{name} answer 503 {"error":"Database not configured"}. So does the
discovery document’s database block, which reads not_configured.
That is not an outage, and there is no database to configure. The registry’s handlers gated
those routes on credentials the live Worker never had, and the gateway kept them
byte-identical so that the cutover changed nothing a client could see. Three of them have
their data in files and can be switched on from files in a later change. Version history is
console data, so /versions stays unserved here.
Parity
The acceptance test for the cutover wasscripts/parity.mjs.
It sends read-only requests to a baseline and a candidate: every route, every component slug
on /v1/ui/{name} and /v1/rs/{name}, the renamed names, the filters, the error paths and
the method handling. It diffs status, Location, content type, the CORS, cache and security
headers, and the body. Intentional differences are listed in the script with their reasons.
Before the domain moved, parity against the deployed Worker ran 1,359 requests with 0
unexplained differences. Only two differences are intentional: the bare /v1 now serves the
discovery document instead of an HTML 404, and an unknown path gets a small JSON 404.
Rollback, in brief
The registry’s own Worker is untouched and still answers on itsworkers.dev address. To
roll back: revert the custom-domain route in the gateway’s wrangler.jsonc first, or the next
deploy takes the domain back; then move api.mzizi.dev from the gateway Worker back to the
registry Worker in the Cloudflare dashboard. The gateway’s README keeps the exact steps.
Developing
CONTRIBUTING.md for changing a route or moving the
pin.