12. Reconcile with the tools you already run

Bring your existing DRC or ERC report into the same model, and see where the two tools agree, differ, and cannot see each other's work.

You already run a design-rule check. Your CAD tool ships one, you have tuned it, and it gates your release. The question to ask of anything new is “what does it add to what I already have, and where do the two disagree”.

You could answer it by reading two reports side by side, but that does not scale and nobody does it twice. So bring the other tool’s report into the same model and ask directly.

Import the other tool’s report

Run your existing check and keep the JSON. The project keeps KiCad’s own report for this board in reports/kicad-drc.json, so you can follow along without KiCad installed. It came from:

kicad-cli pcb drc --format json -o kicad-drc.json designs/jetson/jetson-agx-thor-baseboard.kicad_pcb

KiCad 10.0.6 found 578 violations. Import them:

$ agni import-results reports/kicad-drc.json --design designs/jetson -o kicad.results.json
kicad-cli pcb drc 10.0.6 — 957 finding(s) from designs/jetson
attached to an entity: 946 of 957
     1 not attached — an entity the description names but the loaded design does not contain
         e.g. Footprint REF**
    10 not attached — board outline geometry, which belongs to no component or net
         e.g. Segment on Edge.Cuts

This document carries no coverage axis: a vendor report lists violations and says
nothing about what it did not check, so its silence must not be read as a pass.

Read the summary slowly. In it the import tells you how far to trust what follows.

946 of 957 attached to an entity. A vendor report names things in prose, so importing it means resolving each name to an entity in your design. “Track [/CSI/CAM0.CSI2_CLK+] on In2.Cu”, or a curved one written “Track (arc) […]”, resolves to your design’s net of that name. “NPTH pad of J12” is an unplated hole with no pin or net, and it resolves to its part. The resolution works only because agni names a KiCad schematic’s nets exactly as KiCad does, including the sheet path on a bus member drawn on a sub-sheet. There are more findings than violations because a clearance violation names two items, and each becomes a finding.

The rest are named, with a reason. Ten are board outline geometry, which belongs to no component or net. One names a footprint, REF**, that is on the board and in no schematic. Nothing is dropped quietly. That matters, because a silently discarded finding is worse than one that was never imported.

The document carries no coverage axis. This is the same idea as rung 9, applied to somebody else’s tool. A vendor report is a flat list of violations. It does not say which checks ran, so it cannot distinguish “checked and fine” from “never checked”. The import records that limitation rather than papering over it, and every reader of the document inherits the caveat.

Compare the two runs

Now produce your own run over the same design and compare them:

$ agni check designs/jetson --results-out agni.results.json > /dev/null
$ agni results agni.results.json --compare kicad.results.json
comparing:
  ours:   agni <version> — 87 finding(s) over mount://jetson/designs/jetson
  theirs: kicad-cli pcb drc 10.0.6 — 957 finding(s) over designs/jetson   [no coverage axis: its silence is not a pass]

entities flagged:
  both         1
  ours only    85
  theirs only  259

