How FabLL (faebryk.core.node) maps Python node/trait declarations into the TypeGraph + instance graph, including field/trait invariants and instantiation patterns. Use when defining new components or traits, working with the Node API, or understanding type registration.
cd ~/.claude/skills
git clone https://github.com/atopile/atopile.git atopile mkdir -p ~/.claude/skills/fabll
curl -fsSL https://raw.githubusercontent.com/atopile/atopile/HEAD/.claude/skills/fabll/SKILL.md \
-o ~/.claude/skills/fabll/SKILL.md fabll (primarily src/faebryk/core/node.py) is the high-level Python API for defining and working with hardware components. It bridges the gap between Python classes and the underlying TypeGraph and instance graph.
import faebryk.core.faebrykpy as fbrk
import faebryk.core.graph as graph
import faebryk.core.node as fabll
g = graph.GraphView.create()
tg = fbrk.TypeGraph.create(g=g)
class _App(fabll.Node):
pass
app = _App.bind_typegraph(tg=tg).create_instance(g=g)
src/faebryk/core/node.py (Node/Traits/fields, type registration, binding/instantiation helpers)src/faebryk/core/faebrykpy.py (edge types used by FabLL under the hood)src/faebryk/core/graph.py (GraphView wrapper used by instances)src/faebryk/library/): Every component (Resistor, Capacitor, etc.) inherits from Node.Node subclasses dynamically from ato files.Node instances to extract parameters and constraints.fabll.Node is constructed with a graph.BoundNode.SomeType.MakeChild(...)Traits.MakeEdge(SomeTrait.MakeChild().put_on_type()) (or similar)MyType.bind_typegraph(tg).create_instance(g)faebryk.library.*) intentionally have short identifiers (class name) for ato importsNode._register_type)src/faebryk/core/node.py (field system).__init_subclass__).ato dev test --llm test/core/test_node.py -q and ato dev test --llm test/library/test_traits.py -qNode subclasses if they can be a Trait. This allows them to be applied to different component families.Node.__init_subclass__).EdgeTrait.traverse(trait_type=...).MyNode() with no args: instances are created from a bound type via bind_typegraph(...).create_instance(...).import faebryk.core.graph as graph
import faebryk.core.faebrykpy as fbrk
g = graph.GraphView.create()
tg = fbrk.TypeGraph.create(g=g)
inst = MyNode.bind_typegraph(tg).create_instance(g=g)
Node.__init_subclass__ forbids “deeper than one level” inheritance for node types.Node subclasses that typically contain an ImplementsTrait edge.class MyTrait(Node):
is_trait = Traits.MakeEdge(ImplementsTrait.MakeChild().put_on_type())
node_instance.get_trait(TraitType) to retrieve a trait instance. This performs a graph traversal.EdgeComposition. add_child creates this edge. Large trees (10k+ nodes) should be constructed carefully to avoid Python loop overhead; the underlying graph is efficient, but Python interactions cost time.Use when facing 2+ independent tasks that can be worked on without shared state or sequential dependencies
Use when you have a written implementation plan to execute in a separate session with review checkpoints
Use when executing implementation plans with independent tasks in the current session
Use when encountering any bug, test failure, or unexpected behavior, before proposing fixes
Use when implementing any feature or bugfix, before writing implementation code
Use when creating new skills, editing existing skills, or verifying skills work before deployment