concur

Cross-source consensus check for chip libraries.

A small Rust CLI that runs downstream of ds2sf and chip-fetcher: it loads every available source-of-truth for a chip's symbol and footprint (datasheet-extracted, KiCad UL bundle, Fusion 360 EAGLE .lbr, Altium binary), compares them across seven axes, and emits a result.json with status: golden | divergent | unrecoverable plus tagged hints[] so the upstream caller can either re-fetch a suspect library or escalate to a human.

The pipeline:

chip-fetcher  →  ds2sf (status: ok)  →  concur (status: golden)  →  downstream is happy
                                            ↓ divergent
                                       chip-fetcher refetches a lib
                                       OR human reviews

Why this matters

Concur is opinionated about whether a divergence requires upstream work or is safe to ship. Many "disagreements" between sources are known-benign patterns (exposed-pad counted as pin N+1 in one source but not the other, JEDEC-outline-name vs marketing-name, alt-function pin labels, pad-array span misread as body dim). Concur classifies these as variants and ships the dataset with status: golden_with_variants (exit 0) so the upstream caller can move forward and just remember the variants downstream. Real disagreements stay divergent (exit 2).

Real example from this release's smoke tests:

$ concur check ~/project/chip-fetcher/library/ADS1115IDGSR
  ds2sf       — 10 pins, 10 pads, package "VSSOP-10"
  kicad       — 10 pins, 10 pads, footprint "SOT_ADS1115IDYNR_TEX"
  eagle (.lbr) — 10 pins, 10 pads, package "DGS0010A_N"

OK: ADS1115IDGSR — GOLDEN with variants [variants: label_only, stub_pin_names, body_dim_artifact]

What concur figured out:

  • label_only_mismatch — KiCad's footprint name starts with SOT_ because that's TI's UL library prefix convention, but the geometry (pad count, pad layout, pitch) all agrees with EAGLE's DGS0010A_N and ds2sf's VSSOP-10. The package family really is VSSOP. Cosmetic only.
  • stub_symbol_pin_names — the KiCad UL symbol has pin "names" of "1", "2", "3"… instead of real labels. Downstream can use ds2sf's or EAGLE's pin labels.
  • body_dim_measurement_artifact — ds2sf and EAGLE report different body dimensions (5.05×3.10 vs 4.45×2.00). Body dim is courtyard-only, doesn't affect placement; the diff is a measurement-method artifact (lead-tip span vs pad-array span vs body D dim).

All three are flagged but explained, exit 0, chip-fetcher moves forward.

Outputs

<chip-dir>/<MPN>-concur.result.json — the audit + agent contract:

{
  "schema_version": "1",
  "status": "golden_with_variants",
  "exit_code": 0,
  "mpn": "ADS1115IDGSR",
  "summary": "ADS1115IDGSR — GOLDEN with variants [variants: label_only,stub_pin_names,body_dim_artifact]",
  "sources_compared": ["ds2sf","kicad","eagle"],
  "sources_missing":  ["altium"],
  "variants": [
    { "kind": "label_only_mismatch",
      "notes": "ds2sf: VSSOP-10 → family=VSSOP | eagle: DGS0010A_N → family=VSSOP | kicad: SOT_ADS1115IDYNR_TEX → family=SOT" },
    { "kind": "stub_symbol_pin_names",
      "stub_sources": ["kicad"],
      "canonical_sources": ["ds2sf","eagle"] },
    { "kind": "body_dim_measurement_artifact",
      "notes": "ds2sf: 5.05×3.10 mm | eagle: 4.45×2.00 mm" }
  ],
  "axes": [
    { "axis": "pad_count",     "verdict": "agree" },
    { "axis": "pin_names",     "verdict": "disagree",
      "conflicts": ["kicad has stub-only pin names …"] },
    { "axis": "package_family","verdict": "disagree",
      "conflicts": ["Package families disagree across sources: ds2sf=VSSOP, kicad=SOT, eagle=VSSOP"] }
  ],
  "hints": [
    { "action": "ul_symbol_has_stub_names", "source": "kicad", "pin_count": 10,
      "suggestion": "Use ds2sf-extracted symbol JSON or refetch the .kicad_sym from a manufacturer-direct source" }
  ]
}

