diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,1372 @@
+# Hydra changelog
+
+All notable changes to the Hydra project are documented in this file.
+
+This changelog tracks changes across all Hydra implementations
+(Haskell, Java, Python, Scala, TypeScript, Clojure, Common Lisp, Emacs Lisp, Scheme)
+and supporting infrastructure.
+
+The format is inspired by [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
+and [Apache TinkerPop](https://github.com/apache/tinkerpop/blob/master/CHANGELOG.asciidoc).
+
+Pre-1.0 versions are listed below.
+Untagged versions correspond to in-repository version bumps that were not pushed as Git tags or Hackage releases;
+they are documented here for completeness.
+
+---
+
+## [0.17.0] - 2026-07-01
+
+Major themes: first-class support for effects and I/O in the kernel, TypeScript and
+Scala reaching publishable parity with the other hosts, and continued maturation of
+the published-host build model.
+
+### Highlights
+
+- **Effects and I/O** ([#286](https://github.com/CategoricalData/hydra/issues/286),
+  [#288](https://github.com/CategoricalData/hydra/issues/288),
+  [#494](https://github.com/CategoricalData/hydra/issues/494)): a new `effect` variant
+  on `hydra.core.Type` for representing effectful computations; new kernel modules
+  `hydra.file` (`FilePath`, `FileType`, `FileStatus`, `FileExtension`), `hydra.time`
+  (`Timespec`), and `hydra.error.file`; new primitive libraries `hydra.lib.effects`,
+  `hydra.lib.files`, and `hydra.lib.text` with byte-level I/O; and a new
+  `EffectfulTestCase` mechanism so the common test suite can exercise effectful
+  primitives across hosts.
+- **TypeScript is a complete implementation**
+  ([#462](https://github.com/CategoricalData/hydra/issues/462)): self-hosts and passes
+  the common test suite, with a per-package npm publish pipeline
+  ([#492](https://github.com/CategoricalData/hydra/issues/492)).
+- **Scala publishing**: per-package Maven Central publish infrastructure
+  ([#491](https://github.com/CategoricalData/hydra/issues/491)).
+- **Published-host build model**: published mode now compiles the kernel from the
+  co-generated `dist/haskell` rather than Hackage, removing the need for a
+  `haskell=local` shim ([#500](https://github.com/CategoricalData/hydra/issues/500));
+  the oil-and-water principle and cold-build workflow for `dist/haskell` are documented
+  ([#376](https://github.com/CategoricalData/hydra/issues/376)).
+- **Kernel hygiene**: `uniqueLabel` (apostrophe suffixes) replaced by `chooseUniqueLabel`
+  (numeric suffixes) in `hydra.names`
+  ([#436](https://github.com/CategoricalData/hydra/issues/436)).
+
+### Implementations
+
+Eight hosts self-host and pass the common test suite across five families: Haskell,
+Java, Python, Scala, and the four Lisp dialects (Clojure, Common Lisp, Scheme, Emacs
+Lisp), with TypeScript now joining as a complete host/target. Go remains a "head bud"
+(the coder still has emission bugs and the head's runtime is largely placeholder; it
+does not yet host the test suite).
+
+### New Features
+
+- Translingual cross-reference convention for `doc` strings: doc-escape tags render to
+  each host's native doc syntax (Javadoc, Haddock, Sphinx, TSDoc)
+  ([#433](https://github.com/CategoricalData/hydra/issues/433)).
+- Neo4j JSON-artifact validation demo, exercised across Java, Python, Haskell, and
+  TypeScript ([#510](https://github.com/CategoricalData/hydra/issues/510)).
+
+### Improvements
+
+- The Java/Maven publish set now covers every official Hydra target language, one coder
+  package per implementation family
+  ([#468](https://github.com/CategoricalData/hydra/issues/468)).
+- JVM Maven artifact groups are bifurcated to `net.fortytwo.hydra.java` and
+  `net.fortytwo.hydra.scala`, so the Java and Scala (and future Clojure) publish sets
+  never collide on coordinates
+  ([#519](https://github.com/CategoricalData/hydra/issues/519)).
+- Host-specific third-party integrations (the former `bindings/` tree) are folded into
+  `overlay/`, unifying hand-written host-native source under one tree
+  ([#511](https://github.com/CategoricalData/hydra/issues/511)).
+- The coder de-parameterizes context and error types, simplifying generated coder
+  signatures ([#518](https://github.com/CategoricalData/hydra/issues/518)).
+- TypeScript-to-Java generation now emits the `hydra.lib.*` aggregate namespace
+  interfaces (`Maps`, `Strings`, etc.)
+  ([#499](https://github.com/CategoricalData/hydra/issues/499)).
+
+---
+
+## [0.16.1] - 2026-06-16
+
+Major themes: the first release built by bootstrapping from previously published
+packages, the first full 9 × 9 cross-implementation bootstrapping sweep, and
+published-package self-containment fixes for the artifacts that bootstrap rests on.
+
+### Highlights
+
+- **Bootstrap from published packages**: the build links the published 0.16.0 hosts
+  (Hackage / Maven Central / PyPI) and uses them to build the next version of Hydra,
+  resting on 0.16.0's forward-compatibility guarantees — the published-host consume
+  model with a `--local-host` shim, used for the first time in a release
+  ([#370](https://github.com/CategoricalData/hydra/issues/370)). 0.16.1 still builds
+  against **local** Haskell and Python hosts (`hostOverrides`), because the published
+  0.16.0 artifacts it would otherwise consume are the very ones being repaired below.
+- **First full 9 × 9 bootstrapping sweep** — every implementation generating every
+  other; dozens of cross-host issues surfaced and fixed
+  ([#409](https://github.com/CategoricalData/hydra/issues/409), ongoing).
+- **Published-package self-containment**: relocate each host's hand-written runtime
+  into `overlay/<lang>/hydra-kernel/` so it ships inside the published `hydra-kernel`
+  artifact — Python `hydra.python.util` into the wheel
+  ([#461](https://github.com/CategoricalData/hydra/issues/461),
+  [#472](https://github.com/CategoricalData/hydra/issues/472)) and the Haskell
+  authoring DSL + `Libraries`/`Terms` into the sdist
+  ([#473](https://github.com/CategoricalData/hydra/issues/473)). Generalized to a
+  uniform `overlay/ = transform(packages) + copy(overlay)` model across all hosts
+  ([#434](https://github.com/CategoricalData/hydra/issues/434)).
+- **Kernel self-containment via generated `hydra.lib.*` registries**: primitive
+  names are derived from generated `PrimitiveDefinition` def-modules rather than
+  hand-written name strings, in every host
+  ([#473](https://github.com/CategoricalData/hydra/issues/473)).
+- **In-memory encode/decode synthesis**: derived `hydra.{encode,decode}.*` modules
+  are synthesized at build time and excluded from `dist/`, with the synthesizer (not
+  inference) as the authority for their annotations
+  ([#448](https://github.com/CategoricalData/hydra/issues/448),
+  [#476](https://github.com/CategoricalData/hydra/issues/476)).
+- **Release hardening**: Apache source-release compliance (signed source archive,
+  LICENSE/NOTICE bundling, KEYS) ([#441](https://github.com/CategoricalData/hydra/issues/441)),
+  per-package publish orchestrators ([#449](https://github.com/CategoricalData/hydra/issues/449)),
+  and packaging-boundary verification gated in CI and at publish time
+  ([#472](https://github.com/CategoricalData/hydra/issues/472)).
+
+### New features
+
+- Published-host consume model wired through `bin/sync.sh` for all three hosts
+  (`--published-host` default, `--local-host` shim), with the version basis keyed
+  off `hydra.json` and the `VERSION` file retired
+  ([#370](https://github.com/CategoricalData/hydra/issues/370),
+  [#347](https://github.com/CategoricalData/hydra/issues/347)).
+- Java and Python coder DSL sources made the sole source of truth; the legacy
+  Haskell DSL copies were deleted and cross-package references resolve by name
+  ([#346](https://github.com/CategoricalData/hydra/issues/346)).
+- Per-host `verify-distribution.sh` self-containment gates (Haskell stages the
+  per-package trio and `stack build`s it; Python installs the wheels into an
+  isolated venv and imports the kernel modules; Java resolves the published jars
+  from an offline consumer), run in CI and as a hard gate in `bin/prepare-release.sh`
+  ([#472](https://github.com/CategoricalData/hydra/issues/472)).
+- Apache-compliant canonical source archive: signed + checksummed `git archive`
+  tarball as the release of record, root `NOTICE`, `KEYS`, and a release-verify CI
+  workflow ([#441](https://github.com/CategoricalData/hydra/issues/441)).
+- Per-package publish orchestrators `publish-maven.sh` / `publish-pypi.sh` with
+  dependency-closure and leaves-first ordering checks
+  ([#449](https://github.com/CategoricalData/hydra/issues/449)).
+- `hydra-typescript` published as a target Java/Maven + PyPI artifact
+  ([#468](https://github.com/CategoricalData/hydra/issues/468)).
+- Java coder emits a fluent builder for every generated record type
+  ([#465](https://github.com/CategoricalData/hydra/issues/465)); Python coder emits
+  per-field `with_<field>` copy-update methods and a fluent builder
+  ([#466](https://github.com/CategoricalData/hydra/issues/466)).
+
+### Improvements
+
+- Drop the vestigial `InferenceContext` parameter from the `Primitive.implementation`
+  carrier across all hosts; add a graph-free `funT` coder and six `lists` default
+  implementations ([#446](https://github.com/CategoricalData/hydra/issues/446)).
+- Derive package routing from declared modules; split derived generation into broad
+  `mainDslModules` and scoped `mainEncodingModules`
+  ([#474](https://github.com/CategoricalData/hydra/issues/474),
+  [#475](https://github.com/CategoricalData/hydra/issues/475)).
+- Hash JSON content into the per-package input digest; add `digest-check
+  refresh-input` and a CI guard that force-regenerates and diffs
+  `dist/haskell/hydra-{java,python}` ([#469](https://github.com/CategoricalData/hydra/issues/469)).
+- Per-package inference seeds downstream packages from each package's full universe
+  while inferring only write targets, fixing `hydra-scala` inference within the CI
+  heap budget; declare the `hydra-java` dependency in `hydra-scala` for cold
+  ordering ([#470](https://github.com/CategoricalData/hydra/issues/470)).
+- Remove the vestigial `Lib/Defaults` registry and empty `defaultLibModules`
+  manifest field from all hosts ([#437](https://github.com/CategoricalData/hydra/issues/437)).
+- Bundle LICENSE + NOTICE into Java jars (`META-INF`) and Python wheels
+  (`dist-info`); declare Apache-2.0 in the Scala build
+  ([#441](https://github.com/CategoricalData/hydra/issues/441)).
+- Mark lazy parameters on the Scala and Common Lisp primitive registries so eager
+  coders thunk correctly ([#453](https://github.com/CategoricalData/hydra/issues/453),
+  [#477](https://github.com/CategoricalData/hydra/issues/477),
+  [#425](https://github.com/CategoricalData/hydra/issues/425)).
+- Staging-loop WIP-commit gate to keep `WIP:` commits off `origin/main`
+  ([#466](https://github.com/CategoricalData/hydra/issues/466)).
+
+### Bug fixes
+
+- **Python wheel self-containment**: the `hydra-kernel` wheel now ships
+  `hydra.python.util`; gated by a packaging-boundary smoke test in CI and
+  `publish-pypi.sh` ([#472](https://github.com/CategoricalData/hydra/issues/472),
+  [#461](https://github.com/CategoricalData/hydra/issues/461)).
+- **Haskell sdist self-containment**: track the generated `Hydra/Dsl/Terms.hs`
+  (was gitignored) so the committed dist exports `ToPrimName`, fixing the cold
+  build of the published `hydra-kernel`
+  ([#473](https://github.com/CategoricalData/hydra/issues/473)).
+- Decode synthesizer threads the fully-applied result type into wrap/record/union
+  decoder bodies, so derived decoders emit `DataRow<v>` rather than raw `DataRow`,
+  fixing Java and Scala generic decode compilation
+  ([#476](https://github.com/CategoricalData/hydra/issues/476)).
+- Scala coder emits explicit type arguments for polymorphic non-primitive
+  references under a type application (e.g. `requireField`), fixing `Any`-inference
+  of curried decoder lambda parameters in `decode/typed`
+  ([#434](https://github.com/CategoricalData/hydra/issues/434)).
+- Common Lisp and Emacs Lisp: move the hand-written runtime to a dialect-tier path
+  so it no longer collides with the generated `hydra.lib.*` def-modules
+  ([#434](https://github.com/CategoricalData/hydra/issues/434)).
+- Python coder uses the binding `TypeScheme` as the authoritative source for
+  parameter and return types ([#488](https://github.com/CategoricalData/hydra/issues/488));
+  fixes a duplicate `self` parameter in builders
+  ([#478](https://github.com/CategoricalData/hydra/issues/478)).
+- Sort term definitions by name in source-file generation so non-Haskell hosts emit
+  deterministic alphabetical Haskell output (host-independent of `Maps.elems`
+  iteration order) ([#489](https://github.com/CategoricalData/hydra/issues/489)).
+- Java coder serializes the `static` method modifier (previously a non-exhaustive
+  case) ([#465](https://github.com/CategoricalData/hydra/issues/465)); JavaDoc
+  `@link`/`@param` sanitization for strict doclint
+  ([#449](https://github.com/CategoricalData/hydra/issues/449)).
+- Scala host writer appends a trailing newline when missing, fixing a Lisp-target
+  byte mismatch ([#463](https://github.com/CategoricalData/hydra/issues/463)).
+- Clojure host: silent wrapping `bigint_to_int{8,16,32,64}` casts per the kernel
+  contract ([#483](https://github.com/CategoricalData/hydra/issues/483)); load-order
+  and `--kernel-only` filter fixes after kernel renames
+  ([#425](https://github.com/CategoricalData/hydra/issues/425)); load the
+  `hydra-haskell` baseline for Clojure→Haskell rebuilds
+  ([#487](https://github.com/CategoricalData/hydra/issues/487),
+  [#460](https://github.com/CategoricalData/hydra/issues/460)).
+- Lisp-dialect bootstrap fixes: emit JSON object entries as 2-element `Pair` lists
+  rather than dotted cons ([#452](https://github.com/CategoricalData/hydra/issues/452),
+  also fixing [#16](https://github.com/CategoricalData/hydra/issues/16)); read
+  module names via the correct struct accessor
+  ([#471](https://github.com/CategoricalData/hydra/issues/471)); drop stale
+  surplus flag arguments from `generate-source-files` calls
+  ([#457](https://github.com/CategoricalData/hydra/issues/457),
+  [#458](https://github.com/CategoricalData/hydra/issues/458),
+  [#464](https://github.com/CategoricalData/hydra/issues/464)); rename eta-wrapped
+  projection/unwrap parameters to avoid kernel shadowing
+  ([#428](https://github.com/CategoricalData/hydra/issues/428)); propagate a
+  non-zero exit from the Scheme test runner on failures and fix Scheme float
+  scientific-notation formatting for `|x| >= 1e7`
+  ([#447](https://github.com/CategoricalData/hydra/issues/447)).
+- Cross-host target dispatch: Common Lisp and Clojure hosts dispatch Scala and
+  TypeScript targets ([#482](https://github.com/CategoricalData/hydra/issues/482),
+  [#483](https://github.com/CategoricalData/hydra/issues/483)); Scala/Java host
+  target-dispatch completions ([#5](https://github.com/CategoricalData/hydra/issues/5),
+  [#7](https://github.com/CategoricalData/hydra/issues/7),
+  [#17](https://github.com/CategoricalData/hydra/issues/17)).
+- TypeScript test runtime reads the kernel JSON field names `body`/`signature`
+  (not legacy `term`/`typeScheme`); `lists.nub` dedups by canonical JSON
+  ([#485](https://github.com/CategoricalData/hydra/issues/485)).
+- Sync robustness: always reassemble `dist/python` under `HYDRA_IN_SYNC` to heal
+  partial-dist state ([#480](https://github.com/CategoricalData/hydra/issues/480));
+  persist the run dir on bootstrap prep-phase failures
+  ([#481](https://github.com/CategoricalData/hydra/issues/481)); complete per-host
+  static deps so the bootstrap demo finds fresh dist
+  ([#445](https://github.com/CategoricalData/hydra/issues/445)).
+- Pin the Python target test interpreter to Python ≥ 3.12
+  ([#486](https://github.com/CategoricalData/hydra/issues/486)); Emacs Lisp / Scheme
+  target test-runner re-copy robustness
+  ([#456](https://github.com/CategoricalData/hydra/issues/456)).
+- JavaDoc Pages publish rewritten to build a combined site from the CI-generated
+  `dist/java/` artifact, fixing the failure mode where `pages.yml` ran against a
+  bare checkout with no `dist/java/` present
+  ([#450](https://github.com/CategoricalData/hydra/issues/450)).
+
+### Documentation
+
+- Document the `overlay/` self-containment model, the published-host consume model
+  for all three hosts, the `hydra.json` version / host-version basis, and a
+  migration-shims recipe ([#434](https://github.com/CategoricalData/hydra/issues/434),
+  [#370](https://github.com/CategoricalData/hydra/issues/370),
+  [#347](https://github.com/CategoricalData/hydra/issues/347)).
+- Document the kernel self-containment / `hydra.lib.*` def-module model and the
+  derived-module no-inference invariant
+  ([#473](https://github.com/CategoricalData/hydra/issues/473),
+  [#466](https://github.com/CategoricalData/hydra/issues/466)); generated Java and
+  Python record builders documented in the DSL guides
+  ([#465](https://github.com/CategoricalData/hydra/issues/465),
+  [#466](https://github.com/CategoricalData/hydra/issues/466)).
+- Use absolute GitHub URLs in package READMEs so links resolve when published
+  standalone ([#454](https://github.com/CategoricalData/hydra/issues/454)); bundle a
+  README into each Python package dir for sdist metadata
+  ([#418](https://github.com/CategoricalData/hydra/issues/418)).
+
+---
+
+## [0.16.0] - 2026-06-09
+
+Major themes: primitive-metadata reification, self-hosting coder DSLs with all
+eight hosts passing the common test suite, finalized `hydra.packaging`, and a
+deep kernel-vocabulary cleanup.
+
+### Highlights
+
+- **`PrimitiveDefinition` and per-namespace registry modules** with host-independent
+  specs for every standard-library primitive ([#156](https://github.com/CategoricalData/hydra/issues/156), [#319](https://github.com/CategoricalData/hydra/issues/319)).
+- **Self-hosting coder DSLs; all eight hosts pass the common test suite**, including
+  the completed TypeScript head ([#344](https://github.com/CategoricalData/hydra/issues/344), [#126](https://github.com/CategoricalData/hydra/issues/126)).
+- **Finalized `hydra.packaging`** and a unified `Module.dependencies` field ([#369](https://github.com/CategoricalData/hydra/issues/369), [#354](https://github.com/CategoricalData/hydra/issues/354)).
+- **Kernel-vocabulary cleanup**: `maybe`→`optional` across kernel and hosts, plus
+  order-preserving JSON objects ([#401](https://github.com/CategoricalData/hydra/issues/401), [#398](https://github.com/CategoricalData/hydra/issues/398)).
+
+### New features
+
+- Reify `PrimitiveDefinition` in `hydra.packaging` with per-namespace `hydra.lib.<sub>` registries ([#156](https://github.com/CategoricalData/hydra/issues/156)).
+- Host-independent `comments` specifications for all standard-library primitives ([#319](https://github.com/CategoricalData/hydra/issues/319)).
+- Kernel-oriented style checks in `hydra.validate.*` ([#321](https://github.com/CategoricalData/hydra/issues/321), [#351](https://github.com/CategoricalData/hydra/issues/351), [#352](https://github.com/CategoricalData/hydra/issues/352)), on a reshaped validation API ([#320](https://github.com/CategoricalData/hydra/issues/320)).
+- Promote the JSON Schema coder to a full DSL coder ([#350](https://github.com/CategoricalData/hydra/issues/350)).
+- Transpose coder sources into host-native DSLs for self-hosting ([#344](https://github.com/CategoricalData/hydra/issues/344), [#358](https://github.com/CategoricalData/hydra/issues/358)).
+- `Term`-typed annotations replacing `Map<Name, Term>` ([#386](https://github.com/CategoricalData/hydra/issues/386)).
+- Language-specific EDSL features on the kernel `Language` ([#233](https://github.com/CategoricalData/hydra/issues/233)).
+- Primitive-metadata-driven laziness in eager coders ([#391](https://github.com/CategoricalData/hydra/issues/391)).
+- `/test` skill and `bin/test.sh` for target-language test validation ([#387](https://github.com/CategoricalData/hydra/issues/387)).
+- Automatic differentiation: a `grad` transform ([#324](https://github.com/CategoricalData/hydra/issues/324)).
+- `hydra.show.error.pg` for `InvalidGraphError` ([#374](https://github.com/CategoricalData/hydra/issues/374)).
+
+### Improvements
+
+- Finalize `hydra.packaging`: `Binding`→`TypeDefinition`, `Module`/`Package` `comments`, `moduleName` cleanup ([#369](https://github.com/CategoricalData/hydra/issues/369), [#396](https://github.com/CategoricalData/hydra/issues/396), [#402](https://github.com/CategoricalData/hydra/issues/402), [#404](https://github.com/CategoricalData/hydra/issues/404)).
+- Merge `Module.termDependencies`/`typeDependencies` into one `dependencies` field ([#354](https://github.com/CategoricalData/hydra/issues/354)).
+- Resolve the `maybe`/`optional` ambiguity across kernel and all hosts ([#401](https://github.com/CategoricalData/hydra/issues/401)).
+- Order-preserving JSON objects; order-sensitive `Value` equality ([#398](https://github.com/CategoricalData/hydra/issues/398)).
+- Rename `Namespace`→`ModuleName` ([#316](https://github.com/CategoricalData/hydra/issues/316)) and the phantom DSL types to `Typed*` ([#397](https://github.com/CategoricalData/hydra/issues/397)).
+- Move from a type-class enum to type-class names ([#275](https://github.com/CategoricalData/hydra/issues/275)).
+- Repackage "eval lib" modules as kernel lib modules; promote remaining sources ([#260](https://github.com/CategoricalData/hydra/issues/260), [#355](https://github.com/CategoricalData/hydra/issues/355), [#356](https://github.com/CategoricalData/hydra/issues/356)).
+- Reshape `hydra.context` into `InferenceContext` ([#368](https://github.com/CategoricalData/hydra/issues/368)).
+- Streamline the Haskell, Java, Python, and Scala syntax models, re-pinning Java to SE 21 and Python to the 3.14 PEG grammar ([#297](https://github.com/CategoricalData/hydra/issues/297)).
+- Adopt persistent immutable collections across hosts ([#359](https://github.com/CategoricalData/hydra/issues/359), [#360](https://github.com/CategoricalData/hydra/issues/360), [#361](https://github.com/CategoricalData/hydra/issues/361), [#362](https://github.com/CategoricalData/hydra/issues/362)).
+- Migrate underscored kernel definition names to camelCase ([#348](https://github.com/CategoricalData/hydra/issues/348)).
+- Tidy qualified/unqualified imports in the Haskell DSL sources ([#308](https://github.com/CategoricalData/hydra/issues/308)).
+- Eliminate the `Hydra.Module.Compat` shim ([#315](https://github.com/CategoricalData/hydra/issues/315)).
+- Homogenize writer conventions across target languages ([#339](https://github.com/CategoricalData/hydra/issues/339)).
+- Disambiguate format-version field naming across JSON metadata ([#412](https://github.com/CategoricalData/hydra/issues/412)).
+- Per-package DSL→JSON build with per-package incremental inference ([#381](https://github.com/CategoricalData/hydra/issues/381), [#395](https://github.com/CategoricalData/hydra/issues/395)).
+- Prune stale `dist/` outputs; self-heal digests; exclude digests from VCS; reconcile drift; fail loud ([#357](https://github.com/CategoricalData/hydra/issues/357), [#393](https://github.com/CategoricalData/hydra/issues/393), [#405](https://github.com/CategoricalData/hydra/issues/405), [#378](https://github.com/CategoricalData/hydra/issues/378), [#379](https://github.com/CategoricalData/hydra/issues/379), [#392](https://github.com/CategoricalData/hydra/issues/392), [#414](https://github.com/CategoricalData/hydra/issues/414)).
+- Accept all valid (host, target) pairs in the generation drivers ([#421](https://github.com/CategoricalData/hydra/issues/421)).
+- Move Gradle build infrastructure into `heads/java/`; remove top-level `pixi.toml` ([#384](https://github.com/CategoricalData/hydra/issues/384), [#385](https://github.com/CategoricalData/hydra/issues/385)).
+- Eliminate post-generation test patches; fix loader/runner kludges; re-enable test timing ([#307](https://github.com/CategoricalData/hydra/issues/307), [#309](https://github.com/CategoricalData/hydra/issues/309), [#311](https://github.com/CategoricalData/hydra/issues/311)).
+- Performance/benchmarks and usability assessments ([#277](https://github.com/CategoricalData/hydra/issues/277), [#283](https://github.com/CategoricalData/hydra/issues/283)).
+- Split the Hackage distribution into per-package distributions ([#418](https://github.com/CategoricalData/hydra/issues/418)).
+
+### Bug fixes
+
+- Encode `uint32` JSON literals as numbers, not strings ([#431](https://github.com/CategoricalData/hydra/issues/431)).
+- Satisfy or suppress warnings in generated Java ([#349](https://github.com/CategoricalData/hydra/issues/349)).
+- Restore JSON parser test cases (polymorphic case handling, ordering fallback) ([#336](https://github.com/CategoricalData/hydra/issues/336)).
+- Keep annotations through `termAlternatives`/`typeAlternatives` adaptation ([#353](https://github.com/CategoricalData/hydra/issues/353)).
+- Scala host decodes module JSON containing term definitions ([#342](https://github.com/CategoricalData/hydra/issues/342)).
+- Java coder: fix exponential `let`-bound `cases` cost ([#372](https://github.com/CategoricalData/hydra/issues/372)) and explicit type args on `PersistentMap.ofEntries` ([#394](https://github.com/CategoricalData/hydra/issues/394)).
+- Python-host codegen: drop extra `pyStringToPyStrings` wrapping ([#367](https://github.com/CategoricalData/hydra/issues/367)).
+- `escape_literal_char` no longer mangles RDF triples ([#363](https://github.com/CategoricalData/hydra/issues/363)).
+- Sync robustness: stale coder JSON, omitted native modules, dead helper, bad source dirs ([#406](https://github.com/CategoricalData/hydra/issues/406), [#400](https://github.com/CategoricalData/hydra/issues/400), [#411](https://github.com/CategoricalData/hydra/issues/411), [#408](https://github.com/CategoricalData/hydra/issues/408)).
+- Cross-host self-hosting fixes (Scala, TypeScript, and the four Lisp dialects) ([#422](https://github.com/CategoricalData/hydra/issues/422), [#423](https://github.com/CategoricalData/hydra/issues/423), [#424](https://github.com/CategoricalData/hydra/issues/424), [#429](https://github.com/CategoricalData/hydra/issues/429), [#444](https://github.com/CategoricalData/hydra/issues/444), [#366](https://github.com/CategoricalData/hydra/issues/366), [#389](https://github.com/CategoricalData/hydra/issues/389), [#407](https://github.com/CategoricalData/hydra/issues/407), [#425](https://github.com/CategoricalData/hydra/issues/425), [#426](https://github.com/CategoricalData/hydra/issues/426), [#427](https://github.com/CategoricalData/hydra/issues/427), [#432](https://github.com/CategoricalData/hydra/issues/432), [#438](https://github.com/CategoricalData/hydra/issues/438), [#439](https://github.com/CategoricalData/hydra/issues/439), [#443](https://github.com/CategoricalData/hydra/issues/443)).
+
+### Removed
+
+- Removed the `bigfloat` literal type from `FloatType` and `FloatValue` ([#330](https://github.com/CategoricalData/hydra/issues/330)).
+  Arbitrary-precision floating-point values were inconsistently supported
+  across host languages (Java/Scala in particular lacked a true IEEE 754
+  arbitrary-precision implementation), and nothing in the codebase relied on
+  them. `FloatType` and `FloatValue` now have only `float32` and `float64`
+  variants. Removed library primitives: `bigfloatToBigint`, `bigfloatToFloat32`,
+  `bigfloatToFloat64`, `bigintToBigfloat`, `float32ToBigfloat`,
+  `float64ToBigfloat`, `readBigfloat`, `showBigfloat`, `roundBigfloat`. New
+  primitives `float32ToFloat64` and `float64ToFloat32` (the latter lossy)
+  replace the removed bigfloat-routed conversions.
+- Removed `heads/haskell/bin/assemble-hackage-sdist.sh` ([#418](https://github.com/CategoricalData/hydra/issues/418)), the 0.15-era
+  bridge that flattened the multi-source-dir Haskell head into one self-contained
+  `hydra` sdist. Superseded by the per-package assembler (see Improvements).
+
+### Documentation
+
+- Comprehensive documentation refresh for 0.16 ([#383](https://github.com/CategoricalData/hydra/issues/383))
+  spanning nine tracks across READMEs, `docs/`, the wiki, CLAUDE.md, and
+  in-source kernel comments.
+- New `docs/json-format.md` reference describing the canonical JSON wire format
+  (tagged-union duality, optional-field rules, IEEE 754 sentinels, integer
+  threshold).
+- New wiki pages: `Design` (rationale behind each major choice) and `Inference`
+  (HM type inference with class constraints).
+- Cross-checked every prose doc against current code; corrected drift in
+  primitive-checking sections of `docs/recipes/maintenance.md`, the `Primitive`
+  shape in `docs/implementation.md` and `docs/recipes/adding-primitives.md`,
+  and the build-system narrative.
+- Wove motivation ("the why") through the existing doc surface rather than
+  collecting it into separately-titled sidebars; landed an inference-overview
+  centerpiece on the wiki ([#377](https://github.com/CategoricalData/hydra/issues/377)).
+- Aligned doc vocabulary with the LambdaGraph paper and the literature review
+  for the design space Hydra inhabits.
+- Net-new READMEs for `packages/hydra-kernel`, `packages/hydra-ext`,
+  `packages/hydra-coq`, and `packages/hydra-wasm`; top-level `README.md`
+  now carries a canonical packages table.
+- Audited and refreshed the Claude surface: CLAUDE.md "Where to look up X"
+  table extended with rows for `docs/getting-started.md`, `docs/json-format.md`,
+  and the `Design` / `Inference` wiki pages; hard-rules block reordered by
+  violation frequency; `claude/pitfalls.md` superseded entries folded into
+  `docs/troubleshooting.md` / recipes.
+- Project-descriptor strings reviewed and aligned across 24 build / packaging
+  files (Hackage synopsis, Maven Central description, PyPI / conda-forge
+  classifiers, Hydra-format `package.json` files).
+- `docs/index.html` (the GitHub Pages landing page) refreshed with audience
+  hops into wiki Concepts / Design, `docs/getting-started.md`, and the GitHub
+  repo, plus the full published-artifact list across Hackage, Maven Central,
+  PyPI, and conda-forge.
+- In-source kernel-code rationale comments added at key Sources sites covering
+  injection / pair / either / unit-void duality, error taxonomy, variant
+  records, inference-context threading, validation profiles, reduction state,
+  lexical filters, name mangling, scoping, variable handling, defaults
+  integration, and Tarjan SCC choice rationale. JSON encode/decode modules
+  cross-reference `docs/json-format.md`.
+- Filed `Primitive.implementation` carrier-simplification follow-up
+  ([#446](https://github.com/CategoricalData/hydra/issues/446))
+  to drop the unused `InferenceContext` and `Graph` parameters once the
+  `Lib/Defaults/` integration ([#437](https://github.com/CategoricalData/hydra/issues/437))
+  lands.
+
+---
+
+## [0.15.0] - 2026-04-29
+
+A structural-cleanup release.
+The repository is reorganized into a three-tree
+`packages/` (DSL sources) / `heads/` (per-host runtime) / `dist/` (generated output)
+layout ([#290](https://github.com/CategoricalData/hydra/issues/290)), the kernel is simplified ([#251](https://github.com/CategoricalData/hydra/issues/251), [#292](https://github.com/CategoricalData/hydra/issues/292), [#332](https://github.com/CategoricalData/hydra/issues/332)), and Java + Python now
+ship as per-package publishable artifacts on Maven Central / PyPI / conda-forge
+([#305](https://github.com/CategoricalData/hydra/issues/305)).
+Incremental, content-hash-based caches accelerate the sync pipeline ([#247](https://github.com/CategoricalData/hydra/issues/247)).
+Three new generation-only targets — Coq ([#326](https://github.com/CategoricalData/hydra/issues/326)), WebAssembly ([#325](https://github.com/CategoricalData/hydra/issues/325)), and an
+automatic-differentiation demo ([#324](https://github.com/CategoricalData/hydra/issues/324)) — are in progress as Claude collaborations.
+
+### Highlights
+
+- **Three-tree repository layout**: `packages/` (DSL), `heads/` (host runtime),
+  `dist/` (generated) ([#290](https://github.com/CategoricalData/hydra/issues/290)).
+- **Per-package distributions** for Java (4 Maven artifacts) and Python (5 wheels):
+  `hydra-kernel`, `hydra-pg`, `hydra-rdf`, `hydra-{java,python}`, plus `hydra-ext`
+  on PyPI ([#305](https://github.com/CategoricalData/hydra/issues/305)).
+- **Kernel simplifications**: `Function`/`Elimination` removed ([#332](https://github.com/CategoricalData/hydra/issues/332)),
+  `FunctionPrimitive` removed ([#251](https://github.com/CategoricalData/hydra/issues/251)), `Hydra.Ext.*` prefix retired ([#331](https://github.com/CategoricalData/hydra/issues/331)),
+  `Context` error wrapper gone ([#292](https://github.com/CategoricalData/hydra/issues/292)).
+- **Incremental caches** across the sync pipeline; ~70x speedup on no-op resync ([#247](https://github.com/CategoricalData/hydra/issues/247)).
+- **JSON kernel format v1** with formal wire-format spec and four-field rename ([#343](https://github.com/CategoricalData/hydra/issues/343)).
+- **Three new generation-only targets** (in progress): Coq ([#326](https://github.com/CategoricalData/hydra/issues/326)), WebAssembly ([#325](https://github.com/CategoricalData/hydra/issues/325)),
+  automatic-differentiation demo ([#324](https://github.com/CategoricalData/hydra/issues/324)).
+
+### New features
+
+- Per-package distributions ([#305](https://github.com/CategoricalData/hydra/issues/305)): standalone Maven / PyPI / conda-forge builds,
+  generated `build.gradle` / `pyproject.toml` per package, transitive dep resolution.
+- JSON kernel format v1 ([#343](https://github.com/CategoricalData/hydra/issues/343)): formal spec at `docs/json-format.md`,
+  four-field rename to `typeScheme`, `Module` field reorder, `formatVersion` stamp.
+- `decimal` literal type in the kernel ([#338](https://github.com/CategoricalData/hydra/issues/338)) across all hosts.
+- Type-directed JSON encoder with idiomatic optional encoding ([#314](https://github.com/CategoricalData/hydra/issues/314), [#318](https://github.com/CategoricalData/hydra/issues/318)).
+- Incremental type inference plus content-hash caches ([#247](https://github.com/CategoricalData/hydra/issues/247)).
+- Coq generation target ([#326](https://github.com/CategoricalData/hydra/issues/326), in progress): `hydra-coq` package, 131/131 `.v` files pass `coqc`.
+- WebAssembly target ([#325](https://github.com/CategoricalData/hydra/issues/325), in progress): `hydra-wasm` package, M4 closure mechanism.
+- Automatic-differentiation demo ([#324](https://github.com/CategoricalData/hydra/issues/324), in progress): symbolic source-to-source.
+- `hydra.show.error` module ([#265](https://github.com/CategoricalData/hydra/issues/265)): consolidated error-message builders.
+- `hydra.lib.maybes.toList` primitive ([#257](https://github.com/CategoricalData/hydra/issues/257)).
+- NaN / Inf round-tripping through JSON and per-language serdes ([#312](https://github.com/CategoricalData/hydra/issues/312), [#318](https://github.com/CategoricalData/hydra/issues/318), [#330](https://github.com/CategoricalData/hydra/issues/330)).
+- Typeclass inference test group ([#274](https://github.com/CategoricalData/hydra/issues/274)).
+- Term and type linters ([#232](https://github.com/CategoricalData/hydra/issues/232)).
+- Validation for modules and graphs ([#155](https://github.com/CategoricalData/hydra/issues/155)).
+- User-defined-function (UDF) support and DSL-vs-primitive overrides
+  ([#62](https://github.com/CategoricalData/hydra/issues/62), [#63](https://github.com/CategoricalData/hydra/issues/63), [#102](https://github.com/CategoricalData/hydra/issues/102), [#158](https://github.com/CategoricalData/hydra/issues/158)).
+- Stale-source detection across sync entrypoints ([#228](https://github.com/CategoricalData/hydra/issues/228)).
+
+### Improvements
+
+- Sync infrastructure: matrix tool, per-package orchestrator, per-language wrappers ([#290](https://github.com/CategoricalData/hydra/issues/290)).
+- TestGraph post-generation patches eliminated; DSL emits `TestEnv` refs directly.
+- Minimized standard imports in generated Haskell ([#161](https://github.com/CategoricalData/hydra/issues/161)); improved auto-aliases ([#322](https://github.com/CategoricalData/hydra/issues/322)).
+- Removed kernel term dependencies from the interpreter ([#257](https://github.com/CategoricalData/hydra/issues/257)).
+- Removed `Graph` and `Context` arguments from primitive implementations ([#266](https://github.com/CategoricalData/hydra/issues/266)).
+- Refactored kernel term modules: split rewriting/schemas, renamed show.meta → codegen,
+  moved `Coder` to `coders`, merged `extract.helpers` ([#221](https://github.com/CategoricalData/hydra/issues/221)).
+- Removed Aeson and HsYAML dependencies; YAML coder moved to `hydra-ext` ([#261](https://github.com/CategoricalData/hydra/issues/261)).
+- Lisp recursive let bindings via SCC ([#341](https://github.com/CategoricalData/hydra/issues/341)); parenthesis cleanup ([#84](https://github.com/CategoricalData/hydra/issues/84)).
+- Everything-to-everything bootstrapping demo ([#254](https://github.com/CategoricalData/hydra/issues/254)).
+- Re-enabled skipped Python tests; `disabledForPython` retired ([#263](https://github.com/CategoricalData/hydra/issues/263)).
+- Promoted host-specific code in `packages/` into per-head locations ([#337](https://github.com/CategoricalData/hydra/issues/337)).
+- Migrated `hydra.common` Java module out ([#10](https://github.com/CategoricalData/hydra/issues/10)).
+- Test infrastructure unification under `UniversalTestCase` ([#246](https://github.com/CategoricalData/hydra/issues/246)).
+- Default property graph → RDF mapping ([#296](https://github.com/CategoricalData/hydra/issues/296)).
+- 13 unsafe partial primitives replaced with `Maybe`-returning alternatives ([#201](https://github.com/CategoricalData/hydra/issues/201)).
+- Java generated code uses standard `java.util` collection interfaces ([#313](https://github.com/CategoricalData/hydra/issues/313)).
+- `Term.union` renamed to `Term.inject` ([#334](https://github.com/CategoricalData/hydra/issues/334)).
+- Inconsistencies in domain DSLs cleaned up ([#219](https://github.com/CategoricalData/hydra/issues/219)).
+- Coder packages moved out of hydra-haskell ([#182](https://github.com/CategoricalData/hydra/issues/182)).
+- Java package-naming scheme revised ([#223](https://github.com/CategoricalData/hydra/issues/223)).
+- Decimal used (instead of bigfloat) for JSON numbers ([#340](https://github.com/CategoricalData/hydra/issues/340)).
+- Hydra kernel moved out of hydra-haskell ([#282](https://github.com/CategoricalData/hydra/issues/282)).
+
+### Bug fixes
+
+- `substInTypeScheme` capture-unsafe substitution under nested forall binders.
+- Java `Float64` arithmetic primitives corrected for current `PrimitiveFunction` API.
+- Clojure decimal handling: value-based equality, `BigInteger` return from `decimal_to_bigint`.
+- Scheme runtime R7RS imports for `sets.scm` / `maps.scm` / `eithers.map_set`.
+- Python coder defaults corrected from `Py.Name` to `Py.Expression`.
+- Scala host JSON-decode failure on modules containing term definitions ([#342](https://github.com/CategoricalData/hydra/issues/342)).
+- Lisp coder mutually-recursive let bindings for Clojure ([#341](https://github.com/CategoricalData/hydra/issues/341)).
+
+### Documentation
+
+- Documentation refresh for the 0.15 packaging restructure ([#290](https://github.com/CategoricalData/hydra/issues/290), [#331](https://github.com/CategoricalData/hydra/issues/331)); CLAUDE.md,
+  READMEs, recipes, demos, and seven wiki pages updated.
+- Code-generation recipe rewritten for the per-package dist layout ([#282](https://github.com/CategoricalData/hydra/issues/282)).
+- New `maintenance.md` recipe consolidates non-source-file scans, stale generated
+  detection, design-violation checks, and freshness checks.
+- Documentation style guide added at `docs/documentation-style-guide.md`.
+- Cross-worktree messaging protocol documented in CLAUDE.md.
+- Decimal type documented in the lexicon and per-language READMEs ([#338](https://github.com/CategoricalData/hydra/issues/338)).
+- JSON encoding format docs updated for idiomatic optional encoding ([#314](https://github.com/CategoricalData/hydra/issues/314)).
+
+---
+
+## [0.14.1] - 2026-03-30
+
+Patch release.
+Regenerates all implementations after a fix to the group eval primitive ([#281](https://github.com/CategoricalData/hydra/issues/281)),
+and relocates the property-graph and RDF/SHACL "ext" modules into hydra-java and hydra-python.
+
+### Improvements
+
+- Moved PG, RDF, and SHACL ext modules from hydra-ext into hydra-java and hydra-python.
+
+### Bug fixes
+
+- Group eval primitive fix; all targets regenerated ([#281](https://github.com/CategoricalData/hydra/issues/281)).
+- JavaDoc HTML-entity escaping in generated `DestructuringPattern.java`.
+
+---
+
+## [0.14.0] - 2026-03-29
+
+Major release adding four new complete Hydra implementations — Scala ([#273](https://github.com/CategoricalData/hydra/issues/273)),
+Clojure ([#278](https://github.com/CategoricalData/hydra/issues/278)), Common Lisp, and Scheme — bringing the total to seven bootstrapping hosts
+(plus Emacs Lisp, which passes the test suite but does not yet participate in bootstrapping).
+Also includes kernel simplifications, an Avro bidirectional coder ([#301](https://github.com/CategoricalData/hydra/issues/301)),
+eval primitives ([#281](https://github.com/CategoricalData/hydra/issues/281)), new demos, and significant performance work on the Scheme host.
+
+### Highlights
+
+- **Four new complete implementations**: Hydra-Scala ([#273](https://github.com/CategoricalData/hydra/issues/273)), Hydra-Clojure ([#278](https://github.com/CategoricalData/hydra/issues/278)),
+  Hydra-Common Lisp, and Hydra-Scheme pass the common test suite and can serve as
+  bootstrapping hosts.
+  The four Lisp dialects share a single coder and serializer.
+- **Kernel simplifications**: removed `RowType`/`WrappedType` ([#82](https://github.com/CategoricalData/hydra/issues/82)),
+  unified `Graph`/`TypeContext`/`InferenceContext` ([#192](https://github.com/CategoricalData/hydra/issues/192)),
+  replaced `Module.elements` with `Module.definitions` ([#214](https://github.com/CategoricalData/hydra/issues/214)),
+  consolidated error types ([#268](https://github.com/CategoricalData/hydra/issues/268)), and promoted all staging modules to DSL sources ([#267](https://github.com/CategoricalData/hydra/issues/267)).
+- **Avro bidirectional coder** ([#301](https://github.com/CategoricalData/hydra/issues/301)) with property graph pipeline demo.
+- **Scheme bootstrap performance**: 58 minutes → 5.7 minutes via O(1) vhash data structures
+  and IEEE 754 float precision fixes.
+
+### Breaking changes
+
+- Removed legacy adapter framework; replaced by the staging-promoted variant ([#236](https://github.com/CategoricalData/hydra/issues/236), [#295](https://github.com/CategoricalData/hydra/issues/295)).
+- Replaced legacy Flow monad with Either ([#245](https://github.com/CategoricalData/hydra/issues/245)).
+- Removed `Module.elements`; use `Module.definitions` ([#214](https://github.com/CategoricalData/hydra/issues/214)).
+- Removed `RowType` and `WrappedType` ([#82](https://github.com/CategoricalData/hydra/issues/82)).
+- Renamed `hydra.accessors` to `hydra.paths` ([#271](https://github.com/CategoricalData/hydra/issues/271)).
+- Renamed `hydra.tarjan` and merged into `hydra.sorting` ([#220](https://github.com/CategoricalData/hydra/issues/220)).
+- Merged `hydra.constraints` into `hydra.query` ([#272](https://github.com/CategoricalData/hydra/issues/272)).
+- Moved `hydra.workflow` to hydra-ext ([#270](https://github.com/CategoricalData/hydra/issues/270)).
+- Consolidated `hydra.compute` into `hydra.util` ([#269](https://github.com/CategoricalData/hydra/issues/269)).
+- Removed `hydra.describe` ([#216](https://github.com/CategoricalData/hydra/issues/216)) and types from `hydra.mantle` ([#217](https://github.com/CategoricalData/hydra/issues/217)).
+- Replaced `OtherError` with task-specific error types ([#268](https://github.com/CategoricalData/hydra/issues/268)).
+- Java: lowered minimum Java version to 11 ([#249](https://github.com/CategoricalData/hydra/issues/249)).
+- Java: `Pair` replaces `Tuple2` ([#252](https://github.com/CategoricalData/hydra/issues/252)); `Comparable` implemented for generated classes ([#131](https://github.com/CategoricalData/hydra/issues/131)).
+
+### New features
+
+- Hydra-Scala ([#273](https://github.com/CategoricalData/hydra/issues/273)): complete implementation, sbt/Scala 3, 3043 tests.
+- Hydra-Lisp: Clojure ([#278](https://github.com/CategoricalData/hydra/issues/278)), Common Lisp, Emacs Lisp, Scheme — four dialects,
+  one coder. CI workflows for Clojure, Common Lisp, and Scheme.
+- Avro bidirectional coder ([#301](https://github.com/CategoricalData/hydra/issues/301)) with demo.
+- Eval primitives ([#281](https://github.com/CategoricalData/hydra/issues/281)): Logic, Equality, Math, collections, and Groups.
+- Generated DSL modules ([#180](https://github.com/CategoricalData/hydra/issues/180)): `hydra.dsls` generates DSL helpers from type modules.
+- New demos: GraphQL+JSON ([#279](https://github.com/CategoricalData/hydra/issues/279)), PG validation ([#284](https://github.com/CategoricalData/hydra/issues/284)), SHACL ([#294](https://github.com/CategoricalData/hydra/issues/294)), Avro+PG.
+- Packaging module ([#290](https://github.com/CategoricalData/hydra/issues/290)): `hydra.packaging` with `Package` type and validation.
+- New primitives: `lists.foldr` ([#280](https://github.com/CategoricalData/hydra/issues/280)), `maybes.toList`, float rounding ([#264](https://github.com/CategoricalData/hydra/issues/264), [#285](https://github.com/CategoricalData/hydra/issues/285)).
+- Cross-language benchmarking suite ([#234](https://github.com/CategoricalData/hydra/issues/234)).
+- Limited typeclass inference ([#164](https://github.com/CategoricalData/hydra/issues/164)).
+- Standardized validation patterns across modules ([#291](https://github.com/CategoricalData/hydra/issues/291)).
+
+### Improvements
+
+- Promoted all staging modules to DSL sources ([#267](https://github.com/CategoricalData/hydra/issues/267)).
+- Removed legacy adapters, JSON/YAML coders, grammar framework ([#236](https://github.com/CategoricalData/hydra/issues/236), [#295](https://github.com/CategoricalData/hydra/issues/295)).
+- Java: efficient immutable data structures ([#193](https://github.com/CategoricalData/hydra/issues/193)); flattened term naming.
+- Java: hidden specialized collection classes in type-level files ([#313](https://github.com/CategoricalData/hydra/issues/313)).
+- Inference error messages improved ([#231](https://github.com/CategoricalData/hydra/issues/231)).
+- Combined nested let bindings in the Haskell coder ([#248](https://github.com/CategoricalData/hydra/issues/248)).
+- Simplified `hydra.adapt.simple` ([#255](https://github.com/CategoricalData/hydra/issues/255)).
+- Removed Haskell operators dependency from tests ([#288](https://github.com/CategoricalData/hydra/issues/288)).
+- Regression tests for non-Haskell/Java coders ([#85](https://github.com/CategoricalData/hydra/issues/85)).
+- Regex support added ([#293](https://github.com/CategoricalData/hydra/issues/293)).
+- `hydra.annotations.isNativeType` revisited ([#214](https://github.com/CategoricalData/hydra/issues/214)).
+- Migrated grammar-generated models ([#295](https://github.com/CategoricalData/hydra/issues/295)).
+- `<<= -shouldBe-> <<~` operator change ([#276](https://github.com/CategoricalData/hydra/issues/276)).
+- Minimize Generation.hs ([#225](https://github.com/CategoricalData/hydra/issues/225)).
+- Implemented missing Flows primitives ([#183](https://github.com/CategoricalData/hydra/issues/183)).
+- Removed JavaDocs from the repository ([#262](https://github.com/CategoricalData/hydra/issues/262)).
+- Floating-point test portability fixes for Linux CI ([#264](https://github.com/CategoricalData/hydra/issues/264), [#285](https://github.com/CategoricalData/hydra/issues/285)).
+- Moved YAML coder to hydra-ext ([#224](https://github.com/CategoricalData/hydra/issues/224)).
+- Minimized native Python and Java primitives in favor of DSL implementations ([#244](https://github.com/CategoricalData/hydra/issues/244)).
+- Removed the `disabledForPython` test tag ([#250](https://github.com/CategoricalData/hydra/issues/250)).
+
+### Release tooling
+
+- 0.14 release tracking ([#304](https://github.com/CategoricalData/hydra/issues/304)).
+
+### Documentation
+
+- Thorough cleanup of user documentation ([#302](https://github.com/CategoricalData/hydra/issues/302), [#303](https://github.com/CategoricalData/hydra/issues/303)).
+- Coding style guide added to wiki.
+- Updated 'new implementation' recipe with learnings from Clojure head ([#278](https://github.com/CategoricalData/hydra/issues/278)).
+
+---
+
+## [0.13.0] - 2026-02-27
+
+Major release completing Hydra-Python ([#66](https://github.com/CategoricalData/hydra/issues/66)) and Hydra-Java ([#166](https://github.com/CategoricalData/hydra/issues/166)) as self-hosting Hydra implementations
+and demonstrating mutual self-hosting across all three languages.
+Significant improvements to type inference, type checking, rewriting, and adaptation.
+New language features include first-class Either types, typeclass inference, binary data support,
+and a native JSON parser/writer.
+Comprehensive tooling for cross-implementation bootstrapping
+and provisional support for Go, Rust, and JavaScript targets.
+
+### Highlights
+
+- **Mutual self-hosting across three implementations**: Hydra is now fully self-hosting
+  in Haskell ([#179](https://github.com/CategoricalData/hydra/issues/179)), Java, and Python, and can cross-generate between every combination
+  of host and target language (9 paths total).
+- **Hydra-Java is complete** ([#166](https://github.com/CategoricalData/hydra/issues/166)): all kernel and generation tests pass.
+- **Hydra-Python is complete** ([#66](https://github.com/CategoricalData/hydra/issues/66)): 100% test parity with Haskell.
+- **Language coders promoted into the Hydra kernel** ([#176](https://github.com/CategoricalData/hydra/issues/176)): Haskell, Java, and Python
+  coders are now defined as Hydra DSL modules, making them self-hosting.
+- **Either type support** ([#210](https://github.com/CategoricalData/hydra/issues/210)) with full inference, checking, and library support.
+- **Native JSON parser and writer** ([#188](https://github.com/CategoricalData/hydra/issues/188), [#243](https://github.com/CategoricalData/hydra/issues/243), [#253](https://github.com/CategoricalData/hydra/issues/253)): Hydra's own JSON parser and writer
+  replace the Aeson dependency; bootstrap-from-JSON architecture for cross-implementation
+  code generation.
+
+### Breaking changes
+
+- Renamed `Optional` to `Maybe` throughout the codebase ([#204](https://github.com/CategoricalData/hydra/issues/204)):
+  `hydra.lib.optionals` → `hydra.lib.maybes`; all `optional` variants renamed to `maybe`.
+- Removed unlabeled product and sum types; replaced with pair types ([#212](https://github.com/CategoricalData/hydra/issues/212)).
+- Renamed `hydra.core.TypedTerm` to `hydra.core.TypeApplicationTerm`.
+- Renamed `hydra.json` to `hydra.json.model`.
+- Renamed `hydra.lib.maps.remove` to `hydra.lib.maps.delete`.
+- Removed deprecated `hydra.decoding` module.
+- Removed old `hydra.mantle.Either` type (replaced by core `Either`).
+- Removed `hydra.lib.tuples` library.
+- Removed C# coder stub (C# syntax model remains).
+- DSL syntax migration: removed `OverloadedStrings` for term expressions ([#238](https://github.com/CategoricalData/hydra/issues/238)).
+- Removed `Hydra.Dsl.ShorthandTypes` ([#222](https://github.com/CategoricalData/hydra/issues/222)).
+
+### New features
+
+- Self-hosting in Haskell ([#179](https://github.com/CategoricalData/hydra/issues/179)) and full mutual cross-generation (Haskell ↔ Java ↔ Python).
+- New bootstrapping demo validating all 9 paths across 249 modules.
+- Promoted Haskell, Java, and Python coders from staging code into Hydra DSL sources ([#176](https://github.com/CategoricalData/hydra/issues/176)).
+- JSON-as-source-of-truth bootstrapping architecture ([#243](https://github.com/CategoricalData/hydra/issues/243), [#253](https://github.com/CategoricalData/hydra/issues/253)):
+  new executables and scripts enabling `bootstrap-from-json` for cross-implementation
+  code generation.
+- Generated term encoders and decoders replace legacy hand-coded modules ([#47](https://github.com/CategoricalData/hydra/issues/47)).
+- Hydra-Python completion ([#66](https://github.com/CategoricalData/hydra/issues/66)): restructured project layout with `src/main` and
+  `src/gen-main` ([#191](https://github.com/CategoricalData/hydra/issues/191)); full library implementations including `hydra.lib.flows`;
+  `@lru_cache` optimization for nullary bindings; PyPy compatibility.
+- Hydra-Java completion ([#166](https://github.com/CategoricalData/hydra/issues/166)): all kernel and generation tests pass; deep changes
+  to Java coder; `Lazy` utility class for delayed evaluation; array-type support
+  in Java serde; tail-call optimization in the Java coder; `Tuple` implements `Comparable`.
+- Either type ([#210](https://github.com/CategoricalData/hydra/issues/210)): `EitherType`, `either` term constructor, `hydra.lib.eithers` library
+  with `either`, `map`, `mapList`, `mapMaybe`, `bimap`, `bind`, `fromLeft`, `fromRight`,
+  `isLeft`, `isRight`, `lefts`, `rights`, `partitionEithers`.
+- Pair type as a core construct ([#211](https://github.com/CategoricalData/hydra/issues/211)).
+- Void type ([#237](https://github.com/CategoricalData/hydra/issues/237)): uninhabited `void` type as the dual of `unit`; type-level only.
+- Native JSON parser and writer ([#188](https://github.com/CategoricalData/hydra/issues/188), [#242](https://github.com/CategoricalData/hydra/issues/242)):
+  bidirectional JSON encoder/decoder; replaces the Aeson dependency;
+  cross-checked via a special test runner.
+- Typeclass inference ([#164](https://github.com/CategoricalData/hydra/issues/164)):
+  type schemes with typeclass constraints via `TypeVariableMetadata`;
+  typeclass metadata on primitive definitions; Haskell coder uses typeclass info.
+- Binary/`ByteString` support ([#172](https://github.com/CategoricalData/hydra/issues/172)): binary data via `ByteString` instead of `String`;
+  Haskell coder uses `Data.ByteString`; new `binaryToBytes` primitive.
+- Parser combinators: new `hydra.parsing` module with combinator types and DSL.
+- Higher-order primitive interpreter ([#198](https://github.com/CategoricalData/hydra/issues/198)): all primitives are fully interpretable
+  across all three implementations; legacy `requiresInterp` tag removed.
+- Let hoisting and flattening: hoisting polymorphic let terms;
+  refined hoisting for monomorphic bindings inside polymorphic ones;
+  more efficient `liftLambdaAboveLet` ([#202](https://github.com/CategoricalData/hydra/issues/202));
+  case-statement hoisting ([#241](https://github.com/CategoricalData/hydra/issues/241)); subterm hoisting helpers.
+- Provisional language targets: Go ([#65](https://github.com/CategoricalData/hydra/issues/65)), Rust (with experimental type-level coder),
+  JavaScript (syntax model, serde, DSL, generated sources), and Java/Python syntax DSLs.
+- New adapter framework ([#236](https://github.com/CategoricalData/hydra/issues/236)): all external coders refactored
+  (Haskell, YAML, Scala, JSON Schema, C++, PDL, Protobuf, GraphQL).
+- Compact labeled records and variants ([#122](https://github.com/CategoricalData/hydra/issues/122)).
+- New primitives:
+  `hydra.lib.lists.find`, `hydra.lib.lists.partition`,
+  `hydra.lib.flows.withDefault`, `hydra.lib.flows.foldl`,
+  `hydra.lib.math.{max,min,abs,pred,signum,succ,even,odd}`,
+  `hydra.lib.pairs.bimap`, `hydra.lib.eithers.bind`,
+  `hydra.lib.literals.binaryToBytes`, complete `readXxx`/`showXxx` families,
+  `hydra.lexical.chooseUniqueName`, `neg` renamed to `negate`,
+  full floating-point math primitives in Python ([#208](https://github.com/CategoricalData/hydra/issues/208)).
+- DeepCore DSL: a layer one level deeper than the Meta DSLs,
+  for programs that construct programs that construct terms.
+- `typeOf` implementation ([#168](https://github.com/CategoricalData/hydra/issues/168)).
+- Implement `Comparable` for generated Java classes ([#131](https://github.com/CategoricalData/hydra/issues/131)); update of Hydra-Java ([#166](https://github.com/CategoricalData/hydra/issues/166)).
+- Compact labeled records exploration ([#122](https://github.com/CategoricalData/hydra/issues/122)).
+- Comparison primitives without typeclasses ([#187](https://github.com/CategoricalData/hydra/issues/187)).
+- Investigated core support for Either and Flow monads ([#200](https://github.com/CategoricalData/hydra/issues/200)).
+
+### Improvements
+
+- Type system:
+  - Refactored `hydra.inference` to create new module `hydra.checking`.
+  - Inference checks after unification to prevent schema names from being unified
+    with inferred type variables.
+  - Type application terms preserved when preparing application terms for Python.
+  - Sanity-check tuple projection index against arity during inference.
+  - Bind lost type variables in term annotations.
+  - Made `extendTypeContextForLet` tolerant of untyped bindings.
+- Code generation:
+  - Python: support for deeply-nested match statements; more complete `let` support;
+    Pythonic syntax for polymorphic function definitions; refinements for complex
+    case-hoisting scenarios; performance improvements ([#209](https://github.com/CategoricalData/hydra/issues/209), [#239](https://github.com/CategoricalData/hydra/issues/239), [#240](https://github.com/CategoricalData/hydra/issues/240)); inline
+    let/case rewriting for Python targets ([#203](https://github.com/CategoricalData/hydra/issues/203)).
+  - Java: method declaration style consistent with calling style.
+  - Haskell: standardized typeclass names.
+  - Increased maximum trace depth to support more complex sources.
+- Common test suite promotion: all tests promoted into a shared, implementation-independent
+  test kernel ([#213](https://github.com/CategoricalData/hydra/issues/213)).
+- Statically-compiled test suite in Haskell ([#207](https://github.com/CategoricalData/hydra/issues/207)).
+- Included all Hydra kernel types in test schema ([#205](https://github.com/CategoricalData/hydra/issues/205)).
+- Reorganized Haskell DSL definitions; standardized imports.
+- Added TODO comments to all unsafe primitives ([#201](https://github.com/CategoricalData/hydra/issues/201)).
+- New `rewriteAndFoldTerm` utility for simultaneous rewriting and folding.
+- Lexical helper for dereferencing schema types through aliases.
+- Made JSON parser lazy with new `lazy` parser combinator.
+- More efficient substitution helpers for empty substitutions.
+- Precomputed type/inference context in kernel test runner for performance.
+- Property graph encoding and decoding modules promoted into DSL.
+- `hydra.tabular` and `hydra.pg.graphson` modules promoted into DSL.
+- `hydra.show.*` modules generated into Java and Python.
+- Aligned epsilon encoding with the LambdaGraph spec ([#89](https://github.com/CategoricalData/hydra/issues/89)).
+- Fixed asymmetry of introductions and eliminations ([#86](https://github.com/CategoricalData/hydra/issues/86), [#134](https://github.com/CategoricalData/hydra/issues/134)).
+- Minimized inferred type annotations ([#114](https://github.com/CategoricalData/hydra/issues/114)).
+- Investigated combining products with records, sums with unions ([#196](https://github.com/CategoricalData/hydra/issues/196), [#212](https://github.com/CategoricalData/hydra/issues/212)).
+- Refined type reduction in adapters ([#144](https://github.com/CategoricalData/hydra/issues/144)).
+- Investigation of unification issues ([#163](https://github.com/CategoricalData/hydra/issues/163)).
+- Refactored RowType ([#82](https://github.com/CategoricalData/hydra/issues/82)).
+- LLM-assisted PG schemas and mappings ([#171](https://github.com/CategoricalData/hydra/issues/171)).
+- Simplified unit-valued variants in Python ([#206](https://github.com/CategoricalData/hydra/issues/206)).
+- Checked for inconsistencies between Term/TTerm and Type/TType DSLs ([#218](https://github.com/CategoricalData/hydra/issues/218)).
+- GenPG demo: refactored to support Haskell, Python, and Java; Python runner;
+  Java generation; finalized output format.
+- Testing: extended test runners for let hoisting (Haskell, Python, Java);
+  floating-point precision tests; ordering tests for `hydra.lib.maps`/`hydra.lib.sets`;
+  inference tests for inferred System F terms; case-hoisting test cases; new JSON coder tests;
+  thorough test cases for all primitives ([#199](https://github.com/CategoricalData/hydra/issues/199)).
+
+### Bug fixes
+
+- Fixed interpreter bugs causing test failures ([#235](https://github.com/CategoricalData/hydra/issues/235)).
+- Fixed bug in type checking in connection with dead code.
+- Fixed bug in `removeTypesFromTerm`.
+- Fixed bug in `typeOfMap`.
+- Fixed 32-bit max int value in `hydra.constants`.
+- Fixed numeric precision in Python.
+- Added `BigDecimal` support and fixed `uint8` (short) support in Java.
+- Fixed Haskell coder with respect to imports for binary literals.
+- Excluded `Prelude.encodeFloat` and `Prelude.decodeFloat` from generated Haskell
+  due to name collisions.
+- Fixed consistency issues in Python primitives:
+  `hydra.lib.sets.toList`, `hydra.lib.maps.union` (precedence),
+  `hydra.lib.strings.lines`, `hydra.lib.strings.readString` (dequoting),
+  `hydra.lib.lists.apply`, `hydra.lib.maps.toList`.
+- Fixed Haskell type signature of `hydra.lists.span`.
+- Fixed issue with eta expansion of typed terms.
+- Fixed shadowing issue in generated encoding modules.
+- Added missing alternatives in `hydra.rewriting.rewriteTermM`.
+
+### Documentation
+
+- Updated main README with complete implementation status.
+- Added Documentation sections to all implementation READMEs.
+- Fixed outdated Code-organization.md (Python now uses `src/gen-main`).
+- Fixed incorrect code paths in Implementation.md.
+- Added Java section to Testing wiki.
+- Comprehensive developer recipes in `docs/recipes/`.
+- Documentation for tail-call optimization implementation.
+- Added Haddock comments to Haskell primitives.
+- Created wiki page on the release process ([#194](https://github.com/CategoricalData/hydra/issues/194)).
+
+### Community
+
+- Accepted babeloff's `isTrivialTerm` changes.
+
+---
+
+## [0.12.0] - 2025-08-28
+
+A consolidation release: significant Python progress, kernel-level cleanup,
+and a wave of bookkeeping closures for Hydra-Java module ports.
+
+### Breaking changes
+
+- Removed `hydra.decoding` module ([#190](https://github.com/CategoricalData/hydra/issues/190)).
+- Flattened dependency tiers; eliminated tier-1, tier-2, tier-3 organization ([#184](https://github.com/CategoricalData/hydra/issues/184)).
+- Removed `typed` term variant ([#173](https://github.com/CategoricalData/hydra/issues/173), [#162](https://github.com/CategoricalData/hydra/issues/162)).
+- Module naming changes: moved tabular and relational modules into kernel ([#152](https://github.com/CategoricalData/hydra/issues/152)).
+- Standardized on uncurried helper functions in term-level DSLs ([#174](https://github.com/CategoricalData/hydra/issues/174)).
+- Renamed `hydra.lib.flows.traverseOptional` to `hydra.lib.flows.mapOptional`.
+- Eliminated camel-cased namespace parts from the kernel ([#152](https://github.com/CategoricalData/hydra/issues/152)).
+- Replaced list and optional eliminations with primitive functions ([#150](https://github.com/CategoricalData/hydra/issues/150)).
+- Moved `Hydra.Ext` to hydra-ext ([#178](https://github.com/CategoricalData/hydra/issues/178)); moved 'ext' sources into hydra-ext ([#189](https://github.com/CategoricalData/hydra/issues/189)).
+
+### New features
+
+- Significant progress toward Hydra-Python completion:
+  generated all kernel types and terms into Python;
+  added `Decimal` support for bigfloat values;
+  environment tracking for variable scoping;
+  generated `hydra.languages` into Python;
+  `__hash__` and `__eq__` on serializable generated classes ([#160](https://github.com/CategoricalData/hydra/issues/160)).
+- Designated `unit` term and type variants ([#186](https://github.com/CategoricalData/hydra/issues/186)).
+- `hydra.lib.flows.mapElems` and `hydra.lib.flows.mapKeys` utilities.
+- Promoted JSON coder into the DSL ([#181](https://github.com/CategoricalData/hydra/issues/181)).
+- Promoted JSON utilities into the DSL ([#181](https://github.com/CategoricalData/hydra/issues/181)).
+- C# coder ([#139](https://github.com/CategoricalData/hydra/issues/139)).
+- GQL model and parser ([#140](https://github.com/CategoricalData/hydra/issues/140)).
+- Tabular adapters ([#142](https://github.com/CategoricalData/hydra/issues/142)).
+- Type-level C++ coder ([#170](https://github.com/CategoricalData/hydra/issues/170)).
+- Variable-types-to-Haskell-typedefs transformation ([#70](https://github.com/CategoricalData/hydra/issues/70)).
+- A newline at the end of each generated file ([#154](https://github.com/CategoricalData/hydra/issues/154)).
+- Refactor kernel modules and primitives by connectivity ([#177](https://github.com/CategoricalData/hydra/issues/177)).
+
+### Improvements
+
+- Condensed repeated elements in error traces ([#165](https://github.com/CategoricalData/hydra/issues/165)).
+- Fixed transitive schema dependencies ([#185](https://github.com/CategoricalData/hydra/issues/185)).
+- Improved adapter solution with respect to literals.
+- Better handling of type variables in Python coder.
+- Enhanced term-level Python generation with proper ordering to minimize forward references.
+- Topo-sort helper function for dependency management.
+- Updated all Python libraries with latest changes.
+- Distinguished between deannotation and detyping of terms.
+- Adapted primitives when applying language constraints to a graph.
+- Use unqualified names where possible in generated code ([#153](https://github.com/CategoricalData/hydra/issues/153)).
+- Eliminated `Data.Graph` (containers) dependency ([#167](https://github.com/CategoricalData/hydra/issues/167)).
+- "Close the loop" demonstration ([#175](https://github.com/CategoricalData/hydra/issues/175)).
+- Implemented `typeOf` ([#168](https://github.com/CategoricalData/hydra/issues/168)).
+
+### Bug fixes
+
+- Fixed System F terms for records and case statements ([#168](https://github.com/CategoricalData/hydra/issues/168)).
+- Fixed issue with transitive type-level module dependencies ([#185](https://github.com/CategoricalData/hydra/issues/185)).
+- Corrected handling of variable references in Python application terms.
+- Fixed nullary functions in Python (added empty parens).
+- Added missing alternatives in `hydra.rewriting.rewriteTermM`.
+
+### Bookkeeping
+
+- Closed long-standing Hydra-Java module-port issues
+  ([#9](https://github.com/CategoricalData/hydra/issues/9), [#11](https://github.com/CategoricalData/hydra/issues/11), [#15](https://github.com/CategoricalData/hydra/issues/15), [#16](https://github.com/CategoricalData/hydra/issues/16), [#18](https://github.com/CategoricalData/hydra/issues/18), [#19](https://github.com/CategoricalData/hydra/issues/19), [#20](https://github.com/CategoricalData/hydra/issues/20), [#21](https://github.com/CategoricalData/hydra/issues/21), [#22](https://github.com/CategoricalData/hydra/issues/22), [#23](https://github.com/CategoricalData/hydra/issues/23), [#25](https://github.com/CategoricalData/hydra/issues/25), [#44](https://github.com/CategoricalData/hydra/issues/44), [#45](https://github.com/CategoricalData/hydra/issues/45));
+  most of the underlying work shipped in earlier releases.
+- Closed Hydra-Java DSL-port issues ([#24](https://github.com/CategoricalData/hydra/issues/24), [#26](https://github.com/CategoricalData/hydra/issues/26), [#27](https://github.com/CategoricalData/hydra/issues/27), [#28](https://github.com/CategoricalData/hydra/issues/28), [#29](https://github.com/CategoricalData/hydra/issues/29)) and
+  the Scala/Avro tracking issues ([#77](https://github.com/CategoricalData/hydra/issues/77), [#81](https://github.com/CategoricalData/hydra/issues/81)); these had been resolved
+  by earlier releases (Scala in 0.14.0, Avro bidi in 0.14.0).
+
+### Documentation
+
+- Updated Hydra-Haskell README.
+- Updated Hydra-Java README with corrected links.
+- Updated JavaDocs.
+
+---
+
+## [0.11.0] - 2025-03-16
+
+Untagged in-repository version.
+A type-inference rebase release: major restructuring of inference internals
+to align with Algorithm W, plus a sweeping removal of explicit type annotations
+across the kernel.
+
+### Highlights
+
+- **Inference rebased on Algorithm W** ([#118](https://github.com/CategoricalData/hydra/issues/118)): unify-early strategy ([#146](https://github.com/CategoricalData/hydra/issues/146)),
+  infinite-type checks restored ([#116](https://github.com/CategoricalData/hydra/issues/116)), recursive-element inference ([#90](https://github.com/CategoricalData/hydra/issues/90)),
+  unified handling of elements and let bindings ([#112](https://github.com/CategoricalData/hydra/issues/112)), minimized manual
+  type annotations ([#119](https://github.com/CategoricalData/hydra/issues/119)).
+- **`hydra.inference` module** introduced for inference type definitions;
+  substitution and unification moved up a level.
+
+### Breaking changes
+
+- Argument order of `Logic.ifElse` changed ([#147](https://github.com/CategoricalData/hydra/issues/147)).
+
+### New features
+
+- Inference test cases promoted into the common test suite ([#148](https://github.com/CategoricalData/hydra/issues/148));
+  added "kernel examples" inference tests; more recursion / mutual recursion cases.
+
+### Improvements
+
+- Removed type annotations across all kernel sources ([#119](https://github.com/CategoricalData/hydra/issues/119)).
+- Migrated to fully-applied primitive library DSLs ([#157](https://github.com/CategoricalData/hydra/issues/157)).
+- Aligned `Graph` and `Element` with `LetBinding` ([#159](https://github.com/CategoricalData/hydra/issues/159)).
+- `hydra.core.Unit` recognized by the Haskell coder.
+- Refactored inference tests.
+
+### Bug fixes
+
+- Fix for underdetermined type in `hydra.decode`.
+
+---
+
+## [0.10.0] - 2025-02-19
+
+Untagged in-repository version.
+Adds Hydra-Python (initial completion), a GraphSON coder,
+provisional Hydra-Go support, and dot-separated namespace conventions.
+
+### Highlights
+
+- **Hydra-Python initial completion** ([#80](https://github.com/CategoricalData/hydra/issues/80), [#66](https://github.com/CategoricalData/hydra/issues/66)): Python coder, generated kernel
+  modules in Python, and full library implementations across kernel namespaces.
+- **GraphSON coder** ([#79](https://github.com/CategoricalData/hydra/issues/79)).
+- **Provisional Hydra-Go** ([#65](https://github.com/CategoricalData/hydra/issues/65)).
+- **Namespace formatting** standardized to dot-separated form ([#151](https://github.com/CategoricalData/hydra/issues/151)).
+
+### Breaking changes
+
+- All namespaces use dot-separated form ([#151](https://github.com/CategoricalData/hydra/issues/151)).
+
+### New features
+
+- Hydra-Python: Python coder; generated `hydra.coreEncoding`, `hydra.strip`,
+  `hydra.literals` and other kernel modules in Python; tuple-expression support;
+  updated `hydra.constants` in Python.
+- GraphSON coder ([#79](https://github.com/CategoricalData/hydra/issues/79)).
+- Provisional Hydra-Go ([#65](https://github.com/CategoricalData/hydra/issues/65)).
+- `string-to-char-list` and `char-list-to-string` primitives ([#149](https://github.com/CategoricalData/hydra/issues/149)).
+- Restored normalization for generated term variables ([#145](https://github.com/CategoricalData/hydra/issues/145)).
+
+### Improvements
+
+- Re-leveled dependency tiers ([#135](https://github.com/CategoricalData/hydra/issues/135)).
+- Updated all Java, Haskell, hydra-ext, and Python primitives to current sources.
+
+---
+
+## [0.9.0] - 2025-01-06
+
+Untagged in-repository version.
+Bootstraps Hydra-Python and the JSON Schema coder; introduces a fluent Java DSL for flows.
+
+### Highlights
+
+- **JSON Schema coder** ([#141](https://github.com/CategoricalData/hydra/issues/141)).
+- **Python coder scaffold**: serde, language constraints, and generated Haskell
+  sources for Python.
+- **Fluent-style Java DSL for flows** ([#143](https://github.com/CategoricalData/hydra/issues/143)).
+
+### New features
+
+- JSON Schema coder ([#141](https://github.com/CategoricalData/hydra/issues/141)).
+- Python coder scaffold and serde.
+- Provisional Python language constraints module.
+- Fluent-style Java DSL for flows ([#143](https://github.com/CategoricalData/hydra/issues/143)); moved Flows DSL into `hydra.dsl`.
+- New `hydra.coders` DSL.
+- New DSL functions for core variants.
+
+### Improvements
+
+- Generalized `Namespaces` so it can be used for languages other than Haskell.
+- Local-name-only Python type aliases (the directory tree provides the namespace).
+- Coders DSL used to simplify Java language-constraint sources.
+- Removed redundant productions in the Python grammar.
+- Added unit tests for fluent flows.
+
+### Documentation
+
+- Updated JavaDocs for 0.9.0.
+
+---
+
+## [0.8.1] - 2024-09-24
+
+Patch release.
+
+### Improvements
+
+- Generalized the property graph merging utility to accept type systems other than Hydra Core.
+
+---
+
+## [0.8.0] - 2024-09-09
+
+C# support ([#139](https://github.com/CategoricalData/hydra/issues/139)), Graphviz DOT coder, term accessors, and a small breaking change in Java
+to support Spark.
+
+### Breaking changes
+
+- Made `FlowException` serializable for Spark support (may affect existing error handling).
+
+### New features
+
+- C# syntax module based on the Microsoft ANTLR grammar ([#139](https://github.com/CategoricalData/hydra/issues/139)).
+- Graphviz DOT coder ([#136](https://github.com/CategoricalData/hydra/issues/136)):
+  full support for lambdas and recursive `let` statements;
+  compact 'accessor graph' visualization option;
+  customizable label styles;
+  highlighted let-bound terms; edge labels.
+- Term accessor type to facilitate lenses and path-aware transformations.
+- OpenGQL grammar and generated Haskell for the OpenGQL model ([#140](https://github.com/CategoricalData/hydra/issues/140)).
+
+### Improvements
+
+- Added `</>` as alternative to `@@` application operator in Haskell DSLs.
+- Utilities for working with term accessors.
+- More specific exception class for JSON decoding.
+- Additional convenience methods on `JsonDecoding.java`.
+- Used transitive dependencies in hydra-java and hydra-ext.
+- Upgraded ANTLR to address a vulnerability.
+- Moved TinkerPop utilities from `hydra/ext/org/apache/tinkerpop` into `hydra/pg`.
+
+---
+
+## [0.7.0] - 2024-08-21
+
+Major refactoring of module organization and namespace management.
+Establishes the DNS-style namespace convention in hydra-ext
+and lifts property-graph models into a top-level `hydra/pg` namespace.
+
+### Breaking changes
+
+- Namespace reorganization: migrated to DNS-based module naming in hydra-ext ([#138](https://github.com/CategoricalData/hydra/issues/138)):
+  `hydra/ext/avro` → `hydra/ext/org/apache/avro`,
+  `hydra/ext/graphql` → `hydra/ext/org/graphql`,
+  `hydra/ext/yaml` → `hydra/ext/org/yaml`,
+  `hydra/ext/json/decoding` → `hydra/ext/org/json/decoding`,
+  `hydra/ext/rdf` → `hydra/ext/org/w3/rdf`,
+  `hydra/ext/shacl` → `hydra/ext/org/w3/shacl`,
+  `hydra/ext/tinkerpop` → `hydra/ext/org/apache/tinkerpop`.
+- Property graphs: promoted property graph modules from
+  `hydra/ext/org/apache/tinkerpop` to `hydra/pg`.
+- Project structure: renamed `hydra-extensions` to `hydra-ext`;
+  renamed `hydra/langs` to `hydra/ext` ([#138](https://github.com/CategoricalData/hydra/issues/138));
+  made hydra-ext into a Gradle subproject alongside hydra-java;
+  added top-level Gradle build.
+
+### Improvements
+
+- Moved TinkerPop modules from hydra-haskell into hydra-ext for better separation.
+- Moved miscellaneous models to `Hydra.Ext.Other` ([#138](https://github.com/CategoricalData/hydra/issues/138)).
+- Moved XML Schema, SQL, ShEx, and OWL models to hydra-ext.
+- Moved KQL, Parquet, and Python modules to hydra-ext.
+- Separated JavaDocs for hydra-java and hydra-ext.
+- Updated publishing configuration in `build.gradle`.
+
+---
+
+## [0.6.0] - 2024-08-19
+
+Type-system improvements (System F type abstraction/application; eliminated polymorphic
+types from Hydra Core), expanded language support (Graphviz DOT model, generated Java
+field-name constants), and revamped annotation handling.
+
+### Breaking changes
+
+- Eliminated `InferenceContext` helper type ([#103](https://github.com/CategoricalData/hydra/issues/103)).
+- Changed typing environment from `Map Name Type` to `Map Name TypeScheme` in graphs ([#76](https://github.com/CategoricalData/hydra/issues/76)).
+- Updated annotations and flows to use `map<Name, Term>` instead of `map<string, Term>` ([#133](https://github.com/CategoricalData/hydra/issues/133)).
+- Unified `Name` and `FieldName`; aliased to `string` ([#121](https://github.com/CategoricalData/hydra/issues/121)).
+- Renamed `hydra/core.UnitType` to `hydra/core.Unit` ([#123](https://github.com/CategoricalData/hydra/issues/123)).
+- Eliminated annotation classes; Hydra has a single built-in notion of annotations ([#113](https://github.com/CategoricalData/hydra/issues/113)).
+- Unified the `Nominal` type with `RowType` ([#115](https://github.com/CategoricalData/hydra/issues/115)).
+- Removed the `extends` parameter for row types ([#132](https://github.com/CategoricalData/hydra/issues/132)).
+- Replaced `hydra/Kv` with `hydra/Annotations` (rename revisited).
+
+### New features
+
+- System F support: `typeAbstraction` and `typeApplication` term constructors.
+- Python3 syntax model based on the official Python BNF ([#80](https://github.com/CategoricalData/hydra/issues/80)).
+- Graphviz DOT model and initial support ([#136](https://github.com/CategoricalData/hydra/issues/136)).
+- Field-name constants generated in Java code generation ([#137](https://github.com/CategoricalData/hydra/issues/137)).
+- Provisional Algorithm W implementation in Haskell (originally from @wisnesky), kept for reference.
+
+### Improvements
+
+- Primitive organization: Hydra primitives organized into libraries for namespace management.
+- Code generation:
+  - Escaped field name constants and `with_` methods in Java coder.
+  - Generated field name constants in Java ([#137](https://github.com/CategoricalData/hydra/issues/137)).
+  - Avoided duplicated comments in wrapper classes in generated Java.
+  - Removed superfluous newtype comments in Haskell coder.
+- Updated Delta Parquet model to follow the Java API more closely.
+- Enriched OpenCypher features module with the complete list of standard Cypher functions.
+- Added convenience methods to `JsonEncoding.java`.
+- Restored `Hydra.Inference` subdirectory.
+- Allowed arbitrary case for element names ([#7](https://github.com/CategoricalData/hydra/issues/7)).
+- Corrected `uint8` representation in Java to `Short` ([#120](https://github.com/CategoricalData/hydra/issues/120)).
+
+### Bug fixes
+
+- Fixed handling of type annotations in term adapters.
+- Fixed decoding of encoded terms annotated with a type.
+- Corrected encoding of universal types in `showTerm` ([#117](https://github.com/CategoricalData/hydra/issues/117)).
+
+---
+
+## [0.5.3] - 2024-08-06
+
+Patch release.
+Preserves order of map key/value pairs and set elements during JSON serialization.
+
+### Bug fixes
+
+- Preserved ordering of key/value pairs and set elements in JSON output.
+
+### New features
+
+- Polymorphic `equal` primitive in Haskell and Java.
+- Generated Hydra type definitions together with native instantiations of Hydra types
+  in Haskell (a stepping stone toward generated coders, [#47](https://github.com/CategoricalData/hydra/issues/47)).
+
+---
+
+## [0.5.1] - 2024-08-01
+
+Patch release.
+Dependency updates and minor improvements following the 0.5.0 Hydra Core overhaul.
+
+### Improvements
+
+- Updated dependencies.
+
+---
+
+## [0.5.0] - 2024-07-26
+
+Untagged in-repository version.
+Major Hydra Core overhaul: eliminates polymorphic types in favor of explicit
+TypeScheme; consolidates the annotation system; revamps `Let` term encoding.
+
+### Breaking changes
+
+- Eliminated polymorphic types from Hydra Core in Haskell ([#125](https://github.com/CategoricalData/hydra/issues/125)):
+  removed type parameters from `hydra/core` types in Hydra-Java; replaced type schemes
+  with forall types ([#76](https://github.com/CategoricalData/hydra/issues/76)).
+- Revamped core encoding and `Let`: bindings are now a list of
+  `(name, term, optional type scheme)` triplets instead of a map.
+- Unified typed-term types and moved `TypeScheme` into Hydra Core.
+- Eliminated `AnnotationClass`; Hydra has a single built-in notion of annotations now ([#113](https://github.com/CategoricalData/hydra/issues/113)).
+- Renamed and refactored phantom-type wrappers ([#128](https://github.com/CategoricalData/hydra/issues/128)); removed deprecated `Reference`
+  type from `hydra/phantoms`.
+- Removed incomplete support for stream types and stream terms ([#88](https://github.com/CategoricalData/hydra/issues/88)).
+
+### New features
+
+- `LiteralTypes` DSL module so literals can be built independently of terms.
+- `Hydra.Minimal` module to facilitate collaboration on Hydra application prototypes.
+- `TypeConstraint` type added to the kernel.
+- `foldl` primitive in Haskell and Java; DSL uses `foldl` instead of the built-in
+  list elimination term by default.
+
+### Improvements
+
+- Improvements to Java and JSON coders; improved untyped JSON coder.
+- Pre-order and post-order term-traversal test cases added.
+- Refactored type inference tests.
+- Restored generated Java (Core through Tier 3) with only a few manual tweaks.
+- Element names allow arbitrary case ([#7](https://github.com/CategoricalData/hydra/issues/7)).
+
+---
+
+## [0.4.0] - 2024-07-10
+
+Untagged in-repository version.
+Adds null checks to generated Java (breaking, but justified — Hydra-Java disallows nulls),
+the Gremlin model, and Protobuf annotation refinements.
+
+### Breaking changes
+
+- Null checks added to constructors and `withXXX()` methods in generated Java;
+  null values are no longer permitted in Hydra-Java.
+- Removed Java 8 restriction (raised minimum Java version).
+
+### New features
+
+- Gremlin model ([#127](https://github.com/CategoricalData/hydra/issues/127)); generated Haskell for Gremlin.
+- `hydra/lib/lists.safeHead` primitive in Haskell (necessary in Java due to eager evaluation).
+- Support for Protobuf `deprecated=true` annotation; non-string Protobuf options.
+- Java options in generated Protobuf.
+
+### Improvements
+
+- Used `java.util.Objects.requireNonNull` instead of a custom null check in generated Java.
+- Added 'automatically generated file' disclaimer to generated Java files.
+- Added autogen comments and null checks to (most) generated Java.
+- Added necessary schema-level dependencies for built-in modules.
+- Added null checks to the Flows DSL in Java.
+
+---
+
+## [0.3.0] - 2024-06-05
+
+Untagged in-repository version.
+Adds an OpenCypher parser based on an ANTLR grammar ([#124](https://github.com/CategoricalData/hydra/issues/124)),
+a KQL (Kusto Query Language) model and serializer,
+a Delta Parquet model,
+and an early property graph queries model in the style of Cypher.
+
+### New features
+
+- OpenCypher parser based on the OpenCypher M23 ANTLR grammar ([#124](https://github.com/CategoricalData/hydra/issues/124));
+  ANTLR added as a build dependency;
+  large Cypher test suite drawn from the Cypher Manual.
+- Cypher-to-PG-query transformer (Java; partially implemented).
+- Property graph queries DSL and generated property graph query classes in Java.
+- Property graph queries model (Cypher / future GQL style).
+- KQL (Kusto Query Language) initial model and basic serializer.
+- Delta Parquet model with generated sources.
+
+### Improvements
+
+- Java options and `deprecated=true` support in generated Protobuf.
+- Convenience methods in Java.
+
+---
+
+## [0.2.0] - 2024-01-10
+
+Hydra-Java 0.2.0 release.
+Significant Java tooling and DSL build-out, Protobuf bidirectional coder,
+Python3 syntax model ([#80](https://github.com/CategoricalData/hydra/issues/80)), property graph validation ([#100](https://github.com/CategoricalData/hydra/issues/100)),
+JSON bidirectional support in Java ([#104](https://github.com/CategoricalData/hydra/issues/104)),
+OpenCypher initial model ([#108](https://github.com/CategoricalData/hydra/issues/108)),
+Cypher unification, and the start of the typed-DSL story in Haskell.
+
+### New features
+
+- Property graph validation: validator type, optionality on property types,
+  customizable id/property handling in the merging adapter, fine-tuned validation,
+  comprehensive unit tests in Java ([#100](https://github.com/CategoricalData/hydra/issues/100)).
+- Bidirectional JSON serialization/deserialization in Java ([#104](https://github.com/CategoricalData/hydra/issues/104)).
+- Checkstyle configuration based on Google style guide ([#111](https://github.com/CategoricalData/hydra/issues/111)).
+- Python3 syntax model based on the official Python BNF ([#80](https://github.com/CategoricalData/hydra/issues/80)).
+- Initial OpenCypher model and parser scaffold ([#108](https://github.com/CategoricalData/hydra/issues/108)).
+- Protobuf coder ([#99](https://github.com/CategoricalData/hydra/issues/99)): type encoder, field numbering, formatting, deprecated annotation,
+  Java options, non-string options.
+- Adapter framework tolerance of recursive types ([#58](https://github.com/CategoricalData/hydra/issues/58)); default branch for case
+  statements ([#60](https://github.com/CategoricalData/hydra/issues/60)).
+- Topological sort in type inference ([#67](https://github.com/CategoricalData/hydra/issues/67)).
+- `hydra/query` model ([#73](https://github.com/CategoricalData/hydra/issues/73)).
+- Records-to-TinkerPop-elements coder ([#64](https://github.com/CategoricalData/hydra/issues/64)).
+- Equality primitives for all literal types ([#92](https://github.com/CategoricalData/hydra/issues/92)); polymorphic logic primitives ([#95](https://github.com/CategoricalData/hydra/issues/95)).
+- `mapKeys` primitive ([#93](https://github.com/CategoricalData/hydra/issues/93)).
+- Tuple support in Java ([#94](https://github.com/CategoricalData/hydra/issues/94)).
+- Java 8 as an optional target ([#96](https://github.com/CategoricalData/hydra/issues/96)); optionally generate Java classes as `Serializable` ([#97](https://github.com/CategoricalData/hydra/issues/97)).
+- Bidirectional "merged vertex" and "merged edge" coders ([#106](https://github.com/CategoricalData/hydra/issues/106)).
+- Nullability and parameterization in the tabular model ([#107](https://github.com/CategoricalData/hydra/issues/107)).
+- Term-level / type-level dependency distinction for modules ([#109](https://github.com/CategoricalData/hydra/issues/109)).
+- Flatten nested `let` terms for transformation into Java ([#110](https://github.com/CategoricalData/hydra/issues/110)).
+- Various `Flow` utilities in Java: `bind3`; convenience methods for consuming results;
+  `fromFlow` variants including one that throws.
+
+### Improvements
+
+- Hydra-Java module ports ([#10](https://github.com/CategoricalData/hydra/issues/10), [#12](https://github.com/CategoricalData/hydra/issues/12), [#13](https://github.com/CategoricalData/hydra/issues/13), [#14](https://github.com/CategoricalData/hydra/issues/14), [#17](https://github.com/CategoricalData/hydra/issues/17), [#30](https://github.com/CategoricalData/hydra/issues/30), [#31](https://github.com/CategoricalData/hydra/issues/31), [#32](https://github.com/CategoricalData/hydra/issues/32), [#33](https://github.com/CategoricalData/hydra/issues/33), [#34](https://github.com/CategoricalData/hydra/issues/34), [#35](https://github.com/CategoricalData/hydra/issues/35),
+  [#38](https://github.com/CategoricalData/hydra/issues/38), [#39](https://github.com/CategoricalData/hydra/issues/39), [#41](https://github.com/CategoricalData/hydra/issues/41), [#43](https://github.com/CategoricalData/hydra/issues/43), [#48](https://github.com/CategoricalData/hydra/issues/48), [#71](https://github.com/CategoricalData/hydra/issues/71), [#72](https://github.com/CategoricalData/hydra/issues/72), [#75](https://github.com/CategoricalData/hydra/issues/75), [#83](https://github.com/CategoricalData/hydra/issues/83)):
+  `Common`, `CoreEncoding`, `CoreLanguage`, `Kernel`, `Flows`, `Lists`, `Literals`,
+  `Math`, `Sets`, `Strings`, `Optionals`, `Maps`, `Flows` primitives, `Sets` primitives.
+- Common DSLs in Haskell: Flow support ([#68](https://github.com/CategoricalData/hydra/issues/68)), Let support ([#69](https://github.com/CategoricalData/hydra/issues/69)).
+- Renamed annotation type parameter `m` to `a` ([#41](https://github.com/CategoricalData/hydra/issues/41)).
+- Updated wrapper, element, and variable types ([#75](https://github.com/CategoricalData/hydra/issues/75)).
+- Removed `schema` field from `Element` ([#83](https://github.com/CategoricalData/hydra/issues/83)).
+- GraphQL coder ([#78](https://github.com/CategoricalData/hydra/issues/78)).
+- Code quality:
+  - Updated main and test sources to conform to Checkstyle configuration ([#111](https://github.com/CategoricalData/hydra/issues/111)).
+  - Extended line-length limit from 100 to 120 characters.
+  - Disabled overly restrictive indentation and import-order rules.
+  - Disabled `RightCurlyAlone` for compact inline map definitions.
+- Streamlined property-graph element merging to unify properties with identical
+  keys and types ([#106](https://github.com/CategoricalData/hydra/issues/106)).
+- Convenience functions for printing literals and literal types in the Java DSL.
+- Minor addition to JSON decoding.
+- DSL convenience: alphabetic-case flexibility for element names ([#7](https://github.com/CategoricalData/hydra/issues/7)).
+
+### Bug fixes
+
+- Fixed type annotations for the Sets Java port ([#48](https://github.com/CategoricalData/hydra/issues/48)).
+- Various minor fixes during the Java module ports.
+
+---
+
+## [0.1.1] - 2022-12-04
+
+Patch release the same day as 0.1.0.
+README polish only.
+
+---
+
+## [0.1.0] - 2022-12-04
+
+First packaged release of Hydra (Hackage).
+This release contains the complete foundation of Hydra.
+
+### Core language
+
+- Hydra's core type and data languages (`hydra.core`).
+- Core models for graphs and modules.
+- Computation model with the `Flow` monad.
+- BNF grammars support.
+- Phantom types.
+- Basic operations on types and terms.
+
+### Type system
+
+- Hindley–Milner-style type inference.
+- Type schemes with polymorphism.
+- Type/term validation.
+
+### Transformations
+
+- Adapter system: type-to-type rewriting and transformation.
+- Coders:
+  Haskell coder (types and terms),
+  Java coder (types and terms),
+  partial Scala coder (terms only),
+  Avro coder,
+  JSON coder,
+  PDL (Pegasus Data Language) coder,
+  RDF + SHACL coder,
+  YAML coder.
+
+### Language support
+
+- Models for GraphQL, OWL (Web Ontology Language), ShEx (Shape Expressions),
+  and TinkerPop-style property graphs.
+
+### Developer tools
+
+- Type-construction DSL and term-construction DSL.
+- QuickCheck property-based tests.
+
+### Implementations
+
+- Hydra-Haskell: bootstrapping implementation with full kernel.
+- Hydra-Java: Java implementation with mature tooling.
+
+### Community
+
+- Set up the LambdaGraph Discord server ([#2](https://github.com/CategoricalData/hydra/issues/2)).
+
+---
+
+## Contributing
+
+We welcome contributions! Please see:
+
+- [Developer recipes](https://github.com/CategoricalData/hydra/tree/main/docs/recipes)
+- [LambdaGraph Discord](https://bit.ly/lg-discord)
+
+## Release process
+
+See the [Release policy](https://github.com/CategoricalData/hydra/wiki/Release-policy)
+wiki page and [docs/release-workflow.md](docs/release-workflow.md)
+for information on how Hydra releases are versioned, built, and published.
diff --git a/LICENSE b/LICENSE
new file mode 100644
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Hydra
+Copyright 2021-2026 The Hydra authors
+https://github.com/CategoricalData/hydra
diff --git a/hydra-wasm.cabal b/hydra-wasm.cabal
new file mode 100644
--- /dev/null
+++ b/hydra-wasm.cabal
@@ -0,0 +1,43 @@
+cabal-version: 1.12
+
+-- This file has been generated from package.yaml by hpack version 0.39.1.
+--
+-- see: https://github.com/sol/hpack
+
+name:           hydra-wasm
+version:        0.17.0
+synopsis:       Hydra's WebAssembly coder: emit Wasm from Hydra modules
+description:    Hydra is an implementation of the LambdaGraph data model, which takes advantage of an isomorphism between labeled hypergraphs and typed lambda calculus: in Hydra, "graphs are programs, and programs are graphs". WebAssembly support for Hydra
+category:       Data
+homepage:       https://github.com/CategoricalData/hydra#readme
+bug-reports:    https://github.com/CategoricalData/hydra/issues
+author:         Joshua Shinavier <josh@fortytwo.net>
+maintainer:     Joshua Shinavier <josh@fortytwo.net>
+license:        Apache-2.0
+license-file:   LICENSE
+build-type:     Simple
+extra-source-files:
+    LICENSE
+    NOTICE
+    CHANGELOG.md
+
+source-repository head
+  type: git
+  location: https://github.com/CategoricalData/hydra
+
+library
+  exposed-modules:
+      Hydra.Wasm.Coder
+      Hydra.Wasm.Language
+      Hydra.Wasm.Serde
+      Hydra.Wasm.Syntax
+  other-modules:
+      Paths_hydra_wasm
+  hs-source-dirs:
+      src/main/haskell
+  build-depends:
+      base >=4.19.0 && <4.22
+    , containers >=0.6.7 && <0.8
+    , hydra-kernel ==0.17.0
+    , scientific >=0.3.7 && <0.4
+  default-language: Haskell2010
diff --git a/src/main/haskell/Hydra/Wasm/Coder.hs b/src/main/haskell/Hydra/Wasm/Coder.hs
new file mode 100644
--- /dev/null
+++ b/src/main/haskell/Hydra/Wasm/Coder.hs
@@ -0,0 +1,980 @@
+-- Note: this is an automatically generated file. Do not edit.
+-- | WebAssembly code generator: converts Hydra type and term modules to WAT source code
+
+module Hydra.Wasm.Coder where
+import qualified Hydra.Analysis as Analysis
+import qualified Hydra.Ast as Ast
+import qualified Hydra.Coders as Coders
+import qualified Hydra.Core as Core
+import qualified Hydra.File as File
+import qualified Hydra.Environment as Environment
+import qualified Hydra.Error.Checking as Checking
+import qualified Hydra.Error.Core as ErrorCore
+import qualified Hydra.Error.Packaging as ErrorPackaging
+import qualified Hydra.Errors as Errors
+import qualified Hydra.Formatting as Formatting
+import qualified Hydra.Graph as Graph
+import qualified Hydra.Json.Model as Model
+import qualified Hydra.Lexical as Lexical
+import qualified Hydra.Overlay.Haskell.Lib.Eithers as Eithers
+import qualified Hydra.Overlay.Haskell.Lib.Equality as Equality
+import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
+import qualified Hydra.Overlay.Haskell.Lib.Literals as Literals
+import qualified Hydra.Overlay.Haskell.Lib.Logic as Logic
+import qualified Hydra.Overlay.Haskell.Lib.Maps as Maps
+import qualified Hydra.Overlay.Haskell.Lib.Math as Math
+import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals
+import qualified Hydra.Overlay.Haskell.Lib.Pairs as Pairs
+import qualified Hydra.Overlay.Haskell.Lib.Sets as Sets
+import qualified Hydra.Overlay.Haskell.Lib.Strings as Strings
+import qualified Hydra.Names as Names
+import qualified Hydra.Packaging as Packaging
+import qualified Hydra.Parsing as Parsing
+import qualified Hydra.Paths as Paths
+import qualified Hydra.Query as Query
+import qualified Hydra.Relational as Relational
+import qualified Hydra.Rewriting as Rewriting
+import qualified Hydra.Scoping as Scoping
+import qualified Hydra.Serialization as Serialization
+import qualified Hydra.Strip as Strip
+import qualified Hydra.Tabular as Tabular
+import qualified Hydra.Testing as Testing
+import qualified Hydra.Topology as Topology
+import qualified Hydra.Typed as Typed
+import qualified Hydra.Typing as Typing
+import qualified Hydra.Util as Util
+import qualified Hydra.Validation as Validation
+import qualified Hydra.Variables as Variables
+import qualified Hydra.Variants as Variants
+import qualified Hydra.Wasm.Language as Language
+import qualified Hydra.Wasm.Serde as Serde
+import qualified Hydra.Wasm.Syntax as Syntax
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import qualified Data.Scientific as Sci
+import qualified Data.Map as M
+import qualified Data.Set as S
+buildFieldOffsets :: Graph.Graph -> M.Map Core.Name [(Core.Name, Int)]
+buildFieldOffsets g =
+
+      let recordFieldsOf =
+              \t ->
+                let stripped = Strip.deannotateType t
+                in case stripped of
+                  Core.TypeRecord v0 -> Just v0
+                  Core.TypeForall v0 ->
+                    let innerStripped = Strip.deannotateType (Core.forallTypeBody v0)
+                    in case innerStripped of
+                      Core.TypeRecord v1 -> Just v1
+                      _ -> Nothing
+                  _ -> Nothing
+          entryFor =
+                  \nameSchemePair ->
+                    let tname = Pairs.first nameSchemePair
+                        tscheme = Pairs.second nameSchemePair
+                        tbody = Core.typeSchemeBody tscheme
+                        mfields = recordFieldsOf tbody
+                    in (Optionals.cases mfields Nothing (\fts ->
+                      let namedOffsets =
+                              Lists.map (\p ->
+                                let i = Pairs.first p
+                                    ft = Pairs.second p
+                                in (Core.fieldTypeName ft, (Math.mul i 4))) (Lists.zip (Lists.foldl (\acc -> \_f -> Lists.concat2 acc [
+                                Lists.length acc]) [] fts) fts)
+                      in (Just (tname, namedOffsets))))
+          schemaTypesList = Maps.toList (Graph.graphSchemaTypes g)
+          entries = Optionals.cat (Lists.map entryFor schemaTypesList)
+      in (Maps.fromList entries)
+buildFunctionSignatures :: t0 -> Graph.Graph -> [Packaging.TermDefinition] -> M.Map String ([Syntax.ValType], [Syntax.ValType])
+buildFunctionSignatures cx g termDefs =
+
+      let toSigEntry =
+              \nameAndScheme ->
+                let nm = Pairs.first nameAndScheme
+                    ts = Pairs.second nameAndScheme
+                    snakeName = Formatting.convertCaseCamelToLowerSnake (Core.unName nm)
+                    sigEither = extractSignature cx g (Core.typeSchemeBody ts)
+                in (Eithers.either (\_err -> Nothing) (\sig -> Just (snakeName, sig)) sigEither)
+          primEntries =
+                  Optionals.cat (Lists.map (\kv -> toSigEntry (
+                    Pairs.first kv,
+                    (Scoping.termSignatureToTypeScheme (Packaging.primitiveDefinitionSignature (Graph.primitiveDefinition (Pairs.second kv)))))) (Maps.toList (Graph.graphPrimitives g)))
+          boundEntries = Optionals.cat (Lists.map (\kv -> toSigEntry kv) (Maps.toList (Graph.graphBoundTypes g)))
+          localEntries =
+                  Optionals.cat (Lists.map (\td -> Optionals.bind (Optionals.map Scoping.termSignatureToTypeScheme (Packaging.termDefinitionSignature td)) (\ts -> toSigEntry (Packaging.termDefinitionName td, ts))) termDefs)
+      in (Maps.fromList (Lists.concat [
+        primEntries,
+        boundEntries,
+        localEntries]))
+buildStringOffsets :: [String] -> (M.Map String Int, Int)
+buildStringOffsets strs =
+
+      let step =
+              \acc -> \s ->
+                let m = Pairs.first acc
+                    off = Pairs.second acc
+                    len = Strings.length s
+                in (Maps.insert s off m, (Math.add off (Math.add 4 len)))
+          final = Lists.foldl step (Maps.empty, 1024) strs
+          rawEnd = Pairs.second final
+          aligned = Math.mul (Optionals.fromOptional 0 (Math.maybeDiv (Math.add rawEnd 15) 16)) 16
+      in (Pairs.first final, aligned)
+buildVariantIndexes :: Graph.Graph -> M.Map Core.Name [(Core.Name, Int)]
+buildVariantIndexes g =
+
+      let unionFieldsOf =
+              \t ->
+                let stripped = Strip.deannotateType t
+                in case stripped of
+                  Core.TypeUnion v0 -> Just v0
+                  Core.TypeForall v0 ->
+                    let innerStripped = Strip.deannotateType (Core.forallTypeBody v0)
+                    in case innerStripped of
+                      Core.TypeUnion v1 -> Just v1
+                      _ -> Nothing
+                  _ -> Nothing
+          entryFor =
+                  \nameSchemePair ->
+                    let tname = Pairs.first nameSchemePair
+                        tscheme = Pairs.second nameSchemePair
+                        tbody = Core.typeSchemeBody tscheme
+                        mfields = unionFieldsOf tbody
+                    in (Optionals.cases mfields Nothing (\fts ->
+                      let namedIndexes =
+                              Lists.map (\p ->
+                                let i = Pairs.first p
+                                    ft = Pairs.second p
+                                in (Core.fieldTypeName ft, i)) (Lists.zip (Lists.foldl (\acc -> \_f -> Lists.concat2 acc [
+                                Lists.length acc]) [] fts) fts)
+                      in (Just (tname, namedIndexes))))
+          schemaTypesList = Maps.toList (Graph.graphSchemaTypes g)
+          entries = Optionals.cat (Lists.map entryFor schemaTypesList)
+      in (Maps.fromList entries)
+clampValTypesToI32 :: [t0] -> [Syntax.ValType]
+clampValTypesToI32 vts = Lists.map (\_vt -> Syntax.ValTypeI32) vts
+collectCallTargets :: [Syntax.Instruction] -> S.Set String
+collectCallTargets instrs =
+    Lists.foldl (\acc -> \instr -> case instr of
+      Syntax.InstructionCall v0 -> Sets.insert v0 acc
+      Syntax.InstructionBlock v0 -> Sets.union acc (collectCallTargets (Syntax.blockInstructionBody v0))
+      Syntax.InstructionLoop v0 -> Sets.union acc (collectCallTargets (Syntax.blockInstructionBody v0))
+      Syntax.InstructionIf v0 -> Sets.union (Sets.union acc (collectCallTargets (Syntax.ifInstructionThen v0))) (collectCallTargets (Syntax.ifInstructionElse v0))
+      _ -> acc) Sets.empty instrs
+collectInstructionLocals :: [Syntax.Instruction] -> S.Set String
+collectInstructionLocals instrs =
+    Lists.foldl (\acc -> \instr -> case instr of
+      Syntax.InstructionLocalGet v0 -> Sets.insert v0 acc
+      Syntax.InstructionLocalSet v0 -> Sets.insert v0 acc
+      Syntax.InstructionLocalTee v0 -> Sets.insert v0 acc
+      Syntax.InstructionBlock v0 -> Sets.union acc (collectInstructionLocals (Syntax.blockInstructionBody v0))
+      Syntax.InstructionLoop v0 -> Sets.union acc (collectInstructionLocals (Syntax.blockInstructionBody v0))
+      Syntax.InstructionIf v0 -> Sets.union (Sets.union acc (collectInstructionLocals (Syntax.ifInstructionThen v0))) (collectInstructionLocals (Syntax.ifInstructionElse v0))
+      _ -> acc) Sets.empty instrs
+collectStrings :: [Packaging.TermDefinition] -> [String]
+collectStrings termDefs =
+
+      let collectOne =
+              \acc -> \t -> case t of
+                Core.TermLiteral v0 -> case v0 of
+                  Core.LiteralString v1 -> Sets.insert v1 acc
+                  _ -> acc
+                _ -> acc
+          allStrings =
+                  Lists.foldl (\acc -> \td -> Rewriting.foldOverTerm Coders.TraversalOrderPre collectOne acc (Packaging.termDefinitionBody td)) Sets.empty termDefs
+      in (Sets.toList allStrings)
+encodeApplication :: t0 -> t1 -> M.Map String Int -> M.Map Core.Name [(Core.Name, Int)] -> M.Map Core.Name [(Core.Name, Int)] -> M.Map String ([t2], t3) -> Core.Term -> Either Errors.Error [Syntax.Instruction]
+encodeApplication cx g stringOffsets fieldOffsets variantIndexes funcSigs term =
+
+      let gathered = Analysis.gatherArgs term []
+          fun = Pairs.first gathered
+          args = Pairs.second gathered
+          dfun = Strip.deannotateTerm fun
+      in (Eithers.bind (Eithers.mapList (\a -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs a) args) (\realArgInstrs ->
+        let flatRealArgInstrs = Lists.concat realArgInstrs
+            droppedArgInstrs = Lists.concat (Lists.map (\ai -> Lists.concat2 ai [
+                  Syntax.InstructionDrop]) realArgInstrs)
+        in case dfun of
+          Core.TermVariable v0 ->
+            let rawName = Core.unName v0
+                lname = Formatting.convertCaseCamelToLowerSnake rawName
+            in (Logic.ifElse (Lists.null (Optionals.fromOptional [] (Lists.maybeTail (Strings.splitOn "." rawName)))) (
+              let mFirstArg = Lists.maybeHead args
+                  firstArgInstrs =
+                          Optionals.cases mFirstArg [
+                            Syntax.InstructionConst (Syntax.ConstValueI32 0)] (\_a -> Optionals.fromOptional [] (Lists.maybeHead realArgInstrs))
+                  extraArgDropInstrs =
+                          Lists.concat (Lists.map (\ai -> Lists.concat2 ai [
+                            Syntax.InstructionDrop]) (Lists.drop 1 realArgInstrs))
+              in (Right (Lists.concat [
+                extraArgDropInstrs,
+                [
+                  Syntax.InstructionLocalGet lname,
+                  (Syntax.InstructionLoad (Syntax.MemoryInstruction {
+                    Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                    Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                      Syntax.memArgOffset = 4,
+                      Syntax.memArgAlign = 2}}))],
+                firstArgInstrs,
+                [
+                  Syntax.InstructionLocalGet lname,
+                  (Syntax.InstructionLoad (Syntax.MemoryInstruction {
+                    Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                    Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                      Syntax.memArgOffset = 0,
+                      Syntax.memArgAlign = 2}})),
+                  (Syntax.InstructionCallIndirect (Syntax.TypeUse {
+                    Syntax.typeUseIndex = (Just "__closure_1"),
+                    Syntax.typeUseParams = [],
+                    Syntax.typeUseResults = []}))]]))) (
+              let mSig = Maps.lookup lname funcSigs
+                  callerArgCount = Lists.length args
+                  calleeParamCount = Optionals.cases mSig callerArgCount (\sig -> Lists.length (Pairs.first sig))
+                  padCount = Math.sub calleeParamCount callerArgCount
+                  padInstrs =
+                          Lists.concat (Lists.replicate (Logic.ifElse (Equality.gt padCount 0) padCount 0) [
+                            Syntax.InstructionConst (Syntax.ConstValueI32 0)])
+              in (Right (Lists.concat [
+                flatRealArgInstrs,
+                padInstrs,
+                [
+                  Syntax.InstructionCall lname]]))))
+          Core.TermProject v0 -> Optionals.cases (Lists.maybeHead args) (Right [
+            Syntax.InstructionConst (Syntax.ConstValueI32 0)]) (\firstArg -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs firstArg) (\firstArgInstrs -> encodeProjection cx g fieldOffsets v0 firstArgInstrs))
+          Core.TermCases v0 -> Optionals.cases (Lists.maybeHead args) (Right [
+            Syntax.InstructionConst (Syntax.ConstValueI32 0)]) (\firstArg -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs firstArg) (\firstArgInstrs -> encodeCases cx g stringOffsets fieldOffsets variantIndexes funcSigs v0 firstArgInstrs))
+          Core.TermLambda v0 ->
+            let peeled = peelLambdaApp (Core.TermLambda v0) args
+                paramNames = Pairs.first peeled
+                innerBody = Pairs.second peeled
+                bindInstrs =
+                        Lists.concat (Lists.map (\np ->
+                          let pname = Formatting.convertCaseCamelToLowerSnake (Core.unName (Pairs.first np))
+                              argInstrs = Pairs.second np
+                          in (Lists.concat2 argInstrs [
+                            Syntax.InstructionLocalSet pname])) (Lists.zip paramNames realArgInstrs))
+                extraArgInstrs =
+                        Lists.concat (Lists.map (\ai -> Lists.concat2 ai [
+                          Syntax.InstructionDrop]) (Lists.drop (Lists.length paramNames) realArgInstrs))
+            in (Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs innerBody) (\bodyInstrs -> Right (Lists.concat [
+              bindInstrs,
+              extraArgInstrs,
+              bodyInstrs])))
+          _ -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs fun) (\funInstrs -> Right (Lists.concat [
+            droppedArgInstrs,
+            funInstrs,
+            [
+              Syntax.InstructionDrop,
+              (Syntax.InstructionConst (Syntax.ConstValueI32 0))]]))))
+encodeCases :: t0 -> t1 -> M.Map String Int -> M.Map Core.Name [(Core.Name, Int)] -> M.Map Core.Name [(Core.Name, Int)] -> M.Map String ([t2], t3) -> Core.CaseStatement -> [Syntax.Instruction] -> Either Errors.Error [Syntax.Instruction]
+encodeCases cx g stringOffsets fieldOffsets variantIndexes funcSigs cs scrutineeInstrsRaw =
+
+      let tname = Formatting.convertCaseCamelToLowerSnake (Names.localNameOf (Core.caseStatementTypeName cs))
+          caseFields = Core.caseStatementCases cs
+          scrutineeInstrs =
+                  Logic.ifElse (Lists.null scrutineeInstrsRaw) [
+                    Syntax.InstructionConst (Syntax.ConstValueI32 0)] scrutineeInstrsRaw
+          prologue =
+                  Lists.concat [
+                    scrutineeInstrs,
+                    [
+                      Syntax.InstructionLocalSet "__rec_ptr",
+                      (Syntax.InstructionLocalGet "__rec_ptr"),
+                      (Syntax.InstructionLoad (Syntax.MemoryInstruction {
+                        Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                        Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                          Syntax.memArgOffset = 4,
+                          Syntax.memArgAlign = 2}})),
+                      (Syntax.InstructionLocalSet "v"),
+                      (Syntax.InstructionLocalGet "__rec_ptr"),
+                      (Syntax.InstructionLoad (Syntax.MemoryInstruction {
+                        Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                        Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                          Syntax.memArgOffset = 0,
+                          Syntax.memArgAlign = 2}}))]]
+      in (Eithers.bind (Eithers.mapList (\cf ->
+        let cfname = Formatting.convertCaseCamelToLowerSnake (Core.unName (Core.caseAlternativeName cf))
+            cfterm = Core.caseAlternativeHandler cf
+        in (Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.TermApplication (Core.Application {
+          Core.applicationFunction = cfterm,
+          Core.applicationArgument = (Core.TermVariable (Core.Name "v"))}))) (\armBody -> Right (cfname, armBody)))) caseFields) (\explicitArms ->
+        let defaultArmLabel = "_default"
+            mDefault = Core.caseStatementDefault cs
+        in (Eithers.bind (Optionals.cases mDefault (Right [
+          Syntax.InstructionConst (Syntax.ConstValueI32 0)]) (\defTerm -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs defTerm)) (\defaultArmBody ->
+          let arms = Lists.concat2 explicitArms [
+                (defaultArmLabel, defaultArmBody)]
+              explicitLabelForName =
+                      \fname -> Optionals.fromOptional defaultArmLabel (Optionals.map Pairs.first (Lists.find (\arm -> Equality.equal (Pairs.first arm) fname) explicitArms))
+              typeName = Core.caseStatementTypeName cs
+              mUnionVariants = Maps.lookup typeName variantIndexes
+              brTableLabels =
+                      Optionals.cases mUnionVariants (Lists.map Pairs.first explicitArms) (\variantPairs ->
+                        let sorted = Lists.sortOn Pairs.second variantPairs
+                        in (Lists.map (\np ->
+                          let fieldName = Formatting.convertCaseCamelToLowerSnake (Core.unName (Pairs.first np))
+                          in (explicitLabelForName fieldName)) sorted))
+              endLabel = Strings.cat2 "end_" tname
+              innerDispatch =
+                      Lists.concat2 prologue [
+                        Syntax.InstructionBrTable (Syntax.BrTableArgs {
+                          Syntax.brTableArgsLabels = brTableLabels,
+                          Syntax.brTableArgsDefault = defaultArmLabel})]
+              dispatch =
+                      Lists.foldl (\acc -> \arm ->
+                        let label = Pairs.first arm
+                            body = Pairs.second arm
+                        in (Lists.concat [
+                          [
+                            Syntax.InstructionBlock (Syntax.BlockInstruction {
+                              Syntax.blockInstructionLabel = (Just label),
+                              Syntax.blockInstructionBlockType = Syntax.BlockTypeEmpty,
+                              Syntax.blockInstructionBody = acc})],
+                          body,
+                          [
+                            Syntax.InstructionBr endLabel]])) innerDispatch arms
+          in (Right [
+            Syntax.InstructionBlock (Syntax.BlockInstruction {
+              Syntax.blockInstructionLabel = (Just endLabel),
+              Syntax.blockInstructionBlockType = (Syntax.BlockTypeValue Syntax.ValTypeI32),
+              Syntax.blockInstructionBody = dispatch})])))))
+encodeLiteral :: Core.Literal -> Syntax.Instruction
+encodeLiteral lit =
+    case lit of
+      Core.LiteralBoolean v0 -> Syntax.InstructionConst (Syntax.ConstValueI32 (Logic.ifElse v0 1 0))
+      Core.LiteralString _ -> Syntax.InstructionConst (Syntax.ConstValueI32 0)
+      Core.LiteralFloat _ -> Syntax.InstructionConst (Syntax.ConstValueI32 0)
+      Core.LiteralInteger v0 -> case v0 of
+        Core.IntegerValueInt8 v1 -> Syntax.InstructionConst (Syntax.ConstValueI32 (Literals.bigintToInt32 (Literals.int8ToBigint v1)))
+        Core.IntegerValueInt16 v1 -> Syntax.InstructionConst (Syntax.ConstValueI32 (Literals.bigintToInt32 (Literals.int16ToBigint v1)))
+        Core.IntegerValueInt32 v1 -> Syntax.InstructionConst (Syntax.ConstValueI32 v1)
+        Core.IntegerValueInt64 _ -> Syntax.InstructionConst (Syntax.ConstValueI32 0)
+        Core.IntegerValueUint8 v1 -> Syntax.InstructionConst (Syntax.ConstValueI32 (Literals.bigintToInt32 (Literals.uint8ToBigint v1)))
+        Core.IntegerValueUint16 v1 -> Syntax.InstructionConst (Syntax.ConstValueI32 (Literals.bigintToInt32 (Literals.uint16ToBigint v1)))
+        Core.IntegerValueUint32 v1 -> Syntax.InstructionConst (Syntax.ConstValueI32 (Literals.bigintToInt32 (Literals.uint32ToBigint v1)))
+        Core.IntegerValueUint64 _ -> Syntax.InstructionConst (Syntax.ConstValueI32 0)
+        Core.IntegerValueBigint _ -> Syntax.InstructionConst (Syntax.ConstValueI32 0)
+encodeLiteralType :: Core.LiteralType -> Syntax.ValType
+encodeLiteralType lt =
+    case lt of
+      Core.LiteralTypeBinary -> Syntax.ValTypeI32
+      Core.LiteralTypeBoolean -> Syntax.ValTypeI32
+      Core.LiteralTypeFloat v0 -> case v0 of
+        Core.FloatTypeFloat32 -> Syntax.ValTypeF32
+        Core.FloatTypeFloat64 -> Syntax.ValTypeF64
+      Core.LiteralTypeInteger v0 -> case v0 of
+        Core.IntegerTypeBigint -> Syntax.ValTypeI64
+        Core.IntegerTypeInt8 -> Syntax.ValTypeI32
+        Core.IntegerTypeInt16 -> Syntax.ValTypeI32
+        Core.IntegerTypeInt32 -> Syntax.ValTypeI32
+        Core.IntegerTypeInt64 -> Syntax.ValTypeI64
+        Core.IntegerTypeUint8 -> Syntax.ValTypeI32
+        Core.IntegerTypeUint16 -> Syntax.ValTypeI32
+        Core.IntegerTypeUint32 -> Syntax.ValTypeI32
+        Core.IntegerTypeUint64 -> Syntax.ValTypeI64
+      Core.LiteralTypeString -> Syntax.ValTypeI32
+encodeProjection :: t0 -> t1 -> M.Map Core.Name [(Core.Name, Int)] -> Core.Projection -> [Syntax.Instruction] -> Either t2 [Syntax.Instruction]
+encodeProjection cx g fieldOffsets proj scrutineeInstrs =
+
+      let typeName = Core.projectionTypeName proj
+          fieldName = Core.projectionFieldName proj
+          mFields = Maps.lookup typeName fieldOffsets
+          mOffset =
+                  Optionals.cases mFields Nothing (\pairs ->
+                    let matching = Lists.filter (\p -> Equality.equal (Pairs.first p) fieldName) pairs
+                    in (Optionals.map Pairs.second (Lists.maybeHead matching)))
+      in (Optionals.cases mOffset (Right (Lists.concat [
+        scrutineeInstrs,
+        (Logic.ifElse (Lists.null scrutineeInstrs) [] [
+          Syntax.InstructionDrop]),
+        [
+          Syntax.InstructionConst (Syntax.ConstValueI32 0)]])) (\off -> Right (Lists.concat [
+        Logic.ifElse (Lists.null scrutineeInstrs) [
+          Syntax.InstructionConst (Syntax.ConstValueI32 0)] scrutineeInstrs,
+        [
+          Syntax.InstructionLoad (Syntax.MemoryInstruction {
+            Syntax.memoryInstructionType = Syntax.ValTypeI32,
+            Syntax.memoryInstructionMemArg = Syntax.MemArg {
+              Syntax.memArgOffset = off,
+              Syntax.memArgAlign = 2}})]])))
+encodeTerm :: t0 -> t1 -> M.Map String Int -> M.Map Core.Name [(Core.Name, Int)] -> M.Map Core.Name [(Core.Name, Int)] -> M.Map String ([t2], t3) -> Core.Term -> Either Errors.Error [Syntax.Instruction]
+encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs term =
+    case term of
+      Core.TermAnnotated v0 -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.annotatedTermBody v0)
+      Core.TermApplication v0 -> encodeApplication cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.TermApplication v0)
+      Core.TermCases _ -> Right [
+        Syntax.InstructionConst (Syntax.ConstValueI32 0)]
+      Core.TermEither v0 ->
+        let eitherTag = Eithers.either (\_lv -> 0) (\_rv -> 1) v0
+            innerTerm = Eithers.either (\lv -> lv) (\rv -> rv) v0
+        in (Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs innerTerm) (\payloadInstrs -> Right (Lists.concat [
+          [
+            Syntax.InstructionConst (Syntax.ConstValueI32 eitherTag)],
+          payloadInstrs,
+          [
+            Syntax.InstructionConst (Syntax.ConstValueI32 8),
+            (Syntax.InstructionCall "__alloc"),
+            (Syntax.InstructionLocalSet "__rec_ptr"),
+            (Syntax.InstructionLocalSet "__rec_scratch"),
+            (Syntax.InstructionLocalGet "__rec_ptr"),
+            (Syntax.InstructionLocalGet "__rec_scratch"),
+            (Syntax.InstructionStore (Syntax.MemoryInstruction {
+              Syntax.memoryInstructionType = Syntax.ValTypeI32,
+              Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                Syntax.memArgOffset = 4,
+                Syntax.memArgAlign = 2}})),
+            (Syntax.InstructionLocalSet "__rec_scratch"),
+            (Syntax.InstructionLocalGet "__rec_ptr"),
+            (Syntax.InstructionLocalGet "__rec_scratch"),
+            (Syntax.InstructionStore (Syntax.MemoryInstruction {
+              Syntax.memoryInstructionType = Syntax.ValTypeI32,
+              Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                Syntax.memArgOffset = 0,
+                Syntax.memArgAlign = 2}})),
+            (Syntax.InstructionLocalGet "__rec_ptr")]])))
+      Core.TermInject v0 ->
+        let typeName = Core.injectionTypeName v0
+            field = Core.injectionField v0
+            fieldName = Core.fieldName field
+            fterm = Core.fieldTerm field
+            dterm = Strip.deannotateTerm fterm
+            isUnit =
+                    case dterm of
+                      Core.TermUnit -> True
+                      Core.TermRecord v1 -> Lists.null (Core.recordFields v1)
+                      _ -> False
+            mVariants = Maps.lookup typeName variantIndexes
+            tag =
+                    Optionals.cases mVariants 0 (\pairs ->
+                      let matching = Lists.filter (\p -> Equality.equal (Pairs.first p) fieldName) pairs
+                      in (Optionals.cases (Lists.maybeHead matching) 0 (\p -> Pairs.second p)))
+        in (Eithers.bind (Logic.ifElse isUnit (Right [
+          Syntax.InstructionConst (Syntax.ConstValueI32 0)]) (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs fterm)) (\payloadInstrs -> Right (Lists.concat [
+          [
+            Syntax.InstructionConst (Syntax.ConstValueI32 tag)],
+          payloadInstrs,
+          [
+            Syntax.InstructionConst (Syntax.ConstValueI32 8),
+            (Syntax.InstructionCall "__alloc"),
+            (Syntax.InstructionLocalSet "__rec_ptr"),
+            (Syntax.InstructionLocalSet "__rec_scratch"),
+            (Syntax.InstructionLocalGet "__rec_ptr"),
+            (Syntax.InstructionLocalGet "__rec_scratch"),
+            (Syntax.InstructionStore (Syntax.MemoryInstruction {
+              Syntax.memoryInstructionType = Syntax.ValTypeI32,
+              Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                Syntax.memArgOffset = 4,
+                Syntax.memArgAlign = 2}})),
+            (Syntax.InstructionLocalSet "__rec_scratch"),
+            (Syntax.InstructionLocalGet "__rec_ptr"),
+            (Syntax.InstructionLocalGet "__rec_scratch"),
+            (Syntax.InstructionStore (Syntax.MemoryInstruction {
+              Syntax.memoryInstructionType = Syntax.ValTypeI32,
+              Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                Syntax.memArgOffset = 0,
+                Syntax.memArgAlign = 2}})),
+            (Syntax.InstructionLocalGet "__rec_ptr")]])))
+      Core.TermLambda v0 -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.lambdaBody v0)
+      Core.TermLet v0 ->
+        let bindings = Core.letBindings v0
+            body = Core.letBody v0
+        in (Eithers.bind (Eithers.mapList (\b ->
+          let bname = Formatting.convertCaseCamelToLowerSnake (Core.unName (Core.bindingName b))
+          in (Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.bindingTerm b)) (\bval -> Right (Lists.concat2 bval [
+            Syntax.InstructionLocalSet bname])))) bindings) (\bindInstrs -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs body) (\bodyInstrs -> Right (Lists.concat2 (Lists.concat bindInstrs) bodyInstrs))))
+      Core.TermList v0 ->
+        let numElems = Lists.length v0
+            listSize = Math.mul (Math.add numElems 1) 4
+        in (Eithers.bind (Eithers.mapList (\el -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs el) v0) (\encodedElems ->
+          let allElemInstrs = Lists.concat encodedElems
+              allocInstrs =
+                      [
+                        Syntax.InstructionConst (Syntax.ConstValueI32 listSize),
+                        (Syntax.InstructionCall "__alloc"),
+                        (Syntax.InstructionLocalSet "__rec_ptr")]
+              lengthStoreInstrs =
+                      [
+                        Syntax.InstructionLocalGet "__rec_ptr",
+                        (Syntax.InstructionConst (Syntax.ConstValueI32 numElems)),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = 0,
+                            Syntax.memArgAlign = 2}}))]
+              storeInstrs =
+                      Lists.concat (Lists.map (\i -> [
+                        Syntax.InstructionLocalSet "__rec_scratch",
+                        (Syntax.InstructionLocalGet "__rec_ptr"),
+                        (Syntax.InstructionLocalGet "__rec_scratch"),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = (Math.mul (Math.add i 1) 4),
+                            Syntax.memArgAlign = 2}}))]) (Lists.foldl (\acc -> \_e -> Lists.cons (Lists.length acc) acc) [] v0))
+              finalInstrs = [
+                    Syntax.InstructionLocalGet "__rec_ptr"]
+          in (Right (Lists.concat [
+            allElemInstrs,
+            allocInstrs,
+            lengthStoreInstrs,
+            storeInstrs,
+            finalInstrs]))))
+      Core.TermLiteral v0 -> case v0 of
+        Core.LiteralString v1 -> Optionals.cases (Maps.lookup v1 stringOffsets) (Right [
+          Syntax.InstructionConst (Syntax.ConstValueI32 0)]) (\off -> Right [
+          Syntax.InstructionConst (Syntax.ConstValueI32 off)])
+        _ -> Right [
+          encodeLiteral v0]
+      Core.TermMap v0 ->
+        let mapEntries = Maps.toList v0
+            numMapEntries = Lists.length mapEntries
+            mapWordCount = Math.add (Math.mul numMapEntries 2) 1
+            mapSize = Math.mul mapWordCount 4
+        in (Eithers.bind (Eithers.mapList (\kv -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Pairs.first kv)) (\kInstrs -> Eithers.map (\vInstrs -> Lists.concat2 kInstrs vInstrs) (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Pairs.second kv)))) mapEntries) (\encodedMapKVs ->
+          let allMapKVInstrs = Lists.concat encodedMapKVs
+              mapAllocInstrs =
+                      [
+                        Syntax.InstructionConst (Syntax.ConstValueI32 mapSize),
+                        (Syntax.InstructionCall "__alloc"),
+                        (Syntax.InstructionLocalSet "__rec_ptr")]
+              mapLengthStoreInstrs =
+                      [
+                        Syntax.InstructionLocalGet "__rec_ptr",
+                        (Syntax.InstructionConst (Syntax.ConstValueI32 numMapEntries)),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = 0,
+                            Syntax.memArgAlign = 2}}))]
+              numMapWords = Math.mul numMapEntries 2
+              mapReverseIndices = Lists.foldl (\acc -> \_i -> Lists.cons (Lists.length acc) acc) [] (Lists.replicate numMapWords ())
+              mapStoreInstrs =
+                      Lists.concat (Lists.map (\j -> [
+                        Syntax.InstructionLocalSet "__rec_scratch",
+                        (Syntax.InstructionLocalGet "__rec_ptr"),
+                        (Syntax.InstructionLocalGet "__rec_scratch"),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = (Math.mul (Math.add j 1) 4),
+                            Syntax.memArgAlign = 2}}))]) mapReverseIndices)
+              mapFinalInstrs = [
+                    Syntax.InstructionLocalGet "__rec_ptr"]
+          in (Right (Lists.concat [
+            allMapKVInstrs,
+            mapAllocInstrs,
+            mapLengthStoreInstrs,
+            mapStoreInstrs,
+            mapFinalInstrs]))))
+      Core.TermOptional v0 -> Optionals.cases v0 (Right [
+        Syntax.InstructionConst (Syntax.ConstValueI32 0)]) (\val -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs val)
+      Core.TermPair v0 -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Pairs.first v0)) (\firstInstrs -> Eithers.bind (encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Pairs.second v0)) (\secondInstrs -> Right (Lists.concat [
+        firstInstrs,
+        secondInstrs,
+        [
+          Syntax.InstructionConst (Syntax.ConstValueI32 8),
+          (Syntax.InstructionCall "__alloc"),
+          (Syntax.InstructionLocalSet "__rec_ptr"),
+          (Syntax.InstructionLocalSet "__rec_scratch"),
+          (Syntax.InstructionLocalGet "__rec_ptr"),
+          (Syntax.InstructionLocalGet "__rec_scratch"),
+          (Syntax.InstructionStore (Syntax.MemoryInstruction {
+            Syntax.memoryInstructionType = Syntax.ValTypeI32,
+            Syntax.memoryInstructionMemArg = Syntax.MemArg {
+              Syntax.memArgOffset = 4,
+              Syntax.memArgAlign = 2}})),
+          (Syntax.InstructionLocalSet "__rec_scratch"),
+          (Syntax.InstructionLocalGet "__rec_ptr"),
+          (Syntax.InstructionLocalGet "__rec_scratch"),
+          (Syntax.InstructionStore (Syntax.MemoryInstruction {
+            Syntax.memoryInstructionType = Syntax.ValTypeI32,
+            Syntax.memoryInstructionMemArg = Syntax.MemArg {
+              Syntax.memArgOffset = 0,
+              Syntax.memArgAlign = 2}})),
+          (Syntax.InstructionLocalGet "__rec_ptr")]])))
+      Core.TermProject _ -> Right [
+        Syntax.InstructionConst (Syntax.ConstValueI32 0)]
+      Core.TermRecord v0 ->
+        let recFields = Core.recordFields v0
+            numFields = Lists.length recFields
+            recSize = Math.mul numFields 4
+        in (Eithers.bind (Eithers.mapList (\fld -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.fieldTerm fld)) recFields) (\encodedFields ->
+          let allFieldInstrs = Lists.concat encodedFields
+              allocInstrs =
+                      [
+                        Syntax.InstructionConst (Syntax.ConstValueI32 recSize),
+                        (Syntax.InstructionCall "__alloc"),
+                        (Syntax.InstructionLocalSet "__rec_ptr")]
+              storeInstrs =
+                      Lists.concat (Lists.map (\i -> [
+                        Syntax.InstructionLocalSet "__rec_scratch",
+                        (Syntax.InstructionLocalGet "__rec_ptr"),
+                        (Syntax.InstructionLocalGet "__rec_scratch"),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = (Math.mul i 4),
+                            Syntax.memArgAlign = 2}}))]) (Lists.foldl (\acc -> \_f -> Lists.cons (Lists.length acc) acc) [] recFields))
+              finalInstrs = [
+                    Syntax.InstructionLocalGet "__rec_ptr"]
+          in (Right (Lists.concat [
+            allFieldInstrs,
+            allocInstrs,
+            storeInstrs,
+            finalInstrs]))))
+      Core.TermSet v0 ->
+        let setElems = Sets.toList v0
+            numSetElems = Lists.length setElems
+            setSize = Math.mul (Math.add numSetElems 1) 4
+        in (Eithers.bind (Eithers.mapList (\el -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs el) setElems) (\encodedSetElems ->
+          let allSetElemInstrs = Lists.concat encodedSetElems
+              setAllocInstrs =
+                      [
+                        Syntax.InstructionConst (Syntax.ConstValueI32 setSize),
+                        (Syntax.InstructionCall "__alloc"),
+                        (Syntax.InstructionLocalSet "__rec_ptr")]
+              setLengthStoreInstrs =
+                      [
+                        Syntax.InstructionLocalGet "__rec_ptr",
+                        (Syntax.InstructionConst (Syntax.ConstValueI32 numSetElems)),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = 0,
+                            Syntax.memArgAlign = 2}}))]
+              setStoreInstrs =
+                      Lists.concat (Lists.map (\i -> [
+                        Syntax.InstructionLocalSet "__rec_scratch",
+                        (Syntax.InstructionLocalGet "__rec_ptr"),
+                        (Syntax.InstructionLocalGet "__rec_scratch"),
+                        (Syntax.InstructionStore (Syntax.MemoryInstruction {
+                          Syntax.memoryInstructionType = Syntax.ValTypeI32,
+                          Syntax.memoryInstructionMemArg = Syntax.MemArg {
+                            Syntax.memArgOffset = (Math.mul (Math.add i 1) 4),
+                            Syntax.memArgAlign = 2}}))]) (Lists.foldl (\acc -> \_e -> Lists.cons (Lists.length acc) acc) [] setElems))
+              setFinalInstrs = [
+                    Syntax.InstructionLocalGet "__rec_ptr"]
+          in (Right (Lists.concat [
+            allSetElemInstrs,
+            setAllocInstrs,
+            setLengthStoreInstrs,
+            setStoreInstrs,
+            setFinalInstrs]))))
+      Core.TermTypeApplication v0 -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.typeApplicationTermBody v0)
+      Core.TermTypeLambda v0 -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.typeLambdaBody v0)
+      Core.TermUnit -> Right [
+        Syntax.InstructionConst (Syntax.ConstValueI32 0)]
+      Core.TermUnwrap _ -> Right [
+        Syntax.InstructionConst (Syntax.ConstValueI32 0)]
+      Core.TermVariable v0 ->
+        let rawName = Core.unName v0
+            lname = Formatting.convertCaseCamelToLowerSnake rawName
+        in (Logic.ifElse (Lists.null (Optionals.fromOptional [] (Lists.maybeTail (Strings.splitOn "." rawName)))) (Right [
+          Syntax.InstructionLocalGet lname]) (Right [
+          Syntax.InstructionConst (Syntax.ConstValueI32 0)]))
+      Core.TermWrap v0 -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs (Core.wrappedTermBody v0)
+      _ -> Left (Errors.ErrorOther (Errors.OtherError "unexpected term variant in WASM encoding"))
+encodeTermDefinition :: t0 -> t1 -> M.Map String Int -> M.Map Core.Name [(Core.Name, Int)] -> M.Map Core.Name [(Core.Name, Int)] -> M.Map String ([t2], t3) -> Packaging.TermDefinition -> Either Errors.Error Syntax.ModuleField
+encodeTermDefinition cx g stringOffsets fieldOffsets variantIndexes funcSigs tdef =
+
+      let name = Packaging.termDefinitionName tdef
+          term = Packaging.termDefinitionBody tdef
+          lname = Formatting.convertCaseCamelToLowerSnake (Core.unName name)
+          typ =
+                  Optionals.cases (Optionals.map Scoping.termSignatureToTypeScheme (Packaging.termDefinitionSignature tdef)) Core.TypeUnit Core.typeSchemeBody
+          extracted = extractLambdaParams term
+          paramNames = Pairs.first extracted
+          innerBody = Pairs.second extracted
+          lambdaParamNameStrs = Lists.map (\pn -> Formatting.convertCaseCamelToLowerSnake (Core.unName pn)) paramNames
+      in (Eithers.bind (extractParamTypes cx g typ) (\typeParams ->
+        let typeParamCount = Lists.length typeParams
+            lambdaParamCount = Lists.length lambdaParamNameStrs
+            syntheticCount = Logic.ifElse (Equality.gt typeParamCount lambdaParamCount) (Math.sub typeParamCount lambdaParamCount) 0
+            syntheticParamNames =
+                    Logic.ifElse (Equality.gt syntheticCount 0) (Lists.map (\i -> Strings.cat2 "arg_synth_" (Literals.showInt32 i)) (Math.range 0 (Math.sub syntheticCount 1))) []
+            paramNameStrs = Lists.concat2 lambdaParamNameStrs syntheticParamNames
+            wasmParams =
+                    Lists.map (\pn -> Syntax.Param {
+                      Syntax.paramName = (Just pn),
+                      Syntax.paramType = Syntax.ValTypeI32}) paramNameStrs
+            initPrologue =
+                    Lists.concat (Lists.map (\sn -> [
+                      Syntax.InstructionLocalGet sn,
+                      Syntax.InstructionDrop]) syntheticParamNames)
+            resultTypes = [
+                  Syntax.ValTypeI32]
+            dBody = Strip.deannotateTerm innerBody
+            scrutineeInstrs = Optionals.cases (Lists.maybeHead paramNameStrs) [] (\p0 -> [
+                  Syntax.InstructionLocalGet p0])
+        in (Eithers.bind (case dBody of
+          Core.TermProject v0 -> encodeProjection cx g fieldOffsets v0 scrutineeInstrs
+          Core.TermCases v0 -> encodeCases cx g stringOffsets fieldOffsets variantIndexes funcSigs v0 scrutineeInstrs
+          Core.TermUnwrap _ -> Right [
+            Syntax.InstructionConst (Syntax.ConstValueI32 0)]
+          _ -> encodeTerm cx g stringOffsets fieldOffsets variantIndexes funcSigs innerBody) (\rawBodyInstrs ->
+          let bodyInstrs = Lists.concat2 initPrologue rawBodyInstrs
+              referencedLocals = collectInstructionLocals bodyInstrs
+              allLocalNames = Sets.toList (Sets.difference referencedLocals (Sets.fromList paramNameStrs))
+              wasmLocals =
+                      Lists.map (\ln -> Syntax.FuncLocal {
+                        Syntax.funcLocalName = (Just ln),
+                        Syntax.funcLocalType = Syntax.ValTypeI32}) allLocalNames
+          in (Right (Syntax.ModuleFieldFunc (Syntax.Func {
+            Syntax.funcName = (Just lname),
+            Syntax.funcTypeUse = Syntax.TypeUse {
+              Syntax.typeUseIndex = Nothing,
+              Syntax.typeUseParams = wasmParams,
+              Syntax.typeUseResults = resultTypes},
+            Syntax.funcLocals = wasmLocals,
+            Syntax.funcBody = bodyInstrs})))))))
+encodeType :: t0 -> t1 -> Core.Type -> Either t2 [Syntax.ValType]
+encodeType cx g t =
+
+      let typ = Strip.deannotateType t
+      in case typ of
+        Core.TypeAnnotated v0 -> encodeType cx g (Core.annotatedTypeBody v0)
+        Core.TypeFunction v0 -> encodeType cx g (Core.functionTypeCodomain v0)
+        Core.TypeUnit -> Right []
+        Core.TypeVoid -> Right []
+        Core.TypeLiteral v0 -> Right [
+          encodeLiteralType v0]
+        Core.TypeForall v0 -> encodeType cx g (Core.forallTypeBody v0)
+        _ -> Right [
+          Syntax.ValTypeI32]
+encodeTypeDefinition :: t0 -> t1 -> Packaging.TypeDefinition -> Either t2 [Syntax.ModuleField]
+encodeTypeDefinition cx g tdef =
+
+      let name = Packaging.typeDefinitionName tdef
+          lname = Formatting.convertCaseCamelToLowerSnake (Names.localNameOf name)
+          typ = Core.typeSchemeBody (Packaging.typeDefinitionBody tdef)
+          dtyp = Strip.deannotateType typ
+      in case dtyp of
+        Core.TypeFunction _ -> Eithers.bind (extractParamTypes cx g typ) (\paramTypes -> Eithers.bind (encodeType cx g typ) (\resultTypes -> Right [
+          Syntax.ModuleFieldType (Syntax.TypeDef {
+            Syntax.typeDefName = (Just lname),
+            Syntax.typeDefType = Syntax.FuncType {
+              Syntax.funcTypeParams = paramTypes,
+              Syntax.funcTypeResults = resultTypes}})]))
+        _ -> Right []
+encodeValType :: t0 -> t1 -> Core.Type -> Either t2 Syntax.ValType
+encodeValType cx g t =
+
+      let typ = Strip.deannotateType t
+      in case typ of
+        Core.TypeAnnotated v0 -> encodeValType cx g (Core.annotatedTypeBody v0)
+        Core.TypeApplication v0 -> encodeValType cx g (Core.applicationTypeFunction v0)
+        Core.TypeLiteral v0 -> Right (encodeLiteralType v0)
+        Core.TypeUnit -> Right Syntax.ValTypeI32
+        Core.TypeVoid -> Right Syntax.ValTypeI32
+        Core.TypeForall v0 -> encodeValType cx g (Core.forallTypeBody v0)
+        _ -> Right Syntax.ValTypeI32
+extractLambdaParams :: Core.Term -> ([Core.Name], Core.Term)
+extractLambdaParams term =
+
+      let stripped = Strip.deannotateTerm term
+      in case stripped of
+        Core.TermLambda v0 ->
+          let paramName = Core.lambdaParameter v0
+              body = Core.lambdaBody v0
+              inner = extractLambdaParams body
+          in (Lists.cons paramName (Pairs.first inner), (Pairs.second inner))
+        Core.TermCases _ -> ([
+          Core.Name "arg_0"], term)
+        Core.TermProject _ -> ([
+          Core.Name "arg_0"], term)
+        Core.TermUnwrap _ -> ([
+          Core.Name "arg_0"], term)
+        Core.TermTypeLambda v0 -> extractLambdaParams (Core.typeLambdaBody v0)
+        Core.TermTypeApplication v0 -> extractLambdaParams (Core.typeApplicationTermBody v0)
+        _ -> ([], term)
+extractParamTypes :: t0 -> t1 -> Core.Type -> Either t2 [Syntax.ValType]
+extractParamTypes cx g t =
+
+      let typ = Strip.deannotateType t
+      in case typ of
+        Core.TypeFunction v0 -> Eithers.bind (encodeValType cx g (Core.functionTypeDomain v0)) (\domType -> Eithers.bind (extractParamTypes cx g (Core.functionTypeCodomain v0)) (\rest -> Right (Lists.cons domType rest)))
+        Core.TypeForall v0 -> extractParamTypes cx g (Core.forallTypeBody v0)
+        _ -> Right []
+extractSignature :: t0 -> t1 -> Core.Type -> Either t2 ([Syntax.ValType], [Syntax.ValType])
+extractSignature cx g t =
+    Eithers.bind (extractParamTypes cx g t) (\params -> Eithers.bind (encodeType cx g t) (\results -> Right (clampValTypesToI32 params, (clampValTypesToI32 results))))
+hexEscapeString :: Int -> String
+hexEscapeString b =
+
+      let byte = Optionals.fromOptional 0 (Math.maybeMod b 256)
+          digitToHex =
+                  \d -> Logic.ifElse (Equality.lt d 10) (Strings.fromList [
+                    Math.add d 48]) (Strings.fromList [
+                    Math.add d 87])
+      in (Strings.cat [
+        "\\",
+        (digitToHex (Optionals.fromOptional 0 (Math.maybeDiv byte 16))),
+        (digitToHex (Optionals.fromOptional 0 (Math.maybeMod byte 16)))])
+moduleToWasm :: Packaging.Module -> [Packaging.Definition] -> t0 -> Graph.Graph -> Either Errors.Error (M.Map String String)
+moduleToWasm mod defs cx g =
+
+      let partitioned = Environment.partitionDefinitions defs
+          typeDefs = Pairs.first partitioned
+          termDefs = Pairs.second partitioned
+          stringList = collectStrings termDefs
+          stringOffsetsAndEnd = buildStringOffsets stringList
+          stringOffsets = Pairs.first stringOffsetsAndEnd
+          stringEnd = Pairs.second stringOffsetsAndEnd
+          dataField = stringDataSegment stringOffsets
+          fieldOffsets = buildFieldOffsets g
+          variantIndexes = buildVariantIndexes g
+          funcSigs = buildFunctionSignatures cx g termDefs
+      in (Eithers.bind (Eithers.mapList (encodeTypeDefinition cx g) typeDefs) (\typeFields -> Eithers.bind (Eithers.mapList (encodeTermDefinition cx g stringOffsets fieldOffsets variantIndexes funcSigs) termDefs) (\termFields ->
+        let allFields = Lists.concat2 (Lists.concat typeFields) termFields
+            bumpGlobal =
+                    Syntax.ModuleFieldGlobal (Syntax.GlobalDef {
+                      Syntax.globalDefName = (Just "__bump_ptr"),
+                      Syntax.globalDefType = Syntax.GlobalType {
+                        Syntax.globalTypeValType = Syntax.ValTypeI32,
+                        Syntax.globalTypeMutable = True},
+                      Syntax.globalDefInit = [
+                        Syntax.InstructionConst (Syntax.ConstValueI32 stringEnd)]})
+            allocFunc =
+                    Syntax.ModuleFieldFunc (Syntax.Func {
+                      Syntax.funcName = (Just "__alloc"),
+                      Syntax.funcTypeUse = Syntax.TypeUse {
+                        Syntax.typeUseIndex = Nothing,
+                        Syntax.typeUseParams = [
+                          Syntax.Param {
+                            Syntax.paramName = (Just "sz"),
+                            Syntax.paramType = Syntax.ValTypeI32}],
+                        Syntax.typeUseResults = [
+                          Syntax.ValTypeI32]},
+                      Syntax.funcLocals = [],
+                      Syntax.funcBody = [
+                        Syntax.InstructionGlobalGet "__bump_ptr",
+                        (Syntax.InstructionGlobalGet "__bump_ptr"),
+                        (Syntax.InstructionLocalGet "sz"),
+                        (Syntax.InstructionBinop (Syntax.NumericOp {
+                          Syntax.numericOpType = Syntax.ValTypeI32,
+                          Syntax.numericOpName = "add"})),
+                        (Syntax.InstructionGlobalSet "__bump_ptr")]})
+            memField =
+                    Syntax.ModuleFieldMemory (Syntax.MemoryDef {
+                      Syntax.memoryDefName = (Just "memory"),
+                      Syntax.memoryDefLimits = Syntax.Limits {
+                        Syntax.limitsMin = 2,
+                        Syntax.limitsMax = Nothing}})
+            memExport =
+                    Syntax.ModuleFieldExport (Syntax.ExportDef {
+                      Syntax.exportDefName = "memory",
+                      Syntax.exportDefDesc = (Syntax.ExportDescMemory "memory")})
+            bumpExport =
+                    Syntax.ModuleFieldExport (Syntax.ExportDef {
+                      Syntax.exportDefName = "__bump_ptr",
+                      Syntax.exportDefDesc = (Syntax.ExportDescGlobal "__bump_ptr")})
+            allocExport =
+                    Syntax.ModuleFieldExport (Syntax.ExportDef {
+                      Syntax.exportDefName = "__alloc",
+                      Syntax.exportDefDesc = (Syntax.ExportDescFunc "__alloc")})
+            closureType =
+                    Syntax.ModuleFieldType (Syntax.TypeDef {
+                      Syntax.typeDefName = (Just "__closure_1"),
+                      Syntax.typeDefType = Syntax.FuncType {
+                        Syntax.funcTypeParams = [
+                          Syntax.ValTypeI32,
+                          Syntax.ValTypeI32],
+                        Syntax.funcTypeResults = [
+                          Syntax.ValTypeI32]}})
+            closureTable =
+                    Syntax.ModuleFieldTable (Syntax.TableDef {
+                      Syntax.tableDefName = (Just "__closure_table"),
+                      Syntax.tableDefRefType = Syntax.RefTypeFuncref,
+                      Syntax.tableDefLimits = Syntax.Limits {
+                        Syntax.limitsMin = 0,
+                        Syntax.limitsMax = Nothing}})
+            funcExports =
+                    Lists.map (\td ->
+                      let ename = Formatting.convertCaseCamelToLowerSnake (Core.unName (Packaging.termDefinitionName td))
+                      in (Syntax.ModuleFieldExport (Syntax.ExportDef {
+                        Syntax.exportDefName = ename,
+                        Syntax.exportDefDesc = (Syntax.ExportDescFunc ename)}))) termDefs
+            allBodyInstrs =
+                    Lists.concat (Lists.map (\tf -> case tf of
+                      Syntax.ModuleFieldFunc v0 -> Syntax.funcBody v0
+                      _ -> []) termFields)
+            allCallTargets = collectCallTargets allBodyInstrs
+            localFuncNames =
+                    Sets.insert "__alloc" (Sets.fromList (Lists.map (\td -> Formatting.convertCaseCamelToLowerSnake (Core.unName (Packaging.termDefinitionName td))) termDefs))
+            externalCalls = Sets.toList (Sets.difference allCallTargets localFuncNames)
+            defaultSig = ([
+                  Syntax.ValTypeI32], [
+                  Syntax.ValTypeI32])
+            importFields =
+                    Lists.map (\fname ->
+                      let parts = Strings.splitOn "." fname
+                          modName = Strings.intercalate "." (Lists.reverse (Optionals.fromOptional [] (Lists.maybeTail (Lists.reverse parts))))
+                          sig = Optionals.fromOptional defaultSig (Maps.lookup fname funcSigs)
+                          sigParams = Pairs.first sig
+                          sigResults = Pairs.second sig
+                          wasmImportParams =
+                                  Lists.map (\vt -> Syntax.Param {
+                                    Syntax.paramName = Nothing,
+                                    Syntax.paramType = vt}) sigParams
+                      in (Syntax.ModuleFieldImport (Syntax.ImportDef {
+                        Syntax.importDefModule = modName,
+                        Syntax.importDefName = fname,
+                        Syntax.importDefDesc = (Syntax.ImportDescFunc (Syntax.ImportFunc {
+                          Syntax.importFuncName = (Just fname),
+                          Syntax.importFuncTypeUse = Syntax.TypeUse {
+                            Syntax.typeUseIndex = Nothing,
+                            Syntax.typeUseParams = wasmImportParams,
+                            Syntax.typeUseResults = sigResults}}))}))) externalCalls
+            wasmMod =
+                    Syntax.Module {
+                      Syntax.moduleName = Nothing,
+                      Syntax.moduleFields = (Lists.concat [
+                        importFields,
+                        [
+                          closureType,
+                          memField,
+                          memExport,
+                          dataField,
+                          bumpGlobal,
+                          bumpExport,
+                          allocFunc,
+                          allocExport,
+                          closureTable],
+                        funcExports,
+                        allFields])}
+            code = Serialization.printExpr (Serialization.parenthesize (Serde.moduleToExpr wasmMod))
+            filePath = Names.moduleNameToFilePath Util.CaseConventionLowerSnake (File.FileExtension "wat") (Packaging.moduleName mod)
+        in (Right (Maps.singleton filePath code)))))
+peelLambdaApp :: Core.Term -> [t0] -> ([Core.Name], Core.Term)
+peelLambdaApp term args =
+    Logic.ifElse (Lists.null args) ([], term) (
+      let stripped = Strip.deannotateTerm term
+      in case stripped of
+        Core.TermLambda v0 ->
+          let paramName = Core.lambdaParameter v0
+              body = Core.lambdaBody v0
+              restArgs = Optionals.fromOptional [] (Lists.maybeTail args)
+              inner = peelLambdaApp body restArgs
+          in (Lists.cons paramName (Pairs.first inner), (Pairs.second inner))
+        _ -> ([], term))
+stringDataSegment :: Ord t0 => (M.Map String t0 -> Syntax.ModuleField)
+stringDataSegment offsets =
+
+      let entries = Lists.sortOn Pairs.second (Maps.toList offsets)
+          bytesForEntry =
+                  \entry ->
+                    let s = Pairs.first entry
+                        len = Strings.length s
+                        lenBytes =
+                                [
+                                  Optionals.fromOptional 0 (Math.maybeMod len 256),
+                                  (Optionals.fromOptional 0 (Math.maybeMod (Optionals.fromOptional 0 (Math.maybeDiv len 256)) 256)),
+                                  (Optionals.fromOptional 0 (Math.maybeMod (Optionals.fromOptional 0 (Math.maybeDiv len 65536)) 256)),
+                                  (Optionals.fromOptional 0 (Math.maybeMod (Optionals.fromOptional 0 (Math.maybeDiv len 16777216)) 256))]
+                        contentBytes = Strings.toList s
+                        allBytes = Lists.concat2 lenBytes contentBytes
+                    in (Strings.cat (Lists.map (\b -> hexEscapeString b) allBytes))
+          allHex = Strings.cat (Lists.map bytesForEntry entries)
+      in (Syntax.ModuleFieldData (Syntax.DataSegment {
+        Syntax.dataSegmentName = Nothing,
+        Syntax.dataSegmentMode = (Syntax.DataModeActive [
+          Syntax.InstructionConst (Syntax.ConstValueI32 1024)]),
+        Syntax.dataSegmentBytes = allHex}))
diff --git a/src/main/haskell/Hydra/Wasm/Language.hs b/src/main/haskell/Hydra/Wasm/Language.hs
new file mode 100644
--- /dev/null
+++ b/src/main/haskell/Hydra/Wasm/Language.hs
@@ -0,0 +1,173 @@
+-- Note: this is an automatically generated file. Do not edit.
+-- | Language constraints and reserved words for WebAssembly (WAT text format)
+
+module Hydra.Wasm.Language where
+import qualified Hydra.Ast as Ast
+import qualified Hydra.Coders as Coders
+import qualified Hydra.Core as Core
+import qualified Hydra.Error.Checking as Checking
+import qualified Hydra.Error.Core as ErrorCore
+import qualified Hydra.Error.Packaging as ErrorPackaging
+import qualified Hydra.Errors as Errors
+import qualified Hydra.Graph as Graph
+import qualified Hydra.Json.Model as Model
+import qualified Hydra.Lexical as Lexical
+import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
+import qualified Hydra.Overlay.Haskell.Lib.Sets as Sets
+import qualified Hydra.Packaging as Packaging
+import qualified Hydra.Parsing as Parsing
+import qualified Hydra.Paths as Paths
+import qualified Hydra.Query as Query
+import qualified Hydra.Relational as Relational
+import qualified Hydra.Tabular as Tabular
+import qualified Hydra.Testing as Testing
+import qualified Hydra.Topology as Topology
+import qualified Hydra.Typed as Typed
+import qualified Hydra.Typing as Typing
+import qualified Hydra.Util as Util
+import qualified Hydra.Validation as Validation
+import qualified Hydra.Variants as Variants
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import qualified Data.Scientific as Sci
+import qualified Data.Set as S
+-- | Language constraints for WebAssembly
+wasmLanguage :: Coders.Language
+wasmLanguage =
+    Coders.Language {
+      Coders.languageName = (Coders.LanguageName "hydra.wasm"),
+      Coders.languageConstraints = Coders.LanguageConstraints {
+        Coders.languageConstraintsLiteralVariants = literalVariants,
+        Coders.languageConstraintsFloatTypes = floatTypes,
+        Coders.languageConstraintsIntegerTypes = integerTypes,
+        Coders.languageConstraintsTermVariants = termVariants,
+        Coders.languageConstraintsTypeVariants = typeVariants,
+        Coders.languageConstraintsTypes = typePredicate}}
+  where
+    literalVariants =
+        Sets.fromList [
+          Variants.LiteralVariantBoolean,
+          Variants.LiteralVariantFloat,
+          Variants.LiteralVariantInteger,
+          Variants.LiteralVariantString]
+    floatTypes =
+        Sets.fromList [
+          Core.FloatTypeFloat32,
+          Core.FloatTypeFloat64]
+    integerTypes =
+        Sets.fromList [
+          Core.IntegerTypeInt8,
+          Core.IntegerTypeInt16,
+          Core.IntegerTypeInt32,
+          Core.IntegerTypeInt64,
+          Core.IntegerTypeUint8,
+          Core.IntegerTypeUint16,
+          Core.IntegerTypeUint32,
+          Core.IntegerTypeUint64]
+    termVariants =
+        Sets.fromList [
+          Variants.TermVariantAnnotated,
+          Variants.TermVariantApplication,
+          Variants.TermVariantCases,
+          Variants.TermVariantEither,
+          Variants.TermVariantInject,
+          Variants.TermVariantLambda,
+          Variants.TermVariantLet,
+          Variants.TermVariantList,
+          Variants.TermVariantLiteral,
+          Variants.TermVariantMap,
+          Variants.TermVariantOptional,
+          Variants.TermVariantPair,
+          Variants.TermVariantProject,
+          Variants.TermVariantRecord,
+          Variants.TermVariantSet,
+          Variants.TermVariantTypeApplication,
+          Variants.TermVariantTypeLambda,
+          Variants.TermVariantUnit,
+          Variants.TermVariantUnwrap,
+          Variants.TermVariantVariable,
+          Variants.TermVariantWrap]
+    typeVariants =
+        Sets.fromList [
+          Variants.TypeVariantAnnotated,
+          Variants.TypeVariantApplication,
+          Variants.TypeVariantEither,
+          Variants.TypeVariantFunction,
+          Variants.TypeVariantForall,
+          Variants.TypeVariantList,
+          Variants.TypeVariantLiteral,
+          Variants.TypeVariantMap,
+          Variants.TypeVariantOptional,
+          Variants.TypeVariantPair,
+          Variants.TypeVariantRecord,
+          Variants.TypeVariantSet,
+          Variants.TypeVariantUnion,
+          Variants.TypeVariantUnit,
+          Variants.TypeVariantVariable,
+          Variants.TypeVariantVoid,
+          Variants.TypeVariantWrap]
+    typePredicate = \_ -> True
+-- | A set of reserved words in WebAssembly text format
+wasmReservedWords :: S.Set String
+wasmReservedWords =
+    Sets.fromList (Lists.concat [
+      keywords,
+      valueTypes,
+      instructionPrefixes])
+  where
+    keywords =
+        [
+          "module",
+          "type",
+          "func",
+          "param",
+          "result",
+          "local",
+          "global",
+          "table",
+          "memory",
+          "elem",
+          "data",
+          "start",
+          "import",
+          "export",
+          "block",
+          "loop",
+          "if",
+          "then",
+          "else",
+          "end",
+          "br",
+          "br_if",
+          "br_table",
+          "return",
+          "call",
+          "call_indirect",
+          "drop",
+          "select",
+          "unreachable",
+          "nop",
+          "mut",
+          "offset",
+          "align"]
+    valueTypes =
+        [
+          "i32",
+          "i64",
+          "f32",
+          "f64",
+          "v128",
+          "funcref",
+          "externref"]
+    instructionPrefixes =
+        [
+          "i32",
+          "i64",
+          "f32",
+          "f64",
+          "local.get",
+          "local.set",
+          "local.tee",
+          "global.get",
+          "global.set",
+          "memory.size",
+          "memory.grow"]
diff --git a/src/main/haskell/Hydra/Wasm/Serde.hs b/src/main/haskell/Hydra/Wasm/Serde.hs
new file mode 100644
--- /dev/null
+++ b/src/main/haskell/Hydra/Wasm/Serde.hs
@@ -0,0 +1,551 @@
+-- Note: this is an automatically generated file. Do not edit.
+-- | WebAssembly serializer: converts WAT AST to concrete WAT text format
+
+module Hydra.Wasm.Serde where
+import qualified Hydra.Ast as Ast
+import qualified Hydra.Coders as Coders
+import qualified Hydra.Constants as Constants
+import qualified Hydra.Core as Core
+import qualified Hydra.Error.Checking as Checking
+import qualified Hydra.Error.Core as ErrorCore
+import qualified Hydra.Error.Packaging as ErrorPackaging
+import qualified Hydra.Errors as Errors
+import qualified Hydra.Graph as Graph
+import qualified Hydra.Json.Model as Model
+import qualified Hydra.Overlay.Haskell.Lib.Equality as Equality
+import qualified Hydra.Overlay.Haskell.Lib.Lists as Lists
+import qualified Hydra.Overlay.Haskell.Lib.Literals as Literals
+import qualified Hydra.Overlay.Haskell.Lib.Logic as Logic
+import qualified Hydra.Overlay.Haskell.Lib.Optionals as Optionals
+import qualified Hydra.Overlay.Haskell.Lib.Strings as Strings
+import qualified Hydra.Packaging as Packaging
+import qualified Hydra.Parsing as Parsing
+import qualified Hydra.Paths as Paths
+import qualified Hydra.Query as Query
+import qualified Hydra.Relational as Relational
+import qualified Hydra.Serialization as Serialization
+import qualified Hydra.Tabular as Tabular
+import qualified Hydra.Testing as Testing
+import qualified Hydra.Topology as Topology
+import qualified Hydra.Typed as Typed
+import qualified Hydra.Typing as Typing
+import qualified Hydra.Util as Util
+import qualified Hydra.Validation as Validation
+import qualified Hydra.Variants as Variants
+import qualified Hydra.Wasm.Syntax as Syntax
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import qualified Data.Scientific as Sci
+-- | Serialize a block or loop instruction to WAT
+blockInstructionToExpr :: String -> Syntax.BlockInstruction -> Ast.Expr
+blockInstructionToExpr keyword b =
+
+      let label = Syntax.blockInstructionLabel b
+          bt = Syntax.blockInstructionBlockType b
+          body = Syntax.blockInstructionBody b
+          labelStr = Optionals.cases label "" (\l -> Strings.cat2 " $" l)
+          btPart = blockTypeToExpr bt
+          bodyParts = Lists.map instructionToExpr body
+          header =
+                  Serialization.spaceSep (Optionals.cat [
+                    Just (Serialization.cst (Strings.cat [
+                      "(",
+                      keyword,
+                      labelStr])),
+                    btPart])
+      in (Serialization.newlineSep (Lists.concat [
+        [
+          header],
+        (Lists.map (\p -> Serialization.cst (Strings.cat2 "  " (Serialization.printExpr p))) bodyParts),
+        [
+          Serialization.cst ")"]]))
+-- | Serialize a block type to WAT
+blockTypeToExpr :: Syntax.BlockType -> Maybe Ast.Expr
+blockTypeToExpr bt =
+    case bt of
+      Syntax.BlockTypeEmpty -> Nothing
+      Syntax.BlockTypeValue v0 -> Just (Serialization.cst (Strings.cat [
+        "(result ",
+        (valTypeToStr v0),
+        ")"]))
+      Syntax.BlockTypeTypeUse v0 -> Just (typeUseToExpr v0)
+-- | Serialize a constant value instruction to WAT
+constValueToExpr :: Syntax.ConstValue -> Ast.Expr
+constValueToExpr c =
+    case c of
+      Syntax.ConstValueI32 v0 -> Serialization.cst (Strings.cat2 "i32.const " (Literals.showInt32 v0))
+      Syntax.ConstValueI64 v0 -> Serialization.cst (Strings.cat2 "i64.const " (Literals.showInt64 v0))
+      Syntax.ConstValueF32 v0 -> Serialization.cst (Strings.cat2 "f32.const " (Literals.showFloat32 v0))
+      Syntax.ConstValueF64 v0 -> Serialization.cst (Strings.cat2 "f64.const " (Literals.showFloat64 v0))
+-- | Serialize a data segment to WAT
+dataSegmentToExpr :: Syntax.DataSegment -> Ast.Expr
+dataSegmentToExpr d =
+
+      let name = Syntax.dataSegmentName d
+          mode = Syntax.dataSegmentMode d
+          bytes = Syntax.dataSegmentBytes d
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in case mode of
+        Syntax.DataModeActive v0 -> Serialization.spaceSep [
+          Serialization.cst (Strings.cat2 "(data" nameStr),
+          (Serialization.spaceSep [
+            Serialization.cst "(offset",
+            (Serialization.spaceSep (Lists.map instructionToExpr v0)),
+            (Serialization.cst ")")]),
+          (Serialization.cst (Strings.cat [
+            "\"",
+            bytes,
+            "\")"]))]
+        Syntax.DataModePassive -> Serialization.spaceSep [
+          Serialization.cst (Strings.cat2 "(data" nameStr),
+          (Serialization.cst (Strings.cat [
+            "\"",
+            bytes,
+            "\")"]))]
+-- | Serialize an export declaration to WAT
+exportDefToExpr :: Syntax.ExportDef -> Ast.Expr
+exportDefToExpr e =
+
+      let name = Syntax.exportDefName e
+          desc = Syntax.exportDefDesc e
+      in (Serialization.spaceSep [
+        Serialization.cst "(export",
+        (Serialization.cst (Strings.cat [
+          "\"",
+          name,
+          "\""])),
+        (exportDescToExpr desc),
+        (Serialization.cst ")")])
+-- | Serialize an export descriptor to WAT
+exportDescToExpr :: Syntax.ExportDesc -> Ast.Expr
+exportDescToExpr desc =
+    case desc of
+      Syntax.ExportDescFunc v0 -> Serialization.cst (Strings.cat [
+        "(func $",
+        v0,
+        ")"])
+      Syntax.ExportDescMemory v0 -> Serialization.cst (Strings.cat [
+        "(memory $",
+        v0,
+        ")"])
+      Syntax.ExportDescTable v0 -> Serialization.cst (Strings.cat [
+        "(table $",
+        v0,
+        ")"])
+      Syntax.ExportDescGlobal v0 -> Serialization.cst (Strings.cat [
+        "(global $",
+        v0,
+        ")"])
+-- | Serialize a local variable declaration to WAT
+funcLocalToExpr :: Syntax.FuncLocal -> Ast.Expr
+funcLocalToExpr l =
+
+      let name = Syntax.funcLocalName l
+          typ = Syntax.funcLocalType l
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in (Serialization.cst (Strings.cat [
+        "(local",
+        nameStr,
+        " ",
+        (valTypeToStr typ),
+        ")"]))
+-- | Serialize a function definition to WAT
+funcToExpr :: Syntax.Func -> Ast.Expr
+funcToExpr f =
+
+      let name = Syntax.funcName f
+          typeUse = Syntax.funcTypeUse f
+          locals = Syntax.funcLocals f
+          body = Syntax.funcBody f
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+          headerStr = Strings.cat2 "(func" nameStr
+          typeUsePart = typeUseToExpr typeUse
+          localParts = Lists.map funcLocalToExpr locals
+          bodyParts = Lists.map instructionToExpr body
+          innerParts = Lists.concat2 localParts bodyParts
+      in (Logic.ifElse (Lists.null innerParts) (Serialization.spaceSep [
+        Serialization.cst headerStr,
+        typeUsePart,
+        (Serialization.cst ")")]) (Serialization.newlineSep (Lists.concat [
+        [
+          Serialization.spaceSep [
+            Serialization.cst headerStr,
+            typeUsePart]],
+        (Lists.map (\p -> Serialization.cst (Strings.cat2 "  " (Serialization.printExpr p))) innerParts),
+        [
+          Serialization.cst ")"]])))
+-- | Serialize a function type to WAT
+funcTypeToExpr :: Syntax.FuncType -> Ast.Expr
+funcTypeToExpr ft =
+
+      let params = Syntax.funcTypeParams ft
+          results = Syntax.funcTypeResults ft
+          paramParts =
+                  Lists.map (\p -> Serialization.cst (Strings.cat [
+                    "(param ",
+                    (valTypeToStr p),
+                    ")"])) params
+          resultParts =
+                  Lists.map (\r -> Serialization.cst (Strings.cat [
+                    "(result ",
+                    (valTypeToStr r),
+                    ")"])) results
+      in (Serialization.spaceSep (Optionals.cat [
+        Just (Serialization.cst "(func"),
+        (Logic.ifElse (Lists.null paramParts) Nothing (Just (Serialization.spaceSep paramParts))),
+        (Logic.ifElse (Lists.null resultParts) Nothing (Just (Serialization.spaceSep resultParts))),
+        (Just (Serialization.cst ")"))]))
+-- | Serialize a global definition to WAT
+globalDefToExpr :: Syntax.GlobalDef -> Ast.Expr
+globalDefToExpr g =
+
+      let name = Syntax.globalDefName g
+          gt = Syntax.globalDefType g
+          init = Syntax.globalDefInit g
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in (Serialization.spaceSep [
+        Serialization.cst (Strings.cat2 "(global" nameStr),
+        (globalTypeToExpr gt),
+        (Serialization.spaceSep (Lists.map instructionToExpr init)),
+        (Serialization.cst ")")])
+-- | Serialize a global type to WAT
+globalTypeToExpr :: Syntax.GlobalType -> Ast.Expr
+globalTypeToExpr gt =
+
+      let vt = Syntax.globalTypeValType gt
+          mut = Syntax.globalTypeMutable gt
+      in (Logic.ifElse mut (Serialization.cst (Strings.cat [
+        "(mut ",
+        (valTypeToStr vt),
+        ")"])) (Serialization.cst (valTypeToStr vt)))
+-- | Serialize an if instruction to WAT
+ifInstructionToExpr :: Syntax.IfInstruction -> Ast.Expr
+ifInstructionToExpr i =
+
+      let label = Syntax.ifInstructionLabel i
+          bt = Syntax.ifInstructionBlockType i
+          thenBranch = Syntax.ifInstructionThen i
+          elseBranch = Syntax.ifInstructionElse i
+          labelStr = Optionals.cases label "" (\l -> Strings.cat2 " $" l)
+          btPart = blockTypeToExpr bt
+          thenParts = Lists.map instructionToExpr thenBranch
+          elseParts = Lists.map instructionToExpr elseBranch
+          header =
+                  Serialization.spaceSep (Optionals.cat [
+                    Just (Serialization.cst (Strings.cat [
+                      "(if",
+                      labelStr])),
+                    btPart])
+          thenBlock =
+                  Serialization.newlineSep (Lists.concat [
+                    [
+                      Serialization.cst "(then"],
+                    (Lists.map (\p -> Serialization.cst (Strings.cat2 "  " (Serialization.printExpr p))) thenParts),
+                    [
+                      Serialization.cst ")"]])
+          elseBlock =
+                  Serialization.newlineSep (Lists.concat [
+                    [
+                      Serialization.cst "(else"],
+                    (Lists.map (\p -> Serialization.cst (Strings.cat2 "  " (Serialization.printExpr p))) elseParts),
+                    [
+                      Serialization.cst ")"]])
+      in (Logic.ifElse (Lists.null elseParts) (Serialization.newlineSep [
+        header,
+        thenBlock,
+        (Serialization.cst ")")]) (Serialization.newlineSep [
+        header,
+        thenBlock,
+        elseBlock,
+        (Serialization.cst ")")]))
+-- | Serialize an import declaration to WAT
+importDefToExpr :: Syntax.ImportDef -> Ast.Expr
+importDefToExpr i =
+
+      let modName = Syntax.importDefModule i
+          name = Syntax.importDefName i
+          desc = Syntax.importDefDesc i
+      in (Serialization.spaceSep [
+        Serialization.cst "(import",
+        (Serialization.cst (Strings.cat [
+          "\"",
+          modName,
+          "\""])),
+        (Serialization.cst (Strings.cat [
+          "\"",
+          name,
+          "\""])),
+        (importDescToExpr desc),
+        (Serialization.cst ")")])
+-- | Serialize an import descriptor to WAT
+importDescToExpr :: Syntax.ImportDesc -> Ast.Expr
+importDescToExpr desc =
+    case desc of
+      Syntax.ImportDescFunc v0 ->
+        let name = Syntax.importFuncName v0
+            tu = Syntax.importFuncTypeUse v0
+            nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+        in (Serialization.spaceSep [
+          Serialization.cst (Strings.cat2 "(func" nameStr),
+          (typeUseToExpr tu),
+          (Serialization.cst ")")])
+      Syntax.ImportDescMemory v0 ->
+        let name = Syntax.importMemoryName v0
+            lim = Syntax.importMemoryLimits v0
+            nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+        in (Serialization.spaceSep [
+          Serialization.cst (Strings.cat2 "(memory" nameStr),
+          (limitsToExpr lim),
+          (Serialization.cst ")")])
+      Syntax.ImportDescTable v0 ->
+        let name = Syntax.importTableName v0
+            rt = Syntax.importTableRefType v0
+            lim = Syntax.importTableLimits v0
+            nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+        in (Serialization.spaceSep [
+          Serialization.cst (Strings.cat2 "(table" nameStr),
+          (limitsToExpr lim),
+          (Serialization.cst (refTypeToStr rt)),
+          (Serialization.cst ")")])
+      Syntax.ImportDescGlobal v0 ->
+        let name = Syntax.importGlobalName v0
+            gt = Syntax.importGlobalType v0
+            nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+        in (Serialization.spaceSep [
+          Serialization.cst (Strings.cat2 "(global" nameStr),
+          (globalTypeToExpr gt),
+          (Serialization.cst ")")])
+-- | Serialize an instruction to WAT
+instructionToExpr :: Syntax.Instruction -> Ast.Expr
+instructionToExpr instr =
+    case instr of
+      Syntax.InstructionConst v0 -> constValueToExpr v0
+      Syntax.InstructionLocalGet v0 -> Serialization.cst (Strings.cat [
+        "local.get $",
+        v0])
+      Syntax.InstructionLocalSet v0 -> Serialization.cst (Strings.cat [
+        "local.set $",
+        v0])
+      Syntax.InstructionLocalTee v0 -> Serialization.cst (Strings.cat [
+        "local.tee $",
+        v0])
+      Syntax.InstructionGlobalGet v0 -> Serialization.cst (Strings.cat [
+        "global.get $",
+        v0])
+      Syntax.InstructionGlobalSet v0 -> Serialization.cst (Strings.cat [
+        "global.set $",
+        v0])
+      Syntax.InstructionLoad v0 ->
+        let vt = Syntax.memoryInstructionType v0
+            ma = Syntax.memoryInstructionMemArg v0
+            off = Syntax.memArgOffset ma
+            offStr = Logic.ifElse (Equality.equal off 0) "" (Strings.cat2 " offset=" (Literals.showInt32 off))
+        in (Serialization.cst (Strings.cat [
+          valTypeToStr vt,
+          ".load",
+          offStr]))
+      Syntax.InstructionStore v0 ->
+        let vt = Syntax.memoryInstructionType v0
+            ma = Syntax.memoryInstructionMemArg v0
+            off = Syntax.memArgOffset ma
+            offStr = Logic.ifElse (Equality.equal off 0) "" (Strings.cat2 " offset=" (Literals.showInt32 off))
+        in (Serialization.cst (Strings.cat [
+          valTypeToStr vt,
+          ".store",
+          offStr]))
+      Syntax.InstructionUnop v0 ->
+        let vt = Syntax.numericOpType v0
+            nm = Syntax.numericOpName v0
+        in (Serialization.cst (Strings.cat [
+          valTypeToStr vt,
+          ".",
+          nm]))
+      Syntax.InstructionBinop v0 ->
+        let vt = Syntax.numericOpType v0
+            nm = Syntax.numericOpName v0
+        in (Serialization.cst (Strings.cat [
+          valTypeToStr vt,
+          ".",
+          nm]))
+      Syntax.InstructionTestop v0 ->
+        let vt = Syntax.numericOpType v0
+            nm = Syntax.numericOpName v0
+        in (Serialization.cst (Strings.cat [
+          valTypeToStr vt,
+          ".",
+          nm]))
+      Syntax.InstructionRelop v0 ->
+        let vt = Syntax.numericOpType v0
+            nm = Syntax.numericOpName v0
+        in (Serialization.cst (Strings.cat [
+          valTypeToStr vt,
+          ".",
+          nm]))
+      Syntax.InstructionConvert v0 -> Serialization.cst v0
+      Syntax.InstructionCall v0 -> Serialization.cst (Strings.cat [
+        "call $",
+        v0])
+      Syntax.InstructionCallIndirect v0 -> Serialization.spaceSep [
+        Serialization.cst "call_indirect",
+        (typeUseToExpr v0)]
+      Syntax.InstructionBlock v0 -> blockInstructionToExpr "block" v0
+      Syntax.InstructionLoop v0 -> blockInstructionToExpr "loop" v0
+      Syntax.InstructionIf v0 -> ifInstructionToExpr v0
+      Syntax.InstructionBr v0 -> Serialization.cst (Strings.cat [
+        "br $",
+        v0])
+      Syntax.InstructionBrIf v0 -> Serialization.cst (Strings.cat [
+        "br_if $",
+        v0])
+      Syntax.InstructionBrTable v0 ->
+        let labels = Syntax.brTableArgsLabels v0
+            def = Syntax.brTableArgsDefault v0
+        in (Serialization.cst (Strings.cat [
+          "br_table ",
+          (Strings.intercalate " " (Lists.map (\l -> Strings.cat2 "$" l) labels)),
+          " $",
+          def]))
+      Syntax.InstructionReturn -> Serialization.cst "return"
+      Syntax.InstructionDrop -> Serialization.cst "drop"
+      Syntax.InstructionSelect -> Serialization.cst "select"
+      Syntax.InstructionUnreachable -> Serialization.cst "unreachable"
+      Syntax.InstructionNop -> Serialization.cst "nop"
+      Syntax.InstructionMemorySize -> Serialization.cst "memory.size"
+      Syntax.InstructionMemoryGrow -> Serialization.cst "memory.grow"
+      Syntax.InstructionRefNull v0 -> Serialization.cst (Strings.cat [
+        "ref.null ",
+        (refTypeToStr v0)])
+      Syntax.InstructionRefIsNull -> Serialization.cst "ref.is_null"
+      Syntax.InstructionRaw v0 -> Serialization.cst v0
+-- | Serialize limits to WAT
+limitsToExpr :: Syntax.Limits -> Ast.Expr
+limitsToExpr l =
+
+      let mn = Syntax.limitsMin l
+          mx = Syntax.limitsMax l
+      in (Serialization.spaceSep (Optionals.cat [
+        Just (Serialization.cst (Literals.showInt32 mn)),
+        (Optionals.map (\m -> Serialization.cst (Literals.showInt32 m)) mx)]))
+-- | Serialize a memory definition to WAT
+memoryDefToExpr :: Syntax.MemoryDef -> Ast.Expr
+memoryDefToExpr m =
+
+      let name = Syntax.memoryDefName m
+          lim = Syntax.memoryDefLimits m
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in (Serialization.spaceSep [
+        Serialization.cst (Strings.cat2 "(memory" nameStr),
+        (limitsToExpr lim),
+        (Serialization.cst ")")])
+-- | Serialize a module field to a WAT expression
+moduleFieldToExpr :: Syntax.ModuleField -> Ast.Expr
+moduleFieldToExpr field =
+    case field of
+      Syntax.ModuleFieldType v0 -> typeDefToExpr v0
+      Syntax.ModuleFieldFunc v0 -> funcToExpr v0
+      Syntax.ModuleFieldMemory v0 -> memoryDefToExpr v0
+      Syntax.ModuleFieldTable v0 -> tableDefToExpr v0
+      Syntax.ModuleFieldGlobal v0 -> globalDefToExpr v0
+      Syntax.ModuleFieldImport v0 -> importDefToExpr v0
+      Syntax.ModuleFieldExport v0 -> exportDefToExpr v0
+      Syntax.ModuleFieldData v0 -> dataSegmentToExpr v0
+      Syntax.ModuleFieldElem _ -> Serialization.cst ";; elem segment (not yet supported)"
+      Syntax.ModuleFieldStart v0 -> Serialization.cst (Strings.cat [
+        "(start $",
+        v0,
+        ")"])
+-- | Serialize a WebAssembly module to a WAT expression
+moduleToExpr :: Syntax.Module -> Ast.Expr
+moduleToExpr mod =
+
+      let name = Syntax.moduleName mod
+          fields = Syntax.moduleFields mod
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+          fieldExprs = Lists.map moduleFieldToExpr fields
+      in (Serialization.newlineSep (Lists.concat [
+        [
+          Serialization.cst (Strings.cat2 "(module" nameStr)],
+        (Lists.map (\fe -> Serialization.cst (Strings.cat2 "  " (Serialization.printExpr fe))) fieldExprs),
+        [
+          Serialization.cst ")"]]))
+-- | Serialize a function parameter to WAT
+paramToExpr :: Syntax.Param -> Ast.Expr
+paramToExpr p =
+
+      let name = Syntax.paramName p
+          typ = Syntax.paramType p
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in (Serialization.cst (Strings.cat [
+        "(param",
+        nameStr,
+        " ",
+        (valTypeToStr typ),
+        ")"]))
+-- | Convert a reference type to its WAT string
+refTypeToStr :: Syntax.RefType -> String
+refTypeToStr rt =
+    case rt of
+      Syntax.RefTypeFuncref -> "funcref"
+      Syntax.RefTypeExternref -> "externref"
+-- | Serialize a table definition to WAT
+tableDefToExpr :: Syntax.TableDef -> Ast.Expr
+tableDefToExpr t =
+
+      let name = Syntax.tableDefName t
+          rt = Syntax.tableDefRefType t
+          lim = Syntax.tableDefLimits t
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in (Serialization.spaceSep [
+        Serialization.cst (Strings.cat2 "(table" nameStr),
+        (limitsToExpr lim),
+        (Serialization.cst (refTypeToStr rt)),
+        (Serialization.cst ")")])
+-- | Convert a string to a WAT comment
+toWatComment :: String -> String
+toWatComment s =
+    Strings.cat [
+      ";; ",
+      s]
+-- | Serialize a type definition to WAT
+typeDefToExpr :: Syntax.TypeDef -> Ast.Expr
+typeDefToExpr td =
+
+      let name = Syntax.typeDefName td
+          ft = Syntax.typeDefType td
+          nameStr = Optionals.cases name "" (\n -> Strings.cat2 " $" n)
+      in (Serialization.spaceSep [
+        Serialization.cst (Strings.cat2 "(type" nameStr),
+        (funcTypeToExpr ft),
+        (Serialization.cst ")")])
+-- | Serialize a type use clause to WAT
+typeUseToExpr :: Syntax.TypeUse -> Ast.Expr
+typeUseToExpr tu =
+
+      let idx = Syntax.typeUseIndex tu
+          params = Syntax.typeUseParams tu
+          results = Syntax.typeUseResults tu
+          idxPart =
+                  Optionals.map (\i -> Serialization.cst (Strings.cat [
+                    "(type $",
+                    i,
+                    ")"])) idx
+          paramParts = Lists.map paramToExpr params
+          resultParts =
+                  Lists.map (\r -> Serialization.cst (Strings.cat [
+                    "(result ",
+                    (valTypeToStr r),
+                    ")"])) results
+      in (Serialization.spaceSep (Optionals.cat (Lists.concat [
+        [
+          idxPart],
+        (Lists.map (\p -> Just p) paramParts),
+        (Lists.map (\r -> Just r) resultParts)])))
+-- | Convert a value type to its WAT string representation
+valTypeToStr :: Syntax.ValType -> String
+valTypeToStr vt =
+    case vt of
+      Syntax.ValTypeI32 -> "i32"
+      Syntax.ValTypeI64 -> "i64"
+      Syntax.ValTypeF32 -> "f32"
+      Syntax.ValTypeF64 -> "f64"
+      Syntax.ValTypeFuncref -> "funcref"
+      Syntax.ValTypeExternref -> "externref"
diff --git a/src/main/haskell/Hydra/Wasm/Syntax.hs b/src/main/haskell/Hydra/Wasm/Syntax.hs
new file mode 100644
--- /dev/null
+++ b/src/main/haskell/Hydra/Wasm/Syntax.hs
@@ -0,0 +1,601 @@
+-- Note: this is an automatically generated file. Do not edit.
+-- | A WebAssembly text format (WAT) syntax model, based on the WebAssembly spec (https://webassembly.github.io/spec/core/), retrieved 2026-04-06
+
+module Hydra.Wasm.Syntax where
+import qualified Hydra.Core as Core
+import Prelude hiding  (Enum, Ordering, decodeFloat, encodeFloat, fail, map, pure, sum)
+import qualified Data.Scientific as Sci
+import qualified Data.Int as I
+-- | A WebAssembly module, the top-level container
+data Module =
+  Module {
+    -- | Optional module name
+    moduleName :: (Maybe String),
+    -- | The module's fields (types, functions, memories, tables, globals, imports, exports, etc.)
+    moduleFields :: [ModuleField]}
+  deriving (Eq, Ord, Read, Show)
+_Module = Core.Name "hydra.wasm.syntax.Module"
+_Module_name = Core.Name "name"
+_Module_fields = Core.Name "fields"
+-- | A field within a WebAssembly module
+data ModuleField =
+  -- | A type definition
+  ModuleFieldType TypeDef |
+  -- | A function definition
+  ModuleFieldFunc Func |
+  -- | A memory definition
+  ModuleFieldMemory MemoryDef |
+  -- | A table definition
+  ModuleFieldTable TableDef |
+  -- | A global variable definition
+  ModuleFieldGlobal GlobalDef |
+  -- | An import declaration
+  ModuleFieldImport ImportDef |
+  -- | An export declaration
+  ModuleFieldExport ExportDef |
+  -- | A data segment
+  ModuleFieldData DataSegment |
+  -- | An element segment
+  ModuleFieldElem ElemSegment |
+  -- | A start function index
+  ModuleFieldStart String
+  deriving (Eq, Ord, Read, Show)
+_ModuleField = Core.Name "hydra.wasm.syntax.ModuleField"
+_ModuleField_type = Core.Name "type"
+_ModuleField_func = Core.Name "func"
+_ModuleField_memory = Core.Name "memory"
+_ModuleField_table = Core.Name "table"
+_ModuleField_global = Core.Name "global"
+_ModuleField_import = Core.Name "import"
+_ModuleField_export = Core.Name "export"
+_ModuleField_data = Core.Name "data"
+_ModuleField_elem = Core.Name "elem"
+_ModuleField_start = Core.Name "start"
+-- | A WebAssembly value type
+data ValType =
+  -- | 32-bit integer
+  ValTypeI32 |
+  -- | 64-bit integer
+  ValTypeI64 |
+  -- | 32-bit float
+  ValTypeF32 |
+  -- | 64-bit float
+  ValTypeF64 |
+  -- | Function reference
+  ValTypeFuncref |
+  -- | External reference
+  ValTypeExternref
+  deriving (Eq, Ord, Read, Show)
+_ValType = Core.Name "hydra.wasm.syntax.ValType"
+_ValType_i32 = Core.Name "i32"
+_ValType_i64 = Core.Name "i64"
+_ValType_f32 = Core.Name "f32"
+_ValType_f64 = Core.Name "f64"
+_ValType_funcref = Core.Name "funcref"
+_ValType_externref = Core.Name "externref"
+-- | A function type signature
+data FuncType =
+  FuncType {
+    -- | Parameter types
+    funcTypeParams :: [ValType],
+    -- | Result types
+    funcTypeResults :: [ValType]}
+  deriving (Eq, Ord, Read, Show)
+_FuncType = Core.Name "hydra.wasm.syntax.FuncType"
+_FuncType_params = Core.Name "params"
+_FuncType_results = Core.Name "results"
+-- | A reference to a function type, either by index or inline
+data FuncTypeRef =
+  -- | Reference by type index
+  FuncTypeRefIndex String |
+  -- | Inline function type
+  FuncTypeRefInline FuncType
+  deriving (Eq, Ord, Read, Show)
+_FuncTypeRef = Core.Name "hydra.wasm.syntax.FuncTypeRef"
+_FuncTypeRef_index = Core.Name "index"
+_FuncTypeRef_inline = Core.Name "inline"
+-- | A type use clause, referencing a type definition
+data TypeUse =
+  TypeUse {
+    -- | Optional type index reference
+    typeUseIndex :: (Maybe String),
+    -- | Explicit parameter declarations (may augment or override type index)
+    typeUseParams :: [Param],
+    -- | Explicit result types
+    typeUseResults :: [ValType]}
+  deriving (Eq, Ord, Read, Show)
+_TypeUse = Core.Name "hydra.wasm.syntax.TypeUse"
+_TypeUse_index = Core.Name "index"
+_TypeUse_params = Core.Name "params"
+_TypeUse_results = Core.Name "results"
+-- | A named type definition in the type section
+data TypeDef =
+  TypeDef {
+    -- | Optional type name
+    typeDefName :: (Maybe String),
+    -- | The function type
+    typeDefType :: FuncType}
+  deriving (Eq, Ord, Read, Show)
+_TypeDef = Core.Name "hydra.wasm.syntax.TypeDef"
+_TypeDef_name = Core.Name "name"
+_TypeDef_type = Core.Name "type"
+-- | A function definition
+data Func =
+  Func {
+    -- | Optional function name
+    funcName :: (Maybe String),
+    -- | The function's type signature
+    funcTypeUse :: TypeUse,
+    -- | Local variable declarations
+    funcLocals :: [FuncLocal],
+    -- | The function body (a sequence of instructions)
+    funcBody :: [Instruction]}
+  deriving (Eq, Ord, Read, Show)
+_Func = Core.Name "hydra.wasm.syntax.Func"
+_Func_name = Core.Name "name"
+_Func_typeUse = Core.Name "typeUse"
+_Func_locals = Core.Name "locals"
+_Func_body = Core.Name "body"
+-- | A local variable declaration within a function
+data FuncLocal =
+  FuncLocal {
+    -- | Optional local name
+    funcLocalName :: (Maybe String),
+    -- | The local's value type
+    funcLocalType :: ValType}
+  deriving (Eq, Ord, Read, Show)
+_FuncLocal = Core.Name "hydra.wasm.syntax.FuncLocal"
+_FuncLocal_name = Core.Name "name"
+_FuncLocal_type = Core.Name "type"
+-- | A function parameter declaration
+data Param =
+  Param {
+    -- | Optional parameter name
+    paramName :: (Maybe String),
+    -- | The parameter's value type
+    paramType :: ValType}
+  deriving (Eq, Ord, Read, Show)
+_Param = Core.Name "hydra.wasm.syntax.Param"
+_Param_name = Core.Name "name"
+_Param_type = Core.Name "type"
+-- | Arguments for a branch table instruction
+data BrTableArgs =
+  BrTableArgs {
+    -- | Branch target labels
+    brTableArgsLabels :: [String],
+    -- | Default branch target
+    brTableArgsDefault :: String}
+  deriving (Eq, Ord, Read, Show)
+_BrTableArgs = Core.Name "hydra.wasm.syntax.BrTableArgs"
+_BrTableArgs_labels = Core.Name "labels"
+_BrTableArgs_default = Core.Name "default"
+-- | A WebAssembly instruction
+data Instruction =
+  -- | Push a constant value
+  InstructionConst ConstValue |
+  -- | Get local variable by name or index
+  InstructionLocalGet String |
+  -- | Set local variable by name or index
+  InstructionLocalSet String |
+  -- | Set local variable and keep value on stack
+  InstructionLocalTee String |
+  -- | Get global variable by name or index
+  InstructionGlobalGet String |
+  -- | Set global variable by name or index
+  InstructionGlobalSet String |
+  -- | Load from memory (e.g., i32.load, f64.load)
+  InstructionLoad MemoryInstruction |
+  -- | Store to memory (e.g., i32.store, f64.store)
+  InstructionStore MemoryInstruction |
+  -- | Unary numeric operation (e.g., i32.clz, f64.neg)
+  InstructionUnop NumericOp |
+  -- | Binary numeric operation (e.g., i32.add, f64.mul)
+  InstructionBinop NumericOp |
+  -- | Test operation (e.g., i32.eqz)
+  InstructionTestop NumericOp |
+  -- | Comparison operation (e.g., i32.eq, f64.lt)
+  InstructionRelop NumericOp |
+  -- | Type conversion (e.g., i32.wrap_i64, f64.convert_i32_s)
+  InstructionConvert String |
+  -- | Call a function by name or index
+  InstructionCall String |
+  -- | Indirect function call through a table
+  InstructionCallIndirect TypeUse |
+  -- | A block instruction
+  InstructionBlock BlockInstruction |
+  -- | A loop instruction
+  InstructionLoop BlockInstruction |
+  -- | An if-then-else instruction
+  InstructionIf IfInstruction |
+  -- | Branch to a label
+  InstructionBr String |
+  -- | Conditional branch to a label
+  InstructionBrIf String |
+  -- | Branch table
+  InstructionBrTable BrTableArgs |
+  -- | Return from the current function
+  InstructionReturn |
+  -- | Drop the top value from the stack
+  InstructionDrop |
+  -- | Select one of two values based on a condition
+  InstructionSelect |
+  -- | Trap immediately
+  InstructionUnreachable |
+  -- | No operation
+  InstructionNop |
+  -- | Get current memory size in pages
+  InstructionMemorySize |
+  -- | Grow memory by a number of pages
+  InstructionMemoryGrow |
+  -- | Null reference of the given type
+  InstructionRefNull RefType |
+  -- | Test if a reference is null
+  InstructionRefIsNull |
+  -- | A raw WAT instruction string (escape hatch)
+  InstructionRaw String
+  deriving (Eq, Ord, Read, Show)
+_Instruction = Core.Name "hydra.wasm.syntax.Instruction"
+_Instruction_const = Core.Name "const"
+_Instruction_localGet = Core.Name "localGet"
+_Instruction_localSet = Core.Name "localSet"
+_Instruction_localTee = Core.Name "localTee"
+_Instruction_globalGet = Core.Name "globalGet"
+_Instruction_globalSet = Core.Name "globalSet"
+_Instruction_load = Core.Name "load"
+_Instruction_store = Core.Name "store"
+_Instruction_unop = Core.Name "unop"
+_Instruction_binop = Core.Name "binop"
+_Instruction_testop = Core.Name "testop"
+_Instruction_relop = Core.Name "relop"
+_Instruction_convert = Core.Name "convert"
+_Instruction_call = Core.Name "call"
+_Instruction_callIndirect = Core.Name "callIndirect"
+_Instruction_block = Core.Name "block"
+_Instruction_loop = Core.Name "loop"
+_Instruction_if = Core.Name "if"
+_Instruction_br = Core.Name "br"
+_Instruction_brIf = Core.Name "brIf"
+_Instruction_brTable = Core.Name "brTable"
+_Instruction_return = Core.Name "return"
+_Instruction_drop = Core.Name "drop"
+_Instruction_select = Core.Name "select"
+_Instruction_unreachable = Core.Name "unreachable"
+_Instruction_nop = Core.Name "nop"
+_Instruction_memorySize = Core.Name "memorySize"
+_Instruction_memoryGrow = Core.Name "memoryGrow"
+_Instruction_refNull = Core.Name "refNull"
+_Instruction_refIsNull = Core.Name "refIsNull"
+_Instruction_raw = Core.Name "raw"
+-- | A block or loop instruction with a label and body
+data BlockInstruction =
+  BlockInstruction {
+    -- | Optional block label
+    blockInstructionLabel :: (Maybe String),
+    -- | The block's result type
+    blockInstructionBlockType :: BlockType,
+    -- | The instructions in the block
+    blockInstructionBody :: [Instruction]}
+  deriving (Eq, Ord, Read, Show)
+_BlockInstruction = Core.Name "hydra.wasm.syntax.BlockInstruction"
+_BlockInstruction_label = Core.Name "label"
+_BlockInstruction_blockType = Core.Name "blockType"
+_BlockInstruction_body = Core.Name "body"
+-- | The type of a block, loop, or if instruction
+data BlockType =
+  -- | No result
+  BlockTypeEmpty |
+  -- | Single result value type
+  BlockTypeValue ValType |
+  -- | Full function type signature
+  BlockTypeTypeUse TypeUse
+  deriving (Eq, Ord, Read, Show)
+_BlockType = Core.Name "hydra.wasm.syntax.BlockType"
+_BlockType_empty = Core.Name "empty"
+_BlockType_value = Core.Name "value"
+_BlockType_typeUse = Core.Name "typeUse"
+-- | Memory access arguments
+data MemArg =
+  MemArg {
+    -- | Memory offset in bytes
+    memArgOffset :: Int,
+    -- | Alignment hint (power of 2)
+    memArgAlign :: Int}
+  deriving (Eq, Ord, Read, Show)
+_MemArg = Core.Name "hydra.wasm.syntax.MemArg"
+_MemArg_offset = Core.Name "offset"
+_MemArg_align = Core.Name "align"
+-- | A memory load or store instruction
+data MemoryInstruction =
+  MemoryInstruction {
+    -- | Value type to load or store
+    memoryInstructionType :: ValType,
+    -- | Memory argument (offset and alignment)
+    memoryInstructionMemArg :: MemArg}
+  deriving (Eq, Ord, Read, Show)
+_MemoryInstruction = Core.Name "hydra.wasm.syntax.MemoryInstruction"
+_MemoryInstruction_type = Core.Name "type"
+_MemoryInstruction_memArg = Core.Name "memArg"
+-- | An if-then-else instruction
+data IfInstruction =
+  IfInstruction {
+    -- | Optional label for the if block
+    ifInstructionLabel :: (Maybe String),
+    -- | The result type of the if
+    ifInstructionBlockType :: BlockType,
+    -- | The 'then' branch instructions
+    ifInstructionThen :: [Instruction],
+    -- | The 'else' branch instructions (may be empty)
+    ifInstructionElse :: [Instruction]}
+  deriving (Eq, Ord, Read, Show)
+_IfInstruction = Core.Name "hydra.wasm.syntax.IfInstruction"
+_IfInstruction_label = Core.Name "label"
+_IfInstruction_blockType = Core.Name "blockType"
+_IfInstruction_then = Core.Name "then"
+_IfInstruction_else = Core.Name "else"
+-- | A typed numeric operation (used for unop, binop, testop, relop)
+data NumericOp =
+  NumericOp {
+    -- | Operand value type
+    numericOpType :: ValType,
+    -- | Operation name (e.g., add, sub, mul, eqz, lt_s)
+    numericOpName :: String}
+  deriving (Eq, Ord, Read, Show)
+_NumericOp = Core.Name "hydra.wasm.syntax.NumericOp"
+_NumericOp_type = Core.Name "type"
+_NumericOp_name = Core.Name "name"
+-- | A memory definition
+data MemoryDef =
+  MemoryDef {
+    -- | Optional memory name
+    memoryDefName :: (Maybe String),
+    -- | Memory size limits (in pages of 64KB)
+    memoryDefLimits :: Limits}
+  deriving (Eq, Ord, Read, Show)
+_MemoryDef = Core.Name "hydra.wasm.syntax.MemoryDef"
+_MemoryDef_name = Core.Name "name"
+_MemoryDef_limits = Core.Name "limits"
+-- | A data segment for initializing memory
+data DataSegment =
+  DataSegment {
+    -- | Optional data segment name
+    dataSegmentName :: (Maybe String),
+    -- | Whether this is an active or passive data segment
+    dataSegmentMode :: DataMode,
+    -- | The data bytes (as a string of escaped bytes)
+    dataSegmentBytes :: String}
+  deriving (Eq, Ord, Read, Show)
+_DataSegment = Core.Name "hydra.wasm.syntax.DataSegment"
+_DataSegment_name = Core.Name "name"
+_DataSegment_mode = Core.Name "mode"
+_DataSegment_bytes = Core.Name "bytes"
+-- | The mode of a data segment
+data DataMode =
+  -- | Active segment: loaded at the given offset expression
+  DataModeActive [Instruction] |
+  -- | Passive segment: must be explicitly loaded via memory.init
+  DataModePassive
+  deriving (Eq, Ord, Read, Show)
+_DataMode = Core.Name "hydra.wasm.syntax.DataMode"
+_DataMode_active = Core.Name "active"
+_DataMode_passive = Core.Name "passive"
+-- | Size limits for memories and tables
+data Limits =
+  Limits {
+    -- | Minimum size
+    limitsMin :: Int,
+    -- | Optional maximum size
+    limitsMax :: (Maybe Int)}
+  deriving (Eq, Ord, Read, Show)
+_Limits = Core.Name "hydra.wasm.syntax.Limits"
+_Limits_min = Core.Name "min"
+_Limits_max = Core.Name "max"
+-- | A global variable definition
+data GlobalDef =
+  GlobalDef {
+    -- | Optional global name
+    globalDefName :: (Maybe String),
+    -- | The global's type (value type and mutability)
+    globalDefType :: GlobalType,
+    -- | Initialization expression
+    globalDefInit :: [Instruction]}
+  deriving (Eq, Ord, Read, Show)
+_GlobalDef = Core.Name "hydra.wasm.syntax.GlobalDef"
+_GlobalDef_name = Core.Name "name"
+_GlobalDef_type = Core.Name "type"
+_GlobalDef_init = Core.Name "init"
+-- | A global variable type
+data GlobalType =
+  GlobalType {
+    -- | The value type
+    globalTypeValType :: ValType,
+    -- | Whether the global is mutable
+    globalTypeMutable :: Bool}
+  deriving (Eq, Ord, Read, Show)
+_GlobalType = Core.Name "hydra.wasm.syntax.GlobalType"
+_GlobalType_valType = Core.Name "valType"
+_GlobalType_mutable = Core.Name "mutable"
+-- | A table definition
+data TableDef =
+  TableDef {
+    -- | Optional table name
+    tableDefName :: (Maybe String),
+    -- | The reference type of table elements
+    tableDefRefType :: RefType,
+    -- | Table size limits
+    tableDefLimits :: Limits}
+  deriving (Eq, Ord, Read, Show)
+_TableDef = Core.Name "hydra.wasm.syntax.TableDef"
+_TableDef_name = Core.Name "name"
+_TableDef_refType = Core.Name "refType"
+_TableDef_limits = Core.Name "limits"
+-- | Active element segment parameters
+data ElemActive =
+  ElemActive {
+    -- | Table index
+    elemActiveTable :: String,
+    -- | Offset expression
+    elemActiveOffset :: [Instruction]}
+  deriving (Eq, Ord, Read, Show)
+_ElemActive = Core.Name "hydra.wasm.syntax.ElemActive"
+_ElemActive_table = Core.Name "table"
+_ElemActive_offset = Core.Name "offset"
+-- | An element segment for initializing tables
+data ElemSegment =
+  ElemSegment {
+    -- | Optional element segment name
+    elemSegmentName :: (Maybe String),
+    -- | Whether this is an active or passive element segment
+    elemSegmentMode :: ElemMode,
+    -- | The reference type of elements
+    elemSegmentType :: RefType,
+    -- | Initialization expressions (one per element)
+    elemSegmentInit :: [[Instruction]]}
+  deriving (Eq, Ord, Read, Show)
+_ElemSegment = Core.Name "hydra.wasm.syntax.ElemSegment"
+_ElemSegment_name = Core.Name "name"
+_ElemSegment_mode = Core.Name "mode"
+_ElemSegment_type = Core.Name "type"
+_ElemSegment_init = Core.Name "init"
+-- | The mode of an element segment
+data ElemMode =
+  -- | Active segment: loaded at the given table index and offset
+  ElemModeActive ElemActive |
+  -- | Passive segment: must be explicitly loaded via table.init
+  ElemModePassive |
+  -- | Declarative segment: declares function references for ref.func
+  ElemModeDeclarative
+  deriving (Eq, Ord, Read, Show)
+_ElemMode = Core.Name "hydra.wasm.syntax.ElemMode"
+_ElemMode_active = Core.Name "active"
+_ElemMode_passive = Core.Name "passive"
+_ElemMode_declarative = Core.Name "declarative"
+-- | A reference type for tables and reference instructions
+data RefType =
+  -- | Function reference
+  RefTypeFuncref |
+  -- | External reference
+  RefTypeExternref
+  deriving (Eq, Ord, Read, Show)
+_RefType = Core.Name "hydra.wasm.syntax.RefType"
+_RefType_funcref = Core.Name "funcref"
+_RefType_externref = Core.Name "externref"
+-- | An import declaration
+data ImportDef =
+  ImportDef {
+    -- | The module name to import from
+    importDefModule :: String,
+    -- | The name of the imported entity
+    importDefName :: String,
+    -- | The import descriptor (what kind of entity is imported)
+    importDefDesc :: ImportDesc}
+  deriving (Eq, Ord, Read, Show)
+_ImportDef = Core.Name "hydra.wasm.syntax.ImportDef"
+_ImportDef_module = Core.Name "module"
+_ImportDef_name = Core.Name "name"
+_ImportDef_desc = Core.Name "desc"
+-- | An import descriptor specifying the kind of imported entity
+data ImportDesc =
+  -- | Import a function with the given type
+  ImportDescFunc ImportFunc |
+  -- | Import a memory with the given limits
+  ImportDescMemory ImportMemory |
+  -- | Import a table
+  ImportDescTable ImportTable |
+  -- | Import a global variable
+  ImportDescGlobal ImportGlobal
+  deriving (Eq, Ord, Read, Show)
+_ImportDesc = Core.Name "hydra.wasm.syntax.ImportDesc"
+_ImportDesc_func = Core.Name "func"
+_ImportDesc_memory = Core.Name "memory"
+_ImportDesc_table = Core.Name "table"
+_ImportDesc_global = Core.Name "global"
+-- | A function import descriptor
+data ImportFunc =
+  ImportFunc {
+    -- | Optional local name for the imported function
+    importFuncName :: (Maybe String),
+    -- | The function's type
+    importFuncTypeUse :: TypeUse}
+  deriving (Eq, Ord, Read, Show)
+_ImportFunc = Core.Name "hydra.wasm.syntax.ImportFunc"
+_ImportFunc_name = Core.Name "name"
+_ImportFunc_typeUse = Core.Name "typeUse"
+-- | A global import descriptor
+data ImportGlobal =
+  ImportGlobal {
+    -- | Optional local name
+    importGlobalName :: (Maybe String),
+    -- | Global type
+    importGlobalType :: GlobalType}
+  deriving (Eq, Ord, Read, Show)
+_ImportGlobal = Core.Name "hydra.wasm.syntax.ImportGlobal"
+_ImportGlobal_name = Core.Name "name"
+_ImportGlobal_type = Core.Name "type"
+-- | A memory import descriptor
+data ImportMemory =
+  ImportMemory {
+    -- | Optional local name
+    importMemoryName :: (Maybe String),
+    -- | Memory limits
+    importMemoryLimits :: Limits}
+  deriving (Eq, Ord, Read, Show)
+_ImportMemory = Core.Name "hydra.wasm.syntax.ImportMemory"
+_ImportMemory_name = Core.Name "name"
+_ImportMemory_limits = Core.Name "limits"
+-- | A table import descriptor
+data ImportTable =
+  ImportTable {
+    -- | Optional local name
+    importTableName :: (Maybe String),
+    -- | Reference type
+    importTableRefType :: RefType,
+    -- | Table limits
+    importTableLimits :: Limits}
+  deriving (Eq, Ord, Read, Show)
+_ImportTable = Core.Name "hydra.wasm.syntax.ImportTable"
+_ImportTable_name = Core.Name "name"
+_ImportTable_refType = Core.Name "refType"
+_ImportTable_limits = Core.Name "limits"
+-- | An export declaration
+data ExportDef =
+  ExportDef {
+    -- | The exported name
+    exportDefName :: String,
+    -- | What is being exported
+    exportDefDesc :: ExportDesc}
+  deriving (Eq, Ord, Read, Show)
+_ExportDef = Core.Name "hydra.wasm.syntax.ExportDef"
+_ExportDef_name = Core.Name "name"
+_ExportDef_desc = Core.Name "desc"
+-- | An export descriptor identifying what is being exported
+data ExportDesc =
+  -- | Export a function by name or index
+  ExportDescFunc String |
+  -- | Export a memory by name or index
+  ExportDescMemory String |
+  -- | Export a table by name or index
+  ExportDescTable String |
+  -- | Export a global by name or index
+  ExportDescGlobal String
+  deriving (Eq, Ord, Read, Show)
+_ExportDesc = Core.Name "hydra.wasm.syntax.ExportDesc"
+_ExportDesc_func = Core.Name "func"
+_ExportDesc_memory = Core.Name "memory"
+_ExportDesc_table = Core.Name "table"
+_ExportDesc_global = Core.Name "global"
+-- | A constant value instruction
+data ConstValue =
+  -- | A 32-bit integer constant
+  ConstValueI32 Int |
+  -- | A 64-bit integer constant
+  ConstValueI64 I.Int64 |
+  -- | A 32-bit float constant
+  ConstValueF32 Float |
+  -- | A 64-bit float constant
+  ConstValueF64 Double
+  deriving (Eq, Ord, Read, Show)
+_ConstValue = Core.Name "hydra.wasm.syntax.ConstValue"
+_ConstValue_i32 = Core.Name "i32"
+_ConstValue_i64 = Core.Name "i64"
+_ConstValue_f32 = Core.Name "f32"
+_ConstValue_f64 = Core.Name "f64"