ours only:
  net /CSI/CSIA_3V3
  net /CSI/CSIA_5V
  net /CSI/CSIA_I2C_VCC
  net /CSI/CSIB_3V3
  net /CSI/CSIB_5V
  net /CSI/CSIB_I2C_VCC
  net /CSI/I2C_MUX_SCL
  net /CSI/I2C_MUX_SDA
  net /CSI/I2C_{CAM}.SCL
  net /CSI/I2C_{CAM}.SDA
  net /CSI/MUX_I2C_4_SCL
  net /CSI/MUX_I2C_4_SDA
  net /CSI/MUX_I2C_5_SCL
  net /CSI/MUX_I2C_5_SDA
  net /CSI/MUX_I2C_6_SCL
  net /CSI/MUX_I2C_6_SDA
  net /CSI/MUX_I2C_7_SCL
  net /CSI/MUX_I2C_7_SDA
  net /DCDC/12V_OUT
  net /DCDC/12V_VDD
  net /DCDC/16V_OUT
  net /DCDC/16V_VDD
  net /DCDC/1V15_OUT
  net /DCDC/1V8_OUT
  net /DCDC/20V_OUT
  net /DCDC/20V_VDD
  net /DCDC/3V3_OUT
  net /DCDC/3V3_VDD
  net /DCDC/5V_OUT
  net /DCDC/5V_VDD
  net /DCDC/5V_{AON}_OUT
  net /DCDC/5V_{AON}_VDD
  net /DCDC/VIN_PWR_ON
  net /Expansion connector/+12V_FMC
  net /Expansion connector/+3V3_AUX
  net /Expansion connector/+3V3_FMC
  net /Expansion connector/+5V_FMC
  net /Expansion connector/+VCC_FMC
  net /Expansion connector/+V_{ADJ}
  net /Expansion connector/I2C7.SCL
  net /Expansion connector/I2C7.SDA
  net /Expansion connector/I2C8.SCL
  net /Expansion connector/I2C8.SDA
  net /I2C_{SYS}.SCL
  net /I2C_{SYS}.SDA
  net /Peripherals/FAN_VDD
  net /Power/3V3_LDO
  net /SFP/SFI_CONN_RX_N
  net /SFP/SFI_CONN_RX_P
  net /SFP/SFI_CONN_TX_N
  net /SFP/SFI_CONN_TX_P
  net /SFP/SH
  net /SoM_IO/I2C0_SCL_1V8
  net /SoM_IO/I2C0_SDA_1V8
  net /SoM_IO/I2C1_SCL_1V8
  net /SoM_IO/I2C1_SDA_1V8
  net /SoM_IO/I2C2_SCL_1V8
  net /SoM_IO/I2C2_SDA_1V8
  net /SoM_IO/I2C3_SCL_1V8
  net /SoM_IO/I2C3_SDA_1V8
  net /SoM_IO/I2C5_SCL_1V8
  net /SoM_IO/I2C5_SDA_1V8
  net /SoM_IO2/TC_VCC
  net /USB DP Alt mode/USBC1_DPEQ0
  net /USB DP Alt mode/USBC1_EQ0
  net /USB DP Alt mode/USBC1_SSEQ0
  net /USB Debug, PD/DEBUG_SCL
  net /USB Debug, PD/DEBUG_SDA
  net /USB Debug, PD/FTDI_3V3
  net /USB Debug, PD/PDC_I2C1_IRQn
  net /USB Debug, PD/PDC_I2C2_IRQn
  net /USB Debug, PD/PDC_I2C3_SCL
  net /USB Debug, PD/PDC_I2C3_SDA
  net /USB Debug, PD/PDC_LDO_1V8
  net /USB Debug, PD/PDC_LDO_3V3
  net FLASH_PWR
  net Net-(D1-C)
  net Net-(J12-RS0)
  net Net-(J12-RS1)
  net Net-(J12-RX_{LOS})
  net Net-(J12-TX_{DISABLE})
  net Net-(J12-TX_{FAULT})
  net VCC_IN
  net unconnected-(J18-PadB24)
  net unconnected-(J18-PadB25)

