Skip to content

docs(terminal): root-cause + fix Terminal coordinate-frame mismatch#41

Merged
red1oon merged 55 commits into
masterfrom
fable/meshdb-livewire
Jul 11, 2026
Merged

docs(terminal): root-cause + fix Terminal coordinate-frame mismatch#41
red1oon merged 55 commits into
masterfrom
fable/meshdb-livewire

Conversation

@red1oon

@red1oon red1oon commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Summary

  • Root-caused the Terminal coordinate-frame mismatch between bim-compiler's deploy/buildings/Terminal_extracted.db and bim-ootb's modeller/Terminal_ARC.db, per prompts/TERMINAL_COORDINATE_FRAME_MISMATCH.md.
  • Ground truth (raw .ifc via ifcopenshell world-bbox-center) matches bim-ootb's frame (<2cm); bim-compiler's canonical DB was a carve-out of the multi-building sandbox_1M city demo (extract_per_building.py reading T0_Terminal_ rows from build_sandbox_1M.py's tile placement) stacked on extractIFCtoDB.py's S169 centroid-normalize — both uncorrected. Constant offset proven across 12 sampled guids (stdev <1mm).
  • Fixed deploy/buildings/Terminal_extracted.db in place (gitignored build artifact, not committed to git) with the proven-constant SQL offset correction; backed up, integrity-checked, re-verified against ground truth (<6mm all axes).
  • PROGRESS.md updated: item marked resolved, flags other CBD_BUILDINGS sharing the same carve-out path as unverified for the same bug class (follow-up, not done here).

This branch (fable/meshdb-livewire) carries prior accumulated session work already pushed to origin; this PR is just the diff needed to land it on master.

Test plan

  • ifcopenshell world-bbox-center probe on raw TerminalMerged.ifc reproduces bim-ootb's Terminal_ARC.db value to <2cm (ground truth).
  • 12-guid sample shows a byte-consistent constant delta (stdev <1mm on x/y/z) between bim-compiler's pre-fix DB and bim-ootb — rules out rotation/structural cause.
  • Post-fix deploy/buildings/Terminal_extracted.db: PRAGMA integrity_check = ok, row count unchanged (48,428), re-sampled guids match ground truth <6mm.
  • CI green (gated by repo's auto-merge bot).

🤖 Generated with Claude Code

red1oon and others added 30 commits July 10, 2026 14:45
… Modeller-only scope

Renumber WalkerDoctrine.md's duplicate §13 to §14 (rooms rule) and fix the citation.
Drop the dead SAMPLECASTLE_REAL_ROOMS_RECONCILE.md anchor (lives only on an unmerged
branch, not this one). Reframe the Viewer Find Panel Room Lens reference as a one-way,
read-only borrow-from source for the Modeller's ARC-import step, name its unfiltered
query as a live false positive, and explicitly scope Task 5 to Modeller-only — no
Viewer files touched.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
MANAGER.md said "get the actual thing working" without citing what working means,
letting review verdicts drift toward generic pass/fail instead of the actual product
bar. Point at RESUME_GRAPH_MODELLER_INTEGRATION.md §VISION-LOCK's five sentences.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…t real

Direct query (object_type=COMPILED, ≈-named) proves Terminal has zero real IfcSpace
rooms — the doc previously miscounted them as "real rooms already baked in." Same
correction applied to HHS's 14 rows (already caught by Task 5 but §2's table hadn't
been updated to match). Adds the full 8-building room-count table: only Duplex has
real, habitability-filtered data, and it isn't merged to main yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… bug

Direct grep of internal/sources/Ifc4_SampleHouse.ifc finds 4 real IFCSPACE entities
(Living room, Bedroom, Entrance hall, Roof) that never made it into the shipped
SampleHouse_ARC.db (0 rooms) — an extraction gap, not a source-data gap as previously
assumed. Clinic/Garage/Hospital/HHS have no source IFC in this checkout to check
either way, so their "0 rooms" state is unverified, not confirmed-no-data.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…forward work to Sonnet

Task 6: 3 usable real rooms exist in SampleHouse's source IFC but never reached the
shipped ARC — an extraction bug, not a data gap. Per user directive, all further work
on this doc goes to Sonnet, not Fable, from here on; Tasks 1+5's Fable history is left
as an accurate record, not rewritten.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…/utility) below MIN_AREA

