fix: P0 — COM premium crash, lineweight truncation, ISO critique no-op

Three production-blocking defects + two legal/infra gaps from the recon pass.

R1 (CRITICAL): the 8 premium meta-tools (drawing_plan, drawing_critique,
point_from_snap, construction_xline, construction_clear, drawing_apply_iso_layers,
dimension_auto, entity_select_smart) raised NotImplementedError on the COM
backend — i.e. the entire "non-negotiable" premium workflow crashed on the
DEFAULT Windows backend. Lifted all eight to AutoCADBackend as concrete,
backend-agnostic implementations built on the shared abstract primitives +
the identical EntityInfo.properties contract, so both backends inherit them.
The only backend-specific piece left is the new `_create_xline` primitive
(XLINE has no cross-backend entity_create_* equivalent). Removes ~285 lines of
ezdxf-only duplication; the existing meta-tool test suite now covers shared code.

R2 (CRITICAL): layer_create/layer_modify/entity_set_properties used
int(lineweight), truncating every millimetre lineweight (0.50, 0.25, 0.18, 0.13)
to 0 — silently wiping the whole ISO 128 discipline, because engineering/layers.py
passes mm-floats while the MCP boundary passes hundredths-ints. Added
normalize_lineweight() to reconcile both conventions to ezdxf/COM hundredths and
wired it into all six call sites.

R3 (HIGH): _check_iso128 was a permanent no-op (everything was 0 from R2, so the
`lw <= 0: continue` guard skipped all layers). Fixed by R2; additionally exclude
CONSTRUCTION-class layers (intentionally sub-ISO 0.05mm scratch weight) to avoid
a new false positive, and corrected the misleading "normalises to mm" comment.

Also: add MIT LICENSE (referenced by CLAUDE.md but missing — legal gap) and
restore .github/workflows/ci.yml (lint kept non-blocking until the repo-wide
ruff cleanup; the test job is the real gate).

Verified: 182 passed / 2 xfailed; functional check confirms lineweights now
store as hundredths (GEOMETRY=50) and the ISO critique correctly flags a 0.40mm
layer while passing a clean ISO drawing.
This commit is contained in:
Umutcan Edizsalan
2026-06-18 10:02:09 +03:00
parent 9258da429f
commit 702af0d6e1
6 changed files with 397 additions and 344 deletions
+7 -2
View File
@@ -44,13 +44,18 @@ async def _check_iso128(backend: "AutoCADBackend") -> list[Issue]:
return [Issue("warning", "iso128", f"layer_list failed: {exc}")]
allowed = set(ISO_128_LINEWEIGHTS_MM)
for lyr in layers:
# CONSTRUCTION-class layers are intentionally sub-ISO (0.05mm scratch
# weight) and must be cleared before finalize — never an ISO violation.
if "CONST" in lyr.name.upper():
continue
lw = float(lyr.lineweight)
# AutoCAD sentinels: -1 (Default), -2 (ByBlock), -3 (ByLayer);
# 0.0 = ezdxf's "use default" — not an ISO 128 violation.
if lw <= 0:
continue
# ezdxf returns lineweight in mm-hundredths (e.g. 25 = 0.25mm) for
# some entity properties; the layer dataclass already normalises to mm.
# Layer lineweights come through as ezdxf/COM hundredths-of-a-mm
# (e.g. 25 == 0.25mm) — they are NOT pre-normalised to mm, so accept
# either the raw mm value or hundredths/100.
if lw not in allowed and (lw / 100.0) not in allowed:
issues.append(Issue(
severity="warning",