Propose a change
Name Last commit message Last updated
concur Migrate asset from Helium wiki 1mo ago
concur-hero.png Migrate asset from Helium wiki 1mo ago
install.sh Add adompkg installer files 1mo ago
package.json Add adompkg installer files 1mo ago
page.json Remove internal identifiers from page.json 10d ago
README.md Initial commit: app/concur 1mo ago
SKILL.md Add adompkg installer files 1mo ago
uninstall.sh Add adompkg installer files 1mo ago

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.

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