theirs only:
  component C102
  component C107
  component C111
  component C117
  component C121
  component C127
  component C130
  component C131
  component C132
  component C138
  component C139
  component C142
  component C144
  component C145
  component C156
  component C194
  component C195
  component C196
  component C197
  component C202
  component C234
  component C236
  component C242
  component C243
  component C245
  component C246
  component C247
  component C249
  component C251
  component C252
  component C253
  component C255
  component C257
  component C26
  component C260
  component C268
  component C269
  component C270
  component C271
  component C273
  component C274
  component C276
  component C280
  component C286
  component C287
  component C293
  component C295
  component C298
  component C299
  component C300
  component C301
  component C302
  component C305
  component C307
  component C309
  component C310
  component C311
  component C314
  component C318
  component C335
  component C338
  component C343
  component C348
  component C349
  component C35
  component C350
  component C354
  component C355
  component C370
  component C371
  component C372
  component C373
  component C375
  component C378
  component C384
  component C387
  component C39
  component C43
  component C47
  component C5
  component C52
  component C55
  component C59
  component C6
  component C70
  component C75
  component C79
  component C81
  component C86
  component C9
  component C90
  component C93
  component C94
  component D10
  component D12
  component D14
  component D19
  component D24
  component D30
  component D31
  component D39
  component D42
  component D51
  component D61
  component D7
  component D9
  component H4
  component H5
  component J1
  component J10
  component J11
  component J12
  component J14
  component J15
  component J18
  component J19
  component J2
  component J7
  component L4
  component L5
  component Q10
  component Q18
  component Q38
  component Q40
  component R119
  component R123
  component R14
  component R156
  component R16
  component R162
  component R166
  component R172
  component R18
  component R19
  component R193
  component R195
  component R196
  component R201
  component R202
  component R205
  component R218
  component R225
  component R228
  component R231
  component R234
  component R260
  component R261
  component R284
  component R288
  component R29
  component R298
  component R301
  component R306
  component R326
  component R344
  component R346
  component R347
  component R348
  component R351
  component R352
  component R354
  component R356
  component R357
  component R360
  component R361
  component R362
  component R366
  component R370
  component R374
  component R375
  component R376
  component R377
  component R387
  component R49
  component R52
  component R54
  component R59
  component R60
  component R65
  component R69
  component R71
  component R74
  component R76
  component R87
  component R9
  component R90
  component R91
  component R92
  component TP11
  component TP12
  component TP21
  component TP24
  component TP3
  component TP4
  component TP5
  component TP63
  component TP73
  component TP77
  component U1
  component U17
  component U19
  component U26
  component U28
  component U31
  component U33
  component U57
  component U60
  component U69
  component U71
  component U78
  component U8
  component Y2
  net +3V3
  net +5V_SOM
  net /CSI/CAM0.CSI2_CLK+
  net /CSI/CAM0.CSI2_CLK-
  net /CSI/CAM0.CSI2_D0+
  net /CSI/CAM0.CSI2_D0-
  net /CSI/CAM0.CSI2_D1+
  net /CSI/CAM0.CSI2_D1-
  net /CSI/CAM0.CSI3_D0+
  net /CSI/CAM0.CSI3_D0-
  net /CSI/CAM0.CSI3_D1+
  net /CSI/CAM0.CSI3_D1-
  net /CSI/CAM1.CSI0_CLK+
  net /CSI/CAM1.CSI0_D0+
  net /CSI/CAM1.CSI0_D0-
  net /CSI/CAM1.CSI0_D1+
  net /CSI/CAM1.CSI0_D1-
  net /CSI/CAM1.CSI1_D0+
  net /CSI/CAM1.CSI1_D0-
  net /CSI/CAM1.CSI1_D1+
  net /CSI/CAM1.CSI1_D1-
  net /CSI/CAM3.CSI6_CLK+
  net /CSI/CAM3.CSI6_CLK-
  net /CSI/CAM3.CSI6_D0+
  net /CSI/CAM3.CSI6_D0-
  net /CSI/CAM3.CSI6_D1+
  net /CSI/CAM3.CSI6_D1-
  net /CSI/CAM3.CSI7_D0+
  net /CSI/CAM3.CSI7_D0-
  net /Expansion connector/DP2.AUX-
  net /Expansion connector/PCIe_{C2x1}.CLK-
  net /Expansion connector/PCIe_{C2x1}.TX0+
  net /M.2/PCIe_{C1x1}.CLK-
  net /M.2/PCIe_{C1x1}.~{CLKREQ}
  net /M.2/PCIe_{C5x4}.TX1+
  net /M.2/PCIe_{C5x4}.TX1-
  net /Power/USBPD1_HV
  net /SFP/SFI.RX+
  net /SoM_IO2/DP0.HPD
  net /SoM_IO2/DP0.TX0+
  net /SoM_IO2/DP0.TX0_C+
  net /SoM_IO2/DP2.AUX_C+
  net /SoM_IO2/DP2.AUX_C-
  net /SoM_IO2/PCIe_{C2x1}R_CLK-
  net GND
  net SYS_VIN_HV
  net VCC

