Commit Graph

314 Commits

Author SHA1 Message Date
m3ultra
4514cb94b5 Lane B R38 (v8 WAVE 1, INHABITATION): all four runtime items — the whole round costs +1 walked draw
The town is inhabited: 23 towns finally differ, 181 back yards have a Hills Hoist with washing on it,
a magpie owns one street for six weeks of the year, and six point sources put a life off-screen.

MEASURED, walked, not bookmarked — two port-isolated no-store servers (:8472 = `git archive HEAD`,
:8471 = treatment, assets symlinked so E's mid-round wave is identical on both sides), 102 8-metre
spine steps at yaw 0, each frame fully streamed, through the shell's own composer:

  worst draws  224 -> 225   (+1)
  worst tris   89,502 -> 93,298   (+3,796 of ~75k spare)
  sum draws over 102 frames  16,676 -> 16,663   (-13)

The citizen sim and the tram are hidden identically on both sides, and that IS the measurement: with
them live the same step read control 346 vs treatment 232, because peds spawn on wall-clock time.
`?yards=0` reproduces HEAD exactly (224 / 89,502 / 16,676). Isolated at a fixed pose: washing +1 draw
/ +512 tris, magpie +1 draw / +182 tris, every yard box prop +0 draws.

§1.2 THE CHARACTER VECTOR — +0 draws, +0 tris, classic byte-identical BY CONSTRUCTION.
`townCharacter(null)` returns the frozen v1 literals and a null tint keeps the SAME material cache key,
so classic gets the same object, not a copy of it: default-boot ground hashes identical to HEAD
mesh-for-mesh, `?classic=1` hashes unmoved from R37. There is no `if (classic)` in the ground path.
The sky feeds the BASE skyName, never `setSky` (a one-way latch that would have killed R32's dawn dome
on all 23 towns). The vacuous arm is per-town: `newtown_godverse` / `redhill_godverse` carry `state: ''`,
so a per-corpus arm would have dropped exactly those two silently. 21 distinct palettes across 23 towns.
`gravel` and `reddust` were not unwired but UNWIREABLE — their `use` values named no slot ground.js had;
making the slot addressable fixed it at the root, and both are selected now. E's three new grounds
landed mid-round and the upgrade was a name change in one table, which is what procedural-first is for.

§1.4 BACKYARD AUSTRALIA — inside boxMats, +0 draws. Houses inset off their boundaries so there is a
yard; 36 `yard` lots that had rendered as blank shopfront sheds since v1 are now fenced blocks with a
hoist, a shed and often a tank. Collision byte-identical (the lot rect is where the fence stands).

THE WASHING SHIPS, and I wrote the inverted weight rather than dropping it. The shipped top-weighted
mode moves a hem 0.10 cm calm / 0.67 cm gusty; `pegged` gives 4.5 cm / 31 cm — ~52x, and at the hem
instead of the pegs. The `canopy` string is byte-for-byte unchanged, so the gum-tree covenant argument
is untouched. It is ONE TOWN-WIDE InstancedMesh (1 draw at any N, cap 256, proximity-first off the R37
chunk seam) rather than per-chunk, which would have been +1 x 31 live chunks = 4x the whole margin.
Zero on every real town (no hoists ⇒ no mesh) and zero at night.

§1.3 THE MAGPIE — +1 draw on screen, exactly 0 otherwise; 182 tris of 900. Territory scales with the
road graph: 6 on the 6.78 km synthetic town, 157 on bendigo's 188.6 km / 2,593 edges, nearest 120 m
from spawn. The latch sets, the day roll clears it, localStorage gains no key and the save never
mentions it. `swoopPos()` is exported and pure. The hat stays cut.

MY OWN SEASON MECHANISM WAS VACUOUS AND THE SWEEP CAUGHT IT: keyed on citySeed alone it produced a
CONSTANT, because the town key is deliberately off the plan — 24 of 24 towns were 214 days from
swooping season, and it would have gated green because `?magpie=1` forces it. Re-keyed on
(citySeed, townKey): `newtown_real` is in season on arrival on the default seed, marrickville is 8 days
out, and 12.9% of 1,000 seeds put the synthetic default in season against a design ratio of 11.5%.

§1.1 THE AUDIO LAYER — six new mixer layers, zero draws, zero tris, seeded anchors, distance falloff,
AND A StereoPannerNode PER LAYER, so direction is real (measured spread -0.71..+0.85) instead of a
limitation written into the notes. Day-of-week derived locally. All six anchored on the default boot;
3 of 6 report `no-anchor` on real towns rather than being faked onto shopfronts. The falsifiability
control — one manifest key renamed away, served from a third port — makes that source report
`no-entry`, 0 plays, never `audible`, with the other five unchanged and zero console errors.

TWO DEFECTS MY OWN GREEN NUMBERS COULD NOT SEE, both caught by a screenshot: the washing shipped at 256
instances / +1 draw / cap respected and was INVISIBLE behind its own back fence (per-instance peg height,
and a fence taller than the hoist), and the magpie perched on THIN AIR over the road. R37's lesson
relearned at full price. Fence 1.60 / hoist 2.15 measured against the object; territories now snap to
furniture.js's own streetlight rule.

LANE E'S PROPS, ADJUDICATED: hoist + aerial permanently primitive (E's spike killed them, and primitive
is also the +0-draw mechanism). `paling_fence` at 1,121 tris x 905 runs = 1.01M triangles — no. The
`magpie` GLB is HELD FOR THE TINT: it reads as a crow, and a magpie seen for 1.2 s in peripheral vision
IS its white bar. My 182-tri bird already carries it, at a fifth of the triangles and no fetch.
furniture.js's "novelty_record is 26.5k tris" was stale by six epochs — corrected to 8,000.

Zero fetch delta: `?noassets=1` fetches the same 23 assets, same list, on HEAD and on R38.
0 console errors on 10 boots (default, classic, yards=0, washing=0&magpie=0&ambient=0, noassets,
magpie=1, darwin, hobart, bendigo, the patched-manifest control) beyond the known PointerLock ones.

Shots: docs/shots/laneB_r38/. Detail + every number: LANE_B_NOTES §38.
2026-08-03 18:53:26 +10:00
m3ultra
1568c9b62b Lane E R38 (v8 wave 1): the asset wave — trellis2_mlx swap verified 1.92x, six sounds, four grounds, and the thin-structure answer
A. PIPELINE FIX: gen_props.py trellis_mac -> trellis2_mlx, contract read from its
   manifest.json. The two operators are NOT drop-in on output — trellis2_mlx writes
   BOTH candidate.glb (raw) and candidate_pbr.glb (baked), so the old
   sorted(rglob('*.glb'))[0] would have silently shipped untextured meshes. Added
   _pick_glb() (result.json first) + the bg_remove_local cutout stage, fail-soft.
   MEASURED: median 128.0s vs trellis_mac's 245.4s p50 = 1.92x. 5/5 first attempt,
   0 retries against the 4-5% budget. One 489s tail outlier, no error — named.

B. AUDIO (1.1) — six PACK entries, +0.86MB, ZERO draws/tris, all originalby
   construction: dog-bark-fence, mower-distant, radio-through-window, sprinkler,
   roller-door, magpie-carol. Seeded via crc32(name); beds fold seamlessly
   (wrap-jump <=0.18x internal step). Verified by spectrogram + band-energy, and
   one defect found by LOOKING: the sprinkler's spray masked its own ticks and read
   as a hose — rebalanced and re-rendered. Distance is spent in the SPECTRUM, not
   the level, because encode()'s loudnorm undoes a quiet render.

C. GROUNDS (1.2) — gen_skins.py had NO ground template; added one with its own
   outdoor style prefix (the house STYLE says "warm fluorescent", an interior cue).
   4 new 512^2 square tiles. Review's 5.7s is 9.7s here — same per-pixel, mine are
   1.78x the pixels. Found: gravel/reddust are selected by nothing partly because
   their `use` values name no slot ground.js:177 has.

