Analyze KiCad projects and PDF schematics: schematics, PCB layouts, Gerbers, footprints, symbols, netlists, and design rules. Reviews designs for bugs, traces nets, cross-references schematic to PCB, extracts BOM data, checks DRC/ERC, DFM, power trees, and regulator circuits. Every finding carries a confidence label and evidence source with trust_summary rollup. Analyzes PDF schematics from dev boards, reference designs, eval kits, and datasheets. Supports KiCad 5–10. Use whenever the user mentions .kicad_sch, .kicad_pcb, .kicad_pro, PCB design review, schematic analysis, PDF schematics, reference designs, Gerber files, DRC/ERC, netlist issues, BOM extraction, signal tracing, power budget, DFM, or wants to understand, debug, compare, or review any hardware design. Also for "check my board", "review before fab", "what's wrong with my schematic", "is this ready to order", "check my power supply", "verify this circuit", or any electronics/PCB design question.
| Skill | Purpose |
|---|---|
bom | BOM extraction, enrichment, ordering, and export workflows |
digikey | Search DigiKey for parts (prototype sourcing) |
mouser | Search Mouser for parts (secondary prototype source) |
lcsc | Search LCSC for parts (production sourcing, JLCPCB) |
element14 | Search Newark/Farnell/element14 (international sourcing, reliable datasheets) |
jlcpcb | PCB fabrication & assembly ordering |
pcbway | Alternative PCB fabrication & assembly |
spice | SPICE simulation verification of detected subcircuits |
emc | EMC pre-compliance risk analysis — consumes schematic + PCB analyzer output |
Use this skill to parse schematics/PCBs and extract structured data. Hand off to for BOM enrichment, pricing, and ordering. Hand off to /// for part searches and datasheet fetching. Hand off to / for fabrication ordering and DFM rule validation. for simulation verification during design reviews when any SPICE simulator is installed (check with ). for EMC pre-compliance risk analysis during design reviews when both schematic and PCB analysis are available. These are not optional — skipping them leaves value-computation errors and EMC risks undetected.
bomdigikeymouserlcscelement14jlcpcbpcbwayspicewhich ngspice ltspice xyceemcBefore analysis: When the user asks to analyze or review a KiCad project, check whether a datasheets/ directory exists in the project. If not, and DigiKey API keys are available (DIGIKEY_CLIENT_ID), offer to sync datasheets first: "I can download datasheets for your components before analysis — this enables pin-level verification and decoupling validation against manufacturer specs. Want me to sync them?" If the user declines or no API keys are set, proceed without datasheets — the analysis works without them but datasheet verification findings won't be available.
If you see a DS-001 finding in the analyzer output (severity high, detector audit_datasheet_coverage), the review cannot make any verified claim. Stop and either (a) run the datasheet sync via digikey / mouser / lcsc / element14 (whichever has credentials/stock), (b) populate MPNs on the BOM parts, or (c) state explicitly in the report that every pin-level, electrical, and regulator finding is consistency only — do not use the words "verified", "confirmed", or "per datasheet" anywhere. DS-002 (datasheets missing but MPNs set) and DS-003 (partial MPN coverage) are softer variants with the same implication for the parts they cite.
This skill also handles PDF schematics — reference designs, dev board schematics, eval board docs, application notes, and datasheet typical-application circuits. Common use cases:
Workflow: Read the PDF pages visually → identify components and connections → extract structured data → translate to KiCad symbols and nets → validate against datasheets.
For the full methodology — component extraction, notation conventions, net mapping, subcircuit extraction, KiCad translation, and validation — read references/pdf-schematic-extraction.md.
For deep validation of extracted circuits against datasheets (verifying values, checking patterns, detecting errors), use the methodology in references/schematic-analysis.md.
This skill includes Python scripts that extract comprehensive structured JSON from KiCad files in a single pass. Run these first, then reason about the output.
Read analyzer JSON output directly rather than writing ad-hoc extraction scripts. The JSON schema has specific field names (documented below and in references/output-schema.md) that are easy to get wrong in custom code. To extract a specific section: python3 -c "import json; d=json.load(open('file.json')); print(json.dumps(d['key'], indent=2))".
When the JSON surprises you — an AttributeError, unexpected shape, field
returning None that "should" have a value — stop and run --schema before
writing a second extraction attempt. It prints the exact field names and
types for every top-level key:
python3 <skill-path>/scripts/analyze_schematic.py --schema
python3 <skill-path>/scripts/analyze_pcb.py --schema
python3 <skill-path>/scripts/analyze_gerbers.py --schema
JSON field cheat sheet — the most common mistakes when reading analyzer output by hand:
| What you want | Correct path and field | Common mistake |
|---|---|---|
| Pins on a net | nets[<name>].pins[].component / .pin_number / .pin_name / .pin_type | ref, pin, type, number |
| Unnamed-net pretty display | nets[<name>].display_name — when set, a Ref.PinName hint for an __unnamed_N net whose only named IC pin tells the story (e.g. __unnamed_36 → U1.VBOOT). Absent means the analyzer couldn't disambiguate. | Ignoring display_name and pasting raw __unnamed_36 into the report |
| IC pin map | ic_pin_analysis[] is a list of IC entries; each has .reference and .pins[] with .pin_number / .pin_name / .pin_type / .net / .connected_to[] | Treating it as {ref: {...}} or pins[].number |
| Detected circuits | Every pattern-matched circuit (power regulators, RC filters, crystal oscillators, bridges, …) lives in findings[] — filter with finding_schema.get_findings(data, Det.POWER_REGULATORS) etc. Do not read from subcircuits[]: that's an IC-neighborhood grouping ({center_ic, ic_value, neighbor_components, …}), not a categorized detection index | Looking for subcircuits.power_regulators, subcircuits.rc_filters, or any subcircuits[type] key — these never existed in v1.3 output |
| Zone net | pcb.zones[].net is an integer net ID, not a string. Use f"{net!r}" or convert first | f"{net:20s}" — crashes with ValueError: Unknown format code 's' for object of type 'int' |
| Footprint position | pcb.footprints[].x / .y at top level (no .position wrapper) | footprints[].position.x |
| Findings | findings[] flat list — each has rule_id, detector, severity, summary, report_context. Filter with finding_schema.get_findings(data, Det.*) or group_findings(data) | Looking for keyed dicts like signal_analysis.power_regulators[] (pre-v1.3 format, removed) |
This prevents format-string bugs and wrong field names. Use f-strings or json.dumps() for output formatting — never %s with non-string types. See references/output-schema.md for the full schema with common extraction patterns.
In all commands below, <skill-path> refers to this skill's base directory (shown at the top of this file when loaded).
python3 <skill-path>/scripts/analyze_schematic.py <file.kicad_sch> --analysis-dir analysis/
python3 <skill-path>/scripts/analyze_schematic.py <file.kicad_sch> --analysis-dir analysis/ --compact
python3 <skill-path>/scripts/analyze_schematic.py <file.kicad_sch> --output analysis.json # one-off, no cache
Outputs structured JSON (~60-220KB depending on board complexity) with:
findings[] entries with matching Det.* detectors; use get_findings(data, Det.POWER_REGULATORS) etc. to fetch):
vref_source (lookup/heuristic/fixed_suffix) and vout_net_mismatch fieldsSupports modern .kicad_sch (KiCad 6+) and legacy .sch (KiCad 4/5). Hierarchical designs parsed recursively.
Legacy format: For KiCad 5 legacy .sch files, the analyzer parses .lib files (cache libraries and project libs) to populate pin data. Pin-to-net mapping, signal analysis, and subcircuit detection all work when .lib files are available. Coverage is typically 92–100% — components whose .lib files are missing (standard KiCad system libs not in the repo) will lack pin data. Built-in fallbacks cover 40+ common symbols (R, C, L, D, LED, transistors, MOSFETs, crystals, switches, polarized caps, connectors up to 20-pin, resistor packs) with mil-based pin offsets and automatic wire-snap correction for version-mismatched pin positions.
When analyze_schematic.py returns incomplete data (components with missing pins due to unavailable .lib files), use additional project files to recover full analysis capability. The most valuable source is the .net netlist file, which provides explicit pin-to-net mapping that closes any remaining gaps.
For detailed parsing instructions, data recovery workflows, and a priority matrix of supplementary sources (netlist, cache library, PCB cross-reference, PDF exports), read references/supplementary-data-sources.md.
Verify analyzer output against reality. The analyzer can silently produce plausible-looking but incorrect results — wrong voltage estimates, missing MPNs, wrong pin-to-net mappings. These don't cause script errors; they just produce bad data that flows into your report. In testing across multiple boards, every project had at least one misleading analyzer output. Cross-reference against the raw .kicad_sch file:
(symbol (lib_id blocks, subtract power symbols. Must match analyzer count exactly.Q_NPN_BEC = pin 1=B, 2=E, 3=C) that doesn't match the actual part. Everything passes consistency checks, but the board is wrong. To catch this:
lib_id suffix encodes a pin ordering assumption. SOT-23 BJTs exist in at least 6 pinout variants (BEC, BCE, EBC, ECB, CBE, CEB); SOT-23 MOSFETs in GDS, GSD, SGD, DSG. If no MPN is specified, there's no way to verify the assumption — flag this as a critical ambiguity.vref_source field. "lookup" means datasheet-verified (~60 families); "heuristic" means it's a guess that needs manual verification. The vout_net_mismatch field flags estimated Vout differing >15% from the output rail name voltage.See references/schematic-analysis.md Step 2 for the full verification checklist. If the script fails or returns unexpected results, see references/manual-schematic-parsing.md for the complete fallback methodology.
python3 <skill-path>/scripts/analyze_pcb.py <file.kicad_pcb> --analysis-dir analysis/
python3 <skill-path>/scripts/analyze_pcb.py <file.kicad_pcb> --analysis-dir analysis/ --proximity # add crosstalk analysis
python3 <skill-path>/scripts/analyze_pcb.py <file.kicad_pcb> --output pcb.json # one-off, no cache
Outputs structured JSON (~50-300KB depending on board complexity) with:
--proximity)Add --full to include individual track/via coordinates, per-segment trace impedance (microstrip Z0 from stackup), pad-to-pad routed distances, return path continuity analysis, and via stub lengths. The --full output feeds the spice skill's parasitic extraction (extract_parasitics.py) for PCB-aware simulation. Supports KiCad 5 legacy format.
Zone fills must be current. The copper presence analysis uses KiCad's filled polygon data, which is computed when the user runs Edit → Fill All Zones (shortcut B) and stored in the .kicad_pcb file. If the board was modified after the last fill, the filled polygon data may be stale and the copper presence results will be inaccurate. When reviewing copper presence data, note whether the fill_ratio seems reasonable — a zone with 0 filled area or is_filled: false likely hasn't been filled.
Zone outline ≠ actual copper. The zone outline_bbox is the user-drawn boundary; filled_bbox is where copper actually exists after clearances, keepouts, and priority cuts. The copper_presence section shows which components have zone copper on the opposite layer — use this for capacitive touch pad isolation, antenna keep-out, and thermal analysis instead of inferring copper presence from zone outlines.
Copper-sensitive components need deeper checks. For capacitive touch pads and antennas, confirming "no opposite-layer copper" is necessary but not sufficient. The copper absence could be accidental — one zone refill after a routing change could add copper and kill touch sensitivity or detune the antenna. Check for explicit keepout zones (rule areas) that enforce the copper-free area as a DRC rule. Also measure same-layer GND clearance around touch pads and compare against the controller's app note minimum. For touch pads, compare trace lengths across all pads — significant asymmetry shifts baseline readings per channel. Report physical details (pad size, position, clearance, trace width/length) for all copper-sensitive components. See references/pcb-layout-analysis.md → Copper-Sensitive Components for the full checklist.
Verify after every run: Confirm footprint count and board outline dimensions against the raw .kicad_pcb file. Verify pad-to-net assignments for IC footprints against the schematic's pin-to-net mapping — this catches library footprint errors where pad numbering doesn't match the symbol pinout. If the script fails, see references/manual-pcb-parsing.md for the fallback methodology.
All PCB analysis sections now produce findings with the rich format (detector, rule_id, category, severity, confidence, summary, recommendation, report_context). Additionally, 7 new assembly/DFM checks run automatically:
warning when the foreign zone is a non-ground net or the component has no GND pad; severity is info when the foreign zone is GND and the component has a GND pad (the common case of a bypass cap sitting over the ground pour — expected layout, not a clearance issue).After running both schematic and PCB analyzers, run the cross-domain analyzer.
Point --schematic and --pcb at the current run's JSON files and pass
--analysis-dir analysis/ so the result lands inside the same run folder
and the manifest tracks it:
# Recommended: integrate into the current run
python3 <skill-path>/scripts/cross_analysis.py \
--schematic analysis/<run_id>/schematic.json \
--pcb analysis/<run_id>/pcb.json \
--analysis-dir analysis/
# One-off (bypasses the cache)
python3 <skill-path>/scripts/cross_analysis.py \
--schematic schematic.json --pcb pcb.json --output cross.json
Checks: CC-001 connector current capacity, EG-001 ESD protection gaps, DA-001 decoupling adequacy, XV-001..003 schematic/PCB sync. PCB JSON optional.
When --full is used with the PCB analyzer, the output includes a connectivity_graph section with per-net copper connectivity analysis via union-find over pads, tracks, vias, and zone fills. This enables deterministic plane split detection and return path validation in cross_analysis.py. Each net entry shows island count, component-to-island mapping, gap locations, and disconnected pad pairs.
# Recommended: integrate into the current run
python3 <skill-path>/scripts/analyze_gerbers.py <gerber_directory/> --analysis-dir analysis/
# One-off
python3 <skill-path>/scripts/analyze_gerbers.py <gerber_directory/> --output gerber.json
Outputs: layer identification (X2 attributes), component/net/pin mapping (KiCad 6+ TO attributes), aperture function classification, trace width distribution, board dimensions, drill classification (via/component/mounting), layer completeness, alignment verification, pad type summary (SMD/THT ratio). Add --full for complete pin-to-net connectivity dump. ~10KB JSON.
The gerber analyzer produces a findings list with rich format findings: GR-001 missing layers, GR-002 alignment issues, GR-003 drill problems, GR-004 paste aperture mismatches, GR-005 open board outlines.
If the script fails or returns unexpected results, see references/manual-gerber-parsing.md for the complete fallback methodology for parsing raw Gerber/Excellon files directly.
All scripts output JSON to stdout by default. Prefer --analysis-dir analysis/
to integrate output into the run-folder convention described in "Analysis
Cache Convention" below — every analyzer in a single session then co-locates
inside the same analysis/<run_id>/ folder and is tracked by the manifest.
Use --output file.json only for one-off runs where you don't want the
result cached. Add --compact for single-line JSON.
Analyzer JSON is worth keeping — these are expensive to regenerate (large
schematics take time). --analysis-dir preserves every run and is the form
downstream tools (kidoc, diff_analysis, what_if) expect. They're not worth
committing to git, but don't delete them between analysis steps.
All analyzers produce a uniform output envelope:
{
"analyzer_type": "schematic|pcb|emc|cross_analysis|thermal|gerber|lifecycle|spice",
"schema_version": "1.3.0",
"summary": {
"total_findings": 42,
"by_severity": {"error": 3, "warning": 15, "info": 24}
},
"findings": [
{"rule_id": "...", "detector": "...", "severity": "...", "confidence": "...", "evidence_source": "...", "summary": "...", ...}
],
"trust_summary": {
"total_findings": 42,
"trust_level": "high|mixed|low",
"by_confidence": {"deterministic": 20, "heuristic": 18, "datasheet-backed": 4},
"by_evidence_source": {"datasheet": 4, "topology": 10, "heuristic_rule": 18, ...},
"provenance_coverage_pct": 96.5
}
}
The findings list is the single authoritative source for all findings. Use finding_schema.get_findings() or finding_schema.group_findings() to filter by detector, rule prefix, or category. Detector names are available as constants in finding_schema.Det. Severities are error, warning, or info; confidence is deterministic, heuristic, or datasheet-backed.
All analyzers support --text for human-readable output, --analysis-dir for
integrated run-folder output (preferred), and --output for writing to a
specific file verbatim (one-off). When both are passed, the explicit
--output path wins — pick one form per invocation.
All analyzers support --stage and --audience flags:
Stages: schematic, layout, pre_fab, bring_up
Audiences: designer (default), reviewer, manager
# Show only layout-relevant findings for a reviewer
python3 <skill-path>/scripts/analyze_pcb.py board.kicad_pcb --stage layout --audience reviewer --text
# Manager summary of schematic review readiness
python3 <skill-path>/scripts/analyze_schematic.py design.kicad_sch --audience manager --text
# Pre-fab checklist for cross-domain analysis
python3 <skill-path>/scripts/cross_analysis.py -s sch.json -p pcb.json --stage pre_fab --text
JSON output always includes all findings. --stage adds stages and in_active_stage fields to each finding plus a stage_filter summary. audience_summary is always computed with designer/reviewer/manager views. --text output respects both flags.
Analysis outputs are stored in analysis/ with timestamped run folders managed by analysis_cache.py. The manifest (analysis/manifest.json) tracks all runs.
| File Type | Location | Regenerable? | Commit to git? |
|---|---|---|---|
| Analyzer JSON | analysis/<timestamp>/*.json | Yes (expensive) | Configured by track_in_git in .kicad-happy.json (default: no) |
| Manifest | analysis/manifest.json | Yes | Always (tracked by default) |
| Design review report | User-chosen path | Yes | Optional |
When creating design reviews, check the manifest for prior runs. If auto_diff is enabled and prior runs exist, automatically diff current vs previous using diff_analysis.py and include the delta in the "Previous Review Delta" section.
See also the bom skill's cleanup section for datasheets, order CSVs, and backups.
The analysis section in .kicad-happy.json controls the shared analysis output directory:
{
"analysis": {
"output_dir": "analysis",
"retention": 5,
"auto_diff": true,
"track_in_git": false,
"diff_threshold": "major"
}
}
| Field | Default | Description |
|---|---|---|
output_dir | "analysis" | Analysis directory path, relative to project root |
retention | 5 | Max unpinned runs to keep. 0 = unlimited |
auto_diff | true | Auto-include delta section in design reviews |
track_in_git | false | When false, JSONs gitignored but manifest tracked |
diff_threshold | "major" | Severity that triggers new timestamped folder: minor, major, breaking |
All fields are optional. Missing fields use defaults.
Schematic analyzer top-level keys:
analyzer_type, schema_version, summary, findings, trust_summary,
file, kicad_version, file_version, title_block, statistics,
bom, components, nets, subcircuits, ic_pin_analysis, design_analysis,
connectivity_issues, hierarchy_context, hierarchy_warning,
net_classifications, rail_voltages
Optional (present when non-empty): pdn_impedance, sleep_current_audit, voltage_derating, power_budget, power_sequencing, bom_optimization, test_coverage, assembly_complexity, usb_compliance, inrush_analysis, sheets (multi-sheet only), missing_info, bom_lock, project_settings
Key nested structures:
statistics: {total_components, unique_parts, dnp_parts, total_nets, total_wires, total_no_connects, component_types, power_rails, missing_mpn, ...}bom[]: {reference, references[], value, footprint, mpn, manufacturer, datasheet, quantity, dnp, ...}components[]: {reference, value, footprint, lib_id, lib_name, type, category, mpn, datasheet, dnp, in_bom, parsed_value, ...}nets{net_name}: {pins[], wires, labels[], ...} — each pin: {component, pin_number, pin_name, pin_type, ...} (NOT ref or pin)subcircuits[]: IC-neighborhood groupings ({center_ic, ic_value, neighbor_components, ...}), NOT a categorized detection index — see the JSON field cheat sheet at the top of this file.findings[] — power regulators, voltage dividers, RC/LC filters, feedback networks, opamp/transistor/bridge/crystal circuits, current sense, decoupling, protection, buzzer/speaker, Ethernet/HDMI/memory interfaces, RF chains/matching, BMS, key matrices, isolation barriers, addressable LED chains, and design observations all emit as findings with matching Det.* detectors. Use get_findings(data, Det.POWER_REGULATORS) etc. to fetch them. The pre-v1.3 signal_analysis wrapper and its top-level detection lists are gone.PCB analyzer top-level keys:
analyzer_type, schema_version, summary, findings, trust_summary,
file, kicad_version, file_version, statistics, layers, setup,
nets, net_name_to_id, board_outline, component_groups, footprints,
tracks, vias, zones, keepout_zones, connectivity, net_lengths
Optional: power_net_routing, decoupling_placement, ground_domains, layer_transitions, silkscreen, board_metadata, dimensions, groups, net_classes, dfm_summary, placement_density, copper_presence_summary, board_thickness_mm, trace_proximity (with --proximity). Sections previously at top level (thermal_analysis, thermal_pad_vias, tombstoning_risk, placement_analysis, current_capacity, copper_presence, dfm) are now in findings[]. With --full, the output also includes a connectivity_graph section (see "Connectivity Graph" above).
Key nested structures:
net_lengths is a list (not dict): [{net, net_number, total_length_mm, segment_count, via_count, layers{}}, ...] sorted by length descendingpower_net_routing is a list: [{net, track_count, total_length_mm, min_width_mm, max_width_mm, widths_used[]}, ...]footprints[]: {reference, value, footprint, layer, pads[], sch_path, sch_sheetname, sch_sheetfile, connected_nets[], ...}statistics: {footprint_count, copper_layers_used, smd_count, tht_count, zone_count, via_count, routing_complete, ...}Gerber analyzer top-level keys:
analyzer_type, schema_version, summary, findings, trust_summary,
directory, generator, layer_count, statistics, completeness, alignment,
drill_classification, pad_summary, board_dimensions, gerbers, drills
Workflow: When analyzing a KiCad project, scan the project directory for all available file types and run every applicable analyzer — not just the one the user mentioned. A complete analysis uses all the data available. Use --analysis-dir analysis/ on all analyzers to share a single run folder tracked by the manifest. For one-off runs without cache tracking, use --output file.json instead.
.kicad_sch, .kicad_pcb, .kicad_pro, gerber directories, and .net/.xml netlist files.digikey skill, ask the user). If critical IC datasheets can't be obtained, note this prominently in the report as a verification gap.analyze_schematic.py. If the PCB exists, run analyze_pcb.py --full. If gerbers exist, run analyze_gerbers.py. Run them in parallel when possible.cross_analysis.py --schematic sch.json --pcb pcb.json. This catches dangerous cross-domain bugs (connector current vs trace width, ESD gaps, decoupling adequacy, schematic/PCB sync).analyze_emc.py --schematic sch.json --pcb pcb.json. This is required during design reviews, not optional. The EMC skill runs 44 rule checks covering ground plane integrity, decoupling, switching harmonics, PDN impedance, diff pair skew, ESD paths, and more. Include results in the EMC section of the report.which ngspice ltspice xyce. If any simulator is installed, SPICE is required before writing the report. Hand off to the spice skill with the schematic analysis JSON. This validates filter frequencies, divider ratios, opamp gains, and more against actual simulation results. SPICE takes <1 second on most boards and catches value-computation errors (wrong resistor ratio, wrong cap for cutoff frequency) that no static analyzer finds. If both schematic and PCB analysis exist, use --parasitics for high-impedance circuits (>100K feedback dividers, LC filters, RF matching networks). Include results in the Simulation Verification section of the report. Output schema: top-level keys are summary, simulation_results, workdir, total_elapsed_s, simulator. Each entry in simulation_results[] has: subcircuit_type, components (list of refs, e.g. ["R5", "C3"]), reference (joined refs, e.g. "R5/C3"), status (pass/warn/fail/skip), expected (dict of metric values), simulated (dict of measured values), delta (dict of error percentages).analyze_thermal.py --schematic schematic.json --pcb pcb.json. Estimates junction temperatures from package θJA and board thermal via correction. Include results in the Thermal Hotspot section of the report.analyze_schematic.py --lifecycle flag. Checks component obsolescence status via distributor APIs. Include results in the Component Lifecycle section of the report, or note "Lifecycle audit not performed — [reason: no API keys / no network / no MPNs].".kicad_pro project file directly (it's JSON) for design rules, net classes, and DRC/ERC settings.*review*.md, *design-review*.md). If found, read the most recent one. If auto_diff is enabled and prior runs exist, run diff_analysis.py on current vs previous run and include the delta in the "Previous Review Delta" section.references/report-generation.md for the report template.The more data sources you combine, the more confident the analysis. A schematic-only review misses layout issues; a PCB-only review misses design intent. Always use everything available.
Default to thorough analysis unless the user asks for a quick review. The reason: the bugs that kill boards are the ones that look correct at a glance. A spot-check might confirm 5 ICs are correct while the 6th has pins 3 and 4 swapped — and that's the one that kills the board. Thoroughness principles:
.kicad_sym file is circular — it's the source of the potential error. Download datasheets before starting verification (see "Datasheet Acquisition" below), open the actual PDF for each IC, extract the pin function table, and cite page/section numbers when reporting verification results.Datasheets are what separate a consistency check from a correctness check. Without them, you can confirm the design agrees with itself — but not that it matches the real-world parts. Obtain datasheets early in the workflow.
Automated sync (preferred): Run datasheet sync scripts early in the workflow. They download datasheets for all components with MPNs into a shared datasheets/ directory with an manifest.json manifest. Run the preferred source first; if some parts fail, try others — they share the same directory and skip already-downloaded files.
python3 <digikey-skill-path>/scripts/sync_datasheets_digikey.py <file.kicad_sch>
python3 <lcsc-skill-path>/scripts/sync_datasheets_lcsc.py <file.kicad_sch>
python3 <element14-skill-path>/scripts/sync_datasheets_element14.py <file.kicad_sch>
python3 <mouser-skill-path>/scripts/sync_datasheets_mouser.py <file.kicad_sch>
DigiKey is best (direct PDF URLs). element14 is reliable (no bot protection). LCSC works for LCSC-only parts. Mouser is a last resort (often blocks downloads).
Check for existing datasheets: Before downloading, look for:
<project>/datasheets/ with manifest.json (from a previous sync)<project>/docs/ or <project>/documentation/Datasheet property URLs embedded in the KiCad symbolsFallback methods when automated sync isn't available or misses parts:
Datasheet property URL from the schematic symbol — many KiCad libraries include direct PDF linksdigikey skill to search by MPN and download individual datasheetsStructured datasheet extraction (for large designs or repeated reviews): Pre-extract datasheet specs into cached JSON for faster, more consistent pin verification. This is especially valuable for designs with 10+ ICs where re-reading PDFs from scratch each time is slow.
python3 <skill-path>/scripts/datasheet_page_selector.py <pdf_path> --mpn <mpn> --category <category>
After reading the selected pages and producing an extraction JSON, score and cache it using datasheet_score and datasheet_extract_cache modules. Extractions are stored in datasheets/extracted/<MPN>.json and reused across reviews. The datasheets skill owns the full extraction pipeline (schema, page selection, scoring rubric, consumer API) — see skills/datasheets/SKILL.md and its reference guides.
What to extract from each datasheet (note page/section/figure/equation numbers for citations):
For passives: While individual resistor/capacitor datasheets are rarely needed, verify the component values against the IC datasheets that specify them. The IC's datasheet says "use a 10µF input cap" — verify the schematic actually has 10µF there, not 1µF.
Anti-pattern: verification without datasheets. The most common failure mode in design review is verifying component connections against KiCad library symbols instead of manufacturer datasheets. This is circular — if the library symbol has a wrong pin mapping, the schematic, PCB, and analyzer output will all agree with each other (and with the wrong pinout). Only the datasheet reveals the error. This is especially dangerous for custom/community library symbols (e.g., sacmap:TPS61023) where there's no upstream KiCad library as a secondary check. If you find yourself verifying a pinout by reading the .kicad_sym file or the analyzer's pin data and confirming it matches the schematic — stop. That's a consistency check, not a correctness check. Open the actual PDF datasheet, find the pin function table, and verify against that. Cite the datasheet page/section/figure number in your report so the designer can confirm your work.
When both files exist, cross-reference them. This catches the most expensive bugs — swapped pins, missing nets, and footprint mismatches pass DRC/ERC but produce non-functional boards.
Footprint property vs actual PCB footprint (e.g., SOT-23 vs SOT-23-5).The PCB analyzer's sch_path, sch_sheetname, and sch_sheetfile fields in each footprint enable automated cross-referencing.
Compare two analysis JSON outputs to see what changed between design revisions (e.g., base branch vs PR, v1 vs v2). Use when the user says things like "compare designs", "what changed", "diff my schematic", "show changes from main", or "diff base vs head". Full reference: references/diff-analysis.md.
# Compare two schematic analysis outputs (JSON to stdout)
python3 <skill-path>/scripts/diff_analysis.py base.json head.json
# Human-readable text output
python3 <skill-path>/scripts/diff_analysis.py base.json head.json --text
# Write to file, custom threshold (ignore <2% deltas)
python3 <skill-path>/scripts/diff_analysis.py base.json head.json --output diff.json --threshold 2.0
# Ignore small percentage changes (e.g., rounding noise)
python3 <skill-path>/scripts/diff_analysis.py base.json head.json --threshold 5.0 --text
Auto-detects analyzer type (schematic, PCB, EMC, SPICE). Reports:
detection_schema.SCHEMAS identity and value fieldsnone (no changes), minor (statistics only), major (component/signal/finding changes), breaking (SPICE regressions, new CRITICAL EMC findings, new ERC warnings)Also used programmatically by analysis_cache.should_create_new_run() to decide whether new outputs warrant a new timestamped run folder.
Estimates junction temperatures of power-dissipating components by combining schematic power data with PCB thermal infrastructure (copper pour, thermal vias, package type). Use when the user says "check thermals", "thermal analysis", "will this overheat", "junction temperature", "power dissipation", or "thermal design".
# Recommended: integrate into the current run
python3 <skill-path>/scripts/analyze_thermal.py \
-s analysis/<run_id>/schematic.json \
-p analysis/<run_id>/pcb.json \
--analysis-dir analysis/
# Human-readable text report
python3 <skill-path>/scripts/analyze_thermal.py -s schematic.json -p pcb.json --text
# Custom ambient temperature (default: 25°C), one-off output file
python3 <skill-path>/scripts/analyze_thermal.py -s schematic.json -p pcb.json --ambient 40 -o thermal.json
Models each power component (LDO, switching regulator, shunt resistor) as a point heat source. Computes Tj = T_ambient + P_diss × Rθ_JA_effective, where Rθ_JA comes from a package lookup table (SOT-223: 60°C/W, QFN-5x5: 25°C/W, etc.) and is corrected for PCB thermal vias and copper pour. Rules:
| Rule | Condition | Severity |
|---|---|---|
| TS-001 | Tj exceeds absolute maximum | CRITICAL |
| TS-002 | Tj within 15°C of absolute maximum | HIGH |
| TS-003 | Tj > 85°C (may affect nearby passives) | MEDIUM |
| TS-004 | P > 0.5W with no thermal vias | MEDIUM |
| TS-005 | Significant power, within safe limits | INFO |
| TP-001 | MLCC within 10mm of hot component | LOW |
| TP-002 | Electrolytic cap within 10mm of hot component | MEDIUM |
Thermal findings and assessments include the rich format envelope (detector, rule_id, summary, evidence_source, report_context). Rule IDs: TS-001..005 (safety), TP-001..002 (proximity), TH-DET (assessments).
Instantly see the impact of component value changes on circuit behavior without re-running the full analyzer. Use when the user says "what if I change", "what happens if", "try a different value", "swap R5 to 4.7k", "parameter sweep", "what value gives me X", or wants to explore design trade-offs. Full reference: references/what-if.md.
# Single value change
python3 <skill-path>/scripts/what_if.py analysis.json R5=4.7k --text
# Sweep: comma list or log range
python3 <skill-path>/scripts/what_if.py analysis.json R5=1k,2.2k,4.7k,10k --text
python3 <skill-path>/scripts/what_if.py analysis.json R5=1k..100k:10 --text
# Tolerance corner analysis (±5% worst-case)
python3 <skill-path>/scripts/what_if.py analysis.json R5=4.7k+-5% C3=100n+-10% --text
# Find the right value: inverse solver with E-series snapping
python3 <skill-path>/scripts/what_if.py analysis.json --fix voltage_dividers[0] --target 3.3 --text
python3 <skill-path>/scripts/what_if.py analysis.json --fix rc_filters[0] --target 1000 --text
# EMC impact preview
python3 <skill-path>/scripts/what_if.py analysis.json C3=1u --emc --text
# SPICE re-simulation on affected subcircuits
python3 <skill-path>/scripts/what_if.py analysis.json R5=4.7k --spice --text
# Export patched JSON for further analysis (EMC, thermal, diff)
python3 <skill-path>/scripts/what_if.py analysis.json R5=4.7k --output patched.json
Patches component values in the analyzer JSON, recalculates derived fields (filter cutoff, divider ratio, opamp gain, crystal load, current sense range, regulator Vout), and shows before/after comparison with percentage deltas. Supports single changes, multi-point sweeps (comma or log-range), tolerance corner analysis, inverse fix suggestions with E-series snapping, EMC impact preview, PCB parasitic awareness (auto-discovered or via --pcb), and SPICE re-verification.
Summarises findings across all analyzers in a run. Use when the user wants a top-N list, a severity-filtered view, or a machine-readable roll-up without reading individual JSON files. Reads the current run from analysis/manifest.json.
# Top findings from the current run (default: top 20)
python3 <skill-path>/scripts/summarize_findings.py analysis/
# Limit to top 10 high-severity findings
python3 <skill-path>/scripts/summarize_findings.py analysis/ --top 10 --severity high
# JSON output for programmatic consumption
python3 <skill-path>/scripts/summarize_findings.py analysis/ --json
# Summarise a specific run by ID
python3 <skill-path>/scripts/summarize_findings.py analysis/ --run <run_id>
Flags: --top N (default 20), --severity (filter to critical/high/warning/info), --run (explicit run ID instead of latest), --json (machine-readable output).
Queries distributor APIs to check component lifecycle status (active, NRND, EOL, obsolete) and operating temperature range coverage. Use when the user says "check for obsolete parts", "lifecycle audit", "are any parts end of life", "temperature audit", "will this work at industrial temp range", or during production readiness reviews.
# Basic lifecycle check
python3 <skill-path>/scripts/lifecycle_audit.py analysis.json
# With temperature range validation (preset or custom)
python3 <skill-path>/scripts/lifecycle_audit.py analysis.json --temp-range industrial
python3 <skill-path>/scripts/lifecycle_audit.py analysis.json --temp-range "-40,105"
# Query specific distributors only
python3 <skill-path>/scripts/lifecycle_audit.py analysis.json --only digikey,lcsc
# Search for replacement parts when EOL/NRND found
python3 <skill-path>/scripts/lifecycle_audit.py analysis.json --suggest-alternatives
# Save results
python3 <skill-path>/scripts/lifecycle_audit.py analysis.json --output lifecycle.json
Reads the analyzer JSON BOM section, extracts unique MPNs, queries distributors (LCSC no-auth, DigiKey, element14, Mouser) for lifecycle status and operating temperature. Temperature presets: commercial (0/70°C), industrial (-40/85°C), extended (-40/105°C), automotive (-40/125°C), military (-55/125°C). Also checks datasheet extraction cache for temperature data before making API calls.
The lifecycle audit produces rich format findings: LC-001 (obsolete/discontinued), LC-002 (last time buy), LC-003 (NRND), LC-004 (unknown status), LC-005 (single source), LC-006 (long lead time), LT-001 (temperature violation).
Requires network access — unlike the core analyzers, this script calls distributor APIs. Same environment variables as the distributor skills (DIGIKEY_CLIENT_ID/SECRET, MOUSER_SEARCH_API_KEY, ELEMENT14_API_KEY). LCSC requires no credentials.
All schematic rule findings appear in findings[]. The following rule IDs are produced by the schematic analyzer:
| Rule | Detector | Condition | Severity |
|---|---|---|---|
| SS-001 | audit_sourcing_gate | MPN coverage < 50% | high |
| SS-002 | audit_sourcing_gate | MPN coverage 50–80% | warning |
| SS-003 | audit_sourcing_gate | MPN coverage 80–100% | info |
| NT-001 | analyze_connectivity | Single-pin net: signal pin | warning |
| NT-001 | analyze_connectivity | Single-pin net: power_out or passive pin | info |
| RS-001 | audit_rail_sources | Rail has a declared source (direct, PWR_FLAG, or bridged jumper) | info or warning |
| RS-002 | audit_rail_sources | Rail depends on user closing an open jumper | high |
| LB-001 | detect_label_aliases | Net has >= 2 distinct global/hierarchical labels (power nets excluded) | info |
| PP-001 | audit_power_pin_dc_paths | IC power_in pin reaches a rail only through a capacitor (2-hop BFS) | high |
SS-001 is a pre-fab blocker — a high finding that should be resolved before ordering. NT-001 severity depends on pin type: signal pins (digital I/O, bidirectional) are warning; power_out and passive pins are info. RS-001 severity varies by confidence level in the detected source. PP-001 uses a 2-hop BFS over the net graph, rejecting capacitor edges, to confirm a direct DC path from a power rail to each IC power_in pin.
Detailed methodology and format documentation lives in reference files. Read these as needed — they provide deep-dive content beyond what the scripts output automatically.
| Reference | Lines | When to Read |
|---|---|---|
schematic-analysis.md | 1133 | Deep schematic review: datasheet validation, design patterns, error taxonomy, tolerance stacking, GPIO audit, motor control, battery life, supply chain |
pcb-layout-analysis.md | 447 | Advanced PCB: impedance calculations, differential pairs, return paths, copper balance, edge clearance, copper-sensitive components (capacitive touch, antennas), custom analysis scripts |
output-schema.md | 293 | Full analyzer JSON schema with field names, types, and common extraction patterns |
file-formats.md | 379 | Manual file inspection: S-expression structure, field-by-field docs for all KiCad file types, version detection |
gerber-parsing.md | 729 | Gerber/Excellon format details, X2 attributes, analysis techniques |
pdf-schematic-extraction.md | 315 | PDF schematic analysis: extraction workflow, notation conventions, KiCad translation |
supplementary-data-sources.md | 288 | Legacy KiCad 5 data recovery: netlist parsing, cache library, PCB cross-reference |
net-tracing.md | 120 | Manual net tracing: coordinate math, Y-axis inversion, rotation transforms |
manual-schematic-parsing.md | 289 | Fallback when schematic script fails |
manual-pcb-parsing.md | 467 | Fallback when PCB script fails |
manual-gerber-parsing.md | 621 | Fallback when Gerber script fails |
report-generation.md | 614 | Report template (critical findings at top), analyzer output field reference (schematic/PCB/gerber), severity definitions, writing principles, domain-specific focus areas, known analyzer limitations |
standards-compliance.md | 638 | IPC/IEC standards tables: conductor spacing (IPC-2221A Table 6-1), current capacity (IPC-2221A/IPC-2152), annular rings, hole sizes, impedance, via protection (IPC-4761), creepage/clearance (ECMA-287/IEC 60664-1). Consider for all boards; auto-trigger for professional/industrial designs, high voltage, mains input, or safety isolation. |
design-intent.md | — | Design intent resolution, target market / certification / power constraints that gate findings by context |
diff-analysis.md | — | How diff_analysis.py compares two analyzer runs and emits severity-ranked change reports |
what-if.md | — | How what_if.py patches component values, recalculates derived fields, and suggests fixes for feedback dividers / crystal load caps / cap derating |
config-reference.md | — | .kicad-happy.json schema — project config for analysis cache, suppressions, design intent, risk scoring |
datasheet-verification.md | — | Automated cross-check of schematic connections against structured datasheet extractions (pin voltage, required externals, decoupling adequacy) |
For script internals, data structures, signal analysis patterns, and batch test suite documentation, see scripts/README.md.
| Extension | Format | Purpose |
|---|---|---|
.kicad_pro | JSON | Project settings, net classes, DRC/ERC severity, BOM fields |
.kicad_sch | S-expr | Schematic sheet (symbols, wires, labels, hierarchy) |
.kicad_pcb | S-expr | PCB layout (footprints, tracks, vias, zones, board outline) |
.kicad_sym | S-expr | Symbol library (schematic symbols with pins, graphics) |
.kicad_mod | S-expr | Single footprint (in .pretty/ directory) |
.kicad_dru | Custom | Custom design rules (DRC constraints) |
fp-lib-table / sym-lib-table | S-expr | Library path tables |
.sch / .lib / .dcm | Legacy | KiCad 5 schematic, symbol library, descriptions |
.net / .xml | S-expr/XML | Netlist export, BOM export |
.gbr / .g* / .drl | Gerber/Excellon | Manufacturing files (copper, mask, silk, outline, drill) |
For version detection and detailed field-by-field format documentation, read references/file-formats.md.
For a thorough datasheet-driven schematic review — identifying subcircuits, fetching datasheets, validating component values against manufacturer recommendations, comparing against common design patterns, detecting errors, and suggesting improvements — read references/schematic-analysis.md. Use this reference whenever the user asks to review, validate, or analyze a schematic in depth.
Fetching datasheets: When the analysis requires datasheet data, use the DigiKey API as the preferred source (see the digikey skill) — it returns direct PDF URLs via the DatasheetUrl field without web scraping. Search by MPN from the schematic's component properties. Fall back to web search only for parts not on DigiKey.
For advanced layout analysis beyond what the PCB analyzer script provides — impedance calculations from stackup parameters, DRC rule authoring, power electronics design review techniques, differential pair validation, return path analysis, copper balance assessment, board edge clearance rules, and manual script-writing patterns — read references/pcb-layout-analysis.md.
Most routine PCB analysis (via types, annular ring, placement, connectivity, thermal vias, current capacity, signal integrity, DFM scoring, tombstoning risk, thermal pad vias) is handled automatically by analyze_pcb.py. Use the reference for deeper manual investigation.
For interpreting auto-detected design intent and calibrating review severity by product class and target market (hobby vs consumer vs industrial vs medical vs automotive vs aerospace), read references/design-intent.md. Check the design_intent object in analysis output to understand the design context.
During a review you will often run one-off python3 -c "import json; ..." probes to inspect analyzer output (pin-nets, rail voltages, specific finding contents, etc.). Two practices that materially improve the user's ability to follow along:
Announce what you're checking before each probe. One concise sentence before the script — not after, not in a comment inside the script. The user should be able to read only the narrative and understand the review flow without opening every tool call.
[Bash] python3 -c "import json; d = json.load(open('analysis/.../schematic.json')); print([...])" with no surrounding prose.The narrative matters most for probes that investigate why something looks wrong — those are the moments a user loses context fastest.
Defensive patterns for JSON-shape uncertainty. Analyzer output has heterogeneous shapes (lists of dicts, dicts keyed by ref, optional sections, nested paths). Scripts that assume the wrong shape crash mid-probe.
x[:3] on a dict raises KeyError: slice(None, 3, None). Use list(x.values())[:3] or list(x.items())[:3] for dicts.min() / max(), check non-empty: min([]) raises ValueError: min() iterable argument is empty. Use min(items, default=None) or guard with if items:..get("key", default) not ["key"] when a section may be absent (many sections are optional based on what the analyzer found).isinstance(x, list) vs isinstance(x, dict) — components is a list of dicts, nets is a dict keyed by net name. Check the schema reference before iterating.r = c if isinstance(c, str) else c.get("reference", "").pad.get("abs_x") can be None; guard before arithmetic.Small investment, much lower friction.
Schematic — verify: decoupling caps on every IC VCC/GND pair, I2C pull-ups, reset pin circuits, unconnected pins have no-connect markers, consistent net naming across sheets, ESD protection on external connectors, power sequencing (EN/PG), adequate bulk capacitance.
PCB — verify: power trace widths for current (IPC-2221), via current capacity, creepage/clearance for high voltage, decoupling cap proximity to IC power pins, continuous ground plane (no splits under signals), controlled impedance traces (USB/DDR), board outline closed polygon, silkscreen readability, thermal via count for every exposed-pad IC (report the count and compare against the datasheet's recommended range — this is one of the most common QFN/DFN layout errors), keepout zone enforcement for copper-sensitive components (touch pads and antennas — confirming copper absence isn't enough because it could be accidental; check that keepout zones exist as DRC rules), differential pair length deltas with protocol-specific tolerance (compute the delta and cite the spec — raw lengths alone don't tell the designer if there's a problem), pad-to-net cross-reference at PCB level for all ICs/transistors/connectors (catches library footprint pin numbering errors that are invisible to DRC/ERC — the most dangerous class of PCB bug). Consider references/standards-compliance.md for IPC/IEC standard values — conductor spacing and current capacity are relevant for most boards; creepage/clearance and via protection apply to mains-connected or safety-isolated designs.
Common bugs (ranked by board-killing potential): swapped IC pins (library symbol vs datasheet pinout — invisible to DRC/ERC), transistor pinout ambiguity (SOT-23 without MPN — symbol assumes a pin ordering that may not match the real part; assess plausibility against common conventions when verification isn't possible), wrong footprint pad numbering, missing nets from un-synced schematic→PCB, wrong package variant (SOT-23 vs SOT-23-5), floating digital inputs, missing bulk caps, reversed polarity, incorrect feedback divider values, wrong crystal load caps, USB impedance mismatch, QFN thermal pad missing vias, connector pinout errors, unusual passive values (a value that's technically valid but uncommon for the application — e.g., a non-standard pull-up resistance, an unusual decoupling capacitor value).
When producing a design review report, read references/report-generation.md for the standard report template, severity definitions, writing principles, and domain-specific focus areas. The report format covers: overview, component summary, power tree, analyzer verification (spot-checks), signal/power/design analysis review, quality & manufacturing, prioritized issues table, positive findings, and known analyzer gaps. Always cross-reference analyzer output against the raw schematic before reporting findings.
When comparing two designs, diff: component counts/types, net classes/design rules, track widths/via sizes, board dimensions/layer count, power supply topology, KiCad version differences.
All analysis scripts process untrusted input (user-provided KiCad files, third-party PDF datasheets, distributor API responses). The parsing architecture mitigates prompt injection and code execution risks:
.kicad_sch, .kicad_pcb) are
parsed by a dedicated recursive-descent parser (sexp_parser.py) — not
eval(), exec(), or any code execution primitive. The parser produces
Python lists/strings only.pdftotext (external
binary, list-based args — no shell injection) and page content is passed to
the LLM for structured extraction. Extracted data is validated against a
5-dimension quality rubric before caching.--write flag.