# Release notes

This page is rendered from the repository `CHANGELOG.md`, which release-please writes from the conventional-commit type of every squashed pull request. Releases are newest first. The 6 most recent releases are here in full; the whole history is in [CHANGELOG.md](https://github.com/AmbiqAI/helia-aot/blob/cf2246a7ad439fa38d57462118e7840e5497a685/CHANGELOG.md).

## Unreleased — Tensor Packaging (breaking)

This branch consolidates per-tensor placement under a single
`memory.tensors:` rule surface and reshapes the runtime contract for
caller-supplied arenas. Two YAML keys and several C-side symbols are
**removed**; downstream consumers should migrate before upgrading.

### Removed YAML keys

`MemoryArgs` now rejects these legacy keys with an actionable error
naming the new equivalent:

- `memory.persistent_storage` → use a per-tensor rule under
  `memory.tensors`, e.g.
  ```yaml
  memory:
    tensors:
      - type: persistent
        memory: SRAM
  ```
- `memory.constant_residency` → use per-tensor rules under
  `memory.tensors` with `memory:` (source) and optional
  `constant_destination_memory:` (staged runtime memory).

### Generated C-API changes (all build modes)

- Removed: per-tensor `<prefix>_tensor_<name>_size` macros (e.g.
  `<prefix>_tensor_0_size`, `<prefix>_tensor_<op>_<role>_size`).
  Per-tensor byte size now lives on the descriptor at
  `<prefix>_tensor_descriptors[i].size`. Public `_size` macros are
  still emitted for model **inputs/outputs**, where they are part
  of the stable I/O API.
- Changed: `<prefix>_tensor_descriptor_t` no longer carries a
  `data_ptr` field. Every tensor (constant, persistent, or
  scratch) is bound to an arena slot; the kernel-visible address
  is `<prefix>_arena_buffers[descriptor.region] + descriptor.offset`.
  Downstream code that read `descriptor.data_ptr` directly must
  switch to that formula.

### Generated C-API changes (`memory.allocate_arenas: false`)

- `<prefix>_bind_arena(region, buffer, size)` — bind state is
  module-global; no `ctx` pointer parameter.
- `<prefix>_bind_arenas(buffers, sizes, n)` — same; `n` must equal
  `<prefix>_num_arena_buffers`.
- Removed: `<prefix>_arena_table_entry_t`,
  `<prefix>_arena_buffers_table_count`. Use
  `<prefix>_arena_sizes[<prefix>_num_arena_buffers]` for per-region
  capacity introspection.
- `<prefix>_hydrate_constants(ctx)` now takes a non-`const`
  `<prefix>_model_context_t *`.
- Every region must be bound **before** `<prefix>_model_init`, which
  internally invokes `<prefix>_context_init` and returns non-zero if
  any region is unbound.

### New / renamed knobs

- `memory.auto_hydrate_constants` — **deprecated, runtime no-op.**
  `<prefix>_model_init` now always invokes
  `<prefix>_hydrate_constants` between `<prefix>_context_init` and
  the operator init loop, regardless of this flag. This closes a
  race where an operator's `_init` hook could read constants
  (e.g. `arm_convolve_weight_sum` reading weights) before manual
  hydration was driven by the application. The flag is retained
  for backwards compatibility with existing YAML configs but no
  longer changes generated runtime behavior. Callers that need a
  custom hydration mechanism (DMA, async pre-stage, decompression,
  model swap) override the weak `<prefix>_hydrate_constants`
  symbol — `model_init` invokes the override at the same fixed
  point. The default helper is idempotent so pre-hydrating from
  the caller before `model_init` is safe. Setting the flag to
  `false` emits a soft `WARNING` at convert time so users still
  toggling the legacy YAML knob know the runtime no longer
  honors it.
  `<prefix>_model_run` returns status `200` only as a
  defense-in-depth check (e.g. when `<prefix>_clear_hydrated()`
  was called after a successful `model_init` without re-running
  it). The latch is observable via `<prefix>_is_hydrated()` and
  resettable via `<prefix>_clear_hydrated()` (also called
  automatically by every `context_init`).
- `<prefix>_bind_arena()` now rejects misaligned caller buffers
  with status `4`. The required alignment is exposed at
  `<prefix>_arena_alignments[<prefix>_num_arena_buffers]`
  (power-of-two per region, matches the `alignas(...)` applied to
  internal-arena builds).
- `memory.dump_residency_json` (default `false`) writes
  `<prefix>_residency.json` with `schema_version: 3` (top-level
  `plan_hash`, top-level `tensor_layout_hash`, per-arena
  `region_id`). The two hashes have disjoint scope:
  `plan_hash` fingerprints the **arena envelope** only (per-region
  role / memory / source_memory / size / alignment / is_staged)
  and mirrors the generated `<PREFIX>_PLAN_HASH` C macro for
  arena-ABI drift detection across separately-compiled binaries;
  `tensor_layout_hash` fingerprints **per-tensor placement**
  (tensor_id / role / memory / offset / size) and captures drift
  the envelope hash misses (two tensors swapping offsets inside
  the same arena, a tensor migrating between arenas of identical
  shape, etc.). Honors `--force` for overwrites.

See [tensor-packaging how-to](https://ambiqai.github.io/helia-aot/guide/memory-placement/) for a
worked migration.

### Type checking is now a blocking gate

`ty` runs at its default rule severities and blocks the commit, and CI,
on any error-level diagnostic; no rule is demoted and a unit test pins
the warning count at zero. Clearing the backlog changed a few observable
behaviors:

- `AirInterpreter.set_input` and `AirInterpreter.get_output` are
  **keyword-only**. In-tree callers already passed `key=`/`wrap=`, but an
  external caller doing `get_output(0)` must add the keyword.
- `AirTensor.shape`, `.dtype` and `.ctype` raise `ValueError` when the
  value is unset or the dtype has no C mapping, instead of returning
  `None`. `.ctype` previously let a `None` reach the templates, where it
  rendered as the literal `None` in generated C.
- `AirTensor.quant` and `AirQuantizationParameters.scales` /
  `.zero_points` are the checked way to read quantization; they raise a
  `ValueError` naming the tensor when it carries none.
- `AotOperator.typed_options()` checks the operator's options against its
  concrete `AirXxxOptions` class and raises `TypeError` on a mismatch.
- Reading a LiteRT flatbuffer field that the object API left unset now
  raises a `ValueError` naming the field rather than failing later on
  `None`.
- `compute_tensor_ctype` rejects `STRING` tensors instead of returning a
  `-1` sentinel.
- The test floor moved to `pytest>=9.1.1`; pytest 8's `skip`/`fail`
  wrappers are not statically analyzable.

## [0.24.0](https://github.com/AmbiqAI/helia-aot/compare/v0.23.0...v0.24.0) (2026-09-29)

### Features

* add a knob registry and split the optimization plan and report ([#521](https://github.com/AmbiqAI/helia-aot/issues/521)) ([c7dba00](https://github.com/AmbiqAI/helia-aot/commit/c7dba008fa26ff1717bb89322144b6cbe996d1da)), closes [#517](https://github.com/AmbiqAI/helia-aot/issues/517)
* add the optimization section, the accumulation knob and a per-layer optimization plan ([#516](https://github.com/AmbiqAI/helia-aot/issues/516)) ([57a80e7](https://github.com/AmbiqAI/helia-aot/commit/57a80e7c243ccd3ae365c7e6cb22780c59eb80e7)), closes [#513](https://github.com/AmbiqAI/helia-aot/issues/513)
* emit NT_N_PACKED weights for float 1x1 convolution and fully connected ([#508](https://github.com/AmbiqAI/helia-aot/issues/508)) ([e119e23](https://github.com/AmbiqAI/helia-aot/commit/e119e233e06ac0b894d42428c2817926e1911157)), closes [#507](https://github.com/AmbiqAI/helia-aot/issues/507)

### Bug Fixes

* bump the docs reference exports with each release ([#505](https://github.com/AmbiqAI/helia-aot/issues/505)) ([58c2aac](https://github.com/AmbiqAI/helia-aot/commit/58c2aac4fad94359341a6b31189c5c57700e4d26)), closes [#504](https://github.com/AmbiqAI/helia-aot/issues/504)
* infer reduction shapes from explicit AIR metadata ([#509](https://github.com/AmbiqAI/helia-aot/issues/509)) ([d62223e](https://github.com/AmbiqAI/helia-aot/commit/d62223e10140a29d891e5855bfd1cff515c1a399)), closes [#479](https://github.com/AmbiqAI/helia-aot/issues/479)
* keep the docs exports stable under release-please's version bump ([#526](https://github.com/AmbiqAI/helia-aot/issues/526)) ([1a0874f](https://github.com/AmbiqAI/helia-aot/commit/1a0874f4662c401ba2366cd78646f3c7f12ffa17)), closes [#525](https://github.com/AmbiqAI/helia-aot/issues/525)
* restore neutral active top navigation ([#514](https://github.com/AmbiqAI/helia-aot/issues/514)) ([8d861db](https://github.com/AmbiqAI/helia-aot/commit/8d861db4bca8754393cc2bcd6d89de497497a4a9))

### Documentation

* migrate site navigation, guides and reference content ([#473](https://github.com/AmbiqAI/helia-aot/issues/473)) ([f1a3ea6](https://github.com/AmbiqAI/helia-aot/commit/f1a3ea697ebc1a62937cbfb66cca7a6215a02935))
* polish AOT hero and product navigation ([#518](https://github.com/AmbiqAI/helia-aot/issues/518)) ([70e3edc](https://github.com/AmbiqAI/helia-aot/commit/70e3edc931ccc379ccd02cfa5982c922a5bd5668))

## [0.23.0](https://github.com/AmbiqAI/helia-aot/compare/v0.22.0...v0.23.0) (2026-09-26)

### ⚠ BREAKING CHANGES

* generated modules, integer-only ones included, no longer build against ns-cmsis-nn v7.32.x to v7.34.x.

### Features

* add greedy-by-size and hill-climb experimental memory planners ([#359](https://github.com/AmbiqAI/helia-aot/issues/359)) ([6ac4d16](https://github.com/AmbiqAI/helia-aot/commit/6ac4d169d0580f1d70c23e7b39100fa73f58c938))
* declare the public Python API with __all__ and an API manifest ([d2661c3](https://github.com/AmbiqAI/helia-aot/commit/d2661c30c760dfe150a83cb6ddf7a479ef919d41)), closes [#455](https://github.com/AmbiqAI/helia-aot/issues/455)
* dispatch float PACK, UNPACK and SPLIT to native ns-cmsis-nn kernels ([#429](https://github.com/AmbiqAI/helia-aot/issues/429)) ([20f407b](https://github.com/AmbiqAI/helia-aot/commit/20f407b9d26976b77750e1834fe3340438713749))
* export the configuration, CLI, target, error and module-layout reference data ([b252649](https://github.com/AmbiqAI/helia-aot/commit/b252649c64dedb71ff4708415b5dbff4115cc31a))
* place operator code in ITCM and document ITCM tensor placement ([#493](https://github.com/AmbiqAI/helia-aot/issues/493)) ([849b4ab](https://github.com/AmbiqAI/helia-aot/commit/849b4ab516066007050b62ba5e649f0270fd7b56))
* resolve shape expressions in the shape propagation fixed point ([#476](https://github.com/AmbiqAI/helia-aot/issues/476)) ([e537d29](https://github.com/AmbiqAI/helia-aot/commit/e537d293c8658491160138075837460c8e307fa6))
* route 1D dilated depthwise conv to the optimized ns-cmsis-nn kernels ([#503](https://github.com/AmbiqAI/helia-aot/issues/503)) ([49a5ee4](https://github.com/AmbiqAI/helia-aot/commit/49a5ee423b309ef3b586c5e1ae84c33ac219c213)), closes [#502](https://github.com/AmbiqAI/helia-aot/issues/502)
* support FP16 and FP32 nearest-neighbor resize ([#404](https://github.com/AmbiqAI/helia-aot/issues/404)) ([191bed4](https://github.com/AmbiqAI/helia-aot/commit/191bed48b6703327e19aee27722f00c80de92b4c))

### Bug Fixes

* accept JSON values for structured list flags ([#484](https://github.com/AmbiqAI/helia-aot/issues/484)) ([0c5a6f0](https://github.com/AmbiqAI/helia-aot/commit/0c5a6f051dcffc05c94f8f77f43f5e85bd8af8e9)), closes [#481](https://github.com/AmbiqAI/helia-aot/issues/481)
* accept scalar reduce axes and honor keepDims for integer extrema ([#446](https://github.com/AmbiqAI/helia-aot/issues/446)) ([fa0a562](https://github.com/AmbiqAI/helia-aot/commit/fa0a56237b9868e6ce2f397ec7e726945d2932ab))
* carry SUM keepDims and require the exact output shape ([#475](https://github.com/AmbiqAI/helia-aot/issues/475)) ([6217d3e](https://github.com/AmbiqAI/helia-aot/commit/6217d3eb4784a18e8061191e4c938ac258f92b19))
* drop the obsolete MAX/MIN/CLAMP undef prologue from the Zephyr test case ([#478](https://github.com/AmbiqAI/helia-aot/issues/478)) ([fd074a4](https://github.com/AmbiqAI/helia-aot/commit/fd074a4ec1e5047443e3f12e2cf31c8c2b9f92af)), closes [#305](https://github.com/AmbiqAI/helia-aot/issues/305)
* fail fast on out-of-range tensor dims in the buffer sizers ([#477](https://github.com/AmbiqAI/helia-aot/issues/477)) ([2db5429](https://github.com/AmbiqAI/helia-aot/commit/2db5429e908efab1cdd56a0fe80a09d54a350f0c))
* infer dynamic shapes and fold static shape expressions ([#439](https://github.com/AmbiqAI/helia-aot/issues/439)) ([81f0076](https://github.com/AmbiqAI/helia-aot/commit/81f007668082a6e89ce169fb85d4f3f3505f49bd))
* keep emitted operator sources clean under -Wunused-parameter ([#491](https://github.com/AmbiqAI/helia-aot/issues/491)) ([ddeebcd](https://github.com/AmbiqAI/helia-aot/commit/ddeebcd52c1f459df06ccbb4e65915e370f1bc64)), closes [#406](https://github.com/AmbiqAI/helia-aot/issues/406)
* match attribute rule types case-insensitively ([#482](https://github.com/AmbiqAI/helia-aot/issues/482)) ([8077a0d](https://github.com/AmbiqAI/helia-aot/commit/8077a0d060c0d097de5cb6676023db983c128517)), closes [#474](https://github.com/AmbiqAI/helia-aot/issues/474)
* preserve INT16 hard swish prescale precision ([#468](https://github.com/AmbiqAI/helia-aot/issues/468)) ([ec917d1](https://github.com/AmbiqAI/helia-aot/commit/ec917d1de4e565a8a1443652e11f4de6df9d580d))
* preserve INT8 HARD_SWISH precision when deriving prescale ([d68e851](https://github.com/AmbiqAI/helia-aot/commit/d68e851e986ed3732095fe6de6862a3767377042))
* raise on undefined template references during codegen ([#423](https://github.com/AmbiqAI/helia-aot/issues/423)) ([494aa30](https://github.com/AmbiqAI/helia-aot/commit/494aa30068df50628ac5c94e3bc01ad18a21edf4))
* remove the conversion work directory when the conversion ends ([#483](https://github.com/AmbiqAI/helia-aot/issues/483)) ([2a9be27](https://github.com/AmbiqAI/helia-aot/commit/2a9be277dbaff00efff52cc4fb5ec815e41cd85d)), closes [#467](https://github.com/AmbiqAI/helia-aot/issues/467)
* require ns-cmsis-nn v7.35.0 for every generated module ([#498](https://github.com/AmbiqAI/helia-aot/issues/498)) ([76e6961](https://github.com/AmbiqAI/helia-aot/commit/76e69615c8a20146d886bcac4e685a70afa1ff23)), closes [#496](https://github.com/AmbiqAI/helia-aot/issues/496)
* scan registry discovery namespaces to a fixed point ([#489](https://github.com/AmbiqAI/helia-aot/issues/489)) ([9eaecda](https://github.com/AmbiqAI/helia-aot/commit/9eaecda75b356ea9671a5698e8ed65d0af88d214)), closes [#488](https://github.com/AmbiqAI/helia-aot/issues/488)
* tidy conversion edge cases around memory constraints, work dirs and golden data ([#495](https://github.com/AmbiqAI/helia-aot/issues/495)) ([ba3acc8](https://github.com/AmbiqAI/helia-aot/commit/ba3acc844fd1a0e447e944f2493f52a4e0cc4202)), closes [#485](https://github.com/AmbiqAI/helia-aot/issues/485) [#486](https://github.com/AmbiqAI/helia-aot/issues/486) [#487](https://github.com/AmbiqAI/helia-aot/issues/487) [#490](https://github.com/AmbiqAI/helia-aot/issues/490)
* warn when SVDF per-channel quantization is ignored ([#494](https://github.com/AmbiqAI/helia-aot/issues/494)) ([8502692](https://github.com/AmbiqAI/helia-aot/commit/8502692a2b83044d871ac88964bd22baf2f967b1)), closes [#329](https://github.com/AmbiqAI/helia-aot/issues/329)

### Documentation

* consolidate strict template contract guidance ([798a475](https://github.com/AmbiqAI/helia-aot/commit/798a4754197ceac6e75dfebb9af7fd3dfbc37685))
* generate the Python, configuration, CLI, target and module reference ([21e2068](https://github.com/AmbiqAI/helia-aot/commit/21e206893145e13f4ebd83db0f0b8bd0bf117f90))
* scaffold the Astro site in docs/ and relocate MkDocs sources to mkdocs/ ([6f55939](https://github.com/AmbiqAI/helia-aot/commit/6f55939177420046cfc07b0ff01810956fafa0d4)), closes [#454](https://github.com/AmbiqAI/helia-aot/issues/454)

## [0.22.0](https://github.com/AmbiqAI/helia-aot/compare/v0.21.0...v0.22.0) (2026-09-15)

### Features

* add explicit input and output byte-count macros ([#426](https://github.com/AmbiqAI/helia-aot/issues/426)) ([c0926c3](https://github.com/AmbiqAI/helia-aot/commit/c0926c3fe3d06ace28efbb81af6235b8662ca555))
* add native float argmin and argmax support ([bf0fd47](https://github.com/AmbiqAI/helia-aot/commit/bf0fd47d33077150b34251fa60eccbd3d26c850f))
* add native float gather and extrema support ([d5cb054](https://github.com/AmbiqAI/helia-aot/commit/d5cb05462d360cf53549c86e5c63ba2bd9c07200))
* adopt native FP16 and FP32 RSQRT kernels ([#425](https://github.com/AmbiqAI/helia-aot/issues/425)) ([ce6c433](https://github.com/AmbiqAI/helia-aot/commit/ce6c4335af43046115fe4b72a20b47dcc9a9695a))
* adopt native FP16 SQRT from CORE 7.33 ([#421](https://github.com/AmbiqAI/helia-aot/issues/421)) ([83c9f3d](https://github.com/AmbiqAI/helia-aot/commit/83c9f3de5548b470f85fdf8eaaea6a7c1417c651))
* lower non-scalar float SUB broadcasts to native kernels ([0820177](https://github.com/AmbiqAI/helia-aot/commit/0820177a173aa63eae9ca1bfed3189d7d4c028d4))
* support native float HARD_SWISH ([#410](https://github.com/AmbiqAI/helia-aot/issues/410)) ([20ea2ce](https://github.com/AmbiqAI/helia-aot/commit/20ea2cef3ba925806d8e93608500a2c9ac24b6b3))

### Bug Fixes

* declare FP16 utility type dependencies ([#422](https://github.com/AmbiqAI/helia-aot/issues/422)) ([958432e](https://github.com/AmbiqAI/helia-aot/commit/958432e22f27a8d43cec9eceec9e03bb3c00033d))
* expand per-tensor convolution quantization to every output channel ([#411](https://github.com/AmbiqAI/helia-aot/issues/411)) ([1375535](https://github.com/AmbiqAI/helia-aot/commit/1375535ba11b46962a3443949608980dd1e0a2a0))
* finish typed parser errors and quantization hints ([8d65c66](https://github.com/AmbiqAI/helia-aot/commit/8d65c6644ea699ba604025c72d2e75887fe878f2))
* honor precise float requirements in CMake and NSX ([e546fc7](https://github.com/AmbiqAI/helia-aot/commit/e546fc707ff1d0c4bfdc90b833f992abfd598951))
* isolate generated layer parameters across model modules ([#408](https://github.com/AmbiqAI/helia-aot/issues/408)) ([6140aff](https://github.com/AmbiqAI/helia-aot/commit/6140aff10da0065efee96f33ca355becdf0a3089))
* preserve integer mean logical output shapes ([edd88be](https://github.com/AmbiqAI/helia-aot/commit/edd88bee87a0fa9d4e62f8f063d9bbdfed8ec61b))
* reject incompatible integer fully connected filters ([a37f767](https://github.com/AmbiqAI/helia-aot/commit/a37f76737d7234a1d4099b83afac1c5220e35ed7))
* reject int16 FULLY_CONNECTED filters no int16 kernel can honour ([#418](https://github.com/AmbiqAI/helia-aot/issues/418)) ([3c35331](https://github.com/AmbiqAI/helia-aot/commit/3c3533185484309fbcde49b6b1d89c4f979609fd))
* reject invalid concatenation axes before code generation ([9ea546a](https://github.com/AmbiqAI/helia-aot/commit/9ea546a0d52e0bc8b443673ed46e3be498141ba4))

## [0.21.0](https://github.com/AmbiqAI/helia-aot/compare/v0.20.0...v0.21.0) (2026-09-08)

### Features

* lower native float MEAN and broadcast MUL ([19d4d34](https://github.com/AmbiqAI/helia-aot/commit/19d4d34f59ccc67ed3e51d8685867fc9f333029a))
* lower native float MEAN and broadcast MUL ([19d4d34](https://github.com/AmbiqAI/helia-aot/commit/19d4d34f59ccc67ed3e51d8685867fc9f333029a))

### Bug Fixes

* preserve scalar constant rank when parsing LiteRT models ([#402](https://github.com/AmbiqAI/helia-aot/issues/402)) ([54e4217](https://github.com/AmbiqAI/helia-aot/commit/54e4217075f92f18c3f7ef61c5e9bd09e3d03133))

## [0.20.0](https://github.com/AmbiqAI/helia-aot/compare/v0.19.0...v0.20.0) (2026-09-07)

### ⚠ BREAKING CHANGES

* generated modules require ns-cmsis-nn v7.32.0 or newer; the generated common header fails to compile against older releases.

### Features

* accept float16/float32 in SQUEEZE, FILL, ZEROS_LIKE, and DILATE with an operator-named dtype error ([#353](https://github.com/AmbiqAI/helia-aot/issues/353)) ([3520a96](https://github.com/AmbiqAI/helia-aot/commit/3520a9676899d55a028d0c1109c6ed71f8b4215f))
* add float16 rolled and unrolled GRU support ([4c3e974](https://github.com/AmbiqAI/helia-aot/commit/4c3e9746d531c9268d4ddff133bf230d448e9786))
* **e2e:** report passing tolerance margins ([#333](https://github.com/AmbiqAI/helia-aot/issues/333)) ([259c763](https://github.com/AmbiqAI/helia-aot/commit/259c76375a55e54bb474f2e569967937fdbc47f0))
* wire float16/float32 SUB, STRIDED_SLICE, SLICE, and float16 SPLIT to the ns-cmsis-nn float kernels ([#352](https://github.com/AmbiqAI/helia-aot/issues/352)) ([d15ac41](https://github.com/AmbiqAI/helia-aot/commit/d15ac41fa86303f8fbc6c6983ab5d505c16b9eb6))

### Bug Fixes

* align generated code with ns-cmsis-nn 7.32.0 contracts ([#386](https://github.com/AmbiqAI/helia-aot/issues/386)) ([edc5176](https://github.com/AmbiqAI/helia-aot/commit/edc51765f4a96ec5d1013ddf36b8a5906c459b1e))
* avoid shared operator attribute defaults ([f42a245](https://github.com/AmbiqAI/helia-aot/commit/f42a24587047fcf6b46c022a9ba79d9ae27e3ef8))
* declare FP16 on every Cortex-M55 target so list-targets matches the supports_fp16 gate ([#351](https://github.com/AmbiqAI/helia-aot/issues/351)) ([bc2a2ea](https://github.com/AmbiqAI/helia-aot/commit/bc2a2ea4aa607e0e752644e9725f3e38667a30e6))
* **e2e:** migrate to CMSIS 6 and Cortex DFP ([#332](https://github.com/AmbiqAI/helia-aot/issues/332)) ([a10be71](https://github.com/AmbiqAI/helia-aot/commit/a10be711a1b71db183174aac80ed246086ffd07b))
* keep config-derived custom platforms run-local instead of registering them globally ([#334](https://github.com/AmbiqAI/helia-aot/issues/334)) ([188660b](https://github.com/AmbiqAI/helia-aot/commit/188660bf1451cd110171622782f6270ef9af4d56))
* pin ns-cmsis-nn at v7.32.0 and size the float depthwise scratch like its sizer ([#394](https://github.com/AmbiqAI/helia-aot/issues/394)) ([e2e10f7](https://github.com/AmbiqAI/helia-aot/commit/e2e10f783323081b50e2b375809822edfeb761ea))
* raise ConfigValueError with a hint for every user-facing operator validation failure ([#400](https://github.com/AmbiqAI/helia-aot/issues/400)) ([b2bb81e](https://github.com/AmbiqAI/helia-aot/commit/b2bb81e64d8d49f840ea748721f1352a977aaff6))
* reject float16 and float32 on the six operators ns-cmsis-nn ships integer kernels for ([#396](https://github.com/AmbiqAI/helia-aot/issues/396)) ([14227a8](https://github.com/AmbiqAI/helia-aot/commit/14227a8ae883caa8f244cea61b33f78f0702e82b))
* report aot_tensor_io_t.size in bytes for non-int8 I/O tensors ([#380](https://github.com/AmbiqAI/helia-aot/issues/380)) ([9726d4e](https://github.com/AmbiqAI/helia-aot/commit/9726d4ef2e76b762a6effba9fed8ce6afcaa495d))

## [0.19.0](https://github.com/AmbiqAI/helia-aot/compare/v0.18.0...v0.19.0) (2026-09-02)

### ⚠ BREAKING CHANGES

* the `at110` platform name is now `atomiq110`; `--platform.name at110` no longer resolves. `at110` shipped in v0.18.0, but Atomiq is not in production and nothing downstream has pinned the name yet.

### Features

* add atomiq110 board support and gate Ethos-U dispatch on NPU capability ([#276](https://github.com/AmbiqAI/helia-aot/issues/276)) ([8cee4b5](https://github.com/AmbiqAI/helia-aot/commit/8cee4b56ac5c690675b938b3d6d92ff43709c37c))
* add broadcast_to op support ([bc539f2](https://github.com/AmbiqAI/helia-aot/commit/bc539f233b670905e2ea3e0ad5c6d8ca4835f4c2))
* add broadcast_to op support ([bc539f2](https://github.com/AmbiqAI/helia-aot/commit/bc539f233b670905e2ea3e0ad5c6d8ca4835f4c2))
* add dynamic_update_slice op support ([13980ed](https://github.com/AmbiqAI/helia-aot/commit/13980ed65489686df6d64ae24a64caa8b20588dc))
* add dynamic_update_slice op support ([13980ed](https://github.com/AmbiqAI/helia-aot/commit/13980ed65489686df6d64ae24a64caa8b20588dc))
* add mirror_pad op support ([b46bb4b](https://github.com/AmbiqAI/helia-aot/commit/b46bb4ba01aacee1e12340fcb14690619586bc79))
* add mirror_pad op support ([b46bb4b](https://github.com/AmbiqAI/helia-aot/commit/b46bb4ba01aacee1e12340fcb14690619586bc79))
* add RESIZE_BILINEAR and DILATE operators for int8/int16x8 ([f052d51](https://github.com/AmbiqAI/helia-aot/commit/f052d51ea6e312a3307f891c7f148c6c4e21c318))
* add reverse_sequence op support ([68e2d6b](https://github.com/AmbiqAI/helia-aot/commit/68e2d6b618f8a27216232f6b00753a608bdcee06))
* add reverse_sequence op support ([68e2d6b](https://github.com/AmbiqAI/helia-aot/commit/68e2d6b618f8a27216232f6b00753a608bdcee06))
* add scatter_nd op support ([70b9e40](https://github.com/AmbiqAI/helia-aot/commit/70b9e4020ae9ff2fb43edcbf96f0591620b0924b))
* add scatter_nd op support ([70b9e40](https://github.com/AmbiqAI/helia-aot/commit/70b9e4020ae9ff2fb43edcbf96f0591620b0924b))
* add select_v2 op support ([c9ad0eb](https://github.com/AmbiqAI/helia-aot/commit/c9ad0eb29f12fc829574f1904b8c0c86ee75fb5b))
* add select_v2 op support ([c9ad0eb](https://github.com/AmbiqAI/helia-aot/commit/c9ad0eb29f12fc829574f1904b8c0c86ee75fb5b))
* add tile op support ([1570971](https://github.com/AmbiqAI/helia-aot/commit/157097126e5f3da7808cd91162ca2456e3225119))
* add tile op support ([1570971](https://github.com/AmbiqAI/helia-aot/commit/157097126e5f3da7808cd91162ca2456e3225119))
* add where op support ([6ec8a75](https://github.com/AmbiqAI/helia-aot/commit/6ec8a75cc39dfee5e75c723c1daab870a1f386a0))
* add where op support ([6ec8a75](https://github.com/AmbiqAI/helia-aot/commit/6ec8a75cc39dfee5e75c723c1daab870a1f386a0))
* **aot:** add float kernel support across operator pipeline ([#246](https://github.com/AmbiqAI/helia-aot/issues/246)) ([73d9138](https://github.com/AmbiqAI/helia-aot/commit/73d91383aba90a44e0247cca21179fdbc502ebb1))
* carry recurrent state through the float LSTM path ([a41df71](https://github.com/AmbiqAI/helia-aot/commit/a41df718edeb450590b2ea0943992b7ea56a52c6))
* carry recurrent state through the unidirectional sequence LSTM path ([f3777b6](https://github.com/AmbiqAI/helia-aot/commit/f3777b6e03c4264149d9f8c117cdafb2c426bcf0))
* carry recurrent state through the unidirectional sequence LSTM path ([f3777b6](https://github.com/AmbiqAI/helia-aot/commit/f3777b6e03c4264149d9f8c117cdafb2c426bcf0))
* **ci:** file an issue when the weekly release-model E2E run fails ([#299](https://github.com/AmbiqAI/helia-aot/issues/299)) ([3fbe40b](https://github.com/AmbiqAI/helia-aot/commit/3fbe40b29a0cc24c43687614184b8e92882ce11e))
* **cli:** console presentation layer for conversion runs ([#264](https://github.com/AmbiqAI/helia-aot/issues/264)) ([1066679](https://github.com/AmbiqAI/helia-aot/commit/106667960d250504dab9db4babd44beb2856879d))
* **cli:** help panels, factory defaults, quick-start epilog, banner ([#261](https://github.com/AmbiqAI/helia-aot/issues/261)) ([c263d26](https://github.com/AmbiqAI/helia-aot/commit/c263d26879b894d34eed85730f845af1b6743399))
* **config:** warn on unknown nested config keys with did-you-mean ([#268](https://github.com/AmbiqAI/helia-aot/issues/268)) ([6363014](https://github.com/AmbiqAI/helia-aot/commit/6363014c2c3696a32513a642bf5ff81a8b25cf13))
* declare apollo510l compatibility in nsx module manifest ([6c4fb78](https://github.com/AmbiqAI/helia-aot/commit/6c4fb789584b5e27f20074dd6129b725ebc36d7d))
* document and expose supported HeliaAOT target names ([3b5880a](https://github.com/AmbiqAI/helia-aot/commit/3b5880aa291150980c95f0f8ca049c8e69f1622a))
* document and expose supported HeliaAOT target names ([3b5880a](https://github.com/AmbiqAI/helia-aot/commit/3b5880aa291150980c95f0f8ca049c8e69f1622a))
* expose supported target names via CLI and add M55 targets ([fc570ba](https://github.com/AmbiqAI/helia-aot/commit/fc570babbb9902efc6329674e4bb9ad6852b425c))
* **float:** enable FP16/FP32 for ABS, PRELU, and SUM via ns-cmsis-nn float kernels ([#279](https://github.com/AmbiqAI/helia-aot/issues/279)) ([2be2bd5](https://github.com/AmbiqAI/helia-aot/commit/2be2bd5f2a5b6c1788b3145084477d4bb71e465b))
* gate releases on manifest-backed model-corpus E2E ([#277](https://github.com/AmbiqAI/helia-aot/issues/277)) ([0c41e19](https://github.com/AmbiqAI/helia-aot/commit/0c41e19556863c91ef1dacabcede840ec87fb950))
* guard resolve against NULL ctx.buf in kernels that dereference it ([#325](https://github.com/AmbiqAI/helia-aot/issues/325)) ([9abc3b0](https://github.com/AmbiqAI/helia-aot/commit/9abc3b06c4e453bd74ca0339a7e363cb59d358d1)), closes [#316](https://github.com/AmbiqAI/helia-aot/issues/316)
* rename Apollo330P target and match target names case-insensitively ([3cb2215](https://github.com/AmbiqAI/helia-aot/commit/3cb2215b15c8bdcd4aaa79d21a831270d3052be5))
* support Python 3.13 and 3.14 ([8644efa](https://github.com/AmbiqAI/helia-aot/commit/8644efa05439c51790503ca8e880f7dae9504fd8))
* support stateful unidirectional sequence LSTM ([b0449a1](https://github.com/AmbiqAI/helia-aot/commit/b0449a1897ebc3cb69447fa3856709a797ae6746))
* tensor attribute-key warnings and programmatic API surface ([#270](https://github.com/AmbiqAI/helia-aot/issues/270)) ([370d954](https://github.com/AmbiqAI/helia-aot/commit/370d954834d52d251b7158ffbac0f9d4be477ebf))
* typed errors with hints and clean CLI exit codes ([#263](https://github.com/AmbiqAI/helia-aot/issues/263)) ([7f031fa](https://github.com/AmbiqAI/helia-aot/commit/7f031fad5115b8050f26dfb2e3ab36974c31aecd))

### Bug Fixes

* Add missing doxygen blocks to header ([8700eb0](https://github.com/AmbiqAI/helia-aot/commit/8700eb0fe962d175702812172f8cfa6632284001))
* add, mul, sub, expand_dims, max, min, gather bugs ([dbd7a27](https://github.com/AmbiqAI/helia-aot/commit/dbd7a27be5843a6cb2ff7c6b05cc0b5624a3773f))
* address Copilot review feedback on shape propagation ([bd97015](https://github.com/AmbiqAI/helia-aot/commit/bd97015b3010c5c60bf930c3caa1937d263e4eb4))
* adopt context-only run signature in dilate and resize_bilinear templates ([421340c](https://github.com/AmbiqAI/helia-aot/commit/421340c2ceb3f263cfd25453d71654a24988fa9d))
* align svdf recurrent state validation ([#290](https://github.com/AmbiqAI/helia-aot/issues/290)) ([bda8750](https://github.com/AmbiqAI/helia-aot/commit/bda8750976c74856e5814c7b4c08d764988f8ef0))
* **aot:** narrow extern "C" guard scope in generated headers ([#250](https://github.com/AmbiqAI/helia-aot/issues/250)) ([a5154f1](https://github.com/AmbiqAI/helia-aot/commit/a5154f1cdf1415a86e2cfe35f4f48dba1eccb631))
* block unresolved dims in shape rules and guard the memory planner ([0d274ba](https://github.com/AmbiqAI/helia-aot/commit/0d274ba3271b4f6d5eab932a2ce8fa3b3c3d417b))
* build the CLI on Python 3.14 ([c29139c](https://github.com/AmbiqAI/helia-aot/commit/c29139c8bce0d795f22e77084a77bef565a8e96b))
* Correct broadcast_to and batch_to_space rules with proper conditions ([8a0b054](https://github.com/AmbiqAI/helia-aot/commit/8a0b05438ca0df94e39dfe7e3a61e0930d4c0654))
* count rule-confirmed shapes as resolved and claim rank-4-only STB/BTS ([3208948](https://github.com/AmbiqAI/helia-aot/commit/3208948b4b0369dd69ebbfb6a272dc60280c5b2e))
* **e2e:** clone the public ns-cmsis-nn without a credential ([#291](https://github.com/AmbiqAI/helia-aot/issues/291)) ([a22304e](https://github.com/AmbiqAI/helia-aot/commit/a22304e0f02cf90fd2986f9f6dce7ac12d89f41d))
* **e2e:** seed Keras initializers so bidirectional-GRU weights are reproducible ([#314](https://github.com/AmbiqAI/helia-aot/issues/314)) ([116f176](https://github.com/AmbiqAI/helia-aot/commit/116f1768aa8d5f129b1feb8299bf154251e6fa54)), closes [#301](https://github.com/AmbiqAI/helia-aot/issues/301)
* emit scalar gather indices as rank-1 for heliaCore kernel contract ([3399a8d](https://github.com/AmbiqAI/helia-aot/commit/3399a8d3e2c54962c28ee1bd9814d054dec4fc93))
* fix add, mul, sub, expand_dims, max, min, gather bugs ([dbd7a27](https://github.com/AmbiqAI/helia-aot/commit/dbd7a27be5843a6cb2ff7c6b05cc0b5624a3773f))
* fix add, mul, sub, expand_dims, max, min, gather bugs ([4f41a11](https://github.com/AmbiqAI/helia-aot/commit/4f41a11e8428d47aff76ff82c27f1e409cfedb14))
* Handle potential edge case where input batch shape is also negative (not just shape signature) ([90d1021](https://github.com/AmbiqAI/helia-aot/commit/90d102140cbb2ef92733bfa5bed47cfc3a46478a))
* harden rank-0 and expand_dims emission found by adversarial review ([7611299](https://github.com/AmbiqAI/helia-aot/commit/7611299702e8c06f848694b3a808518ee69c4791))
* harden RESIZE_BILINEAR/DILATE validation, correct rounding, drop broken MVE path ([95b4199](https://github.com/AmbiqAI/helia-aot/commit/95b4199ca94cc0275af4698a70949c78a1adb213))
* Improve Windows compatibility ([d0cffaa](https://github.com/AmbiqAI/helia-aot/commit/d0cffaa61fdb8a83d62d71448a94c09b775ba8cd))
* keep includes outside extern "C" guard in new header templates ([1d7e2d4](https://github.com/AmbiqAI/helia-aot/commit/1d7e2d4159922792f1b6c199c3f2119f69cab983))
* make e2e stimulus deterministic ([#288](https://github.com/AmbiqAI/helia-aot/issues/288)) ([101aec9](https://github.com/AmbiqAI/helia-aot/commit/101aec9331d9d9ed92bc1c0e61b94a0dab37409d))
* make generated Zephyr test case CMSIS 6 compatible ([#287](https://github.com/AmbiqAI/helia-aot/issues/287)) ([0cc6e13](https://github.com/AmbiqAI/helia-aot/commit/0cc6e13a1ff149f55643f0ca485e85d2cb164d0b))
* make shape propagation rule ownership explicit ([722b642](https://github.com/AmbiqAI/helia-aot/commit/722b642e6fac3c01296692dcebd3f9af90c4b19e))
* make shape propagation rule ownership explicit ([722b642](https://github.com/AmbiqAI/helia-aot/commit/722b642e6fac3c01296692dcebd3f9af90c4b19e))
* name custom-platform fields in both YAML and CLI spellings ([160e7ab](https://github.com/AmbiqAI/helia-aot/commit/160e7ab55f7687d49e44d2800d27d3617679e1c2))
* normalize negative concat axis before the ownership test ([e7cf8ff](https://github.com/AmbiqAI/helia-aot/commit/e7cf8ff5fa6616395a6feb005199523838c2fc8e))
* raise the ns-cmsis-nn floor to 7.31.0 and pin e2e to match ([#340](https://github.com/AmbiqAI/helia-aot/issues/340)) ([59f4c6f](https://github.com/AmbiqAI/helia-aot/commit/59f4c6fd707718d88ca341ac7c689bb0e013da22)), closes [#304](https://github.com/AmbiqAI/helia-aot/issues/304)
* Reject index depth == 0 ([114a85b](https://github.com/AmbiqAI/helia-aot/commit/114a85bc6c569279dac636c453371491faafec46))
* reject SVDF weights_feature/bias dtypes the kernels cannot consume ([#312](https://github.com/AmbiqAI/helia-aot/issues/312)) ([90c661e](https://github.com/AmbiqAI/helia-aot/commit/90c661eff96ff7632a9f9fbe7124055daa34ff86))
* **release:** publish the GitHub Release only after model-corpus qualification ([#298](https://github.com/AmbiqAI/helia-aot/issues/298)) ([85eda59](https://github.com/AmbiqAI/helia-aot/commit/85eda59e0dc472e12126ccc6b14dac7582a73131))
* Remove _PUT_IN_MRAM_INIT to const mapping in test_emit-stage.py ([a765e04](https://github.com/AmbiqAI/helia-aot/commit/a765e04993e0442b699f554434bfc74c91dbc3b1))
* remove const from MRAM init placement macro ([3e3d519](https://github.com/AmbiqAI/helia-aot/commit/3e3d519da808b8f4ac5006651aed3f59a0e0a987))
* remove const from MRAM init placement macro ([3e3d519](https://github.com/AmbiqAI/helia-aot/commit/3e3d519da808b8f4ac5006651aed3f59a0e0a987))
* remove const from MRAM init placement macro ([dafd5b4](https://github.com/AmbiqAI/helia-aot/commit/dafd5b4bd9e928b73f380c4274af2f86f12bfa49))
* remove duplicate numpy import in parser tests ([a8dc4a7](https://github.com/AmbiqAI/helia-aot/commit/a8dc4a7d61f6276d422bc803123a775b3ab9d8f7))
* replace in-place ndarray shape assignment ([6edada0](https://github.com/AmbiqAI/helia-aot/commit/6edada0a869f6e750d537228677e6345ad2ab82c))
* resolve merge conflicts with main ([e14c183](https://github.com/AmbiqAI/helia-aot/commit/e14c18338cc941d29ee7523c3b98a4504e7b146b))
* resolve merge conflicts with main ([305d13f](https://github.com/AmbiqAI/helia-aot/commit/305d13f4313243ea26f972c719b4fa4cc2c3e641))
* restore CMSIS-NN no-clip sentinel and require persistent LSTM state ([2641268](https://github.com/AmbiqAI/helia-aot/commit/2641268b53a1c8ca83bf8c73a98445c63a4e7baa))
* restore scalar-scalar support for maximum and minimum ([0a54eb0](https://github.com/AmbiqAI/helia-aot/commit/0a54eb0a9e11442e435996f41a3605118d436b00))
* size int8 batch-matmul scratch from the RHS row count ([#296](https://github.com/AmbiqAI/helia-aot/issues/296)) ([28636e9](https://github.com/AmbiqAI/helia-aot/commit/28636e9c405fb732b8cabf868b4c6b009feada6e))
* size transpose-conv int8 scratch so the kernel gets a real buffer ([#313](https://github.com/AmbiqAI/helia-aot/issues/313)) ([bfe683f](https://github.com/AmbiqAI/helia-aot/commit/bfe683f905145dd8725227110892c1672d3df212))
* update fp16 golden test for the renamed LSTM e2e generator ([9bdf93b](https://github.com/AmbiqAI/helia-aot/commit/9bdf93b957a51c5810b90b7bd8e62bab67ab5c8d))
* validate SPLIT output shapes against the split lengths before code generation ([#344](https://github.com/AmbiqAI/helia-aot/issues/344)) ([44bd27c](https://github.com/AmbiqAI/helia-aot/commit/44bd27cd1419b083b586fff927df8afdecd2de59)), closes [#322](https://github.com/AmbiqAI/helia-aot/issues/322)
* validate SUM output shape, rank, and constant axis against the kernel contract ([#326](https://github.com/AmbiqAI/helia-aot/issues/326)) ([b82b256](https://github.com/AmbiqAI/helia-aot/commit/b82b2569f3a1515372704fb429392aa6d12c136b)), closes [#280](https://github.com/AmbiqAI/helia-aot/issues/280) [#207](https://github.com/AmbiqAI/helia-aot/issues/207)
* validate SVDF shapes against the ns-cmsis-nn kernel contract ([#324](https://github.com/AmbiqAI/helia-aot/issues/324)) ([9e3535d](https://github.com/AmbiqAI/helia-aot/commit/9e3535dfa869ad0519a69bc6e07384e57c6f7f87)), closes [#317](https://github.com/AmbiqAI/helia-aot/issues/317) [#280](https://github.com/AmbiqAI/helia-aot/issues/280)
* write generated files as UTF-8 with LF newlines ([4508272](https://github.com/AmbiqAI/helia-aot/commit/450827205d2f0fd17c4e304bfac54a8348513b84))

### Documentation

* document exact-rational vs TFLite 10-bit divergence bounds ([a6ab417](https://github.com/AmbiqAI/helia-aot/commit/a6ab4173a25e942c87552c2ab59714940256801d))
* drop interpreter pin from pipx example ([3c87204](https://github.com/AmbiqAI/helia-aot/commit/3c87204b9422a416a6bb2872806f1dc7c45c6ae6))
* **ethos-u:** correct driver contract and document known gaps ([#266](https://github.com/AmbiqAI/helia-aot/issues/266)) ([364cf21](https://github.com/AmbiqAI/helia-aot/commit/364cf21af03e955de1c91b09a80d9d7aba5a8c6d))
* tighten recurrent-state wording and pass byte length to arm_memset_s8 ([4d30064](https://github.com/AmbiqAI/helia-aot/commit/4d300641b448fe2174b832decf7cda5abf412dbb))
* wire agent instructions into every tool and add operational guidance ([#272](https://github.com/AmbiqAI/helia-aot/issues/272)) ([c68882a](https://github.com/AmbiqAI/helia-aot/commit/c68882abab266384143c669b5fa0ebf409dc8300))

Earlier releases are in [CHANGELOG.md](https://github.com/AmbiqAI/helia-aot/blob/cf2246a7ad439fa38d57462118e7840e5497a685/CHANGELOG.md).
