refs #275
The engine-side half of by-name source binding. `SourceSpec` carries a load-bearing
`role: Option<String>` — `Some(name)` for a spec lowered from a bound `Role` (carried
through the blueprint lowering, previously dropped at compile), `None` for a
hand-built raw-index spec. A pure `bind_sources(specs, keyed_supply)` resolves a
`Vec<(role, Box<dyn Source>)>` into the positional `Vec` `run` consumes, in
`SourceSpec` declaration order, erroring named (`SourceBindError`:
Missing/Extra/Duplicate/Unnamed feed) on a mis-bind. `Harness::run_bound` is the
ergonomic method the by-name production path calls.
The raw-index `run(Vec)` primitive and the k-way merge / per-cycle event loop are
untouched: a positional run stays byte-identical (C1, pinned by
`run_bound_out_of_order_matches_positional_run`), and every existing `run(Vec)` caller
keeps working (it ignores `role`). A `BTreeMap` index makes the Duplicate/Extra
diagnostics deterministic.
C4's tie-break guarantee ("source declaration order") is unchanged — `bind_sources`
emits in `SourceSpec` order, so the merge's source-index tie-break resolves on
declaration order regardless of the caller's supply order. The narrow C23 amendment
(a `SourceSpec.role` is load-bearing for source binding, the rest of the flat graph
stays raw-index) is deferred to the ledger note.
The four error-path RED tests assert via `.map(|_| ()).unwrap_err()`: the `Ok` arm
`Vec<Box<dyn Source>>` is not `Debug` (`Source` has no `Debug` supertrait), so a bare
`.unwrap_err()` would not compile — a plan-byte defect corrected here.
Also sweeps the 45 raw-index `SourceSpec { .. }` literals to `SourceSpec::raw(..)`
across the workspace (mechanical, compiler-enumerated) and pins that a bound root
role's name survives lowering.
Verification: `cargo test --workspace` green (0 failed; incl. 5 `bind_sources` cases,
the `run_bound` byte-identity test, the role-survives-lowering pin, and the four
`.sources`-equality twins under the now-stricter `role` equality);
`cargo build --workspace --all-targets` clean; `cargo clippy -p aura-engine
--all-targets` clean.
docs/specs and docs/plans were retired (prior commit); the source/test
comments that cited them ("spec 0050 §4.1", "spec §Testing N", "per spec",
"the spec's ...") now point at nothing. Strip every such pointer while
preserving the technical substance, the design-ledger contract refs
(C1/C11/C20/C34/C12.1/...), and the Gitea issue refs (#41).
Comment/doc edits only across 20 files — no logic change; full workspace
suite green, clippy clean.
Hand-wires all seven new aura-std nodes (Resample, Delay, Gt, Session, EqConst
x2, And, Latch) + SimBroker into a raw-index FlatGraph over one synthetic
Frankfurt session, pinning the whole vocabulary composed end-to-end:
- held = [0,0,1,1,0] over the 5 bar emissions: flat, latched bar3-close (the
strict breakout landing on session bar 3) through bar4, exit at bar5-close;
- equity = [0,0,0,3,8] pips (SimBroker lagged-exposure integration, pip=1.0);
- a no-entry control (bar3 close == bar2 high) pins the strict-> semantic;
- two disjoint runs byte-identical (C1).
Both spec traps exercised (bar6 rollover closes bar5; bars 1-2 warm Delay[1]).
Phase-1 C9 deliverable; build-step 8 (capstone) of milestone 'Strategy node
vocabulary I'.
closes#91