# Compatibility and upgrades

Minimoon is pre-1.0. This policy defines the compatibility guarantees maintained
for core `0.2.5` and optional UI `0.1.3`, 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.2 baseline locks the root, HTTP and build-resource interfaces
exactly, while `components`, `components/styles` and `testing` permit additive
declarations. The UI 0.1 baseline independently permits additive declarations
in its root, `headless`, `theme` and `resources` packages. 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 | 8 | 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.2 patches must preserve the checked root/HTTP/resource interfaces and all
  three protocol versions; UI 0.1 changes must preserve its additive 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` | Current source pair; dependency and tooling refresh with unchanged public APIs; UI declares core `0.2.5`; publication status is recorded separately |

Previously published archives and their dependency declarations remain immutable.
Upgrade the CLI and direct core dependency to `0.2.5`, and optional UI to `0.1.3`.
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.2.x` / `0.1.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.2.5` and UI `0.1.3` require at least `moon 0.1.20260920` with
`moonc v0.10.14`. Both CI jobs use the official installer pinned to the complete
prebuilt release `0.10.14+7d59c7ec9` (`moon 0.1.20260920`), not latest;
Rust is not required. This raises the previous MoonBit minimum: 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 CI coverage at the 24.20.0 lower boundary and in the 26.10.0 primary
environment. Global `vp 1.0.0` manages pinned Bun `1.4.2`;
`devEngines.runtime` selects Node `26.10.0` 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.

The new compiler requires explicit package qualifiers in blackbox tests and
other cross-package references. For example, use `@minimoon.page(...)` and
`@minimoon.ScrollDetail` when `moon.pkg` assigns the alias `@minimoon` to the
core package. A UI blackbox test similarly uses its declared `@ui` alias. Do
not qualify a local declaration as though it belonged to another package.

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}
```

The framework applies this migration to preserve existing derived methods,
including equality, debug and JSON conversion methods. It is not an instruction
to expose every private application type. Review generated `.mbti` files and
compile consumers after adapting your own library code. The new compiler can
print explicit method signatures for methods that were implicit in earlier
interfaces. The repository keeps its frozen core/UI baseline snapshots unchanged
and checks the reviewed explicit signatures separately; it does not accept
arbitrary snapshot regeneration as compatibility evidence. The checked API
contracts and App Contract `11` / ABI `13` / renderer protocol `8` remain the
compatibility boundaries.

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 [scoped publication exception](../operations/release_candidate_handoff.md#scoped-publication-exception)
allows core `0.2.4` and UI `0.1.2` to publish after automated CI without waiting for a
new host pass. It does not assert host acceptance or change `verify --release`.

## 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.1.3.zip`.

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

The application style manifest must keep these exact versions:

| Dependency | Version |
| --- | --- |
| `@tailwindcss/cli` and `tailwindcss` | `4.3.3` |
| `postcss`, including `overrides.postcss` | `8.5.28` |
| `weapp-tailwindcss` | `5.5.11` |
| `devEngines.packageManager` | Bun `1.4.2` |
| `devEngines.runtime` | Node `26.10.0` |

The repository also pins `acorn 8.18.0` and `eslint-scope 9.1.2` for validation;
ordinary applications do not need these two packages. Use global `vp 1.0.0`,
the current repository and CI baseline, for the `0.2.5` CLI's JavaScript tooling.
Install and initialize it using the
[quickstart](../guides/miniapp_quickstart.md#prerequisites); separate Bun
installation is unnecessary. No local `vite-plus`, Vite or Vitest package is
required. The global CLI's missing-local-`vite-plus` notice is expected here.

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.2`.
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

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. Upgrade MoonBit to the minimum above and initialize global `vp 1.0.0`.
   Install `moon install lampclaw/minimoon/cmd/minimoon@0.2.5`, confirm
   `minimoon --version` reports `0.2.5`, and check PATH for older binaries.
3. Update the application's direct dependency to `lampclaw/minimoon@0.2.5` and,
   if used, `lampclaw/minimoon_ui@0.1.3`. 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 style versions above,
   retain `engines.node: ">=24.20.0"` and the PostCSS override, and set
   `devEngines.runtime` to `{ "name": "node", "version": "26.10.0" }` alongside
   `devEngines.packageManager: { "name": "bun", "version": "1.4.2" }`. 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. The framework publication exception 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.

## Core 0.2 and optional UI 0.1

The new UI module is independently named `lampclaw/minimoon_ui`; it depends on
core 0.2.5, not on Rabbita. Existing optional components and both minimal themes
remain available. The frozen 0.1 consumer is historical source, not a required
compatibility gate against the current core. The maintained consumer targets
the current 0.2 API; migrate source 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 stays `8`.

`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).
