On this page
- SystemGraphView
SystemGraphViewSystemGraphView._adjacencySystemGraphView.node_countSystemGraphView.edge_countSystemGraphView.relationsSystemGraphView.node_ids()SystemGraphView.node()SystemGraphView.find_nodes()SystemGraphView.nodes_in()SystemGraphView.node_at()SystemGraphView.edges_from()SystemGraphView.edges_to()SystemGraphView.neighbors()SystemGraphView.walk()SystemGraphView.impact()SystemGraphView.details_key()SystemGraphView.describe()
SystemGraphView๏
Receive this surface through md.graph_network and md.graph_details; use that owning object's public entry point.
- class SystemGraphView(entry: Mapping[str, object])[source]๏
A document view that is also a walkable graph.
- Purpose:
Backs __graph_network__ and __graph_details__. Both address the same document; this adds the adjacency resolved at build time, so a node's neighbours are a dict lookup instead of a parse.
- Contract:
The adjacency module is imported on FIRST graph access, never at construction. A process that imports melder and never walks pays nothing for the tables.
Extractor candidates are absent by design. They over-generate roughly 8x against a hand-authored graph and are leads, not evidence; they are not in the shipped adjacency, so no walk can traverse a guess by accident.
- _adjacency๏
The lazily imported generated adjacency module.
AGENT_ACCESS: public
- AGENT_PURPOSE:
access: public. What melder.__graph_network__ and __graph_details__ return - everything SystemDocumentView does, plus traversal. edges_from/edges_to/neighbors/walk move through adjacency resolved at build time, so reverse lookup costs the same as forward. impact(node) turns a change into the files it would touch. describe(node) reads the prose for any node a walk reached. Extractor guesses are absent by construction.
- property node_count: int๏
Return how many nodes the graph carries.
- property edge_count: int๏
Return how many edges the graph carries, candidates excluded.
- property relations: Tuple[str, ...]๏
Return every relation name present, sorted.
- Purpose:
The vocabulary of the graph. An agent filtering a walk needs to know what it may filter ON without sampling edges to find out.
- node(node_id: str) Node[source]๏
Return one node by id.
- Parameters:
node_id -- Fully qualified node id.
- Returns:
The node record.
- Return type:
Node
- Raises:
KeyError -- When no such node exists, with close matches offered.
- find_nodes(needle: str) Tuple[Node, ...][source]๏
Return nodes whose id contains needle, case-insensitively.
- Parameters:
needle -- Substring to match against node ids.
- Returns:
Matching nodes, sorted by id.
- Return type:
Tuple[Node, ...]
- nodes_in(source_path: str) Tuple[Node, ...][source]๏
Return every node defined in one source file.
- Purpose:
The bridge from a file to its nodes. source_path is also this document's section key, so a caller holding a section key can immediately ask what lives in it.
- Parameters:
source_path -- Repository-relative path.
- Returns:
Nodes defined there, ordered by definition line.
- Return type:
Tuple[Node, ...]
- node_at(source_path: str, line: int) Node | None[source]๏
Return the node most likely to enclose a line of source.
- Purpose:
Closes the loop from a traceback. conduit.py:412 is otherwise a dead end - the graph knows definition lines, so an agent can infer the enclosing node by hand, but nothing in the API does it.
- Contract:
AN INFERENCE, NOT A FACT, and named to admit it. The graph records where each node BEGINS, never where it ends, so this returns the last node defined at or before line. That is right for a line inside the last class in a file and WRONG for a line in a module-level function that follows one - it will name the class.
Verify against the source before citing it. Returns None when the file has no nodes or every node is defined after the line.
- Parameters:
source_path -- Repository-relative path, as the index keys it.
line -- 1-based line number in that source file.
- Returns:
The enclosing candidate, or None.
- Return type:
Optional[Node]
- edges_from(node_id: str, *, relation: str | None = None) Tuple[Edge, ...][source]๏
Return edges leaving a node.
- Parameters:
node_id -- Fully qualified node id.
relation -- Optional relation filter.
- Returns:
Outbound edges, empty when the node has none.
- Return type:
Tuple[Edge, ...]
- edges_to(node_id: str, *, relation: str | None = None) Tuple[Edge, ...][source]๏
Return edges arriving at a node.
- Purpose:
Reverse lookup - "what points AT this". Reading the document, this is the expensive query: sections carry outbound edges only, so answering it by hand means scanning every section. Resolved once at build time, it costs the same as the forward direction.
- Parameters:
node_id -- Fully qualified node id.
relation -- Optional relation filter.
- Returns:
Inbound edges, empty when nothing points at it.
- Return type:
Tuple[Edge, ...]
- neighbors(node_id: str, *, direction: str = 'out', relation: str | None = None) Tuple[str, ...][source]๏
Return the node ids one step away.
- Parameters:
node_id -- Fully qualified node id.
direction -- out, in, or both.
relation -- Optional relation filter.
- Returns:
Neighbour ids, de-duplicated, order preserved.
- Return type:
Tuple[str, ...]
- Raises:
ValueError -- When direction is not one of the three.
- walk(node_id: str, *, depth: int = 2, direction: str = 'out', relation: str | None = None, origin: str | None = None) Iterator[Tuple[int, Edge]][source]๏
Traverse outward from a node, breadth-first.
- Purpose:
The walk the whole asset exists for. Yields as it goes, so an agent can stop at the first useful hop instead of materialising a subgraph it will discard.
- Contract:
Breadth-first, so shallower relationships arrive first. Every node is expanded at most once - the graph has cycles (borrows and used_by run both ways) and an unguarded walk would not terminate. An edge to a node outside the graph is still yielded, then not expanded; the relationship is real even where the target is not described here.
- Parameters:
node_id -- Node to start from.
depth -- Maximum hops. 1 is immediate neighbours.
direction -- out, in, or both.
relation -- Optional relation filter, applied to every hop.
origin -- Optional trust filter - authored or derived. Use it to walk only mechanical structure, or only authored design.
- Yields:
Tuple[int, Edge] -- Hop number, 1-based, and the edge traversed.
- Raises:
KeyError -- When the starting node is not in the graph.
ValueError -- When depth is below 1 or direction is invalid.
- impact(node_id: str, *, depth: int = 2, relation: str | None = None, origin: str | None = None) Tuple[Impact, ...][source]๏
Return the FILES affected by changing a node, ranked by proximity.
- Purpose:
"I am about to change this - what breaks?" is the most common reason to walk inbound, and the walk answers it in the wrong currency. It yields edges; a caller needs files to open. Deriving one from the other by hand every time is the friction this removes.
- Contract:
Walks INBOUND - dependents, not dependencies - and collapses the result per defining file. hops carries the shortest distance found, so sorting puts direct dependents first; a file reached at hop 1 is far more likely to break than one reached at hop 3.
Nodes outside the described graph are skipped rather than guessed at, so the result is only ever files this graph can actually name.
- Parameters:
node_id -- The node being changed.
depth -- How far to propagate. 1 is direct dependents only.
relation -- Optional relation filter.
origin -- Optional trust filter - authored or derived.
- Returns:
Affected files, nearest first, then by path.
- Return type:
Tuple[Impact, ...]
- Raises:
KeyError -- When the node is not in the graph.
ValueError -- When depth is below 1.
- details_key(node_id: str) str[source]๏
Return the section key describing a node's defining file.
- Purpose:
The join. A walk produces node ids; the prose is addressed by source path. This converts one into the other, so view.get(view.details_key(node_id)) reads the description of any node a walk reached.
- Parameters:
node_id -- Fully qualified node id.
- Returns:
The section key in the graph document.
- Return type:
str
- Raises:
KeyError -- When the node is not in the graph.
- describe(node_id: str) str[source]๏
Return the document section describing a node's defining file.
- Parameters:
node_id -- Fully qualified node id.
- Returns:
The section text.
- Return type:
str
- Raises:
KeyError -- When the node or its section is absent.
RuntimeError -- When the document is unavailable.