Restore documentation layer — match current substrate
ROADMAP: done items moved out of "Next" (codegen rewrite, SSR bridge, edge manifest, X-Mizan-Invalidate, return-type branching, affects_params, kernel extraction, two-stage codegen, mizan-ts). Real "Next" in: framework-adapter wrapper layer (MizanContext + useMizan + DjangoError on top of the kernel) for React/Vue/Svelte; A1–A4 from ISSUES.md. CLAUDE: 4-package layout replaced with the actual 7-package layered architecture (backend protocol adapters + frontend kernel + framework adapters + SSR worker). "STALE codegen" section rewritten to describe what's emitted vs. the wrapper layer that isn't yet. docs/ now tracked (6 files). AFI_ARCHITECTURE rewritten — replaced the speculative `mizan-ast`/`mizan-csr`/`mizan-rpc`/`mizan-schema` package names with the real layout, dropped KDL-schema language for the actual schema-export format. The other 5 docs/ files were already current and are tracked as-is. ARCHITECTURE-REWORK.md deleted — same expert review is re-tracked in the fresher ISSUES.md, two parallel trackers was sediment. README.md deleted — drift was beyond surgical fixes (`mizan_clients.py` convention, `<DjangoContext>` provider, removed `@compose` and `context='local'`, wrong codegen output filenames, 3-package structure vs. 7). Rewrite waits for the wrapper-layer codegen to land so user-facing examples reflect reality. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
177
ROADMAP.md
177
ROADMAP.md
@@ -1,88 +1,50 @@
|
||||
# Mizan Roadmap
|
||||
|
||||
## v1 — Django + React
|
||||
## v1 — Django + Multi-Framework (React, Vue, Svelte)
|
||||
|
||||
### Done
|
||||
|
||||
- **@client decorator** — `context=`, `affects=`, `auth=`, `websocket=`
|
||||
- **ReactContext class** — type-safe context/affects references with linting
|
||||
- **Named contexts** — functions sharing a context name are grouped into one provider and one fetch
|
||||
- **`@client` decorator** — `context=`, `affects=`, `auth=`, `websocket=`, `private=`, `route=`, `methods=`, `rev=`, `cache=`
|
||||
- **`ReactContext` class** — type-safe context/affects references with linting
|
||||
- **Named contexts** — functions sharing a context name grouped into one provider and one fetch
|
||||
- **Context bundling endpoint** — `GET /api/mizan/ctx/<name>/` returns all functions in one response
|
||||
- **Server-driven invalidation (JSON body)** — mutation responses carry `{"result": ..., "invalidate": [...]}`
|
||||
- **Scoped invalidation** — runtime supports `invalidate: [{context: "user", params: {user_id: 5}}]`
|
||||
- **Param elevation** — shared params become required provider props, non-shared become optional
|
||||
- **Schema export** — `x-mizan-functions` + `x-mizan-contexts` for codegen
|
||||
- **`X-Mizan-Invalidate` header** — second invalidation transport for view-path responses (redirects, HTML)
|
||||
- **Return-type branching** — data return → RPC path; `HttpResponse` return → view path
|
||||
- **Scoped invalidation** — `affects_params` lambda; runtime supports `{context, params}` form
|
||||
- **Auth guards** — `auth=True`, `auth='staff'`, `auth='superuser'`, `auth=callable`
|
||||
- **JWT + session auth** — auto-detected, CSRF handled
|
||||
- **MWT** — Mizan Web Token for Edge cache keying (separate secret from JWT/cache)
|
||||
- **Shapes** — Pydantic + django-readers for typed query projections
|
||||
- **WebSocket channels** — real-time bidirectional communication
|
||||
- **Codegen** — generates typed React providers, hooks, mutations from schema
|
||||
- **Protocol-managed caching** — `no-store` on all origin responses, deterministic JSON on context GETs
|
||||
- **HMAC cache keying** — origin-side cache with cross-language HMAC conformance (Python + TypeScript pin)
|
||||
- **Edge manifest** — `python manage.py export_edge_manifest`; both RPC and view-path functions
|
||||
- **SSR bridge** — Django template backend → persistent Bun subprocess via JSON-RPC
|
||||
- **`mizan-runtime` kernel** — framework-agnostic imperative client primitives (data/status/error owned by kernel)
|
||||
- **Two-stage codegen** — Stage 1 emits framework-agnostic protocol layer; Stage 2 emits per-framework hooks (React, Vue, Svelte)
|
||||
- **`mizan-ts`** — TypeScript backend adapter; proves the protocol is language-agnostic
|
||||
|
||||
### Next: X-Mizan-Invalidate Header
|
||||
---
|
||||
|
||||
Second invalidation transport. For view responses (redirects, HTML), invalidation goes in an HTTP header instead of the JSON body. Both transports are first-class AFI spec.
|
||||
### Next (in progress)
|
||||
|
||||
- Header format: `X-Mizan-Invalidate: user;user_id=5, notifications`
|
||||
- Comma-separated contexts, semicolon-separated params per context
|
||||
- Decorator auto-adds header to any HttpResponse with `affects=`
|
||||
- Edge reads this header to purge cached pages
|
||||
- Runtime also reads it on XHR/fetch responses (htmx path)
|
||||
- **React adapter wrapper layer** — codegen emits `MizanContext` provider, `useMizan` hook, `DjangoError` class on top of the `mizan-runtime` kernel. Equivalent wrapper layers for Vue and Svelte adapters. The harness in `examples/django-react-site` is blocked on this.
|
||||
- **Legacy `MizanProvider` removal (A1)** — `mizan-react/src/context.tsx` (~750 lines) replaced by codegen-emitted wrappers. Blocks v1 `mizan-react` publishing.
|
||||
- **Forms migration to kernel (A3)** — `mizan-react/src/forms.ts` (~1163 lines) currently consumes legacy `MizanProvider`. Rewrite to use `mizanCall` from the kernel. Blocks A1.
|
||||
- **Allauth extraction (A2)** — `legacy/allauth/` becomes `mizan-django-allauth` package consuming Mizan's public API.
|
||||
- **Vue/Svelte e2e validation (A4)** — example apps exercising a live backend end-to-end, like `examples/django-react-site` does for React.
|
||||
- **Test coverage gaps** — T1–T12 in `ISSUES.md` (kernel state machine, view-path purge, SSR thread safety, retry logic, cross-language HMAC pin, etc.)
|
||||
|
||||
### Next: Return-Type Branching
|
||||
---
|
||||
|
||||
`@client` serves both RPC developers (React/SPA) and view developers (htmx/templates). Return type determines behavior:
|
||||
### Quality
|
||||
|
||||
- **Data return** (dict, Shape, BaseModel) → RPC path. Generates typed hooks. Invalidation in JSON body.
|
||||
- **HttpResponse return** (render, redirect) → View path. No codegen. Invalidation in `X-Mizan-Invalidate` header.
|
||||
|
||||
Same decorator. Same `affects=`. Same invalidation graph. Two paths.
|
||||
|
||||
### Next: affects_params
|
||||
|
||||
Scoped invalidation with a lambda that extracts which params were affected:
|
||||
|
||||
```python
|
||||
@client(affects='user', affects_params=lambda req: {'user_id': req.user.pk})
|
||||
def update_name(request, name: str) -> dict:
|
||||
...
|
||||
```
|
||||
|
||||
Produces `invalidate: [{context: "user", params: {user_id: 5}}]` in JSON body or `X-Mizan-Invalidate: user;user_id=5` in header.
|
||||
|
||||
### Next: Edge Manifest
|
||||
|
||||
`mizan-generate --manifest` compiles the decorator registry + Django URL conf into static JSON for Edge:
|
||||
|
||||
```json
|
||||
{
|
||||
"contexts": {
|
||||
"user": {
|
||||
"endpoints": ["/api/mizan/ctx/user/"],
|
||||
"views": ["/profile/:user_id/"],
|
||||
"params": ["user_id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Edge reads the manifest at deploy time. When it receives `X-Mizan-Invalidate: user;user_id=5`, it resolves URL patterns with params and purges `/profile/5/` and `/api/mizan/ctx/user/?user_id=5`.
|
||||
|
||||
Generated alongside React code. Covers both RPC and view-path functions.
|
||||
|
||||
### Next: Codegen Rewrite
|
||||
|
||||
Generated code uses the runtime directly (`mizanFetch`, `mizanCall`, `registerContext`) instead of the legacy `MizanProvider` pattern. Mutations have zero invalidation knowledge — the runtime reads the server response.
|
||||
|
||||
### Next: SSR Bridge
|
||||
|
||||
Django renders React components server-side via a persistent Bun subprocess.
|
||||
|
||||
- Bun worker: stdin/stdout JSON-RPC, `renderToString`, component registry
|
||||
- Django bridge: subprocess management, IPC, request synthesis
|
||||
- Template tag: `{% mizan_render "ProfilePage" user_profile=profile %}`
|
||||
- Hydration: `window.__MIZAN_SSR_DATA__` consumed by generated providers
|
||||
- Generated contexts check SSR data before first fetch
|
||||
- **H5** — Mutation hooks expose no loading/error state
|
||||
- **H7** — Redis SCAN blocks request path at scale
|
||||
- **H8** — Svelte codegen uses Svelte 4 stores; should use Svelte 5 runes
|
||||
- **H9** — Svelte `destroy()` not auto-called (memory leak)
|
||||
- **H12** — Forms `triggerValidation` captures stale data
|
||||
- Medium issues (M1–M18) per developer judgment
|
||||
|
||||
---
|
||||
|
||||
@@ -92,7 +54,7 @@ Django renders React components server-side via a persistent Bun subprocess.
|
||||
|
||||
Cloudflare Workers for automatic edge caching.
|
||||
|
||||
- Reads the Edge manifest to configure cache rules
|
||||
- Reads the edge manifest to configure cache rules
|
||||
- Context GETs cached at edge, keyed by context name + params
|
||||
- Reads `X-Mizan-Invalidate` header from mutation responses to purge caches
|
||||
- Reads JSON `invalidate` key from RPC responses for the same purpose
|
||||
@@ -118,74 +80,13 @@ One-command deployment for Django + React apps.
|
||||
|
||||
---
|
||||
|
||||
## Protocol Spec (AFI)
|
||||
## Reference
|
||||
|
||||
The protocol is the product. Two invalidation transports. Every endpoint CDN-ready.
|
||||
Wire protocol shapes (context fetch, mutation call, invalidation transports) are documented in `CLAUDE.md`. Architectural details for specific subsystems live in `docs/`:
|
||||
|
||||
### Context fetch
|
||||
|
||||
```
|
||||
GET /api/mizan/ctx/<name>/?param=value
|
||||
|
||||
200 OK
|
||||
Cache-Control: no-store
|
||||
|
||||
{
|
||||
"function_a": { ... },
|
||||
"function_b": [ ... ]
|
||||
}
|
||||
```
|
||||
|
||||
### Mutation call (RPC path — JSON body transport)
|
||||
|
||||
```
|
||||
POST /api/mizan/call/
|
||||
Cache-Control: no-store
|
||||
|
||||
{
|
||||
"result": { ... },
|
||||
"invalidate": ["context_name"]
|
||||
}
|
||||
```
|
||||
|
||||
### Mutation call (View path — header transport)
|
||||
|
||||
```
|
||||
POST /profile/update/
|
||||
302 Found
|
||||
Location: /profile/5/
|
||||
Cache-Control: no-store
|
||||
X-Mizan-Invalidate: user;user_id=5, notifications
|
||||
```
|
||||
|
||||
### Scoped invalidation (JSON)
|
||||
|
||||
```json
|
||||
{
|
||||
"result": { ... },
|
||||
"invalidate": [
|
||||
"notifications",
|
||||
{ "context": "user", "params": { "user_id": 5 } }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### Scoped invalidation (Header)
|
||||
|
||||
```
|
||||
X-Mizan-Invalidate: user;user_id=5, notifications
|
||||
```
|
||||
|
||||
### Edge manifest
|
||||
|
||||
```json
|
||||
{
|
||||
"contexts": {
|
||||
"user": {
|
||||
"endpoints": ["/api/mizan/ctx/user/"],
|
||||
"views": ["/profile/:user_id/"],
|
||||
"params": ["user_id"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
- `docs/AFI_ARCHITECTURE.md` — package architecture, kernel model, adapter strategy
|
||||
- `docs/CACHE_KEYING.md` — HMAC cache key derivation
|
||||
- `docs/MWT_SPEC.md` — Mizan Web Token format
|
||||
- `docs/SSR_ARCHITECTURE.md` — Django template backend, Bun bridge
|
||||
- `docs/PSR_VS_EDGE.md` — protocol-level rendering vs. paid Edge layer
|
||||
- `docs/PRODUCT_ARCHITECTURE.md` — product surface and pricing tiers
|
||||
|
||||
Reference in New Issue
Block a user