Status ladder

Status Exit Caller action
golden 0 Ship it, no caveats.
golden_with_variants 0 Ship it. Every disagreement is explained by variants[]. Downstream tools can use the variant list to decide which source to prefer (ds2sf for pin labels when the KiCad symbol has stubs, etc).
divergent 2 Real disagreement. Refetch a library or escalate to a human.
unrecoverable 3 Couldn't parse ≥2 sources.

Variant kinds (v0.3)

Kind When What it means
exposed_pad_variant Pad count diff is exactly 1 One source counts the EP/thermal pad as pin N+1; the other rolls it into the body. EE practice varies; both are correct.
module_extra_pads Pad count diff > 1 (one source has more) KiCad/EAGLE footprint includes mounting/shield/test pads beyond the module datasheet's user-facing pinout.
label_only_mismatch Package family names differ but geometry agrees Naming-convention artifact (e.g. TI's SOT_ prefix on a VSSOP footprint, JEDEC outline DGS0010A → VSSOP, IPC-7351 generic name SOP65P640X120-20N → TSSOP). Cosmetic only.
stub_symbol_pin_names One source's pin names are pin numbers ("1","2"…) UL stub case. Downstream should use a richer source (ds2sf or EAGLE) for labels.
body_dim_measurement_artifact Body dim disagrees but pad geometry agrees Different sources measured "body" differently (lead-tip span vs body D-dim vs pad-array span). Body dim is courtyard-only; doesn't affect placement.
naming_convention_mismatch Pin names differ but every disagreement is a benign convention swap Channel-digit position (OUT11OUT for op-amps and multi-channel parts) or power-pin alias (V+VCC, V-GND).

Comparison axes

Axis What it checks
pad_count Number of pads in the footprint
pad_numbers Set of pad numbers/labels (1..N or A1, A4, B7…)
symbol_pin_count Number of pins in the symbol
pin_names Per-pin name across sources (slash → underscore, case-insensitive). Sources that emit stub names ("1","2"…) are flagged as ul_symbol_has_stub_names hint.
pin_to_pad_map Does pin VDD map to the same pad number across sources?
package_family SOIC / VSSOP / QFN / SOT / etc., with JEDEC outline aliases (DGS0010A → VSSOP, RGE → QFN, RUG → VQFN, …)
body_dims Body x/y in mm, ±0.5 mm tolerance

Agent-to-agent contract

hints[] is a tagged-union list (separate from variants[] — variants explain why a disagreement is benign; hints tell the caller what action to take). v0.3 enriches refetch hints with concrete suggested_sources (priority-ordered) and expected_resolution so chip-fetcher knows where to refetch from AND how to verify the refetch worked.

Action Carries When
refetch_library_source {format, suspect, notes} A specific lib looks wrong; chip-fetcher should try a different upstream.
ul_symbol_has_stub_names {source, pin_count, suggestion} KiCad UL stub case (pin "names" are pin numbers).
accept_with_caveats {caveats} Soft diffs within tolerance.
human_review {reason, notes} No automated repair safe.
source_parse_failed {format, path, error} A file couldn't be parsed at all.

Calling recipe

let r = run_concur(chip_dir);
match r.status.as_str() {
    "golden" => mark_chip_dir_clean(),
    "divergent" => {
        for h in &r.hints {
            match h {
                Hint::RefetchLibrarySource { format, .. } => {
                    refetch_lib_from_alternate_source(format);
                    return run_concur(chip_dir); // re-call after refetch
                }
                Hint::UlSymbolHasStubNames { .. } => {
                    // Replace .kicad_sym from ds2sf JSON via downstream sym_create.
                }
                _ => {}
            }
        }
    }
    "unrecoverable" => log_for_human(&r),
    _ => unreachable!(),
}

CLI

concur check <CHIP-DIR>     # run cross-source check
concur inspect <CHIP-DIR>   # print summary of an existing concur.result.json
concur health               # parser readiness check
concur install              # drop SKILL.md

check flags: --ds2sf-symbol, --ds2sf-footprint, --kicad-sym, --kicad-mod, --eagle, --mpn, --out-dir, --force, --json-only.

Validated chips (v0.3 release — 9-chip suite)

MPN Pkg Status Variants caught Notes
ADS1115IDGSR VSSOP-10 golden_with_variants label_only, stub_pin_names, body_dim_artifact TI's SOT_ prefix on VSSOP footprint; UL symbol stubs; ds2sf body-dim picked up the lead-tip span
DRV8316RRGFR VQFN-40 golden_with_variants ep EP counted as pin 41 by KiCad/EAGLE, omitted by ds2sf
VL53L8CX OLGA-16 golden_with_variants ep, label_only, body_dim_artifact Custom optical LGA; thermal pad EP variant
ESP32-S3-WROOM-1-N4 SMD module golden_with_variants module_extras, body_dim_artifact KiCad has 8 extra shield/test pads beyond the module's 41 castellations
LM358D SOIC-8 golden_with_variants naming_convention OUT11OUT channel-digit + V+VCC, V-GND power-pin aliases
TPS62840YBGR DSBGA-8 golden_with_variants body_dim_artifact Cleanest of the suite; only courtyard body-dim diff
BMI270 LGA-14 golden_with_variants label_only, body_dim_artifact Bosch IMU; EAGLE 7.x .lbr now parses (DTD support)
MSP430G2553IPW20 TSSOP-20 divergent Real bug. KiCad symbol shifts pin functions: ds2sf says pin 14=NC, KiCad says pin 14=P1.6 with 8 alt-functions. Likely wrong sub-variant in UL bundle.
R7FA4M1AB3CFP LQFP-100 divergent Real bug. Pin 1: ds2sf=P108_TMS_SWDIO, KiCad=P400. AVCC0 lands on pad 90 vs pad 88. Wrong sub-variant of the Renesas RA4M1 family.

7/9 pass cleanly (golden_with_variants exit 0). 2/9 are real wrong-variant findings the upstream caller should refetch. Zero false positives in v0.3.

Out of scope (current)

  • Altium .SchLib (symbol-side) parsing. v0.6 added .PcbLib (pads) via the sister altium-pcblib crate; .SchLib pin labels are still pending.
  • Body-thickness comparison (z-dim). Sources don't reliably report this.
  • Tolerance-aware lead/pad-pitch checks beyond raw body dims.

Altium multi-variant selection (v0.7)

Many vendor .PcbLibs ship multiple footprint variants in the same file — for example DRV8316RRGFR carries RGF0040E-IPC_A (41-pad IPC standard) AND RGF0040E-MFG (57-pad manufacturing layout with extra fiducials and test points). The upstream altium-pcblib crate picks one as "primary" by stream order.

If concur naively trusts the primary, it can disagree with kicad+eagle 100% of the time. v0.7 computes the pad-count consensus from already-parsed sources (ds2sf / kicad / eagle) and asks altium-pcblib for the variant whose pad count is closest to the median. Names containing -MFG / _MFG / DEBUG / FIDUCIAL / TEST get a tiebreak penalty so the IPC-standard variant wins when in doubt.

Effect on the benchmark: DRV8316RRGFR was reporting divergent with altium engaged (57 vs 41) → now reports golden_with_variants (41 across all four sources, only EP-counting differs).

Build

cargo build --release
sudo cp target/release/concur /usr/local/bin/
concur install

Or just ./build.sh.

Related

  • ds2sf — datasheet → symbol + footprint + provenance JSON. Upstream of concur.
  • chip-fetcher — pulls the libraries that concur cross-checks.