Rules for the runs were being made up mid-run (git for rollback, access
to the real-part drawing archive), so each model started under a
different rule set. BENCH-RULES.md writes them down in one place, stamped
into every new engine, so all models work under the same rules:
workspace limits and no searching for other engines, git init plus
commit-per-working-state, the archive as read-only with nothing
customer-identifying kept in the (publishable) engine folder, tests may
only be added to, and what the final report must cover.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
It was the starting point for the Qwen3.8-Flash-Next run, which now
continues as OpenNest.Engine.Qwen38FlashNext (stamped from _Template).
The unimplemented scaffold under the bare "Qwen" name would only
collide with or be confused for that engine once it lands here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
OpenAI reuses model codenames across generations (GPT-6 reused
GPT-5.6's Sol and Luna), so a bare codename like "Astra" can't
identify which model built the engine. Prefixing the model version
keeps engine names unambiguous as more runs are added. The CLR type
is now Gpt6AstraNestingEngine, so benchmark reports show the new name.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each engine-building run started from a hand-copied scaffold (Qwen's),
which carried that engine's name and stale notes. _Template holds the
generic scaffold with a __NAME__ placeholder, and New-Engine.ps1 stamps
out a named copy. The template's starter tests go through the
benchmark's NestValidator, so a model gets a real pass/fail target
instead of a plumbing-only check; they were verified to pass against
Opus55.
Directory.Build.props now also detects when it sits in an Engines/
folder inside an OpenNest checkout, so an engine stamped there with
-IncludeBuildFiles builds without passing OpenNestRoot.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Engines are moving out of OpenNest so they can be published on their own
and so OpenNest checkouts handed to a model for an engine-building run no
longer contain the competing engines. History for Engines/ (and the
pre-move root-level engine folders) was carried over with git filter-repo.
Engines now build against a sibling OpenNest clone via $(OpenNestRoot),
overridable with /p:OpenNestRoot, with a clear error when it is missing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replace the Terra scaffold with an independent configuration-space contact placer and bounded stock-plan search. Include plugin tests, synthetic and DXF benchmark drivers, results, and deployment documentation.
Correct shared collision clipping and hole subtraction so curved-hole inserts validate consistently. Cover translated layouts, spacing violations, operand order, winding, and independent boolean-area comparisons.
Validation: 1,293 tests passed with 12 fixture skips; all 34 synthetic/generated and four DXF cases are valid and complete.
Reusable Fill/, BestFit, RectanglePacking and CirclePacking components are
fair game; whole-engine delegation and run-all-pick-best stay banned.
Improvements to shared components go in the engine's own project and are
reported, not applied to OpenNest.Core/OpenNest.Engine.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Plugin engines (Opus55, Qwen, Terra) each add two projects at the repo
root, and more are coming; at a dozen they would outnumber the core
projects. They are also a different kind of thing: out-of-solution,
runtime-loaded plugins. Grouping them under Engines/ keeps the root
readable.
Engines/Directory.Build.props now holds the shared TFM, nullable and
implicit-usings settings and the OpenNest.Engine reference, so a new
engine's csproj is nearly empty. The tests/ compile exclusion lives in
Directory.Build.targets because a removal in .props runs before the SDK
adds its default Compile glob and has no effect.
Build-Engines.ps1 replaces the per-README manual build-and-copy steps
for deploying engines into the benchmark's runtime Engines/ folder.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rename the OpenNest.Engine.Sonnet5 scaffold to OpenNest.Engine.Opus55 and
implement an independent whole-job INestingEngine (no built-in engine,
registry, or best-fit internals are called or copied).
- PartCatalog: snapshot perimeter -> polygon per allowed orientation, with
adaptive chord tolerance and MBR-aligned rotations for Automatic parts.
- NoFitCache: spacing footprints and cached Clipper2 Minkowski NFPs (convex
fast path; concave sweep plus both containment terms).
- FrontierPacker: per-(type, orientation) free regions (inner-fit rectangle
minus NFPs), updated incrementally; gap-fill-largest, else least front
advance per area^beta.
- Engine: look-ahead stock choice by estimated whole-job net area, six
deterministic variants, tail re-plan of the last 1-3 sheets.
- Tests judged by OpenNest.Benchmark's NestValidator, including an NFP
containment regression guard.
P260805-10.nest (219 parts), all 9 stock sizes: 219/219 valid, 27 sheets,
91.7% utilization, ~7 s.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Three standalone INestingEngine plugin projects (Solve() unimplemented,
throws NotImplementedException), each outside OpenNest.sln and discovered
at runtime via NestingEngineRegistry.LoadPlugins, same pattern as
OpenNest.Engine.Aurora. Each README spells out that Solve() must be an
independently designed placement algorithm and must never call/wrap/select
over the built-in engines (StockLadderNestingEngine, FixedStrategyNestingEngine,
PlateNesterFactory, NestingEngineRegistry).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>