Render fan-in inputs as source-derived identifiers in the definition view #44

Closed
opened 2026-06-08 12:18:06 +02:00 by Brummel · 0 comments
Owner

Problem

In the composite definition view, a leaf with more than one wired input
slot renders its slots as positional stubs in the node label: [Sub(#A,#B)]
(crates/aura-cli/src/graph.rs:182-183, leaf_label). #A is the target
slot index turned into a letter; it carries no information about where the
value comes from. When several edges fan into the node, a reader cannot tell
which producer feeds #A and which feeds #B.

The positional letter is the wrong handle. The question a reader asks is
"where does this input come from", and that is answerable from the source
node itself.

Rule

Replace the positional letter with a source-derived identifier, shown in
slot order in the node label: [Sub(#id0, #id1)].

  • An input fed by an input-role marker ([price]) uses the role's
    existing name verbatim: #price. A name that already exists is never
    re-coined.
  • An input fed by an interior node uses the shortest abbreviation of
    that node's render label: the initial of each label component (type-name
    initial, capitalized, plus one lowercase initial per shown param alias;
    a nested composite uses its name initial). EMA(slow) -> #Es.

Uniqueness is scoped to a single node-call: only the sibling inputs of
one node must be collision-free. Two inputs of different nodes may share an
identifier -- an identifier is always read relative to its own (...), so
#Es at one Sub and #Es at another are not confusable.

  • An abbreviation lengthens (one more letter on the distinguishing
    component, prefix-free) only as far as that node-call's own siblings force
    it. It is therefore not a stable node id: the same source may render #Ef
    at one node and #E at another, depending on the siblings it must
    separate from there.
  • True tie -- two slots fed by the same source node (e.g. Sub(X, X)):
    not resolvable by lengthening, falls back to a counter suffix.
  • Threshold unchanged: identifiers appear only when a node has >1 wired
    input slot. A single-input node shows no identifier.

Worked example: MACD

Structure: line = EMA(fast) - EMA(slow), signal = EMA(signal) of the
line, hist = line - signal. The two multi-input nodes are the two Subs:

[Sub(#Ef, #Es)]   line:  EMA(fast) - EMA(slow)
[Sub(#S,  #Es)]   hist:  line(a Sub) - EMA(signal)

Both Subs carry an #Es, but the first means EMA(slow) and the second
EMA(signal) -- each unambiguous within its own node-call. Because the
namespace is per-node-call (not composite-global), slow and signal never
collide (they never feed the same node), so neither needs lengthening past
its initials.

Edge labels: dropped

The earlier version of this issue proposed labelling the fan-in edges with
the slot letter via ascii-dag's add_edge(.., Some(label)). With
source-derived identifiers that is unnecessary: the identifier already names
its source, and the source node is visible in the graph. No edge labels are
introduced -- render_flat keeps passing None
(crates/aura-cli/src/graph.rs:85) and ascii-dag's edge-label / collision
behaviour stays untouched. The whole change is local to leaf_label.

Acceptance

  • A leaf with >1 wired input renders each input as a #-prefixed
    identifier in slot order, replacing the positional #A/#B.
  • An input fed by an input-role uses the role's full name (#price); no
    new identifier is coined when a name already exists.
  • An input fed by an interior node uses the shortest abbreviation of
    that node's label (type initial + one per shown param alias; composite
    -> name initial) that is unique among that node's sibling inputs.
  • Abbreviations lengthen only as far as the node-call's own siblings
    require (per-node-call namespace, not composite-global); prefix-free.
  • Two slots fed by the same source node fall back to a counter suffix.
  • Single-input nodes show no identifier (threshold unchanged: >1 wired
    slot).
  • No edge labels are introduced; render_flat still passes None.
  • A test pins the abbreviation and the per-node-call scoping on a
    MACD-like fixture (two EMAs feeding one Sub, that Sub feeding another).
  • Affected goldens regenerated.
## Problem In the composite definition view, a leaf with more than one wired input slot renders its slots as positional stubs in the node label: `[Sub(#A,#B)]` (`crates/aura-cli/src/graph.rs:182-183`, `leaf_label`). `#A` is the *target* slot index turned into a letter; it carries no information about where the value comes from. When several edges fan into the node, a reader cannot tell which producer feeds `#A` and which feeds `#B`. The positional letter is the wrong handle. The question a reader asks is "where does this input come from", and that is answerable from the source node itself. ## Rule Replace the positional letter with a **source-derived identifier**, shown in slot order in the node label: `[Sub(#id0, #id1)]`. - An input fed by an **input-role** marker (`[price]`) uses the role's existing name verbatim: `#price`. A name that already exists is never re-coined. - An input fed by an **interior node** uses the shortest abbreviation of that node's render label: the initial of each label component (type-name initial, capitalized, plus one lowercase initial per shown param alias; a nested composite uses its name initial). `EMA(slow)` -> `#Es`. Uniqueness is scoped to **a single node-call**: only the sibling inputs of one node must be collision-free. Two inputs of *different* nodes may share an identifier -- an identifier is always read relative to its own `(...)`, so `#Es` at one `Sub` and `#Es` at another are not confusable. - An abbreviation lengthens (one more letter on the distinguishing component, prefix-free) only as far as that node-call's own siblings force it. It is therefore not a stable node id: the same source may render `#Ef` at one node and `#E` at another, depending on the siblings it must separate from there. - True tie -- two slots fed by the *same* source node (e.g. `Sub(X, X)`): not resolvable by lengthening, falls back to a counter suffix. - Threshold unchanged: identifiers appear only when a node has >1 wired input slot. A single-input node shows no identifier. ## Worked example: MACD Structure: `line = EMA(fast) - EMA(slow)`, `signal = EMA(signal)` of the line, `hist = line - signal`. The two multi-input nodes are the two `Sub`s: ``` [Sub(#Ef, #Es)] line: EMA(fast) - EMA(slow) [Sub(#S, #Es)] hist: line(a Sub) - EMA(signal) ``` Both Subs carry an `#Es`, but the first means EMA(slow) and the second EMA(signal) -- each unambiguous within its own node-call. Because the namespace is per-node-call (not composite-global), `slow` and `signal` never collide (they never feed the same node), so neither needs lengthening past its initials. ## Edge labels: dropped The earlier version of this issue proposed labelling the fan-in edges with the slot letter via ascii-dag's `add_edge(.., Some(label))`. With source-derived identifiers that is unnecessary: the identifier already names its source, and the source node is visible in the graph. No edge labels are introduced -- `render_flat` keeps passing `None` (`crates/aura-cli/src/graph.rs:85`) and ascii-dag's edge-label / collision behaviour stays untouched. The whole change is local to `leaf_label`. ## Acceptance - [ ] A leaf with >1 wired input renders each input as a `#`-prefixed identifier in slot order, replacing the positional `#A/#B`. - [ ] An input fed by an input-role uses the role's full name (`#price`); no new identifier is coined when a name already exists. - [ ] An input fed by an interior node uses the shortest abbreviation of that node's label (type initial + one per shown param alias; composite -> name initial) that is unique among that node's sibling inputs. - [ ] Abbreviations lengthen only as far as the node-call's own siblings require (per-node-call namespace, not composite-global); prefix-free. - [ ] Two slots fed by the same source node fall back to a counter suffix. - [ ] Single-input nodes show no identifier (threshold unchanged: >1 wired slot). - [ ] No edge labels are introduced; `render_flat` still passes `None`. - [ ] A test pins the abbreviation and the per-node-call scoping on a MACD-like fixture (two EMAs feeding one Sub, that Sub feeding another). - [ ] Affected goldens regenerated.
Brummel added the feature label 2026-06-08 12:18:06 +02:00
Brummel changed title from Label fan-in edges with their slot letter in the composite definition view to Render fan-in inputs as source-derived identifiers in the definition view 2026-06-08 12:41:56 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Brummel/Aura#44