.claude/skills/pyzig/SKILL.md
How the Zig↔Python binding layer works (pyzig), including build-on-import, wrapper generation patterns, ownership rules, and where to add new exported APIs. Use when adding Zig-Python bindings, modifying native extensions, or debugging C-API interactions.
npx skillsauth add atopile/atopile pyzigInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
pyzig is the Zig↔Python interoperability layer used by Faebryk’s native modules (graph, sexp, faebryk typegraph, …).
There are three distinct layers to keep straight:
src/faebryk/core/zig/__init__.py (build-on-import + .pyi syncing)src/faebryk/core/zig/build.zig (builds pyzig.so + pyzig_sexp.so, generates stubs)src/faebryk/core/zig/src/pyzig/* (wrapper generation + minimal C-API surface)ato dev compile
python -c "import faebryk.core.zig; import faebryk.core.graph"
src/faebryk/core/zig/__init__.py (ZIG_NORECOMPILE, ZIG_RELEASEMODE, lock, stub syncing)src/faebryk/core/zig/build.zig (builds extensions + runs .pyi generator)src/faebryk/core/zig/src/pyzig/pybindings.zig (minimal CPython C-API declarations)src/faebryk/core/zig/src/pyzig/pyzig.zig (wrapper generation helpers)src/faebryk/core/zig/src/pyzig/type_registry.zig (global type-object registry)src/faebryk/core/zig/src/pyzig/pyi.zig (stub generation helpers)src/faebryk/core/zig/src/python/graph/graph_py.zigsrc/faebryk/core/zig/src/python/sexp/sexp_py.zigsrc/faebryk/core/zig/src/python/graph/*src/faebryk/core/zig/src/python/sexp/*src/faebryk/core/zig/src/python/faebryk/* (and friends)wrap_in_python(...) / wrap_in_python_simple(...).PyTypeObjects for the same Zig type (type_registry).__init__ (by default): many “reference” types are not meant to be user-constructed; pyzig often installs an init that raises.__zig_address__() to help debug pointer identity.src/faebryk/core/zig/src/pyzig/*src/faebryk/core/zig/src/python/**ato dev compile (imports faebryk.core.zig; editable installs compile-on-import)ZIG_RELEASEMODE=ReleaseFast|ReleaseSafe|Debug as neededsrc/faebryk/core/zig/gen/** gets updated (this is driven by src/faebryk/core/zig/__init__.py)python -m faebryk.core.graph (GraphView allocation/cleanup stress)ato dev test --llm test/core/solver (heavy user of graph + bindings via many subsystems).destroy() vs tp_dealloc calling .deinit()).free(...) path and document it.tp_dealloc that calls deinit..pyi surface accurate; many callers rely on types for navigation.src/faebryk/core/zig/__init__.py is responsible for:
ZIG_NORECOMPILE=1)pyzig.so and pyzig_sexp.so from src/faebryk/core/zig/zig-out/lib/.pyi files into src/faebryk/core/zig/gen/** (black + ruff)development
How the Faebryk parameter solver works (Sets/Literals, Parameters, Expressions), the core invariants enforced during mutation, and practical workflows for debugging and extending the solver. Use when implementing or modifying constraint solving, parameter bounds, or debugging expression simplification.
development
# SEXP Benchmark Strategy ## Goal Measure and improve S-expression pipeline performance with a focus on: - Throughput per stage - Peak memory per stage - End-to-end behavior on realistic KiCad PCB inputs ## Pipeline Stages Benchmark these layers separately: - `tokenizer` - `ast` - `parser` (typed decode) - `encode` (typed encode to raw SEXP) - `pretty` (formatting) ## Dataset Dimensions Use a matrix over: - `depth`: shallow vs deep nesting - `size`: small, medium, large Recommended size buck
development
How the Zig S-expression engine and typed KiCad models work, how they are exposed to Python (pyzig_sexp), and the invariants around parsing, formatting, and freeing. Use when working with KiCad file parsing, S-expression generation, or layout sync.
testing
Spec-driven planning for complex design tasks: when to plan, how to write specs as .ato files, and how to verify against requirements.