Task 5 of the whole-job engine API: add a geometry safety gate that
validates every candidate trial before the runner commits accounting.
- NestJobPlacementValidator: closed-contour validity, rotation-policy
compliance, work-area containment per quadrant, hole-aware material
overlap, and required part spacing. Overlap is interior-only, so
zero-clearance edge/corner contact remains a valid placement.
- NestJobValidator: route candidate validation through the geometry
gate; reject unusable/unclosed/degenerate contours up front.
- NestJobRunner: wrap candidate evaluation in a progress bridge that
tags legacy engine detail with the current candidate context.
- LegacyPlateNesterAdapter: forward IProgress to the legacy engine so
its progress surfaces under the active candidate.
- Tests: geometry (quadrants, rotations, touching, containment, holes,
empty stock, real Default/Strip smoke), validation, and cancellation
suites; repaired test fakes that emitted out-of-bounds or overlapping
placements the gate now correctly rejects.
Engine.Tests: 70 passed, 0 failed, 0 skipped in Debug and Release.
Windows-only OpenNest.Tests not run on Linux.
LegacyPlateNesterAdapter.Create now delegates to PlateNesterFactory
instead of carrying its own minimal Default-only switch, so built-in
strategy resolution has one source of truth. Behavior unchanged:
unknown keys still reject; all four built-ins now resolvable.
44 net8.0 tests pass in Debug and Release; 0 warnings.
Replace name-based quantity deduction with reference-based drawing
identity in the engine paths the whole-job runner reaches
(NestEngineBase fill/pack, StripNestEngine deduction, RemnantFiller
ledger, IterativeShrinkFiller leftovers). Add instance-scoped
PlateNesterFactory that resolves built-in strategies without touching
the global NestEngineRegistry. Add identity and engine-selection tests.
44 net8.0 tests pass in Debug and Release; no new warnings.