diff --git a/docs/specs/0040-wiring-totality-check.md b/docs/specs/0040-wiring-totality-check.md index 510963d..8cbb40b 100644 --- a/docs/specs/0040-wiring-totality-check.md +++ b/docs/specs/0040-wiring-totality-check.md @@ -264,27 +264,49 @@ need all faults are out of scope (the existing variants are first-fault too). the lowered `FlatGraph` is unchanged (the existing identity test covers this; the check adds nothing to lowering). -### Blast radius (named — fixed in this iteration, not deferred) +### Blast radius (empirically enumerated — fixed in this iteration, not deferred) -Three currently-green negative tests in `crates/aura-engine/src/blueprint.rs` wrap a -single-role composite `c` in a root with **empty** `edges` and **empty** `roles` -(`vec![BlueprintNode::Composite(c)], vec![], vec![], vec![]`). That leaves the root's -one interior node (a composite exposes one derived input port per role, -blueprint.rs:76-99) **uncovered**, so `check_ports_connected` — running at the root -level before the recursion — returns `UnconnectedPort { node: 0, slot: 0 }` and -pre-empts the deeper fault each test targets: +The authoritative blast radius was determined by a throwaway probe (the check +implemented, `cargo test --workspace --no-fail-fast` run, then discarded): **exactly +four** currently-green tests flip, all in `crates/aura-engine/src/blueprint.rs` (119 +passed, 4 failed; every other crate — including the aura-cli sample/sweep/param_space/ +render tests — stays green). Three are negative tests that wrap a single-role composite +`c` in a root with **empty** `edges` and **empty** `roles` +(`vec![BlueprintNode::Composite(c)], vec![], vec![], vec![]`), leaving the root's one +interior node (a composite exposes one derived input port per role, blueprint.rs:76-99) +**uncovered**, so `check_ports_connected` — running at the root level before the +recursion — returns `UnconnectedPort { node: 0, slot: 0 }` and pre-empts the deeper +fault each targets: - `bad_interior_index_rejected` (~1372) — asserts `BadInteriorIndex` (a fault inside `c`). - `role_kind_mismatch_rejected` (~1440) — asserts `RoleKindMismatch { role: 0 }`. - `output_port_out_of_range_rejected` (~1463) — asserts `OutputPortOutOfRange`. -Resolution (in this iteration): make each root wrapper **minimally valid** so the test -still reaches its intended fault — give the root a covering input `Role` whose target is -`c`'s input slot (or, where the fault under test does not require `c` to expose an input -port, drop that port). The asserted deep-fault variant is unchanged; these fixtures -merely relied incidentally on under-wiring being accepted, which this cycle makes -invalid. This is the load-bearing test maintenance a new structural invariant entails — -named here, not discovered at implement time. +The fourth is a **compile-success** param-order test, +`param_space_mirrors_compiled_flat_node_param_order_under_nesting` (~1856), which today +compiles a deliberately **under-wired** nested graph just to read its flat param order: +the inner `strategy` composite (~1877) holds `[Composite(fast_slow), LinComb(2)]` but +wires neither of `LinComb`'s two `term` inputs, and the root (~1885) wraps `strategy` +with empty edges/roles, leaving `strategy`'s `price` input uncovered too. The new check +rejects it (`UnconnectedPort`) where it currently returns `Ok`. + +Resolution (in this iteration): +- The **three negative tests**: give each root a covering input `Role` whose target is + `c`'s input slot (`Role { name: "src".into(), targets: vec![Target { node: 0, slot: 0 }], + source: Some(ScalarKind::F64) }`, mirroring the existing covering-role pattern at + ~1414). The root level then passes and the recursion surfaces the intended deep fault + (the index/kind/output checks run before `c`'s own connectivity check), so each STILL + asserts its original variant. +- The **fourth (param-order) test**: fully wire the contrived graph — fan `fast_slow`'s + output into both `LinComb` terms (`Edge { from: 0, to: 1, slot: 0, from_field: 0 }` + and `Edge { from: 0, to: 1, slot: 1, from_field: 0 }` in `strategy`) and add a + covering root role for `strategy`'s `price` input. Wiring does not change node order + or params, so the asserted `param_space == compiled-flat-param-order` equality is + unchanged; only the graph becomes valid. + +These fixtures merely relied incidentally on under-wiring being accepted, which this +cycle makes invalid — the load-bearing test maintenance a new structural invariant +entails. Two adjacent negative tests are **safe by ordering** and need no change: `compile_rejects_kind_mismatch_without_building` (~2013) — the edge kind-check fires @@ -301,9 +323,12 @@ slot is covered by its role target, and `UnboundRootRole` is checked after **each** surface for at least `UnconnectedPort`, and at least one `DoubleWiredPort` test). - The nested-level test (3) and the open-role-boundary test (4) pass. -- The three named blast-radius tests (`bad_interior_index_rejected`, - `role_kind_mismatch_rejected`, `output_port_out_of_range_rejected`) are re-wired to a - minimally-valid root and still assert their original deep-fault variant (green). +- All four empirically-enumerated blast-radius tests are fixed and green: the three + negative tests (`bad_interior_index_rejected`, `role_kind_mismatch_rejected`, + `output_port_out_of_range_rejected`) re-wired with a covering root role and still + asserting their original deep-fault variant; and the param-order test + (`param_space_mirrors_compiled_flat_node_param_order_under_nesting`) fully wired and + still asserting its `param_space == compiled-flat-param-order` equality. - The full existing suite stays green (regression 5) and the compilat is byte-identical for graphs that still compile (regression 6). - The C8 ledger realization note is landed.