Commit Graph

35 Commits

Author SHA1 Message Date
m3ultra
aa9c140eca Lane C R5 C1: v1.1 re-map — record_crate (fixed) + counter_till
Round-5 §Lane C task 1 (the v1.1 gate). Map Lane E's R4-late re-exports in
glb.js:

- record_crate FIXED (E stripped sourceless AO/roughness slots) → crate/
  recordBin upgrade to plastic crates with the procedural sleeves inside;
  removed the stale "fails to load" comment.
- counter → 'counter_till' (the real ~1.6m timber counter WITH a modelled
  till; NOT the 4m balcao). Footprint-fit + floor-plant + keeper-stand pose
  unchanged.
- Double-till resolved (documented): counter_till carries its own till, so
  the separate cash_register attach is dropped whenever the counter GLB is
  live (falls back to cash_register on the primitive counter otherwise);
  milkshake_mixer stays on the milk-bar bench, lifted +0.10m onto the taller
  GLB counter.

Validated (GLB on, via depot): sweep+soak {throws 0, path 0, det 0, worst
10.4ms}, 0 rooms with a visible primitive till, leak-free vs a saturated
baseline (the transient 2geo/4tex first-sight is record_crate + counter_till
cache-fill). Primitive path byte-unchanged (glb.js-only edit). qa.sh --strict
GREEN. Contact sheet docs/shots/laneC/glb_v1_1_r5.jpg. → F can tag v1.1
(LANE_C_NOTES.md).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 20:56:00 +10:00
m3ultra
5485d67ae8 Lane F R5 start: archive R3/R4 instruction claims + v2 flags table + v1.1 watch
- ROUND3/ROUND4_INSTRUCTIONS.md: 'SUPERSEDED by R5' banner (F4 archive task).
- LANE_F_NOTES §10: round-5 tracking — v2 flag-seam table (?plansrc/?winmap/?dig/?roster,
  all pending owning-lane specs), v2 QA-harness plan, v1.1 watch.
- F-progress: round-5 section. Confirmed fal already un-parked at 039c179 (no F change needed).
- v1.1 tag is on watch for Lane C re-map (C1) + Lane E hero-prop bake (E1).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 20:48:19 +10:00
m3ultra
039c179c0e Fable: round-5 update — fal.ai spend authorized (John topped up $22); Lane E runs glass-case/bus-shelter fallbacks
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:38:25 +10:00
m3ultra
fd8b0bfcfc Fable: correct stale fal.ai budget — Hunyuan v2 ~14-17¢/gen, remainder is 2-3 props (~$0.30-0.50, ~$1 ceiling), not $2.70
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:36:12 +10:00
m3ultra
130c183910 Fable (integrator): round-5 lane instructions — v1.1 close-out + v2 foundations behind flags
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 20:32:48 +10:00
m3ultra
2698b402d1 Lane F R4 finalize: gate table all-6-green + v1 tour shots + interior-shot fix
Gate table (LANE_F_NOTES §4) rewritten to R4 all-green with measured evidence:
 1 determinism (selfcheck 1301/1301, fingerprint 0x3fa36874) · 2 soak (37 chunks/20 shops,
 heap 38->38MB, 0 errors, leak-free) · 3 budget (draws 138/tris 31k, decimated peds) ·
 4 asset-free (heap 13->13MB, 0 net) · 5 selfchecks (qa.sh --strict 4/4, 23 GLBs on depot) ·
 6 shots (10 full-frame 1280x720, no letterbox, night closed-facade + real interiors).

shots.py: interior tour shots (record/opshop) now capture via DBG.enterShop(id) directly —
they were passing {type} to enterShop (needs id) then calling shot() (which forces street
mode), so both showed streets. Now they show the themed interiors with keeper + hero props.

Verified by a 6-auditor adversarial v1-readiness workflow -> GO.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 20:22:23 +10:00
m3ultra
6323d58736 Lane B round-4: closed facades (§3.5) + shot poses/letterbox + furniture GLB + novelty_record
- B1: per-shop closed-facade visuals — dark windows + red CLOSED plate + door tooltip, batched via a
  per-vertex aHours attr + two shared shaders + one uHour/uNight uniform pair on a procity:segment
  event (facade atlas untouched, no per-shop materials, no per-frame poll). 22:00 → only the openLate
  video shop lit, all others CLOSED; ~200 draws worst-view with citizens.
