PIXELPUNK JOURNAL / CHAPTER 05 Editorial evidence captured 23 September 2026. These are historical project notes. Status and next-step instructions in these excerpts belong to their original development session. Performance and test results quoted here are from those sessions, not tests performed by the journal build. ======================================================================== docs/facade-scale-plan.md | original lines 30–116 ======================================================================== bridges whose arch ring reads from the side, and big blocks built from a base, a body and a crown rather than a repeated cell. ## 2. Findings ### F1. Arched windows are discs, not arches `Architecture.window` (`scripts/architecture.gd:247`) draws every "arched" canal window as the rectangular window plus a full flat disc pasted above it (`batch.cylinder` turned to face out, around line 296). The wall behind is never cut, the disc is opaque trim colour, and its own smaller inner disc is "glass" without a recess. From any distance a bay reads as a plate on the wall; on a 12 m block that is 36 plates. The disc also hides the lintel box the plain window already drew, so the arched variant costs more geometry than a real arch would. The placed-window tool (`Openings.window_group`, `scripts/openings.gd:402`) always passes `arched = false`, and the four styled architectures ignore `windows = "arched"` entirely, so the inspector's Arched option only affects canal bay windows. Only path arches (`Openings.portal`, `scripts/openings.gd:332`) are real openings: a hole with a `radius`, a spandrel polygon above the springing line (`Openings.spandrel`, line 304), and a ring of ten straight beams. ### F2. The masonry coordinate breaks on every curved surface `masonry_face_coord` (`shaders/masonry_grid.gdshaderinc`) projects the world position onto the tangent of the fragment's own normal. That is exact for a flat wall and wrong for anything that turns: every facet of a cylinder, every 0.5 m segment of a freehand wall, every beam of an arch ring and every strip of a bridge soffit has a different tangent, so the bond restarts with a random phase at each edge. `Masonry.face_coord` mirrors the same rule for placed bricks. Seen in the captures: vertical seams on the 8 m towers where the bond jumps between the 16 shell facets (`tower-facets`), sheared and stepped courses along the curved wall (`curves`), stone blocks running straight through the arch soffit of the bridges (`bridge-close`), and the wall-path arch whose ring shows the flat wall's horizontal courses instead of radiating joints (`window-close`). ### F3. Big blocks have no scale hierarchy The canal facade is one rule at every size: bays of 1.35 m (`scripts/architecture.gd:452`, `scripts/cluster_architecture.gd:132`), one window per bay per floor, a 0.35 m bare-brick band either side of each window (`Masonry.BAND`, 55 % bare). With windows 1.1 m wide the pier between two windows is 0.25 to 0.4 m, so the bands overlap and the entire wall is bare brick; the "plaster" that the surrounds were meant to break up no longer exists on a block wider than about 4 m. Every floor is identical, the ground floor is the same as the third, the corners have no quoins or pilasters on canal buildings (`building_quoins` is only called for victorian and medieval, `scripts/architecture.gd:1474`, while cluster mode does draw canal quoins), and the flat roof is one blank pale slab with a thin railing. The styled architectures repeat the same way. Medieval draws an X-brace and a window in every bay on every floor (`styled_building`, around line 1443), so a 10 x 6 m block becomes wallpaper; japanese is the same grid in lighter timber; victorian is the best of the four because its cornice brackets and sash frames give it a crown, but it has no bay windows or paired sashes for a wide front; modern scales best because ribbon spandrels are what a modern block really has. ### F4. Round towers in the styled architectures are straight boxes on a curve `styled_building` draws a tower as a 16-sided shell (`scripts/architecture.gd:1378`) with eight flat facade panels (`sides = 8`, line 1367): cornice segments, string courses, window frames and pilasters are straight boxes tangent to the cylinder. At radius 1.5 m that is a little untidy; at radius 4 m the boxes float off the shell at their ends and sink into it in the middle, the victorian tower's white cornice becomes eight chords with gaps, and the modern tower's glass ribbons become an octagon inside a 16-gon. The canal tower uses a different shell (16 sides, line 425) from the support rings (`TOWER_SIDES = 24`, `scripts/scene_state.gd:21`), and all towers place exactly eight windows however long the circumference is: on the 8 m tower the windows are 2.5 m apart with blank wall between, on the 3 m tower they nearly touch. ### F5. Stone bridges do not show an arch The canal bridge (`scripts/architecture.gd:782`) and the stone `styled_bridge` (line 1575) both build the arch as a fill under the deck whose depth is `1 - |sin|^0.7`: a scallop, not a semicircle, with no ring on the face and no barrel underneath. Over the 3 m canal the arches are slivers; over 11.5 m the middle arch reads only from below and the end arches do not exist. The parapet, copings and lamp posts are fine and should stay. ## 3. Design rules this plan works to 1. Every masonry surface owns its coordinate. Where the generator knows the surface (a shell, a lofted wall, a ring, a barrel) it writes the metric coordinate itself; the world projection is only the fallback for flat boxes. 2. An arch is an opening. It has a springing line, a semicircular or segmental head cut into the wall, a reveal, a ring of voussoirs with a keystone, and the running bond stops at the ring. 3. Facades compose by size: base, body, crown. Bays get wider as the front gets longer, the solid-to-void ratio rises with size, the ground floor differs from the upper floors, corners and the centre bay are marked. 4. Curved elements are built from rings. Nothing on a tower is a straight box longer than one facet. 5. Nothing changes the save format. New behaviour keys off existing params (`windows`, `style`, `arches`, `w`, `d`, `height`); an optional new param is allowed only with a default that reproduces the old scene. ======================================================================== docs/visual-handoff.md | original lines 2844–2867 ======================================================================== **WP6 verification and budget (17 September 2026):** the closing check on the whole facade-scale plan (WP1 to WP5, including every review fix pass), done in one sitting on Opus 5 after a first Haiku runner's attempt was discarded. That attempt reported 2,310 checks, a total that does not match its own per-suite list (which sums to 2,410) and that list in turn left out the scene suite (456); it captured 11 of the 12 views with `overview` left empty, did no exports, and claimed a 25 % frame-time gain by comparing two runs 4.5 hours apart, against the runbook's same-session rule. Its entry was removed from this file (pre-removal copy `build/backup-wp6/visual-handoff.md`) and its output was renamed, not deleted, to `artifacts/visual-audit/wp6-haiku-partial/`, `wp6-haiku-dense/` and `wp6-haiku-dense.log`. No source code was changed in WP6. Tests: full `tools/test.sh` on the final scripts gives 2,866 checks, 0 failures (scene 456, building tools 549, cluster walls 211, lighting 149, masonry 499, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94), windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), no script errors, exit 0, `artifacts/wp6-full-test.log`. Captures: `artifacts/visual-audit/wp6/` holds all twelve audit views from the runbook's capture block, each with `courtyard.png`, `editor.png` and `performance.json` (no stalls). Budget: before and after were measured in the same sitting against a rebuilt pre-plan tree, never by swapping the live project. The tree was assembled in the session scratchpad from the earliest backup of every script and shader changed since the stage 0 baseline (`build/backup-wp1/` for `masonry.gdshader`, `plaster.gdshader` and `architecture`, `masonry`, `mesh_batch`, `weathering` and `world_view`; `build/backup-wp2/` for `openings` and `cluster_architecture`; `build/backup-wp3/` for `scene_state`, `supports` and `roof_profile`). A file-time sweep found no other script or shader edited after the baseline. The rebuild was proven to be the pre-plan code before any timing: its `window-close` and `towers-close` captures (`artifacts/visual-audit/wp6-preplan-proof/`) show the old disc arches and flat-panel towers, and their `detail.total` matches `baseline/` exactly (5,471 and 4,564). The dense fixture (`artifacts/weather-pass9/dense.json`, `--smoke --churn=100000`, 1920 x 1080, the runbook's measure command) then ran six times, alternating pre-plan and final (`artifacts/visual-audit/wp6-dense-preplan-1..3/` and `wp6-dense-final-1..3/`, logs beside them). Instances go from 24,394 to 26,928 (+2,534, +10.4 %), leaving 3,072 of headroom under `Masonry.BUDGET` 30,000. Mean frame time is 12.54 / 13.71 / 12.44 ms pre-plan against 12.49 / 12.40 / 12.52 ms final (medians 12.54 and 12.49), so the frame cost is within run-to-run noise and no speedup or slowdown is claimed. Draw calls (2,035), chunk draw calls (16) and emitter sources (2,110) are identical in all six runs. `Masonry.BUDGET` stays at 30,000: the final dense scene already uses 26,928, so lowering it would start dropping instances. Caveat: the dense fixture is 100 canal blocks with no towers, bridges or styled buildings, so it measures WP1, WP2 and the canal part of WP4 only. WP3, WP5 and the styled part of WP4 were costed by the scratch measurements in their own entries below. Exports: the Hologram UI exports from 16 September were copied to `build/pre-wp6-exports/` first. `tools/build.sh` rebuilt `build/macos/PixelPunk.app` (exit 0, `codesign --verify --deep --strict` passes, `artifacts/wp6-export-macos.out`, `artifacts/build/export-macos.log`), and `--export-release Windows` rebuilt `build/windows/PixelPunk.exe` (the command returned 0 in the session but no exit code was written to disk; the exe was rewritten at 08:54:18 with a new hash; `artifacts/wp6-export-windows.out` and `artifacts/build/export-windows.log` carry no timestamps and are byte-identical to the 16 September logs, so they cannot tell the two builds apart). `build/PixelPunk-Windows.zip` was repacked from scratch with the same four files under `PixelPunk/`: the new exe, README, notices and the `START HERE.txt` taken from the previous archive. The embedded exe's SHA-256 matches the exported exe (`ed03fe88...`; the old exe was `936620e5...`). Standalone: the exported Mac app ran two smokes. Both returned 0 in the session, but the exit codes were not written to disk; the evidence on disk is the complete reports. The canal audit view with `--verify-selection` matches the engine capture (`artifacts/visual-audit/wp6-standalone/canal/`). The exact standalone smoke that `docs/hologram-ui-handoff.md` left unresolved after an exit 139 also completes, with no capture failures, no selection mismatches or fallbacks and no errors in its log, and its `editor.png` shows the bundled icons and font above the tilt-shift (`artifacts/ui-hologram/standalone-wp6/`, `standalone-wp6.log`). Pre-existing, not a regression: `support_error` "Both ends need a solid landing." appears in 8 of 12 baseline views and in the same 8 now. Six are the `audit.json` views, which hold a bridge whose ends do not land, and two are the `curves.json` views, whose stone bridge (id 2) does the same. The four `towers.json` views, the dense fixture and the artwork scene report none. Review: none, per the stage table. Open items, none blocking. From the package entries below: the modern round tower now reads as a dark banded drum rather than glass (WP3); the audit scene's two small bridges (WP5) and the canal block's centre-bay door and balcony (WP4) are not visible in any audit capture. From the Opus review advisories of those stages, which were recorded in the stage workflow results but never copied into the entries: the japanese tower lost its timber lattice (WP3); segmental bridge rings get too many voussoirs because they are counted as half circles, consistent with `artifacts/review-gap.log` giving 11 stones at both rises (WP5); the gravel strip on lone canal terraces sits inside the deck slab by its own arithmetic (WP4). Platforms: Mac run; Windows export built but not run on Windows. **WP4 facade composition, styled part (17 September 2026):** the four styled architectures are now composed by size the way the canal front is, through one planner, `Architecture.styled_plan(style, length, rows, seed, arched, long_side)`, read by `Architecture.styled_building` and `ClusterArchitecture.facade` alike so a merged styled front and a lone one draw the same bays, storeys, openings and patterns (proven by the parity checks below). Only a building with a front over `NARROW_ENDS` (5 m) is composed at all (`Architecture.styled_composed(length, long_side)`, the review fix below): a small house, every front 5 m or under, plans its old equal bays with one centred light each and both paths draw it exactly as they did before this part. The planner is the shared `bay_plan` with its target floored at each style's old fixed cell (`Architecture.styled_bay_target`: 1.7 m for medieval, japanese and victorian, 2.3 m for modern), so every front of 5 m and under keeps exactly the bays it had and only the wide fronts change (a 10 m front goes from six 1.67 m cells to five bays with narrowed ends and a marked centre; the 8 x 8 modern block keeps three bays, now 2.46/3.08/2.46 instead of three equal 2.67 m). Medieval: each upper-floor panel takes its timber pattern from the seed (`Architecture.pattern_roll`, plain plaster 45 %, one tension brace beside the window 25 %, a brace either side 15 %, brick nogging filling the panel 15 %, drawn by `Architecture.medieval_panel` with rails at the sill and head and the posts once per bay edge; on a composed front `ClusterArchitecture.styled_window` draws a leaded mullion and transom instead of the X of beams that crossed every light, when its caller asks with `leaded`, which only `Architecture.styled_lights` does - every other medieval light, a small house's, a tower's, a placed window's or a portal's, keeps its X); a composed block of three or more floors stands on a stone ground storey (`Architecture.STONE`, masonry material, its quoins in the same stone through `Masonry.quoin_tone`, no loose-brick surrounds because with them the storey read as brick, not stone - `artifacts/visual-audit/wp4-scratch-styled/med-close/` before and after); a front over `NARROW_ENDS` (5 m) jetties each upper floor `JETTY` (0.25 m) further out, capped at `JETTY_MAX` (0.5 m) so it stays inside a pitched roof's 0.74 m bounds margin, each jettied storey its own wall piece lengthened by its jetty at the corners so two jettied walls close over the corner, with a bressummer and brackets under it (`Architecture.jetty_beam`), placed windows, neon strips and swags moved out onto the jettied face, the cornice reaching out over the top jetty, no surround bricks on the timber storeys, and the corner quoins stopping at the first floor (`Masonry.quoin_top`, applied by `building_quoins` and `cluster_quoins` alike). Japanese: a deep tiled eaves band with a fascia at every upper floor line (`Architecture.japanese_eaves`, from the same cut pieces as the floor course), and on fronts over 5 m the windows pulled together in pairs with `PAIR_GAP` (0.24 m, one post) between the two lights of a pair and plain wall between pairs (`Architecture.pair_direction`, counted outwards from the centre and mirrored, the centre bay of an odd count single). Victorian: a body bay of `PAIR_BAY` (2.1 m) or more carries paired sashes with a `SASH_MULLION` between (each light arched on an arched ground floor), the pediment once over the pair, and the centre bay of a front over `WIDE_FRONT` carries a projecting bay window on every floor but the top (`Architecture.victorian_oriel`: cheeks with a narrow light each, apron, sash and head panel standing `ORIEL_DEPTH` (0.40 m, the balcony's margin) proud, a lead roof on the top storey of the stack, brackets under a storey whose floor below carries none), on the lone building's side 0 and on a cluster panel that is the whole of its owner's front. Modern: the planner and nothing else. Files: `scripts/architecture.gd`, `scripts/cluster_architecture.gd`, `scripts/masonry.gd`, `tests/test_building_tools.gd`, `tests/test_cluster_walls.gd`, `docs/visual-handoff.md`. Backups: `build/backup-wp4-styled/` (the state after the canal part; `build/backup-wp4/` still holds the pre-WP4 state). Test-first failures: `artifacts/wp4s-building-tools-testfirst.log` (parse error, "Static function styled_plan() not found in base Architecture") and `artifacts/wp4s-cluster-walls-testfirst.log` (five parity failures: no jetty, no stone storey, no nogging, no cluster oriel, no eaves), both the right reason. Tests: building tools 542 (was 494: `styled_plan_checks`, the styled targets, the 4 m houses of all four styles keeping two 2 m bays and one light per bay, the 10 m medieval front's five bays, 0.25/0.5 m jetty, the cap, the stone storey on three floors and not two, no jetty at 5 m, pattern shares within 6 points of 45/25/15/15 over 120 seeds and deterministic, japanese pairs mirrored with the gap exact and singles at 5 m, victorian pairs in the body bays only, the oriel on every floor but the top and not on a 6 m front, arched pairs, the modern block, then the built geometry: the jettied storeys 0.25 and 0.5 m proud, the stone storey with no plaster on it, quoins stopping under the jetty, both the jettied block and the oriel inside the selection bounds, the eaves band), cluster walls 208 (was 203: `styled_front_parity_checks`, the jettied first floor, the stone storey and the same count of nogging vertices from the lone 10 x 6 medieval block and from its cluster with an annex, the oriel from both victorian paths, the eaves from both japanese paths), masonry 499, scene 456, lighting 149 (unchanged). Suite logs: `artifacts/wp4s-building-tools.log`, `artifacts/wp4s-cluster-walls.log`, `artifacts/wp4s-masonry.log`, `artifacts/wp4s-scene.log`, `artifacts/wp4s-lighting.log`. Full `tools/test.sh`: 2,856 checks, 0 failures (scene 456, building tools 542, cluster walls 208, lighting 149, masonry 499, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) with the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp4s-full-test.log`, exit 0, run on the final scripts. The `--verify-selection` smoke on `audit.json` at night: `verify_selection` true, 0 mismatches, 0 fallbacks, 309 emitter sources, 317 before this part (`artifacts/visual-audit/wp4s-verify-selection/performance.json`, log `artifacts/wp4s-verify-selection.log`). Captures: `artifacts/visual-audit/wp4/` (all twelve re-captured with the final scripts; the canal part's captures are preserved as `artifacts/visual-audit/wp4-canal/`; changed: `styled` and `overview` - the 10 x 6 medieval block is a grey stone ground storey under two jettied timber storeys with braces, nogging and plain panels varying bay by bay and no X over any light, the 8 x 6 japanese block carries an eaves band at each floor with its windows in pairs, the 10 x 8 victorian block's paired sashes and its bay window on the front facing the medieval block, the modern block's centre bay wider than its ends; `canal`, `canal-night` and `bridges` - the medieval block at their right edge; `cluster`, `towers` and `towers-close` - the towers scene's 10 x 6 medieval block and 6 x 8 victorian house the same way; unchanged: `window-close`, `tower-facets`, `curves`, `bridge-close`). Close-ups used for judging are in `artifacts/visual-audit/wp4-scratch-styled/` (`med-close`, `med-night`, `vic-close` from above, `jap-close`, `mod-close`). Budget: the dense fixture has no styled building (100 canal blocks), so its numbers cannot show this part: instances 26,928 before and after, mean frame 19.15 ms before to 19.07 ms after, p95 20.29 to 20.83, emitters 2,110 both, same session, baseline with the `build/backup-wp4-styled/` scripts swapped in and the WP4 scripts restored byte-identical (`artifacts/visual-audit/wp4s-dense-baseline/`, `wp4s-dense/`, logs beside them). Measured instead on the six styled blocks of the two audit scenes built alone (`artifacts/wp4s-styled-measure.gd`, `artifacts/wp4s-styled-measure-before.log` and `-after.log`, the before run on the backup scripts, restored byte-identical): 137,271 to 121,359 vertices, 1,955 to 1,051 brick instances, 237 to 223 emitters - the wide fronts have fewer bays, the X beams are gone and the jettied and stone storeys carry no surround bricks; the modern block is unchanged at 10,044 vertices. Review (Opus 5, different session): one must-fix finding - the entry claimed the small houses kept their look while the diff changed every styled front regardless of size (`medieval_panel` on every medieval bay, the X gone from every medieval light, the victorian pediment new on the cluster path, so the harbour sample's 4 x 4 victorian pair and 6 x 4 medieval hall changed). Fixed (17 September 2026, Fable 5.1): `Architecture.styled_composed(length, long_side)` gates the whole part on the building's longest front being over `NARROW_ENDS`; `styled_plan` takes the building's long side and returns `composed`, and when false plans no jetty, no stone storey, no pattern, no pair, no oriel; `Architecture.styled_bay_legacy` is the pre-WP4 bay drawing verbatim (frame, glass, each style's dressing, posts and the two braces per bay) which `styled_building` uses for a small house, with the old fixed surround band and bare share; `ClusterArchitecture.facade` on a small house keeps its old window sizes (0.68 of the bay, 1.52 m tall), its pilaster pair per bay, no panels, no eaves, and the lights through `styled_window` unleaded; `styled_window`'s new `leaded` parameter defaults to the old X, so towers, placed windows and portals on medieval buildings, which the styled part had also changed through it, draw as before; `Masonry.quoin_top` stops the quoins at the first floor only on a composed building. Proof: `artifacts/wp4fix-small-measure.gd` builds every harbour cluster, every styled harbour building alone and a lone 4 x 4 house of each style at two and three floors, and prints vertex, brick and emitter counts with an MD5 of every group's vertices and colours; run on the `build/backup-wp4-styled/` scripts (`artifacts/wp4fix-small-measure-before.log`) and on the fixed ones (`-after.log`, scripts restored byte-identical after the swap), 24 of the 26 buildings hash identically - the 4 x 4 victorian pair (as a cluster and alone), the 5 x 4 tea house, the 3 x 3 gatehouse, both 3 x 3 medieval towers and all eight 4 x 4 houses - and only the 6 x 4 medieval hall differs (alone 15,390 to 14,706 vertices, 254 to 163 bricks, 21 to 18 emitters; with the keep 34,149 to 36,441, 240 to 156, 25 to 22), which the plan composes by its own jetty rule: three bays on its 6 m fronts instead of four, the first floor jettied, leaded lights and seeded panels on every front. Files: `scripts/architecture.gd`, `scripts/cluster_architecture.gd`, `scripts/masonry.gd`, `tests/test_building_tools.gd`, `tests/test_cluster_walls.gd`, `docs/visual-handoff.md`; backups of the pre-fix state in `build/backup-wp4-fix/`. Test-first: `artifacts/wp4fix-building-tools-testfirst.log` (parse error, "Static function styled_composed() not found in base Architecture") and `artifacts/wp4fix-cluster-walls-testfirst.log` (two failures: the merged 4 x 4 victorian pair drew a pediment, 123 trim vertices where none belong, and the merged 4 x 4 medieval pair no X), both the right reason. Tests: building tools 549 (was 542: a three-storey 4 x 4 medieval house not composed and without the stone storey, no pattern on its bays, the 4 m front of a 4 x 8 block composed with the stone storey, `styled_composed` at 5, 5 with a 6 m side and 6, the lone 4 x 4 medieval house keeping the X's end vertices at the light's corner and no sill rail at its bay edge while the composed 10 m front has the rail; the "5 m front takes the stone storey" check now gives its front a 6 m long side), cluster walls 211 (was 208: the pediment ridge over the body bays from both the lone and the merged 10 x 8 victorian block, none over a merged 4 x 4 victorian pair, the X's end on a merged 4 x 4 medieval pair), masonry 499, scene 456, lighting 149; logs `artifacts/wp4fix-building-tools.log`, `-cluster-walls.log`, `-masonry.log`, `-scene.log`, `-lighting.log`. Full `tools/test.sh`: 2,866 checks, 0 failures (scene 456, building tools 549, cluster walls 211, lighting 149, masonry 499, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94), `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp4fix-full-test.log`, exit 0, on the final scripts. Because the harbour before-and-after captures swapped the backups in and out after that run, the orchestrating session re-ran the full suite on the restored scripts afterwards: 2,866 checks, 0 failures, `--verify` clean, exit 0, `artifacts/wp4-final-full-test.log`. Captures: `artifacts/visual-audit/wp4-fix/` - `styled`, `cluster`, `towers`, `towers-close` re-captured on the fixed scripts and the same as `wp4/` (the audit scenes have no small styled house; the towers scene's 8 x 8 medieval tower has its window X back, too small to see at these sizes); the harbour sample exported to `artifacts/visual-audit/harbour.json` by the measure script and captured as `harbour` (overview), `harbour-small` and `harbour-small-north` (the victorian pair, the hall, the keep and the gatehouse from two sides) on the fixed scripts, with `-before` twins on the `backup-wp4-styled` scripts and `-prefix` twins on the pre-fix `backup-wp4-fix` scripts (restored byte-identical after each swap): the fixed views match the before views on the pair, the gatehouse and the towers where the prefix views show leaded lights and pediments, and the hall shows the composition in the fixed and prefix views alone; `harbour-close` and its twins frame the canal cluster, identical in all three. Not done: the plan's bay targets are applied with a floor at each style's old cell rather than literally (a literal 1.4 m target would have re-bayed every 4 m styled house from two bays to three, which the harbour sample and the audit scenes did not ask for); the whole part - patterns, stone storey, jetty, pairs, eaves, paired sashes, pediment parity, the surround budget - starts only on a building with a front over 5 m, where the plan gates only the jetty that way; a small house of three floors keeps its timber ground storey, a small japanese house its plain floor lines, a small victorian house on the merged path its sashes without the pediment its lone twin always had - chosen so the plan's regression guard (the harbour sample unchanged apart from quoins) holds for every small house; a 4 m front of a composed building takes the leaded lights, patterns and stone storey of the rest of that building, and a 6 x 4 house like the harbour hall is composed, so the harbour is not unchanged either; the jetty is capped at 0.5 m in total where the plan says 0.25 m per upper floor without a cap, so a four- or five-storey block jetties its third floor and above no further; the fence's door bay on styled fronts still reads the old fixed 1.35 m rule (`Architecture.fittings`); the oriel's front light is a single sash, not a pair; a flat-roofed medieval block's jetty and cornice stand up to 0.71 m outside its footprint, the way the canal balcony and cornice already do. Platforms: Mac run; Windows not run. **WP4 facade composition, canal part (17 September 2026):** a canal front is now composed by size instead of repeating one 1.35 m cell: `Architecture.bay_plan(length)` is the one bay planner (target 1.4 m up to 5 m fronts, 2.0 m up to 9 m, 2.4 m above; the two end bays of a front over 5 m narrow to 0.8 of a body bay so the corner reads; a front over 6 m has an odd count and its middle bay is marked as the centre), `Architecture.canal_opening(f, rows, bay, length, arched)` is the one storey rule (the ground floor of a front over 6 m is an arcade of 2.2 x 1.4 m arches when the building asks for arched windows and a row of flat-headed 2.0 m shopfronts otherwise, on a rusticated base band that stands 2 cm proud in a darker stone with a channel every other course on the masonry contract's own course grid; upper floors keep their 1.52 m windows; on a block of three or more storeys the top floor's windows are 15 % shorter and, where that floor is the last row, sit under a solid 0.5 m attic band with a slim course at its foot), and both `Architecture.canal_building` and `ClusterArchitecture.facade` read them, so a merged 12 m front and a lone one draw the same bays, the same heads and the same centre bay (proven by the parity check below); `Architecture.fittings`' fence reads the planner for its door bay on canal fronts too. The centre bay of a front over 6 m carries the door (`Architecture.doorway`: a timber leaf in the lower part of the arcade opening with the crown left as a fanlight, or at one side of the shopfront, and a step) and a balcony on the first floor (`Architecture.balcony`: a slab on two brackets under the sill, railed on three sides, 0.40 m deep so it stays inside the selection box's own margin), on the lone building's side 0 and on a cluster panel that is the whole of its owner's side 0. The surround budget: `Masonry.surround_band(pier)` is a third of the narrowest pier between two openings, capped at `BAND` and floored at a header (a band narrower than a brick end is nothing but cut fragments, so this is the one place the plan's `min(BAND, pier / 3)` is softened; on the 4 m house, whose piers are 0.29 to 0.37 m, that floor is what applies); `Masonry.surround_bare(rects, band, ...)` scales the bare share down with how much of the wall the bands cover so band coverage times bare share stays about `BARE_WALL` (0.33) and never drops under `MIN_BARE` (0.15); `Masonry.surrounds` takes both as optional trailing parameters defaulting to the old `BAND`/`BARE`. A rusticated arcade carries no loose bricks of its own. Quoins on lone canal buildings were already in (`Masonry.building_quoins` at the end of `canal_building`, checked by `tests/test_cluster_walls.gd`'s "A canal house has quoins on its corners"); nothing changed there. The terrace: the deck is `Architecture.TERRACE` (777b80) in the matte masonry material instead of the pale trim slab (a first try in the `plain` material came out brighter than the slab it replaced, 0.64/0.67/0.71 against 0.60/0.64/0.62 at the same pixels, because `plain` at roughness 0.55 catches the sky on a horizontal face; the numbers are from `artifacts/visual-audit/wp4-scratch/`, sampled headlessly); a parapet in the wall stone with a lighter coping rises 0.64 m over the wall, clear of the 0.325 m cornice, with the railing on the coping; a terrace over `TERRACE_LARGE` (40 m2) gets `Architecture.terrace_head` (a stone hut with a lid and a door at the back-left corner, where that corner stands on exposed roof) and a 0.6 m gravel margin inside the parapet; the cluster path (`ClusterArchitecture.terraces`, the caps) draws the same deck tone, parapet, gravel and stair-head from the member's own exposed cap area. Files: `scripts/architecture.gd`, `scripts/cluster_architecture.gd`, `scripts/masonry.gd`, `tests/test_building_tools.gd`, `tests/test_masonry.gd`, `tests/test_cluster_walls.gd`, `tests/test_scene.gd`, `docs/visual-handoff.md`. Backups: `build/backup-wp4/` (all of the above, the pre-WP4 state). The test-first failures are `artifacts/wp4-building-tools-testfirst.log` and `artifacts/wp4-cluster-walls-testfirst.log` ("Static function bay_plan() not found in base Architecture") and `artifacts/wp4-masonry-testfirst.log` ("surround_band()"/"surround_area() not found in base Masonry", "Too many arguments for surrounds()"), all three the right reason since the APIs did not exist; the brick density the masonry check bounds was measured before and after with `artifacts/wp4-density-measure.gd` (`artifacts/wp4-density-before.log`: the 12 x 10 four-storey arched block at 2.94 bricks per m2 of wall, 174,096 vertices, 103 emitters; `artifacts/wp4-density-after.log`: 1.96 bricks per m2, 133,404 vertices, 62 emitters; the 4 m house 311 to 304 bricks). Tests: building tools 494 (was 417: `bay_planner_checks`, the planner's ranges at fifteen lengths from 2 to 12 m, the 4 m house keeping its three 1.33 m bays, the 12 m front at five bays where the old rule gave nine, the storey rule's numbers, one keystone per planned bay per floor on all four sides of the 12 x 10 block, the balcony slab, the parapet in the wall stone, a stair-head on the 120 m2 terrace and none on the 16 m2 one, no pale trim left on the deck), masonry 499 (was 484: `surround_budget_checks`, band and bare helpers, every brick within a 0.2 m band, the 12 x 10 block bounded at 2 bricks per m2), cluster walls 203 (was 199: `wide_front_parity_checks`, the same arches and balcony from the cluster facade as from the lone building, the cluster parapet), lighting 149 and scene 456 (unchanged counts; one scene check, "Partial-width joins preserve exposed wall corners", hard-coded the old rule's bay edge at x = -1.5 on a 6 m front and now derives that edge from `bay_plan(6.0)`, keeping its intent that a half-covered bay is still drawn). Suite logs: `artifacts/wp4-building-tools.log`, `artifacts/wp4-masonry.log`, `artifacts/wp4-cluster-walls.log`, `artifacts/wp4-lighting.log`, `artifacts/wp4-scene.log`. Full `tools/test.sh`: 2,803 checks, 0 failures (scene 456, building tools 494, cluster walls 203, lighting 149, masonry 499, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) with the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp4-full-test.log`, exit 0, run on the same on-disk scripts this entry describes, after the last edit. The `--verify-selection` smoke on `audit.json` at night: `verify_selection` true, 0 mismatches, 0 fallbacks, 317 emitter sources (`artifacts/visual-audit/wp4-verify-selection/performance.json`, log `artifacts/wp4-verify-selection.log`). Captures: `artifacts/visual-audit/wp4/` (all twelve re-captured with the final scripts; changed: `canal`, `canal-night`, `window-close` and `overview` - the 12 x 10 block now reads as base, body and crown: five bays a side instead of nine, an arcade of 2.2 m arches on a darker rusticated base, plaster between the upper windows with brick surrounds instead of a wall that was all bare brick, shorter top-floor windows under the attic band, a stone parapet and coping over the cornice with the railing on it, a dark matte deck with a gravel margin and a stair-head hut at the back corner; `cluster`, `towers`, `towers-close` and `tower-facets` - the merged canal block's 6 m front has three bays with narrowed ends and its wing carries the stone parapet and dark deck; `bridges` and `styled` - the 4 m house and the block edge carry the parapet; unchanged: `curves`, `bridge-close`). The audit block's centre bay is where the road passes through it, so its door and balcony are not in these captures; the test block without a road shows both. Budget: dense fixture instances 27,827 before to 26,928 after (`Masonry.BUDGET` 30,000), mean frame 19.19 ms before to 19.32 ms after, p95 20.83 to 19.81, emitters 2,110 both, same session, the baseline run with the `build/backup-wp4/` scripts swapped in and the WP4 scripts restored byte-identical afterwards (`artifacts/visual-audit/wp4-dense-baseline/`, `wp4-dense/`, logs beside them). Review: not run in this session; the workflow's reviewer step follows this entry. Not done: the four styled architectures (medieval panel patterns, japanese eaves, victorian bay window, modern) are the plan's second part and were out of this run's scope; the plan's "4 m house unchanged apart from quoins" holds for its bays, windows and heads but not literally - its surround band is 0.28 m instead of 0.35 m by the budget rule (311 to 304 bricks) and its terrace has the parapet and dark deck like every canal terrace; the harbour sample's two 6 m canal fronts (`main`, `market`) go from four bays to three by the plan's own 2.0 m target above 5 m, so the harbour is not unchanged either; the plan's 0.5 m attic band and 15 % shorter top windows apply only to blocks of three or more storeys, and the arcade sill is 0.23 m rather than a round number because the merged panel's own margins (a window must clear 0.22 m at the sill and 0.15 m at the head) leave a 2.2 m arch exactly that much room. Platforms: Mac run; Windows not run. **WP5 review fix pass (17 September 2026):** a review of all of WP5 returned two must-fix findings, both fixed here. (1) `MeshBatch.wedge`'s two slanted faces built their normal only from `(t0-a0).cross(a1-a0)` (and the mirror for the other face): a normal to the face, but its sign follows the plan triangle's own winding (`base_a`, `base_b`, `tip`, either way round), not which way is actually outward. `append_quad` re-winds a quad's triangles to match whatever normal it is handed without complaint, so on the `sign=-1` cutwater of every bridge pier (`Architecture.stone_bridge_arches` builds the two cutwaters with `base_a`/`base_b` swapped between `sign=-1` and `sign=1`, so one winds the plan triangle CCW and the other CW) both slanted faces got an inward-pointing stored normal and were silently back-face culled - the docstring's claim that "it does not matter which way round base_a and base_b are given" was false. `tests/test_masonry.gd`'s existing `front_facing()` cannot catch this because it compares a triangle's winding to its own *stored* normal, which is self-consistent whichever way the normal points. The fix resolves each slanted face's outward normal by checking which side of it the plan triangle's own third vertex falls on and flipping if it is the near side (`scripts/mesh_batch.gd:404`), so the result no longer depends on which way the winding runs. (2) The spandrel wall's top sat flat at `g.deck_bottom`, the deck underside at the arch's own mid-bay point, while the real deck curves with `BRIDGE_RISE` across the whole bridge, so every bay but the one straddling the bridge's own crown left a gap between the top of the spandrel and the true deck above it (measured by the reviewer at up to 0.196 m on `curves.json` and 0.192 m on `audit.json`'s bridges) - a dashed dark seam visible under the parapet in `bridge-close` and `curves`. The fix (`scripts/architecture.gd:958`, `Openings.segmental_spandrel`) samples the real deck height (the same `a.lerp(b,t).y + sin(t*PI)*BRIDGE_RISE - deck_thickness` formula used everywhere else the deck curve is read) at nine points across each bay and gives `segmental_spandrel` a new optional `top` polyline that replaces its old flat two-point top edge with that curve; left empty (every other caller), `segmental_spandrel` draws exactly the flat-topped rectangle-minus-arc it always did. Files: `scripts/mesh_batch.gd`, `scripts/architecture.gd`, `scripts/openings.gd`, `tests/test_masonry.gd`. Backups: `build/backup-wp5/` (all four of the above, the pre-fix-pass state; `mesh_batch.gd` and `architecture.gd` were backed up before their first edit, `openings.gd` and `test_masonry.gd` were backed up immediately after by reverting a copy of the edited file with the same diff the edit made, confirmed byte-for-byte against the original by re-diffing forward). The test-first failures are `artifacts/wp5-prefix-check.log` (both new checks run against the pre-fix `scripts/mesh_batch.gd`, `architecture.gd`, `openings.gd` from `build/backup-wp5/`, with the new `tests/test_masonry.gd`): "A wedge with its plan triangle wound CW draws both slanted faces outward, not toward its own third vertex (4 wrong)" and "Every spandrel top-edge vertex sits on the real deck curve at its own x, not the bay's mid-point value (48 of 76 off, worst 0.3694 m)" - both fail for exactly the reasons above, then the production files were restored to the fixed versions (confirmed byte-identical to the versions this entry describes by `diff`) before re-running. New tests: `wedge_checks` builds a wedge with its plan triangle both ways round and checks every triangle's stored normal against the true outward direction (away from the plan triangle's own third vertex, not against the triangle's own winding, which is what let this bug through `front_facing()` before); `bridge_spandrel_curve_checks` builds the same 8 m, 2-arch bridge `bridge_arch_checks` uses, finds every "stone" vertex on the spandrel's own face plane (`z = +/- width/2`) above the arch's own crown height (so the underside arc is excluded), and checks each one against the real deck curve at its own x rather than at the bay's mid-point value. Tests: masonry 489 (was 484: the two checks above), scene 456, building tools 417, cluster walls 199, lighting 149, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94, all unchanged counts, all passing, run for regression since `openings.gd` and `architecture.gd` are shared broadly. Logs: `artifacts/wp5-fix-masonry.log` (fixed code, 489/0), `artifacts/wp5-prefix-check.log` (pre-fix code against the new tests, 2 failures, above), `artifacts/wp5-fix-masonry2.log` (fixed code re-confirmed after restoring from the pre-fix swap, 489/0), `artifacts/wp5fix-test_scene.log`, `wp5fix-test_building_tools.log`, `wp5fix-test_cluster_walls.log`, `wp5fix-test_lighting.log`, `wp5fix-test_weathering.log`, `wp5fix-test_water.log`, `wp5fix-test_time.log`, `wp5fix-test_foliage.log`, `wp5fix-test_wet.log`, `wp5fix-test_sun.log`, `wp5fix-test_tilt.log`, `wp5fix-test_ui.log` (all under `artifacts/`). Sum of those per-suite runs: 2,712 checks, 0 failures. A single full `tools/test.sh` run made afterwards by the orchestrating session agrees: 2,712 checks, 0 failures, windowed `--verify` clean, exit 0, `artifacts/wp5-fix-full-test.log`. Windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp5-fix-verify.log`, exit 0. Captures: `artifacts/visual-audit/wp5/` re-captured, all twelve views (the capture block was run in full rather than only the views the findings name, since both fixes touch every stone bridge in the audit scenes). `bridge-close` and `curves` (the findings' own evidence views, `curves.json`'s 11.5 m three-arch bridge) now show a continuous parapet/spandrel line down to the deck with no dashed seam, and the visible piers show solid cutwater faces on both sides rather than a see-through one; `bridges`, `canal`, `canal-night`, `overview` and `styled` (the views the original implementer's handoff claimed "no artefacts" for without evidence) were looked at directly in this pass and show no seam or missing-face artefact either, though `bridges`' own steep top-down camera does not resolve a cutwater face at that angle and distance, the same camera limitation the original WP5 entry recorded for the ring; `window-close`, `towers`, `towers-close`, `tower-facets`, `cluster` are unaffected, as before, none holding a bridge. Measurements: neither fix adds or removes brick instances (`bridge_arch_checks`' instance-count assertions, unchanged from WP5, still pass); the spandrel polygon gains a handful of extra vertices per bay from the nine-point curve replacing two flat points, well under any budget concern, so no dense-fixture re-run was made for this fix pass. Review: not run in this session - the findings above are this session's own fix of a prior review's must-fix list, not a new review of the fix; a follow-up session with review tooling available should look at this diff before WP4 is taken as building on a doubly-reviewed WP5. Not done: nothing from the original WP5 plan section is newly undone by this pass; the original entry's own "Not done" (the `audit.json` bridges' ring only proven by instance count, not by eye, at that camera's angle) is unchanged and still applies. Platforms: Mac run; Windows not run. **WP5 stone bridges with real arches (17 September 2026):** a stone bridge's understructure is now a real arcade - abutments, piers with a cutwater, a segmental voussoir ring on each face, a barrel soffit and a flat spandrel wall - in place of the scalloped fill that used to read as slivers over a narrow canal and never showed a ring at all; the deck itself (`DioramaState.bridge_point`, `BRIDGE_RISE`) is untouched, exactly as the plan asked. `DioramaState.bridge_arch_count(o, length)` is the one place the drawn arch count is decided: the saved `params.arches` (1 to 3) clamped down to a single arch under a 2.5 m span, and further down if the piers between the requested count would leave no arch a reasonable width (`BRIDGE_PIER_WIDTH` 0.5 m, `BRIDGE_MIN_ARCH_SPAN` 0.9 m) - the saved param itself is never touched, only what gets drawn. `Architecture.bridge_arch_geometry(o, a, b, deck_thickness, index)` works out one arch's plan and section with no drawing at all - its span, its rise (the smaller of a true semicircle and whatever headroom sits between the water and the deck above its own middle, less a fixed clearance, so the crown never breaks through a low deck), and the defining circle that comes from those two (`Masonry.segmental_geometry`) - so the builder and a test read exactly the same numbers. `Architecture.stone_bridge_arches(batch, o, a, b, width, deck_thickness, rng)` is the shared builder: abutments where the arcade meets the bank, piers with a `MeshBatch.wedge` cutwater pointing across the flow between arches, `Masonry.arch_ring` on both faces of every arch, `Openings.segmental_spandrel` (the segmental twin of `Openings.spandrel`, rectangle-minus-arc for a flatter arch than a semicircle) filling the corners above the springing in flat `"stone"`, `MeshBatch.barrel` carrying the courses round the soffit in `"stone_uv"`, and a continuous string-course loft under the parapet on each side. Both call sites - the plain two-metre bridge in `Architecture.connection` and the wide stone case in `styled_bridge` - call this one builder, so a width 3 bridge's arches match a width 2 one over the same span exactly (proven in the test below), which is what "wide bridges reuse the same builder" asked for; timber, japanese, modern and rope bridges are untouched, as the plan says they should be. `Masonry.arch_ring` gained an optional `rise` parameter (default -1, meaning "a true semicircle, rise == radius", which is every shape it drew before this package) so WP5 could reuse it for a genuinely flatter arch rather than inventing a second ring builder: the maths collapses to exactly the old formula at every step when `rise` is left at its default, checked by hand and confirmed by the untouched `arch_ring_checks` in `tests/test_masonry.gd` still passing at tolerances as tight as 1e-5. `Masonry.segmental_geometry(half_span, rise)` is the shared piece of maths (a defining circle's radius and half-angle) that `arch_ring`, `bridge_arch_geometry` and the soffit all read from the same source. `MeshBatch.wedge` is a new small generic builder (a vertical triangular prism, base and tip in plan, extruded through a height range) for the cutwater, general enough to reuse elsewhere a pointed prow is wanted. `DioramaState.bounds()` widens a stone bridge's own `below` margin to reach the water line, since its piers and arches now stand down there instead of stopping 0.3 m under the deck. Files: `scripts/architecture.gd`, `scripts/scene_state.gd`, `scripts/masonry.gd`, `scripts/mesh_batch.gd`, `scripts/openings.gd`, `tests/test_masonry.gd`. Backups: `build/backup-wp5/` (all of the above plus `test_building_tools.gd`, `test_scene.gd`, `test_cluster_walls.gd` and this file, the pre-WP5 state). The test-first failure is `artifacts/wp5-masonry-testfirst.log` (`tests/test_masonry.gd`'s new `bridge_arch_checks`, parsed against the unmodified backups: "Static function \"bridge_arch_geometry()\" not found in base \"Architecture\"", the right reason, since the new API did not exist yet - the same style of failure WP3's test-first step accepted for the same reason). Tests: masonry 484 (was 470: the new `bridge_arch_checks` - a stone bridge keeps its deck on the landings at both widths tested, an 8 m span with `arches: 2` draws the two arches asked for, a width 3 bridge's voussoir count over the same span matches a width 2 one exactly, every bridge triangle in `stone`/`stone_uv` winds for its normal, a 2 m span with `arches: 3` saved draws exactly one arch's rings while the saved param stays 3), building tools 417 (unchanged count; one pre-existing check's tolerance needed a real fix here, not a rewrite - see below), cluster walls 199 (unchanged, run for regression), scene 456 (unchanged, run for regression). One implementation bug was caught by the existing suite, not the new test: the first cutwater length (0.35 m) pushed a pier's wedge tip past `DioramaState.bounds()`'s own margin for a bridge (`width / 2 + 0.25`), so `tests/test_building_tools.gd`'s "stone bridge width 1/4 selection bounds follow the deck" check failed with the rendered extent 0.10 m wider than the selection box on the across axis, exactly the amount `BRIDGE_CUTWATER` (0.35) exceeded the 0.25 m margin by; the fix narrows `BRIDGE_CUTWATER` to 0.22 m, which still reads as a pointed prow at this scale and now sits inside the existing margin, with a comment on the constant explaining why. Suite logs: `artifacts/wp5-masonry.log`, `artifacts/wp5-building-tools.log`, `artifacts/wp5-cluster-walls.log`, `artifacts/wp5-scene.log`. Full `tools/test.sh`: 2,707 checks, 0 failures (scene 456, building tools 417, cluster walls 199, lighting 149, masonry 484, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) with the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), first run `artifacts/wp5-full-test.log`, re-run after a same-session round trip through the backups for the measurements below `artifacts/wp5-full-test-final.log`, both exit 0, both from files confirmed byte-identical to the on-disk state this entry describes. Captures: `artifacts/visual-audit/wp5/` (all twelve views re-captured; changed: `bridges` and `bridge-close` carry the new arcade - `bridge-close` (the 11.5 m three-arch bridge in `curves.json`, side-on) clearly shows a real semicircular opening with a visible ring where the old capture showed a scallop, and the wider `curves` view shows the same bridge's arches as real openings from a shallower angle; `bridges` (the two 3.8 m bridges in `audit.json`, a steep top-down camera) shows the deck and parapet correctly but the camera's own pitch does not resolve the ring at that angle and distance - this is the audit set's existing camera choice for that view, not a code gap, and the ring's existence there is proven by the instance count below rather than by eye; `canal`, `canal-night`, `overview` and `styled` each hold a corner of one of the small bridges and are checked for absence of artefacts (none found) rather than for a visible change at that distance; unchanged: `window-close`, `towers`, `towers-close`, `tower-facets`, `cluster`, none of which hold a bridge. Measurements: the dense fixture (`artifacts/weather-pass9/dense.json`) holds zero bridge objects (`jq '[.objects[]|select(.kind=="bridge")]|length'` → 0), so its `performance.json` is unchanged by this package (`detail.total` 27,827, mean frame 17.73 ms, `artifacts/visual-audit/wp5-dense/performance.json`) and is not evidence about WP5, the same gap WP3 found for its own dense-fixture measurement. The world's `detail` telemetry field does not count a bridge's brick instances at all - confirmed by reverting to `build/backup-wp5/` and re-capturing `bridges`, which reported the identical `detail.total` (5,948) with or without this package's rings, and by `bridge-close` reporting `detail.chunks: 0` in both states - so the real instance measurement is a same-session scratch script, not the audit captures' telemetry: `artifacts/wp5-scratch/measure.gd` builds `audit.json`'s two saved bridges (id 9, stone, width 2, `arches: 3`, 3.8 m span; id 10, stone, width 3, `arches: 2`, 3.8 m span) through `Architecture.connection` and reports `instance_count("brick")` and `vertex_count()`; `before.log` (against `build/backup-wp5/`) reads 0 bricks and 3,624/4,716 vertices for the two bridges; `after.log` (against the code this entry describes, confirmed byte-identical by `diff -q`) reads 30 and 20 bricks (50 total, matching `2 * arches * Masonry.ring_count(half_span)` by hand for both) and 4,674/5,088 vertices, +1,422 vertices total for the pair. Nothing here approaches `Masonry.BUDGET` (30,000) by three orders of magnitude. Frame time on the `bridges` and `bridge-close` audit views moved in opposite directions across the same before/after pair (5.72 to 4.68 ms, and 3.13 to 4.83 ms) - both scenes render in single-digit milliseconds, where session noise dominates any real signal, so no frame-time claim is made from them. Review: not run in this session - no subagent or model-switch tool was available to this implementer to hand the diff to Opus 5 as `docs/facade-scale-agents.md`'s table asks for stage 4. A follow-up session with that tooling should review this package (the diff, this entry, `docs/facade-scale-plan.md`'s WP5 section, and the `bridges`/`bridge-close` before/after PNGs) before WP4 is taken as building on a reviewed WP5. Not done: the acceptance line's "the ring is visible from the side at every span in the audit scenes" is confirmed by eye only for the `curves.json` bridge (`bridge-close`, `curves`, both side-on); the two `audit.json` bridges are proven to carry the same ring by the instance count above, not by eye, because the audit set's own `bridges` camera is a steep top-down angle that does not resolve an opening at that pitch and distance - re-aiming that camera was not done, since the plan names the existing audit scenes and cameras and does not ask for a new one. The pier and abutment boxes, the cutwater wedges and the string course are this implementer's own proportions (`BRIDGE_PIER_WIDTH`, `BRIDGE_CUTWATER`, `BRIDGE_ABUTMENT`, `BRIDGE_CLEARANCE`, `BRIDGE_MIN_RISE`), since the plan gives the arch's own rise formula exactly but not these; a reviewer with the reference painting in front of them may want them adjusted. Platforms: Mac run; Windows not run. **WP3 review fix pass (17 September 2026):** Opus 5's review of WP3 returned three must-fix findings, all fixed here. (1) The modern round tower's glazed ribbon band rendered as a blank white silo with no windows, glazing or visible string courses: `Color(0.42,0.7,0.76,0.42)` in the transparency-alpha `"glass"` material, standing 0.02 m outside the `c0c7c6` shell, and the floor-line ring's colour for modern (`trim if style!="modern" else plaster`) matching the shell exactly. Recolouring the band dark while keeping it in `"glass"` was tried first and rendered-checked before being accepted, and it did not work: a same-session investigation (`artifacts/wp3-review-scratch/`, `debug_modern.gd`/`debug_modern2.gd` confirming the geometry and colour were correct at the data level, then `exp_0.06`/`exp_0.15`/`exp_0.3`/`exp_0.5`/`exp_0.7`/`exp_nocaps10`/`experiment1` sweeping the band's radial offset out to a full metre and `sample_pixels.gd` reading actual output pixels) showed that a transparency-alpha, unshaded material does not composite as a visible tint when it stands flush against an opaque, uncut wall: nothing shows until the band is pushed so far out that it reads only past the wall's own silhouette, against the sky, never over the wall itself. Every existing use of the `"glass"` material sits over a cut opening's dark interior or over open air (a roof parapet, a railing); this was the first use of it flush against a solid, uncut shell, and that combination silently fails to render in this pipeline. The fix (`Architecture.styled_tower`, `scripts/architecture.gd`) draws the ribbon in the same opaque `"plain"` material the shell and trim already use, `Color(0.07,0.12,0.15)`, confirmed dark and clearly readable at the same 0.02 m offset (`artifacts/wp3-review-scratch/exp_opaque/courtyard.png`), and adds a scattered warm-lit emitter per glazed floor (about 28% of facets, night-lit like a real window) to restore the night lighting the old per-window boxes used to contribute, which the review's `emitter_sources` collateral (526 to 274) also named. The floor-line ring's colour drops the modern-only exception and always stands in `trim`, removing the second half of the same "reads as the wall" failure. (2) The WP3 entry below wrongly said `styled` "holds one victorian tower at the frame's edge"; `audit.json`'s only tower is id 2, `style: "canal"`, confirmed again here (`jq -r '.objects[]|select(.kind=="tower")|"\(.id) \(.params.style)"' artifacts/visual-audit/audit.json` → `2 canal`) and the wording is corrected in place below. (3) The WP3 entry's Review line wrongly said review had not run; it now names Opus 5's three findings and that all three are fixed here, none deferred. Files: `scripts/architecture.gd`, `tests/test_building_tools.gd`, `docs/visual-handoff.md`. Backups: `build/backup-wp3-review/` (`architecture.gd`, `visual-handoff.md`, both the pre-review-fix state, i.e. WP3 as implemented before this pass). The test-first failure is `artifacts/wp3-review-testfirst3.log` (a new `modern_tower_glazing_checks` in `tests/test_building_tools.gd`, run against `build/backup-wp3-review/architecture.gd`: "The glazing ribbon is opaque and stands in its own dark tone, not a near-transparent tint that fails to composite over the wall behind it", the right reason, since the pre-fix band was still the old transparent tint). An intermediate version of that test (checking only vertex colour and alpha in the `"glass"` group) passed against both the buggy code and a first, still-broken recolour-only fix, because it never rendered a frame; it was replaced with a check on the `"plain"` group precise enough to fail on the crowning cornice's own trim colour (average lightness 0.24) and pass only on the glazing's own tone (average lightness 0.11), and a second check that the `"glass"` material carries no dark near-opaque tone at all, so a future regression back into that material would fail here even though this test cannot render a frame either. Tests: building tools 417 (was 412; the new check plus its three assertions - shell still in plaster, floor-line ring in trim on every style, glazing ribbon opaque and in its own dark tone, and the `"glass"` material free of that tone), masonry 470 (unchanged, run for regression), cluster walls 199 (unchanged, run for regression), scene 456 (unchanged, run for regression). Full `tools/test.sh`: 2,693 checks, 0 failures (scene 456, building tools 417, cluster walls 199, lighting 149, masonry 470, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) with the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp3-review-full-test.log`. Captures: `artifacts/visual-audit/wp3/` re-captured a second time in this pass (`overview`, `canal`, `canal-night`, `styled`, `towers`, `towers-close`, `tower-facets`, `cluster`; `window-close`, `bridges`, `curves`, `bridge-close` untouched, as in the original WP3 entry) - the first re-capture in this pass (made right after the still-broken recolour-only fix) showed the same blank drum as the finding and was overwritten before being read; the second, after the opaque-material fix, shows the modern tower in `towers` and `towers-close` as a dark banded drum with visible white trim rings and warm window glints, in place of the plain white silo the review named, confirmed against an isolated single-tower render at several radial offsets (`artifacts/wp3-review-scratch/exp_opaque/courtyard.png`) before trusting the full-scene capture. Measurements: none requested by the findings; no instance or vertex count changed (the fix recolours and re-materials existing geometry and adds emitter records, which are not mesh instances or vertices). Review: this is the fix pass responding to Opus 5's review of WP3; all three must-fix findings are fixed above, none deferred. Not done: nothing beyond the three findings was in scope for this pass; the "Not done" list in the WP3 entry below is unchanged by this pass. Platforms: Mac run; Windows not run. **WP3 round towers rebuilt from rings (17 September 2026):** every round tower - the canal shell and the four styled ones - now scales its facet count and its window count to its own circumference instead of a fixed cylinder every tower shared. `DioramaState.tower_sides(o)` returns `clamp(round(circumference / TOWER_FACET), 16, 48)` (`TOWER_FACET = 0.55`) and `DioramaState.tower_window_count(o)` returns `clamp(round(circumference / TOWER_WINDOW_SPACING), 4, 12)` (`TOWER_WINDOW_SPACING = 2.2`); the old `TOWER_SIDES = 24` constant is gone and every consumer calls one of the two functions: `DioramaState.footprint`, `Supports.perimeter` (read by `Supports.plan`, so a tower's skirt courses, plinth band and pillar/bracket rings all key off it), `RoofProfile.faces`' cone ring, `Architecture.supports`' plinth-ring detection, the canal tower's shell/string-course/crown rings and its window loop in `Architecture.canal_building`, a new `Architecture.styled_tower` and `Architecture.styled_tower_roof_edge` for the four styled towers, and `ClusterArchitecture.tower_windows` for a merged tower's own generated windows. This closes the specific inconsistency F4 named: the canal tower's 16-sided shell no longer disagrees with the support rings' old fixed 24. Windows are placed at `tower_window_count` evenly spaced angles per floor, staggered half a spacing on alternate floors, each narrowed to `min(0.8 * facet_chord, cap)` so a frame never spans more than the facet it stands on - the specific complaint in F4 that every tower carried exactly eight windows whatever its radius. `Architecture.styled_tower` replaces the old flat 8-panel facade (straight boxes tangent to the curve, each spanning three quarters of the diameter) with rings and facet-sized pieces only: `MeshBatch.ring` for every string course and the crowning cornice, one dentil box per facet for victorian, a `MeshBatch.cylinder_shell` glazed ribbon band per floor in place of punched windows for modern, and for medieval a stone lower-storey shell (canal stone) under a plastered upper one with a timber `ring` at the seam and at every floor above it, both in the same authored material the flat shell already used so the bond is one piece. `Architecture.styled_tower_roof_edge` replaces the flat-roof edge's per-facet merlon/glass-parapet/railing boxes, previously drawn against the same three-quarter-diameter length, with one facet-chord-wide piece per facet. Files: `scripts/scene_state.gd`, `scripts/architecture.gd`, `scripts/supports.gd`, `scripts/roof_profile.gd`, `scripts/cluster_architecture.gd`, `tests/test_building_tools.gd`, `tests/test_cluster_walls.gd`, `tests/test_masonry.gd`. Backups: `build/backup-wp3/`. The test-first failure is `artifacts/wp3-testfirst.log` (`tests/test_building_tools.gd` parsed against the unmodified `build/backup-wp3/` scripts: "Static function tower_sides() not found in base DioramaState", the right reason, since the new API did not exist yet). Tests: building tools 412 (was 401: a new `tower_scale_checks` - a 3 m turret and a 9 m keep get different facet and window counts from the rule and neither is the old fixed 24 or 8, the smallest and largest towers clamp to 16/48 facets and 4/12 windows, `DioramaState.footprint` and `Supports.perimeter` read the same facet count the shell does, a facet chord stays well under the window spacing, and a medieval keep's batch carries both `stone_uv` and `plaster_uv` from its split shell), masonry 470 (unchanged count; the two generic shell-continuity checks that used to read `DioramaState.TOWER_SIDES` for an arbitrary polygon now say `24` directly, since that check is about the coordinate contract on any polygon, not the tower rule), cluster walls 199 (unchanged count; the cone-tile and mound-skirt-ring checks now compare against `DioramaState.tower_sides(that tower)` instead of the old constant), scene 456 (unaffected, run for regression). One implementation bug was caught by the suite, not the new test: the plinth-ring detection in `Architecture.supports` compared `ring_counts.get(c.course, 0)` against a `tower_sides` variable that defaulted to `0` for non-tower buildings, so `0 == 0` wrongly took the tower-ring branch for every rectangular building's foundation skirt and dropped its per-edge boxes; `tests/test_cluster_walls.gd`'s slope-house plinth-depth check failed with the plinth's lowest vertex 4.35 instead of the expected 4.2, which is how it was found, and the fix adds an explicit `o.kind == "tower" and` guard. Suite logs: `artifacts/wp3-building-tools.log`, `artifacts/wp3-masonry.log`, `artifacts/wp3-cluster-walls.log`, `artifacts/wp3-scene.log`. Full `tools/test.sh`: 2,688 checks, 0 failures (scene 456, building tools 412, cluster walls 199, lighting 149, masonry 470, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) with the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp3-full-test.log`, exit 0 (re-run afterwards as `artifacts/wp3-full-test-final.log`, same result, after a same-session round trip through the backups for the measurements below). Captures: `artifacts/visual-audit/wp3/` (changed: `towers`, `towers-close`, `tower-facets` - every one of these towers stands alone in its own cluster, so each carries the full change: a facet count and a window count sized to its own radius, ring-built string courses and cornices, and the medieval/japanese/modern style bands described above; `canal`, `canal-night`, `overview` hold the single 8 m canal tower and change the same way; `styled` holds that same canal tower (`audit.json` id 2, `style: "canal"`; this entry originally and wrongly called it "one victorian tower", corrected in the review fix pass below) at the frame's edge and changes the same way; `cluster` holds a 4 m canal tower (`towers.json` id 9) that touches the canal block beside it and so is drawn through `ClusterWalls`'s flat per-facet panels rather than through `canal_building`'s tower branch - only its window count and spacing (`ClusterArchitecture.tower_windows`) and its roof cone's facet count change there, not the ring and shell work, which is the clustered-tower gap named below; unchanged: `window-close`, `bridges`, `curves`, `bridge-close`, none of which hold a tower or touch tower code). Measurements: the dense fixture (`artifacts/weather-pass9/dense.json`) holds zero tower objects, so its `performance.json` is unchanged by this package (27,827 instances, 17.55 ms mean, `artifacts/visual-audit/wp3-dense/performance.json`) and is not evidence about WP3; the `towers` audit scene is the real instance measurement: `detail.total` 4,564 at baseline, 5,098 after WP2's arch rings, 4,626 after WP3 (`artifacts/visual-audit/wp3/towers/performance.json`) - a net drop from WP2 because the smaller towers in that scene now carry fewer windows and so fewer voussoir rings, even though the larger ones carry more. A same-session vertex comparison on four isolated towers, built through a scratch script (`artifacts/wp3-scratch/measure.gd`, `before.log` against `build/backup-wp3/`, `after.log` against the new source): an 8 m canal tower 20,436 to 34,710 vertices (+70%, more shell and roof-cone facets, and a finer cone cuts more tile pieces into the mesh instead of placing whole instances); an 8 m victorian tower 41,364 to 20,376 (-51%) and an 8 m medieval tower 42,948 to 16,188 (-62%), both because the old 8-panel facade fit four bays of windows onto each of eight facets - 32 windows on an 8 m tower - where the circumference rule places 11; a 3 m canal tower 12,870 to 9,471 (-26%, window count 8 to 4). Nothing here approaches `Masonry.BUDGET` (30,000); the styled towers' vertex counts fall, and the canal tower's rise, and both stay in the low tens of thousands for a single 8 m tower, nowhere near the budget that governs a whole scene. Review: Opus 5 reviewed this package after this entry was first written and returned three must-fix findings, all fixed in the review fix pass below (see that entry for what changed and how it was verified); none deferred. Not done: the merged/clustered tower panel (`ClusterWalls.faces`/`ClusterArchitecture.facade`) still draws one flat trapezoid per footprint facet in the projected `stone`/`plaster` material rather than a curved `cylinder_shell` - flagged as leftover WP1 work in that package's handoff and not named in WP3's plan section - but it now shares the same facet count as the standalone shell through `DioramaState.tower_sides`, so a clustered tower's panel count, its own generated window spacing (`ClusterArchitecture.tower_windows`) and its footprint all agree with the standalone rule even though the panel surface itself is still flat. A flat-roofed round tower's rooftop deck still tiles a rectangular `x, z` grid and its railing loop still runs on the building's old 4-sided assumption in `Architecture.canal_building`'s and `Architecture.styled_building`'s shared flat-roof-deck code (used by every building kind, not only towers); this was not touched because the plan does not name it and no audit view shows a flat-roofed round tower closely enough to judge it, so it is an open gap rather than a regression. The medieval and japanese timber pilaster braces that the rectangular styled fronts still draw once or twice per bay are dropped entirely on towers rather than adapted into a ring, since the plan's WP3 section does not mention them for towers and one every couple of the 16-48 facets would read as clutter; this is a judgement call made without a review, not a tested acceptance criterion. Platforms: Mac run; Windows not run. **WP2 real arched openings (16 September 2026):** an arch is now an opening rather than a disc pasted on an uncut wall: the wall is cut to a semicircular crown, the spandrel corners are filled back in, a ring of voussoirs with a proud keystone stands on the springing line, and under the ring a thin authored band keeps the arch reading as an arch where the instances are dropped. `Masonry.arch_ring(batch, centre, radius, depth, tone, rng)` places an odd `Masonry.ring_count(radius)` of wedge boxes (inner face tangent to the intrados, width the extrados chord less a mortar joint, so the ring closes outside and opens its joints towards the opening; the middle stone is the keystone, `Masonry.KEYSTONE` times deeper and lighter) and always lays `MeshBatch.arch_band` under them in `stone_uv` with the ring's own coordinate - one painted brick per voussoir along the arc, one course across the ring. `Masonry.surrounds` clips the band of loose bricks at the springing line of any rect carrying a `radius`, so the ring replaces the band over the head. `Openings` gains `springing_of`, `half_disc`, `arch_head` (backing, pane and ring, seeded from where it stands so it never draws on the architectural RNG stream), `_head` (which gives a placed window group a radius when its building asks for arched windows, the light is taller than it is wide and the style builds in stone), a `spandrel` that reads the hole's own foot, and a `portal` whose ten straight beams are replaced by the voussoir ring with the keystone box kept. `Architecture.window` draws an arched head instead of the disc: a half-disc pane at the pane's own depth, a half-disc interior back, a `MeshBatch.barrel` reveal in a recessed opening, the flat trim lintel dropped, the ring outside. The canal bay planner in `Architecture.canal_building` and the merged one in `ClusterArchitecture.facade` now draw the same head rule - the ground floor is an arcade and every floor is one where the building asks for arched windows - taking the head out of the opening's own height so an arched bay fills exactly the hole a plain one would; both pass their cuts to `Openings.spandrels`. Styled fronts arcade their ground floor when asked, in victorian and medieval only (`Masonry.SURROUND_STYLES`); japanese and modern keep flat heads. Files: `scripts/masonry.gd`, `scripts/mesh_batch.gd`, `scripts/openings.gd`, `scripts/architecture.gd`, `scripts/cluster_architecture.gd`, `tests/test_masonry.gd`, `tests/test_cluster_walls.gd`, `tests/test_building_tools.gd`, `tests/test_scene.gd`. Backups: `build/backup-wp2/`. Tests: masonry 470 (was 419: ring count odd and at least five, every stone seated on the intrados with its long axis radial, even spacing springing to springing, joints within a mortar width, one keystone standing proud and upright, the band one course tall and one brick per voussoir with every triangle wound for its normal, the band still drawn with the brick detail off, and a brick count over a two-storey block - every bay arched when asked, the ground floor arcade only when not, and the styled fronts arched in victorian and medieval but not japanese or modern), cluster walls 199 (the arch's bricks are counted against the semicircle above the springing and the ring is counted on it), building tools 401 (`Openings.summary.arched`), scene 456 (a placed tall light is arched only while its building asks for it, and the scene round-trips through a save to the same rings and walls). The test-first failure is `artifacts/wp2-masonry-testfirst.log`; suite logs `artifacts/wp2-masonry.log`, `wp2-cluster-walls.log`, `wp2-building-tools.log`, `wp2-scene.log`, `wp2-test_lighting.log`, `wp2-test_weathering.log`, `wp2-test_wet.log`. Full `tools/test.sh`: 2,677 checks, 0 failures (scene 456, building tools 401, cluster walls 199, lighting 149, masonry 470, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) with the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp2-full-test.log`, exit 0. Captures: `artifacts/visual-audit/wp2/` (changed: `window-close`, `canal`, `canal-night`, `overview`, `cluster`, `towers`, `towers-close`, `tower-facets`, `bridges` and `styled` in the part of frame holding a canal block - every bay that was a flat disc over an uncut wall is now a cut arch with one ring and a keystone, on the canal blocks, the merged cluster block and the round towers' applied windows; unchanged apart from rain, puddles and water: `curves`, `bridge-close`, and the medieval, victorian and modern blocks of `styled`, which do not ask for arched windows). The level of detail was checked three ways and all three are in the same folder: `wp2/lod60/` (ortho size 60, all 6,023 instances still drawn), `wp2/lod-drop/` (the focus moved 45 m off the block so 1,891 of 6,023 instances drop, the arches still read), and `wp2/lod-nobricks/` (`--bricks=off`, zero instances: every arch still carries its ring band with the voussoir joints painted on it, which is what the band exists for). `wp2/arch-close/` is a close view of the wall gateway and the building's path arch beside it. Budget: the dense fixture (`artifacts/weather-pass9/dense.json`, `--churn=100000`) measured twice in this session against the same binary, once with `build/backup-wp2/` restored: 24,394 instances and 18.84 ms mean frame (`artifacts/visual-audit/wp2-dense-baseline/performance.json`) against 27,827 instances and 19.26 ms mean (`artifacts/visual-audit/wp2-dense/performance.json`), so the rings add 3,433 instances (+14%) and 0.43 ms (+2.3%), and the scene stays inside the 30,000 `Masonry.BUDGET` with nothing dropped. Review: Sonnet reviewed this package after this entry was written; acceptance met, no must-fix findings, nothing to fix. Two advisories left as they are: the `build/backup-wp2/test_cluster_walls.gd` backup is timestamped after the first edits (its content is still a sane pre-WP2 version), and the `arch-close` capture crops the path arch it is captioned for at the frame edge. Not done: the canal and styled bridges keep their scalloped fill and their `stone` lofts, which is WP5's package, so `bridges` and `bridge-close` are unchanged; the arched bays are still one bay rule at every size, which is WP4's; the spandrel above an arched bay is a flat polygon at the wall face rather than a box with the wall's depth, exactly as the path arches have always drawn it, so the wall's thickness does not show in the corners above the head. Platforms: Mac run; Windows not run. **WP1 authored masonry coordinates (16 September 2026):** curved masonry now writes its own metric face coordinate into UV instead of projecting the world position facet by facet, so the running bond goes round a tower shell and along a freehand wall in one piece. `shaders/masonry.gdshader` and `shaders/plaster.gdshader` take `uniform bool authored` and read `UV` when it is set (else `masonry_face_coord`, untouched); `Architecture.materials()` adds `stone_uv` and `plaster_uv` (same shaders, `authored = true`); `Weathering.WEATHERED` lists both so UV2 keeps flowing; `MeshBatch` gains `cylinder_shell`, `ring`, `barrel`, a `uvs` argument on `loft` and per-vertex normals on `_append_face`; `Masonry` gains `arc_coord`, `path_lengths`, `path_coord`. Consumers: the canal and styled tower shells (`cylinder_shell`), canal tower string courses and the tower plinth courses in `supports` (`ring`), every `wall_path` band (`loft` with `Masonry.path_lengths`, drawn in `stone_uv`). `barrel` has no consumer until WP5. The spike (one `stone_uv` shell on the canal tower, `artifacts/visual-audit/wp1-spike/tower-facets/`) showed UV reaching the fragment stage under Compatibility before anything else was touched. Files: `scripts/architecture.gd`, `scripts/mesh_batch.gd`, `scripts/masonry.gd`, `scripts/weathering.gd`, `scripts/world_view.gd` (rain uniform on the two new keys), `shaders/masonry.gdshader`, `shaders/plaster.gdshader`, `tests/test_masonry.gd`, `tests/test_cluster_walls.gd` (`stone_vertices_in` counts both masonry keys). Backups: `build/backup-wp1/`. Tests: masonry 419 (was 220; continuity across every facet edge of a 24-sided shell and through every vertex of a curved wall within one mortar joint, the projection's jump shown alongside, builders checked against `arc_coord`/`path_coord` in a turned frame, winding checked per triangle, bond checks re-run through `path_coord`), weathering 189, cluster walls 198, building tools 400, scene 451, all passing (`artifacts/wp1-masonry.log`, `wp1-weathering.log`, `wp1-cluster-walls.log`, `wp1-building-tools.log`, `wp1-scene.log`; the test-first failure is `artifacts/wp1-masonry-testfirst.log`). Full `tools/test.sh`: all 2,619 checks passing, 0 failures (scene 451, building tools 400, cluster walls 198, lighting 149, masonry 419, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94) and the windowed `--verify` clean (`PIXELPUNK_INTEGRATION []`), `artifacts/wp1-full-test.log`, exit 0. Captures: `artifacts/visual-audit/wp1/` (changed: `tower-facets`, `curves`, `towers`, `towers-close`, `canal`, `canal-night`, the 8 m canal towers and the curved wall carry one continuous bond; unchanged apart from rain, puddle and water animation: `overview`, `window-close`, `bridge-close`, `cluster`; `styled` and `bridges` are unchanged in the same way except that the 8 m canal tower's shell is in frame at the edge of both, top-left in `styled` and top-right in `bridges`, and that shell carries the WP1 bond). The first `styled` capture of this package was a zoomed-in frame (draw calls 256 against the baseline's 347, the same content at roughly two thirds of the ortho size; `Main` applies `--camera` directly with no smoothing, so the run took a different size, not an early capture) and was wrongly listed as unchanged; it is kept as `artifacts/visual-audit/wp1/stale-styled-2235/` and was re-captured with the capture block in the fix pass: draw calls 351 / rendered objects 376 against the baseline's 347 / 372, the same +4 the other views show. Every view was then pixel-diffed against the baseline (`artifacts/visual-audit/wp1/diff-baseline-vs-wp1.log`, a headless `Image` compare): the re-captured `styled` differs on 5.97 % of pixels (1.00 % strongly), `bridges` on 18.5 % (2.84 % strongly, the animated canal water fills its bottom quarter), the other unchanged views on 0.8–5 %; the masks `artifacts/visual-audit/wp1/diff-styled.png` and `diff-bridges.png` show only the tower shell, rain, puddles and water. Budget: no instances added; `detail.total` 4564 on `tower-facets` before and after, 5471 on `styled` before and after; the dense-fixture run was not made because WP1 adds neither instances nor a measurable vertex count. Review: Sonnet 5, two must-fix findings, both on the `styled` capture and its claim here, fixed in the fix pass as above (no source changed; masonry re-run at 419 passing, `artifacts/wp1-fixpass-masonry.log`). Not done: the merged cluster tower (`ClusterWalls` 24 flat panels through `Openings.emit_boxes`) still reads the projection per panel, which WP3's ring rebuild replaces; the bridge lofts stay on projected `stone` until WP5 rebuilds them; the one unavoidable wrap seam of a shell sits at world -z behind it. Platforms: Mac run; Windows not run. **Stage 0 baseline (16 September 2026):** captured twelve audit views before facade-scale work. Tests: all 2,420 checks passing, 0 failures (scene 451, building tools 400, cluster walls 198, lighting 149, masonry 220, weathering 189, water 116, time 158, foliage 97, wet 100, sun 72, tilt 176, UI 94). Log: `/Users/user/Documents/PixelPunk/artifacts/visual-audit/stage0-full-test.log`. Captures: `artifacts/visual-audit/baseline/` (overview, canal, canal-night, window-close, bridges, styled, towers, towers-close, tower-facets, cluster, curves, bridge-close). These are the reference views against which each work package (WP1–WP5) will be compared. Platform: Mac only.