freeroute exited 0 and said nothing when it dropped connections, which
cost real diagnosis time: on rc4 two simple two-pin nets came back with no
copper and no explanation. The grid now records each connection it could
not route, the exact check adds each it rejects, and the CLI lists them on
stderr (the SES is still written; the exit code stays 0, as the JAR's).
A connection whose ends both sit in one zone of its net is listed apart,
as left to the zone fill: freeroute does not route through a zone it
cannot trust to be solid, but KiCad's fill often joins those pads anyway.
Ports two FreeRouting building blocks for session output:
- indent.py: IndentWriter (2-space indented S-expression output) and
Identifier (reserved-char/non-ASCII/leading-digit quoting), mirroring
datastructures/IndentFileWriter and IdentifierType. The SES reserved
set includes '-' and '_', so net and padstack names get quoted.
- model.py: RoutedWire/RoutedVia/RoutedNet/RoutingResult — the minimal
in-memory routing structure the maze router will populate and the SES
writer serializes. Coordinates are in DSN units.