User-flagged, verified before fixing: HHS ("large U-shape office block, lots of office rooms
with doors") only compiled 2 rooms; restrooms/utility rooms were being missed across every
building, not just HHS. Instrumented the flood-fill to log ALL candidate pockets (not just
accepted ones) — confirmed this was NOT a mis-tuned MIN_AREA=4.0 threshold hiding rooms that
were actually detected: most sub-threshold pockets are <1.0 m^2 wall-joint/cavity artefacts
(noise), but a real population of 1.0-4.0 m^2 pockets IS a genuine small room (restroom/closet/
riser) wrongly dropped by the same blanket cutoff.

The user's hint ("rooms has doors" / "look for clues that define a toilet, utility that house
MEP") pointed at the fix: MEP fixture data isn't reliable (ARC-only discipline strip already
removed sanitary/plumbing elements from 4 of 5 buildings), but door adjacency is a real,
non-invented structural signal already in every ARC.db — a genuine small room a person uses
always has a door; a wall cavity never does. Measured before shipping: for HHS/Clinic/Hospital/
SampleCastle, pockets <1.0 m^2 are rarely door-adjacent (noise); pockets in [1.0, 4.0) m^2 are
door-adjacent in the large majority (real small rooms) — the two size bands are different
populations, not an arbitrary split.

