Added LICENSE

This commit is contained in:
2026-06-04 03:38:26 -04:00
parent 776e0cf27a
commit 4effcc7597
21 changed files with 201 additions and 70 deletions

95
LICENSE Normal file
View File

@@ -0,0 +1,95 @@
Copyright (c) 2026 Ryth Azhur
Elastic License 2.0
URL: https://www.elastic.co/licensing/elastic-license
## Acceptance
By using the software, you agree to all of the terms and conditions below.
## Copyright License
The licensor grants you a non-exclusive, royalty-free, worldwide,
non-sublicensable, non-transferable license to use, copy, distribute, make
available, and prepare derivative works of the software, in each case subject to
the limitations and conditions below.
## Limitations
You may not provide the software to third parties as a hosted or managed
service, where the service provides users with access to any substantial set of
the features or functionality of the software.
You may not move, change, disable, or circumvent the license key functionality
in the software, and you may not remove or obscure any functionality in the
software that is protected by the license key.
You may not alter, remove, or obscure any licensing, copyright, or other notices
of the licensor in the software. Any use of the licensors trademarks is subject
to applicable law.
## Patents
The licensor grants you a license, under any patent claims the licensor can
license, or becomes able to license, to make, have made, use, sell, offer for
sale, import and have imported the software, in each case subject to the
limitations and conditions in this license. This license does not cover any
patent claims that you cause to be infringed by modifications or additions to
the software. If you or your company make any written claim that the software
infringes or contributes to infringement of any patent, your patent license for
the software granted under these terms ends immediately. If your company makes
such a claim, your patent license ends immediately for work on behalf of your
company.
## Notices
You must ensure that anyone who gets a copy of any part of the software from you
also gets a copy of these terms.
If you modify the software, you must include in any modified copies of the
software prominent notices stating that you have modified the software.
## No Other Rights
These terms do not imply any licenses other than those expressly granted in
these terms.
## Termination
If you use the software in violation of these terms, such use is not licensed,
and your licenses will automatically terminate. If the licensor provides you
with a notice of your violation, and you cease all violation of this license no
later than 30 days after you receive that notice, your licenses will be
reinstated retroactively. However, if you violate these terms after such
reinstatement, any additional violation of these terms will cause your licenses
to terminate automatically and permanently.
## No Liability
*As far as the law allows, the software comes as is, without any warranty or
condition, and the licensor will not be liable to you for any damages arising
out of these terms or the use or nature of the software, under any kind of
legal claim.*
## Definitions
The **licensor** is the entity offering these terms, and the **software** is the
software the licensor makes available under these terms, including any portion
of it.
**you** refers to the individual or entity agreeing to these terms.
**your company** is any legal entity, sole proprietorship, or other kind of
organization that you work for, plus all organizations that have control over,
are under the control of, or are under common control with that
organization. **control** means ownership of substantially all the assets of an
entity, or the power to direct its management and policies by vote, contract, or
otherwise. Control can be direct or indirect.
**your licenses** are all the licenses granted to you for the software under
these terms.
**use** means anything you do with the software requiring one of your licenses.
**trademark** means trademarks, service marks, and similar rights.

142
README.md
View File