rules seen on the same entity (an observation about these two documents,
not a claim that the rules ask the same question):
  ours                         theirs                             entities
  test-point-coverage          kicad-drc/clearance                1

not comparable (a finding naming no component or net): ours 0, theirs 11

Reading the split

The instinct is to compare 91 against 957 and conclude something about which tool is better. That reading is wrong, and the three-way split is there to stop you making it.

Theirs only is mostly components. Nearly all of them are KiCad’s lib_footprint_issues, where a footprint differs from the library copy KiCad has installed, and courtyard and silkscreen checks add to them. Agni has no opinion about most of that and should not pretend to. Your existing DRC is not being replaced.

The nets in that column are KiCad’s clearance findings, and the two tools genuinely disagree about them. KiCad reports 357 clearance violations, and agni, checking the same copper against the board’s declared 0.1 mm minimum, reports none. The board also carries a .kicad_dru file of custom rules, wider gaps for differential pairs and keep-outs between high-speed pairs and copper pours, and agni does not read it. So KiCad is checking against rules unknown to agni, and the split tells you which tool to believe for that question.

Ours only is nets, and each is a statement about what the circuit means: an I2C bus with no pull-up, a rail with no test point, a supply entering through a connector with no reverse protection, a net named against house style. A board DRC structurally cannot reach any of them. It is checking copper against fabrication limits, and it has no model in which “this bus needs a pull-up” is expressible.

Both is two rails, and the line under the list says what that overlap is worth. Agni flags them for reverse protection and test points, KiCad for clearance. That is the same entity under two unrelated questions, so the tool calls it an observation about two documents rather than agreement.

Three bands of flagged entities side by side. A bracket over the left two is labelled agni, and a bracket over the right two is labelled your existing DRC, so the middle band is what both tools reached. The left band holds nets only agni flagged, which are statements about what the circuit means. The right band holds components only the DRC flagged, which are physical manufacturability. The two tools answer on different axes rather than one finding more than the other. agni flagged 17 entities your existing DRC flagged 25 9 nets 8 entities 17 components what the circuit means a bus with no pull-up, a transceiver's logic side, control signals, a naming rule where both routes reach the same thing physical manufacturability edge clearance, silk over pads, footprint library mismatches not a bigger number, a different axis a copper checker has no model in which "this bus needs a pull-up" is expressible 28 and 309 findings respectively, since one entity can carry several

The useful answer to “what does this add” is a different axis, not a bigger number.

About this board’s copper

The numbers above are a real board’s. It was laid out by people, passes its own manufacturer’s review, and still collects hundreds of DRC findings. Most of them are library bookkeeping, or rules that were never given to the second tool. That is normal, so the comparison reads the columns rather than the totals. The columns are complementary, because the two tools are answering different questions, and no amount of careful layout gives a copper checker access to the fact that an I2C bus has no pull-up.

Using it as a gate

agni import-results writes an ordinary check-result document, so everything from rung 11 applies: archive it, re-render it later, diff it against next month’s run. A vendor report that was a terminal scroll becomes an artifact in the same format as your own.

The comparison is the more useful gate. Suppose a finding appears in “theirs only” and is still there months later. That is a check you are not doing. And if a finding moves from “both” into “theirs only”, one of your two tools stopped seeing something it used to.

Next

Drive it in the browser, the last rung.