refactor(understand): one reading of units, plan copies, scale and rooms

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
This commit is contained in:
Umut CAN
2026-09-24 14:45:27 +03:00
co-authored by Claude Opus 5.5
parent c4759e696d
commit 8c1a6cb27c
6 changed files with 244 additions and 347 deletions
+1 -1
View File
@@ -213,7 +213,7 @@ def test_the_method_sheet_is_generated_from_the_result(result, tmp_path):
assert method["Units: layout"] == "INSUNITS in → mm"
assert "x first, then y" in method["Rule: route"]
warnings = [row[1] for row in read_csv(files["csv"][3]) if row[0] == "Warning"]
assert any("INSUNITS declares in" in w for w in warnings)
assert any("INSUNITS declares Inches (1)" in w for w in warnings)
def test_kontrol_lists_the_unassigned_diameter(result, tmp_path):