{
  "$type": "site.standard.document",
  "bskyPostRef": {
    "cid": "bafyreidrytk4vsnqmbskq2l7ns4dtytpg3vcrgbavu2whuq7nl73pxkdti",
    "uri": "at://did:plc:pgryn3ephfd2xgft23qokfzt/app.bsky.feed.post/3mofktdsnj5x2"
  },
  "path": "/t/neon-city-cosysim-and-the-nexus-project/176853#post_5",
  "publishedAt": "2026-06-16T08:55:37.000Z",
  "site": "https://discuss.huggingface.co",
  "tags": [
    "Socket.IO",
    "@skill"
  ],
  "textContent": "# **Changelog**\n\nAll notable changes to CosySim are documented here.\n\n* * *\n\n## **[1.62.1] — “LIVING CITY — LOOP COMPLETIONS” — 2026-06-15**\n\nFinished wiring the v1.62 “Living City” systems end-to-end: the Executive Suite desktop now reads from the same unified comms backbone the rest of the city writes to, faction hostility actually drives the reverse hack, and the pre-existing test debt was repaired so the suite is green again. No new subsystems — these are the last connectors between systems that already shipped.\n\n### **Executive Suite — unified comms & surfaced signals**\n\n  * **Mail → GlobalCommsLog** — the Suite’s Mail app now reads the unified `engine/world/comms_log.py` (`GlobalCommsLog`) instead of the legacy phone-only thread store, so player↔NPC and NPC↔NPC traffic share one inbox; intercepted messages (from phone hacking) surface in a dedicated **Intercepts** folder.\n  * **Desktop breach alerts + Oracle taskbar button** — `phone_hacked` / `message_intercepted` breach events now raise a desktop alert in the Suite, and the taskbar gains an **Oracle** button so the omniscience surface is reachable from the OS shell.\n\n\n\n### **Phone OS — faction-driven reverse hacking**\n\n  * **Hostility triggers NPC→player hacking** — the rare, firewall-defended `NpcHackPlayerService` reverse hack is now actually invoked by faction hostility (sufficiently negative standing), closing the loop with the v1.62.0 phone-defence upgrades: PH-T2 firewall upgrades raise the defence and can flip a hostile attacker’s breach to **BLOCKED**.\n\n\n\n### **Tests — pre-existing debt repaired**\n\n  * **Suite green** — repaired all pre-existing failing/broken tests inherited on this branch so the full pytest suite passes again.\n\n\n\n* * *\n\n## **[1.62.0] — “LIVING PENTHOUSE” — 2026-06-15**\n\nFive fixes that take the penthouse 3D scene from “wired but lifeless” to a room that feels inhabited: characters rest _on_ the furniture, the Director appears and persists, bed-game actions drive consent-gated paired poses, every present character is driven by its own local agent, and idle characters move and emote on a cheap scripted layer between the slow LLM ticks. Verified end-to-end against the live scene on `:5556` with LMStudio up.\n\n### **Penthouse — naturalism & intimacy**\n\n  * **Anchor-aware placement** — `_locationPositions` now carries a per-location anchor (`lie`/`sit`/`stand`) and surface height, and `character_bridge.js` places the model group origin (feet) _on_ the surface instead of sinking through it; backend `scene_state[\"locations\"]` Y values were synced to match.\n  * **Director avatar renders + persists** — placement was aligned with the working `spawnCharacter` path and `_onSceneState` now re-places the Director from `scene_state.director_avatar`, so the avatar shows on load for every client (not only after a manual “Place Avatar” click) and survives reconnects.\n  * **Bed-game → paired poses (consent-gated)** — the missing UI→pose chain was built: `POST /api/bedgame/action` resolves participants and emits `bedgame_action` with a `pose_eligible` flag; the frontend listener maps it to `CharacterBridge.startPose` → `CharModels.startSexPose`. Explicit poses (`explicit_level` ≥ threshold) are gated fail-closed behind the existing adult surface — every involved character must clear `openness ≥ 60` **and** a truthy `consent_given` flag; the Director is exempt. Low-explicit actions always pose.\n  * **Per-character agents (cap fix + nexus guard)** — every character entering the scene now registers its own `CharacterAgent`, the hard 2-character cap was replaced with the `SCENE_METADATA`-driven `_max_characters()`, and a runtime invariant logs when `agents ≠ present characters`. Three characters now each take distinct agent-driven turns per tick.\n  * **Cheap config-driven ambient behavior** — new `engine/agents/ambient_behavior.py` adds a fast scripted ambient layer (fidget/glance/expression/reposition, mood- and presence-weighted) that reuses the existing `set_animation` / `set_expression` emit path between the slow LLM ticks, with a rare config-gated LLM line via the existing agent path. Tunable under `penthouse.ambient.*`; guarded to never override an active pose, a busy character, or a viewerless scene — so idle characters feel alive without spamming the model.\n\n\n\n### **Executive Suite — a new neon OS desktop scene**\n\n  * **New`executive_suite` scene** (`:5596`) — a full-screen neon-noir corporate “operating system”: a draggable **window manager** (z-index focus, traffic-light close, minimize/restore), a left **app dock** with badges, desktop icons, a bottom **taskbar** (start, ⌘K search, pinned apps, system tray) and a layered **animated skyline** behind an office bezel — ported faithfully from the `ui_kits_v2/executive_suite` reference into Jinja2 + CSS-var’d vanilla JS.\n  * **8 functional apps wired to real data** — Files (live inventory + item catalog + sandboxed `data/` JSON), Mail (read/compose against the existing phone comms threads; repoints to GlobalCommsLog in sub-project 2), Notes (autosaving JSON store), Music (player + animated equalizer/queue), Code, a **sandboxed** Terminal (whitelisted read-only commands — `status`/`world`/`inbox`/`scenes`…, no shell exec), Browser, and Settings (theme/accent).\n  * **Live AI assistant + live system tray** — the Assistant panel (“Add my Agent”, LIVE badge, chat feed) drives a real `CharacterAgent` (default Aria) over Socket.IO, reusing the shared `VirtualAgentManager` agent pipeline; the tray clock reads the live `WorldState` game clock and `heat` reads live `PlayerState`. Assistant replies are run through a conservative sanitizer that strips leaked model meta/instruction artifacts (`<<DOC|…>>` blocks, system/metadata markdown headers, stray role prefixes) before they reach the feed.\n  * **Full registration + auto-start** — added across every source-of-truth (launcher `--list`, TUI, control-plane registry, port registry `:5596`, the in-world hub) and enabled by default (`pillars.game.auto_start` + per-scene `auto_start: true`), so it boots with the core game set.\n  * **Surfaced previously-missing hub scenes** — `auction` and `cyberspace` were registered but absent from the hub UI; both now appear in-world and in `--list`.\n\n\n\n### **Comms backbone & NPC↔NPC messaging**\n\n  * **GlobalCommsLog — single source of truth** — new `engine/world/comms_log.py` backs every message (phone DMs, autotexts, NPC↔NPC) in one SQLite log (`data/comms_log.db`) with `query`/`thread`/`about`/`recent` accessors, `mark_observed` for later phone-hacking/Oracle reads, and a `prune` row cap. All writes are defensive — a logging failure can never break a send.\n  * **Comms interceptor + phone write-through** — new `engine/agents/interceptors/comms_logger.py` (`CommsLoggerInterceptor`, pri 90) logs every governed agent reply, while the phone scene logs explicit user sends; a per-call `comms_context` aligns `thread_id`/recipients so the two halves of a conversation share a thread without duplicates.\n  * **NPC phones + NPC↔NPC hybrid messaging** — new `engine/world/npc_comms.py` scheduler (with `npc_dm` threads + an `npc_phone` stub in `phone_db.py`) has NPCs text each other on a template-dominant / occasional-LLM mix, weighted by affinity and anti-spam. It runs on its **own** daemon thread and lock (the `_tick_lock` fix) so NPC traffic never blocks the user-facing phone ticker, and is started/stopped from the phone scene lifecycle.\n  * **Leave-a-message** — new `engine/world/presence.py` plus phone changes let a player message an offline NPC (and NPCs leave autotexts for an offline player): messages are stored `left_unread`, delivered on (re)connect, and surfaced via a “left you a message” affordance in `phone_v2.js` / `phone_ui_v2.html`.\n  * **Calmer, more varied user inbox** — `phone_rules_v2.py` gains a config-driven `comms.autotxt.user_multiplier` (cooldown scaling, per-character overrides), topic seeds drawn from real city events, style pools, and anti-repeat, so user-facing autotexts feel less spammy and less repetitive.\n  * **Pairwise relationship effects** — new `engine/world/relationship_effects.py` nudges each NPC pair’s `character_relationships.relationship_level` (0–1) by a small, tone-/keyword-derived, clamped delta per NPC↔NPC exchange, closing the loop with the affinity-weighted pair selection in the scheduler.\n\n\n\n### **Phone OS overhaul — NPC phones, hacking & upgrades**\n\n  * **NPC phones + derived security** — new `engine/world/phone_os.py` (the `PhoneOS` accessor over a full `npc_phone` table) gives every NPC a real phone with archetype-/faction-seeded base stats, and derives `effective_security`, `effective_firewall`, `hack_power` and `app_slots` from base levels + installed software (the single source of truth being each upgrade’s `phone_upgrade.effects` block). The player’s equipped cyberdeck `trace_resist` hardens the phone on top, coupling the inventory to phone defence. All reads are defensive — a missing/broken DB never crashes a phone read.\n  * **Buyable / skill-installable upgrades** — `engine.world.inventory.ITEM_CATALOG` gains flagged `is_phone_upgrade` software + hardware (encryption patch, firewall v1/v2, comms tap, ICE, app packs, modem/CPU/OS-kernel) sold by the Grid vendor; the new `install_phone_upgrade` skill gates install on owned-item → credits → `skill_check` (idempotent, with before/after derived stats), and `list_phone_upgrades` surfaces the catalog + current stats. Installing an upgrade raises the owner’s derived security/firewall/hack-power/app-slots and can light up a gated UI app (e.g. Comms Tap → Intercept/Breach).\n  * **Player→NPC hacking** — new `content/scenes/phone/phone_hack.py` (`HackPhoneService.hack`) resolves a config-driven check (player hack-power + roll vs the NPC’s security + firewall) and on success performs **intercept** (reads a bounded slice of the NPC’s comms and marks them observed for later Oracle/UI reads), **plant** (writes one spoofed message into the NPC’s comms + phone thread), or **steal** (a bounded, margin-scaled credit skim). Failure costs heat and standing; the method never raises.\n  * **NPC→player hacking (firewall-defended)** — a rare, hostility-driven reverse hack (`NpcHackPlayerService`) where the attack is defended by the player’s `effective_security + effective_firewall + base_difficulty`, so PH-T2 firewall upgrades directly raise the defence and can flip the same attacker from a successful (bounded, recoverable: read + at most one leak-or-plant, capped heat/standing) breach to **BLOCKED**. Emits `phone_hacked` / `message_intercepted` events and persists a breach notification to the comms backbone.\n  * **OS-like phone UI** — new `/api/phone/*` routes and `phone_v2.js` views: a **notifications center** (bell badge + breach/leak/left-message feed off the persisted comms log), home-screen **search** , an installed-apps model that unlocks gated apps, a **Breach** app (pick a target, see its defences, run intercept/plant/steal) and an **Upgrades** app (browse + buy/install the catalog with live before/after stats).\n\n\n\n### **Oracle omniscience — the Oracle reads the comms log**\n\nThe Oracle now genuinely “sees all”: it reads the GlobalCommsLog (player↔NPC + NPC↔NPC chatter) and turns overheard signal into cryptic fortunes, real intel, and rare omens — all governed by a single privacy/spoiler budget so it hints without ever dumping the city’s private conversations.\n\n  * **Privacy-budgeted comms reader** — new `engine/world/oracle_comms.py` is the one shared read layer over the comms log (`select_entries` / `weave_into` / `find_signal`). A HARD `oracle.comms.max_refs` cap bounds how many entries any single reading may cite, a `recent_window` bounds the scan, and `respect_sensitive` skips/abstracts entries flagged sensitive/mature/intimate so private moments stay private. Raw message bodies are never surfaced — only short, abstracted poetic hints — and every referenced entry is stamped `mark_observed(id, 'oracle')`. All comms-log failures degrade gracefully to plain atmospheric behaviour and never crash a reading.\n  * **Comms-aware cryptic fortunes** — `content/scenes/oracle/oracle_scene.py` gains `_maybe_weave_comms`: under `oracle.comms.fortune_chance` a fortune OCCASIONALLY weaves 1–2 real overheard exchanges into the prophecy (cryptically, capped by the budget, marking each entry observed); otherwise it stays purely atmospheric. No comms / a failed roll returns the base fortune unchanged.\n  * **`read_the_signal` intel skill** — new `@skill(pack=\"oracle\")` in `engine/skills/builtin/oracle_skills.py` asks the Oracle to read the streams and surface ONE genuine, log-sourced finding — a low-security **hack opportunity** , an NPC **discussing the player** , or the closest NPC↔NPC **pair** by chatter volume — then grants a small **bounded reward** (`oracle.comms.signal_reward_credits` + `signal_reward_item`) gated by the skill cooldown/cost. Empty streams return an in-world “silence” line with no reward.\n  * **Autonomous comms omens** — `engine/agents/oracle_companion.py` gains a rare, config-weighted (`oracle.comms.omen_weight`) omen action: the companion pulls a single budget-capped entry, renders it as a cryptic line, marks it observed, and delivers it to the player’s phone — so the Oracle reaches out unprompted without ever leaking raw chatter.\n  * **Config** — new `oracle.comms.*` block in `config/default.yaml` (`fortune_chance`, `max_refs`, `recent_window`, `omen_weight`, `signal_reward_credits`, `signal_reward_item`, `signal_cooldown_sec`, `respect_sensitive`) keeps the entire privacy/spoiler budget in one place.\n\n\n\n* * *\n\n## **[1.61.0] — “PUBLIC RELEASE PREP” — 2026-06-13**\n\nMade the repository safe and inviting to publish: a full credential security audit (no live secrets in the tree), a hardened ignore policy, and a complete professional README + documentation pass.\n\n### **Security — credentials externalized (no real secret remains in tracked source)**\n\n  * **80+ secrets removed** : 24 hardcoded Google API keys across `engine/integrations/` (aistudio/drive/workspace) → `os.getenv`; 55 keys in `config/nlm_rpcids.yaml` → file gitignored + redacted `config/nlm_rpcids.example.yaml` shipped; the LMStudio API token and a real personal email pulled out of `config/default.yaml` and source; a live `FIREBASE_API_KEY` in the ARGUS sesame client; and key/email stragglers redacted from `docs/ARGUS_*` reports and a heap test fixture.\n  * **Secret pattern** : real values live only in a gitignored `.env` (auto-loaded by `engine/config.py` via python-dotenv) or `config/secrets.yaml`; committed config uses `${ENV_VAR}` placeholders resolved at read time. `.env.example` documents every variable. **Local runtime is preserved** — verified config loads, all scenes import, and NEON CITY launches clean.\n  * **Personal identifiers** (account handles) moved to `COSYSIM_DEFAULT_ACCOUNT` / `COSYSIM_KNOWN_ACCOUNTS` env vars.\n  * **`.gitignore` hardened**: secrets, `config/nlm_rpcids.yaml`, `data/heap_findings*`, dumps, `*.bak`, cookies/credentials, heap variants; `git rm --cached` applied to the two tracked sensitive files (kept on disk).\n\n\n\n### **Documentation — flagship README + assets**\n\n  * **Complete README rewrite** (drafted by an 8-agent fleet, assembled by hand): hero, badges, “Start here” navigation table, quickstart, security/config guide, then deep sections — Overview & Architecture, NEON CITY living world, Engine Internals (interceptors · stream-tag spec decoding · custom LMStudio steering · ephemeral servers · the Oracle’s dual role), NLM + NEXUS frontier-from-local, CONTROL (training/finetune/self-improvement), Integrations/Apps/CLI, the ARGUS protocol, and the Creation pillar. Emphasizes the open, learn-from-it nature.\n  * **`docs/assets/scenes/`** — 21 curated scene screenshots embedded/linked.\n  * README deep-links the existing `docs/` tree (all links verified to resolve).\n\n\n\n* * *\n\n## **[1.60.0] — “LIVING SYSTEMS” — 2026-06-13**\n\nA 10-agent fleet upgrade (disjoint file ownership; shared-file hooks integrated centrally) that takes the gameplay + infra subsystems from “wired” to pro level. Builds directly on the v1.59 feedback loops.\n\n### **Gameplay depth**\n\n  * **Faction standing now matters** — new `engine/world/faction_gates.py` with reusable helpers scenes call: `shop_access_allowed`, `price_multiplier_for` (matching faction −10%, rival +15%, graded by band), `filter_missions_by_standing`, `npc_standing_note`. `FactionAI._decide()` now weights actions by the player’s standing (allies expand/defend near you, rivals raid/sabotage toward your district), and territory-control shifts are broadcast on the EventBus (`NEONCITY_FACTION_SHIFT`) — previously computed but never emitted.\n  * **Mission consequences + chains** — completion/failure applies faction-control, reputation, and heat deltas via the player API; new `engine/world/mission_chains.py` defines gated multi-mission arcs (off by default); difficulty/reward scale with player skill levels; crew availability is enforced on assignment.\n  * **Crew skill-checks** — operations resolve via a graded success/partial/failure check derived from crew level + loyalty + op difficulty (was: always full reward). Loyalty shifts on outcome; rewards scale per tier.\n  * **Equipment & consumables** — new `engine/world/equipment_effects.py` maps equipped cyberware/weapons to real skill/stat bonuses (`get_equipment_bonuses`); consumable effects generalised to work by item _category_ instead of a 9-item hardcoded list; optional condition wear.\n  * **Economy world-event shocks** — `Market.subscribe_to_world_events()` wires world events → supply/demand shocks via `apply_event` (war→weapons, festival→luxury, shortage→surge), and territory control now flows into specialty-good pricing (`refresh_territory_multipliers`). Activated once at LivingWorld bootstrap. Preserves v1.59 buy/sell settlement.\n\n\n\n### **Agent depth**\n\n  * **Neurochemistry from dialogue** — new `StimulusDetectInterceptor` (pri 88) NLP-detects compliment/insult/kiss/touch/rejection/threat/comfort in replies and applies the matching neurochemistry stimulus to the speaker/addressee, so characters affect each other emotionally from what they actually say (was: stimuli only ever triggered manually).\n\n\n\n### **Infra hardening**\n\n  * **Scheduler** — per-task timeout enforcement (a hung task no longer blocks the loop); stub tasks log an honest “not implemented” instead of faking success.\n  * **LMStudio federation** — exponential backoff + jitter on peer health retries; `__del__`/close no longer spews logging noise during interpreter shutdown.\n  * **Observability** — flood-guard and error-bucket growth are now LRU-bounded; error-rate threshold alerting (throttled); structured-logging init self-check.\n  * **Dead code resolved** — TaskQueue / finetune orchestrator / auto_train either wired into a real path or removed cleanly with exports updated.\n\n\n\n### **Integration & config**\n\n  * All knobs exposed in `config/default.yaml` (faction_gates, territory.faction_ai, mission, crew.skill_check, world.equipment, economy.event_shocks, neurochemistry.stimulus_detect, scheduler, observability.error_aggregator/oracle, lmstudio.task_queue_v2, lmlink.health.backoff) with safe in-code defaults.\n  * Each agent shipped hermetic pytest coverage; shared-file edits (interceptor registration, config, activation calls) were applied centrally to avoid parallel-edit conflicts.\n\n\n\n* * *\n\n## **[1.59.0] — “CONSEQUENTIAL WORLD” — 2026-06-13**\n\nClosed the open feedback loops surfaced by a full subsystem audit. The infrastructure was strong (MCP pipeline, agent loop, LMStudio client, Nexus router) but state changes flowed downstream and were discarded instead of feeding back into the world or agent decisions. This release makes actions consequential.\n\n### **Added — feedback loops**\n\n  * **StatSyncInterceptor (pri 91)** — agents emit `[STAT:arousal+10]` / `[STAT:trust=60]` and the deltas are now **applied to character game state** via the state coordinator (with stat-name aliases: desire→horniness, joy→happiness, …). Runs just before MoodSync (92) so its threshold-rule auto-evaluation sees the new values. Previously these tags were parsed and thrown away — the single biggest “plumbing without payoff” gap.\n  * **Economy settlement** — `market.buy()`/`sell()` now move real value: buy deducts credits from the player wallet, adds the good to inventory, and raises **heat** on contraband; sell requires possession, removes the item, and credits the wallet. Unaffordable/unheld trades are rejected and leave the market untouched. Configurable under `economy:` in `config/default.yaml` (`settle`, `contraband_heat_per_unit`, `sell_to_inventory`).\n  * **EventCascade ↔ WorldSim** — WorldSim gained an `on_event(callback)` subscriber registry fired from its single event funnel (`_log_event`); `EventCascade.start()` (which already probed for `on_event`) now actually connects, and the handler maps `SimEventType` → `WorldEventType` so scene subscriptions match. Cross-scene ripples finally receive world events.\n\n\n\n### **Changed — governance**\n\n  * **Skill cooldown + prerequisites enforced** in the AgentGovernor auto-skill loop. The auto path bypassed `SkillRegistry.execute_skill` (which enforces these), so auto skills could fire every turn regardless of their declared `cooldown`. Registered skills are now throttled and gated on prerequisites; unregistered MCP tools are unaffected. Added `CooldownTracker.was_used()`.\n\n\n\n### **Audit notes (verified, no change needed)**\n\n  * Heat already gates the casino (≥80) and drives lounge NPC behaviour (≥65/85).\n  * The rules engine is already auto-applied every reply (MoodSync threshold eval), and action tags already bump conversation heat — the static audit understated existing wiring.\n  * Crew operations already complete via scene routes + the `crew_check_operations` skill (request-driven); a redundant background timer was intentionally **not** added to avoid double-resolution races.\n\n\n\n### **Tests**\n\n  * `test_stat_sync_interceptor.py` (6), `test_market_settlement.py` (5), `test_eventcascade_worldsim.py` (3) — all green; adjacent dialog/skills/scene suites unaffected.\n\n\n\n* * *\n\n## **[1.58.0] — “DARK RENAISSANCE” — 2026-06-11**\n\nAll-scene visual glow-up from the `artifacts/new-assets` design system, three.js ES-module migration with a full penthouse 3D overhaul, new NEONCITY landing page, and a round of launcher/TUI/runtime bug fixes.\n\n### **Fixed (bugs first)**\n\n  * **TUI navigation** — ←/→ hop between target list and center panel, ↑/↓ are focus-aware (services table vs target list), Enter/Space launch from either panel, rows clickable/focusable; launches now run as isolated `launcher.py <name>` subprocesses (Stop works for every target type)\n  * **lab_break / grid never launched from TUI** — their `__init__` rejected the `host=` kwarg the TUI passes; both constructors now accept it\n  * **Penthouse camera presets crashed after config load** — `setCameraViews` now normalizes the YAML `position` key to the runtime `pos` shape\n  * **Scene rules never registered** — 2-arg `add_rule(SCENE_ID, rule)` calls in neoncity/coders/command_center, nonexistent `register_action()` in casino/command_center, and a wildcard-tripped idempotency guard meant NO scene rules/actions had ever reached the SceneRulesEngine; rewritten to the real API (neoncity 11+5, coders 8+4, casino 7, command_center 5+5)\n  * **`DialogSystem.set_directive(scene_id=)`** — 5 lounge call sites fixed to `scene=` (stage songs, drink rituals, secret reveals all failed silently)\n  * **`MCPFramework.get_or_create()`** — asset_studio called a method that never existed; now `get_scene()`; stale guidance strings in nexus_seeder and generate_coder corrected\n  * **NLM RPC registry corruption** — all three writers now use shared `engine.utils.atomic_write_json()` (tmp + `os.replace`); corrupt files are quarantined to `.corrupt` instead of erroring forever\n  * **intel_hub duplicate assistant blueprint** — idempotent `mount_assistant()`\n  * **launcher** — single-target launch refuses to double-bind an occupied port; subprocess scene logs line-buffered; `browser_test.py --scene` accepts names\n  * **Restarted a wedged Windows WMI service** that hung every Python startup at `platform._wmi_query` (aiohttp import) under heavy multi-process load\n\n\n\n### **three.js r128 → r184 (ES modules)**\n\n  * Vendored `three.module.min.js` + addons (OrbitControls, GLTFLoader, RoomEnvironment, RoundedBoxGeometry, BufferGeometryUtils, SkeletonUtils) under `content/shared/static/vendor/three/`; import-map partial at `content/shared/templates/partials/three_importmap.html`\n  * `content/shared/static/js/three_boot.js` — module boot exposing `window.THREE` (+addons), loading the legacy chain with `async=false` (parallel fetch, ordered execution)\n  * Physical-light conversion (×π) across penthouse_3d.js, bedroom.js, lab_3d.js, penthouse_model_import.js; `outputEncoding` removals; CDN GLTFLoader bootstrap deleted\n\n\n\n### **Penthouse 3D overhaul (Dark Renaissance)**\n\n  * Rose `#fb7185` / violet `#9d71ea` material re-grade, RoomEnvironment IBL, transmission-glass curtain wall (south wall is now a floor-to-ceiling window), instanced 64-building skyline with 320 twinkling windows, neon smog bands, night-sky gradient backdrop, GPU rain curtain (600 shader streaks), rose/violet emissive furniture trim, eye-tuned lighting\n  * Characters rethemed to the kit identities: Mira (plum-black bob) and new Rei (silver-lavender)\n  * 32 FPS on RTX 2060 (headed), zero console errors, all 8 camera views\n\n\n\n### **Scenes glow-up (all 24 scene keys)**\n\n  * `design_tokens_v2.css`: Orbitron display voice, Inter body, Share Tech Mono terminal voice, per-scene accent-rgb fallbacks for all 24 scene keys\n  * Webfonts vendored locally (`/shared/fonts/*.woff2` + `fonts.css`) — offline-safe; adds Share Tech Mono + Press Start 2P\n  * Shared `.cs-chat-bubble` / `.cs-chat-log` dialogue components\n  * Per-scene v2 passes — kit-backed: neoncity, grid, heist, oracle, phone, intel_hub, neonos, hub, asset_studio; extrapolated: tavern, lounge, casino, arena, realm, gallery, lab_break chrome, auction, cyberspace, coders, games, command_center, service UIs\n\n\n\n### **Landing page**\n\n  * Hub `/` now serves the NEONCITY Dark Renaissance landing (skyline, rain, neon title, live footer stats); THE TERMINAL catalogue moved to `/terminal`; navbar/footer hub links point at the catalogue\n\n",
  "title": "NEON-CITY/CosySim and the NEXUS project"
}