The single-file ledger had grown to 2968 lines / ~42k tokens, mixing current design law with accreted history: 59 cycle-stamped realization blocks, 18 [HISTORY] passages, 22 supersession markers, and the C10 / C22 / C24 reframe sagas layered several supersessions deep. A code-grounding audit (31 agents, adversarially verified) confirmed 11 defects stated as current truth: stale crate homes from the C28 #288 roster split (cost nodes, PositionManagement, PositionEvent, Session), the renamed InputSpec->PortSpec, the pre-#241 project model in C16 and the open-threads section, a stale HarnessKind retirement deferral in C24, and three C28-internal inconsistencies. New shape, per the ailang precedent: - INDEX.md stays the sole addressable entry point: foundation, external components, a C-id-keyed contract map (one line per contract), and only the genuinely open architectural threads. - contracts/cNN-<slug>.md carries each contract's current truth only: Guarantee / Forbids / Why with ratified refinements integrated, plus a code-anchored Current state. All confirmed defects are fixed here; crate anchors were re-verified against the tree. - contracts/cNN-<slug>.history.md (18 sidecars) and INDEX.history.md preserve every superseded block verbatim, stamps and issue refs intact, under a frozen-record banner. Nothing was deleted: superseded design intent remains an addressable working-tree artifact, off the per-cycle audit walk. - Ledger discipline is now stated in INDEX.md: live files are edited in place at cycle close, superseded text moves verbatim to the sidecar, and a supersession marker in a live file is itself an audit finding. Every contract file was verified against its old text by an independent zero-loss pass (statement-by-statement) plus a code-accuracy spot check; C-ids and contract titles are unchanged, so existing C-id citations in code, tests, and issues resolve as before.
8.6 KiB
C19 — Bootstrap: blueprint → instance (recursive): history
FROZEN HISTORICAL RECORD. Each block below was true as of its cycle/date stamp and may be superseded; this file is NOT current truth and NOT a grounding surface. Current contract: c19-bootstrap.md.
Realization (cycle 0016 — param-set injection). The bootstrap now binds an
injected param-set, realizing C12's "params injected at graph build (the optimizer
sees a generic vector of typed ranges)" and C19's "factory params → sized node"
literally: a blueprint leaf is value-empty — BlueprintNode::Leaf holds a
LeafFactory { name, params, build } recipe, not a built node — and the value lives
only in the injected vector (no baked default), so the blueprint stays a pure
param-generic recipe. (Renamed in cycle 0024: BlueprintNode::Primitive holds a
PrimitiveBuilder { name, schema, build } — the recipe now carries the full
signature, see the C8 0024 realization; bootstrap_with_params/compile_with_params
moved onto Composite when struct Blueprint collapsed into it, see the C19 0024
realization.) bootstrap_with_params(Vec<Scalar>) /
compile_with_params build each leaf through its own constructor (the single
sizing/validation gate) from its kind-checked slice while lowering (build-then-
wire), consuming the vector slot-by-slot in the same depth-first walk
param_space() projects — so the two share one traversal (subsuming the #34 dual-
traversal hazard) and the value reaches the node at the slot the sweep enumerates.
Arity is checked up front (param_space().len()); a wrong-kind or wrong-length
vector is a typed CompileError::{ParamKindMismatch, ParamArity} (the typed-value
check C8 deferred). The lowering/edge/source rewrite is structurally unchanged, so
the flat graph stays bit-identical for a given point (C23, the correctness
invariant). The value domain (e.g. length ≥ 1) stays the constructor's own
assert; the search-range is still the run's (#32/C20). One value-empty leaf
detail for C22: the blueprint view (pre-run, param-generic) labels a leaf by bare
type (PrimitiveBuilder::label, was LeafFactory::label, → [SMA]) — the
value-bearing SMA(2) of C8's render-
label refinement now appears only in the compiled view (built nodes, Node::label).
Realization (cycle 0017 — blueprint render = main graph + definitions). The
aura graph blueprint view (C9 graph-as-data, #13) renders the authored
structure as a program with subroutines: a flat main graph wiring the
harness with each composite shown as a single opaque node [name], plus a
where: section that defines each distinct composite type once (its
interior with named input-entry nodes and outputs folded onto their producers as
name := … bindings (render refined through cycles 0019–0022; originally
[in:k]/[out] port markers); deduped by name(), collected
recursively so nested composites are opaque nodes with their own definitions). This
supersedes #13's original cluster-box model and is the durable split this view
realizes: blueprint = source (composites as named subroutines, body once) vs.
compiled = inlined machine form (C23, boundary dissolved). The substantive cause
for retiring cluster boxes is a real renderer defect — ascii-dag 0.9.1's subgraph
level-centering rounds sibling x-positions with /2, overlapping wide sibling
labels (width/parity-sensitive, no config/padding dodge surviving unequal-width
siblings); the flat layout is collision-free, and both views now build flat
graphs only. The model also scales (blueprint size tracks top-level wiring, not
inlined node count) and removes #13's nested-composite unimplemented! (the
definitions pass recurses). The interactive enter/focus counterpart (a composite
collapsed to a navigable node) is the playground's, parked as a separate concern
(#37); the static CLI keeps the all-at-once definitions form (#38).
Realization (cycle 0024 — the root is the fully-bound composite; the flat graph is
a named type). struct Blueprint is deleted: the root graph IS a Composite,
and compile_with_params/bootstrap_with_params/param_space are its methods.
What distinguished the root — its bound data sources — is now a property of its input
roles: Role carries source: Option<ScalarKind> (None = an open interior port,
wired by the enclosing graph; Some(kind) = a bound ingestion feed). A composite is
runnable iff every root role is bound (C3: sources bind at ingestion only); an
open root role is a compile-time CompileError::UnboundRootRole. So the "main graph"
is no longer a separate kind — only the composite all of whose roles are
source-bound, governed by the same conditions as any other node. Compilation now
targets a named type: compile validates structurally pre-build (via
signature(), no node constructed — an ill-typed wiring is caught before any build
closure fires) and emits FlatGraph { nodes, signatures, sources, edges } — the
C23 flat graph, now first-class — which Harness::bootstrap consumes (kinds/firing
from the carried signatures, buffer depth from lookbacks()). The per-flat-node
signature travels beside the node, so bootstrap reads it without a built-node
schema() call (which no longer exists, see the C8 0024 realization).
Realization (cycle 0026 — graph render redesign: model + WASM-Graphviz viewer,
#51). aura graph no longer renders ASCII. The render path is now two pieces:
a read-only model serializer (aura_engine::model_to_json, iteration 1) that
walks the root composite + every distinct composite type into a deterministic,
hand-rolled JSON model (C14, golden-tested; the engine's last hand-rolled JSON
writer after RunReport::to_json moved to serde in cycle 0033; the
swapped-param mis-wire property moved here from the old compiled-view test), and a
self-contained HTML viewer (aura-cli::render::render_html, iteration 2) that
inlines that model, the ported prototype viewer JS, and a vendored Graphviz-WASM
blob into one page emitted to stdout. Layout/SVG happen in the browser via
WebAssembly — aura ships no layout engine and stays a serializer (C9: graph-as-data,
no eval/build on the path). The viewer is a render asset (C10 — no node/strategy
logic, no DSL); it labels every input pin from the model's now-real names (C23
debug symbols, named in cycle 0027) and colours wires by the four scalar base
types (C4). This retires ascii-dag and its adapter (graph.rs), the
--compiled/--macd flag plumbing, and the invented #Sf/:=/histogram →
notation — superseding the cycle-0017 flat-ascii model and its renderer-defect
workaround. The DOT/SVG are Graphviz-version-dependent and not golden-tested; the
deterministic JSON model is the asserted contract.
Realization (cycle 0034 — structural-constant bind: a knob removed from
param_space, #55). PrimitiveBuilder::bind(slot, value) adds the third param
category beside the topology factory-arg (C7/C19) and the tuning param (the
cycle-0016 value-pin): a structural constant. The cycle-0016 binding pins a
value in the injected vector while the knob stays in param_space (a tuning
param the sweep varies); bind instead removes the slot from param_space
entirely — the knob is gone, not fixed. The discriminator is the #55
deform-vs-tune test: a value whose variation yields another valid point of the
same strategy is a tuning param (stays in param_space); a value whose
variation deforms the strategy into a different one (e.g. the 2 of an
"SMA2-entry" bound to its two-candle construction) is a structural constant
(bound out), so a sweep never enumerates deformed strategies as valid family
members. Mechanically bind shrinks the builder's declared param surface
(schema.params) and wraps its build closure to re-splice the constant at its
original positional slot; the construction layer
(collect_params/lower_items/param_space/compile_with_params) is
byte-unchanged — both dock sites already key off builder.params(), so the
shrink propagates for free, and chained binds reconstruct the correct positional
vector because each layer computes its slot index relative to the param list it
sees. C23 is unaffected: bind resolves the param name to a position at
authoring time (the by-name authoring address space, the 0032 amendment) and
the flat graph stays wired by raw index — the name never reaches it. The
complementary question — exporting a named frozen strategy (all/most knobs
bound) as a reusable blueprint value — is deferred (#60); bind ships only the
per-knob overlay, no registry (C9/C10 intact).