Three substrate extensions surfaced by the Blazr session port:
1. **App-state threading.** mizan-axum::router() is now generic over a
user-supplied state type and threads `Arc<dyn Any + Send + Sync>` into
every dispatch via RequestHandle. Handlers downcast to their concrete
AppState. The stateless AFI fixture uses `router_stateless()` (matches
the prior signature). RequestHandle gains a `from_dyn()` constructor
to wrap already-erased trait-object references.
2. **`[T; N]` and `BTreeMap<K, V>` lowering in #[derive(Mizan)].** Fixed
arrays emit as `List<T>` (matches Python `tuple[float,...]` → JSON
array). String-keyed maps emit as `List<V>` — closest approximation
until KDL grows a `dict` shape. Also: vec-element registrations get a
per-function scope suffix so two handlers returning `Vec<Same>` don't
collide at the static-name layer.
3. **`types_match` for merge: upsert-into-list semantics.** Now matches
Python `types_match_for_merge`: direct (T == T), upsert (slot is
`Alias(List(T))`, value is T), and list-replace (both sides list).
The AFI fixture only exercised the direct path; the Blazr port's
`morph_set_value` returning a single `MorphLayer` into a context with
`Vec<MorphLayer>` slot is what surfaced the gap.
AFI codegen + wire parity stays 12/12 green after these substrate changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>