D. MESHES — 3 shipped (magpie 894 tris, paling_fence 1121, water_tank 500), all
   GLB-law clean. 2 FAILED and were DELETED: hills_hoist + tv_aerial. Thin wire
   returns as thousands of disconnected fragments, so collapse floors at 250k/89k
   AND a remesh coarse enough for 600 tris erases the pole. Lane B's boxMats
   primitives cost +0 draws and are strictly better. The magpie's geometry passes
   but TRELLIS crushed its white nape/wing to black — traced to the operator's bake
   (the cutout and our decimation are both exonerated); flagged, not hidden.

E. REUSE — all 9 idle assets re-measured; the review's "one line each" holds for
   only 5. furniture.js's extractGLB keeps only the FIRST material, so park_bench/
   coffee_table/box_crate render in material #1 and bench_wood (0 materials) falls
   to grey. Nothing was regenerated that already existed.

The 3 GLBs are staged, NOT published: a depot push is outward-facing and had no
in-session authorization. Held at _r38_results.PENDING_PUBLISH.json; publish +
rename + rebuild lands them. Gate green: validate_manifest 0 errors / 0 warnings.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 18:30:33 +10:00
m3ultra
6bc7926637 Fable (integrator): round-38 instructions — v8 WAVE 1, INHABITATION (audio layer, 23-town character, the magpie, backyard Australia)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 17:49:28 +10:00
m3ultra
e8d4b51c4f Fable (integrator): ROUND 37 CLOSED — v8 wave 0, the floor is level; 14 posters out of the road at +0 draws, two vacuous gates dead, the budget pinned
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 17:43:45 +10:00
m3ultra
b6df11dfd6 Lane F R37 (v8 wave 0, CLOSE): the round gate — QA GREEN 7/0/0/0, flags harness 0 fails / 0 warns, MATRIX GREEN 10 towns x 7 gates
qa.sh --strict --matrix on the true final tree (Lane A e4d7762 + Lane B 47db478/79177bc + Fable
7bd96e5/4a7c0f1 + F 2396885/6afd1ed/f522021), port-isolated on :8975.

  SUMMARY  7 passed · 0 failed · 0 warn · 0 skipped — QA GREEN

  selfcheck   ALL GREEN 157,407/157,407 (was 156,352 — Lane A's +1,055 poster-clearance
              assertions, three arms, all green on the ruled street)
  manifest    0 errors / 0 warnings; atlas-QA 15 atlases, 15 licence lines shown; depot live
  flags       0 fails / 0 WARNS
                classic  fp 0x5f76e76 · dig INERT at the bin · gig layer wholly absent ·
                         162 draws / 16,642 tris · fetch surface CLEAN against v2.1 (125 requests:
                         68 code, 52 same-origin v2.1 assets, 4 depot, 1 NAMED EXCEPTION printed) ·
                         allow-list control fired (2 injected -> 2 named violations)
                default  four flags on · 14 gigs / 14 posters / venue geo / tram · gig golden
                         0xec7a2d39 · 131 draws / 23,382 tris @ venue block · dig REACHABLE naked
                kerb     all six arms green, control at EXACTLY 14 under ?verge=0
                tram     all arms + BOTH controls green
                R11-R36  audio, gigs, continuity, glance, the R30-35 game gates, djdance, real
                         crate, tier-2 kill-the-server: all re-green on the ruled street
  fig-scale   29 figs across 6 shops in [1.4,2.0] m incl. the R36 DJ-body leg
  matrix      GREEN, 10 towns x 7 gates; every town byte-equal on re-boot; 0 fetches under
              ?noassets across all ten; tram verdicts unchanged (fenced on bendigo, fremantle,
              katoomba_real — the same three the rebuilt smoke_tram uses for its absence arm)

One caveat kept in the notes rather than buried, so this round's central finding is not undone by
its own suite: the matrix's budget column (69-161 draws) is DBG.shot('venue_night') CLEAN-LOAD
BOOKMARK numbers, and 37.1 is the proof that a bookmark under-reports a walked-and-turned frame by
~120 draws. That column is a regression signal, not the budget of record. Making the matrix
walk-and-turn every town is a real improvement and a real cost — FILED TO THE v8 DEBT LEDGER, not
smuggled into a floor round.

NO TAG. Wave 0 levels the floor; it does not ship a version.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 17:42:08 +10:00
m3ultra
f522021765 Lane F R37 (v8 wave 0, 0.1 F-half): THE KERB GATE — poster clearance measured on the PAINT, and the ?verge=0 control fires at exactly 14
New STRICT smoke_kerb. Lane A's corrected selfcheck asks the plan-side question (is the poster's
offset inside vergeBand(e)[0]?) -- right for A's file, but it still reads no number that came from
Lane B, which is the precise failure that made the old gate vacuous. So F asks the runtime question,
of the paint: RAYCAST STRAIGHT DOWN AT EVERY RENDERED POSTER AND CLASSIFY THE TOPMOST GROUND HIT.

Classification is by MATERIAL IDENTITY -- skins.groundMat() is a cached factory, so the road mesh's
material IS the object groundMat('djsim-road') returns. No mesh names, no string matching, nothing
that drifts when B edits ground.js. Topmost rather than first, deliberately: B put the carriageway on
top at junctions (ROAD_Y 0 -> 0.04) so roads run through intersections, and what the player sees
under a poster is the top surface.

Six arms, all green on the final tree:
  subject          14 posters rendered == 14 in plan.posters, every one within 0 m of its planned
                   position, read off the real venue-posters InstancedMesh matrices. Nobody had ever
                   asserted that the poster you see is the poster A placed. Zero posters => FAIL.
  detector ctl A   the centreline of the longest main (main@28 m, 137.5 m) classifies ROAD at y 0.04
  detector ctl B   13 m off it (1 m inboard of the corridor edge) classifies FOOTPATH at y 0.02
  THE RULING       0 of 14 posters stand on road paint -- tally {djsim-footpath: 14}
  THE CONTROL      the same leg under ?verge=0 FAILS at EXACTLY 14 -- tally {djsim-road: 14}.
                   Keyed to B's flag, never to a line number, matching A's discipline.
  classic          13 m off the centreline is still ROAD under ?classic=1 and classic renders 0
                   posters -- Fable's CLASSIC KEEPS ITS PAINT ruling holds.

The two detector controls are the load-bearing part: "0 posters on road" is a sentence about nothing
unless the classifier is shown to say road AND footpath on the same boot.

TWO LANES, TWO INDEPENDENT METHODS, THE SAME NUMBER: A counted 14 plan-side by offset in node over
the plan; F counted 14 paint-side by raycast in the browser over B's geometry. Both flip to 0 on the
default boot.

Also lands Fable's ruling on classic's post-v2 fetch delta (4a7c0f1) in the mechanism. The audio pack
is RATIFIED BASELINE -- v2.1 was v2's final tagged state -- so the allow-list authority moves
v2.0 -> v2.1. Git makes that surgical rather than generous: `git diff v2.0 v2.1 -- web/` is the audio
pack, js/world/audio.js and four wiring edits; zero other assets, zero deletions. So the tag change
admits precisely the five ratified files and nothing else, and the depot GLB names survive in v2.1's
manifest unchanged (verified: same-origin baseline 47 -> 52, exceptions 2 -> 1, control still
discriminating). assets/towns/index.json is NOT baseline and now prints every run as
"EXCEPTION (NOT v2.1 baseline)" with its provenance, so it can never read as covenant.