@@ -1,90 +1,122 @@
# Mizan # Mizan
An **Application Framework Interface (AFI)** — one decorator on a server function, a Mizan is an Application Framework Interface (AFI). A single `@client` decorator on a
typed client generated, invalidation automatic, caching protocol-driven. Any backend, server function generates a typed frontend client; cache invalidation and caching are
any frontend, one wire protocol. handled by the protocol.
For the wire protocol, package layout, and codegen state, see [`CLAUDE.md`](CLAUDE.md). ```python
Architecture deep-dives live in [`docs/`](docs/). Open work is tracked in from mizan import client, ReactContext
[`ROADMAP.md`](ROADMAP.md) and [`ISSUES.md`](ISSUES.md).
--- UserContext = ReactContext('user')
## Backend Adapter Parity # Context function — bundled into GET /api/mizan/ctx/user/
@client(context=UserContext)
def user_profile(request, user_id: int) -> UserShape:
return UserShape.query(lambda qs: qs.filter(pk=user_id))[0]
**Django is the maximal rubric** — it implements the full AFI surface. Every other # Mutation — invalidation scoped automatically by matching param name
adapter is measured against it. A cell is marked supported only when *that adapter* @client(affects=UserContext)
wires the capability into its own dispatch surface (not merely that a shared core def update_profile(request, user_id: int, name: str) -> dict:
primitive exists). ...
```
Legend: ✅ full · ◑ partial · ❌ absent · — not applicable to this transport Adapters exist for Django, FastAPI, Rust/Axum, Tauri, and TypeScript. Django is the
reference implementation; per-adapter support is inventoried below.
> **Status:** Mizan is not production-tested. It passes its own test suites but has not
> been run in a production deployment. Treat it as pre-release.
## Documentation
- [`docs/`](docs/) — architecture references: AFI, SSR, cache keying, MWT, PSR vs. Edge
- [`ROADMAP.md`](ROADMAP.md) · [`ISSUES.md`](ISSUES.md) — planned work and known gaps
## Backend adapters
Every adapter implements the same AFI wire protocol. The matrix below inventories
support per adapter, grouped to separate protocol guarantees from Django-specific
features (forms, ORM projection, auth providers, SSR). A cell counts as supported only
when that adapter wires the capability into its own dispatch surface, not merely that a
shared core primitive exists.
Legend: ✅ supported · ◑ partial · ❌ not implemented · — not applicable to this transport
### Protocol core
The surface every Mizan adapter implements.
| Capability | Django | FastAPI | Rust / Axum | Tauri | TypeScript | | Capability | Django | FastAPI | Rust / Axum | Tauri | TypeScript |
|---|:---:|:---:|:---:|:---:|:---:| |---|:---:|:---:|:---:|:---:|:---:|
| RPC call dispatch (`{result, invalidate}`) | ✅ | ✅ | ✅ | ✅ ¹ | ✅ | | RPC call dispatch (`{result, invalidate}`) | ✅ | ✅ | ✅ | ✅ ¹ | ✅ |
| Named-context bundle fetch | ✅ | ✅ | ✅ | ✅ | ✅ | | Named-context bundle fetch | ✅ | ✅ | ✅ | ✅ | ✅ |
| Invalidation — JSON body | ✅ | ✅ | ✅ | ✅ | ✅ | | Invalidation — JSON body | ✅ | ✅ | ✅ | ✅ | ✅ |
| Invalidation — `X-Mizan-Invalidate` header | ✅ | ❌ | ❌ | — ¹ | ✅ |
| Invalidation auto-scoping (three-tier) | ✅ | ✅ | ✅ | ✅ | ✅ | | Invalidation auto-scoping (three-tier) | ✅ | ✅ | ✅ | ✅ | ✅ |
| Function discovery / registration | ✅ | ✅ | ✅ | ✅ | ✅ |
| Codegen IR export (KDL) | ✅ | ✅ | ✅ ⁶ | ✅ ⁶ | — ⁸ |
### Edge, cache & enforcement
Protocol transports and guarantees co-equal with the body channel in the spec.
| Capability | Django | FastAPI | Rust / Axum | Tauri | TypeScript |
|---|:---:|:---:|:---:|:---:|:---:|
| Invalidation — `X-Mizan-Invalidate` header | ✅ | ❌ | ❌ | — ¹ | ✅ |
| Auth-guard enforcement (`auth=…` rejects) | ✅ | ✅ | ❌ ⁵ | ◑ ⁵ | ❌ |
| Origin-side HMAC cache | ✅ | ❌ | ❌ | ❌ | ✅ | | Origin-side HMAC cache | ✅ | ❌ | ❌ | ❌ | ✅ |
| WebSocket channels | ✅ | ❌ | ◑ ² | | | | Edge manifest export | ✅ | ❌ | | | |
| PSR (`render_strategy` in manifest) | ✅ | ❌ | ❌ | — | ✅ |
| Session / CSRF init endpoint | ✅ | ◑ ⁷ | ◑ ⁷ | — | ❌ |
> **Caveat:** Rust/Axum and Tauri accept `auth=` on a function but do not yet enforce
> it — do not rely on `auth=` for access control on those adapters.
### Stack extensions (Django)
Django ecosystem features Mizan wraps. Other adapters provide these only where the
target stack calls for them.
| Capability | Django | FastAPI | Rust / Axum | Tauri | TypeScript |
|---|:---:|:---:|:---:|:---:|:---:|
| WebSocket channels (declared transport) | ✅ | ❌ | ◑ ² | ❌ | ❌ |
| Forms (schema / validate / submit) | ✅ | ❌ | ◑ ³ | ❌ | ❌ | | Forms (schema / validate / submit) | ✅ | ❌ | ◑ ³ | ❌ | ❌ |
| Formsets | ✅ | ❌ | ❌ | ❌ | ❌ | | Formsets | ✅ | ❌ | ❌ | ❌ | ❌ |
| API shapes (ORM query projection) ⁴ | ✅ | — | — | — | — | | API shapes (ORM query projection) ⁴ | ✅ | — | — | — | — |
| Auth guards (`auth=True/'staff'/'superuser'/callable`) | ✅ | ✅ | ❌ | ◑ ⁵ | ❌ |
| JWT auth (access / refresh, session validation) | ✅ | ❌ | ❌ | ❌ | ❌ | | JWT auth (access / refresh, session validation) | ✅ | ❌ | ❌ | ❌ | ❌ |
| MWT (edge identity token) | ✅ | ❌ | ❌ | — | ❌ | | MWT (edge identity token) | ✅ | ❌ | ❌ | — | ❌ |
| SSR bridge | ✅ | ❌ | ❌ | — | ❌ | | SSR bridge | ✅ | ❌ | ❌ | — | ❌ |
| PSR (`render_strategy` in manifest) | ✅ | ❌ | ❌ | — | ✅ |
| Edge manifest export | ✅ | ❌ | ❌ | — | ✅ |
| Codegen IR export (KDL) | ✅ | ✅ | ✅ ⁶ | ✅ ⁶ | ❌ |
| Session / CSRF init endpoint | ✅ | ◑ ⁷ | ◑ ⁷ | — | ❌ |
| Function discovery / registration | ✅ | ✅ | ✅ | ✅ | ✅ |
| Auth-provider integration (allauth) | ✅ | ❌ | ❌ | ❌ | ❌ | | Auth-provider integration (allauth) | ✅ | ❌ | ❌ | ❌ | ❌ |
**Notes** **Notes**
1. Tauri's transport is Tauri IPC (a single `#[tauri::command]` envelope), not HTTP. 1. Tauri's transport is Tauri IPC (a single `#[tauri::command]` envelope), not HTTP.
Invalidation rides in the JSON response body; there is no header channel, so the Invalidation rides in the JSON response body; there is no header channel.
header row is N/A.
2. Rust/Axum declares `Transport::Websocket` in the IR/macro but routes no Axum 2. Rust/Axum declares `Transport::Websocket` in the IR/macro but routes no Axum
WebSocket handler yet. WebSocket handler yet.
3. Rust/Axum carries `is_form`/`form_role` trait stubs but no validate/submit 3. Rust/Axum carries `is_form`/`form_role` trait stubs but no validate/submit endpoint.
endpoint.
4. "API shapes" is Django's django-readers queryset projection — ORM-coupled. Every 4. "API shapes" is Django's django-readers queryset projection — ORM-coupled. Every
adapter carries typed input/output through the KDL IR; the *projection primitive* adapter carries typed input/output through the KDL IR; the projection primitive
itself is Django-only. itself is Django-only.
5. Tauri's `FunctionSpec` carries `auth`/`private` fields, but the dispatch path does 5. Tauri's `FunctionSpec` carries `auth`/`private` fields; the dispatch path does not
not enforce them. enforce them. Rust/Axum has no enforcement either.
6. Rust/Axum and Tauri *are* the IR authority via the `#[mizan::client]` macro + 6. Rust/Axum and Tauri are the IR authority via the `#[mizan::client]` macro + linkme
linkme registry; the codegen links the crate directly (`build_ir()` / the registry; the codegen links the crate directly (`build_ir()` / the `export-ir` bin)
`export-ir` bin) rather than fetching over HTTP. rather than fetching over HTTP.
7. FastAPI and Rust/Axum expose `GET /session/` returning a null CSRF token for wire 7. FastAPI and Rust/Axum expose `GET /session/` returning a null CSRF token for wire
parity; real CSRF is Django-only. parity; CSRF is Django-only.
8. TypeScript is an edge/protocol-reference adapter (HMAC cache, manifest, PSR), not a
codegen source — it demonstrates the cache + invalidation protocol is
language-agnostic.
### Reading the columns ## Conformance
- **FastAPI** — the AFI-common HTTP subset: dispatch, contexts, body invalidation, Adapter parity is gated by the AFI conformance suite in [`tests/afi/`](tests/afi/). It
auth guards, IR export. Channels / forms / SSR / cache are deliberately delegated to currently asserts **IR-shape parity** — the same fixture through Django, FastAPI, and
native FastAPI equivalents. the Rust adapter emits byte-identical KDL (`test_codegen_parity.py`). Per-capability
- **Rust / Axum** — core dispatch + context bundling + compile-time registry, and the runtime assertions (header transport, `auth=` enforcement, cache behavior) are planned.
*server-side* IR authority. No HTTP-layer cache, auth enforcement, or edge surface
yet.
- **Tauri** — the same Rust core over IPC for desktop/mobile. Edge, SSR, MWT, and CSRF
are structurally inapplicable to a local app.
- **TypeScript** — the edge/protocol reference: HMAC cache, edge manifest, and PSR
strategy, proving the cache + invalidation protocol is language-agnostic. It is not a
codegen IR source.
### Keeping this honest ## License
This table is a **snapshot**, and a hand-maintained snapshot drifts the moment an Mizan is licensed under the [Elastic License 2.0](LICENSE) (SPDX: `Elastic-2.0`). You
adapter gains or loses a target. The enforcing layer is the AFI conformance suite at may use, copy, modify, and distribute it freely, including in commercial products you
[`tests/afi/`](tests/afi/), which today gates **IR-shape parity** — the same fixture build on top of it. You may **not** provide Mizan to third parties as a hosted or
through Django, FastAPI, and the Rust adapter must emit byte-identical KDL managed service that exposes a substantial set of its features.
(`test_codegen_parity.py`). It does **not yet** assert *runtime capability* parity
(e.g. "every adapter that claims the header transport actually emits
`X-Mizan-Invalidate`," "every adapter that claims `auth=` actually rejects an
unauthorized call"). Extending `tests/afi/` with per-capability assertions — one row of
this table per asserted behavior — is what turns the table from documentation into a
red-on-regression contract.

View File

@@ -1,6 +1,7 @@
[project] [project]
name = "mizan" name = "mizan"
version = "1.0.1" version = "1.0.1"
license = "Elastic-2.0"
description = "Django + React server functions framework" description = "Django + React server functions framework"
readme = "README.md" readme = "README.md"
requires-python = ">=3.10" requires-python = ">=3.10"

View File

@@ -1,6 +1,7 @@
[project] [project]
name = "mizan-fastapi" name = "mizan-fastapi"
version = "0.1.0" version = "0.1.0"
license = "Elastic-2.0"
description = "Mizan FastAPI backend adapter — HTTP RPC dispatch + context bundling, built on mizan-core." description = "Mizan FastAPI backend adapter — HTTP RPC dispatch + context bundling, built on mizan-core."
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [

View File

@@ -3,7 +3,7 @@ name = "mizan-axum"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "axum HTTP adapter for Mizan — typed RPC dispatch + context-bundle fetch on top of mizan-core's compile-time function registry." description = "axum HTTP adapter for Mizan — typed RPC dispatch + context-bundle fetch on top of mizan-core's compile-time function registry."
license = "MIT" license = "Elastic-2.0"
[dependencies] [dependencies]
mizan-core = { path = "../../cores/mizan-rust" } mizan-core = { path = "../../cores/mizan-rust" }

View File

@@ -3,7 +3,7 @@ name = "mizan-tauri"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Tauri backend adapter for Mizan — typed RPC dispatch over Tauri's IPC. Single `mizan_invoke` command routes through mizan-core's compile-time function registry." description = "Tauri backend adapter for Mizan — typed RPC dispatch over Tauri's IPC. Single `mizan_invoke` command routes through mizan-core's compile-time function registry."
license = "MIT" license = "Elastic-2.0"
[dependencies] [dependencies]
mizan-core = { path = "../../cores/mizan-rust" } mizan-core = { path = "../../cores/mizan-rust" }

View File

@@ -10,5 +10,5 @@
"devDependencies": { "devDependencies": {
"bun-types": "latest" "bun-types": "latest"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -1,6 +1,7 @@
[project] [project]
name = "mizan-core" name = "mizan-core"
version = "0.1.0" version = "0.1.0"
license = "Elastic-2.0"
description = "Mizan Python core — HMAC cache keys, MWT identity. Framework-agnostic primitives shared by every Python backend adapter." description = "Mizan Python core — HMAC cache keys, MWT identity. Framework-agnostic primitives shared by every Python backend adapter."
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [

View File

@@ -3,7 +3,7 @@ name = "mizan-macros"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Proc macros for mizan-core: #[derive(Mizan)], #[mizan::context], #[mizan(...)]. Emits MizanType / ContextMarker / FunctionSpec impls plus linkme registrations." description = "Proc macros for mizan-core: #[derive(Mizan)], #[mizan::context], #[mizan(...)]. Emits MizanType / ContextMarker / FunctionSpec impls plus linkme registrations."
license = "MIT" license = "Elastic-2.0"
[lib] [lib]
proc-macro = true proc-macro = true

View File

@@ -3,7 +3,7 @@ name = "mizan-core"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Mizan server-side IR substrate — types, traits, KDL emitter, registry. Rust analog of cores/mizan-python/src/mizan_core/." description = "Mizan server-side IR substrate — types, traits, KDL emitter, registry. Rust analog of cores/mizan-python/src/mizan_core/."
license = "MIT" license = "Elastic-2.0"
[dependencies] [dependencies]
linkme = "0.3" linkme = "0.3"

View File

@@ -7,5 +7,5 @@
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -1,6 +1,7 @@
{ {
"name": "@rythazhur/mizan", "name": "@rythazhur/mizan",
"version": "0.1.1", "version": "0.1.1",
"license": "Elastic-2.0",
"type": "module", "type": "module",
"main": "dist/index.js", "main": "dist/index.js",
"types": "dist/index.d.ts", "types": "dist/index.d.ts",

View File

@@ -3,7 +3,7 @@ name = "mizan-rust"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Mizan client kernel — Rust port of @mizan/base. Context registry, fetch/call, merge, invalidation, error envelope parsing. Same wire as the TS / Vue / Svelte clients." description = "Mizan client kernel — Rust port of @mizan/base. Context registry, fetch/call, merge, invalidation, error envelope parsing. Same wire as the TS / Vue / Svelte clients."
license = "MIT" license = "Elastic-2.0"
[features] [features]
default = [] default = []

View File

@@ -7,5 +7,5 @@
"svelte": ">=4", "svelte": ">=4",
"@mizan/base": ">=0.1.0" "@mizan/base": ">=0.1.0"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -11,5 +11,5 @@
"@mizan/base": "*", "@mizan/base": "*",
"@tauri-apps/api": "^2" "@tauri-apps/api": "^2"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -7,5 +7,5 @@
"vue": ">=3", "vue": ">=3",
"@mizan/base": ">=0.1.0" "@mizan/base": ">=0.1.0"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -7,5 +7,5 @@
"exports": { "exports": {
".": "./src/index.ts" ".": "./src/index.ts"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -10,5 +10,5 @@
"peerDependencies": { "peerDependencies": {
"@mizan/base": "*" "@mizan/base": "*"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -3,7 +3,7 @@ name = "mizan-codegen"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
description = "Mizan codegen substrate — consumes Mizan IR; emits typed clients for React/Vue/Svelte/Rust/Python." description = "Mizan codegen substrate — consumes Mizan IR; emits typed clients for React/Vue/Svelte/Rust/Python."
license = "MIT" license = "Elastic-2.0"
[[bin]] [[bin]]
name = "mizan-generate" name = "mizan-generate"

View File

@@ -6,5 +6,5 @@
"bin": { "bin": {
"mizan-generate": "./bin/launcher.mjs" "mizan-generate": "./bin/launcher.mjs"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }

View File

@@ -16,5 +16,5 @@
"@types/react": "^19.0.0", "@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0" "@types/react-dom": "^19.0.0"
}, },
"license": "MIT" "license": "Elastic-2.0"
} }