The Laws of Mosaic
Mosaic is not a framework and it is not a code generator with opinions. It is a small compiler. Six laws make it what it is. Every law is enforced by an executable artifact — a test, a CI job, or a type signature — not by goodwill. If a law cannot be enforced, it is a slogan and it does not belong here.
Law 1 — Compiler Input
The entire input to mosaic is a finite, declarative set of files:
mosaic.yaml— the app (which tessera, which deployments),<tessera>/tessera.yaml— the unit (kind, enums, entities, ops),<tessera>/src/*.rs— hand-written behavior, copied verbatim,deploy/*.yaml— deployments (or inlinedeploy:sugar in mosaic.yaml).
No plugins, no build scripts, no configuration that depends on the
environment. Every key is declared, unknown keys are errors
(deny_unknown_fields), and the JSON schema of each file kind is
machine-printable: mosaic schema tessera|mosaic|deploy.
Enforced by: the grammar types in crates/mosaic-grammar (serde
deny_unknown_fields on every spec struct) and the CI schemas are valid JSON step.
Law 2 — Zero Tax
A capability you do not declare costs you nothing. The type vocabulary is closed (nine primitives, declared entities/enums, one level of lists); the middleware vocabulary is closed; the lens set is closed. There is no expression language and therefore nothing to learn, nothing to sandbox, and nothing to optimize. When a need appears that the vocabulary does not cover, the vocabulary is extended in a deliberate ADR — it is never escaped from.
Enforced by: ADR 0001 and its proofs
(mosaic-grammar::ty::tests::rejects_option_and_nested_arrays,
accepts_both_list_spellings).
Law 3 — One Model
There is exactly one model: the tessera. Every artifact — REST routes, the client CLI, the OpenAPI document, the Dockerfile, the k8s manifests — is a projection of the same resolved plan. Two lenses can never drift apart, because neither of them owns the truth.
Enforced by: ADR 0002 and its proof
(mosaic-conformance::tests::render_is_a_pure_function_of_the_plan).
Law 4 — Thin Renderers
A renderer prints. It does not decide. Anything that requires choosing
a fact — a route, a default, a name, a derived op — happens exactly
once, in mosaic-core::resolve. Renderers take a ResolvedPlan and
nothing else; that signature is the law.
Enforced by: ADR 0004 and its proof
(mosaic-render integration test core_never_depends_on_render, which
fails the build if core ever depends on render).
Law 5 — Proven Proof
Every ADR names the test or CI step that proves its decision, and that artifact runs on every push. A decision without a proof is a rumor.
Enforced by: the Proof field in docs/adr/*.md and the CI test
job, which runs all of them.
Law 6 — Copilot Law
A copilot must be able to work in this repo without tribal knowledge.
Everything it needs is in the repository: the JSON schemas
(mosaic schema), the golden outputs (every rendering is committed and
diff-able), the laws and ADRs (short enough to fit in one context
window), and examples that build. If a fact is not written down, it is
not a fact.
Enforced by: the examples/ conformance suite — if the committed
goldens stop matching the code, CI fails, so documentation can never
silently rot.