# Compatibility and upgrades

Minimoon is pre-1.0. This policy defines the compatibility guarantees maintained
for core `0.3.1` and optional UI `0.2.0`, including the versioned transition
from the frozen core 0.1 consumer baseline.

## Compatibility surfaces

Applications import `lampclaw/minimoon` and may opt into
`lampclaw/minimoon_ui`. The generated `.mbti` files define the public source
surfaces. Internal package names, normalized trees, host commands, and
generated helper functions are not public APIs.

The checked core 0.3 baseline locks the root, HTTP and build-resource interfaces
exactly, while `components`, `components/styles` and `testing` permit additive
declarations. The UI 0.2 baseline locks its root, `headless`, `theme`, `resources` and
optional `markdown` interfaces. Historical core 0.2 consumers remain compiled
against the new archive; historical interface snapshots stay immutable. Changing a required
declaration or a locked boundary requires a separately reviewed versioned
baseline and migration notes; updating snapshots is not a compatibility fix.

Generated applications have three versioned boundaries:

| Boundary | Current version | Rule |
| --- | ---: | --- |
| App Contract | 11 | requires schema 11 with or without `application`; older source schemas require migration |
| runtime ABI | 13 | runtime and host files must be generated together |
| renderer protocol | 9 | renderer commands and host decoder must match |

Generated files from different builds or versions must never be mixed. CommonJS
is the verified MiniApp host format; ESM is not an implied upgrade.

## Version policy

- Core 0.3 patches must preserve the checked root/HTTP/resource interfaces and all
  three protocol versions; UI 0.2 changes must preserve its locked baseline.
  Fixes or internal improvements may change generated bytes, which still
  require new real-host evidence. The same exact-root policy remains the
  historical rule for the 0.1.x maintenance line.
- A future pre-1.0 minor may change the root interface or a protocol version,
  but must include a migration guide, update generated interfaces, rebuild every
  fixture, and invalidate prior host evidence explicitly.
- Internal packages carry no direct application compatibility promise. Their
  `.mbti` files are checked to detect accidental architectural drift.

| Core resolved by consumer | UI | Status |
| --- | --- | --- |
| `0.2.0` | `0.1.0` | Historical published baseline; UI declares core `0.2.0` |
| `0.2.1` | `0.1.0` | Historical published pair; fresh registry consumers are recorded in project status |
| `0.2.2` | `0.1.1` | Published pair; UI declares core `0.2.2` |
| `0.2.3` | `0.1.1` | Historical core-only vp migration; UI keeps its core `0.2.2` declaration |
| `0.2.4` | `0.1.2` | Previous published source pair; runtime, verification and Slider fixes; UI declares core `0.2.4` |
| `0.2.5` | `0.1.3` | Previous published pair; stable Vite+ and dependency refresh; UI declares core `0.2.5` |
| `0.2.6` | `0.1.4` | Previous published pair; tooling and stylesheet refresh; UI declares core `0.2.6` |
| `0.2.7` | `0.1.5` | Published pair; MoonBit 0.10.15 and dependency refresh; UI declares core `0.2.7` |
| `0.3.0` | `0.2.0` | Published pair; native inline / protocol 9, Nova/Vega, optional Markdown and Drawer edges; UI declares core `0.3.0` |
| `0.3.1` | `0.2.0` | Core-only candidate: queries and watch fixes; UI retains core `0.3.0` |

