Full KiCad DRC audit — catches net shorts, unconnected pads, dangling vias, and clearance violations that custom scripts miss
Deep electrical verification using KiCad DRC that covers gaps in our custom DFM/DFA scripts.
Our custom scripts (verify_dfm_v2.py, verify_dfa.py) check manufacturing rules but
deliberately ignore critical KiCad DRC categories:
| KiCad DRC category | Custom scripts | This skill |
|---|---|---|
shorting_items | IGNORED | CHECKED |
unconnected_items | IGNORED | CHECKED |
via_dangling | IGNORED | CHECKED |
clearance | IGNORED | CHECKED |
solder_mask_bridge |
| IGNORED |
| CHECKED |
track_dangling | IGNORED | CHECKED |
copper_edge_clearance | ≤5 tolerated | ANALYZED |
hole_clearance | ≤1 tolerated | ANALYZED |
silk_over_copper | ≤2 tolerated | ANALYZED |
Additionally, verify_dfm_v2.py test 43 (trace-pad different-net) auto-skips when >90%
of pads have net=0, which is exactly the condition this skill detects.
kicad-cli pcb drc \
--output /tmp/drc_audit_report.json \
--format json \
--severity-all \
--units mm \
--all-track-errors \
hardware/kicad/esp32-emu-turbo.kicad_pcb
import json
from collections import Counter
with open('/tmp/drc_audit_report.json') as f:
data = json.load(f)
violations = data.get('violations', [])
unconnected = data.get('unconnected_items', [])
# Count by type
types = Counter(v['type'] for v in violations)
Report every category — do NOT skip any.
For each shorting_items violation, check if the description matches "nets XXX and )" (empty second net).
"nets XXX and )" → pad-net assignment bug (pad has no net, trace touches it)"nets XXX and YYY)" → REAL SHORT (two different nets touching — critical)Count separately:
Real net-vs-net shorts: X ← CRITICAL, board will malfunction
Pad-net assignment bugs: Y ← Generator bug, needs _init_pads() fix
If pad-net bugs are found:
# Run routing to populate _PAD_NETS
from generate_pcb import routing
routing.generate_all_traces()
pad_nets = routing.get_pad_nets()
# Check which component refs have NO pad-net assignments
all_refs_with_nets = set(k[0] for k in pad_nets.keys())
# Compare against all component refs in the PCB
For each missing ref, check if it's in routing.py:_init_pads(). Missing refs are the root cause.
For each unconnected_items entry:
For each clearance violation:
For each via_dangling:
## DRC Audit Report
### Summary
| Category | Count | Severity |
|----------|-------|----------|
| Real net shorts | X | CRITICAL |
| Pad-net bugs | Y | HIGH (generator fix) |
| Unconnected items | Z | HIGH |
| Clearance violations | W | MEDIUM-HIGH |
| Dangling vias | V | MEDIUM |
| Solder mask bridge | S | LOW (cascading) |
### Real Net Shorts (CRITICAL)
[list each with position, nets involved]
### Pad-Net Assignment Failures
[list missing refs, root cause in _init_pads()]
[fix: add to passive_placements list]
### Unconnected Items
[group by net, identify break location]
### Clearance Violations
[list with gap values, flag <0.05mm]
### Dangling Vias
[list with position, suggest remove or connect]
### Action Items
1. [prioritized fixes]
After applying fixes, re-run steps 1-2 and confirm:
Never trust custom scripts alone. KiCad DRC checks electrical connectivity
at the netlist level — something our geometry-based scripts cannot do. Run this
audit after every generate_pcb and before every /release.
hardware/kicad/esp32-emu-turbo.kicad_pcb — PCB file to auditscripts/generate_pcb/routing.py — _init_pads() and _PAD_NETS (pad-net assignment)scripts/generate_pcb/board.py — _inject_pad_net() (net injection into KiCad file)scripts/verify_dfm_v2.py — Custom DFM (115 tests, misses electrical shorts)scripts/verify_dfa.py — Custom DFA (9 tests, misses electrical shorts)