Files
Aura/crates
Brummel 1b7e4ad169 feat(aura-engine): param_space() injectivity as a compile invariant
A non-injective param_space() — two slots under one path-qualified name — is
the by-name knob address space (C12/C19) being broken: no binding can select
one slot without the other. This cycle makes it a structural compile error.

One check, check_param_namespace_injective over the param_space() names,
replaces the whole fan-in machinery (signature_of, leaf_has_param,
check_fan_in_distinguishability, check_composite_fan_in) and runs from
compile_with_params AND from both binders before resolve/resolve_axes — so the
canonical by-name author sees the structural cure (CompileError::DuplicateParamPath,
carrying the path and pointing at .named(...)) instead of the AmbiguousKnob symptom
(#59). With an injective space guaranteed before resolve, no bound name can
multi-match, so BindError::AmbiguousKnob is dead and removed (both resolver arms ->
unreachable!). param_space() stays infallible; the invariant lives in the compile
step (C23).

The check is strictly the by-name-addressability property. The old fan-in predicate
(equal signature AND >=1 param) also rejected two collisions that are NOT
param_space duplicates — an asymmetric param/paramless collision and a role-vs-leg
collision — which guarded render identity, dead since the renderer was retired in
0026. Both are intentionally dropped; a future node-/wiring-name check, if wanted,
is decoupled from injectivity.

The new invariant correctly rejected a pre-existing fixture (multi_output_composite's
two unnamed Sma legs); cured in place with the .named(fast/slow) the invariant
mandates. A new E2E test drives the cured cross through the by-name binder
end-to-end (resolve + bootstrap + run to a populated exposure trace).

C9/C12/C19/C23 ledger notes amended. Verified: cargo build/test --workspace green
(0 failed), clippy --workspace --all-targets -D warnings clean.

closes #59
2026-06-11 18:30:26 +02:00
..