Files
mizan/docs/AFI_ARCHITECTURE.md
Ryth Azhur cc887fb1f6 Move codegen out of mizan-django: protocol/mizan-generate/
The codegen consumes a schema from any backend and emits typed client
code for any frontend — it doesn't belong inside a backend adapter.
That placement was historical sediment from when there was only a
Django backend; it predates the AFI generalization.

New top-level slot: `protocol/` for protocol-level tooling. Tree is
now:

  backends/    server protocol adapters
  frontends/   client kernel + per-framework adapters
  cores/       shared language-level primitives
  protocol/    protocol-level tooling
  workers/     runtime workers / bridges

Codegen moves to `protocol/mizan-generate/`. Same file layout under
`generator/` (cli.mjs, lib/), preserved via git mv.

Package metadata cleaned up:
- name: "generate" (placeholder) → "mizan-generate"
- description filled in
- type: module (cli.mjs is .mjs ESM, was previously declared "commonjs")
- bin entry added so `npx mizan-generate --config <config.mjs>` works
  once the package is published, instead of `node path/to/cli.mjs`.

Path-reference fixups:
- backends/mizan-django/README.md: `node path/to/...` → `npx mizan-generate`
- backends/mizan-fastapi/README.md: same
- ISSUES.md: file paths in three issue entries
- CLAUDE.md: codegen description + Package Layout section refreshed
  (added protocol/, mizan-fastapi entry, mizan-python entry)
- docs/AFI_ARCHITECTURE.md: Package Layout refreshed identically

Verified codegen runs from new location: regenerated the FastAPI
example harness's api/ output, identical to pre-move.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 00:16:11 -04:00

93 lines
3.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AFI Architecture
Mizan is an **Application Framework Interface (AFI)** — the
server-client unification layer.
## Package layout
Tree organized by role.
```
backends/ server protocol adapters
mizan-django/ Django adapter
mizan-fastapi/ FastAPI adapter (AFI-common scope)
mizan-ts/ TypeScript adapter (proves the protocol is language-agnostic)
frontends/ client kernel + per-framework adapters
mizan-base/ framework-agnostic kernel; owns data, status, error; adapters subscribe
mizan-react/ React contexts + hooks over the kernel
mizan-vue/ Vue composables over the kernel
mizan-svelte/ Svelte stores/runes over the kernel
cores/ shared language-level primitives
mizan-python/ @client decorator, registry, MWT, HMAC cache keys
protocol/ protocol-level tooling
mizan-generate/ codegen — schema in, typed client out
workers/ runtime workers / bridges
mizan-ssr/ Bun subprocess used by the Django template backend
```
## Two orthogonal products
- **RPC** — typed client generation via codegen
- **SSR** — server rendering via the Bun bridge
Independent and composable. Either ships standalone; together they
compose.
## Kernel model
The client kernel (`mizan-base`) is the one hard thing. Per-
framework adapters are thin idiomatic wrappers around it. Codegen
emits typed bindings against the framework adapter's surface, not
against the raw kernel — so a React developer gets `useEcho()` and
`<MizanContext>`, a Vue developer gets `useEcho()` composables, a
Svelte developer gets readable stores. Same kernel underneath.
## KDL is the IR
The Mizan IR is **KDL** — the LLVM-IR-equivalent of the system. Every
backend adapter produces KDL describing its registered functions,
contexts, types, and invalidation graph. Every codegen target consumes
KDL. KDL is the contract; everything else (REST envelopes, OpenAPI
documents, framework idioms) is sediment around it.
The IR must be validated against multiple adapters before it is
considered stable. Single-adapter validation hides assumptions —
divergence between adapters is what the IR exists to prevent.
Forward-direction primitives:
- `cores/mizan-python` builds the IR from registered functions
(`build_ir()` walks `mizan_core.registry`, emits KDL)
- A `mizan-schema` package (forthcoming) holds the canonical KDL
grammar / type system definition that every adapter targets
- Codegen reads KDL directly — no OpenAPI envelope, no
`openapi-typescript`, no per-backend converter divergence
- Edge manifest, MWT claims, and other protocol artifacts all derive
from the same KDL
**Current implementation is transitional.** Today the codegen consumes
OpenAPI 3.0 (`x-mizan-functions` + `x-mizan-contexts` extensions over
Pydantic→JSON-Schema), produced via Django Ninja or FastAPI's native
generator. That layered indirection is what introduces adapter
divergence (see the AFI conformance suite). KDL-as-IR collapses it.
## Launch surface
Python (Django) + React. Vue and Svelte ship as v1 alongside React.
TypeScript backend (`mizan-ts`) proves the protocol is portable.
## Why the AFI shape
Quadratic ecosystem growth (N server adapters × M client adapters)
collapses to linear (one adapter per stack) when both sides
communicate through a shared protocol.
## Invariants
- All cross-package communication goes through the protocol. No
direct cross-package dependencies.
- New adapters land as new packages, not as modifications to existing
ones.
- Framework adapters wrap the kernel in framework idioms — they
don't bypass it. Codegen targets the adapter, not the raw kernel.