You are W-HOUSES (round 4). Goal: medieval houses that differ by WEALTH and PLACE, generated as a catalogue of variants
before the planner lays them, with doors that always touch the ground. Read omg/kit/building/CITY-LAYOUT.md first
(section 4 is your spec), then styles/medieval.mjs (the medieval spec generator + layout), render.mjs, TYPES.md.
Reference drawings: /tmp/medlay/ref/t5m36.jpg (patrician house), t6m18.jpg (tower house), t6m36.jpg (dormers),
t7m00.jpg (chimneys, louvre), t7m36.jpg (signs), t7m48.jpg + t7m54.jpg (craftsmen houses and cottages): LOOK at them.

Files you own: omg/kit/building/styles/medieval.mjs, omg/kit/building/check.mjs (only if needed),
omg/kit/building/test/houses.test.mjs (new), browse/houses.html (new: the catalogue page), tools/gpu/houses_probe.py
(new), TYPES.md (a short "round 4 overrides" section). Do NOT touch settlement.mjs / settlement-render.mjs (W-PLAN owns
them, in parallel).

FROZEN interface (W-PLAN passes these in makeSpec(style, type, seed, o) overrides; all optional; absent = today's
behaviour so existing tests keep passing):
- o.archetype: 'hovel' | 'cottage' | 'craft' | 'burgher' | 'patrician' | 'tower' (types house/shop/bakery/tavern/
  smithy read it; CITY-LAYOUT.md section 4 gives storeys, bays, look). o.storeys / o.bays / o.d / o.gableFront still win.
- o.wealth: 0..1. Drives glazing (window.std = leaded glass only when wealth > 0.6, else the new 'window.shutter'
  role), dormers (burgher 0-1, patrician 1-3 on the street slope), chimney stack ('chimney.cluster' wealth > 0.7,
  'chimney.twin' 0.4-0.7, chimney_stone below, a 'louvre' on hovels/cottages without a chimney), the arched stone door
  ('door.arched' for patrician/tower), roof material (hovel and most cottages: thatch roles; town: tile).
- o.trade: 'boot' | 'pig' | 'key' | 'pretzel' | null: a hanging sign on the street facade at the first floor line
  (roles 'sign.boot' etc.). o.trade overrides nothing else.
- o.backDoor: boolean (false = no back door, a window or blank instead).
- o.backGrade: metres, ground height at the back wall relative to the street grade (floor y = 0 side). DOOR LAW: a door
  is only drawn where it touches the ground within 0.35 m. |backGrade| <= 0.35: back door at floor level (if
  o.backDoor !== false). backGrade <= -2.0: the stone base already runs down there (o.plinth >= -backGrade, raise it
  if not): put a 'door.cellar' at y = backGrade on the back wall (a door into the undercroft) and 1-2 'window.cellar'
  in the base. Anything else: no back door. The street door is always at y = storeys[0].y as today (the planner sets
  y = street grade); add a check finding when a door's bottom is more than 0.35 m above its grade.
- export catalogue(style, seed, n = 48) -> array of { archetype, type, o } override sets covering every archetype with
  varied bays, storeys (1-4), storey heights (ground 2.6-3.4, upper 2.3-2.8), roof pitch (50-62), jetty (0, 0.3, 0.5),
  gable or eaves front, stone storeys (1 or 2; hovels/cottages all stone or all plain timber), wall/timber/infill
  palette, brace pattern (vary the generated braces: none / corner K / full X 'Prussian wall', see t8m24.jpg).
  Deterministic per seed. W-PLAN will pick from it by plot width and district, so give each entry its footprint
  width w and depth d (measure with the spec).
New kit 'medieval-town' (built by Astra in parallel: atom names, sizes and origins are FROZEN in
jobs/medieval-town-v1/STYLE.md, read it). Use the TRADES pattern (TRADES_KIT / TRADES table: kit + grey-box size) so a
missing kit or atom still renders as a plain box and never breaks; the thatch roof falls back to tile strips when the
kit is absent. Roles: 'dormer.gabled', 'dormer.hipped', 'dormer.wall', 'louvre', 'chimney.cluster', 'chimney.twin',
'sign.boot|pig|key|pretzel', 'oriel', 'door.arched', 'door.cellar', 'window.cellar', 'window.shutter', 'finial',
'thatch.panel', 'thatch.ridge'. Dormers sit on the tile field (no hole needed; they cover the tiles they stand on).
Thatch: lay thatch_panel on a 1 m grid over each roof plane (eaves overhang and verge kept), thatch_ridge along the
ridge; lite and far details keep today's rules (far: a plain roof panel).
Tower archetype: 2 bays, 4 storeys, 2 stone storeys, gable front, oriel on storey 2. Patrician: 4-5 bays or gable front,
3-4 storeys, finial on the gable apex.
Budget: a full-detail patrician house <= 1.6x today's 3-bay house triangles; thatch roofs <= today's tile roofs.
Page browse/houses.html: the catalogue as a grid of houses (one per archetype row, 6-8 variants per row), labels,
window.__ready/__stats, same camera/HUD conventions as browse/buildings.html, plus one hill row with backGrade -3 /
0 / +1.5 on a sloped ground stand-in so the door law is visible.
Local server port 8981, GPU probe FAL_PORT 8982. Evidence: tests (catalogue determinism, every archetype builds with
0 errors in check(), door law: no door bottom > 0.35 m above grade for backGrade in {-4,-2.5,-1,0,1.5}, backDoor false
= no back door, kit absent = grey boxes + findings, budgets), GPU screenshots of the catalogue page (front 3/4 view and
a close look at a patrician and a cottage) that you LOOK at.
Time box: stop by 12:05 CET with what works committed.