Previously published archives and their dependency declarations remain immutable.
Upgrade the CLI and direct core dependency to `0.3.1`, and optional UI to `0.2.0`.
See [project status](https://github.com/lucavance/minimoon/blob/main/docs/project_status.md)
for actual publication and consumer results. This matrix does not establish
real-host acceptance or certify every future `0.3.x` / `0.2.x` combination.
MoonBit dependency resolution may select a higher satisfying version, and a local
workspace may override registry sources; inspect the resolved graph and rerun
consumer gates for another pair.

## Toolchain compatibility

Core `0.3.1` and UI `0.2.0` require at least `moon 0.1.20261012` with
`moonc v0.10.15`. Both CI jobs use the official installer pinned to the complete
prebuilt release `0.10.15+943464bfa` (`moon 0.1.20261012`), not latest;
Rust is not required. This retains the minimum introduced by core `0.2.7` /
UI `0.1.5`: older compilers
are not supported for the new source syntax. The direct dependencies are
`moonbitlang/async@0.22.4` and `moonbitlang/x@0.5.5`.

Repository and generated-starter JavaScript tooling support Node `>=24.20.0`,
with current CI coverage at the 24.20.0 lower boundary and in the 26.11.1 primary
environment. Current source uses global `vp 1.1.0` to manage pinned Bun `1.4.3`;
`devEngines.runtime` selects Node `26.11.1` without adding `.node-version`.
The Node minimum has not changed.
Update CI, the package consumer gate, starter guidance and compatibility notes
together when changing these constraints.

Published registry CLI `0.2.6` retains its released pins (table below). Registry
CLI `0.3.0` provides the current Starter pins. The Unreleased watcher fixes and
repository performance observations require the current source checkout; they
are not part of any published archive.

Blackbox tests and cross-package references use declared package aliases:
`@minimoon.page(...)`, `@minimoon.ScrollDetail`, or `@ui` in UI tests.
Local declarations need no package qualifier.

For library types whose concrete derived methods are part of the published API,
retain the derivation and explicitly export those extensions, for example:

```moonbit
pub(all) struct Model {
  count : Int
} derive(Eq, Debug)

pub extend Model with Eq::{equal, not_equal}
pub extend Model with Debug::{to_repr}
```

Export existing public equality, debug and JSON conversion methods, retaining
private application types. Review generated `.mbti` files and compile consumers.
The repository keeps frozen core/UI baselines and checks the reviewed explicit
signatures separately; arbitrary snapshot regeneration is not compatibility evidence. The checked API
contracts and App Contract `11` / ABI `13` / renderer protocol `9` remain the
compatibility boundaries. The 0.10.15 update replaces deprecated built-in
`value.to_json()` calls with `Json(value)` and iterator `length()` with `count()`;
array and string lengths retain their existing meaning. Generated sources
must use the new formatter's `Int32` and default-parameter spelling.

The `0.2.2` CLI also contains the App-aware helper fix and import cleanups that
were absent from registry CLI `0.2.1`. That older CLI can fail `--deny-warn` for
apps with `application` configured on `moonc v0.10.13`; upgrading only the core
library does not replace the old CLI's generated helper. Install the matching
CLI and confirm PATH selects it.

Compiler and stylesheet upgrades can change generated bytes. Regenerate with
the selected toolchain before validation; old host evidence never covers a
changed fingerprint. The historical
[scoped publication exception](https://github.com/lucavance/minimoon/blob/main/docs/operations/release_candidate_handoff.md#scoped-publication-exception)
applied only to core `0.2.4` / UI `0.1.2`, not the current candidate.

## Packaging and JavaScript dependencies

Moon packaging can inherit an ancestor Git repository's `.moonignore`.
The root `/ui/` rule makes direct `cd ui` publication (including
`moon -C ui publish`) unsafe: it can produce an empty ZIP despite source being
present. The UI archive gate packages an isolated source copy under its own Git
root and validates the actual archive, required files and consumers. The checked
ZIP is `_build/publish/lampclaw-minimoon_ui-0.2.0.zip`.

Publish core `0.3.0` first, validate registry consumers, then publish the reviewed
UI `0.2.0` archive from an independent directory. Validate the complete registry
pair and upgrades from core `0.2.5` / UI `0.1.3`; follow the
[release procedure](https://github.com/lucavance/minimoon/blob/main/docs/operations/release_candidate_handoff.md#ordered-local-registry-publication).
Packaging checks do not prove registry availability or a host pass.

Use the exact application style versions for the selected CLI:

| Dependency | Published CLI `0.2.6` | Candidate CLI `0.3.0` |
| --- | --- | --- |
| `@tailwindcss/cli` and `tailwindcss` | `4.3.3` | `4.3.3` |
| `postcss`, including `overrides.postcss` | `8.5.29` | `8.5.30` |
| `weapp-tailwindcss` | `5.5.12` | `5.6.1` |
| `devEngines.packageManager` | Bun `1.4.2` | Bun `1.4.3` |
| `devEngines.runtime` | Node `26.11.1` | Node `26.11.1` |
| `overrides.source-map-js` | not declared | `1.2.2` |

Unpublished source also generates `overrides.source-map-js: "1.2.2"` to
remove vulnerable nested resolutions. The registry `0.2.6` CLI retains its
original template. Existing apps can add this override and reinstall; see the
[source audit policy](https://github.com/lucavance/minimoon/blob/main/docs/project_status.md#source-dependency-audit-policy)
for the remaining `braces` advisory and temporary exception.

Only the repository needs `acorn 8.19.0` and `eslint-scope 9.1.2` for validation.
Use `vp 1.1.0` for source and the published baseline. Follow the
[quickstart](../guides/miniapp_quickstart.md#prerequisites); separate Bun and
local `vite-plus`, Vite or Vitest packages are unnecessary. The
missing-local-`vite-plus` notice is expected.

Use `vp install`, `vp run <task>` and `vp pm audit --level high`. Acceptance
checks use `vp run --no-cache <task>`. Preserve the native MoonBit build pipeline:
Vite+ built-ins `vp build`, `vp test` and `vp check` do not run Minimoon tasks.
Bun remains the package-manager/runtime backend and `bun.lock` remains tracked.
Internal Bun tools execute through the shared launcher using
`vp env exec bun <arguments>` with process-local `VP_BUN_VERSION=1.4.3`.
Bun management must be enabled (`vp env on bun`); the direct managed launch
preserves process termination and cancellation. The stylesheet adapter uses
`vp node` because weapp-tailwindcss requires Node's `findPackageJSON`.
An explicit lower-bound run uses `VP_NODE_VERSION=24.20.0 vp run --no-cache <task>`;
the internal launcher preserves that selection.

## Upgrade procedure

Core 0.3.1 adds optional `/query` pagination, confirmed search, refresh and retry;
existing APIs and protocols stay unchanged. UI remains 0.2.0 with its original
core 0.3.0 declaration. Use source until publication is recorded.

For upgrades from core 0.2, follow the
[UI migration guide](https://github.com/lucavance/minimoon/blob/main/ui/docs/migration.md#core-030--ui-020)
and regenerate all host output for protocol 9.

1. Read the [core changelog](../../CHANGELOG.md), the
   [UI changelog](https://github.com/lucavance/minimoon/blob/main/ui/CHANGELOG.md)
   when applicable, and [publication status](https://github.com/lucavance/minimoon/blob/main/docs/project_status.md).
   Use the source workflow if the target versions are not available yet.
2. Use the MoonBit minimum above and global `vp 1.1.0`.
   After registry availability is recorded, install
   `moon install lampclaw/minimoon/cmd/minimoon@0.3.1`; until then follow the
   [source workflow](../guides/miniapp_quickstart.md#create-from-the-current-source)
   instead. Check PATH and confirm `minimoon --version` reports `0.3.1`.
3. Update the application's direct dependency to `lampclaw/minimoon@0.3.1` and,
   if used, `lampclaw/minimoon_ui@0.2.0`. Update direct async/x imports to the
   reviewed versions above when the application declares them. Run `moon update`
   and confirm the resolved versions without unintended workspace overrides.
4. Update an existing application's `package.json` to the current style
   versions above, retain `engines.node: ">=24.20.0"` and the PostCSS override, and set
   `devEngines.runtime` to `{ "name": "node", "version": "26.11.1" }` alongside
   `devEngines.packageManager: { "name": "bun", "version": "1.4.3" }`. Run
   `vp install` to update its lockfile. Rebuilding does not rewrite an existing
   manifest. Subsequent reproducible installs use `vp install --frozen-lockfile`.
5. Apply explicit package qualification and public derived-method extensions
   where the new compiler requires them. Run `moon info`, review `.mbti` changes,
   format the affected sources, and run warning-free checks and application tests
   for the targets supported by that app. The Starter is JS-only; the framework
   and independent UI consumers also validate native behavior.
6. Rebuild the entire application in release mode with `minimoon build .`;
   do not mix runtime, host, protocol, initial-tree or page files from different
   builds. Preserve private configuration only through the supported builder.
7. Run `minimoon verify . --candidate`. Validate the exact `dist/` in WeChat
   Developer Tools before claiming a host pass for your application.
8. Record new evidence and run `minimoon verify . --release` only after that
   host pass. Framework release evidence does not supply app evidence.

Evidence uses the `fnv1a64-relpath-v2` boundary over complete distributable raw
bytes plus the generated manifest and smoke checklist. A checklist-only,
stylesheet, shared-template or static-asset change invalidates old evidence even
when Contract/ABI/protocol numbers are unchanged.

Rollback means restoring the CLI, module and JavaScript dependency versions,
lockfile and complete generated artifact set together. Restoring only one helper
file is unsupported. A published module version cannot be overwritten.

## Migrating from core 0.1

The independent `lampclaw/minimoon_ui@0.2.0` module depends on core `0.3.0`.
Existing optional core components remain available. Nova is the UI default;
explicit `VegaV1` retains the old visual recipe. The frozen core 0.1 consumer
is historical source. The maintained frozen core 0.2 consumer is compiled
against the 0.3 archive to check source compatibility; migrate older calls and
exhaustive enum matches before rebuilding.

Upgrade an application contract's `schemaVersion` to `11` and regenerate the
entire output. Old schema `8`, `9` and `10` are rejected, including no-App projects.
The optional application package exports `Deps` and `program() -> App[Deps]`;
all opted-in page factories receive those dependencies. `PageContext` is opaque.
See [shared-state migration](../guides/shared_state.md). Do not mix old renderer
output with current host files; runtime ABI is `13`, renderer protocol advances to `9`.

`page_with_input` now requires `preview_input: () -> Input`; its builder receives
an ordinary immutable input, not `Val[Input]`. The actual decoder runs before
building the runtime, so required route values can initialize local state
directly. `Page.create_runtime(input?)` and `AppRuntime.create_page(page, input?)`
return `Result[PageRuntime, DecodeError]`. Handle errors instead of supplying
fake defaults. Repeated Load is rejected, and Load must precede interactions;
the first Load sends a full revision-1 tree. Initial commands run at the first
Ready/mount, not during preview or Load. See [API ergonomics](../guides/api_ergonomics.md).

UI applications opt into build resources with
`resources: [{ "package": "lampclaw/minimoon_ui/resources", "features": [] }]`.
The provider must be a declared dependency; an empty feature list includes all
resources, while a nonempty list selects components and their dependencies.
Providers are trusted native MoonBit dependency code, not sandboxed plugins.
The builder validates names, output paths and conflicting assets. Resources
are fingerprinted and verified with the rest of the generated application.

Import the UI root package as `@ui`; use `@ui.root(page_context, build)` once
per page. Declare `MeasureNodes` on pages using anchored surfaces or measured
touch controls. Native substitutions, consolidated public APIs and remaining
verification obligations are recorded in the
[UI migration map](https://github.com/lucavance/minimoon/blob/main/ui/docs/migration.md).
