# Development

The main branch and CI pin MoonBit
`0.10.20+65efd5b93` with matching core. Check the workflow for the relevant
commit's execution results. From the repository root:

```sh
moon update
moon fmt
moon info
python scripts/verify.py --profile quick --targets js wasm wasm-gc native
```

Review generated `.mbti` diffs when changing public APIs; do not edit them by hand. All four backends run the same protocol tests. `tests/generated` and `examples/telemetry/generated` contain compiler output with handwritten tests alongside it.

Use only installed backends locally; Windows without MSVC can select
`--targets js wasm wasm-gc`. Unselected targets are not claimed as passed.
`quick` checks formatting, compiler minimum, strict check/test/release build,
the portable example and verification failure contracts. `full` adds independent
compiler/peer exchange and a benchmark smoke run:

```sh
python -m pip install -r examples/telemetry/requirements.txt
python scripts/verify.py --profile full --targets js native --capnp capnp
```

Both profiles write a new directory under `work/verification`, containing
`summary.json`, `summary.sha256`, command logs and SHA-256 hashes. The report
fingerprints tracked and non-ignored source before/after the run and fails if
it changed. Missing tools, timeouts, failed dependencies and missing artifacts
fail the run; quick's external-oracle check is explicitly skipped. Counts are
commands, not individual assertions or independent test cases. `--moon`,
`--node`, `--capnp`, `--timeout` and `--output` make the environment explicit.
The driver installs no toolchain and keeps child temporary files in its run
directory. Do not run two builds against the same checkout concurrently.

The full profile compiles eleven schemas with official 1.5.0, compares formatted
generated APIs without rewriting source, checks eleven canonical fixtures,
executes both peers and verifies plain/packed streams. Source archive hashing
is additionally enforced in CI. Keep each implementation change, its regression
and its relevant API documentation together; the evidence is the logs and
independent outputs, not a self-assigned rubric score.

## External oracles

Committed fixtures use official Cap'n Proto 1.5.0; see [regeneration](../fixtures/README.md). CI builds the same 1.5.0 compiler from its SHA-256-pinned source archive, regenerates the unchanged upstream test/compiler schemas, and exchanges messages with `pycapnp==2.2.1` on Python 3.12. The [schema compatibility peer](../examples/schema_compat) checks generic, dynamic and constant values; the telemetry peer performs the application calculation independently.

The portable example requires no filesystem or host FFI:

```sh
moon run --target wasm examples/roundtrip
moon run --target wasm-gc examples/roundtrip
moon run --target js examples/roundtrip
moon run --target native examples/roundtrip
```

## Native and Node.js CLIs

`internal/stdio` is a host adapter. C handles binary stdin/stdout; JS uses Node's `node:fs`. Protocol parsing, generation and packing remain MoonBit code. Standard input/output is supported on native and Node.js. Wasm users can use file-based commands where the host filesystem package is available, or call the library directly.

Linux CI uses the system C compiler. MoonBit `0.10.20+65efd5b93` requires an MSVC-compatible compiler/linker and Windows SDK for Windows native builds; run native commands from an x64 Visual Studio developer shell with the C++ build tools installed. The Node.js request-file path and JS/Wasm tests do not need a C compiler.

The 0.3.0 local benchmark used MoonBit 0.10.14 with LLVM-MinGW 20261006 and `CCC_OVERRIDE_OPTIONS=+-D_CRT_RAND_S`. That is a historical environment record, not the Windows native setup for 0.4.2.

## Layout

- Root `reader_*`, `builder_*`, `pointer_builder.mbt`, `copy.mbt`, `canonical.mbt`, `packed.mbt`, `stream.mbt`: serialization runtime.
- `codegen/`: compiler request decoding and MoonBit source generation.
- `cmd/`: compiler plugin and packing utilities.
- `fixtures/`, `tests/`: independent fixtures, generated API tests and regressions.
- `examples/`: portable roundtrip, cross-language batch processing, and unchanged-schema interoperability.

Changes should include a reproducer or reference fixture where practical. Do not add performance or production-use claims without reproducible evidence.

CI also checks JS and MSVC native targets and the binary stream example on Windows. The Linux
interoperability job runs native/JS stream processing and a short benchmark
execution check. That short run validates workload/checksum/timing output; it
is not a performance regression threshold. See [streaming](../examples/streaming)
and [benchmark methodology](../benchmarks/README.md) for full reproductions.

## Published package verification

After publishing to Mooncakes, run this from the matching release checkout:

```sh
python scripts/verify_release.py --release-tag v0.4.2
```

The script requires Python 3.12, MoonBit `0.10.20+65efd5b93`, Node.js 24, a native C compiler,
and the official `capnp` 1.5.0 executable. `--moon` and `--capnp` accept explicit
tool paths. `--version` may select another package only if it provides the APIs
exercised by this checkout's script. To verify an older release, use its matching
checkout and script. When `--release-tag` is supplied, it must match both the
checkout and package.

A temporary module under `work/` installs the registry package, generates an
unchanged schema containing a name collision, generic container, AnyPointer and
constants, and runs the resulting API on all four targets. It also checks the
package's required files, MIT notices and original upstream hashes; compiles
its native/Node.js host adapters; exercises binary stdin/stdout and invalid
request handling. It removes only its own temporary directory when finished.

CI runs this check for published releases and manual workflow runs. Push/PR
checks do not require an unreleased package to exist in the registry. Publish
the Mooncakes package before publishing its GitHub release; the release check
binds the tag, manifest, CLI and installed package to the same version.
