Unify the blueprint main-graph render through the composite definition machinery #48
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?
Symptom
aura graph --macdrenders the main graph far poorer than a composite'sinterior. From the rendered main graph it is not visible what the strategy
actually does:
Two facts the strategy turns on are absent: (a) that the
histogramfield —not the macd line, not the signal — drives
Exposure(the edge carriesfrom_field: 2, seecrates/aura-cli/src/main.rs:254), and (b) anythingExposurecomputes. The whole strategy is one line —— and none of it reaches the graph.
The composite
where:view, by contrast, already solves the "show what a nodeis" problem (goal A) completely: a typed signature title, leaf labels
carrying aliased param names + ordered input-slot stubs (
[EMA(fast)],[Sub(#Ef,#Es)]), and output bindings ([macd := Sub(...)]).Root cause — accidental code divergence, not a design principle
Two divergent render paths in
crates/aura-cli/src/graph.rs. The leaf-labeldifference is one line:
graph.rs:44—render_blueprint(main graph):Leaf(factory) => factory.label()(bare)graph.rs:299—render_definition(composite):Leaf(factory) => leaf_label(c, i, factory)(enriched)The main graph takes the bare variant; the composite interior takes the
enriched one.
[Exposure]could run throughleaf_labelexactly like[EMA(fast)]and show its params + slot stubs. It does not, only becauserender_blueprintis a separate, poorer path that never inherited thecomposite machinery (
leaf_label, the edge handling,output_binding).Structural basis — the blueprint is a composite for render purposes
Struct shapes in
crates/aura-engine/src/blueprint.rs:nodesandedgesare the same types — identity, not analogy. The A-solvingmachinery (
leaf_label, edge handling,output_binding) operates solely onnodes+edges, so it applies to aBlueprintwith no semantic change. Theblueprint differs only at the borders, and each is a small render adapter,
not a blocker:
sources(typed, bound) vsinput_roles(named, open). Bothalready render as an entry marker —
[source:F64]is the counterpart of[price].Blueprinthas no alias field, butBlueprint::param_space()(
blueprint.rs:183) yields the same per-node information;leaf_labelwould source params from there instead of
c.params().Sink sharpening (load-bearing)
A sink is not a type. Verified: a grep for
Sinkacrossaura-engine/aura-corefinds only test fixtures (SinkF64/SinkI64) and test names —no
trait Sink, no enum variant, no model category. The only structural markis an empty output schema,
output: vec. The testnode_is_producer_and_sink_at_once(
crates/aura-engine/src/harness.rs:1108) shows sinkhood is not even exclusive— a node can produce and be tapped at once.
Therefore sinkhood is a topology role / convention: the zero-output bottom end
of C8's "at most one output", not a node kind. Consequences:
OutField.OutFieldis a forwarded port (for aconsumer); a sink is a terminal node (side effect, no consumer). They are not
two forms of "output"; a composite may have both.
mechanism forbidding an interior sink in a composite.
sink is a leaf like any other, run through
leaf_label, that happens to haveno outgoing edge. No special handling.
Direction (names the unification; does not prescribe the implementation)
One shared render path over the common shape:
nodes+edges+ entries +per-node params + outputs. The blueprint is the root composite with
differently-shaped borders.
render_definitionalready is that path — it ismerely typed to
&Compositeinstead of the shared shape. Routing the blueprintthrough it makes the main graph inherit, for free: leaf params, slot stubs, and
from_fieldedge semantics.Relationship to other findings
from_fieldfinding: edges dropfrom_field/slotatgraph.rs:60, and ascii-dag'sadd_edgelabel slotat
graph.rs:87is passedNone. A unified path that renders edgefield/slot labels in both views resolves it as a by-product, so it is folded
in here rather than filed separately.
#28(render a consumer's own graph — reach),#37(interactive enter-to-expand — playground), and
#40(multi-output compositeboundary — closed; the substrate this builds on). These are neighbours, not
duplicates.
Invariant note
C12 states the harness is ontologically not a node (a closed root, not a
composable fragment). That is the wrong axis for the render: ontology
(composable vs terminal) and render form (which fields are drawn) are
independent. The harness is ontologically not a node and
render-structurally a composite — both hold at once. Earlier reasoning that
used C12 to deny the main graph a signature was a category error; it is
recorded here so the next reader does not repeat it.