Three fixes to TryUpgradeOrNewPlate and a new post-pass:
1. Change ShouldUpgrade from < to <= so upgrade wins when costs are
tied (e.g., all zero) — previously 0 < 0 was always false
2. Guard against "upgrades" that shrink a dimension — when options are
sorted by cost and costs are equal, the next option may have a
smaller length despite higher width (e.g., 72x96 after 60x144)
3. Revert plate size when upgrade fill fails — the plate was being
resized before confirming parts fit, leaving it at the wrong size
4. Add TryConsolidateTailPlates post-pass: after all nesting, find the
lowest-utilization new plate and try to absorb its parts into
another plate via upgrade. Eliminates wasteful tail plates (e.g.,
a 48x96 plate at 21% util for 2 parts that fit in upgraded space).
Real nest file: 6 plates → 5 plates, all 43 parts placed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>