README: the ?verge=0 row now carries A's corrected band figures rather than the charter headline --
9 m is the synthetic 28 m main only; a real main is 24 m => 7 m, and side@12, 72% of the corpus, is
3 m.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 17:30:59 +10:00
m3ultra
4a7c0f1295 Fable (integrator): budget PINNED 292/124,793 (the 280-vs-191 split was camera bearing) + ruling on classic's post-v2 fetch delta; stale numbers corrected in Fable-owned docs
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 17:22:59 +10:00
m3ultra
6afd1ed7a3 Lane F R37 (v8 wave 0, 0.3): THE BUDGET OF RECORD SETTLED — 292 draws / 124,793 tris, and the 280-vs-191 fight was about the CAMERA BEARING
Two sessions disagreed by 90 draws and neither was wrong. Worst draw per BEARING, 12 bearings x
102 stations down the same spine, one tree, one box: 0deg 284 · 30deg 248 · 60deg 208 · 90deg 177 ·
120deg 196 · 150deg 214 · 180deg 211 · 210deg 207 · 240deg 178 · 270deg 182 · 300deg 223 ·
330deg 267. 110 draws of spread from the camera direction alone, on identical positions -- and the
peak sits at yaw 0, the DEFAULT ARGUMENT of DBG.teleport(x, z, ry = 0). The city-patterns audit
took the default and landed on the worst bearing (280, reproduced at 282-292); the animal spike
supplied a yaw and landed mid-range (191, reproduced at 205-215). Correct numbers, different
quantities. Lane B's independent R37 walk (276 draws / 99,880 tris) and mine (282 / 99,878) agree
on TRIANGLES TO 2 -- the same frame through two harnesses.

THE PIN, default boot, synthetic golden seed, tree 7bd96e5, walked the spine:
  292 draws of 300 (NIGHT, 31 live chunks -- the R+1 dispose window at maximum)
  120,145 tris on synthetic; 124,793 on fitzroy_real, the corpus worst
  ?classic=1: 269 draws / 90,580 tris
  margin: EIGHT draws (the audit said "about twenty") and ~75k tris
The worst-draw frame and the worst-tri frame are NOT the same frame. Real towns are draw-cheap and
tri-dear; the synthetic town is the opposite. The audit's "99k-124k" tri range is confirmed and
pinned at its top.

Also measured: viewport is IRRELEVANT (1280x720 and 2560x1440 identical to the byte -- culling is
frustum-shaped, not pixel-shaped) · the R+1 dispose residue is worth +19 draws, not the 60-80
folklore (the rest is place and bearing) · CitizenSim's per-frame rig-acquisition budget means any
one-render-per-station sampler photographs a half-dressed street · ?r=3 measures 307 draws and
BREACHES the 300 gate through an ungated override (filed, not fixed) · ?shadows=1 costs +38 draws
and +38% tris · Lane B's kerb change independently confirmed at +0 draws / -8 tris at the worst
frame, by a harness B did not write.

THE SHARED INSTANCE CAP: 256, one InstancedMesh, town-wide. Measured +1 draw at every N from 32 to
2048, and N x tris/instance ALWAYS submitted (the instance bounding sphere spans the town). Draws
are not the constraint; triangles are. 256 x a 2-4 tri cell = 512-1,024 tris = 0.5% of budget;
0.01 ms/frame to rewrite every matrix. Binding companions: <=24 tris/instance at the cap, and spend
it PROXIMITY-FIRST -- anchor supply runs from synthetic's 246 poles over 6.8 km to bendigo_real's
7,325 over 188 km, so 256 sprayed town-wide there is one instance per 730 m.

Honest limit stated where the number is quoted: headless SwiftShader cannot change a draw or
triangle count (both are counted in JS, and the viewport control proves it), but frame TIME remains
unmeasured on any real GPU and no v8 proposal may claim a millisecond figure.