- B2: the shots 'letterbox' was camera-jammed-into-a-wall poses, not a composer bug (composer proven
  correctly sized headless). Reframed street_noon/arcade/warehouse to look down a street
  (streetViewPose), added the 3 missing bookmarks, night_neon now frames the lit video shop amid
  CLOSED neighbours, + a defensive composer resize. shots.py: 10 un-letterboxed shots, 0 errors.
- B3: furniture GLB use-if-ready upgrade (bench + food_cart, sit on their footprints) + novelty_record
  placed at record stores. novelty_record GLB is 26.5k tris (5x glb_law) → stays low-poly primitive
  until Lane E decimates it; ?noassets verified 0 network.

qa.sh --strict GREEN (4/4).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 19:59:27 +10:00
m3ultra
dafb079ff4 Lane E round 4 (E2): fix record_crate + ship counter-with-till, both live on depot
- record_crate: R3 normalize left a sourceless texture (packed AO/roughness map
  didn't survive WebP export; metallicRoughness+occlusion pointed at it) → three.js
  'undefined uri' crash. New pipeline/fix_glb_textures.py strips material slots that
  reference a sourceless texture. Verified loads in vendored GLTFLoader; re-published.
- counter_till (new fitting): ~2m timber counter + period till, flux_local→trellis_mac
  on-device, 1.61x0.64m / 1.15m tall, 32k tris. Verified loads; published. Lane C maps
  kind counter -> counter_till (balcao 4m 'counter' kept for long-bar use).
- publish.py: --only <name> filter + passwordless tailnet detection (GOD3_DEPOT override).
- manifest rebuilt (15 fittings, alias counter->counter_till); validate --depot 0 errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 19:07:15 +10:00
m3ultra
aad9baa584 Lane F R4: gate 3 PASS (draws 138/tris 31k) + remove dead setExposure call
Gate 3 (budget) official re-measure vs committed decimated peds (E1 518678d, D2
signed off a5e4b64): busiest node, pop 200, midday, 12-yaw peak -> draws 138 (<=300),
tris ~31k (<=200k). Baseline was 372k. Green.

D3 (a5e4b64) made the impostor toneMapped:true so exposure is global via
renderer.toneMappingExposure; citizens.setExposure() became a no-op, so the F1 wire is
removed (removing it before D's commit would have regressed night brightness). Boots
clean, 0 console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 19:02:19 +10:00
m3ultra
a5e4b64a9d Lane D round-4: in-shell verify (D1) + decimated-ped validation (D2) + impostor tone-map fix (D3)
D1: peds+keepers upgrade placeholder->rig in the shell; 12 enter/exit shops leak-free
(renderer.info.memory back to exact baseline); determinism holds across reload; ?noassets
fully placeholder with zero ped fetches.

D2 (gate-3 critical path): validated Lane E's decimated fleet — all 19 peds <=3k tris
(1564-2805, avg 2450), rigs bind+animate (skinning/skeleton preserved), 0 broken meshes under
eviction churn, silhouettes+identity intact, atlas bakes clean. Near fleet ~59.6k tris at the
24-cap (was ~1.2M) — F clear to re-measure gate 3.

D3: fixed a real bug found only in-shell — the impostor self-tone-mapped (toneMapped:false +
in-shader ACES), correct on the direct-canvas test page but DOUBLE-tone-mapped under the shell's
EffectComposer/OutputPass. Reworked to a standard toneMapped:true material outputting linear via
three's own tonemapping/colorspace chunks, so it matches the near rigs on both render paths.
setExposure is now a no-op (exposure is global). Verified noon+night in-shell.

Only web/js/citizens/impostor.js changed (+ NOTES/progress/R4 shots).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 18:56:28 +10:00
m3ultra
34926324bd Lane C R4: hero props into rooms (arcade/booth/fridge/mixer/register)
Round-4 §Lane C — map the 4 new hero props + cash_register (manifest now
14 fittings), validate, measure, clean up.

- glb.js: map listening_booth→listeningCorner (record), drinks_fridge→fridge
  (milkbar), arcade_cabinet→new arcadeCabinet primitive (video focal prop).
  New attachCounterTop() places cash_register on every counter's till slot
  (hides the primitive till) + milkshake_mixer on the milk-bar benchtop;
  counter primitive + keeper stand untouched. All yaw 0 (no correction).
- fittings.js: new arcadeCabinet primitive (footprint/height matched to the
  GLB); counter exposes counterTop attach points + tags the primitive till.
- theme.js: arcadeCabinet in the video recipe; the 3 focal props (arcade,
  listeningCorner already, +) raised to priority 6 + placed first so the
  door-counter path loop can't pull them → 24/24 appearance.
- interiors.js: thread recipe.key to upgradeRoom (gates milkshake_mixer to
  milk bars).
- interior_test.html: load GLBs via the live depot: path (drop the deleted
  _local_glb localBase shim; ?localdepot=1 still works offline).

Validated (all via live depot): primitive sweep 810 {throws 0, pathFail 0,
detFail 0}; GLB-on soak {throws 0, path 0, det 0, leakGeo 0, leakTex 0,
worst 7.3ms}; all 5 new props render planted/scaled/facing right (contact
sheet docs/shots/laneC/glb_heroprops_r4.jpg). Room tris measured: milk-bar
GLB-on ~468k (drinks_fridge 77k + milkshake_mixer 73k) — reported to Lane E
as the #1 bake-pass target (not fixed, per integrator decision #2; interiors
render one-at-a-time so gate 3 is unaffected). record_crate still broken +
counter still oversized — both await Lane E re-export (C task 5). Deleted the
stale web/assets/_local_glb/ validation copy. qa.sh --strict GREEN.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 18:44:09 +10:00
m3ultra
518678d4e4 Lane E round 4 (E1): decimate 19 ped rigs 924k→46k tris (≤3k each) for gate 3
weld + meshopt simplify (--ratio 0.05 --error 0.12); skinning + skeleton preserved
(65 joints intact), walk/idle clips untouched, silhouettes clean at street distance.
Originals backed up to gitignored pipeline/.peds_orig/. Hands to Lane D (D2) for rig
validation; Lane F re-measures gate 3 (~24-rig cap × ≤3k ≈ ≤67k fleet).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 18:29:50 +10:00
m3ultra
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>
2026-07-14 18:26:30 +10:00
m3ultra
9416d0ae08 Lane F R4: wire citizens.setExposure (F1) + permittedMax storeys-checker fix (F2)
F1: pass renderer.toneMappingExposure into CitizenSim each street frame so mid-tier
impostors track the animated day/night exposure (per LANE_D_NOTES). Verified: boots
clean, 0 console errors, exposure animates night 1.18 <-> midday 0.98.

F2: scope the consistency storeys check to permittedMax = max>=2 ? min(max+1,3) : max
(Lane A's corner-anchor rule, LANE_A_NOTES R3). Consistency now 0 warnings across 6
seeds; a single-storey type at >1 still trips. qa.sh --strict GREEN 4/4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 18:15:42 +10:00
m3ultra
5899924da1 Fable (integrator): round-4 lane instructions — v1-tag round (gate 3 tris + gate 6 shots critical path)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 18:06:37 +10:00
m3ultra
bd40ec7e7a Lane E round 3 (landed by Fable after review): 5 hero props gen'd local + published, local-depot mode, manifest 14 fittings + 8 furniture
- gen_props.py: flux_local -> trellis_mac -> normalize pipeline; 5/8 props kept
  (arcade-cabinet, listening-booth, drinks-fridge, milkshake-mixer, novelty-record)
- magazine-rack -> primitive (thin-wire gotcha); glass-case + bus-shelter -> fal.ai fallback
- cash-register reused from depot; all 22 GLBs live, validate --depot 0/0
- loaders.js ?localdepot=1 + stage_local_depot.py for network-free GLB validation
- qa.sh --strict GREEN 4/4 at commit time

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 18:03:03 +10:00
m3ultra
53f472d0d7 Lane F R3: hours/closed-shops + manifest/rig-fleet/?noassets + --depot + QA harness fixes
§3.5 hours: isOpen() gates enterShop — closed shops locked; at night only the openLate video
rental opens. §3.4: ?noassets (zero-network primitive path, verified via Performance API),
interior fitting GLB upgrades from the 3GOD depot (useGLB), and the rig-fleet upgrade
(models/peds/*.glb) so peds + keepers become shared GLB rigs, leak-free (shared loadGLB cache
proven, not a leak). qa.sh manifest gate now --depot (16 GLBs live) — GREEN 4/4.

Browser QA harness fixes so shots.py/soak.py actually run: DBG async-poll (was racing the async
install), plan via window.PROCITY (DBG.plan unexposed), enterShop bare-id, shop.lot is a lot id,
midday pin (§3.5 else closes shops mid-walk), GLB-cache warmup, budget peaks -> warnings (gate 3
clean pass is authoritative). Gate 2 soak PASS both asset modes; gate 4 asset-free PASS;
docs/shots/v1_tour/ (10 shots) + contact sheet captured.

Findings (LANE_F_NOTES §9): D/E decimate tri-heavy ped GLBs (gate 3 tris ~279k > 200k budget;
draws fine ~200/300). B: add 3 shots bookmark poses, fix headless composer letterbox in
DBG.shot(), render the §3.5 closed-facade visual (predicate window.PROCITY.isOpen).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 17:19:11 +10:00
m3ultra
fe40ea7d0a Lane C: round-3 GLB hero-prop validation (useGLB path)
Validated Lane E's 9 fitting GLBs in real rooms. 5 good, now live behind useGLB (wire_shelf, clothes_rack, bookshelf, cube_shelf_wide, work_table); record_crate broken (won't load) + counter too long/no-till fall back to primitive. Report: docs/LANES/LANE_C_GLB_VALIDATION.md.

glb.js: real-metre scale clamped to footprint, per-kind yaw for Z-major assets (+90deg) per manifest facing convention, manifest.localBase for offline validation, awaitable upgrades. interiors.js: room.glbReady. interior_test.html: GLB toggle.

Soak useGLB on (50 rooms): throws 0, pathFail 0, detFail 0, leakGeo 0, leakTex 0, worst 10.5ms, 256 upgrades. qa.sh --strict green.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:18:12 +10:00
m3ultra
fafd5a700a Lane B (Streetscape): round-3 — scene.environment for PBR peds + budget re-measure with citizens
- lighting.js sets scene.environment (neutral PMREM sky->ground gradient, no asset) in attachRenderer, before CitizenSim constructs; Lane D rig-fleet peds bake their impostor atlas from it and render dark if null. Verified set in street/night/interior + after interior-return.
- Re-measured worst continuous-walk view WITH citizens (pop 140, 125 active peds) via window.DBG: 263 scene / 275 total midday, 275 night -- <=300 everywhere. Radius-2 auto already the spawn default.
- Round-3 task 3 (furniture GLB footprints) standby: Fable s3.4 manifest upgrade not yet landed.
- Docs: LANE_B_NOTES.md + B-progress.md round-3 updates.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 16:00:22 +10:00
m3ultra
0985b05790 Lane D (Citizens): round-3 support — setExposure day/night hook + design notes
Fable round-3 §Lane D (all three tasks):
- sim.js: add CitizenSim.setExposure(e) passthrough so mid-tier billboards track the
  shell's per-segment renderer.toneMappingExposure (lighting.js animates it); stored so it
  survives the placeholder->rig atlas re-bake. Verified: uniform tracks 0.55<->2.3 and
  persists across the fleet upgrade.
- Keeper GLB-rig upgrade contract verified leak-free (my side): 15 enter/exit cycles with a
  fleet-backed rig keeper leave renderer.info.memory geo/tex exactly at baseline. Enabling it
  in the shell is one arg (pass `fleet` to KeeperManager) once F's §3.4 lands.
- LANE_D_NOTES: exact Lane F call sites for setExposure + keeper fleet-upgrade, and the
  chunk-streamed roster v1.5 design note (chunk-local identity, windowing, ownership/hand-off,
  budget, opt-in migration) — design only, no implementation.

Code touches only sim.js; no sibling files edited. Determinism still passes, near cap 24,
mixer 0.3ms, no console errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 15:55:25 +10:00
m3ultra
918a968185 Lane A: add LANE_A_NOTES.md — answer Lane F's storeys-warning + hours contract questions
Cross-lane note (ROUND3 process rule: notes for other lanes go in docs/LANES/):
qa.sh's storeys warnings are benign corner anchors (finding #5 stale), with the
exact permittedMax rule for Lane F to scope its checker; openLate/hours contract
confirmed ready for §3.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 15:54:16 +10:00
m3ultra
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>
2026-07-14 15:52:30 +10:00
m3ultra
862bbcd8de Lane E publish landed: 16 GLBs + thumbs live on 3GOD depot; pipeline fixes
Depot publish executed over the new passwordless tailnet path (allowlist auth,
GOD3_DEPOT=http://100.94.195.115:8788). Two contract bugs fixed en route:
- publish.py: /api/thumb wants JPEG keyed by the GLB name (was posting PNG keyed
  by a .png name -> 404 that mislabelled successful GLB uploads as ERR); thumb
  push now isolated per the MESHGOD house contract (cosmetic, never fails publish).
- validate_manifest.py: send a custom User-Agent (Cloudflare 403s Python-urllib
  on the public path) + honor GOD3_DEPOT override like publish.py.

validate_manifest.py --depot -> 0 errors, 0 warnings. qa.sh --strict all green.
_published.json records the 16 published assets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 15:35:28 +10:00
m3ultra
ae6017ca11 Fable (integrator): round-3 update — publish authorized, hero props go local
John authorized origin push (done) + depot publish (he runs it; GOD3_PW stays out of
agent hands). Hero props switch from the gated $2.70 fal.ai batch to the free
MODELBEAST path: sf3d + TRELLIS.2 weights verified already cached on-device (the
round-2 'HF-gated, setup needed' note was stale) — flux_local concepts -> trellis_mac
GLBs -> normalize.py, fal.ai only as per-reject fallback.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:41:50 +10:00
m3ultra
90bd06c328 Fable (integrator): round-3 lane instructions + archive round-1 lane prompts
Round-2 close-out: all lane work landed on main (C keeper-stand re-land, B streetscape,
F integration), stray lane-c/keeper-stand branch deleted (content identical), QA strict
green. ROUND3_INSTRUCTIONS.md assigns the polish/validation round: F leads (manifest
+ hours + QA gates), B shaves the spawn draw budget, C+E validate the GLB path via a
local depot mode, A verifies one stale finding, D supports. priorwork/ archives the
original per-lane prompts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:30:36 +10:00
m3ultra
aa4ed4fdca Lane F: integration — interiors + keepers + street peds + QA harness
interior_mode.js bridges Lane B's enterShop seam to Lane C buildInterior and Lane D
keepers (spawn at counter keeperStand, greet, leak-free over 5 cycles). CitizenSim
wired into the street loop (pop 140, ~96 active midday, worst ~191 draws). tools/:
qa.sh gate runner (all 4 landed gates GREEN --strict), scaffold/consistency checks,
shots.py + soak.py browser harnesses. docs/shots/ reference tree, LANE_F_NOTES
runbook, V2_IDEAS parking lot.

(F's inline seam edits to index.html/skins.js landed with the Lane B commit.)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:29:03 +10:00
m3ultra
5313402e43 Lane B (Streetscape): chunk-streamed walkable town shell
First-person shell: chunk streaming, instanced buildings + facade texture atlas
(22 facade materials -> 1; 5 skin materials city-wide), signs, awnings, furniture,
day/night lighting, minimap, pixel-accurate collision (incl. arbitrary-angle lots),
door raycast -> procity:enterShop, DBG harness, all-fallback mode. Renders Lane A's
full generated town (seed 20261990 'Boolarra Heads', 493 shops); worst continuous-
walk view ~261 draws (<=300 gate). 6 adversarial-review bugs fixed (collision sign,
house doors, awning skin, sign atlas, furniture seed hash, shot-mode restore).

index.html and skins.js include Lane F's inline integration seam edits (marked
'[Lane F integration]'): interior/keeper/citizen wiring + facade filename fix.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:28:47 +10:00
m3ultra
8577c48594 Lane C: keeper stand pose on the counter contract (re-land on main)
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, rig-front = local -Z per keepers.js), clamped
in-bounds. Deterministic; purely additive.

Note: commit 4235060 carries this message but actually contains Lane A's round-2
content (shared-index race, flagged in 3e98f05). This commit lands the real Lane C
change — identical content to stray branch lane-c/keeper-stand (85438b5), which is
now redundant. Verified: 36-build sweep + 50-room soak green.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 14:27:58 +10:00
m3ultra
063a959e29 Lane E (assets): pipeline, manifest + 23 on-device facade skins
Audit -> normalize (16 GLBs + thumbs) -> web/assets/manifest.json (the
contract Lanes B/C/D read) -> facade gap-fill.

Step 4 facades generated locally on the M3 Ultra via MODELBEAST
flux_local (FLUX.2-klein-4B / MLX on MPS): 23 skins, free, ~5.7s each,
blank signboard, eyeballed, harvested, mapped to shop types. Every
registry type now has >=3 facades (stall 2->4, closing the Lane A gap).
Corner-lot -side walls tagged face:"side" with empty types so no shop
front ever selects a windowless wall. manifest validates green.

Still gated on John (both optional -- the game runs asset-free):
publish the 16 GLBs to 3GOD (needs GOD3_PW), MeshGod hero props (~$2.70).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:48:25 +10:00
m3ultra
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 (4235060) due to a
shared-index race. Content is safe & correct; this note flags it for review. Committed
atomically via pathspec to avoid re-triggering the race.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:45:24 +10:00
m3ultra
9eb1acc61b Lane D (Citizens): deterministic LOD crowd — rigs/impostors/keepers + test page
Populate the town at city scale, on budget, deterministic per-citizen identity:
- rigs.js — ported 90sDJsim rig stack: mixamorig canonicalisation so one shared
  walk clip drives all 19 peds, head-bone height-normalise, feet-plant, pooled
  near-tier actors with walk<->idle crossfade
- impostor.js — 4-yaw sprite-atlas baker + instanced billboards: whole mid crowd
  in 1 draw call, tone-matched to the ACES near rigs
- sim.js — deterministic roster, footpath lanes off the street graph, near/mid/far
  LOD with hysteresis + hard 24-cap, staggered mixer budget, time-of-day density
- placeholder.js — seeded low-poly box humanoids (frame-one population + ?noassets)
- keepers.js — one keeper per shop at the counter, idle + greet-turn
- 21 ped GLBs (byte-identical from 90sDJsim), citizens_test.html harness,
  LANE_D_NOTES.md, 5 beauty shots

Verified in-browser: 200 citizens at max mixer 0.2ms (budget 2ms), near capped 24,
determinism holds (200 identities match seed), no T-pose, ?noassets crash-free.
Consumes Lane A plan.streets with zero adapter. Six adversarial-review bugs fixed
(non-deterministic fleet order, shared-resource disposal on pool eviction,
impostor colour-management).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 13:43:05 +10:00
m3ultra
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>
2026-07-14 13:37:26 +10:00
m3ultra
0e9d3fb0f2 Lane C: on-demand seeded shop interiors (library + test page)
Every shop door opens into a unique, believable, seeded interior — generated
in ~4ms, byte-identical every revisit (shop.seed), themed by shop.type.

- interiors.js: buildInterior(shop, THREE, opts) public API — pure fn of shop,
  returns {group, spawn, exits, places, dims, placement, dispose()}.
- theme.js: 9 CITY_SPEC type recipes (archetype/wallpaper/floor bias, clutter,
  counter pos, fittings mix, stock kind, signage) + type aliasing + one-time
  mergeRegistry() override seam for Lane F. Standalone (no hard registry dep).
- shell.js: room shell from lot x archetype (cosy/gallery/wide/hall/pokey),
  glazed shopfront + street backdrop, blocked back doorway, interior lighting.
- fittings.js: parametric kit ported from 90sDJsim + extended (bins, crates,
  4 shelf types, VHS aisle, glass case, counter+till, fridge, magazine/spinner
  racks, armchair, escalator, pegboard, barred window, returns slot, art).
- layout.js: per-archetype zones, thriftgod shuffled wall-slot system,
  occupancy grid, guaranteed door->counter flood-fill path (pull/carve).
- stock.js: v1 visual stock (pooled canvas sleeves/spines/boxes/garments/snacks
  with price stickers) + stockAdapter hook for BaseGod content later.
- context.js: seed sub-streams + shared-geometry cache + leak-free disposeAll().
- glb.js: optional GLB hero-prop upgrade via Lane E manifest (off by default,
  primitive fallback).
- interior_test.html: standalone page — seed/type/archetype, first-person walk,
  wireframe/occupancy/path debug, 50-room soak (perf + leak + determinism).

Acceptance (verified): same seed -> identical placement (0/810 mismatches);
9 types x 5 archetypes render sensibly (docs/shots/laneC grid); build <50ms
(steady ~4ms, soak worst 8ms); leak-free dispose (geo/tex delta 0); door->counter
path always exists (0 fails, 0 carves); runs with zero assets and zero network.
Adversarial multi-agent review: 5 findings, all fixed and re-verified.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-14 12:08:12 +10:00
m3ultra
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>
2026-07-14 12:06:41 +10:00
jing
a702a69f1e PROCITY scaffold: spec, research, 6 Opus lane prompts, core modules, vendored three r175, 69 inherited skins
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 10:46:40 +10:00