--autonest can now use more than one physical sheet. The first layout
replaces the target plate's parts, further layouts are inserted as new
plates after it, and --stock offers explicit sheet sizes (with optional
costs) built from the target's spacing, quadrant and clamp rail.
NestPipelineCommit gains ApplyToPlates for callers without a
PlateManager. Per-sheet results and overlap checks cover every
committed plate.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Built-in festive schemes theme the background, sheet and accents while
keeping 12-color part palettes distinct, light enough for black part IDs
and clear of the green etch stroke. They are only applied when chosen;
there is no automatic seasonal switching.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dropping the parts that land on a clamp suits small parts, which fill the
gaps between clamps. Large parts often do better if the fill area stops
short of the clamps. The rows still fit, and no part is lost on a clamp.
When every clamp in the fill area lies on one edge, interactive Fill now
also fills the area with that edge moved just past the clamp keep-outs,
as a larger edge spacing would. It keeps whichever layout the strategy's
comparer ranks better, and a tie keeps the dropped-parts layout. Clamps
on more than one edge skip the comparison. The second fill reuses the
cached best-fit pairs. While it runs, a preview counts as the new best
only when it beats the first layout, so the preview never gets worse.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Interactive Fill on a plate with clamps used to split the plate into
clamp-free rectangles and fill each one separately. It showed no progress,
so Accept did nothing until the end, and Stop discarded the result. Packing
around the clamps also tends to give a worse layout than losing the few
parts that land on them.
FillItem and FillGroup now fill the area as if there were no clamps. They
then drop each part that enters a clamp keep-out or sits too close to an
existing part, using the same check as before. For a multi-part group, the
whole copy is dropped when any member fails. Progress previews are filtered
by the same check, so a layout accepted early is clamp-clear. A quantity
request that loses copies asks for that many more, up to two more times.
Pack and whole-plate Nest still pack only into the clamp-free areas.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Interactive Fill ran the best-fit pair phase first. The first pair
computation for a drawing can take about a minute, and until it finished
the progress dialog showed no layout, Accept stayed disabled and the
status text did not change.
The fill now packs the part boxes (RectBestFit) before the pair phase and
reports that layout, so Accept is available at once. The layout is only a
fallback: strategies still run in their usual order, and a completed fill
picks the same winner as before. While the pairs are computed, the detail
line reads "Computing best-fit pairs (may take a minute)...". Accept or
Stop now stops the wait. The computation keeps running in the background
and is cached for the next fill.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Circles packs every part as its minimum enclosing circle at centers tangent
to two of the work-area walls, placed discs and clamp keep-outs, bottom-left
and left-bottom, with hexagonal and square lattice seeds. It bids only when
every part fills at least 0.8 of its enclosing circle and otherwise returns
everything unplaced at once. Default runs it as a third candidate.
Rectangles' sheet-by-sheet stock loop moves to NestingEngines/SheetByStock
(Rectangles output unchanged) and Default's candidate scoring and commit
forwarding become shared helpers. Circles also runs the whole job preferring
each offered stock and keeps the best result. Contract tests take shapes an
engine can override.
Synthetic round jobs, salvage-credited: Circles wins or ties all six with
valid layouts; Default cost falls about 4% versus Irregular alone.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cutout prepass now bundles frames smallest first, so a larger frame's
round cutout can take a ring part or an earlier bundle as one insert through
the circle packer: a flange holds a washer that holds a smaller washer that
holds a slug. Chains stop at four parts deep. Lattice and NFP proposals never
take these inserts, since they could seat a part in a ring's bore.
Expansion and released demand recurse, so placed order cuts innermost first
at every level and an unplaced outer frame returns its whole chain to demand.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Add CutoutCirclePacker, a circle-in-circle proposal for the cutout
router. When a cutout is one circle and every insert fills at least 0.8
of its enclosing circle, it packs the inserts largest first at centers
tangent to the wall or placed discs, trying a center-out pass (a single
insert sits concentric) and a wall-first pass (optimal counts for up to
nine equal discs). Every pose passes NestLayoutCheck.
The router runs it first and skips the lattice and NFP searches when it
places all demand; otherwise the higher count wins and existing
proposals keep ties. On synthetic disc jobs the prepass drops from
minutes to seconds and places as many or more inserts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Item.Create builds the circle packer's view of a part: the minimum
enclosing circle of its outward-flattened perimeter (padded by the
layout check's flattening allowance), its fill ratio, the offset back
to the part origin, and the largest disc clear of material inside its
cutouts. Gears and sprockets pack by their tip circle around their
bore; the fill ratio lets a future engine decide which jobs to bid on
instead of a yes/no round test.
Adds MinimumEnclosingCircle (Welzl, repeatable order) to Core geometry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Staggered stripes were spaced only so adjacent stripes touched
diagonally. When the in-stripe pitch stretched past sqrt(3)*D, stripes
two apart, which sit directly over each other, came closer than a
diameter. Clamp the stripe spacing to at least a radius in both fills.
FillEndOdd also divided by zero when a single circle fit per stripe;
it now stacks those stripes a diameter apart. FillEndEven now clones
the template item, so placed circles keep its radius instead of zero.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Select entities in the CAD converter (click, or drag a window/crossing
box) and right-click to exclude/include them or set them to cut, etch or
display only, regardless of their DXF layer. Delete excludes the
selection.
Roles are stored per source entity on the drawing and persisted in the
entity set as an optional `roles` map. Display-only geometry is kept out
of the program, so posts, nesting and verification never see it; placed
parts draw it as a dashed overlay. Load-time scribe repair skips
etch-layer entities set to cut. Per-entity exclusions now survive filter
changes.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reads each stock as a bar and cuts parts in one row along its length, packing
part lengths with a port of the CutList saw cut-list packer (first-fit
decreasing with swap optimization, exhaustive search for small jobs) plus a
best-fill subset-sum candidate. Each part is packed at its length less its
measured self-nesting gain, and a slide-left compaction pass nests shaped ends
(turning alternate mitred parts) and refills the freed length. Every slid pose
is confirmed with NestLayoutCheck.Clears.
On five synthetic flat-bar jobs every layout is valid and complete; total cost
33696 vs Rectangles 36816 and Default 34080.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A tabbed cutout's slug stays attached while the sheet is cut, but nesting
saw a closed hole and could place parts inside it. Nesting and layout paths
now read material through NestingMaterial.ForNesting, which drops closed
contours with tab spans so the slug counts as part. That covers part
outlines and collision lines, the cutout router, fill expansion, best-fit,
NestLayoutCheck and the GPU bitmaps. Area, overlap diagnostics and cutting
keep the hole, and programs without tabs read exactly as before.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A hole can now be declared a tabbed cutout in the CAD Converter: pick a
circle or any edge of a closed hole, set the tab count and width, and drag
the tabs around the hole. The definition persists on the drawing and in the
nest file, and stays editable from the source entities.
The builder replaces the hole with open cut pieces and uncut spans on a new
Tab layer. Tabs are material, so area, nesting and overlap checks still see
a closed hole, but they are never cut. Plan Cutting and Assign Lead-ins cut
each piece from the slug with the internal lead-in and no lead-out. A lead
that would reach back over a tab is mirrored, and an arc lead onto an arc
pierces straight in. Planning accounts for each span between tabs and runs
the open-cut proof, so its own tabbed cutouts certify; tabs followed by a
lead-out are still refused. Pre-post review flags programs that still
contain tab motions.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cutout cut in several pieces around tabs, as PEP programs often are, made
pre-post review report every piece's lead-out and the part's open fragments
as incomplete. Review now proves such open cuts release nothing: within the
part they touch other cuts only at their own ends and form no loop (each
closed contour with its leads counting as one point), and leads at open ends
stay out of the gap beyond them. Anything else stays incomplete. Plan Cutting
keeps refusing to certify its own tabs followed by a lead-out.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A cutout cut in pieces around tabs is a set of open cut figures. Filling the
cut outline closed each piece with a chord, drawing a slanted bridge across
the hole. The fill path now rejoins open figures across their tab gaps, and
parts with open cuts use it for drawing, hit-testing and the lead-in overlay.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Clicking the location label now saves the mouse-follow/click-only choice
to StatusBarLocationFollowsMouse (default true), so it survives restarts.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mouse-follow mode set the auto-sized location label on every MouseMove,
relaying out the whole status strip and slowing the UI. Updates now run
at most every 100 ms with a trailing update so the label settles on the
final point. Mouse-follow is now the default; clicking the label still
toggles click-only mode.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Rebuild the dialog as a two-column layout: a larger preview with a
color swatch, a Change Color button and read-only size, area and
source-file details on the left; Drawing (name, customer) and Nesting
(quantity, priority, cut first) groups on the right.
Quantity shows how many parts are already nested and how many remain,
priority explains that lower numbers nest first, and cut first gets a
short description. The form now uses Segoe UI with font auto-scaling,
re-renders the preview when its size changes, selects the name on
open, and is titled "Drawing Properties - <name>".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The v4 upgrade now keeps existing library data: each distinct package
blob is stored once by hash, every revision and current row is copied
with default nesting settings, and the v4 drawing tables are dropped,
all in the migration transaction. Pre-v4 databases get the v5 tables
directly.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Schema v5 stores each distinct drawing package once in drawing_packages,
keyed by SHA-256; revisions point at it, so details, settings, archive and
restore revisions add no blob. The v4 drawing tables are replaced outright
(no production library existed); nest tables are untouched.
Nesting settings (cut first, priority, rotation constraints, color) become
structured record fields (DrawingLibraryRecord.Settings), returned on every
read, filterable by cutFirst, editable through the metadata endpoint and
applied by LibraryDrawingInsert. Canonical packages now leave every
record-owned field at its default, so renaming or changing settings never
changes the package hash. Saving a nest drawing to the library carries its
settings into the record.
The desktop library browser gains a Cut first column and an Edit Settings
dialog that saves notes and settings as a new revision with the same package.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Drawings flagged CutFirst (e.g. test squares) are sequenced ahead of
every other part: they get their own route with the chosen method, then
the remaining parts follow. Cutoffs crossing a cut-first part still
precede it. The flag is editable in Edit Drawing, persists in .nest as
`cutFirst` (omitted when false) and is kept by split pieces.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Center Parts centred the parts on the whole plate, ignoring edge
spacing, so a wider clamp-side margin left the parts closer to the
clamps than the opposite edge. It now centres them in Plate.WorkArea()
via the new Plate.OffsetToCenterPartsInWorkArea, so each side keeps
the same extra room beyond its edge spacing.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds WithActive for handlers that only forward to the active nest
document and collapses 32 of them to one line. The eight align and
evenly-space items share Align_Click, reading their AlignType from Tag.
Center Parts becomes CenterParts_Click and ignores a missing plate or
an empty plate instead of throwing. The hidden, disabled Paste item
loses its empty handler. SetValueForm, OptionsForm and ShapeLibraryForm
are now disposed and owned by the main window.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
MainStatusBar owns the status, location, selection and plate labels and
the click-vs-move location mode. Bind(EditNestForm)/Unbind() replace the
manual PlateView subscribe/unsubscribe pairs in OnMdiChildActivate;
MainForm keeps only its overlap-menu subscription. Applying the location
mode now detaches both mouse handlers first, which also drops the old
self-assignment of the mode flag.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves startup and settings code out of MainForm:
- PostProcessorLoader discovers posts and registers their materials.
Each DLL now loads in isolation; a failing one is named in a startup
warning instead of throwing out of the MainForm constructor.
- MachineSettings owns the clamp-settings and nest-defaults entry points
and their once-per-session warnings; BomImportForm calls it directly.
- NewNestFactory creates File > New nests and their daily names;
GetNestName is now a pure static the characterization test calls.
- MainWindowSettings restores/saves window placement and migrates the
legacy nest template.
- UpdaterStatus owns the updater and its status-bar item.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves the long workflow handlers into OpenNest/Forms/Commands:
AutoNestCommand (dialog, owned modal progress, solve, validation review,
commit and result notices), PostCommand (prepare, configure, verify,
save dialog, multi-file overwrite confirmation) and NestStorageController
(database open/save/save-as with reconciliation and storage errors).
MainForm keeps the busy guards, the nesting lockout and nestingCts, and
reacts to the controller's StateChanged to lock storage settings and
saving. The characterization test now flips the controller's IsSaving
instead of the removed databaseSaveInProgress field.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves every MainForm busy predicate into MainForm.Guards.cs, built on
IsJobRunning, ViewsOf, IsPlateWorkBusy and IsNestFillBusy. Auto Nest,
Validate and Post share TryBeginPlateCommand; Clamps, Automatic Cutoffs
and Plan Cutting reuse the shared predicates. The deliberate variants
(Expand Spacing ignores busy actions; the report guard adds database
saves) keep their names and remain pinned by characterization tests.
NavigationEnableCheck now takes the lockout flag instead of
SetNestingLockout repeating its logic.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Moves members verbatim into MainForm.File/View/Tools/Nest/Plate/Status
partials (nested under MainForm.cs in the project); MainForm.cs keeps
the shell: fields, startup, overrides and the Window menu. Each file
keeps only the usings it needs. No logic changes; private member names
used by reflection-based tests are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pins the nest-name format and which operations each MainForm busy
guard counts, ahead of splitting and consolidating MainForm.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lists every part in the cutting inspection panel's scope, including ones
with no finding, so an all-clear nest doesn't just look like an empty
grid. Selecting a part jumps to its first issue or zooms to it when clear.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Breakoffs are now picked by their joining line, default to the smaller side as scrap
(flippable), and cut that line between tabs on a new Break layer instead of slots.
Plan Cutting and Assign Lead-ins enter each cut from the scrap with the nest's internal
lead-in, or pierce on the line without one; checks treat break cuts as intentional open
cuts that are not material.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Forming backgauge tabs drawn as open cuts came off the sheet loose and could not be
planned. A breakoff merges the scrap into the outline and cuts the shared edge as
closed slots between tabs, so it stays attached and every pierce lands in scrap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lets a single drawing be opened and edited in the CAD converter
directly from the drawing list, reusing the existing apply-back
logic from the Edit Drawings button (now shared via
EditDrawingsInConverter).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
NestPipelineResult.Unplaced lists each requirement's unplaced copies with a
typed NestUnplacedReason, counted from the returned placements: no stock fits
at the sampled rotations, reserved in a cutout of an unplaced frame, stock
exhausted, plate limit, no position found, or proposal not keepable. Desktop
Auto Nest, Console --autonest and MCP autonest_plate/autonest_job report them;
the API returns NestResponse.Unplaced, persisted from response schema 5.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
NestPipeline.Run now bundles parts that fit other parts' enclosed cutouts
into their frames before the selected engine, for desktop, Console, MCP and
API alike. A valid complete bundled trial is kept; a refused trial falls back
to the ordinary solve (reason on RefusedCutoutTrial), and an incomplete trial
is compared with it, keeping whichever valid proposal places more. An
incomplete but valid trial is now keepable like any incomplete result.
Expanded sheets list each frame's inserts before the frame, so the committed
order cuts every insert before the cutout that releases its slug.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Posting review now proves containment exactly as the cutting planner does
(shared NestedPartContainment) and warns when a nested part is cut after its
host (NestedCutOrder) or when a host's hole lead or the nested part's lead
meets the other's material (NestedLead), including subprogram hole poses.
Ambiguous containment is incomplete, never clear; fixed-lead motions are not
reported twice. A committed cutout preview warns until Plan Cutting cuts the
insert first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fix the focus-sensitive failure in HighlightedNestShowsItsPlatesAndDrawings_AndEnterOpensIt from GitHub run 39042902952. Explicitly focus the nest grid and assert it owns focus before sending Enter. Production keyboard handling and all existing open, cancel, and missing-archive assertions remain unchanged.
The cut planner disabled "Add scrap cut-offs" along with every other
control while a plan ran, including the very first auto-started plan.
It now stays enabled; toggling it mid-plan cancels the run in progress
and restarts planning with the new setting.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Console and Mcp each re-derived whether a name was a fill strategy, a
whole-job engine or unknown. EngineNameResolver now owns that decision,
trims consistently and accepts renamed legacy engine names; front ends
keep their own message wording.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The 5.5 pinned-entry shortcut in ContourEntryFeasibility looked up the
choice's contour before the probe's own validation, so an owned choice with
an out-of-range contour ordinal threw instead of returning Incomplete as it
did before. The lookup now runs only for an ordinal inside the preparation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Since 5.2 a locked program's own rapid crossing is a fixed-lead warning on an
UNVERIFIED plate, so it no longer makes the panel's "Can't apply" case. The
blocked plate now holds overlapping parts, a hard block, and the test checks
the same navigation and no-partial-Apply behaviour.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Assign Lead-ins (LeadInAssigner) now leaves every unlocked part with active
drawing pins unchanged and returns those parts, so it never overwrites a pin
with the plate's settings; the desktop names them ("N parts kept their
drawing lead-ins (plate P: parts ...); use Plan Cutting to apply their
drawing pins."). Parts without pins, with pins switched off, or locked are
assigned or skipped exactly as before.
The pre-post review now covers drawing pins. A part with active pins whose
placed program does not cut each pinned contour exactly as the pin's own
emission (re-emitted with the part's cutting settings and matched motion for
motion) warns "Drawing pins not applied", as do locked lead-ins overriding
pins and a pin that no longer matches the geometry; pins switched off are
not reported. The contours that are cut as pinned join locked programs in
the fixed-lead re-check against every part's clean material, and fixed
leads are now also checked against active clamps (Plan Cutting itself does
not model clamps).
AGENTS.md records the fixed-emission safeguard and the characterization
digests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A drawing-pinned contour is now a fixed emission like a locked program. A
regenerated placement maps its execution motions onto the emitted contour
choices (one group per choice after the program's scribes, opened by its
rapids) and owns as fixed the lead-in, cut, lead-out and tab of every pinned
contour; the rapids between contours, including the one into a pinned
contour, stay the planner's and strictly checked. If the motions do not
split cleanly into one group per choice, nothing is treated as fixed.
So a pinned lead that meets another part's material or its own part's no
longer rejects the candidate: the feasibility precheck accepts a pinned
entry as given, the search keeps it in place, and replay reports a FixedLead
warning naming the part, cutting contour, pin and the part hit, with the
advice to increase spacing or switch off drawing pins for the part. The
plate is UNVERIFIED and needs acceptance; the lead is never shortened and
the entry never moved. The unpinned control and the same plate with pins
off are Ready.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Capture now honours a placement's pins only while they are active: a part
with DrawingPinsOff plans from the plate settings with no warning (D1's
per-part escape hatch), and Part.HasActiveDrawingPins is the shared test.
A pinned part is regenerated like any unlocked part whatever lead-ins or
settings it carried. A locked part with active pins keeps its exact program
and warns "Locked lead-ins override drawing pins on part N; Clear Lead-ins
to apply the pins." instead of being refused; an unlocked part a caller left
ineligible warns that its pins are not applied.
Apply's freshness record now holds each drawing's pin list (reference and an
explicit StateFingerprint of every pin's point, leads and tab) and each
part's pins-off flag, so editing either after capture returns Stale. The
fingerprint writer is shared between settings and pins; a reflection test
pins ContourCutPin's public surface to what the fingerprint covers.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PreparedContours.Capture(program, parameters, pins) takes CutPinResolver
results for the same contours and fixes every resolved pin's contour: its
one and only entry is the pin's point, and it is emitted through the
existing emitter with the pin's own lead-in, lead-out and tab (angle
rounding off, so the entry never moves). Every catalogue returns the pinned
entry alone and emission refuses any other entry for that contour, so no
search path can relocate it. The certified tab size is the pinned outside's
own, so a pinned tab gap is genuine and replay certifies it. Unpinned
contours keep the shared settings and automatic selection; without pins the
existing preparation is untouched (5.1 digests unchanged).
Capture now resolves a regenerated part's drawing pins. A pin that does not
resolve (not on a contour, on several, sharing one, or unplaceable) is never
guessed: its contour stays automatic and the plate gets a FixedLead warning
naming the pin, making the proposal UNVERIFIED. A tab pinned on an internal
contour cannot be cut as pinned (only the outside is tabbed) and warns the
same way. Pins-off, locked parts with pins and freshness follow in 5.4.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
D1a (user, 2026-10-14): one locked cutout must not refuse the whole layout.
With confirmed parameters a locked program is now a fixed emission, accepted
as given. The replay checker and the lead validator take a per-motion owner:
a violation inside the fixed emission (a lead meeting another part's or its
own material, a rapid inside the locked program crossing a cut contour, an
uncertifiable tab gap or a partial/reversed/retraced cut) is recorded apart
instead of failing the candidate. The search never rejects or learns an order
rule from them, so fixed emissions never steer it; the planner's rapid into
the locked program and every regenerated lead keep every strict check.
Replay turns those violations into typed FixedLead findings that name the
part, contour and the part hit. A plate whose only findings are these is
BestEffort with IndependentlyReplayed set: never Ready, applicable only with
the per-proposal acceptance, and CuttingPlanService.Apply still rejects it.
Overlap, unreadable programs, stale input and cancellation still block, and
unlocked programs a caller left ineligible and the no-parameter route keep
refusing as before.
Pre-post review now re-checks locked leads against every part's clean
material, so the same violations reappear before posting.
Existing tests that encoded the old locked refusal now assert the warning;
two batch tests that used a locked crossing as their hard block use an
overlap instead. The 5.1 digests are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>