Re-pinned in LANE_F_NOTES 37; the four other docs that assert the number are flagged with what each
line should now say rather than edited in another author's file. README flags table gains ?verge=0
(Lane B's control, F's file) and a row naming the ?r=3 breach.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 17:19:24 +10:00
m3ultra
23968856dc Lane F R37 (v8 wave 0, 0.2 + 0.5): the vacuous tram gate rebuilt; classic_regression gets a git-derived network allow-list
0.2 — smoke_tram was ONE assertion (`!!getObjectByName('tram')`), a printed SKIP + early return
on absence, and it PASSED ON THE FENCED PATH because tram.js:110-114 adds a named EMPTY group.
Rebuilt STRICT, four arms + both controls demonstrated every run: RUNS (route/stops/metres, and
the body measurably moves under the SHELL'S own rAF loop) · BEHAVES (an isolated tram on a
throwaway scene, fixed dt: traverses, dwell time accounts to exactly dwells x 3.5 s, max cruising
tick <= SPEED*dt, every discontinuity bounded by 2*LANE with >=1 end reversal, and it rides
3.2 m off Lane A's OWN main-edge centreline) · GENUINELY ABSENT on the fenced katoomba_real
(fenced verdict, 0 stops, 0 group children, 0 m moved) · OFF under ?tram=0 and ?classic=1.
CONTROL A points the run-predicate at the fenced town and CONTROL B points the absence-predicate
at the running tram; both must go red or the gate fails. A missing subject now FAILS.

0.5 — classic_regression made no network assertion at all for 21 rounds, which is why R36's
fetch-surface widening needed a brand-new smoke. It now watches the wire from before the first
byte, with the allow-list DERIVED FROM THE v2.0 TAG at gate time (git ls-tree + the v2.0
manifest), never a deny-list. The four v2-era depot street GLBs and the five record-shop fittings
are BASELINE and admitted by provenance, not by exception. Same-origin is NOT a free pass -- the
R36 breach WAS same-origin, so /models/peds is enumerated by the v2.0 tree (exactly the
covenanted 21 files). Anti-vacuous: a required v2 core must be observed or the clean verdict is
refused. CONTROL, run every time: injecting the R36 breach itself (models/peds/woman_dj_01.glb)
plus a never-existed asset turns the clean verdict into exactly 2 violations.

Measured and carried, not fixed here: booting the actual v2.0 tree and diffing its fetch surface
against today's ?classic=1 shows a POST-v2.0 delta -- 5 audio files (R11 f7dd44f) and
assets/towns/index.json (R20/R21). Allowed on the list so the suite is not permanently yellow
over 26 rounds of shipped behaviour, printed every run so it cannot go invisible. Fable's to
ratify or retire.

Also: tools/qa/budget_walk.py (R37 0.3, the measurement rig -- continuous-motion walk through the
real rAF loop, bearing sweep, dwell, and a stepwalk that reproduces the audit's method) and
`flags_check.py --only` for single-gate development runs, which prints a PARTIAL banner so a
subset can never be read as a suite verdict.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 16:54:23 +10:00
m3ultra
7bd96e57fc Fable (integrator): mid-round ruling — CLASSIC KEEPS ITS PAINT (R27 doesn't apply: no gig layer under classic means no posters means no defect to preserve)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 16:45:40 +10:00
m3ultra
79177bc77c Lane B R37 notes: LANE_B_NOTES §37 + B-progress — the kerb ruling measured, the junction defect recorded, the chunk seam diagnosed
The measurement tables (+0 draws at every walked step on two towns, tris DOWN not up, the
raycast surface table, the ?verge=0 and classic hash pairs, the §0.4 hook proofs), plus
three things worth keeping:
 - the defect my own numbers could not see (every intersection painted shut; all metrics
   green, only the picture wrong) and why ?verge=0 + a screenshot caught it;
 - a full-frame pixel A/B is not an A/B while a live sim is in the frame — hiding
   everything but `ground` is what made the classic covenant measurable;
 - the market plaza reads worse under the wider footpath, and that is the STANDING item
   awaiting John's amendment, not new damage from §0.1.
2026-08-03 16:42:48 +10:00
m3ultra
47db478a51 Lane B R37 (v8 wave 0 §0.1 + §0.4): THE KERB IS FOOTPATH — +0 draws, tris DOWN; the chunk seam is subscribable at last
§0.1 — ground.js adopts Lane A's corridor law. The road quad narrows from the whole
corridor to the carriageway and the EXISTING merged footGeos class extends inward to
meet it, consuming `vergeBand(e)[0]` (not `roadWidth/2` — per A's mid-round correction,
so the geometry and A's corrected gate read the same number).

MEASURED, fresh boots, port-isolated no-store servers (:8178 = HEAD control, :8177 =
treatment), 2560x1440:
  synthetic     ground 5 draws / 224 tris -> 5 draws / 216 tris
                walked spine, 102 steps @ 8 m: worst 276 draws BOTH; sum of draws
                20,081 BOTH (identical at every step); 8 bookmarks identical draws
  katoomba_real ground 4 draws / 9,932 tris -> 4 draws / 9,644 tris
                walk 120 steps: worst 100 draws BOTH; sum 7,703 BOTH
+0 draws is proven, not asserted. Tris go DOWN (-8 / -288): the charter's "~2k tris" was
an estimate against a class that already existed. Honest number, stated loudly.

Surfaces verified by RAYCAST, not by reading the code (offset from centreline, topmost hit):
  main@28  road 0-4.75 | kerb 5 | footpath 5.25-17.5     (band [5,14])
  main@24  road 0-5    | footpath 5.25-15.25             (band [5,12], real)
  side@12  road 0-3    | footpath 3.25-9.5               (band [3,6] — 72% of the corpus)
  lane@8   road 0-4    | footpath 4.25-9   DEGENERATE band [4,4] => pre-ruling geometry
  lane@4   road 0-1.75 | kerb 2 | footpath 2.25-5.25     (synthetic, also unchanged)
  arcade   footpath 0-6.5, NO road quad, NO kerbs        (1,102 corpus edges)
  RESIDENTIAL side@14  road 0-2.75 | kerb 3 | GRASS 3.25-6.75 | footpath 7-10.5
The lane case branches on `outer <= inner`, never on a band literal.

Posters: 14 of 14 stood inside painted bitumen before; 0 of 14 after. Not one poster moved
— the ground did.

ONE DEFECT FOUND AND FIXED IN THE ROUND. The first cut painted every intersection shut:
a 12.5 m footpath crosses the perpendicular CARRIAGEWAY where a 3.5 m one only ever
clipped a far corner. Screenshotted, rejected, and fixed by putting the carriageway on
top (ROAD_Y 0 -> 0.04 under the flag): roads run through junctions, footpaths stop at the
kerb they meet. Verified on the real graph's worst 4.3-degree junction.

?verge=0 ships permanently — the gate's falsifiability control. Proven EXACT, not merely
similar: ground vertex+uv hashes identical to the HEAD build (c4c72181 / c111d968 /
1a80ebcd / 12c1241b / fd0d3211), and the same detector goes RED on the default boot.

CLASSIC IS FENCED, NOT AMENDED (the R31 dig-flip pattern). ?classic=1 forces verge off, so
the covenanted town's render does not move on a render-side ruling. Proven twice: identical
ground geometry hashes AND identical ground-only rendered pixels at three poses
(79df268c / 91564001 / a09d1e52), while the default boot differs at all three. If Fable
wants classic to take the footpath too, that is an amendment ruling and a one-token change.

§0.4 — the chunk lifecycle seam. The producer has fired since R3 and Lane D's consumer has
existed since R3, but nothing could connect them: createChunkManager never handed `ctx`
back, so a consumer holding only PROCITY.chunks had nowhere to attach (measured on HEAD:
`!!chunks.ctx === false`). Now `chunks.onChunkBuilt(fn) -> unsubscribe()` for many
consumers plus `chunks.ctx` for the original single slot. Proven live: 136 build / 144
dispose events over a 40-step walk; payload {cx,cz,buildings,furniture,data} with
key === `${cx},${cz}`; a second consumer does not clobber the first; the ctx slot fires;
unsubscribe silences; a THROWING subscriber does not take the streamer down.
ZERO behaviour change when nobody subscribes: a 102-step walk recording
[draws, tris, chunks] per step hashes ceb1ec66 on BOTH builds.

Files: web/js/world/ground.js, web/js/world/chunks.js, docs/shots/laneB_r37_kerb/*,
docs/LANES/LANE_B_NOTES.md, B-progress.md. sim.js untouched (Lane D's).
2026-08-03 16:40:43 +10:00
m3ultra
e4d77629c5 Lane A R37 (v8 wave 0 §0.1, ruling-side): the poster gate was VACUOUS — corrected to three arms with a permanent control
The audit's claim against my lane, re-measured and CONFIRMED exactly: on the default
boot (synthetic 20261990, gigs default-ON) there are 14 posters, all 14 stand inside
e.width/2 — the bitumen ground.js paints — and 0 stand inside the ruled kerb
roadWidth/2. One refinement it did not make: 12 are spine posters at poleOffset=6m,
8m inside the paint (genuinely mid-road); 2 are frontage posters clipping the corridor
edge by 0.06m (FACADE_PROUD past their venue's facade plane).

WHY the gate was green: my placer seats posters via poleOffset, which is DERIVED FROM
roadWidth, and my selfcheck asserted clearance against roadWidth/2. Gate and subject
were the same function agreeing with itself — the R27 cross-convention trap recurring
inside the very file whose header explains it. It never read a number that came from
Lane B, so no change to where the road is painted could make it fail.

The correction (selfcheck.js, districtInvariants), three arms:
  1. no poster on a carriageway — measured through vergeBand(e)[0], the published law
     itself, the same call B's ground now consumes, so gate and renderer move together
  2. every SPINE poster stands INSIDE some edge's vergeBand — the outer bound the old
     check never had ("not on the road" also passed for a poster in a paddock).
     Frontage exempt BY MEASUREMENT: 18/108 gig plans have a frontage poster past every
     corridor edge (worst 3.98m, launceston_real) via plan_osm's lot setback.
     Spine violations over the same corpus: 0/108.
  3. THE CONTROL — count posters standing on bitumen under the PRE-RULING ground
     (?verge=0, road quad = full e.width) and assert it is NOT ZERO on every gig plan
     (min 3 / max 212 / never 0 across 510 plans), pinned at EXACTLY 14 on the default
     boot. A control allowed to drift toward zero is how a gate goes vacuous.
     The replica is pinned to B's FLAG, not to a line number that will drift.

FALSIFIABILITY PROVEN. Simulated ?verge=0 honestly — vergeBand switched to the
pre-ruling reading, poleOffset pinned to the true band so the PLACER stays
byte-identical (it is a render flag: paint changes, plan does not; fingerprint and
every gig golden green in both runs, so the gate's reading is the only variable):
  corrected (R37) gate  →  FAIL, 1020 failures (2 arms x 510 plans)
  pre-R37 (HEAD) gate   →  ALL GREEN 156,352/156,352  — structurally blind

GOLDENS: NOTHING MOVED, ZERO RE-PINS. 0x5f76e76, GIG_GOLDEN 0xec7a2d39, 25 base town
goldens and 24 real-town gig goldens all untouched — correct and predicted, since the
only generator-adjacent file changed is the selfcheck, which validates output and never
produces it. 156,352 -> 157,407 checks (+1,055), 10.3s.

Corridor law CONFIRMED for Lane B, semantics unchanged, contract published in full
(LANE_A_NOTES §37) with four hazards flagged loudly while B consumes it in parallel:
roadWidth and edge.width are both FULL widths but one is carriageway and one corridor
(that naming IS why this bug existed); lane's band is NOT the literal [2,2] the round
instructions state (2 synthetic edges are, 56 real lane edges are [4,4] — branch on
outer<=inner); arcade is all footpath with coincident kerbs to skip; the inward
extension never inverts (0 of 31,039 edges). Two charter numbers corrected: the "9m
band / 18m of every main" figures are synthetic-only — on every real town a main is
24m => 7m band, and the corpus's dominant edge is side@12 at 22,415/31,039 (72%) with
a 3m footpath.

FILED, NOT FIXED — v8 debt ledger, four entries (LANE_A_NOTES §37): D1 chunkIndex
(two impls, THREE divergences, header comment promises a swap that would break three
ways — owner B) · D2 isOpen (three impls + an ad-hoc fourth site; A's canonical one has
ZERO importers; the live shell copy treats no-hours as CLOSED where A's law says OPEN —
latent until v8 adds an hours-less lot — owner F) · D3 two shop registries (B's missing
all three venue kinds => buildings.js:344 renders op-shop signage on every gig venue
since R13 — owner B) · D4 NEW, mine: the poster gate's inner bound is NEAREST-EDGE and
an arcade (kerb 0) camouflages a real carriageway — 8 real-town plans hide a spine
poster up to 1.78m inside a main, 0 on synthetic. Cost measured decision-grade:
synthetic 0/4 plans move, 11/26 town gig goldens re-pin, poster counts unchanged.
Deferred to R38 on purpose — it moves plan output for a reason that is NOT the kerb
ruling, and the "did the kerb ruling move a golden?" answer must stay a clean no.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 16:25:04 +10:00
m3ultra
62c0a2185d Fable (integrator): round-37 instructions — v8 WAVE 0, THE FLOOR (budget re-pin first, the kerb, two gate repairs, the chunk hooks)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 16:03:31 +10:00
m3ultra
67b62389e7 Fable: the animal ruling — generate, don't download (foreign-skeleton proven on our own bytes; economics cut tier 2); charter gains the budget re-pin + classic network allow-list
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 15:30:43 +10:00
m3ultra
751d5fe57e Fable: V8 SOMEONE LIVES HERE draft charter — John's rulings recorded (kerb=footpath; real towns get the content, civic fetch funded into v8; animals pending spike)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 14:43:53 +10:00
m3ultra
d59df8e1c0 Fable: the post-v7.0 city-patterns review — 16-agent top-down audit + adversarial design pass; v8 SOMEONE LIVES HERE proposed, three folklore numbers corrected
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-03 14:18:04 +10:00
m3ultra
ae2137fd9c Fable (integrator): the v7 epoch retro — hands before tags, classic keeps its people, the fork famine chapter
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 00:34:18 +10:00
m3ultra
c842547e61 Fable (integrator): ROUND 36 CLOSED — v7.0 tagged on 4709cfe; the hold's arc complete; the fork-famine record kept
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 00:33:02 +10:00
m3ultra
4709cfece6 Lane F R36 w2.5 (v7.0 close, final): the hold RESOLVED — re-gate 0 fails / 0 warns on the true final tree
§36.4 held -> ruled -> RESOLVED: Fable ruled 'classic keeps its people', D fixed
it in rigs.js alone (2fd4c1c: base-17 restored, the five DJ bodies append behind
djs=dance riding the shell's existing !CLASSIC signal; classic's 129-citizen
census byte-identical to a b339402^ shadow tree). F's full-suite re-gate on the
true final tree (run 3): SUMMARY 7 passed / 0 failed / 0 warn / 0 skipped, QA
GREEN, MATRIX GREEN 10 towns x 7 gates, flags harness 0 fails / 0 WARNS — the
smoke_djdance warn flipped to '?classic=1: zero DJ-body fetches'; default keeps
all 22 bodies, the organic gig-crowd proof, and the DJ figure-scale statures
exactly. Honest record: re-gate runs 1-2 died to a box-level fork famine
(~10,600 leaked m3panel pmset|tail orphans, fixed at source) — starvation
artifacts, not gates; noted in §36.5.

The five-holds law end-to-end in one round: held by F, ruled by Fable, fixed by
the owning lane, re-proven by the gate that held it. Nothing improvised.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 00:31:22 +10:00
m3ultra
2fd4c1cf79 Lane D R36 w2.5 (Fable ruling): CLASSIC KEEPS ITS PEOPLE — the 5 DJ bodies gate out of ?classic's pool
b339402 appended the 5 trellis'd DJ bodies to PED_NAMES.normal unconditionally, so
?classic=1 fetched them and its seeded crowd pool widened 17->22 (F's held §36.4 warn).
Ruled option (b): the five gate OUT of classic, mirroring the sit/look/dance !CLASSIC
clip gates. classic is the v2 town INCLUDING ITS PEOPLE; the DJs walk every other boot.

MECHANISM (rigs.js only — zero shell edits): PED_NAMES.normal restored to the covenanted
base 17 (exact pre-July-20 list); the five move to PED_NAMES.djs; loadPedFleet gains
djs = dance (default tracks the existing dance flag, which the shell already passes as
!CLASSIC). Roster = djs ? [...normal, ...djs] : normal — the five APPEND, so no base
slot renumbers: default boot's 22-list is byte-identical to the pre-ruling list and
classic's 17-list is byte-identical to pre-b339402. pickRig maps through pool.length,
so 17 restores the exact pre-July-20 crowd mapping, not merely the width.

MEASURED (fresh contexts, port-isolated no-store servers, seed 20261990):
- ?classic=1: ZERO of the 5 DJ GLBs fetched (21 ped-GLB fetches = 17+2 bodies +
  walk+idle) · pool 17 normal / 19 all · 129-citizen census all base-17 u comical,
  zero DJ · 0 console errors.
- default: all 5 fetched · pool 22/24 · 37 DJ-bodied street peds · F's organic gig
  proof preserved (pinned seed's venue crowd includes dj_phrtt_01 + woman_dj_02) ·
  0 console errors.
- IDENTITY vs pre-July-20: classic booted on a shadow tree with b339402^ rigs.js —
  full 129-citizen (id, pedRoll, pedIndex, pedName) census BYTE-IDENTICAL to the
  gated tree's classic boot. Same crowd, ped for ped, as before July 20.

Known side effect (noted §36): citizens_test.html passes no opts -> its dev harness
shows 17+2; not a covenanted surface, {djs:true} restores it if wanted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:20:52 +10:00
m3ultra
622a5e0d82 Fable: frontier 2b/2c — THE HORIZON MATTE + VORONOI OUTSKIRTS (from the Lague video review; engine path rejected, shader tricks adopted)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:14:31 +10:00
m3ultra
d9d8cbfd3e Lane F R36 w2 (v7.0 close): THE FREEZE — README v7 section, charter risk verdicts, notes §36
README: the v7.0 section (the loop dig->guide->want->travel->list->paper, the
delta-law machinery, the classic covenant) + the morning-paper manual row.

V7_THE_GAME.md: the five charter risks get their retired-or-carried verdicts,
v4-style, written by F under the single-lane-close ruling: economy RETIRED-
structural (the named bot verifier carried to the live tier) · schema drift
RETIRED (three optional widenings, zero migrations) · re-emit identity CARRIED
(never fired; owned-item stability check unbuilt — the next re-emit round owns
it) · scope gravity RETIRED (the stage gates held) · v6 collision RETIRED (the
2 a.m. commits were the one contact, swept R36w1 + gated R36w2).

LANE_F_NOTES §36 + F-progress: the close record — both playtests, E's three
flags closed by measurement, the DJ-roster hold, the full gate numbers
(7 passed / 0 failed / 0 warn / 0 skipped · flags 0 fails / 1 warn (deliberate)
· selfcheck 156,352/156,352 · figure-scale 29 figs incl. the 5 DJ bodies ·
MATRIX GREEN 10 towns x 7 gates · R32-35 smokes re-green on the final tree).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:10:34 +10:00
m3ultra
b8e1082182 Lane F R36 w2 (v7.0 close): the 2 a.m. assets gated — DJ-body figure-scale leg + smoke_djdance
interior_scale_check.py grows the DJ-body leg (E flag a): the 5 trellis bodies
(b339402) spawned BY NAME through the real browse path — bind skeletons measure
0.984-0.989 UNITS vs the legacy roster's ~173 (cm convention), rigs.js:163
span-normalise absorbs it: statures 1.64/1.71/1.81/1.87/1.89 m, all [1.4,2.0],
feet planted, rig-kind verified. The old sample's (i*7)%19 could never reach
fleet indices 17-21 — the subject is now provably exercised.

flags_check.py grows STRICT smoke_djdance (E flag b: gate on binds + NaN, never
node counts): 4 Rokoko clips bind 64/65 tracks (sole unbound mixamorigReference
— E's census reproduced at runtime); gig dancers clip-driven (identity by
duration, mixer advancing, position.y FLAT); ?classic ZERO dance-clip fetches
(positive control: default fetched 4); ?noassets procedural sway ALIVE (amp
0.067 m vs clip-driven 0.00 — the inverse pair proves the branch).

ONE WARN, deliberate (the held finding, machine-recorded): ?classic fetches the
5 DJ body GLBs — unconditional PED_NAMES.normal members (D's file), which also
widened classic's crowd pool 17->22 ungated. Held for Fable per the five-holds
law; F did not improvise in D's file during the close.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:09:48 +10:00
m3ultra
83bce93f82 Lane E R36 w1: the 2 a.m. commits regularized — 9 assets (not 7) swept, Rokoko zone correction, depot 44→53
046668e + b339402 provenance'd: 4 dance clips are ROKOKO free mocap (263 pack,
Mixamo-skeleton export — the brief's Mixamo guess corrected by measurement; new
licence-table zone) and there are FIVE trellis DJ bodies, not three. All 9
sha1-identical to their 90sDJsim originals; chain recorded to source FBXs.

Structural: clips mesh-free 68n/198t/52-joint skin+IBM, 0 NaN, bind 65/66 (only
mixamorigReference unbound); bodies 3998-4000 tris, 1024 webp, no Draco, ped law
PASS. FLAG -> F w2: bodies' bind-pose ~0.99 units vs roster ~175 (cm) — the
figure-scale gate's expected number; rigs.js:163 absorbs it at spawn. No file
touched, nothing fixed in place.

Depot: published per R22 standing authorization via tailnet ingress,
_published.json 44->53, all 9 fetched back from the public depot byte-identical.
validate_manifest 0/0, publish --verify 53/53 live.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:43:17 +10:00
m3ultra
24183b1eb3 Fable (integrator): round-36 instructions — the v7.0 close (Fable plays the full loop, E regularizes the 2am assets, F gates and tags)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:23:13 +10:00
m3ultra
285ce69553 Fable: THE FRONTIER gains THE CIVIC LAYER — parks/fountains/statues/memorials; OSM maps them all (the war memorial angle), synthetic gets a seeded kit
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:20:24 +10:00
type-two
3ef751e1e3 Fable (integrator): THE TOUR — day one to first gem, 6 frames, no staging
The v7.0 charter's money shot, driven through the REAL loop on the pinned seed: arrive hunting
(the splash mission) → the strip → the shop (rumor overhead) → THE GEM (THE VERANDAHS 'Tinny',
asking $19 against ★ RARE guide $60+ — with onboarding beat ③ visible below, walking its talk)
→ the crate → dawn day 2: '⚖ SOLD Tinny — hammer $89, $78 after fees'. Bought $19, hammered
$89: the loop, told in six frames. docs/shots/v7_tour/ + sequence README. What remains for the
v7.0 tag is deliberately NOT mine: docs freeze + John's playtest (hands before tags).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 20:18:13 +10:00
type-two
25cef5983e Fable (integrator): ROUND 35 CLOSED — the first five minutes land; every v7.0 SYSTEM is built
qa.sh --strict --matrix: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10 towns green. New
STRICT smoke_first_five: the fresh game hunts a roster artist and the splash names hunt + cash
· the beats walked the REAL paths (② at the crate, ③ on the buy, the send-off on the ⚖) · a
returning save gets no tutorial · a second fresh browser hunts the SAME artist (seeded, not
random) · ?game=0 shows nothing · 0 console errors. THE CROSS-ROUND CATCH: the seeded want
moved a fresh-boot invariant (wants 1, not 0) and the R33 gate went red on the FULL run while
green solo — amended to a baseline snapshot, lesson filed in §35 (a feature that moves a boot
invariant must sweep every gate that assumed it; full runs exist for exactly this). Money shot:
docs/shots/v7_beta/first_five_splash.png. Remaining for v7.0: the tour + docs freeze + THE TAG
— which waits for John's hands (the alpha precedent).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 20:13:02 +10:00
type-two
55b984e0b0 Lane C+B R35 (v7.0 close #2): THE FIRST FIVE MINUTES — arrive hunting, three beats walk the hustle
A FRESH game (day 1 · empty crate · empty auction house) seeds ONE artist want off
rng(citySeed,'firstwant',0) × the parody roster (dig.js ARTISTS exported) — the splash names
the mission before the first step ('You're hunting HILLS HOIST — $191 in your pocket'), and
the keeper rumors point at the same hunt from shop one. Three toast-beats ride EXISTING events
(zero new systems): ① find a record shop (on the go-click) → ② riffle · mind the guide · BUY
(first digOpen) → ③ sell at a counter or ⚖ LIST and sleep (first find, via wallet.onChange) →
the send-off on the first sale-or-listing (the listener removes itself). A returning save gets
its town back, not a tutorial (fresh-detection = state, no save flag — the delta law stays
clean); ?game=0 / ?classic=1 never reach the block. #pc-toast body-mounted (the #pc-game rule):
beats fire INSIDE shops, and a SLEEP taken at a counter now shows its morning paper.
2026-07-20 20:13:02 +10:00
type-two
c9e233a7e5 Fable (integrator): ROUND 34 CLOSED — GODBAY hammers, all green; v7.0 needs only the first five minutes
qa.sh --strict --matrix: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10 towns green. New
STRICT smoke_godbay: consigned through the real crate DOM · ONE-HAMMER determinism (a frozen
pre-sleep export slept twice lands byte-identical — the seeded gavel, measured not trusted) ·
honest bounded resolution (net $19 ≤ 2×$24×0.88) · the wake toast carried the morning paper ·
the ride to melbourne hammered a listing on arrival · ?game=0 has no crate to list from · 0
console errors. Money shots in docs/shots/v7_beta/ (the dawn paper + the ⚖ crate). The full
v7 loop now closes end to end: dig the gem → keeper cash now or the gavel tomorrow → the
wantlist points at another town → the ride costs a day and hammers your listings on arrival.
Remaining for the v7.0 tag: THE FIRST FIVE MINUTES (onboarding), the tour, docs freeze — and
John's hands on the whole thing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 19:32:06 +10:00
type-two
e528c92fed Lane B R34: ⚖ LIST in the crate · AT AUCTION section · the morning paper rides the toasts
hud.js: every crate find row gains ⚖ (mail-in consignment — very 1996); AT AUCTION section
(non-empty only) shows what hammers tomorrow; the rebuild watcher now folds listings in.
index.html: the wake toast and the travel-arrival toast carry the drained auction news —
'🌅 day 2 · ⚖ SOLD "Cane Toad Blues" — hammer $22, $19 after fees' is the come-back-tomorrow
hook paying off at dawn.
2026-07-20 19:32:06 +10:00
type-two
b048f51640 Lane F R34 (v7.0 close #1): GODBAY — the offline seeded auction, one hammer per item, ever
godbayHammer(entry, townKey): THE ONE-HAMMER LAW — seeded by ITEM IDENTITY
(godbay:<townKey>:<sku|slotId>:<dayFound>:<pricePaid>), NEVER by resolution day: a passed-in
item re-lists to the same result forever, so there is no retry farm anywhere in the economy
(the keeper's offer is a formula, the auction is one hammer per item per life). Fixed 4-draw
stream. Rolls: 15% passed in (comes home free) · hammer uniform across the item's band
(grail's open top = 2×low; unbanded alpha finds auction around pricePaid — honest, never
invented) · 12% bidding war ×1.5–2.0 · 12% commission, net floor $1. EV ≈ 0.8× band midpoint
— UNDER the asking-price EV of in-band stock: random flipping bleeds, only FINDS profit
(charter law #2 at the auction house); the keeper's half-of-low stays the instant floor, the
gavel the bounded ceiling (2×high×0.88). Band table imported from C's bible.js and PRNG from
core/prng.js — one authority each, no mirrors.
listings: optional on procity-save/1 (entry shape + listDay ≥ 1, the pulls/wants back-compat
law). listFind (identity — the entry LEAVES the crate, it cannot also sell at a counter) ·
resolveAuctions() runs in adopt() AND sleep(), so sleep, travel, and day-moving imports all
hammer what they pass · takeAuctionNews() drains the transient morning paper (NOT saved — the
ledger is cash/collection; the paper is a toast).
2026-07-20 19:32:06 +10:00
type-two
776b10b599 Fable (integrator): ROUND 33 CLOSED — THE HUNT lands, all green; the beta's last system is in
qa.sh --strict --matrix on the final tree: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10
towns green. New STRICT smoke_wantlist_travel: ☆→★ through the real card (the save carried
{THE VERANDAHS — 'Servo at Midnight'}) · a keeper muttered the hunted artist within 2 shops
('saw one in Castlemaine just last week') · buying the wanted sleeve cleared the hunt · the
synthetic→melbourne ride cost EXACTLY one day with $179 and the find riding along · the
same-town reboot was free (the control discriminates) · the ride home charged again (day 3) ·
?game=0 built zero want DOM and muttered nothing · 0 console errors. Matrix note: town_matrix
shares one browser across towns so travel drifts the day as it walks — safe because
determinism double-boots the SAME town (free by the same-town rule); reasoned before landing.
Money shots: docs/shots/v7_beta/rumor_and_wantlist.png (the keeper's mutter over the toy
shop's 70s wallpaper + THE WANTLIST open in the crate) + want_card.png. README manual row.
v7.0-beta systems are now ALL BUILT — what remains of v7: Esc-in-person (John's hands), then
the v7.0 close (GodBay offline auctions, THE FIRST FIVE MINUTES, the tour, the tag).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 19:01:40 +10:00
type-two
7b26e45fa0 Lane B R33: THE WANTLIST in the crate panel · the arrival toast · the build-race fix the shot found
hud.js: THE WANTLIST section in the crate (non-empty only — no header over nothing): hunted
rows, ✕ stops hunting, refresh watches wants length so an open panel follows adds/clears.
THE FIX: R32's game surface BUILT only in street update() frames — a door entered fast after
boot had no crate/bar inside at all, and the interior tickGame() refreshed a UI that never
existed. Every gate idles on the street long enough to build, so green gates missed it; the
R33 money-shot script entered faster and exposed it. tickGame() now builds-or-refreshes in
ANY mode (shots are a detector, not decoration — filed in LANE_F_NOTES §33).
index.html: game.traveled at boot → '🚌 <town> — the ride cost a day. Day N' toast (save.js
already charged the fare and re-keyed the week before the shell read game.day).
2026-07-20 19:01:40 +10:00
type-two
37773bc81d Lane F R33 (v7.0-beta wave 2): wants on the save · the keeper's rumor · TRAVEL COSTS A DAY
save.js: optional wants:[{artist?|title?|sku?}] on procity-save/1 (validated exact-and-loud,
≥1 string field per entry, cap 40, absent-when-empty — the same back-compat law as pulls).
recordWant (case-insensitive dedupe) / findWant (a want covers an item when every field the
WANT names matches) / removeWant (identity). TRAVEL in adopt(): the adopted save's town !==
this boot's townKey (town OR seed — a new seed is a new town) ⇒ day += 1, traveled = true,
prunePulls — load AND import both pay the fare; same-town adoption is FREE, so reloads and
export→import round trips keep the save-determinism gate's byte equality untouched. The 23
towns are a map you spend days crossing now, not a dropdown.
interior_mode.js: onWant/isWanted seams into dig.open; buying a matching item clears its want
('✓ off the wantlist'). THE RUMOR (charter #6 — the keeper finally gossips): seeded
xmur3('rumor:citySeed:shopId:day') → ~45% of shop entries mutter a hunted want + a real
cached town in the banner. Runtime-only stream, freshly keyed — A's rotation boundary holds;
no game / empty wantlist ⇒ the line never exists. Full persona lines stay D's for the v6
clip epoch; the banner is the keeper's voice until then.
2026-07-20 19:01:40 +10:00
type-two
ce71908bb5 Lane C R33 (v7.0-beta wave 2): ☆ WANT IT on the pull card
The wantlist grows from the card, not a search box the 90s didn't have: you pulled it, it's
dear, you'll hunt one cheaper. ☆ WANT IT → ★ ON THE WANTLIST (a stamp once wanted, not a
button). Construction-gated on opts.onWant/isWanted — ?game=0 / classic cards carry ZERO
wantlist DOM, the classic-pure pattern.
2026-07-20 19:01:40 +10:00
type-two
9aae167d64 Fable (integrator): ROUND 32 CLOSED — v7.0-beta wave 1 all green; smoke_bible + the routing amendment
qa.sh --strict --matrix on the final tree: 7 passed · 0 failed · 0 warn · 0 skipped, MATRIX 10
towns green. New STRICT gate smoke_bible: band law over EVERY bin off the digOffers surface
(80 offers/5 bins), the buy-everything ledger runs on THE GEM'S BIN so the finder-margin leg is
non-vacuous (bin1: 2 gems, grail asking $19 vs keeper $30; ledger closes to the cent — Σask
$333 → Σoffer $135, gems alone +$21, every non-gem strictly negative), scarcity measured
(emptied bin 0/16 on re-open AND across a full reload; 16 pulls in the save) with the ?game=0
negative control re-opening 16/16 (the detector discriminates). sell_routing amended from the
alpha inequality (credited < paid) to the exact formula (credited == min(basis−1, basis//2),
basis = bandLow-or-pricePaid) — the fence moved from the receipt to the band, which is what
charter law #2 always said; it passed on a banded standard item (+$4 on basis $8). _at_bin
grows an idx param (back-compatible). Money shots in docs/shots/v7_beta/ (the guide card + the
crate at the counter). LANE_F_NOTES §32 (incl. the JING5 fresh-checkout trap: gitignored
web/assets/models synced from m3ultra — also un-warned the validator's 15 cross-pack checks).
README manual: the guide/gem/scarcity rows. Remaining beta charter queued in the round doc:
wantlist + rumors · travel costs a day · Esc-in-person · then GodBay.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 18:27:19 +10:00
type-two
bb30767b62 Lane B R32 (§31.6 queue 1–3): the crate lives in shops · cluster-pose spawn · dawn reads dawn
hud.js: #pc-game rides document.body (position:fixed, z 30) instead of the mode-hidden street
root — day/cash/CRATE/SLEEP are YOURS inside a shop too (the playtest's 'crate at the counter').
C toggles the crate ANYWHERE; the surface yields to the dig/sell cards and the map (they own
the screen). tickGame() exported so the interior/map frame branches keep it live (buys update
the count while you shop); dispose removes the body-mounted wrap.
index.html: the frozen spawn (-96,9,east) was tuned for the synthetic fixture — on real towns
it faced dirt (§31.6-1). Non-classic boots now spawn ON the main-street footpath door-line
(block kind 'mainstreet', both generators; every-door fallback) at the door nearest the shop
cluster's heart, facing the LONGER run of shopfronts down the strip's dominant axis. Pure plan
math, zero draws — no stream moves; ?classic=1 keeps the frozen pose forever.
lighting.js: dawnSky opt (shell passes high-cirrus, null under classic) — the DAWN segment
swaps the dome off the golden-SUNSET default that read dusk-orange (§31.6-3), and swaps back.
setSky() is now an explicit override: weather's rain/overcast dome always wins over base+dawn.
2026-07-20 18:26:56 +10:00
type-two
75e5e06288 Lane F R32 (v7.0-beta wave 1): per-day scarcity — pulls ride procity-save/1, the bin remembers
save.js: optional pulls: string[] on the SAME schema (validated exact-and-loud when present;
absent on every alpha save — old savers drop it silently, never reject; payload omits it when
empty so the alpha byte shape survives). recordPull/pullsFor seams; pruned on sleep/import —
day-tagged keys from other days are unreachable by construction (the consumer embeds the
current day), untagged keys are real-sourced and KEPT (sold means gone, tier-2 spirit at
tier 1). Cap 600 FIFO (delta law: saves stay tiny). Collection entries gain optional band
(recordFind stamps dig + shelf buys) — C's §9.1 sell basis reads it.
interior_mode.js: pull keys ${shopId}|${binKey}${pullTag}#${slot} — pullTag @d<game.day> for
rotating crates INCLUDING day 1 (the SEED stays untagged per the day-1 convention; the ledger
doesn't — a day-1 pull must not survive into day 2's identical-looking untagged key space),
'' for real-sourced (their pulls never expire). The seed input to binSeed is UNTOUCHED — A's
rotation boundary holds. Selling an item does NOT restock the bin (pulls are independent of the
collection — the leak the §30.6 filing predicted). digOffers getter = the honest-gate surface
(index/ask/band/sku) so the bible gate asserts identity, not looks.
2026-07-20 18:26:36 +10:00
type-two
f9517f14ab Lane C R32 (v7.0-beta wave 1): THE BIBLE — bands derived, gems seeded, the cards get the guide stamp
bible.js: band ranges MIRRORED from E's pipeline thresholds (record 8/25/60 · book 5/15/40 ·
toy 6/20/50) — derived in JS off the price_band labels the packs already carry, NO pack re-emit
(charter risk #3 never opens). guideText renders a RANGE ('guide $8–24' / '$60+'), never a
verdict — the card never says gem; spotting asking-under-guide is the player's skill.
dig.js: parody sleeves roll seeded bands (25/45/22/8) + a 10% gem on collector/grail only,
asking strictly under the keeper's own bandLow offer (collector $2–9 vs $12 · grail $5–20 vs
$30) — margin by construction; fixed 9-draw stream per item; rare ≡ grail (matches real packs).
Real offers carry band off price_band — and real asking always sits INSIDE its band (the band
derives FROM the price), so with the §9.1 basis swap every real round trip stays strictly
negative: the no-pump gate holds untouched, structurally. open({gone}) omits pulled slots AFTER
the draw (R27 pick-then-omit, zero collateral; o.i survives filtering — identity preserved).
currentOffers() honest surface for F's gate. sell.js: the §9.1 basis swap EXECUTED exactly as
pre-ratified — sellOffer(sellBasis(entry)) = min(bandLow−1, max(1, floor(bandLow·0.5))) when
banded; alpha-era entries (no band) keep the pricePaid basis and sell exactly as before. The
sell card carries the guide line too.
2026-07-20 18:26:15 +10:00
m3ultra
046668e5af feat(gig): club dancers play real dance clips, not procedural sway
loadPedFleet gains dance:!CLASSIC (mirrors the sit/look gate) → fleet.danceClips
= 4 mesh-free mixamorig club dances (party/medium/drink/sway). _make picks one
per dancer off a fresh gigdance seeded stream (zero impact on existing draws /
the same-seed-same-crowd covenant), spawnRig plays it, and update() drops the
fake bounce for real-clip dancers (procedural sway stays as the classic/noassets
fallback). ?classic fetches nothing, byte-identical.

Verified: default boot fetches all 4 dance GLBs (gated load runs), both modules
parse + export clean, page boots. Same clips + _canon/_rotOnly/spawnRig proven
animating in 90sDJsim (its crowd/rigs.js is this file ported).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 02:11:55 +10:00
m3ultra
b3394027be feat(citizens): +5 trellis DJ bodies in the ped roster
Same 5 Mixamo-rigged DJ characters as 90sDJsim, converted FBX->skinned GLB +
decimated to 4k tris (<=5k ped law) via MESHGOD scripts/fbx_to_ped.py — mixamorig:
skeleton + skin preserved. Added to PED_NAMES (rigs.js). Shares the proven bind:
identical _canon/_rotOnly + the same GLBs verified animating in 90sDJsim.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-20 01:37:10 +10:00
m3ultra
3c5d0a1e95 Fable: THE FRONTIER gains THE VERNACULAR KIT — John's building-variety idea, source corrected (OSM/Overture footprints + parametric archetypes, never Google 3D)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 22:43:57 +10:00
m3ultra
67913f8b66 Fable: THE FRONTIER gains THE THIRD DIMENSION + TEXTURE LIFE — the noise ruling (semantic streams stay; noise only where continuous), terrain chartered v8+ with costs named
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 22:40:53 +10:00
m3ultra
bb5f36f1e0 Fable (integrator): ROUND 31 CLOSED — v7.0-alpha tagged and pushed; the playtest found what the gates couldn't
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:42:36 +10:00
m3ultra
2491f1c8ec Lane F R31 wave 2 (v7.0-alpha close): THE SHOT + the ledger. docs/shots/v7_alpha/crate_panel.png — the alpha's face: Monster Robot Party's real frontage, THE CRATE open with 3 real finds (real cover thumbs, paid/where/day honest), game bar day 1 · $116 · CRATE 3 · SLEEP, driven through the REAL loop with the dig param ABSENT (the R31 flip carries the shot), 0 console errors. LANE_F_NOTES §31 (the flip both ways, the two new gate legs + their negative control, harness lesson #4 — the explicit-flag blindfold, THE BETA QUEUE filed) + F-progress R31. Tag v7.0-alpha rides this commit, LOCAL ONLY — Fable reviews and pushes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:38:07 +10:00
m3ultra
50385c0f08 Lane F R31 wave 1 (v7.0-alpha close): THE DIG FLIP — the alpha-blocker Fable's playtest found. DIG_ON = flagOn('dig') (default-ON, ?dig=0 opt-out, ?classic=1 off — the v3.1 pattern; the v2-era opt-in survived 6 epochs past the README's 'dig on' claim because every R30 gate booted dig=1 explicitly: the explicit-flag blindfold). Fenced forever: default_boot_gate asserts dig REACHABILITY on a NAKED boot (E at a bin → digActive true), classic_regression asserts dig INERT at the bin (zero pcdg DOM, measured not assumed). PROCITY.flags gains dig. Splash de-staled ('Every door opens.' — no more '(soon)'; controls line carries E riffle/sell · C crate · SLEEP to save) + README manual row (sell at counter · C crate · SLEEP = save/advance/rotate). PROCITY_QA_PORT env override (flags_check, interior_scale_check, town_matrix) so the suite runs port-isolated instead of silently reusing whatever holds :8130. Verified both ways on :8951 (naked boot digs + closes clean; dig=0 and classic zero dig DOM, classic ZERO storage calls; noassets digs parody, 0 errors). qa.sh --strict --matrix on :8931: 7/0/0/0, flags_check 0 fails 0 warns, MATRIX 10 towns green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 16:37:02 +10:00
m3ultra
d96cbde004 Fable (integrator): round-31 instructions — the alpha close (wave 0: Fable plays it; then micro-fixes; then the tag)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 15:58:32 +10:00
m3ultra
7a7da29132 Fable (integrator): ROUND 30 CLOSED — v7.0-alpha wave 1 complete, all green, 7/0/0; the game remembers, spends, and cannot cheat
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 15:11:54 +10:00