Provides documentation and utility for navigating the instance graph, managing memory, and working with graph references in the codebase.

Install

mkdir -p .claude/skills/graph && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/2103" && unzip -o skill.zip -d .claude/skills/graph && rm skill.zip

Installs to .claude/skills/graph

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

How the Zig-backed instance graph works (GraphView/NodeReference/EdgeReference), the real Python API surface, and the invariants around allocation, attributes, and cleanup. Use when working with low-level graph APIs, memory management, or building systems that traverse the instance graph.
289 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Advanced

Key capabilities

  • Traverse nodes and edges in the instance graph
  • Manage memory invariants for Zig-backed storage
  • Interact with compiler type graph implementations
  • Perform explicit cleanup of graph allocations

How it works

It provides a Python wrapper around a Zig-based graph implementation, using value-like handles to manage nodes and edges in global backing storage.

Inputs & outputs

You give it
Graph node or edge reference
You get back
Traversed graph structure or bound reference

When to use graph

  • Working with low-level graph APIs
  • Navigating the instance graph
  • Debugging memory management issues
  • Developing compiler graph utilities

About this skill

Graph Module

The faebryk.core.graph module is a thin Python wrapper around the Zig graph implementation.

Source-of-truth for behavior is:

  • Zig implementation: src/faebryk/core/zig/src/graph/graph.zig
  • Python bindings: src/faebryk/core/zig/src/python/graph/graph_py.zig
  • Public Python API surface (stubs): src/faebryk/core/zig/gen/graph/graph.pyi

Quick Start

from faebryk.core.graph import GraphView

g = GraphView.create()
try:
    _ = g.create_and_insert_node()
finally:
    g.destroy()

Relevant Files

  • Python wrapper/re-export: src/faebryk/core/graph.py
  • Zig graph core: src/faebryk/core/zig/src/graph/graph.zig
  • Zig → Python wrappers: src/faebryk/core/zig/src/python/graph/graph_py.zig
  • Generated type stubs: src/faebryk/core/zig/gen/graph/graph.pyi

Dependants (Call Sites)

  • src/faebryk/core/node.py (FabLL: nodes/traits are graph-backed)
  • src/atopile/compiler/gentypegraph.py (compiler constructs typegraphs/instances via graph APIs)
  • src/faebryk/core/graph_render.py (graph visualization)

How to Work With / Develop / Test

Mental Model

  • NodeReference / EdgeReference: value-like handles (UUIDs) into global backing storage in Zig.
  • GraphView: a membership + adjacency view over those references (per-view arena + maps + bitsets).
  • BoundNode / BoundEdge: “reference + owning GraphView pointer” wrappers used for traversal helpers.

Core Invariants (do not violate)

  • No direct constructors: GraphView(), NodeReference(), EdgeReference() are not meant to be called; use the exposed factory methods.
    • GraphView.create()
    • NodeReference.create(**attrs)
    • EdgeReference.create(source=..., target=..., edge_type=..., **attrs)
  • Explicit cleanup: GraphView.create() allocates a Zig-side graph on the C allocator; it is freed only by GraphView.destroy().
    • Do not rely on Python GC to reclaim Zig allocations.
  • Attribute limits: node/edge dynamic attributes are fixed-capacity in Zig (currently 6 entries). Exceeding this is a hard failure.
  • Edge type width: edge types are u8 in Zig; treat them as 0..255 in Python (hashing/modulo happens on the Zig side).
  • Self node exists: GraphView.init inserts a self_node; counts include it.

API Cheatsheet (matches src/faebryk/core/zig/gen/graph/graph.pyi)

from faebryk.core.graph import GraphView, Node, Edge

g = GraphView.create()
try:
    n1 = g.create_and_insert_node()           # -> BoundNode
    n2 = Node.create(name="n2")               # -> NodeReference (not inserted yet)
    bn2 = g.insert_node(node=n2)              # -> BoundNode

    e = Edge.create(source=n1.node(), target=bn2.node(), edge_type=7, name="link")
    _be = g.insert_edge(edge=e)               # -> BoundEdge
finally:
    g.destroy()

Debugging

  • GraphView.__repr__() prints GraphView(id=..., |V|=..., |E|=...) from Zig.
  • Graph wrapper has a stress test: python -m faebryk.core.graph (runs test_graph_garbage_collection).

Development Workflow

  1. Zig changes: edit src/faebryk/core/zig/src/graph/*.
  2. Rebuild: ato dev compile (imports faebryk.core.zig, which compiles in editable installs).
  3. If you add/remove exposed methods: update the wrapper in src/faebryk/core/zig/src/python/graph/graph_py.zig and ensure stubs regenerate.

Testing

Key test entrypoints:

  • Python: python -m faebryk.core.graph
  • Zig: zig test src/faebryk/core/zig/src/graph/graph.zig

When not to use it

  • When working with high-level application logic unrelated to the compiler graph

Prerequisites

faebryk core library

Limitations

  • Dynamic attributes are fixed-capacity (6 entries)
  • Requires explicit manual cleanup of graph views

How it compares

It exposes low-level memory management and graph traversal APIs specifically for the compiler's type graph rather than generic graph data structures.

Compared to similar skills

graph side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
graph (this skill)66moNo flagsAdvanced
python-project-structure86moNo flagsBeginner
library15moNo flagsIntermediate
generate-subsystem-skills17moNo flagsAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

Search skills

Search the agent skills registry