PROCITY/docs/LANES/LANE_A_NOTES.md
m3ultra 918a968185 Lane A: add LANE_A_NOTES.md — answer Lane F's storeys-warning + hours contract questions
Cross-lane note (ROUND3 process rule: notes for other lanes go in docs/LANES/):
qa.sh's storeys warnings are benign corner anchors (finding #5 stale), with the
exact permittedMax rule for Lane F to scope its checker; openLate/hours contract
confirmed ready for §3.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 15:54:16 +10:00

2.0 KiB

LANE A — NOTES (cross-lane answers from CityGen)

Durable answers to questions other lanes raised against Lane A. Full status in A-progress.md.

Round 3 (2026-07-14)

→ Lane F: the qa.sh "storeys outside registry range" warnings are BENIGN (finding #5 closed)

Your consistency gate prints ~5 warnings per run: "N shop(s) have storeys outside their registry type range … else a plan↔registry drift — ask Lane A".

Verified across 8 seeds: they are all the intended "occasional 3-storey corner anchor" (CITY_SPEC), never drift. Evidence:

  • Single-storey types (video/milkbar/stall, registry [1,1]) are observed at 1 storey ONLY — e.g. 412 video shops, none at 2. So the specific "video at 2" example does not occur.
  • The only shops above their registry max are tall-capable types (record/opshop/toy/book/pawn [1,2], dept [2,3]) reaching 3 via the corner anchor. Round-1's cornerBoost gate only boosts types with registry max ≥ 2, so it can't over-raise a single-storey type.

To silence the warning correctly, scope your check to the permitted max, not the strict registry max:

permittedMax(type) = registryMax >= 2 ? Math.min(registryMax + 1, 3) : registryMax
// flag only shops with storeys < registryMin || storeys > permittedMax  → that IS real drift

This rule is now documented in docs/CITY_SPEC.md (Layer-1 shops schema, storeys line) and enforced by web/js/citygen/selfcheck.js (tightened this round — a single-storey type exceeding 1 now fails loudly).

→ Lane F: hours / openLate contract is ready for your §3.5 wiring (no changes)

hours = [open, close], 24h integers, 0 ≤ open < close ≤ 23. Exactly one shop per town has openLate: true (closes ≥ 22:00; a video rental or milk bar, never a market stall); the field is absent on all others. Gate on the field — plan.shops.find(s => s.openLate) — not a magic hours threshold. Your ROUND3_INSTRUCTIONS §Lane F states it correctly, so consume as-is.