Sweep closure drops named binding back to positional + manual name re-zip #57
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Surfaced by the milestone fieldtest "The World — parameter-space & sweep"
(docs/specs/fieldtest-milestone-the-world-param-sweep.md, scenario mw_2).
Friction
.axis("sma_cross.fast", [2,3]).axis(...).sweep(run)resolves the named axesto a positional grid — but the per-point
runclosure receives a bare&[Scalar]and must callbootstrap_with_params(point.to_vec())(positional)and rebuild the blueprint by hand. To put readable knob names into the per-point
RunManifest.params, the author must re-zipparam_space()names onto the pointthemselves (the
aura sweepCLI does exactly this zip by hand internally).So the named-binding ergonomics stop at the grid boundary: inside the sweep the
author is back to positional vectors and manual name re-zipping, re-deriving
information
param_space()already holds. The mw_2 comparison works, but onlybecause the consumer re-zips names onto
pt.paramsfor display.Direction (no decision made here)
Consider threading a named view of the point into the closure — e.g. a small
Pointwithget(name), or havingSweepPointcarry the param names — so aconsumer need not re-zip from
param_space(). Pairs with the #32/#33 sweepergonomics surface. Low-to-medium; strikeable.
Pairs with #52 — the two halves of one sweep-ergonomics surface (both touch sweep.rs and the named↔positional boundary). A named
SweepPointview threaded into the per-point closure (this issue) is the prerequisite for #52'sRandomSpaceto report readable per-point params. Plan them together, #57 first.Design reconciliation (specify, in-context entry)
Spec:
0046-sweep-named-binding. The forks below were listed open on thisissue ("Direction (no decision made here)"); they were resolved in the
in-context design discussion (brainstorm) on 2026-06-15.
Fork: named-view attach point / closure-signature change (issue floated
"a small Point with get(name)" vs "SweepPoint carrying the param names")
→ resolved to a signature-preserving derived view (approach C): the run
closure stays
Fn(&[Scalar]) -> RunReportbyte-for-byte (honouring #52's#71-firewall constraint), and names are paired with the positional point by a
derived view, not threaded into the closure (approach A, rejected because it
would touch the frozen signature and force a mc/walk_forward cascade).
Provenance: user chose "C" (2026-06-15), after being shown A vs C with
the trade-offs.
Fork: scope of the named view (just remove the in-closure re-zip, vs also
make the returned family readable by knob name) → resolved to both: (i)
the in-closure manifest re-zip is removed, and (ii)
SweepFamilycarries theparam-space so a returned family is readable by name post-hoc.
Provenance: user "dann mach beides" (2026-06-15).
Fork: named view as a type vs a free function → resolved to a free
function
zip_params(space, point) -> Vec<(String, Scalar)>(no new type,no lifetime); the borrowed
NamedPoint<'a>struct was rejected as ceremony.Provenance: user "Das NamedPoint kommt mir auch umständlich vor"
(2026-06-15), ratified with "ja, mach das fertig".
Fork: where the lossy f64 collapse lives → resolved to the manifest
constructor (
sim_optimal_manifesttakes typedVec<(String, Scalar)>andcollapses to f64 internally); the view stays purely typed (no f64 method on
it).
Provenance: user rejected an
as_f64_pairsview method as "festgenageltauf f64" (2026-06-15).
Done — shipped in cycle 0046 and audited drift-clean.
A sweep point's
param_space()names are now a derived view, not a hand re-zip:aura_core::zip_params(space, point) -> Vec<(String, Scalar)>is the one sharedprojection. The three open-coded re-zips in the CLI (
sweep_family,sweep_over,run_oos) collapse to one call each.GridSpaceretains theParamSpeclist it already receives innew();SweepFamilycarries it and exposesnamed_params(i), so a returned family isreadable by knob name without the blueprint in hand (consumer ii).
sim_optimal_manifestnow takes typedVec<(String, Scalar)>and does thelossy f64 collapse internally — the manifest's
Vec<(String, f64)>field (thetyped-param-space precursor) stays deferred.
The run-closure signature
Fn(&[Scalar]) -> RunReportis byte-unchanged, so #52'sRandomSpaceplugs into the samesweep()execution layer with zeroreconciliation (#71 firewall held). Behaviour-preserving:
aura sweep/walk-forward / run output is byte-identical.
Commits:
119221c(spec),cd9f7e4(plan),fb8cabf(implement),b188773(audit —drift-clean). New tests:
zip_params×2,sweep_family_carries_param_space,family_named_params_round_trips; full workspace suite + clippy green.