Logo ProcessCore

Graph Identity, Back-Edges, And Scope

ProcessCore is an object graph with convenience indexes maintained by the model. Understanding a few invariants makes traversal behavior much easier to predict.

Every Process is exactly one directed edge. Input and Output are optional singular nodes; fan-in, fan-out, and parallel lanes use multiple process instances, even when those instances share a name and protocol state.

Shared Node Identity

Samples are equal by Name. Data nodes are equal by Path and Selector.

When a process is added to a dataset, its input and output nodes are canonicalized against the root dataset registry. If another process already uses the same logical node, both processes point to the same object instance after canonicalization. Compatible metadata from the later node is merged into that instance: annotations and nested data parts are accumulated, while missing typed and dynamic fields are filled.

Conflicting non-empty metadata raises a canonicalization error rather than selecting a value by load order. The one role-specific exception is Source plus Sample on the same logical sample; these are compatible endpoint roles and normalize to Sample.

This is why a sample produced by one process can be consumed by another process without manually wiring both processes to the same object instance.

Back-Edges

ProcessCore maintains back-edges when you use the public set/clear methods:

Relationship

Back-edge

Process has input node

Node InputOf contains the process

Process has output node

Node OutputOf contains the process

Dataset has process

Process ProcessOf points to the dataset

Dataset has child dataset

Child PartOf points to the parent

Use SetInputSample, SetOutputData, ClearInput, ClearOutput, AddProcess, and AddPart so these links stay correct.

Scope

Traversal methods on Sample, Data, and IONode can accept a process scope. Dataset-scoped helpers pass dataset.AllProcesses() for you.

Use a scope when:

Without a scope, node-centered traversal follows the node's back-edges directly.

Nested Datasets

Dataset.AllProcesses() walks the dataset and all nested HasPart children. Adding a child dataset re-canonicalizes the child graph against the parent root, so shared sample/data nodes can connect processes across the hierarchy.

Removing a child detaches it and rebuilds the child's own registry so it can act as a root dataset again.

Fragment Selectors

Data identity includes the selector. Two data nodes with the same path but different selectors are distinct nodes. Traversal can still connect them if their selectors are semantically related and the dataset has a matching fragment selector provider registered.

The fragment selector provider walkthrough demonstrates this with CSV row, column, and cell fragments.

What To Use When

Task

API

Add processes safely

dataset.AddProcess

Add nested datasets safely

dataset.AddPart

Connect process I/O safely

SetInputSample, SetInputData, SetOutputSample, SetOutputData

Stay inside a dataset

Dataset-scoped helpers such as NodesUpstreamOf

Query from a node with explicit scope

node.UpstreamNodes(scope = dataset.AllProcesses())

Traverse related fragments

Register an IFragmentSelectorProvider on the dataset

Type something to start searching.