Groups U and N were built side by side, so the takeoffs carried narrow
stand-ins for what group U reads properly. On main they read through U:
- describe.drawing_units is the one call every reader makes (kept records,
labelled room faces as evidence); describe, scale_check and the takeoffs
all use it. Without the room faces, a layout that declares inches over
millimetres can tie three ways and fall to the header.
- layout_tags takes its plan copies from describe.prepare, room_regions its
rooms from describe.find_rooms, and pipe_rows its scale from scale_check,
per-room groups included. scale_stand_in and the takeoff's own unit bands
and cluster grid are gone.
- test_understand_one_reading pins the agreement: one unit, one plan copy,
one verdict and one set of rooms per drawing, across drawing_understand,
drawing_scale_check and the two takeoffs.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd
Equipment tags found exactly once in each drawing are matched (a tag
found twice - a plan copy, a legend - is reported ambiguous and takes no
part; two plan copies resolve to the cluster that matches the most
tags). For every pair of matched tags at least min_pair_mm apart on the
reference, the ratio of their distances is taken in millimetres by each
drawing's inferred unit; the median, the quartiles, the share within
+/-10 % of the median, the same per room of the reference, and the
verdict: to_scale (>= 80 %, with its factor), schematic (<= 50 %),
partly, or insufficient under three matched tags.
server.py grows SECTION 26 to two tools with drawing_scale_check (core,
read-only, tagged analysis/query); alias record, inventory, README
release snapshot 243, frozen group sizes (analysis 14).
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FKFStjEFzpGyLq5bMpWxTd