Skip to main content
Every component of the Mzizi Dashboard Standard has a contract: one machine-readable, versioned JSON file stating what every implementation of the component must render and do. In the owner’s words (4 October 2026), “the components should also be updated, same as the mzizi language — every component should have a contract.” The contracts live in the registry, in mzizi-dev/mzizi-registry contracts/, added on 4 October 2026 (mzizi-registry#406, tracking issue #404). The first family, app/, covers the 31 server-rendered app components of @bundu/ui (@bundu/ui/app/*.astro, built in mzizi-dev/packages-npm).
A contract is the specification. Read it before you build or change an app component, in any language. The Astro build is checked against all of it. A React or Rust build is a port of the same contract, and is done when it passes.

Where they live

The 31 app/ contracts, by the helix node each component belongs to: Each name is the file contracts/app/<name>.contract.json. Every one is at version 1.0.0 as of 4 October 2026; contracts/index.json is the current list.

What a contract states

Part of contracts/app/button.contract.json:
Its contract field, with one clause per line:

Versioning

Each contract is versioned on its own, with semver. Major when a clause, prop, slot or state is removed or narrowed; minor when one is added; patch for prose only.

The contract block and the language

The contract field uses the clause grammar of the Mzizi language (RFC-0006 and RFC-0010), the subset that applies to rendered markup:
  • Subjects: slot, role, label, class and portal (the root element’s attribute), <element> "<text>" (with min_height), uses <data-slot>, and when <state> ….
  • Predicates: is, contains, not_empty, in, uses "--token", min_height and shows.
As in the language, a clause, check or density row that a runner cannot evaluate fails. An unevaluable contract must never read as a passing one (RFC-0006, FM-12). It is the same grammar the Mzizi Roots crates use for their pub const CONTRACT (today the twelve mzizi-brand components), which each crate’s suite evaluates on dioxus-ssr markup. Neither is run by the language’s mz contract: no component is written in Mzizi yet, so package test suites evaluate these contracts. The grammar is shared so that mz contract can check them once components are written in Mzizi; that is a design intention, not built.

Requirements

Three fields are rules every implementation meets, and the Astro contract test evaluates them:
  • No JavaScript. noJs.script is none for 29 of the 31. AppShell and CommandPalette are enhancement: each ships one script, and everything its noJs.without lists works when the script does not run. See Without JavaScript.
  • Density. Every interactive part declares a fine and a coarse height, and each row is evaluated. Controls are dense on a mouse (mostly 32–40px) and 44–48px on touch. See Density.
  • Theming. A brand overlay changes colour only (--primary, --ring, AppShell’s --app-accent, and the mark). Layout never varies by brand. The markup carries no colour values, and a mineral class appears only as one of the component’s declared statusColours. See Brand overlays.

How each implementation is checked

identity is what a sibling shares with the Astro build: slot, slot+role or slot+variants. A sibling’s differences from the contract are listed in its divergences.

Coverage and gaps

Seven primitives have siblings in the registry: a .tsx for button, badge, card, alert, input, label and skeleton, and a .rs for button, badge, card, input and label. The 24 shell and page patterns have neither. The plan is mzizi-registry#397 (an Astro target, so these .astro files move into the registry) and #401 (Rust ports of the console patterns). The coverage table in contracts/README.md is kept true by the registry’s test. Four contracts record gaps:
  • AppShell: the collapse toggle is 32px on every pointer. On a touch screen at 64rem or wider it is under the 44px the rest of the shell keeps (WCAG 2.5.8 is met at 24px; 2.5.5 is not).
  • PageHeader: the “View docs” pill is 24px on touch.
  • InfoTip: 32px on touch.
  • BrandMark: only the Nyuchi mark ships. Mukoko, Bundu, Mzizi and the sub-brands need their registry icon pairs before their dashboards can adopt the standard.

Adding or changing a contract

1

Edit the contract in the registry

Edit or add contracts/app/<name>.contract.json and bump its version by the rules above.
2

Update the index and the coverage table

contracts/index.json and the table in contracts/README.md. The registry’s test fails if a file or version is missing from the index, or a coverage row disagrees.
3

Test both sides

pnpm test in the registry, then in mzizi-dev/packages-npm pnpm contracts:fetch <your branch> and pnpm test. The Astro build must pass the new contract before either side merges.
Never edit the copy of contracts/ in packages-npm. Change the contract in the registry, and the package follows.