- storey_doors() + _door_adjacent(): per-storey real IfcDoor centres, 1.0m buffer.
- flood_rooms(): a pocket in [DOOR_RESCUE_MIN_AREA=1.0, MIN_AREA=4.0) m^2 is now accepted iff
  door-adjacent; still-tagged ≈/RM_/COMPILED (spacesOf()'s placement-exclusion untouched) but
  predefined_type='INTERNAL_SMALL' (vs 'INTERNAL') for traceability of which path found it.
- Re-ran --write on the 5 gap buildings: HHS 2→5, Clinic 113→190, Hospital 142→213,
  SampleCastle 25→47, Garage unchanged (0 door-adjacent small pockets found).
- W-ROOM-INJECT-ALL8 rerun 32/32 on bim-ootb worktree: placement-eligibility still 0 for every
  synthetic-only building — door-rescued rooms are exactly as display-only as any other
  compiled room, never reach schedule placement.

Doc: prompts/Modeller/DISC_Walker/ROOM_INJECTION_HYBRID.md updated with the finding + fix.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…bandwidth cap hit

GitHub flagged 10GB/month LFS bandwidth usage. 59+ .db files already LFS-tracked
(deploy/buildings/*, build/*.db) burn quota on every clone/fetch. Going forward:
schema/rules DBs regenerate via migration/*.sql or their mining scripts; extracted/
derived building DBs distribute via OCI (already the dev/live channel), not git.
Existing LFS-tracked files are left alone — this only stops new commits.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…rule

User pushback (correct): the previous §DOOR-RESCUE fix used DOOR_RESCUE_MIN_AREA=1.0 and a flat
1.0m buffer picked by eyeballing HHS/Clinic/Hospital's specific data — a fitted band, not a rule.
This generalizes it:

- The room definition is now architectural, not size-banded: an enclosed pocket is a room if it
  is big enough on its own (area >= MIN_AREA, unchanged) OR it has a real door AND isn't a bare
  rasterization sliver. No area number stands between "noise" and "small room" anymore.
- Door adjacency buffer is now each door's OWN extracted footprint (half its real leaf/frame
  span) + one grid cell of slack (RES) -- self-scaling to whatever doors a building actually has,
  not a fixed metre guess that happened to work on 5 sample buildings.
- The noise floor is NOISE_FLOOR_DIM = 3*RES (0.6m) -- a pocket narrower than a few grid cells in
  EITHER axis is rasterization noise by construction, a property of the flood-fill's own
  resolution, not an area threshold reverse-engineered from observed rooms.

Re-verified: HHS 6, Clinic 195, Hospital 201, SampleCastle 53, Garage 5 (close to, not identical
to, the earlier fitted-band numbers -- expected, since the rule is now geometry-derived rather
than tuned to match them). W-ROOM-INJECT-ALL8 rerun 32/32 on bim-ootb worktree.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…evidence

Tested SEAL=1 (narrower wall-dilation) to try to recover HHS's WC-stall spaces the user found
named in German ("WC Trennwand") — rejected: doesn't fix HHS (the WC block's OWN enclosing walls,
not just its internal stall partitions, are simply absent from this extraction, a resolution/
data-completeness issue SEAL can't touch) AND it fragments real rooms elsewhere into spurious
1-2 sq.m splinters in Hospital (142->253, mostly noise) and SampleCastle -- a regression, not an
improvement. Reverted to SEAL=2 (already-shipped, verified value unchanged).

Separately, user asked whether doors have standard dimensions we could use as a smell test.
Checked: real hinged doors cluster 0.7-1.1m (single leaf) / 1.2-2.7m (double leaf/wide entrance)
across all 5 buildings' door data -- consistent, no anomaly, EXCEPT SampleCastle: 28 IfcDoor rows
at 0.5m width, all named 'liftdeur' (Dutch: elevator door). Real, correctly-classified doors --
but they lead to a lift shaft, not a room, and 2 of them were rescuing actual elevator-shaft
fragments as fake compiled "rooms" (verified directly: room count with vs without lift doors as
the door-rescue signal differs). Same shape of problem as the existing §STAIR-EXCLUDE pattern --
excluded via a maintained, multi-language door-name keyword list (liftdeur/lift/elevator/aufzug/
fahrstuhl/hoist), not a width cutoff (a lift door's width isn't reliably distinct from a narrow
single-leaf door's).

SampleCastle 53->51 (the 2 lift-shaft fakes removed); HHS/Clinic/Hospital/Garage unchanged (no
lift doors in their door-rescue signal). W-ROOM-INJECT-ALL8 rerun 32/32.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…en where walls can't

User's repeated, correct point: HHS has 43/39/34 real doors across 3 floors (verified directly,
German-named "Türelement... Drehflügel" = swing-door elements) -- "each door must be to a room."
Flood-fill (even with §DOOR-RESCUE) only ever found 4/2/0 rooms on those floors because HHS's
extraction is missing the walls that would divide the floor into individual offices at all (91%+
of each floor floods as one exterior-reachable blob) -- door-rescue only widens acceptance for
pockets flood-fill ALREADY finds enclosed; it can't help where nothing is enclosed to begin with.

New technique for where wall-enclosure structurally cannot work: partition the storey's free space
by NEAREST DOOR (multi-source BFS through real free cells, real walls still block) -- each door
claims whatever space no other door reaches first, exactly the "every door leads to a room"
principle stated directly, not an area/threshold proxy for it.

Gate (measured, not fitted per-building): use door-partition only where flood-fill's OWN result
(with door-rescue already applied) finds fewer rooms than DOOR_SHORTFALL_RATIO=0.15 of the
storey's real door count -- HHS's floors find 0-11% of their door count via flood-fill; every
other building's WORKING floors find 20-100%+ of theirs (Garage's sparsest working floor: 5/8=62%;
Hospital's sparsest: 1/5=20%) -- the ratio sits below every failing floor and above every working
one, verified directly so it never overrides an already-functioning result (Garage's 5-room floor
and Hospital's 1-room floor both correctly kept their flood-fill result unchanged).

Result: HHS 6->105 (36/31/29/9 per floor -- in the "tens per floor" range the user predicted from
door counts alone). Clinic/Hospital/Garage/SampleCastle counts unchanged except Clinic's near-empty
'Unknown' storey (0->2, same gate correctly firing there too). predefined_type='INTERNAL_DOORPART'
marks these rows for traceability; object_type='COMPILED' (what tag-purity/placement-exclusion
checks key on) unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tability+door-partition results to Find Panel
…m-ootb port

Records the merge (b202eb4) and hands off the one remaining task: port
rule_frame_ref mining + walk-time zOff to bim-ootb's own disc_walker.js and
terminal_rules.db — the fix is bim-compiler-only, the actual Modeller app still
has the collapse bug live until this ports over.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Committing DBs wasn't the only cost: 49 bim-ootb worktrees + a duplicate ~/Projects/bim-ootb
clone were each pulling fresh 100-250MB mesh.db/geo.db LFS blobs. Real end users never
touch git LFS at all (they hit the deployed static site) — 100% of the quota was dev-side
worktree churn. Removed the duplicate clone (confirmed clean, 100+ commits stale) and
pruned 25 safe (clean + fully-pushed) stale worktrees in bim-ootb. Protocol: check
`git worktree list` before creating a new one, one clone per repo, prune on sight.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…tions

GitHub confirmed 0 bandwidth budget remaining, not just approaching the cap. Escalates
the earlier reduce-usage guidance to a hard block: no pushing any commit that touches
LFS-tracked content, no fetching/checking-out branches whose LFS blobs aren't already
locally cached, until the user confirms the quota has reset. Applies to every Agent-tool
prompt that touches git, not just this session.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…repo, right file, new findings

User caught it: the doc anchored on bim-compiler/deploy/dev/navigate_find.js, which turns out to
be a STALE, unmaintained fork (2859-line diff vs the live copy, no recent commits since this
repo's initial migration). The actual, actively-developed Viewer code is bim-ootb/viewer/
navigate_find.js (3640 lines, commits as recent as pill-drawer/HBA work) -- same repo as Modeller's
disc_walker.js, removing the cross-repo constraint the original doc assumed.

Checked the live code directly and found it's further along than assumed (storey grouping + a
Storey/Type toggle already exist) but also found a new, concrete bug: the Type toggle's
`object_type || predefined_type` fallback never reaches predefined_type for compiled rooms, since
object_type='COMPILED' is always truthy -- masks the INTERNAL/INTERNAL_SMALL/INTERNAL_DOORPART
distinction compile_rooms.py now writes.

Biggest correction: confirmed viewer/import_db_builder.js (the live "drop your own IFC" schema
builder) never creates a spatial_structure table at all -- a user's own imported building gets ZERO
room data today, real or synthetic. Scoped as its own Task 5, separate from the display-only fixes,
since fixing it means porting compile_rooms.py's algorithm from Python to JS (no Python runs in a
browser) -- not a quick win.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…e-once via explicit trigger

User's call, this session: since real usage is 100% JS (no server, no Python runtime in the
browser — confirmed for the live IFC-import path), retire compile_rooms.py in favor of one JS
port usable both offline (Node CLI, replacing today's Python bake for the 8 shipped residents) and
in-browser (a new Modeller Outliner "Room Walker" action, parallel to the existing Disc Walker
convention). Explicitly NOT "recompute live on every open" -- user's own point that this costs
real time (HHS's grid alone is ~90k cells/floor) -- compute once, on demand or at import, persist,
same principle as today's offline bake just relocated to whichever moment actually needs it.

5 tasks specced: (1) verify how Disc Walker is actually triggered today before assuming a UI
pattern to copy -- unconfirmed this session; (2) port the algorithm verbatim to a shared JS module;
(3) Node CLI mode replacing compile_rooms.py, witnessed byte-for-byte against this session's Python
counts (SampleHouse 3/Duplex 20/Terminal 43/SampleCastle 51/HHS 105/Clinic 197/Garage 5/Hospital
201) before Python is touched; (4) the browser-mode Room Walker Outliner action; (5) retire
compile_rooms.py once Task 3's parity witness is 100% green.

Cross-referenced from ROOM_INJECTION_HYBRID.md's Task 3 (now has a concrete trigger mechanism
instead of an open-ended display spec) and VIEWER_FIND_PANEL_ROOM_ACCURACY.md's Task 5 (this doc
is its actual breakdown).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…less of content

User-confirmed reset date. Also sharpens the finding: a push touching zero LFS-tracked
files still hung 2+ min and never landed (fix/dw-datum-port push attempt) - the git-lfs
pre-push hook appears to probe the endpoint unconditionally. Rule is now "any push may
hang until reset," not just LFS-content pushes. Don't retry a hung push blindly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…external target

VISION-LOCK is the internal engineering bar; the guide site is the user-facing proof
it's met. Notes current known gaps (Terminal datum port stuck behind LFS block,
room-mode data coverage, x-ray bug, 2 live Viewer UI bugs) so a new session doesn't
have to re-derive "how far are we" from scratch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Verified and pushed successfully (earlier push attempt's 2-min hang was transient,
not a hard LFS block - retry succeeded in 25s). Terminal collapse bug heals once
PR #726 merges (user's call).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…status, LFS quota, 2 Viewer bugs

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…llenge answered, W-SCHED-MINE 7/7 + W-DX-WALKBACK-RSGT 14/14 clean-room on committed state

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…l SQL, no-LFS channel for stale mesh.db copies (W-MESHDB-RESOLVE 2/5→5/5, byte-identical, idempotent)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
red1oon and others added 25 commits July 11, 2026 01:53
…ine against silent spatial_structure loss

Reframed the task after checking Task 6's own finding: the regression source isn't the
b93ca13 ARC-only strip (already disproven — spatial_structure was unchanged across it),
it's finalize_all_8.js's generic per-building meta-split silently shipping an empty
spatial_structure table whenever its (ephemeral, unpreserved) source lacks one — the
confirmed cause of 7/8 buildings' room-data loss in 6068fab.

Hardened finalize_all_8.js: explicit carrySpatialStructureForward() falls back to the
currently-shipped resident ARC.db when the fresh source has no room data, plus a
regression gate that aborts if carry-forward reported data but the write-time db
disagrees. module.exports + require.main guard added so the logic is unit-witnessable
without the vanished /tmp scratch inputs.

Witness W-SPATIAL-CARRY (9/9) reproduces the exact Duplex/SampleHouse regression shapes
against real data already local in /tmp/wt-fable-livewire (read-only, no LFS fetch).

Re-running the full pipeline against bim-ootb main and pushing regenerated *_ARC.db
files stays LFS-blocked until 2026-08-01 — this commit is the script fix + witness only.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ion scripts carry spatial_structure into main, no binary push

Per repo convention (migration/DV_*_rules.sql, CL002_name_value_component_library.sql):
never touch a shipped DB as a binary commit when a deterministic SQL script can carry
the same content. bim-ootb main's 6 residents (SampleHouse/HHS/Clinic/Garage/Hospital/
SampleCastle) still ship 0 spatial_structure rows, and Duplex still carries the
unfiltered Roof row -- both real, verified on the unmerged fable/modeller-lod400-livewire
branch but not on main.

ROOM001-006_*_spatial_structure_carry.sql: full spatial_structure DDL + INSERT rows dumped
straight off livewire's real data (sqlite3 .mode insert, no BLOB columns in this table).
ROOM007_Duplex_strip_roof.sql: single DELETE -- confirmed by direct diff that main's 26
rows differ from livewire's 25 by exactly the R301 Roof row.

witness_room_migration_apply.sh (W-ROOM-MIGRATION-APPLY, 7/7): applies every script to a
scratch copy of main's real *_ARC.db and diffs the FULL resulting table against livewire's
real data -- byte-identical on all 7. Text-only diff, no LFS content touched.

This gets any local main checkout on par with the branch's room data by running
`sqlite3 modeller/{Name}_ARC.db < ROOM00N_*.sql` -- it does not deploy to the live site
(needs an actual DB commit, still LFS-blocked until 2026-08-01).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…low-up

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…r, port compile_rooms.py to JS

Task 1: traced dwWalk()'s real call chain (missed by a modeller/*.js-only grep — the actual
call site is in modeller.html's inline script). Confirmed explicit-user-action only (Outliner
discipline-row click -> onWalk callback -> bonsai_outliner.js's single dispatch chokepoint),
never automatic-on-load. No inconsistency to flag — Room Walker can copy this exact convention.

Task 2: build/room_walker.js ports compile_rooms.py's flood-fill/door-rescue/door-partition
algorithm verbatim (every constant + its justifying comment carried over unchanged). Same
db.exec()/_rows() sql.js interface disc_walker.js and finalize_all_8.js already use, so one
implementation genuinely serves both Node and browser -- no dual-implementation split.

Witness W-ROOM-WALKER-PARITY (6/6): runs the real Python and the JS port against separate
scratch copies of the same real building data and diffs the FULL resulting spatial_structure +
rel_contained_in_space content (not just counts) -- byte-identical on SampleCastle/HHS/Clinic/
Garage/Hospital/Terminal, both the door-rescue and door-partition paths exercised.

Surfaced, not silently fixed: Terminal's fresh algorithm run gives 53 rooms, not the 43
currently shipped -- shipped data predates the door-rescue/door-partition refinements. Flagged
as a content decision (BLOCKED), not assumed either way.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…oom-count question flagged

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…ration, not a binary

User decision 2026-07-11: precision over staleness for display-only data. Terminal's shipped
spatial_structure (43 rooms) predates the door-rescue/door-partition refinements to the
compile-rooms algorithm; re-running today's algorithm (verified byte-identical between
compile_rooms.py and its JS port) gives 53. ROOM008_Terminal_correction_43_to_53.sql applies
the fix via sqlite3, no binary DB commit -- full replace is safe since Terminal's entire
spatial_structure table is synthetic (0 real rows).

witness_room008_terminal_correction.js (W-ROOM008-TERMINAL 4/4): migration-applied result is
byte-identical to room_walker.js computed fresh from the same real source geometry right now,
elements_meta confirmed untouched. This closes ROOM_WALKER_JS_PORT.md Task 3 fully (both bars).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…er shipped

Ports the Task 4 SQL migrations + MDB001 into bim-ootb modeller/patches/,
wired into str_walker_outliner.js's resident/geoDb open path (W-PATCH-SELFHEAL
43/43) — closes the manual-sqlite3-step gap the prior follow-up left open.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… real Duplex MEP (11 rows, all guard-allowed families median-exact; M3 two-level verbatim; W5-ZFAM diagnostic; 14/14+7/7)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… category, retire compile_rooms.py from room-injection duty

Task 4 (browser wiring done in bim-ootb worktree, this commit is the bim-compiler-side fix
the browser witness caught): compileRooms() queried spatial_structure unconditionally for
storey guids, but Python's compile_rooms.py wraps that specific query in try/except because a
truly fresh building has no such table yet. The node-side parity witness never exercised this
path since every real shipped _ARC.db it compared against already had a spatial_structure
table -- only the live browser test (dropping the table entirely to simulate a fresh building)
surfaced it. Fixed with a table-existence check, mirroring Python's guard exactly. Re-verified:
node parity witness still 6/6, browser witness 12/12 (see bim-ootb companion commit).

Task 5: compile_rooms.py is retired from room-injection duty but NOT deleted -- found a real,
unrelated dependency (scripts/witness_geomap_tier3.py imports it directly as a Python baseline-
scoring library). Updated ROOM_INJECTION_HYBRID.md's Task 2 (automation half superseded by the
explicit-trigger Room Walker design, not built as originally specced) and
COMPILE_ROOMS_TYPE_INFERENCE.md's anchor (points future work at room_walker.js, not the now-
superseded Python file) so no future session gets misdirected.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…chored WALL_HIGH + mined z (detector: median edge 0.09m vs pendants 0.96-2.28m; W6 0.963→1.000; pendants honestly refused)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…n/walker/M3), 0 slots on Duplex BY MEASUREMENT: wall choice is mirror-dependent, absolute MIN/MAX refs refuse honestly (seam proven by falsifier, byte-inert at 0 rows)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…SPECT_* review rows (ROOM009-014)

User visual review on HHS localhost found two algorithmic defects: a corridor accepted
as a room (open non-wall edge) and a room rect crossing through a wall. Root-caused on
real ARC data across all 8 buildings (not HHS-patched):
- §WALL-VERT: IfcCurtainWall parents have NO transform — curtain walls rasterized as
  nothing. Their IfcMember/IfcPlate children join the raster iff bbox_z >= 0.5×median
  real door height (self-scaling; Terminal's 33k flat Metal Deck plates stay out).
- §STOREY-Z: 'Unknown'-storey enclosure/doors (HHS 716, Hospital 3760 rows) reassigned
  to the z-nearest real floor. HHS flood-fill recovers on all 3 levels — door-partition
  (the corridor-blob source) no longer triggers there.
- §RECT-HONESTY: room rect = largest inscribed rectangle expanded to raw walls, replacing
  the region bbox — a rect can no longer paint across a wall into the next room.
- §ROOM-FORM (user doctrine "a room must be well formed, fully enclosed, has door"):
  openM (unsealed perimeter, 3-wide probe) > 2×median door width → SUSPECT_OPEN;
  no adjacent door → SUSPECT_NO_DOOR. Suspects keep '⚠'-marked rows for a future review
  feature, excluded from rel_contained_in_space; never silently dropped.

Both implementations updated in lockstep (compile_rooms.py numpy paths → plain flat
arrays mirroring the JS port operation-for-operation). Witnesses: W-ROOM-WALKER-PARITY
6/6 byte-identical; NEW W-ROOM-WELLFORMED 19/19 (independent-raster falsifiers: zero
wall-crossing non-suspect rects, zero suspect containment, HHS corridor collapse cannot
re-form). ROOM009-014 migrations verified apply-identical to walker output (6/6).
New counts: SC 51(9⚠) HHS 33(2⚠) Clinic 209(26⚠) Garage 5(3⚠) Hospital 213(66⚠)
Terminal 53(10⚠). Spec: ROOM_INJECTION_HYBRID.md §7.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ne budget)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… grouping (ROOM015-020)

A confirmed room's single §RECT-HONESTY rect under-covered non-rectangular rooms
(measured coverage down to 0.23-0.26 — the user's "doesn't fully form the inner room
space"). Per ROOM_INJECTION_HYBRID.md §8 (user-directed 3-step design):
1. Fill-ratio preprocessor: rooms whose first rect covers >=0.95 of the (seal-band-
   recovered) region stay single-row — the majority, cheapest path.
2. Room space set: below the bar, the region decomposes via repeated CONSTRAINED
   maximal-rectangle scan (both dims >= NOISE_FLOOR_DIM, grid-derived; stop at 0.95
   coverage or 8 rects — measured max used: 7). No wall-crossing by construction;
   curved-wall residue reported honestly, never faked.
3. Shared identity: one spatial_structure row per sub-rect; primary keeps RM_<st>_<k>,
   extras lettered (b, c, ...); NEW room_guid column groups the set; identical
   name/predefined_type; rel_contained_in_space keys LOGICAL guids only (any-rect
   containment). SUSPECT rooms stay single-rect (orthogonal to §ROOM-FORM).

Both ports lockstep; includes the concurrent §DISC-ARC discipline filter (Sonnet,
same working tree — merged, not overwritten). Coverage gains (W-ROOM-FILL, median/
worst): Hospital 0.74→0.86 / 0.32→0.67, Terminal 0.81→0.87 / 0.42→0.69, Clinic
0.78→0.81 / 0.45→0.57, per-room monotone. Witnesses: W-ROOM-WALKER-PARITY 6/6
byte-identical (dump now covers room_guid), W-ROOM-WELLFORMED 19/19 (zero regression,
sub-rects in the wall-crossing oracle), NEW W-ROOM-FILL 18/18, ROOM015-020 migrations
apply-identical 6/6 (supersede ROOM009-014's single-rect data).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…/archive/ (evidence-logged)

9 archived (self-declared DONE/DEPRECATED/DRAINED + zero blocking refs), 22 kept live,
6 flagged ambiguous. Full per-file evidence trail in prompts/PROMPTS_ARCHIVE_AUDIT_2026-07-11.md
§Log. docs/*.md swept: nothing to archive (all live mkdocs pages, post-07-03 unified pass).
git mv only — history preserved. CLAUDE.md/PROGRESS.md FLM pointer fixes left uncommitted
(files dirty from concurrent lanes).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…y shipped, real gap was substrate

Corrects this doc's own "render wiring not started" framing: _renderDiscChains/_commitDiscChains
(§ROUTER-NNCHAIN, §CAMPAIGN M4/M5) already render routeChains' segments as cylinder tubes. The
actual remaining gap: witness_modeller_router_nnchain.js is RED on bim-ootb main (shipped
Terminal_ARC.db resident is ARC-only, 0 MEP) and __dwPixelProbe's A/B-isolation missed dwChain-
tagged tubes (fixed). New witness_mep_route_render.js proves Terminal PLB 4315 + ACMV 1002 = 5317
and Duplex PLB 358 segs render + paint real isolated pixels, matching W-WALKBACK-MEP's oracle.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…HHS buildings db + §4 execution log

VIEWER_FIND_PANEL_ROOM_ACCURACY.md §2b: buildings/HHS_Office_Federated_extracted.db
(the file the Viewer actually fetches for HHS) still shipped the stale 14-row set;
ROOM021 ports the SAME source-of-truth data as ROOM002 (modeller/HHS_ARC.db @
fable/modeller-lod400-livewire fd7da67, extracted via sqlite3 .mode insert) to the
buildings/ target. Applied+verified locally (§ROOM021-PARITY byte-identical, 109
rows); binary stays uncommitted per the DB-via-SQL-migration rule. §4 appended:
Tasks 1+2 DONE in bim-ootb fix/viewer-room-accuracy @ a995908 (local only, LFS
block) — W-VIEWER-ROOM-HAB 6/6 (Duplex 20 habitable + R301 label:ROOF excluded;
HHS 105/0 leaks), W-VIEWER-TYPE-GROUP (COMPILED:105 -> INTERNAL_DOORPART:105).
No Viewer-side self-heal .sql loader exists (checked; Modeller's is on unmerged
fix/meshdb-selfheal-loader only) — noted as open follow-up, not invented.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ped, supersedes stuck §4

§4's fix/viewer-room-accuracy worktree was left uncommitted-beyond-local and unpushed, missing its
own named follow-up (no Viewer-side self-heal loader). Rebuilt clean this session: bim-ootb PR #732
ships the habitability filter (Task 1), the Type-toggle COMPILED fallthrough fix (Task 2), and the
HHS buildings/patches/ SQL migration + runtime self-heal loader (§2b) — witness 11/11, pushed with
no LFS stall (corrects §4's over-cautious "no push possible" note). ROOM021_HHS_buildings_extracted_
carry.sql (already committed by §4) cross-validated byte-identical to the new patch's payload.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
… open; flag concurrent worktree

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…in place

TERMINAL_COORDINATE_FRAME_MISMATCH.md: bim-ootb's Terminal_ARC.db matches
raw-IFC ground truth (<2cm, verified via ifcopenshell world-bbox-center on
the source .ifc); bim-compiler's deploy/buildings/Terminal_extracted.db was
a carve-out of the multi-building sandbox_1M city demo (extract_per_building.py
reading T0_Terminal_ rows verbatim from build_sandbox_1M.py's tile-placement
output, scripts/build_sandbox_1M.py L216-320) stacked on extractIFCtoDB.py's
S169 centroid-normalize (L1453-1506) — both uncorrected. Delta proven constant
across 12 sampled guids (stdev <1mm): (545.61m, 51.22m, 14.66m).

Fixed deploy/buildings/Terminal_extracted.db (gitignored build artifact, not
committed) in place with the proven-constant offset correction; backed up,
integrity-checked, re-verified against ground truth (<6mm on all axes).

PROGRESS.md: mark item resolved, flag other CBD_BUILDINGS sharing the same
carve-out path as unverified for the same bug class.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…hipped, OCI upload block lifted

Room_guid multi-rect grouping ported into viewer/navigate_find.js's _allRoomVolumes()/
_roomLensOn() (bim-ootb PR #733), witnessed 8/8 (rendered box footprint-area SUM = spatial_
structure's own rect-union area SUM, diff=0.000m2) with zero regression to the existing
habitability-filter witness (11/11). Closes the standing OCI room-data upload blocker.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…oom-template strategy specs

- CLAUDE.md: DB changes are permanently migration-script+self-heal-loader, not an LFS workaround —
  stop citing LFS as the blocker for DB fixes.
- prompts/MANAGER.md: PR merge is standing Manager scope once independently verified, don't kick
  back an already-answerable merge decision.
- VIEWER_FIND_PANEL_ROOM_ACCURACY.md / UBBL_RULES_GATE.md: MANAGER assignment markers + doc-trail
  corrections from today's dispatched work.
- ROOM_TYPE_TEMPLATE_CLASSIFIER.md: new spec, room-type classification via size/aspect-ratio
  template mined from Duplex's real object_type ground truth, repeat-confirmation methodology.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Resolved PROGRESS.md conflict: kept today's current CURRENTLY JUGGLED status as primary,
folded in the 2026-07-10 marathon's still-open items (4 unmerged branches, guide-screenshot
failure, SampleCastle closure note) that weren't superseded. Auto-merged build/disc_walker.js,
build/project_rule_mesh_binding.py, build/terminal_rules.db, scripts/witness_terminal_nospaces.js,
RESUME_DISC_WALKER_ENVELOPE_BOUND.md — syntax/integrity-checked clean post-merge.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@red1oon red1oon merged commit 1b48865 into master Jul 11, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant