Three defects in the feature catalogue, all faithfully transcribed from the
plan text and all wrong in shipped code.
1. Keyway.prims(view="side") emitted the arc the keyway REMOVES. `Arc` is CCW
start -> end, and the emitted (right wall -> left wall) is the ~31 degree
cap over the slot opening, not the ~329 degrees of shaft that survives it.
Measured live on AutoCAD 2026 (Documents.Add scratch doc, closed in a
finally): ModelSpace.AddArc(center, radius, start_rad, end_rad) -- angles in
RADIANS, CCW start -> end -- gives ArcLength 8.098 mm for the emitted
74.534 -> 105.466 deg and 86.150 mm for the reversed 105.466 -> 74.534 deg,
against a 94.248 mm full circle at r = 15; StartPoint/EndPoint of the
emitted arc are exactly the notch walls at x = +/-4. Swapped, so the arc now
runs left wall -> right wall the long way round, and the side view's bbox
goes from (-4, 11, 4, 15) to (-15, -15, 15, 14.457).
2. Hole and Pocket cut the plate from OPPOSITE faces in the same view frame:
Hole ran z = 0 -> depth, Pocket z = thickness -> thickness - depth, and
neither takes a face parameter. A plate carrying both showed the pocket
milled from one side and the blind hole drilled from the other, silently --
omission() returns None for both, so nothing reported it. The frame comment
now names the machined face (v = thickness, the face the front view looks
at), and Hole drills from it: the blind floor, the counterbore step and the
through bore all hang down from there, as Pocket already did.
3. Chamfer.validate bounded the axial leg against the whole part, never against
the segment the chamfer sits on. A shallow lead-in passed validation and was
drawn straight through a shoulder at a radius that segment does not have
(size 30 at 10 deg on a 15 mm end segment: radial 5.29 < 10 so the radial
guard was happy, yet `before` landed at x = 45, two segments away). New
helper _anchor_segment names the segment a corner actually cuts into -- at a
step, the adjacent one carrying the larger radius -- and the leg is bounded
by its length, refused by name with the step it would have crossed.
Tests: the keyway test asserted only primitive counts and two x coordinates, so
it passed with the arc reversed; it now pins the sweep, the endpoints and the
bbox. The hole test exercised only a through hole, which is symmetric; added a
blind-hole-and-pocket test that pins both to the same face, and a counterbore
test. Added three chamfer tests (two refusals, one that must still be
accepted). Each fix was mutation-checked: reverting it fails its test.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd