agni

module
v0.1.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 10, 2026 License: Apache-2.0

README

Agni

CI Go Reference Go Report Card Go 1.26

Agni is an engine for electronic design files. It reads schematics and PCBs from several formats into one neutral, protobuf-defined IR, then checks, diffs, renders, and queries them. The front-end normalizes formats the way a compiler normalizes languages into one AST, so every analysis downstream is written once and works on all of them.

What it does

  • Reads many formats into one IR. EDIF netlists and schematics, KiCad schematics and boards, IPC-2581, xschem, and gEDA all parse into the same ir.Design. Adding a reader is one entry in readers/formats/registry.go.
  • Structural checks (ERC/DRC-like). Missing I2C pull-ups, unprotected exposed signals, power rails without decoupling, boards that fail track-width rules. Findings come out in plain language and cite the net or component they fire on.
  • Revision diff over the IR. Compares two revisions structurally (components, nets, connectivity), not as a text diff of the source files, so it survives reformatting and rename churn.
  • Rendering. Faithful schematic and board geometry, or an auto-laid-out netlist graph, to SVG or a WebGL canvas.
  • A browser viewer. agni serve opens the tree, renders a design, runs the checks, and locates each finding on the canvas.
  • A datalog query surface. Ask arbitrary questions of the design fact base (agni query), the same fact base the rules are built on.
  • A datasheet parameter layer. Join a design against extracted datasheet limits and check, for example, that a rail stays inside a part's recommended operating range.

Try it in 60 seconds

No private data needed. The demo/ folder holds two shareable KiCad boards: a clean one and the same board with deliberate design issues.

git clone https://github.com/panyam/agni
cd agni
make agni
./bin/agni check demo/showcase.fires.kicad_pro
findings by rule:
  bulk-cap               2
  decoupling-present     2
  esd-protection         2
  i2c-pull-up            1
  input-protection       1
  test-point-coverage    2

  [error]   i2c-pull-up: SCL (I2C net has no pull-up resistor)
  [warning] input-protection: VBUS (connector feeds a power input with no fuse or TVS in the path)
  [info]    esd-protection: USB_D+ (externally-exposed signal net has no ESD protection)
  ...

Then open the browser viewer on the same boards:

make demo

Load showcase.fires.kicad_pro in the left tree, press Run checks, and click a finding to locate its net on the schematic. See demo/README.md.

How it works

One contract sits in the middle: the protobuf IR (protos/, generated into gen/). Readers (readers/edif/, readers/kicad/, readers/ipc2581/, and the xschem/gEDA readers) are the only code that knows a file format; they produce ir.Design. Everything else — check/, diff/, render/, the query engine, the web service — consumes the IR and never looks at a source file. Add a reader and every analysis works on the new format for free. Add an analysis and it works on every format for free.

The same shape repeats at two more contracts: a geometry IR that N producers fill and N renderers draw, and a parameter IR that N datasheet extractors fill and the checks read.

Philosophy

  • One neutral IR, many formats. A schematic is a schematic whether it came from KiCad, EDIF, or IPC-2581. Normalize each format once, and write every analysis once against the IR. Add a reader and every check, diff, render, and query works on the new format; add an analysis and it works on every format.
  • Format-neutrality is enforced, not aspirational. Analyses read the IR, never source files, and the IR carries no field a second format could not populate. Architectural constraints checked in CI keep the core from accreting format-specific special cases.
  • Silence is never coverage. A check that cannot evaluate reports "not applicable" or flags what it could not model; it never returns a false pass. Findings cite the net, component, or datasheet page they come from, and unverified data is marked as such. You can always tell "clean" from "not checked".
  • Verify against reality. Readers and rules are checked against the native tools (kicad-cli ERC/DRC) and real design exports, not only hand-written fixtures. A feature is done when it works on a real file.
  • Open core with a clear boundary. The engine is shareable under Apache-2.0. Proprietary formats, house rules, and confidential designs live in a private overlay that depends on the engine without forking it. Company-specific material stays in the overlay, never in the shared engine.
  • Legible to software engineers. EDA carries decades of domain vocabulary. Agni maps it to concepts software engineers already know (an IR, a linter, a semantic diff, a lockfile), so you can contribute without an EE degree. See the software-analogy map.

Formats read today

Format Extensions Netlist Faithful geometry
EDIF 2.0.0 .edn .edf .edif (netlist), .eds (schematic) yes schematic
KiCad .kicad_sch .kicad_pcb .kicad_pro yes schematic + board
IPC-2581 .xml .cvg yes board
xschem .sch (sniffed) yes schematic
gEDA gschem .sch (sniffed) yes schematic

