bench: matrix v6 adds arch_roundtrip; four architectural correctness checks; the live arch smoke

The evidence for track F, in the shape tracks A, E and B + G used.

- benchmarks/tasks_v6.py: 19 tasks, DEFAULT_MATRIX = "v6"; v5 to v2 stay
  addressable. arch_roundtrip draws the example plan with
  arch_plan_from_spec and reads it back without the spec: rooms_detect must
  find each labelled room within 0.1 % of its label and of the net floor
  computed by hand (4825 x 5750 and 3825 x 5750), the schedules must list
  D1, D2, W1, W2, and the plan is gated on a zero-issue critique and a
  finalize score of at least 90. A test removes one room label and the gate
  fails naming arch_room_unlabelled.
- Four correctness checks, every number worked out by hand in the docstring:
  L / T / X junction corners and wall areas, a 4 x 5 m room labelled 20.00 m2
  rather than its 21.84 m2 axis area, a door interrupting both faces, and a
  plan of plain lines read as 20 and 15 m2 at confidence 0.6. The published
  A/B report is re-run over 43 checks: 26 / 43 -> 43 / 43, zero regressed.
- scripts/smoke_arch_com.py runs the whole plan once on a live seat and
  closes every document it opens; the CHANGELOG records what it returned.
- The token suite measures a TOOL_PACKS=core,arch row; check_doc_numbers
  derives the task count from the v6 matrix; CLAUDE.md, both READMEs and
  the spec status line say what shipped.
- fix(com): the first live smoke exited 1 - the room reader found 0 wall
  segments. Measured on AutoCAD 2026 (2026-09-23): with a makepy cache,
  ModelSpace.Item(i) returns the gen_py IAcadEntity wrapper
  (type(item).__name__ == "IAcadEntity") and item.StartPoint on an
  AcDbLine raises AttributeError, so every entity_list row lost its
  type-specific properties (28 wall LINEs, 0 with start/end). _entity_info
  now re-dispatches exactly that wrapper through _com_unnarrow; after the
  fix 38 of 53 rows carry start/end and the smoke exits 0 with both rooms
  at 27 743 750 / 21 993 750 mm2 and 0 critique issues. Re-dispatch
  measured at ~1.7 ms per entity (dynamic vs gencache alike).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
This commit is contained in:
Umut CAN
2026-09-23 23:35:46 +03:00
co-authored by Claude Opus 5.5
parent 6e004cc658
commit 0abbe55041
20 changed files with 952 additions and 53 deletions
+53
View File
@@ -568,6 +568,59 @@ def test_a_dimension_reports_where_its_text_stands():
assert props["text_position"] == [181.0, 230.0]
class IAcadEntity:
"""What pywin32 hands back for ``ModelSpace.Item(i)`` once a makepy cache
for the AutoCAD type library exists: acax25enu.tlb declares the result
``IAcadEntity*``, so the wrapper is the gen_py class of that name and it
exposes only the entity base's members. Measured on AutoCAD 2026
(2026-09-23, scripts/smoke_arch_com.py): ``type(item).__name__`` is
``"IAcadEntity"`` and ``item.StartPoint`` on an AcDbLine raises
``AttributeError: '<win32com.gen_py.AutoCAD 2025 Type Library.IAcadEntity
instance>' object has no attribute 'StartPoint'``. The concrete object is
reachable only through ``_oleobj_``."""
BASE_MEMBERS = frozenset(
{"ObjectName", "Handle", "Layer", "color", "Linetype", "Visible", "GetBoundingBox"}
)
def __init__(self, raw):
object.__setattr__(self, "_oleobj_", raw)
def __getattr__(self, key):
if key in self.BASE_MEMBERS:
return getattr(self._oleobj_, key)
raise AttributeError(
"'<win32com.gen_py.AutoCAD 2025 Type Library.IAcadEntity instance>' "
f"object has no attribute {key!r}"
)
def test_a_line_listed_through_a_narrowed_wrapper_keeps_its_endpoints():
"""``entity_list`` reads every entity through ``ModelSpace.Item``. With a
makepy cache the LINE rows lost ``start``/``end`` (only the bounding box
survived), so on the live seat the room reader found 0 wall segments and
``arch_plan_from_spec`` refused its first room label."""
from backends.com_backend import _entity_info
raw = _Entity(
"AcDbLine",
GetBoundingBox=lambda: ((125.0, 125.0, 0.0), (1000.0, 125.0, 0.0)),
StartPoint=(125.0, 125.0, 0.0),
EndPoint=(1000.0, 125.0, 0.0),
Length=875.0,
Handle="2B0",
Layer="A-WALL-E-N",
color=256,
Linetype="ByLayer",
Visible=True,
)
info = _entity_info(IAcadEntity(raw))
assert info.type == "LINE" and info.layer == "A-WALL-E-N"
assert info.properties["start"] == [125.0, 125.0]
assert info.properties["end"] == [1000.0, 125.0]
assert info.properties["length"] == 875.0
def test_com_geometry_bbox_is_the_drawn_body_without_the_attribute():
from backends.com_backend import _entity_info