c1e862cf7c
26 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
c1e862cf7c |
Lane A R27 wave 5: THE FACADE FIX — it was every town, not just the real ones (the covenant amended)
selfcheck ALL GREEN 156,352/156,352; consistency green. 51 goldens re-pinned in this one commit per the amendment law. scaffold_check is RED and CANNOT be green from here — the covenant hashes are duplicated in LANE F's files; exact values handed to F in LANE_A_NOTES §R27w5 (I don't edit other lanes' files). THE RULING'S PREMISE WAS WRONG, AND THE WRONG HALF WAS LOAD-BEARING. Wave 5 says "synthetic follows B's canon so every golden has been green over a wrong product since R18". Half right. Synthetic does NOT follow B's canon -- it is broken identically, and so is the marched path, and so are all three checked-in fixtures. It is not "every real town since R18". It is EVERY TOWN, EVERY PATH, SINCE v1. The ruling told me to measure the marched path rather than assume it was clean "because that's how this one survived nine rounds" -- so I measured all three, and the same discipline caught the premise itself. MEASURED FIRST, IN B'S CANON (+Z = the facade), BEFORE TOUCHING ANYTHING: synthetic seed 20261990 0 toward / 681 away (dot = -1.0000, exactly anti-parallel) marched katoomba/fremantle/godverse, fixtures melbourne/katoomba/silverton 0 toward, all away real-roads katoomba 0/72 <- B's number, reproduced 637 of 681 synthetic lots had their facade pointing at NO STREET AT ALL (44 hit a different street by corner coincidence). Then I confirmed it with my own eyes rather than trust the arithmetic: booted ?classic=1, stood on the synthetic main street at lot 0 -> three blank grey boxes. Walked BEHIND them into the block -> NUMBAT PLAYTHINGS, sign/door/windows/awning, facing the dirt. The classic covenant town has been a row of back walls since v1. After the fix, same camera, same seed, same ?classic=1: CROWN TOYS & GAMES · MARBLES & KITES · NUMBAT PLAYTHINGS -- a strip of shopfronts facing the road. FOUR SITES, ONE SIGN, AND EVERY ONE OF THEM SAID SO IN ITS OWN COMMENT: plan.js:122 synthetic strip "facade faces back down the outward normal, to the street" <- it didn't plan.js:244 market row "the facade then faces -(outward) = +x" <- it didn't plan_osm:330 marched avenue "facade faces +z (north) to the avenue" <- due south plan_osm:443 real roads B's proven one-liner (B measured it, then reverted it -- A's file) All four were atan2(outward) where the intent was atan2(-outward). The code never did what its comment said, and CITY_SPEC:71 blessed the result by writing the SIM convention into the LOTS contract. Nobody was wrong; the spec was. After: synthetic 681/681, marched + fixtures 100%, real-roads katoomba 72/72. THE COVENANT MOVED -- JOHN RULED IT, I DIDN'T. Fixing synthetic necessarily moves 0x3fa36874, frozen "forever" since R16. That is not Lane A's call, so I stopped and asked with the evidence. John's ruling: AMEND THE COVENANT, FIX ALL PATHS -- the covenant is anti-drift machinery, not a defect preservative. 51 pins in this commit: classic/synthetic 0x3fa36874 -> 0x5f76e76 gig 0xb1d48ea1 -> 0xec7a2d39 fixtures melbourne 0x9c7e76b3 · katoomba 0xf3aafec8 · silverton 0x6d74c4 23 real towns base + gig (46) Verified byte-identical across two fresh processes; pack-xor 0xa5058322. CITY_SPEC records the amendment as a ONE-TIME, ruling-gated precedent -- from this hash forward the law reads as it always did. A SECOND BUG THE FIX EXPOSED (fixed here, counted). buildRealRoads seated blocks at KERB = 4 m from the CENTRELINE, but a `main` carriageway is 10 m wide -- its kerb is at 5 m. EVERY MAIN-STREET BUILDING HAS STOOD 1 m INSIDE THE ROAD SINCE R18. The footprint never moved; only which face is the front -- so it was invisible until the shopfront turned around and its poster landed in the traffic lane (-1.07 m clearance, 6 real failures). Blocks now seat behind the kerb per A's own published corridor law (roadWidth/2 + FOOTPATH). Pack drops 6.4% -> 6.6%, counted, not hidden. THE CROSS-CONVENTION GATE -- built to F's lesson, not to a spec line. F proved that measuring lots against CITY_SPEC:71's own convention is SELF-AGREEMENT: 72/72 "facing" over a town of blank walls. So this gate restates nothing. It replicates LANE B'S OWN maths from buildings.js (toWorld(lot, 0, y, d/2 + 0.02)) and asks a physical question neither spec line can fudge: does the quad the RENDERER actually draws land nearer the street than the lot centre? It fires if A's ry sign drifts OR if B's zf sign drifts. It would have caught this on day one of v1. CITY_SPEC amendments: the lots contract now states facade/door/frontage = local +Z; the SIM/rig convention is documented separately as the different thing it is, with the explicit rule -- never assert a lot's facing against a spec line, assert it against the geometry the renderer draws. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
839575b28d |
Lane A round 27 (v5.0): the docs freeze — CITY_SPEC v5 + the risk list judged (ledger #6)
Docs only. No code, no golden moved — correct: tier 2 touches no plan, no cache, no atlas bytes. selfcheck ALL GREEN 156,212/156,212; scaffold + consistency green; classic 0x3fa36874 and gig 0xb1d48ea1 frozen. The whole stock epoch moved zero plan goldens, which was the determinism boundary's entire promise. CITY_SPEC v5 SECTION — written from the ARTIFACTS, not the briefs (this epoch's own lesson): - The tier ladder: 0 parody / 1 static real / 2 live GODVERSE, each degrading softly to the rung below. - `sourcing` is NOT `tier`, and C's ruling is the precise one — both ship in every index. `tier: 1` is the LADDER RUNG (a mint atlas is still a static file, so still rung 1); `sourcing: "real"|"mint"` is WHERE THE CONTENTS CAME FROM. Different axes. Collapsing them is exactly how a mint crate comes to read as real. Measured: 15 keyed atlases = 1 real + 14 mint. - The three id-space fences, verified rather than restated (below). - The manifest: existence DECLARED, never probed — the root fix for fail-soft-by-404 colliding with the zero-console-errors law. No entry, no fetch, zero 404s, no attribution exceptions. 15 entries / 15 dirs. - Ruling 2 as law (mixed caches are the design; no gate may assert it away — mine did). - Lane A's seam is exactly one field: godverseShopId, and `'godverseShopId' in shop` is the tier test. THE ID FENCES ARE VERIFIED, NOT ASSERTED. The plan-id/godverse-id trap is STILL LIVE in the data and I reproduced it: in redhill_godverse, bare `31` is "Wholefood Cafe" as a plan id and "Silky Oak Furnature" as a godverse id — the exact ambiguity that made F's enterShop(31) enter the wrong shop and pass a soft-fall assertion vacuously on the wrong subject. So it goes in the spec as a STANDING RULE, not a fixed bug: no code or gate may compare a bare number across the two spaces. (Within the godverse space, G's two halves — census <=2992, dealgod store ids — are numerically disjoint by construction, which is what makes the opaque key safe.) THE RISK LIST, JUDGED LINE BY LINE — AND I DID NOT PRE-RETIRE ANYONE'S GATE: 1. CARRIED. Tier-2 latency/stutter is this round's defining gate and I'm writing in wave 2 — F's reader and kill-the-server gate do not exist yet. NOTHING retires this line except that gate going green. Retiring it from a doc while the code is unwritten would be the precise species this epoch spent four holds catching: a rule meeting a case that doesn't exist yet. The offline law is a promise until #3 makes it falsifiable; that's the whole point of #3. 2. RETIRED — measured, and the remedy the risk NAMED is the remedy that shipped ("crate rotation rather than bigger atlases"). Max 2 atlases/shop vs C's hard cap of 2; the 14 mint shops sit at 16 items / 1 atlas / 1024²; only the one real POS shop earns 2048² (120 items, 2 atlases, 1.2 MB) under the 60+ rule. 3. RETIRED — DESIGNED OUT, not solved. The risk assumed a fuzzy-matching problem ("names drift, shops move"). There is no matcher: identity is an explicit opaque key G emits. The predicted failure cannot occur in the predicted form — and the proof is the headline shop: Monster Robot is in NEITHER the census NOR OSM, so no name-matching strategy could ever have found it. Mis-stocking is fenced structurally instead (duplicate ids error, uniqueness over defined ids, the orphaned-atlas gate). 4. SPLIT. Write-back RETIRED by John's ruling recorded as MECHANISM, not config: /reserve and /buy are ABSENT, not stubbed — races and reservation semantics cannot occur because the verbs don't exist, and "prove the absence" beats any sandbox flag a config typo could flip. (Option B re-opens this line deliberately at v5.x, behind a hold budget.) The `gone` read half is CARRIED to F's #4. 5. Unchanged, extended: static-atlas determinism proved in practice (G's index-only sku re-emit moved no .webp bytes); the fail-soft ladder proved on every rung; the id fences now have case law behind them. 6. NEW, CARRIED — the orphaned atlas, with a live near-miss on the books. 7. NEW, CARRIED — "real" is one shop wide: 14 of 15 keyed atlases are mint, because exactly one shop has a POS. Honest and marked, not a defect — but the epoch's headline claim rests on ONE shop, and any future claim of scale needs either siblings for monsterrobot or continued care that `sourcing` stays legible to humans and not just to gates. THE GATE THAT ARMED ITSELF (the law working unattended, worth recording). My R25 orphaned-atlas gate SKIPped on newtown_godverse all through R25 — "no committed atlas keys to this town", subject absent, so it said so instead of passing quietly. The moment G's 14 mint atlases landed it STARTED BINDING ON ITS OWN and passed: 156,211 -> 156,212, and that +1 IS the gate arming itself. Nobody edited it. That is what the vacuous-gate law buys — a gate that waits, in the open, for its subject to exist. G: redhill_godverse's lift drops keyed shop 2286 "Empire Revival"; you stocked its numeric neighbour 2287. Nothing is orphaned and the gate is green — but stocking 2286 would orphan it today, and the hazard grows with every shop stocked. Carried as risk #6. F: nothing of mine gates your tag. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a493c0a13c |
Lane A round 25 (v5.0-alpha): the sweep reconciled with Ruling 2 + the six pins (ledger #1)
All 8 tree reds cleared. selfcheck ALL GREEN 156,211/156,211; scaffold + consistency green; classic
0x3fa36874 and gig 0xb1d48ea1 frozen. F: the tag is unblocked from my side, nothing of mine is pending.
SIX OF THE EIGHT REDS WERE MY OWN GATE ASSERTING RULING 2 AWAY. I built the R24 identity arm on an
assumption that was true when I wrote it and false the moment G shipped: that a godverse cache is ALL
census shops. Ruling 2 makes it MIXED -- a keyed GODVERSE layer plus an inherited OSM texture layer that
G measured to be load-bearing, not cosmetic (census-only Red Hill: 306 m spacing warn + a poster inside a
kerb). So newtown_godverse (18 keyed + 54 texture) and redhill_godverse (10 + 27) were HEALTHY TOWNS MY
GATE CALLED BROKEN -- it fired 54/72 on a good town. Keyed asserts now run PER-LAYER over the keyed subset
only; unkeyed texture shops raise nothing. The validator's "N/M missing" warn dies with it. The one honest
requirement left at that layer: a `godverse+osm` cache must have a NON-EMPTY godverse layer (else it's an
osm cache wearing the wrong `source`) -- still a warn, for the R24 charter reasons that still hold.
THE UNIQUENESS CHECK WAS BROKEN IN BOTH DIRECTIONS. `new Set(all ids).size === shops.length` collapses
every `undefined` into ONE Set entry, so it (a) failed structurally on any mixed cache -- 54 texture shops
became one entry -- and (b) could HIDE A REAL DUPLICATE behind that same collapse. Now over DEFINED ids
only. And per the vacuous-gate law I made it prove it bites rather than asserting that it does:
validateTownCache rejects duplicates at the front door, so a dup can never reach the plan that way -- the
test feeds one STRAIGHT TO THE LIFT (generatePlanOSM does not validate) and asserts the predicate catches
it, with a healthy mixed cache passing the same predicate. A check nobody can watch fail is not a check.
NEW -- THE ORPHANED-ATLAS GATE (my own R24 finding, now enforced instead of filed). The lift legitimately
drops shops (overlap-resolve, counted since R19). Dropping a shop that HAS a committed atlas means real
stock keyed to a shop that isn't in the town -- exactly the failure I filed in R24, and one F's #7b could
only catch in a browser at the end of a round. Now a node gate: for each godverse town, every
stock_godverse/<id>/ on disk belonging to that cache MUST be seated, else FAIL. Subject-aware -- it SKIPs
by name when a town has no atlas, rather than passing quietly.
It already found one, benign today: redhill's lift drops keyed shop 2286 "Empire Revival" (10 keyed in
cache -> 9 seated). No atlas, so nothing is orphaned and the gate passes -- but it prints, because a drop
must never be silent (the R19/R20 ruling). G: stocking Empire Revival at the beta would orphan it. Monster
Robot Party is seated (lot 8), which is the one that matters this round.
THE SIX PINS, cross-checked two ways before landing -- byte-identical across two fresh processes, AND
matching the three values G stated independently in
|
||
|
|
1eb0b45bd0 |
Lane A round 24 (v5.0-alpha): the identity field — godverseShopId, published first (ledger #2)
The optional shop key that resolves `stock_godverse/<godverseShopId>/`. Schema STAYS v2 (optional field ⇒ every shipped cache still valid, the 21 osm caches untouched by construction). Published to web/assets/towns/README.md — the doc G and E build to — plus CITY_SPEC. selfcheck ALL GREEN (+15 checks), synthetic 0x3fa36874 frozen, NO golden moved. THE BRIEF'S "THE POS SHOP ID IS THE ID — NO MAPPING TABLE" IS FALSE FOR THE ONE SHOP THIS ALPHA IS ABOUT. G's own docstring says it: Monster Robot Party is NOT in thriftgod's census, so its id is its DEALGOD STORE ID 3962749, while census shops use thriftgod ids (max 2992) -- two disjoint spaces, deliberately kept clear of each other. Had I coded "godverseShopId == shop.id" or derived it from the census, the headline shop could never be keyed. So it is an OPAQUE key: no derivation from `id`, no equality assert, no mapping table (the R12 gigKey law -- one key, zero mapping; G emits, everyone reads). THE FIELD HAD TO SURVIVE THE LIFT OR IT WAS DECORATION. plan_osm builds a FRESH shop object and copies nothing unknown, and the runtime reads plan.shops[], never the cache -- so a cache-only field could never reach F's per-shop base. It's now carried through, CONDITIONALLY: absent ⇒ the key isn't written ⇒ JSON.stringify byte-identical ⇒ every pinned golden holds until G re-emits (that re-emit IS the sanctioned move). Proven end-to-end: a keyed cache puts `stock_godverse/3962749/` on the plan with census ids (101..107) coexisting alongside it. ARMS SPLIT BY HAZARD, NOT TIDINESS: - malformed -> ERROR. It names a path segment; "3962749" vs 3962749 is the same folder but different JSON, and that coercion drift is the exact species that broke C's atlas contract (licence/license). - duplicate -> ERROR. Two shops keyed to one atlas IS mis-stocking -- charter risk #3 forbids it by name. - missing on a godverse cache -> WARN + fail-soft to tier 0. RECORDED DEPARTURE (Fable's to overrule): ledger #2 says validateTownCache "requires" the field; I made MISSING a warn. Three reasons. (1) The charter's determinism boundary is "world = seeded, frozen, gated; stock = data tiers" -- an error inverts it, failing to load a TOWN because its STOCK identity is absent; tier 0 must always boot. (2) Charter risk #3 names the remedy for identity gaps: "fail-soft to tier 0, never mis-stocked" -- missing IS the soft case, duplicate is the hard one; they are different failures and now get different arms. (3) Sequencing: newtown_godverse carries 0 ids today, it is G's to re-emit in wave 2 (their namespace, no census DB on m3), so a hard error would red the tree for C and E through all of wave 1 to say what the warn already says. The requirement keeps its teeth where R23 taught us to put them -- the VACUOUS-GATE LAW: selfcheck FAILS on partial keying (a half-keyed town silently mis-stocks the rest) and prints an explicit "⊘ SKIP ... 0/18 shops carry godverseShopId. Subject absent ... binds the moment one id lands" at zero. It names its subject, proves it touched it with a count, and cannot pass vacuously. FILED FOR G BEFORE THEY START (measured in wave 1, so it costs them minutes not a wave): redhill_godverse cannot contain Monster Robot from EITHER source. godverse_town.py takes roads from the OSM donor and shops from the census, and the shop is in neither -- not in the census (G's R23 finding), and NOT in E's redhill_real, which I checked the moment it landed: 36 shops, ZERO of type `record`, nothing matching /monster|robot/. As written the adapter yields a Red Hill of census charity shops while the atlas keys to a shop that isn't in the town -- F's #7b id-equality gate would fail at the end of the round. It must be injected explicitly; the opaque-key design exists precisely to serve that case. Second trap on the same path: redhill_godverse must still clear MIN_TOWN_SHOPS (6) from the census bbox or the cache is rejected outright (hard error). E's donor is otherwise good: valid, no warns, 73.3 m median spacing. HOUSEKEEPING: removed toowoomba's two stale pins -- E retired the cache in R23, and a golden for a town that cannot load can never fire (the vacuous-gate law, one layer down). E's attempt also proved my R23 spacing metric is GAMEABLE: the re-bbox fixed the median (395.7 -> 89.4 m, "passes") while hub density fell 3/12 -> 2/12, the pack's worst. It is necessary, not sufficient -- D's hub test is the complement, and E used both and refused to game it. Ballarat (255 m) is still flagged and still E's call; I pin what moves. PINS NOT TAKEN YET, DELIBERATELY: redhill_real is untracked/in-flight (E still editing build_towns.py), and redhill_godverse + the re-keyed newtown_godverse don't exist until wave 2. Pinning a moving file buys a false green or a spurious red. The round's law says A pins these BATCHED -- that batch lands when E commits and G's caches are in. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
292b07aa91 |
Lane A round 23 (v5.0-alpha): the spacing warn — D's thin-tail finding as law (ledger #5)
validateTownCache now warns when medianShopSpacing(cache) > MAX_MEDIAN_SPACING_M (150 m). Metric + threshold exported from the barrel so no lane re-derives them. WARN, NEVER ERROR: a flagged cache still boots a valid district (toowoomba shipped green through the entire v4.0 pack) — E curates, A flags. selfcheck ALL GREEN 161,372/161,372 (+72); synthetic 0x3fa36874 frozen; NO golden moved (only E's toowoomba re-bbox may move one this round, per the round's law). THE THRESHOLD IS MEASURED, NOT PICKED. The brief offered darwin 27 m / toowoomba 388 m as "plenty of daylight for a line" — but that's 2 points. Measuring all 23 towns shows a near-continuum, and the line is FORCED into (119.3, 254.9]: braddon at 119.3 m is ALIVE by D's own hub test (7 shops within 160 m, identical to darwin's 7), ballarat at 254.9 m is not. 150 m sits in the pack's widest gap (x2.14), with 1.26x margin below and 1.70x above. Flags 2 of 23. TWO TOWNS FLAG, NOT ONE. The brief names only toowoomba (D spot-checked the two 12-shop towns). The measurement adds BALLARAT at 255 m — nobody has looked at it, and it's independently one of the three towns my R22 graded cluster fallback fired on (no venue candidate at the >=3-shops/160 m floor). Two signals agree. Filed for E as a curation call, counted either way. THE BRIEF'S ANCHORS WERE IN THE WRONG SPACE, AND IT MATTERS. D's 27 m is PLAN space (post-lift metres); validateTownCache is CACHE space (raw lat/lon — the only thing that exists at ingest, and the layer where a bad bbox must be caught). Darwin is 68.3 m in cache space, not 27. Interpolating a threshold between D's figures would have silently mixed spaces. I verified the hypothesis before trusting it: computing the metric plan-side reproduces D's numbers exactly (darwin 27.2 vs 27, toowoomba 386.8 vs 388, hubs 7 and 3). Cache space is correct HERE and provably safe: the lift marches shops at a regularised cadence, so it COMPRESSES dense towns (darwin plan/cache 0.40) but not sparse ones (toowoomba 0.98, ballarat 1.01) -- the error lives at the dense end, the warn only fires at the sparse end. Verified all 23 towns in both spaces: exactly ONE disagrees, newtown_godverse (94.4 cache passes / 158.3 plan would warn). Filed for G/Fable, NOT acted on: no cache-space line catches it without false-positiving braddon, and godverse is a census subset (18 thriftgod shops over the footprint that carries 72 OSM shops) so its sparsity is coverage, not a bad bbox — re-bboxing, the warn's only remedy, cannot fix it. Worth knowing since R23 stocks the real crate in that town and the beta asks "fitzroy_godverse if the census is dense there". Also fixed en route: the R17 silent-fallback trap bit again in my own scratch harness — an unregistered town key resolves to the melbourne fixture rather than erroring, so five towns silently measured identical. Registered the caches; noting it because it has now cost two rounds. Coverage: sparse cache warns + still boots (structural + district suites on a flagged town), compact cache does NOT warn (no false positive), metric edge cases (< 2 shops -> null, coincident -> 0, no throw on empty), and an exact-value check (a 100 m pair measures 100 m, projection sane). Cost: ~1 ms/town at registration (25.6 ms for all 23 incl. fitzroy's 160 shops) vs a <100 ms plan budget. E -> use the warn as your acceptance test for #4: re-bbox, re-run, warn goes silent = the town has a high street. If your fix moves toowoomba's or ballarat's cache, ping me — goldens are mine to re-pin, and only what you move. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
d485b18ecc |
Lane A round 22: close the tri-diet loop — B's numbers say the fix is E's, not A's (ledger #1)
Docs-only handshake close; no code, no goldens. Filed so F isn't waiting on A for the re-measure. My R22 notes left ledger #1's ownership open on purpose: "if B's layer-by-layer names plan geometry (lot or poster counts) as the venue_night driver, I own the fix and will take it." B's diagnosis ( |
||
|
|
3face97046 |
Lane A round 22: absorb the town pack — 23 towns, 36 goldens pinned in one commit (v4.0, ledger #2)
E's 17 new towns + Lane G's newtown_godverse fed through the lift. ONE batched golden commit as briefed: REAL_TOWN_GOLDENS + REAL_TOWN_GIG_GOLDENS go 5 -> 23 towns each, zero unpinned. THE HEADLINE: everything built this epoch held at 23-town scale, FIRST TRY. 1,210 shops -> 1,133 seated (77 dropped, 6.4%, all counted by cause); 1 CONNECTED COMPONENT and 3 VENUES on every one of the 23 towns. fitzroy — 160 shops, 2x anything absorbed before — landed 139 seated, 1 component, 3 venues, 212 posters, all invariants green. The junction-protected DP, fragmentation ruling, cluster bias, poster cap and capacity fence needed NO new hardening: the pack needed absorbing, not fixing. - Graded cluster fallback (the one refinement). Three towns have no candidate at the floor at all (ballarat/toowoomba/newtown_godverse top out at 2 shops within 160m); R21's bias switched off entirely there, stranding venues at 0. It now falls back to the DENSEST AVAILABLE — ballarat 0,2,0 -> 2,2,2, godverse 0,1,1 -> 2,2,2, toowoomba 1,0,0 -> 1,2,1. Fires only where the floor is unreachable, so NO already-pinned town moved (verified). Acceptance at pack scale: 20 of 23 towns have every venue >=3; the three above sit at their town's genuine ceiling — the carved-out case, stated explicitly. - Drop outliers, counted not hidden: daylesford 19% (32 shops on a 171-road graph, the thinnest in the pack, all overflow), fitzroy 13%. RGAP is already 0.5m and NODE_CLEAR 3m; the only lever left is spilling overflow onto a DIFFERENT street, which buys a few percent by putting a shop on a road it isn't on. Same ruling as R20: drop and count beats teleport. - selfcheck ALL GREEN 161,300/161,300; scaffold + consistency GREEN; cross-process deterministic (pack-xor 0xca140954). classic 0x3fa36874 / gig 0xb1d48ea1 / marched fixtures FROZEN. Handshake -> C + D + F: the pack is in, 23 towns pinned, start your verifies. Tri diet (ledger #1): if B's layer-by-layer names plan geometry as the venue_night driver, I own the fix. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
110c82833b |
Lane A round 21: venue cluster-adjacency bias — D's relocation finding (ledger #1)
D found katoomba's pub 1,000m from the retail cluster — a gig with no passing crowd. Measuring all five towns first showed it was SYSTEMIC: 11 of 15 venues sat with <3 shops within 160m (newtown's were 0/0/1 — every venue stranded). After the bias: 0 of 15. Katoomba's pub 1 → 9. Castlemaine cleared without needing the floor exception the brief anticipated. - pickVenues builds a CLUSTER-ADJACENT field first (>= CLUSTER_MIN 3 shops within CLUSTER_R 160m), then the kind flavors (pub corner / band_room fringe / rsl off-spine) bias WITHIN that field rather than overriding it (per the brief: biases, not absolutes) — a fringe band_room in the cluster beats one a kilometre from anyone. A town with no cluster at all falls back to the pool. - SYNTHETIC FROZEN BY CONSTRUCTION, not by luck. The brief assumed a blanket filter would be a no-op because 'the synthetic town is one dense cluster anyway'. Measurement says otherwise: 4 synthetic candidates PER SEED sit under the threshold (min cluster 0-1), so a blanket filter WOULD have moved the frozen golden. Gated on plan.source === 'osm' (undefined on synthetic) — impossible rather than unlikely. The marched fixtures are 'osm' but genuinely dense (min cluster 3/11/13) ⇒ verified no-op. - Only the GIG goldens moved (venue selection is gig-layer; base town goldens untouched): katoomba 0xbf586b77, newtown 0xacdb3eee, fremantle 0xcf3426fc, bendigo 0x646b2c23, castlemaine 0xf9713a69. classic 0x3fa36874 / gig 0xb1d48ea1 / marched fixtures FROZEN. selfcheck ALL GREEN 66419/66419; scaffold + consistency GREEN; cross-process deterministic. - FYI: E's v4.0 pack (glebe/marrickville/newcastle) already boots clean through my loader (validates + full suites pass), listed UNPINNED — I pin the pack in R22; it does not gate the beta tag. Handshake → C + D: cluster bias landed, goldens re-pinned, start your verifies (before/after table in LANE_A_NOTES §R21). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5d29863b78 |
Lane A round 20: absorb E's density widening — capacity, pub facade bias, goldens pinned (ledger #2)
E's five caches landed at 3-6x shops (292 total: katoomba 20→80, fremantle 21→80, newtown 18→72,
bendigo 9→36, castlemaine 6→24). All five absorb cleanly and still place 3 venues; the R20 poster cap
auto-scaled off the live shop count exactly as designed (katoomba 111 posters at 80 shops).
- CAPACITY WIDENED (the R18 overflow fence, load-tested). At 4x the dominant drop cause was OVERFLOW —
an edge-side holding more shops than fit (katoomba 10 of 11 drops). Tightened the run: NODE_CLEAR 6→3
and a ROADS-ONLY RGAP 2→0.5 (the shared marched GAP is untouched ⇒ marched fixtures stay frozen).
Drops 7.9% → 5.5% (16/292). 0.5m also reads truer — a real AU main street is continuous terrace
shopfronts, not detached boxes. Stopped there deliberately: the next lever (spilling overflow onto a
DIFFERENT street) buys ~1% by putting a shop on a road it isn't on — dropping a crowded shop is the
honest trade. Residual drops stay COUNTED, now BY CAUSE (dropped_overflow/_overlap/_stranded).
- VENUE FACADE BIAS NOW COVERS pub. R16 exempted pub ('spine-fronted, +Z always open') — true on the
synthetic/marched towns, but on a REAL graph at density the pub landed where its frontage poster
overhung a cross street (newtown, -0.91m). The POSTER_CLEAR filter now covers every venue kind; still a
NO-OP on synthetic (every pub candidate already clears) ⇒ gig golden 0xb1d48ea1 frozen.
- Goldens re-pinned ONCE (base + gig, all five towns). classic 0x3fa36874 / gig 0xb1d48ea1 / marched
fixtures FROZEN. selfcheck ALL GREEN 51866/51866; scaffold + consistency GREEN; cross-process
deterministic.
- Fixed: my real-cache loader globbed *.json and tried to validate E's new index.json as a town cache —
it now skips it (that's B's selector index, not a cache).
Handshake → all: densities absorbed, goldens pinned. → F: re-measure venue_night + gate the five towns.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
955ec3497b |
Lane A round 20: spine-poster cap scaled by shop count (v4.0-beta, ledger #1)
Closes my own R19 finding + F's one open budget edge. A sparse REAL town has few shops but a big edge graph, so the 'two posters per main edge' pole run reads busy (katoomba 438) and drove venue_night to 200,965 tris (+0.5% over the 200k soft ceiling). - gigs.js buildPosters caps the spine pole run at POSTER_PER_SHOP × shops (1.5/shop, floor 12) — a seeded subsample. SCALED BY SHOP COUNT, not edge count (the whole point). katoomba 438→31 posters (~2x the synthetic feel), fremantle 32, castlemaine 14. NO-OP on the shop-dense synthetic town (493 shops ⇒ cap ~740 ≫ its ~15 posters), so the synthetic gig golden 0xb1d48ea1 stays FROZEN. - Posters are gig-layer (withGigs), so the real-town BASE goldens are unchanged (correctly green). Added REAL_TOWN_GIG_GOLDENS (the full district+capped-poster plan per town: katoomba 0xbd332e83, …) to regression-guard the capped output byte-exact, not just via districtInvariants. classic/gig/marched fixtures frozen; selfcheck ALL GREEN 51675/51675; scaffold + consistency GREEN; cross-process deterministic. → F: re-measure venue_night, the +965 edge should close. Density absorb (ledger #2) pends E's widened caches — the poster cap already reads the live shop count, so it auto-scales to the widened towns. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6fc4b40632 |
Lane A round 19: the v4.0-alpha close — fragmentation ruling + findings hardened + goldens pinned
A's finalization (ledger #1), the round's spine. Every filed R18/R19 finding resolved; the tag is F's. - Fragmentation (D's finding; Fable ruled, A owns details). The naive real graph fragmented (katoomba 105 components, 58% street-metres on islands). plan_osm.buildRealRoads now: (a) JUNCTION-PROTECTED Douglas-Peucker — a point shared by >=2 ways is a junction; simplify only BETWEEN junctions, never through one (the collinear tee-off drop, the root cause) → 94-100% main-net alone; (b) cull/bridge — main component + near-fragments joined (JOIN_TOL 12m; shop-island bridge <=200m), far SHOPLESS islands culled. Result: 1 connected component on all 5 towns (katoomba 100% main-net, 2 islands culled). Every dropped shop COUNTED in norm.dropped (ruling): katoomba 19/20 (1 crowd drop — R18 overflow prediction measured), the other four kept all. - E's poster-clearance finding fixed (gigs.js): a spine poster overhanging a real crossing carriageway is skipped, measured exactly as the selfcheck kerb floor — a NO-OP on synthetic (gig golden frozen, pr() consumed before the check). 23 real-town clearance failures → 0. - Goldens pinned (A->E->A finalization): all 5 real towns on their real-roads output (katoomba 0xb7ffbca2, newtown 0x6f984c81, fremantle 0xfb197000, bendigo 0x21179b3b, castlemaine 0x7c47f639). synthetic 0x3fa36874 / gig 0xb1d48ea1 / marched fixtures / classic / default FROZEN — the alpha changed nothing outside the cache-schema path. selfcheck ALL GREEN 51670/51670; scaffold + consistency GREEN. Cross- process deterministic. - New finding filed (beta, non-blocking): spine-poster density scales with edges (katoomba 438 vs ~14 synthetic; draws low via instancing) → a beta posters-per-town cap. Handshake fired → B/C/D/F: katoomba_real boots real roads, golden pinned, findings resolved. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a78dc76f84 |
Lane A round 18: the real-graph lift — OSM ways → CityPlan street graph (v4.0-alpha REAL ROADS)
The epoch headline (ledger #2). A v2 cache's roads[] now builds the CityPlan street graph FROM real OSM geometry instead of marching shops onto synthetic avenues. SAME CityPlan schema out — B/C/D/F consume it unchanged by contract. roads absent ⇒ the v1 marched fallback, so classic/gig/osm goldens are FROZEN. plan_osm.buildRealRoads: project ways+shops to the local metre frame → simplify each way (Douglas-Peucker eps~6m, the fidelity knob) → snap coincident points (<=3m) to shared nodes = real intersections → straight-segment edges → classify main by OSM highway class + shop density → seat each shop on its NEAREST real edge (real order, real side), marched with regularised spacing + a deterministic overlap-resolve pass. Fidelity (charter risk #4): real edge/order/side + regularised spacing — NOT pixel positions (real shops overlap; the no-overlap invariant is load-bearing). Alpha failure list in LANE_A_NOTES §R18: overflow drop on short edges; intersections = shared-coordinates only (a D sim-graph risk); per-edge frontage-strip blocks not planar faces (a B ground-render item); crowded-intersection overlap-resolve. Proven: a committed synthetic irregular graph (main + two cross streets + a real intersection + an acute angle + a dead-end lane + a curve) passes the FULL structuralSuite + gig district + byte-identical determinism; mutation-tested non-vacuous (flip the facade facing → 'faces its frontEdge' fails). Robust on messy inputs (single road, coincident dups, disconnected ways, all-roads-too-short → marched). All osm goldens frozen; E's 4 trailing caches pinned on v1; katoomba_real UNPINNED (its real-roads golden pins when E lands roads — the A->E->A finalization). selfcheck ALL GREEN 16810/16810; scaffold + consistency GREEN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
6fffd19043 |
Lane A round 17: v3.2 the town-cache contract (published first) + plan_osm hardened for real data
The real-map scout (ledger #6), A's half. Scope fence held: NO new plan features, NO golden moved (classic 0x3fa36874, gig 0xb1d48ea1, all three osm fixtures frozen). The scout proves the EXISTING ?plansrc=osm contract eats real geography. - The town-cache contract (published FIRST — E builds build_towns.py to it). plan_osm.js gains validateTownCache() (authoritative {ok,errors,warnings}), registerTownCache(), a generatePlanOSM(.., {cache}) seam, and TOWN_CACHE_SCHEMA/MIN_TOWN_SHOPS(6)/MAX_TOWN_SPAN_M(5km). Shape: {schema,key,town, source,license,attribution,center{lat,lon},shops[{id,name,type,lat,lon,suburb?}]}. Home declared: web/assets/towns/<key>.json (+ README.md full spec). Documented in CITY_SPEC v3.2 + LANE_A_NOTES R17. - plan_osm hardened: blank name -> registry label; the validator gates finite center/coords + a >=6-shop floor and warns on unknown-type(->opshop)/dup-id/span>5km. Proven vs thriftgod's real 2,828-shop city_source.json: boots a valid plan, 0 bad coords, 0 'undefined' names. - selfcheck: a committed synthetic-adversarial contract suite (valid-messy caches boot + pass structural/ gig; invalid reject; wide-spread warns; registry seam) + an auto-loader for web/assets/towns/*.json (validate -> suites -> pin per-town golden), empty and green until E lands caches. ALL GREEN 15277/15277. - v4 charter risk list (LANE_A_NOTES R17): the MEGA-STRIP (unbounded bbox -> 11.6 km strip; town selection is E's real lever, warned >5km); sparse compact towns (2 km inner-Canberra held 6 shops); osm facades clear (rows 54 m apart) so R16's bias is a no-op on real towns. E->A handshake: E drops a cache in web/assets/towns/, the selfcheck prints its golden, I pin it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
2b13dd4ad7 |
Lane A round 16: v3.1 corner-poster clearance bias (#6) + no-spine osm fixture (#7)
Ledger #6 fix + the round's one sanctioned gig-golden re-pin, and ledger #7. Classic/synthetic golden 0x3fa36874 frozen (classic boot byte-identical across all seeds); base plan untouched. - Corner poster: the R15 finding (frontage poster near a crossing kerb) is NOT fixable by the brief's 'nudge along the facade' — proved the crossing edge is PARALLEL and spans the facade (0/187 slides help); band_room/rsl land on through-lots on narrow warehouse blocks whose +Z wall (B's door side) overlaps the block's other street by up to ~3 m. Surfaced to Fable; ruling: bias pickVenues. It now prefers a band_room/rsl candidate whose +Z facade clears every carriageway by >= POSTER_CLEAR (0.5 m), broadening off-spine if the fringe is uniformly narrow. Result: 0/851 frontage posters below floor across 400 seeds (worst 0.51 m); pub untouched (hero shot unmoved). - Gig golden re-pinned 0x4f4a549d -> 0xb1d48ea1 (posters moved). selfcheck's R15 blanket frontage exemption becomes a real floor: frontage >= POSTER_CLEAR, spine >= 0 (POSTER_CLEAR exported from the barrel). Mutation-tested non-vacuous. - No-spine osm fixture 'silverton' (single-row town, 0 main edges) proves pickVenues' no-spine branch + buildPosters' no-main fallback, closing the R14 sweep gap. Base golden pinned 0xd4b351c9; sweep asserts 0 main edges + graceful 2-4-venue placement. selfcheck ALL GREEN 14769/14769; scaffold + consistency GREEN. - CITY_SPEC v3 amended (golden, poster clearance-bias prose, no-spine note, recorded amendment). Left the prime-flag-law blockquote for F (the v3.1 classic-law + flags-table is F's amendment). For F: default-boot golden = 0xb1d48ea1; ?classic=1 target = 0x3fa36874. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
35da83c347 |
Lane A round 15: frontage poster +Z street-face flip (ledger #1) + gig golden re-pin
R14 review found every venue's own-frontage poster on the building's −Z BACK since R13 (~16 m behind the street face, B measured 15.9 m) — invisible from the street, why queue_night framed no poster. Ledger #1, A-first (B's hero re-shoot + F's tour hang off this). - gigs.js buildPosters item 1: flip to the +Z street facade (B's canon: buildings.js facade zf=+d/2 + venue.js door/queue/camera are +Z) AND ry=lot.ry+π so the printed face points +Z at the queue-side camera (else DoubleSide shows a mirrored band name). Proven: pub+rsl frontage posters now sit 0.06 m from B's door, printed-face·(+Z street)=1.000. Spine posters untouched. - Gig golden re-pinned 0x1f636349 → 0x4f4a549d (the round's ONE sanctioned move; posters moved). Synthetic golden 0x3fa36874 frozen. §v3 FROZEN marker records the amendment (amendment law). - selfcheck: the +Z facade is the block-interior side in plan coords, so corner venues (band_room/rsl fronting one street with another behind — seed 1 lot#481, 1.58 m from a crossing centreline) seat the frontage poster near that street. That's B's building geometry (the door is there too), not a mid-road defect — so the no-bitumen assert now EXEMPTS building-bound frontage posters, keeps it for spine posters. 400-seed sweep green again: 14264/14264. - CITY_SPEC §v3 amended (poster prose → +Z facade + ry+π; golden line; frontage/spine carriageway split; recorded amendment in the FROZEN marker). LANE_A_NOTES §R15 hands B/F the new golden + a corner-venue eyeball note. Convention settled: visible venue face is +Z; selfcheck's −Z 'faces frontEdge' is the sim/GLB convention (π-off the visual front, the R13 RY_FLIP ambiguity). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
a3911a4590 |
Lane A round 14: v3.0 release — 400-seed district invariant sweep + CITY_SPEC §v3 frozen
Release round: harden + freeze, no new systems. No golden moved (synthetic 0x3fa36874, gig
0x1f636349 both re-verified frozen); selfcheck.js is the only code touched, so no seeded generation
stream gained a draw (release-round law).
- selfcheck.js: factored the district checks out of gigSuite into districtInvariants(plan,label)
(behaviour-preserving — hero-seed gigSuite runs byte-identical), then added a 400-seed synthetic
sweep + the large edge seeds asserting the full district contract each (2-4 venues, >=1 pub, never
the openLate shop, no band twice/night town-wide, per-venue 4-6 nights, every poster off the
carriageway). Asserts the seeded count spans {2,3,4} across 400 seeds (146/121/133 — range is
exercised, not pinned). osm graceful placement: katoomba (19 shops, no warehouse district) still
lands 2-4 valid venues incl. a pub for every hero seed. Poster check kept at roadWidth/2 (a literal
poleOffset compare would false-fail corner posters); added -1e-6 epsilon on the strict boundary.
ALL GREEN 14264/14264 in ~0.7s.
- CITY_SPEC §v3: final wording pass, marked FROZEN at v3.0 (round 14) with a v2-style marker + an
explicit carve-out for F's pending alias-line deletion. Fixed the roadWidth prose (full carriageway
width, not 'half-corridor'). Genres final (pubrock/grunge/covers).
Coordination: the R12 single-venue alias line stays in §v3 for F to delete atomically with the
gig_state.js getters (debt #1) — deleting now would be doc-ahead-of-code (alias still live) and race F.
Flagged to F that the runtime block omits nightOf(id); to B that venue.js:228 is a 2nd bare-string
site. Verified: mutation-tested the sweep (non-vacuous — catches 5-venue/7-night/on-road violations)
+ adversarial pass (goldens frozen, freeze matches code, deterministic).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
6fba79a1cb |
Lane A round 13: v3.0-beta the district (?gigs=1) — 2–4 venues, week schedule, town-wide posters, verge fix
Publishes the multi-venue plan.gigs interface C/D/B/F hang off (half-day handshake, A first). - pickVenues: seeded 2–4 shops converted in place → pub (spine end) / band_room (warehouse fringe) / rsl (off-spine); 4th = 2nd pub at far end. Registry gains weight-0 band_room+rsl kinds + venueKind/genreKey/placement. Never the openLate landmark; osm-safe fallbacks. - gigKey contract (debt #1): gigKeyFor(genreKey) => 'gig-'+genreKey, the single exported genre→bed mapping. No table anywhere; F deletes the GIG_BED bridge. - plan.gigs goes district: 7 nights × every venue, each plays a seeded 4–6 (dark reads true); cover skewed by kind; no band plays two venues on one night; custom names spread night-major. - plan.posters goes town-wide: tonight's playing venues each get frontage + seeded spine run. - Verge fix (debt #5): new corridor law roadWidth/vergeBand/poleOffset(edge) in registry.js (road-vs-verge split of edge.width, published as functions ⇒ base goldens frozen). Posters seat on the verge, never bitumen; selfcheck asserts no poster on a carriageway. - registry pub.interior 'band_room'→'pub' (unread field; avoids collision with band_room type). Gig golden re-pinned 0xa6ae5a5e→0x1f636349 (multi-venue changed output; in-commit per amendment law). selfcheck ALL GREEN 3273/3273; scaffold_check + consistency GREEN; flags-off byte-identical. CITY_SPEC §v3.0-beta + LANE_A_NOTES §Round 13 updated in this commit. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
acf734a1e5 |
Lane A round 12: v3.0-alpha gig layer (?gigs=1) — venue, plan.gigs, band names, closing-time debt
Publishes the gig interface the whole round hangs off (A runs first). Everything is
behind ?gigs=1 as a POST-HOC augmentation (gigs.js withGigs, applied by the selector),
so generatePlan is untouched and all v2 goldens stay frozen (synthetic 0x3fa36874, osm
melbourne 0x34cfdec0, katoomba 0x0f652510). Source-agnostic (synthetic + osm).
- Venue: one 'pub' per town — a spine-end plain shop converted in place (keeps lot
id/geometry, enterable), shop.venue=true, never the openLate landmark. Registry gains
a weight-0 'pub' type (interior:'band_room' for Lane C) → never auto-placed → base
plan byte-identical.
- plan.gigs: 7 nightly {gigId,venueShopId,bandName,genreKey:'pubrock',night,startSeg:5,
endSeg:5,cover}; cover ~half free / half $2-$10 (F charges at the door).
- Band names: bandName(seed) generator (90s pub-rock) + OPTIONAL web/assets/custom_bands.json
drop-in (priority into the pool; absent → pure generator, no fetch under ?noassets).
- plan.posters: ~6 seeded {id,gigId,x,z,ry} for Lane B.
- Closing-time debt paid: isOpen(shopOrHours,hour) exported (half-open law as code, D consumes).
- map.html?gigs=1: venue ring + poster pins + gig panel line. Flags-off unchanged.
Self-check ALL GREEN 3074/3074 (gigSuite ×2 sources, flags-off≡base, gig golden
0xa6ae5a5e). qa.sh --strict GREEN 6/6. Verified in-browser both modes. CITY_SPEC v3
section + LANE_A_NOTES handshake for C/D/B/F. Atomic pathspec commit (shared-tree race).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
e5d4679471 |
Lane A round 9: freeze CityPlan v2 contract in CITY_SPEC + closing-time occupant ruling
Ship round. Docs + one selfcheck log-line only; no generator change ⇒ all three goldens unchanged (synthetic 0x3fa36874, osm/melbourne 0x34cfdec0, osm/katoomba 0x0f652510). 1. CITY_SPEC v2 contract FROZEN — new "CityPlan v2 — frozen producer contract" section: producer API, goldens table (keyed seed/plansrc/town) + how to pin a new one, town-key mechanism, osm normalization rules, hours/openLate/storeys laws. Matches code as shipped (F diffs claims vs code). Refreshed the stale round-6 Plan-sources blockquote to multi-town reality. Layer-1 changes now require a CITY_SPEC amendment + golden re-pin in the same commit. 2. Recipe sanity — DRY-RAN end-to-end: appended a throwaway Newtown (42 shops), selfcheck auto-ran the full parity suite (1931/1932, only golden unpinned) and printed a paste-ready `newtown: 0x9045e577,`. Reverted; no 3rd town shipped. Added the selfcheck `⚠ UNPINNED — add to OSM_GOLDENS` line so the recipe is mechanical; fixed the recipe wording to match. 3. Closing-time occupant ruling (D's on-call Q) — ratifies + freezes what D's sim.js already does: half-open hours, no new entry when closed, occupants DRAIN (finish bounded dwell) never popped, player not force-ejected, openLate video is the night crowd. In CITY_SPEC + LANE_A_NOTES. No code change asked of D. qa.sh --strict GREEN; selfcheck 1727/1727. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
f952f513d0 |
Lane A round 8: OSM to parity + a second town (Katoomba) — carried R7 brief, full
The carried brief (slipped R7) lands complete — all four items, qa.sh --strict GREEN.
1. Selfcheck PARITY: extracted structuralSuite(plan,label) and run the FULL invariant suite
on every (source, town) — synthetic + both OSM towns get identical coverage (storeys,
one-shop-per-lot, facing, within/cross-block overlap, corridor coverage, determinism,
exactly-one-openLate). ALL GREEN 1727/1727 (was 1362; OSM went subset → full ×2 towns).
2. SECOND TOWN: Katoomba (Blue Mountains, 19 shops, op-shop/book heavy) — regional contrast
to inner-Melbourne. osm_fixture.js → OSM_TOWNS{melbourne,katoomba}+DEFAULT_TOWN;
generatePlanFor(seed, source, {town}); ?plansrc=osm&town=katoomba. Golden 0x0f652510.
Melbourne 0x34cfdec0 + synthetic 0x3fa36874 UNCHANGED (town key kept off the plan).
3. "Add a town" recipe in LANE_A_NOTES (R8): extract → OSM_TOWNS → pin golden → tell F.
4. Normalization + LOG: importer bends real data to the contracts (unknown kind→opshop,
hours-clamp so only one shop is openLate, video-preferred landmark w/ fallback) and logs
it via {report}; selfcheck prints per-town (e.g. melbourne hoursClamped:5, openLate:video).
For F: three goldens to pin, gate keyed (seed, plansrc, town); selector gained {town} — see
LANE_A_NOTES R8. Screenshots docs/shots/laneA/osm-{melbourne,katoomba}.png.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
52eb1090ef |
Lane A round 6: second plan source ?plansrc=osm (real-data OSM import) — full seam
The carried-over OSM plan source (no-showed R4–R5) lands complete, invariants green — a second CityPlan producer behind the same contract, so B–F consume it unchanged. - osm_fixture.js: 95 REAL inner-Melbourne secondhand/charity/music/book/toy/antique shops, extracted deterministically from thriftgod city_source.json (Overpass cache), imported as a module ⇒ ZERO network. - plan_osm.js: generatePlanOSM(seed) — project lat/lon→metres, bin shops into latitude-band avenues off a spine (real row + real E–W order preserved), march into a valid non-overlapping CityPlan, centre on origin, report true 362×486 bbox, real shop names, one openLate video. - index.js: generatePlanFor(seed, source) selector — default 'synthetic' BYTE-IDENTICAL (golden 0x3fa36874 untouched); 'osm' → the importer. generatePlanOSM exported for F. - selfcheck.js: parameterized by source — OSM runs the full structural invariant suite (frontEdge/facing/no-overlap/chunk-coverage/finite/JSON/determinism/openLate) + its own golden 0x34cfdec0; synthetic-only brief checks skipped. ALL GREEN 1362/1362. - map.html: ?plansrc=osm renders it (reference wiring for F). Screenshot in docs/shots/laneA/. - CITY_SPEC: plan-source note; LANE_A_NOTES R6: seam + goldens + shape-diffs for F's gate (F2). Honest cut: street geometry regularized (real row+order drive it, exact metres do not); name-parody deferred. qa.sh --strict GREEN. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
5b8c806271 |
Lane A round 4: harden openLate contract (hours>=22 ⟺ openLate == the video), confirm F2
v1-tag round. Two confirmations + one hardening fix; qa.sh --strict GREEN (4/4).
A2 — openLate: F's night gate `hours[1] >= 22` matched 4–15 shops/seed (regular videos
jitter base-21 → 22), not the single landmark the shell assumes. Fixed in plan.js: regular
shops close by LATE_HOUR-1 (21:00); only the deterministically chosen openLate landmark
reaches ≥22, pick is now video-first. So `hours[1] >= 22` and the `openLate` field are the
same singleton, always the video rental (verified 15 seeds). Makes generation match
web/index.html:159-161 + soak.py:68 ("at night only the openLate shop is open"). selfcheck
asserts exactly-one / field⟺threshold / is-video. ALL GREEN 1301/1301.
A1 — Lane F's F2 permittedMax storeys scoping: confirmed 0 warnings across 7 seeds + a
false-negative test (injected video@2 in a scratch checker → caught every seed).
GOLDEN.hash 0x098eec2b → 0x3fa36874: intended A2 output change (a few videos close 21 not
22 for seed 20261990), NOT drift; F2 is tooling-only. Same lots/shops/types/names/skins.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
b20b3b08f5 |
Lane A round 3: verify F finding #5 (storeys) stale, harden selfcheck + document corner-anchor rule
Per ROUND3_INSTRUCTIONS 'Lane A — on-call + one verification': - F finding #5 (shops with storeys outside registry range) verified STALE across 8 seeds: zero violations. Single-storey types (video/milkbar/stall) never exceed 1; the only shops above registry max are the intentional 3-storey corner anchors (tall-capable types), exactly per CITY_SPEC. Round-1 cornerBoost gate already prevents the reported bug. This is also the source of qa.sh's 5 benign storeys warnings (flagged for Lane F to scope to permittedMax). - Hardened the selfcheck storeys assertion from the too-lax <=max(mx,3) to the exact permitted range (max>=2 ? min(max+1,3) : max), so a single-storey type exceeding 1 now fails loudly. Proven non-vacuous. selfcheck.js only — plan output/fingerprint unchanged (golden 0x098eec2b still matches, confirmed per task 2). - Documented the storeys corner-anchor rule in the CITY_SPEC schema. - hours/openLate contract unchanged; ready for Lane F's §3.5 consumer. qa.sh --strict GREEN (4/4). Committed atomically by pathspec (shared-tree race). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> |
||
|
|
3e98f05a52 |
Lane A: flag commit-4235060 mislabel for Fable (shared-tree race note)
My round-2 Lane A changes were committed under Lane C's message (
|
||
|
|
42350607a0 |
Lane C: keeper stand pose on the counter contract (Lane D/F integration)
Answers Lane F §8 (the counter is kind:'counter' in `places`) and closes the
keeper-spawn gap: buildInterior now returns room.counter = { mesh, pose, stand }
and tags the counter interactable with userData.keeperStand. `stand` = {x,z,ry}
where a shopkeeper stands (service side, facing the customer), in room-local
space, rig-front = local -Z per keepers.js. Deterministic; purely additive.
Verified in-browser: 36-build type sweep + 50-room soak — stand in-bounds,
faces customer (dot>0 all), carried on `places` (deep-equal), deterministic;
no change to existing placement, path, leaks, or perf (avg 3.6ms / worst 7.7ms,
geo/tex leak 0).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
||
|
|
8b7ca9aae4 |
Lane A (CityGen): deterministic town generator, registry, names, 2D map, self-check
Layer-1 CityPlan generator per CITY_SPEC schema v1 — pure data, no THREE, all randomness
through core/prng, deterministic + JSON-serializable + <1ms.
- web/js/citygen/plan.js: generatePlan(citySeed) → CityPlan (spine, cross-streets, market
square + dept anchor, arcade, warehouse fringe, residential collar w/ corner milkbars,
laneways) + chunkIndex (Amanatides–Woo edge supercover) + corner overlap-resolution pass.
- web/js/core/registry.js: SHOP_TYPES (all 9) + district weights + enums (shared vocabulary).
- web/js/citygen/names.js + wordlists.js: seeded 90s-AU shop/town names, 50+ patterns.
- web/js/citygen/index.js: canonical barrel entry (adopts Lane F's integration shim).
- web/map.html: standalone Canvas-2D plan debugger (pan/zoom/hover, layers, export JSON).
- web/js/citygen/selfcheck.js: node acceptance harness — determinism, golden fingerprint,
facing, within- AND cross-block no-overlap, chunk+edge coverage, finiteness, assets. ALL GREEN
(1271/1271) over 6 seeds. web/package.json ({"type":"module"}) lets node run it.
- docs/shots/laneA/: 5 seeds screenshotted, each reads as a town.
Fixes from an adversarial multi-agent review (15 confirmed defects): market facades faced the
wrong way; cross-block corner overlaps; chunkIndex skipped chunks incl. the origin/spine;
stall frontEdge z-band; doubled-possessive names; unparseable map road colour; +others.
CITY_SPEC amendment (treaty, same commit): shop-types table aligned to the registry lanes
import; documented lot.ry/frontEdge, block.kind/district-id, and web/package.json.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|