Documentation

Full documentation lives at panyam.github.io/agni.

  • Getting started — build, symbol libraries for xschem/gEDA, native EDA tools, golden comparisons.
  • User guide — concepts, the CLI, checks, diff, and the query language, written for someone new to the tool.
  • Software-analogy map — the hardware-to-software analogy map. If you read code but not schematics, start here.
  • Overview — the engineering docs: IR and ingestion, geometry and rendering, semantic diff, format primers.
  • examples/README.md — runnable walkthroughs, one per feature.
  • CONSTRAINTS.md — the enforceable architectural rules. Read before proposing changes.
  • Open core — the open-core split: this public engine, and how a private overlay adds proprietary readers and rules without forking it.

Status

Agni reads real exports from every listed format and runs its full analysis over them. It is young: the format coverage is bounded (see each reader's notes), the rule catalog is growing, and the datasheet extraction pipeline is early. The architecture is the settled part; the breadth is the work in progress. Issues and readers for new formats are welcome.

Building

Requires Go 1.26 and pnpm (for the web viewer bundle).

cd web && pnpm install && cd ..   # once
make build                        # web bundle + go build ./...
make install                      # install the agni CLI to $GOBIN
make testall                      # the full gate: vet, tests, bundle, web unit tests

License

Apache-2.0. See LICENSE and NOTICE.

Directories

Path Synopsis
Package census is the element-coverage guard (WS6-011).
Package census is the element-coverage guard (WS6-011).
cmd
agni command
Command agni is the CLI umbrella for the EDA tooling engine: read a design into the neutral IR and run analyses over it (stats, checks, diff; rendering and other surfaces will join here).
Command agni is the CLI umbrella for the EDA tooling engine: read a design into the neutral IR and run analyses over it (stats, checks, diff; rendering and other surfaces will join here).
core
check
Package check runs rule checks over a netlist IR Design.
Package check runs rule checks over a netlist IR Design.
check/naming
Package naming compiles an operator-supplied net-naming convention into a check.RuleSource (WS3-015).
Package naming compiles an operator-supplied net-naming convention into a check.RuleSource (WS3-015).
classify
Package classify is the format-neutral component-classification pass (WS3-071).
Package classify is the format-neutral component-classification pass (WS3-071).
diff
Package diff computes a semantic diff between two netlist IR Designs.
Package diff computes a semantic diff between two netlist IR Designs.
graph
Package graph builds a netlist-graph view of a design from the core IR alone, for formats that carry no schematic page (IPC-2581, a bare netlist, a board-only export).
Package graph builds a netlist-graph view of a design from the core IR alone, for formats that carry no schematic page (IPC-2581, a bare netlist, a board-only export).
model
Package model is the design read-surface CONTRACT: the Model interface a rule or query evaluates against, plus the value types that interface exposes.
Package model is the design read-surface CONTRACT: the Model interface a rule or query evaluates against, plus the value types that interface exposes.
query
Package query is the design query surface (WS3-029): a small declarative datalog over the WS3-004 fact base (check.Facts), so an engineer runs ad-hoc queries — "search your whole design as relations, including datasheets" — and every answer carries the provenance of the facts that produced it.
Package query is the design query surface (WS3-029): a small declarative datalog over the WS3-004 fact base (check.Facts), so an engineer runs ad-hoc queries — "search your whole design as relations, including datasheets" — and every answer carries the provenance of the facts that produced it.
render
Package render turns the geometry sidecar (agni.v1.geom) into concrete drawable output.
Package render turns the geometry sidecar (agni.v1.geom) into concrete drawable output.
results
Package results reads and writes the check-result document (agni.v1.checks.CheckResults), the artifact half of the checks contract (WS3-103).
Package results reads and writes the check-result document (agni.v1.checks.CheckResults), the artifact half of the checks contract (WS3-103).
results/foreign
Package foreign imports a check-result document from another tool's report (WS3-104).
Package foreign imports a check-result document from another tool's report (WS3-104).
review
Package review runs a project's declared design-review checklist (a "manifest") against one design and reports, per checklist item, whether its check passed, failed, did not apply, or is not yet automated (WS3-050).
Package review runs a project's declared design-review checklist (a "manifest") against one design and reports, per checklist item, whether its check passed, failed, did not apply, or is not yet automated (WS3-050).
svg
Package svg builds SVG documents ergonomically, replacing hand-formatted fmt.Fprintf calls.
Package svg builds SVG documents ergonomically, replacing hand-formatted fmt.Fprintf calls.
validate
Package validate holds the reader-health invariants behind `agni validate` (WS6-007): structural sanity checks over what a reader produced, catching "parsed but empty" and "placements that resolve to nothing" regressions that per-fixture unit tests miss on real files.
Package validate holds the reader-health invariants behind `agni validate` (WS6-007): structural sanity checks over what a reader produced, catching "parsed but empty" and "placements that resolve to nothing" regressions that per-fixture unit tests miss on real files.
datasheet
derive
Package derive is the deterministic extraction stage of the datasheet pipeline (docs/24-derivation.md): PartSpec = f(document, toolchain, recipes, patches).
Package derive is the deterministic extraction stage of the datasheet pipeline (docs/24-derivation.md): PartSpec = f(document, toolchain, recipes, patches).
doc
Package doc loads, validates, and queries doc-IR Documents (agni.v1.doc): the intermediate decomposition of a source document (datasheet PDF, app note) that sits between the raw bytes and the parameter-IR.
Package doc loads, validates, and queries doc-IR Documents (agni.v1.doc): the intermediate decomposition of a source document (datasheet PDF, app note) that sits between the raw bytes and the parameter-IR.
param
Package param loads and validates parameter-IR PartSpecs (agni.v1.param), the datasheet-parameter contract described in docs/20-parameter-ir.md.
Package param loads and validates parameter-IR PartSpecs (agni.v1.param), the datasheet-parameter contract described in docs/20-parameter-ir.md.
gen
Package intake produces a SANITIZED, deterministic summary of a design — the factual skeleton the /design-intake onboarding workflow builds on (WS3-091).
Package intake produces a SANITIZED, deterministic summary of a design — the factual skeleton the /design-intake onboarding workflow builds on (WS3-091).
internal
expect
Package expect loads a test design's expected findings from a sidecar file, so one artifact drives both the conformance harness (this repo) and, later, the web viewer's expectations panel (roadmap WS9-018).
Package expect loads a test design's expected findings from a sidecar file, so one artifact drives both the conformance harness (this repo) and, later, the web viewer's expectations panel (roadmap WS9-018).
geomath
Package geomath is the shared geometry math for the geom sidecar: mapping symbol-local coordinates into sheet (world) coordinates under a placement Transform.
Package geomath is the shared geometry math for the geom sidecar: mapping symbol-local coordinates into sheet (world) coordinates under a placement Transform.
mounts
Package mounts is the containment boundary of the web tier: named root folders the server exposes, plus the join that keeps every client-supplied path inside its mount.
Package mounts is the containment boundary of the web tier: named root folders the server exposes, plus the join that keeps every client-supplied path inside its mount.
native
Package native shells out to a format's own CLI to produce a golden reference render (SVG), to validate the WebGL/SVG paths against.
Package native shells out to a format's own CLI to produce a golden reference render (SVG), to validate the WebGL/SVG paths against.
netgraph
Package netgraph assembles a pin-level netlist from schematic geometry.
Package netgraph assembles a pin-level netlist from schematic geometry.
server
Package server is the Connect translation layer over the transport-neutral service implementations (CONSTRAINTS C13): one adapter per service, each method a pure unwrap/call/wrap plus the sentinel-to-code mapping in toConnectErr.
Package server is the Connect translation layer over the transport-neutral service implementations (CONSTRAINTS C13): one adapter per service, each method a pure unwrap/call/wrap plus the sentinel-to-code mapping in toConnectErr.
service
Package service holds the importable, transport-neutral service implementations (CONSTRAINTS C13).
Package service holds the importable, transport-neutral service implementations (CONSTRAINTS C13).
sexpr
Package sexpr is the shared s-expression parser for the format readers (KiCad, EDIF) and the coverage census.
Package sexpr is the shared s-expression parser for the format readers (KiCad, EDIF) and the coverage census.
symread
Package symread is the shared rim of the symbol-file schematic readers (xschem, gEDA gschem, and any future dialect such as Lepton EDA): the netlist-tier logic that was byte-identical or constant-parameterized between them.
Package symread is the shared rim of the symbol-file schematic readers (xschem, gEDA gschem, and any future dialect such as Lepton EDA): the netlist-tier logic that was byte-identical or constant-parameterized between them.
version
Package version reports the engine build's identity, so an artifact the engine writes can name what produced it.
Package version reports the engine build's identity, so an artifact the engine writes can name what produced it.
readers
edif
Package edif parses EDIF 2.0.0 netlists into the agni IR.
Package edif parses EDIF 2.0.0 netlists into the agni IR.
formats
Package formats is the single registry of design-file formats the engine reads: for each extension, the UI label, the netlist reader, and the faithful-geometry reader.
Package formats is the single registry of design-file formats the engine reads: for each extension, the UI label, the netlist reader, and the faithful-geometry reader.
geda
Package geda reads gEDA gschem schematic (.sch) and symbol (.sym) files into the agni IR.
Package geda reads gEDA gschem schematic (.sch) and symbol (.sym) files into the agni IR.
ipc2581
Package ipc2581 reads IPC-2581 (revision A/B/C) interchange XML into the neutral IR (agni.v1.ir).
Package ipc2581 reads IPC-2581 (revision A/B/C) interchange XML into the neutral IR (agni.v1.ir).
kicad
Package kicad reads KiCad s-expression files (.kicad_pcb, .kicad_sch) into the neutral IR (agni.v1.ir).
Package kicad reads KiCad s-expression files (.kicad_pcb, .kicad_sch) into the neutral IR (agni.v1.ir).
xschem
Package xschem reads xschem schematic (.sch) and symbol (.sym) files into the agni IR.
Package xschem reads xschem schematic (.sch) and symbol (.sym) files into the agni IR.
stdlib
profiles
Package profiles turns a declarative interface definition into check rules (WS3-034).
Package profiles turns a declarative interface definition into check rules (WS3-034).
relations
Package relations is the standard EDB relation catalog: the built-in "data providers" that project a check.Model (and a seeded datasheet library) into the query engine's fact base — netlist, board, and datasheet relations.
Package relations is the standard EDB relation catalog: the built-in "data providers" that project a check.Model (and a seeded datasheet library) into the query engine's fact base — netlist, board, and datasheet relations.
ruledef
Package ruledef reads and writes rule DEFINITIONS: the declarative source a rule compiles from (WS3-103).
Package ruledef reads and writes rule DEFINITIONS: the declarative source a rule compiles from (WS3-103).
rules/builtin
Package builtin is the standard EE rule catalog: one file per rule (rule_*.go), each a check.Rule value carrying its documentation and an Eval, plus the declarative-twin Specs that the parity tests hold to those Evals.
Package builtin is the standard EE rule catalog: one file per rule (rule_*.go), each a check.Rule value carrying its documentation and an Eval, plus the declarative-twin Specs that the parity tests hold to those Evals.
rules/datalog
Package datalogrules holds check rules authored as datalog queries (via query.RuleFromQuery, WS3-038) rather than as Go or Spec.
Package datalogrules holds check rules authored as datalog queries (via query.RuleFromQuery, WS3-038) rather than as Go or Spec.
rules/intent
Package intent checks a loaded design against a DESIGN-INTENT declaration: an external, authored statement of what a design is SUPPOSED to contain — which modules, which voltage domains — that the netlist is checked against.
Package intent checks a loaded design against a DESIGN-INTENT declaration: an external, authored statement of what a design is SUPPOSED to contain — which modules, which voltage domains — that the netlist is checked against.
tools
catalogdocs command
Command catalogdocs generates the docsite's browsable rule and relation catalog (issue 14) from the composed engine catalog and the embedded per-rule/per-relation Detail markdown.
Command catalogdocs generates the docsite's browsable rule and relation catalog (issue 14) from the composed engine catalog and the embedded per-rule/per-relation Detail markdown.
datasheetstatus command
Command datasheetstatus reports the Stage-A extraction freshness of a datasheet corpus laid out as datasheets/<vendor>/<PART>/ (WS13-009): per part, which source PDFs have a doc-IR sibling, whether that doc-IR still matches the PDF bytes and the installed toolchain, and whether a part-level PartSpec exists.
Command datasheetstatus reports the Stage-A extraction freshness of a datasheet corpus laid out as datasheets/<vendor>/<PART>/ (WS13-009): per part, which source PDFs have a doc-IR sibling, whether that doc-IR still matches the PDF bytes and the installed toolchain, and whether a part-level PartSpec exists.
pdf2doc/validate command
Command validate loads a doc-IR textproto, runs doc.Validate, and prints a per-page region summary.
Command validate loads a doc-IR textproto, runs doc.Validate, and prints a per-page region summary.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL