Hauksbee

Sample report

A full report, on real boards

Verbatim output from hauksbee 0.1.0 (git f0b7fc11a9c5), captured by running the commands below in a clone of the repository and checked in beside this page. Nothing is trimmed, reordered or rewritten; the wrapping is this page's, the words are the tool's.

Every static check, on a board someone fabricated

The SQFMI Watchy, an ESP32 e-paper watch vendored into the repository under its MIT licence: 86 footprints making 82 parts on 84 nets. --check runs the bind, the copper DRC, the connectivity lint and the signal-integrity pass in one report; --plain writes each finding as what it is, why it matters, and what to do. Fifty clearance warnings and three impedance notes, nothing serious, and a closing section that says plainly which faults this pass cannot see because it never powered the board.

hauksbee run crates/hauksbee-ci/examples/boards/watchy.kicad_pcb --check --plain

Heads-up: 2 active IC(s) are unresolved/open, so firmware/analog/AC/thermal results on their nets would be INCOMPLETE, but the copper checks below are unaffected. Add models with --models-dir (hauksbee models --help) to cover them (run --report for the 6-part bind table).

== Copper spacing (DRC) ==
50 issues found, none serious (worth a look).

1. [WARNING] "+3V3" and "/32K_P" are very close but not quite touching at 1 location on the front copper layer (F.Cu) (tightest 0.154 mm, below your 0.200 mm rule).
     Why it matters: They are not shorted today, but at least one spot is below the spacing the board asks for. Small manufacturing variation, a solder smear, or contamination could bridge them, so it is a reliability risk rather than a guaranteed failure.
     What to do:     Open up the spacing between these two so the gap meets your clearance rule, or relax the rule deliberately if you know this spot is fine.

2. [WARNING] "+3V3" and "ACC_INT_1" are very close but not quite touching at 1 location on the front copper layer (F.Cu) (tightest 0.183 mm, below your 0.200 mm rule).
     Why it matters: They are not shorted today, but at least one spot is below the spacing the board asks for. Small manufacturing variation, a solder smear, or contamination could bridge them, so it is a reliability risk rather than a guaranteed failure.
     What to do:     Open up the spacing between these two so the gap meets your clearance rule, or relax the rule deliberately if you know this spot is fine.

3. [WARNING] "+3V3" and "ADC" are very close but not quite touching at 1 location on the back copper layer (B.Cu) (tightest 0.174 mm, below your 0.200 mm rule).
     Why it matters: They are not shorted today, but at least one spot is below the spacing the board asks for. Small manufacturing variation, a solder smear, or contamination could bridge them, so it is a reliability risk rather than a guaranteed failure.
     What to do:     Open up the spacing between these two so the gap meets your clearance rule, or relax the rule deliberately if you know this spot is fine.

  ...and 17 more net pairs like this on the back copper layer (B.Cu) (66 locations, tightest 0.150 mm vs your 0.200 mm rule); pass --verbose for every instance.
  ...and 28 more net pairs like this on the front copper layer (F.Cu) (93 locations, tightest 0.150 mm vs your 0.200 mm rule); pass --verbose for every instance.
  ...and 2 more net pairs like this on In2.Cu (3 locations, tightest 0.154 mm vs your 0.200 mm rule); pass --verbose for every instance.
Summary: 0 short(s), 50 net pair(s) below the clearance rule, 0 at minimum clearance (no margin).

== Connectivity / lint ==
Looks healthy: no connectivity problems found.

== Signal integrity ==
No signal-integrity failures, but 3 things worth a look (see below).

Heads up (worth knowing, not a failure):
  - A high-speed trace pair (DP / DN) is off its impedance target (W~0.150 mm, S~0.350 mm microstrip -> Zdiff ~ 146 ohm [target 90 ohm, USB differential]: estimate +62% from target).
       Why it matters: Fast links like USB (90 ohm differential) or Ethernet need their traces to present a specific impedance so the signal does not reflect off the wire and smear. This is a computed estimate, flagged only because the board did not formally declare a controlled-impedance stackup; it is informational, not a confirmed failure, but a value well off target on a real high-speed net can make the link marginal or fail to enumerate.
       What to do:     If this pair is NOT a high-speed link (USB/Ethernet/HDMI), you can ignore it. If it is: adjust the trace width and pair spacing for your actual layer stackup so the estimate lands near the target (the formulas are in docs/checks/SI_CHECKS.md), or ask your fab to build a controlled-impedance stackup to spec.
  - A high-speed trace pair (USB_D+ / USB_D-) is off its impedance target (W~0.150 mm, S~0.173 mm microstrip -> Zdiff ~ 125 ohm [target 90 ohm, USB differential]: estimate +39% from target).
       Why it matters: Fast links like USB (90 ohm differential) or Ethernet need their traces to present a specific impedance so the signal does not reflect off the wire and smear. This is a computed estimate, flagged only because the board did not formally declare a controlled-impedance stackup; it is informational, not a confirmed failure, but a value well off target on a real high-speed net can make the link marginal or fail to enumerate.
       What to do:     If this pair is NOT a high-speed link (USB/Ethernet/HDMI), you can ignore it. If it is: adjust the trace width and pair spacing for your actual layer stackup so the estimate lands near the target (the formulas are in docs/checks/SI_CHECKS.md), or ask your fab to build a controlled-impedance stackup to spec.
  - A single-ended trace (Net-(U4-LNA_IN/RF)) is off its impedance target (W~0.320 mm microstrip -> Z0 ~ 63 ohm [target 50 ohm, single-ended]: estimate +25% from target).
       Why it matters: A 50 ohm single-ended line is the convention for an RF or antenna feed: the trace has to present that impedance end to end or part of the signal reflects back instead of reaching the antenna, costing range and sensitivity. This is a computed estimate, flagged only because the board did not formally declare a controlled-impedance stackup.
       What to do:     If this is not a controlled-impedance RF path, this estimate is informational. If it is: widen or narrow the trace for your actual layer stackup so the estimate lands near 50 ohm (the formulas are in docs/checks/SI_CHECKS.md), or ask your fab to build a controlled-impedance stackup to spec.

