NodeFox logoNodeFox

Edges & Data Flow

Edge model at a glance

In NodeFox, edges are explicit runtime contracts between nodes. They are not visual decoration. Every edge answers one of two questions:

  1. What data is transferred?
  2. What execution signal is transferred?

NodeFox keeps those concerns separate so orchestration remains deterministic.

Two edge types

Data edge

A data edge copies payload values from a source output slot to a target input slot during Phase 1 (Routing).

Use data edges when you want to move content such as text, JSON objects, binary file blobs, or structured model outputs.

Activation edge

An activation edge sends an execution signal without sending payload data.

Use activation edges when a node should only run after an explicit release signal, even if data already exists on its inputs.

This is the main pattern for quality gates, approval gates, and synchronization barriers.

JSON graph mental model

The canvas is rendered visually, but runtime behaves like a graph object. Thinking in this JSON-like shape helps avoid ambiguous routing:

{
  "edges": [
    {
      "kind": "data",
      "from": { "node": "conversation-1", "slot": 1 },
      "to": { "node": "writer-1", "slot": 1 }
    },
    {
      "kind": "activation",
      "from": { "node": "decision-approval", "slot": 1 },
      "to": { "node": "writer-1", "slot": 1 },
      "mode": "node-to-node"
    }
  ]
}

If you can describe your route plan unambiguously in this structure, you can usually predict runtime behavior before the first test run.

Slot indexing and keyboard mapping

This is a common source of confusion, so treat it as a fixed rule set:

  • On canvas, pressing 1 starts from slot 1.
  • On canvas, pressing 8 starts from slot 8.
  • On canvas, pressing 0 means "bulk connect all visible slots", not "slot zero".
  • In $ references, $1 means input slot 1.
  • In Code nodes, inputs.get(0) reads slot 1 because code APIs are zero-indexed.
  • In Code nodes, outputs.set(0, value) writes to output slot 1.

If you remember one sentence: keyboard and $ references are 1-based; code APIs are 0-based.

How to draw routes in the UI

  1. Hover over a source node so slot handles appear.
  2. Press a number key 1 through 8 to choose an output slot.
  3. Click the target node to complete the route.
  4. Press A while connecting to switch into activation-edge mode.
KeyAction
1..8Start a route from that output slot
0Start bulk multi-slot connect
AToggle activation-edge mode during connect
EscCancel current route operation
ShiftSnap while dragging

Data-edge behavior details

  • Data edges are directional.
  • Fan-out is supported: one output can feed many downstream inputs.
  • Fan-in is supported: multiple upstream outputs can target one input.
  • In fan-in patterns, latest arrival to that input slot is what the node sees for that cycle.

Use explicit merge nodes (Buffer/Combine or equivalent) when you need deterministic multi-branch joins instead of implicit latest-arrival behavior.

Activation-edge behavior details

Activation edges do not make a node magically executable on their own if slot requirements are unmet.

Eligibility still follows node flags and optional-slot rules:

  • If blocking slots are empty, activation signal alone is insufficient.
  • If Activated flag is enabled, data alone is insufficient.
  • Node becomes eligible only when all applicable requirements are satisfied.

This is why activation edges work well as release controls rather than hidden trigger hacks.

For explicit release gating, configure both together on the target node path:

  1. enable Activated on the target node (so data alone cannot run it)
  2. provide an activation edge from the gate/approval branch (so execution permission is explicit)

Using only one side of that pair is a common reason for blocked or prematurely released branches.

Proven edge patterns

Pattern: controlled write

Use both data and activation edges into a Writer:

  • Data edges carry prepared output payload.
  • Activation edge from Decision(approved) releases the write.

This prevents accidental outbound writes from early or low-quality model output.

Pattern: parallel branch synchronization

Run several branches in parallel, set completion signals, and use Wait + activation edge to release the merge stage only when all branches complete.

This keeps merge behavior deterministic and avoids partial-output race conditions.

Pattern: bounded refinement loop

Conversation -> Decision -> (fail branch loops back) with Max retry constraints and activation release into final Writer on pass.

This provides iterative quality improvement without unbounded looping.

Common pitfalls

  • Using only data edges when you meant to gate execution timing.
  • Marking too many slots Optional and then wondering why nodes run with partial context.
  • Forgetting that 0 on keyboard is bulk connect, not slot 0.
  • Mixing 1-based $ references with 0-based code I/O indices.

When behavior feels unclear, inspect routes as contracts: which slot, which edge type, and which eligibility flag controls execution.