You are seat S1 (spec + check). Build:
1. kits-src/breton/style.json (the style law as data, TYPES.md shape, v2 numbers). Roles map to the v1 kit node names
   (browse/kits/breton/kit.json): window.std -> window_ground, window.std.shutters -> window_ground_shutters,
   window.small -> window_small, door.main -> door, door.back -> door (v1 has no back door yet), door.double -> door,
   window.shop -> window_ground, dormer -> dormer, chimney -> chimney_stack, roof.unit.{a,b,c} -> slate_{a,b,c},
   roof.ridge -> ridge_tile, roof.verge -> verge_board_1m, eaves.fascia -> eaves_board_1m, eaves.gutter -> gutter_1m,
   downpipe -> downpipe_1m, corner.long/short -> quoin_long/short, lantern -> lantern. Also a `roles_v2` block for kit v2
   names (window_std, shutters_std, door_back, door_double, window_shop, slate_strip_a/b, roof_underlay, fascia_1m,
   gutter_bracket, gutter_end_cap, gutter_outlet, downpipe_shoe, tavern_sign, bench_stone): spec.mjs picks roles_v2 when
   the loaded kit.json has those nodes. Types: house, longhouse, tavern, shop (BLUEPRINT section 4).
2. omg/kit/building/spec.mjs: `makeSpec(style, type, seed, overrides = {}, kitNodes = null) -> BuildingSpec` and
   `makeSpecChecked(...)` (re-roll up to 8 seeds on spec errors, then a template fallback; returns {spec, tries, fallback}).
   Deterministic (seeded mulberry32 like houses.mjs rng), canonical-JSON fnv1a `hash`. Implements program -> massing
   -> facades + roof furniture: bay grid from the type and style numbers, door on the centre axis for odd bays, garden
   facade mirrored axes + back door + windows on 1+ axes per storey, gable rules (chimney gable: flanking smalls or none),
   dormers on axes for habitable attics (longhouse), chimneys, lantern next to the main door, sign for the tavern,
   optional lean-to (blank the bays it covers). `look`: wall material, roof material, paint colours drawn from the style
   palette (this round: shades of the kit's Breton blue for joinery/shutters/door, plus off-white frames).
3. omg/kit/building/check.mjs: `check(spec, style) -> Finding[]` (TYPES.md) with every SPEC rule of BLUEPRINT section 4
   (rules 1-7 + lean-to rule), each finding a plain sentence. Also `fromLegacyRecipe(rc)`: converts today's
   `breton(seed)` recipe (omg/kit/houses.mjs) to a BuildingSpec so the checker can judge it.
4. omg/kit/building/test/spec.test.mjs: 200 seeds x each type -> 0 errors after re-roll, fallback < 5 %; same seed =
   same hash; the fixture passes check(); and each of these rules has a test that FAILS on `fromLegacyRecipe(breton(s))`
   for some seed s: one-window-per-storey (ground 1.30 vs upper 1.10), head-line, garden-facade (lone upper windows,
   no back door), bay/pier (shutters overlap). Print a short table of type -> width range, storeys, tries, fallbacks.
V3 ADDITIONS (BLUEPRINT rules 8b, 8c, 12): eaves = last full storey y + h + kneewall (0 or 0.6) and the spec carries
`kneewall`; habitable attics get dormers and gable smalls only; back door on an OUTER axis for 2-3 bay facades; the
fallback template must itself pass check() (test it); style.json gets `paint_slots_v1` and the look's paint colours
for kit v1 are blue shades (value 0.75-1.0) for shutters/door and warm white-to-cream for joinery; write
omg/kit/building/fixtures/breton-longhouse.spec.json (exact coordinates, from makeSpec) for seat S2.
V3.1 (Fable pass 2): end pier measured from the outermost surround or OPEN SHUTTER LEAF edge to the corner >= 0.55
(kit v1 shuttered window leaf half-width 1.115 -> >= 1.19 from the clear opening; plain >= 1.0); garden glazing range
0.05-0.30, street 0.10-0.30 (TYPES.md); the fixture is now 8.33 m wide.
Files you own (plus that fixture): kits-src/breton/style.json, omg/kit/building/spec.mjs, omg/kit/building/check.mjs,
omg/kit/building/test/spec.test.mjs. Do not edit other files.