== What this pass did not check ==
These checks read the board. They do not run it, so nothing above can see a fault that only appears while the board is powered: a rail that sags on inrush, a brownout at power-up, a part that overheats under load.

This board has a processor hauksbee can emulate, so it can boot your firmware against the solved circuit and assert on what happens.

  hauksbee-ci init <board>     scaffold a spec into the current dir
  hauksbee-ci run <spec>       run it, here or in a pipeline

And a board with two real shorts in it

The boot-gate example, which carries a deliberate GND-to-+5V bridge on both outer layers. The finding names the two nets, the layer, and the millimetre coordinate. The last line is the exit-code contract: a report command exits 0 even on a serious finding, and --strict is what turns it into a gate.

hauksbee run crates/hauksbee-ci/examples/boards/boot_gate.kicad_pcb --drc --plain

2 issues found, 2 serious.

1. [SERIOUS] Two separate connections, "GND" and "+5V", are touching, near x=112.0 mm, y=100.0 mm on the back copper layer (B.Cu).
     Why it matters: These are meant to be electrically separate. Where they touch they become one connection (a short), so "GND" and "+5V" will be forced to the same voltage. That usually means the board does the wrong thing, and if one is a power rail it can pull large current and overheat.
     What to do:     Pull the two pieces of copper apart so there is a clear gap between them, or remove the bit of copper that bridges them. If they really are supposed to connect, give them the same net name.

2. [SERIOUS] Two separate connections, "GND" and "+5V", are touching, near x=112.0 mm, y=100.0 mm on the front copper layer (F.Cu).
     Why it matters: These are meant to be electrically separate. Where they touch they become one connection (a short), so "GND" and "+5V" will be forced to the same voltage. That usually means the board does the wrong thing, and if one is a power rail it can pull large current and overheat.
     What to do:     Pull the two pieces of copper apart so there is a clear gap between them, or remove the bit of copper that bridges them. If they really are supposed to connect, give them the same net name.

Summary: 2 short(s), 0 net pair(s) below the clearance rule, 0 at minimum clearance (no margin).
note: gate-grade finding(s) above, but this is a report command so the exit code is 0. Add --strict to exit 2 on them (exit contract: 0 = clean or report-only, 2 = findings under --strict, 3 = invalid for analysis), or gate CI with hauksbee-ci.

The same board through the CI gate

The static checks read the board. This powers it: the spec supplies VBUS as a real USB port with its source impedance and current limit, solves the circuit, and asserts that nothing exceeds a rating and that the 3.3 V rail is in tolerance once it has settled. 0.46 s for the 82-part board, no firmware in this spec.

hauksbee-ci run crates/hauksbee-ci/examples/watchy.toml

hauksbee-ci: Watchy power-up
  board: boards/watchy.kicad_pcb
  seeds: 1

  [PASS] no stress faults raised
        no stress faults
  [PASS] +3V3 in [3, 3.6] V after 50ms
        +3V3 after 50ms: min=3.300V (>= 3V), max=3.300V (<= 3.6V) [settled 3.300V]

2/2 assertions passed in 0.48s - GREEN

A check that only firmware can settle

A MOSFET gate with no pull-down, and firmware that never configures the pin driving it. On copper alone the power-up level is undefined and no netlist rule can settle it. Boot the firmware on the emulated part and the answer is a number: the net never left 0 V. The companion spec, boot_gate_pass.toml, is the same board and the same assertion with firmware that does drive the gate, and it goes green.

hauksbee-ci run crates/hauksbee-ci/examples/boot_gate_fail.toml

hauksbee-ci: boot_coverage: MOSFET gate left floating (FAIL)
  board: boards/boot_gate.kicad_pcb
  seeds: 1

  [FAIL] GATE_CTRL driven to >= 3 V within 20 ms of reset
        control net 'GATE_CTRL' was never driven to >= 3 V (firmware left it Hi-Z / undefined through the whole run); observed range [-0.000, -0.000] V
        why: the firmware never drove the control net in time; check `firmware = ...` points at the right image and the net is a GPIO the firmware actually drives (docs/ci/CI.md, "boot_coverage" caveat).

0/1 assertions passed in 0.02s - RED