# Sürümleme — how the platform versions itself, and why your theme/extension keeps working Mozaik stores always run the **latest** platform code — and a release can never break an existing store's theme or extension. Both are true at once because compatibility is **computed, not promised**: every release ships a machine-readable contract manifest, every artifact's references are extracted as a footprint, and CI refuses a release whose class does not match its diff. ## The version model | Part | Identity | Meaning of MAJOR / MINOR / PATCH | |---|---|---| | Storefront (core) | `storefrontVersion` + `generation` in [`meta.get`](/reference/routes/meta.get) | MAJOR = a new **generation** (breaking; the previous generation keeps running as its own Worker for stores not yet compatible). MINOR = additive contract surface and/or a first-party kit restyle — never a removal. PATCH = nothing a theme, extension or agent can observe. | | API | `apiVersion` (semver) | MAJOR = a route/command removal, only after ≥ 12 months deprecated (`deprecations[]` in [`meta.get`](/reference/routes/meta.get) announces them with `removeAfter`). MINOR = additive. Old names stay aliased in-process. | | Theme pack | `id@x.y.z` | MAJOR = removed variable / preset / theme section / skeleton role, or a new parent-kit major. MINOR = additions or a visual CSS change. PATCH = CSS-only fix. Enforced by [`themes.check`](/reference/routes/themes.check) with `against`. | | Extension | `manifest.version` | MAJOR = new scope / PII field / required secret (the owner must consent) or a removal. MINOR = additive. | The contract manifests this build was released with are public: [`compat.contracts.get`](/reference/routes/compat.contracts.get) — the same JSON as `contracts//.json` in the platform repo. ## Compatibility is computed Everything a skin or theme can touch is a *name*: `[data-mz-el="product-card"]`, `[data-mz-part="price"]`, `--mz-*` / `--mzt-*` variables, section types and prop keys, zones, extension blocks, island templates. [`compat.check`](/reference/routes/compat.check) takes an artifact (`css`, `bundle`, `extension` or `tree`) and answers `{ok, breaking[], warnings[]}` against this build — the same checker that runs at `theme.push`, at owner-CSS save, and fleet-wide before every release (the *fleet gate*: every store's live artifacts are re-judged with the candidate build; a MINOR with even one breaking verdict never deploys). A rename ships as an **alias** (old name → new name, with a date ≥ 12 months out). The checker reports aliased names as dated warnings, and the platform mechanically rewrites stored stylesheets to the new names before the alias expires. ## What a store owner sees Compatible updates apply automatically and are recorded in **Sürümler**. Anything visual or permission-shaped waits in **Güncellemeler**: a customized store keeps rendering its current look until the owner previews and clicks *Güncelle*; an extension that wants a new scope shows exactly which permissions grow and applies only with consent. After a MAJOR, a store whose artifacts don't yet pass simply stays on the previous generation — same URL, same look — until its theme/extension is updated or the generation's published EOL passes. ## `requires` — declaring your floor A theme pack or extension may declare what it needs: ```json { "requires": { "contract": 1, "api": ">=1.0.0", "storefront": ">=1.1.0 <2", "kits": { "mozaik.zanaat@1": "^1.0.0" } } } ``` Install and upgrade refuse with `requires_unsatisfied` when the running platform is outside the range; the gallery marks such versions as incompatible. The effective floor is the stricter of what you declare and what the checker computes from your artifact's actual references — so declaring nothing is safe, and declaring a floor is documentation, not magic.