Design
Board specs, stackups and net classes
Pick a fab and a real stackup, define a net class per kind of net, and put impedance and current targets on them so check solves the widths.
The board spec is the first file of a design and the one everything else is checked against. It names the fab, the stackup, the outline, the via types and the net classes. Get it right first: a layout routed against the wrong stackup has the wrong impedance on every controlled line.
agentee new board sensor-nodePick a fab
name = "sensor-node"
fab = "jlcpcb"fab picks a rule preset: generic, jlcpcb or hdi. The preset is a table keyed by the copper layer count, the outer copper weight and the finish, so a four layer 1 oz board gets tighter track rules than a two layer 2 oz one. The jlcpcb values follow JLCPCB's capability page line by line; the rules reference gives each value with the line it comes from, and the few places agentee is stricter on purpose.
Override any rule in [rules]:
[rules]
min_track_width = "0.15mm"
min_clearance = "0.15mm"Pick a real stackup
Do not type layer thicknesses in. Pick the fab's own build:
agentee stackups --fab jlcpcb --layers 4
agentee stackups --fab jlcpcb --layers 6 --thickness 1.6
agentee stackups JLC04161H-7628The presets cover every JLCPCB impedance build from 4 to 20 layers and 0.4 to 3.0 mm, the PCBWay standard builds from 4 to 18 layers, and two generic HDI builds. JLCPCB presets go by the fab's own code, JLC04161H-7628: layers, thickness, outer and inner copper, prepreg. The last command prints one preset's layers with their thickness and permittivity.
agentee edit board sensor-node stackup --preset JLC04161H-7628 --finish ENIGOrder the board with the same build: if JLCPCB uses another stackup, every impedance you solved is off.
Outline, cutouts and holes
agentee edit board sensor-node outline --size 50,30 --corner-radius 1mm[[outline.cutouts]]
origin = [20, 12]
size = [6, 2]
corner_radius = 1 # half the width makes a slotAn outline is a rectangle with size, origin and corner_radius, or a polygon of points. A cutout is a window, slot or large hole routed through the board, and everything that cares about the edge (copper to edge, pads, pours, the router, the sims) treats a cutout's edge as board edge. A cutout in the layout file is different: it only keeps pours off an area on some layers.
Via types
[[vias]]
name = "std"
drill = "0.3mm"
diameter = "0.6mm"A board can list several via types. A through via needs nothing more; blind, buried and microvias need an HDI fab and are covered in HDI: microvias and lamination.
Net classes
A net class is what a net is: its track width, clearance, vias and the targets check holds it to. Give every kind of net its own class. A net left in Default is a warning, because the class decides how it is routed.
agentee edit board sensor-node class Signal --track-width 0.2mm --clearance 0.2mm --via std
agentee edit board sensor-node class Power --current 2A --max-temp-rise 10C
agentee edit board sensor-node class USB --impedance 90ohm --diff-gap 0.15mm --layers F.Cu
agentee edit board sensor-node class RF --impedance 50ohm --coplanar-gap 0.2mm --solver field --layers F.Cuclass edits the class of that name in place or adds it. What the targets do:
currentis checked against IPC-2221 on every layer the class may use, atmax_temp_rise(10 C by default). Inner layers carry less than outer ones, and check names the width that carries it on each:
error: blinky.board.toml: blinky netclass Power on In2.Cu: 0.6mm carries only 0.451A for a 10C rise, 1A needs 1.7994mm (IPC-2221)impedanceis checked on every layer inlayers. Leavetrack_widthout and check solves it on the first layer; givewidthsper layer where one width does not fit every layer.diff_gapmakes the class a differential pair, and its impedance the differential impedance.coplanar_gapmakes it grounded coplanar: the pour keeps that gap either side, with the plane below.solver = "field"checks the class with the GPU field solver, which includes solder mask and copper thickness, instead of closed form formulas.
See what the stackup gives
agentee check
agentee show board:sensor-nodeshow prints the resolved board as JSON: for each class and layer the trace geometry (microstrip on the outer layers, stripline inside), the impedance, the width that meets the target and the current it carries. When a class is off target, check says by how much and what to use:
error: lna.board.toml: lna netclass RF on F.Cu: field solver gives 59.4 ohm with solder mask, outside 50ohm +/- 5%, use track_width = "0.2985mm" (50.2 ohm)Paste the width, rerun check. Controlled impedance and pairs goes further.
Design rule settings
Layout checks come from a registry of rules, each with an id, a category and a default severity. The board can turn them off or change their severity:
[drc]
disable = ["silk-width"]
severity = { "starved-thermal" = "error", "via-in-pad" = "warning" }agentee drc NAME --list prints every rule with whether it applies to this board and why. The design rule checks reference lists them all.
Checklist
fabset, and a stackuppresetthe fab actually builds.- One class per kind of net: signal, power, ground, each impedance, each pair.
- Impedance and current targets on the classes, not widths worked out by hand.
solver = "field"on every class where a few ohms matter.agentee checkclean before the schematic starts naming classes.