The graph is well-formed and names what exists – 12 codes.
Each engine decides one kind of relation; a finding's code is ENGINE.relation. Severities are the catalog's defaults – a project's domains may set others; a grade is a sub-case with its own severity, a topic the part of a code a domain switches on.
STRUCT.name names unique
error
Every designator and every net name occurs once in the graph.
structure: unique designators and nets, every pin in exactly one net or nc, nets with ≥ 2 pins, a voltage range per net, a known board per part, bom: false on a bought or hand-wired board, nets across boards only through a cable; the names in layout and locks, the ground net, purpose.use – finds e.g.: a forgotten pin, a typo in a pin reference
Why
Everything after the graph is generated from it; two parts or nets of one name make every later step pick one of them.
What to do
Rename one of the two.
Sources
edakit handbook 3.1 and 3.2
Replaces G-1
STRUCT.pin every pin in one net or nc
error
Every pin of a part is in exactly one net or listed in the part's nc, a net names only pins the part has, and a pin in nc is in no net. A pin is written by its number, its name or its role – read in that order, a name or role several pins share standing for all of them (handbook 3.1) –; a word that names no pin of its part, in a net, nc, locks.pins, layout.loops or a cable, is reported where it stands, and so is a word that names several pins where one is meant (a loop end, a cable's wire).
Why
A pin that is neither connected nor declared open is usually forgotten; a pin in two nets shorts them; a pin word that names no pin is a typo the rest of the checks would read past.
What to do
Connect the pin, add it to nc when it is meant to stay open, or correct the pin reference – its number, or the name or role its parts entry gives it (edakit graph show <designator> lists every pin with its name and role).
Sources
edakit handbook 3.1 and 3.2
Replaces G-1
STRUCT.net nets well-formed
error
Every net has at least two pins and a voltage range v = [min, max]; a net that spans boards does so through a cable, and the two pins of a cable wire are on one net.
Why
A net with one pin is a typo or an unfinished connection; a net without a voltage range cannot be compared with pin limits; a net across boards without a cable has no copper.
What to do
Complete the net, give it its range over all operating states, or add the cable.
Sources
edakit handbook 3.1 and 3.2
Replaces G-1
STRUCT.board every part on a board
errorwired: note
Every part is on a board of edakit.toml [boards]; a part on a bought board (bought = true) or a hand-wired one (wired = true) stays out of the BOM (bom: false). A bought board none of whose parts is a module – parts wired by hand rather than one purchased assembly – gets a note that names wired = true (grade wired).
Why
Plan, BOM and placement are per board; a part on no board is assembled nowhere, one on a bought or hand-wired board by no assembler. bought = true on a front panel of LEDs, switches and jacks works – no PCB, no assembler – but says something else: that the board is one purchased assembly (maker-coverage FT-2).
What to do
Set board, or bom: false for a part on a bought or hand-wired board. For parts wired by hand: wired = true instead of bought = true in edakit.toml [boards.<name>].
Sources
edakit handbook 3.1, 3.2 and 4.5
rules-at-scale.md, decision 22 (2026-10-31): a hand-wired board gets a key of its own instead of bought (grade wired; maker-coverage FT-2)
Replaces G-1
STRUCT.ref settings name what exists
error
Every name a setting of the graph uses – ground, grounds, locks, a reversible source, layout requirements, purpose.radio – is a part, pin or net of the graph.
Why
A setting that names a missing part checks nothing and says so nowhere.
The graph states purpose.use – private, gift or sale –, purpose.radio, where given, is "off" or the bands (and power) the firmware keeps, each within the part's own bands, and purpose.country, where given, is the ISO 3166-1 alpha-2 code of a member state of the EU (handbook 15.6).
Why
Severities follow the purpose (the profile), and the regulatory review (M-6) starts there.
What to do
Write purpose.use; correct purpose.radio to {"U1": "off"} or {"U1": {"bands_mhz": [[from, to]], "max_dbm": …}}; purpose.country as "AT".
Sources
edakit handbook 3.1 and 3.2
edakit handbook 15.1 and 15.2
Replaces G-1, G-25
STRUCT.lock pins where the firmware expects them
error
Every pin in locks.pins is on its net, and a pin table in a document (locks.doc_pin_table) lists exactly the connected pins.
pin locks: pins the firmware relies on are on the expected nets (locks.pins); optionally a pin table in a Markdown document equals the graph (locks.doc_pin_table) – finds e.g.: firmware and hardware disagree
Why
Firmware and hardware change in different files, often in different sessions. A GPIO that moved compiles fine and fails on the board.
What to do
Change graph, firmware pin table and locks in one commit; regenerate generated tables.
Sources
edakit handbook 3.3
Replaces G-2
STRUCT.domain suggested domains on
note
Every domain the graph suggests (edakit/domains, suggested_by) is named in [project] domains, when the project names its domains.
Why
A domain that is off reports nothing: an audio board without the domain audio passes its audio codes without a word.
What to do
Add the domain to [project] domains, or accept STRUCT.domain <domain> with the reason (edakit domains lists them).
The running edakit meets [project] edakit, where the project names it – ">=0.4", ">=0.4, <0.5" (handbook 2.3).
Why
Skills and the command line come from the plugin; a project that needs a newer one – a key, a check – is checked by an older one without a word.
What to do
Update the plugin (claude plugin marketplace update edakit, then claude plugin update edakit@edakit), or run the edakit the project names.
Sources
Concept docs/concepts/done/versioning.md, V.7
STRUCT.entry graph pins = parts entry
errorsymbol: errordeclared: notestrip: warning
Every part with an LCSC number or a part number has a parts entry, its pins (number and name) equal the entry's where the component states them – without pins it takes the entry's, and only the comparison with the library symbol is left; without an entry as well, the numbers its nets and nc use, so that the rest is checked –, no supply pin is in nc, a component's config names one of its entry's configs and its states name output or bidirectional pins of the entry, each high, low or off (high not on an open-drain output), and – with the library symbol cached by edakit part import – the pins equal that symbol (case and blanks ignored); the symbol gives no number to two pins and has a pin for every pad of its footprint (grade symbol). Pins the entry's symbol_differs names follow the datasheet against the symbol on purpose: left out of the comparison and named in a note with the reason (grade declared). An LED strip (kind led_strip) gives its length, strip.length_m or strip.pixels (grade strip).
graph pins (number and name) = parts entry where the component states pins (without them it takes the entry's map, 3.1) – where they differ and the library symbol is cached, the finding says whether the symbol agrees with the entry (the graph has another part's pins) or with the graph (the entry to be checked against the datasheet); an entry exists for every LCSC number; no supply pin marked nc; with the library's symbol cached by edakit part import, graph pins = that symbol (case and blanks ignored, as SYNC.schematic; accept on the component) – not where the entry's footprint data builds the copy's symbol as a box ("symbol": "box", 4.5): the carrier's library symbol is not the copy's; the cached symbol giving one number to two pins or no pin to a pad of its footprint is grade symbol; pins the entry names in symbol_differs ({"<pin>": "reason from the datasheet"}) are left out of the comparison and named in a note (grade declared) – finds e.g.: a wrong part number, pins shifted by one, an LED whose pin 1 is the cathode, a library symbol that numbers a data input like the ground pin
Why
Checks, simulation, schematic and BOM all read the parts entry. A shifted pin number or a missing entry makes them reason about another part than the one assembled. The library symbol is what a schematic is drawn from: a number it gives to two pins joins them on one pad (the WS2812B-V5/W's DIN on VSS), a pad it has no pin for stays unconnected (the DRV8825's PowerPAD), names swapped against the datasheet feed a regulator backwards (the XC6206) – the netlist inherits it whatever the parts entry says.
What to do
No parts entry: create it (part-search skill); edakit part import <LCSC> reads its pins from the library symbol. Pins differ from the parts entry: either the wrong part is placed – the part number of the part whose pins the graph has, or, to keep this part, the component's pin names and the nets on its pins swapped to the entry's (an LED whose pin 1 is the cathode), or the nets' pins written by role or name (D2.anode) and the component's pins left out, so that the entry says which pin is which (handbook 3.1) –, or the entry is wrong – its pins corrected from the datasheet; with the library symbol cached the finding says which of the two the symbol agrees with. Pins differ from the library symbol where graph and entry agree – a symbol that differs from the datasheet: another part number whose symbol is right, an own symbol, or – where the entry follows the datasheet – symbol_differs in the entry with the reason, and the schematic checked pin by pin against the datasheet; report the symbol to the library (upstream/issue-6-easyeda-symbols.md); where the graph differs from the entry too, the advice for pins that differ from the parts entry. A supply pin marked nc: the pin on its supply's net, or its type corrected from the datasheet. A config the entry does not know: one of the names the finding lists, or the configuration added to the entry's configs from the datasheet. A state: the pin's number or name in the entry, and high, low or off. An LED strip: its length, strip.length_m or strip.pixels.
Sources
edakit handbook 3.2 and 4.1
Replaces P-1
STRUCT.identity graph and entry name the same part
error
A component names the part of its entry: the entry's lcsc is its file name, the component's lcsc is no C99… user-library number (unless bom: false), its part names the entry's mpn, its value reads as the entry's value within 1 %, its type fits the entry's kind.
part identity: the component and its parts entry name the same part – the entry's lcsc is its file name; the component's lcsc is no C99… user-library number (unless bom: false); its part names the entry's mpn (remarks in parentheses or after ; left out, case ignored, a manufacturer before it allowed; a part that starts with a value, "330 Ω 0805", is compared as that value); its value reads as the entry's value_ohm / value_f / value_h within 1 % ("4k7", "100nF", "2R2"); its type fits the entry's kind (microcontroller, regulator: ic or module; transistor: npn, pnp, nmos, pmos, njfet, pjfet; led: led, led_rgb; switch: switch, dip_switch; audio: buzzer; otherwise the same word); accept on the component. A designator prefix against the kind (R, C, L, D, Q, U, J, SW, F, BT, BZ, K, TP) is a warning – finds e.g.: C25789 written for a 74HC165 (a 464 kΩ resistor), R2 "1k" on a 10 kΩ entry, an LED that came in as U1
Why
A wrong LCSC number with the right value text gets the wrong part assembled while every check reasons about the entry.
What to do
Correct the component's lcsc, part, value or type, or the entry.
Sources
edakit handbook 3.1 (component fields type, lcsc, part, value), 4.1 (entry fields, kind, value parameters) and 4.2 (exact match only, C99… user libraries)
pytree: decision E-15, invalid LCSC numbers checked against LCSC on 2026-10-19 (C25789, C124327, C299999, C17236, C15942, C124278, C124279, C17347) and replaced
Replaces P-6
STRUCT.prefix designator prefix fits the kind
warning
The designator's letters fit the kind of its entry (R resistor, C capacitor, D diode or LED, Q transistor, U IC or module, J connector, SW switch, F fuse, BT battery holder, BZ buzzer, K relay, TP test point).
Why
Readers of schematic and board find a part by its letters; a Q that is a diode misleads assembly and review.
What to do
Rename the part, or accept the code with the reason.
Sources
edakit handbook 3.1 (component fields type, lcsc, part, value), 4.1 (entry fields, kind, value parameters) and 4.2 (exact match only, C99… user libraries)
pytree: decision E-15, invalid LCSC numbers checked against LCSC on 2026-10-19 (C25789, C124327, C299999, C17236, C15942, C124278, C124279, C17347) and replaced