Steps 6.4-6.7B — Local surfaces, reference-exhibit validation, SciFi Observation surface

One commit for the work accumulated in the working tree since Step 6.3,
which had never been split into per-step commits:

- src/local-surfaces.js + src/surface-url.js (new); src/ui.js,
  src/validation.js, src/connection.js and public/index.html updated for
  local-surface hosting and generic surface rendering
- tests: local-surfaces (20), scifi-surfaces (24) and postmessage-interop (7)
  new; connection/museum-gallery/surface-validation suites updated
- reference exhibits: shared/contract-core.js defaults to Contract 5.3
  (major 5, minor 3, xzbt 5.3); museum-gallery advertises its surface
  catalog; aquarium/haunted-house/planetarium adapters updated
- SciFi-XZBT (Step 6.7A/6.7B): surface-mode.js + surface-bus.js,
  Observation-surface boot branch, local-change hooks, view.pillars /
  view.warp-flight targets; fixture byte-identical to G:/.vibe/SciFi-XZBT
- SciFi-XZBT contract adapter handshake fix: the inbound bridge filter no
  longer gates on an exact advisory xzbt value (Contract 5.3 §6.5), only on
  its presence/type, matching the host's own envelope validation; the
  adapter now advertises contract minor 3 / version 5.3.0, which it already
  implemented via the 5.3 surfaces field. Root cause of the five failing
  postmessage-interop tests (host hello was silently dropped).
- docs: architecture 6.4 and 6.7A, reference 6.6 and 6.7; evidence logs;
  test-fixtures/PROVENANCE.md resync record

Test results: NGN 154/154 (was 149/154); postmessage-interop 7/7 (was 2/7);
SciFi contract harness 21/21, real-adapter suite 32/32. git diff --check
clean for changed files; two pre-existing trailing-whitespace lines remain
in test-fixtures/reference-exhibits/scifi/index.html, copied verbatim from
the authoritative SciFi source.

Step 6.7 live verification (browser Observation, packaged standalone) is
still pending and is not claimed here.
This commit is contained in:
2026-09-14 19:45:27 -07:00
parent ed76cf6189
commit 745912e451
40 changed files with 5346 additions and 210 deletions
@@ -0,0 +1,172 @@
- banner:
- heading "XZBT-NGN Exhibit Engine" [level=1]
- paragraph: Contract 5.2/5.3 · One exhibit at a time
- main:
- heading "Connection" [level=2]
- generic: Exhibit URL (same origin)
- textbox "Exhibit URL (same origin)":
- /placeholder: /public/exhibits/example/index.html
- text: http://127.0.0.1:4173/test-fixtures/reference-exhibits/museum-gallery/control.html
- button "Load exhibit"
- button "Reconnect"
- button "Disconnect"
- paragraph: Enter a trusted exhibit's local served path or a URL on this origin. Load exhibit also switches exhibits. Reconnect starts a new session, or reloads the last exhibit after disconnect.
- status: connected · synchronized
- paragraph: Museum Gallery · 0.1.0 · Contract 5.3
- paragraph: "Exhibit location: http://127.0.0.1:4173/test-fixtures/reference-exhibits/museum-gallery/control.html"
- iframe:
- banner:
- heading "Museum Gallery — Control Room" [level=1]
- generic: Primary surface · Contract 5.3 · standalone-capable
- generic: host attached
- main:
- paragraph: The Orrery
- paragraph: "Lighting: 60%"
- paragraph: "Rotation: 0.4x"
- paragraph: "Labels: ON"
- paragraph: "Attached non-primary surfaces: 0"
- complementary:
- heading "Artifact" [level=2]
- generic: Selected artifact
- combobox "Selected artifact":
- option "The Orrery" [selected]
- option "Star Map"
- option "Meteorite Fragment"
- heading "Environment" [level=2]
- generic: Lighting level
- generic: 60%
- slider "Lighting level 60%"
- generic: Rotation speed
- generic: 0.4x
- slider "Rotation speed 0.4x"
- generic: Labels enabled
- button "Toggle" [pressed]
- heading "Actions" [level=2]
- button "Flash spotlight"
- contentinfo:
- generic: Control Room
- generic: Control Room standing by.
- heading "Exhibit controls (5)" [level=2]
- generic "Capabilities"
- paragraph: Reported values are authoritative. New values are drafts; select Set or Invoke to submit. Rediscovery resets drafts.
- heading "gallery" [level=3]
- article:
- heading "Selected Artifact" [level=3]
- code: artifact.selected
- paragraph: selection · readable · writable
- status: "Reported value: \"the-orrery\""
- generic "Target descriptor"
- paragraph
- text: New value
- combobox "New value":
- option "The Orrery" [selected]
- option "Star Map"
- option "Meteorite Fragment"
- button "Set"
- article:
- heading "Lighting Level" [level=3]
- code: lighting.level
- paragraph: range · readable · writable
- status: "Reported value: 0.6"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.6"
- button "Set"
- article:
- heading "Rotation Speed" [level=3]
- code: rotation.speed
- paragraph: range · readable · writable
- status: "Reported value: 0.4"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.4"
- button "Set"
- article:
- heading "Labels Enabled" [level=3]
- code: labels.enabled
- paragraph: state · readable · writable
- status: "Reported value: true"
- generic "Target descriptor"
- paragraph
- text: New value
- checkbox "New value" [checked]
- button "Set"
- heading "action" [level=3]
- article:
- heading "Spotlight Flash" [level=3]
- code: action.spotlight-flash
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- heading "Presentation surfaces (3)" [level=2]
- paragraph: Open Contract 5.3 presentation surfaces locally below. URLs resolve against the supplying exhibit. Disconnecting or switching exhibits closes these views. Remote/cast displays remain deferred.
- article:
- heading "Control Room" [level=3]
- code: surface.control
- generic: Primary
- generic: "Role: control"
- paragraph: "URL: control.html"
- status: Open in the authoritative control frame. Use Connection controls to reload or disconnect.
- button "Open" [disabled]
- button "Reload" [disabled]
- button "Close" [disabled]
- article:
- heading "Artifact Display" [level=3]
- code: surface.artifact
- generic: Non-primary
- generic: "Role: ambient"
- paragraph: "URL: artifact.html"
- status: open
- button "Open" [disabled]
- button "Reload"
- button "Close"
- iframe:
- banner:
- heading "Museum Gallery — Artifact Display" [level=1]
- generic: Non-primary surface · attaches to the Control Room
- generic: surface
- main:
- paragraph: The Orrery
- paragraph: "Lighting: 60%"
- paragraph: "Rotation: 0.4x"
- paragraph:
- button "Cycle artifact"
- paragraph: Attached to Control Room.
- contentinfo:
- generic: Artifact Display
- generic: Waiting for shared state.
- article:
- heading "Information Wall" [level=3]
- code: surface.info-wall
- generic: Non-primary
- generic: "Role: information"
- paragraph: "URL: info-wall.html"
- status: open
- button "Open" [disabled]
- button "Reload"
- button "Close"
- iframe:
- banner:
- heading "Museum Gallery — Information Wall" [level=1]
- generic: Non-primary surface · attaches to the Control Room
- generic: surface
- main:
- paragraph: The Orrery
- paragraph: "Labels: ON"
- paragraph:
- button "Toggle labels"
- paragraph: Attached to Control Room.
- contentinfo:
- generic: Information Wall
- generic: Waiting for shared state.
- heading "State and metadata" [level=2]
- button "Refresh state"
- generic "Session and exhibit metadata"
- generic "Current persistent state"
- heading "Protocol diagnostics" [level=2]
- generic "Incoming events"
- generic "Protocol and errors"
@@ -0,0 +1,846 @@
- banner:
- heading "XZBT-NGN Exhibit Engine" [level=1]
- paragraph: Contract 5.2/5.3 · One exhibit at a time
- main:
- heading "Connection" [level=2]
- generic: Exhibit URL (same origin)
- textbox "Exhibit URL (same origin)":
- /placeholder: /public/exhibits/example/index.html
- text: /test-fixtures/reference-exhibits/scifi/index.html
- button "Load exhibit" [active]
- button "Reconnect"
- button "Disconnect"
- paragraph: Enter a trusted exhibit's local served path or a URL on this origin. Load exhibit also switches exhibits. Reconnect starts a new session, or reloads the last exhibit after disconnect.
- status: connected · synchronized
- paragraph: SciFi-XZBT · 5.2.0 · Contract 5.3
- paragraph: "Exhibit location: http://127.0.0.1:4173/test-fixtures/reference-exhibits/scifi/index.html"
- iframe:
- banner:
- generic "Click to Change Sci-Fi Universe":
- generic: STARFLIGHT
- generic: ▼
- generic: "INTERPRISE-G: MAIN BRIDGE"
- button "MUTE"
- generic: 75%
- generic: STARFLIGHT SOUND MATRIX v2.9
- main:
- complementary:
- generic: STARSHIP PRESETS
- 'button "Interprise-G: Main Bridge STARFLIGHT COMMAND"':
- generic: "Interprise-G: Main Bridge"
- generic: STARFLIGHT COMMAND
- 'button "Interprise-G: Main Engineering STARFLIGHT COMMAND"':
- generic: "Interprise-G: Main Engineering"
- generic: STARFLIGHT COMMAND
- 'button "Interprise-G: Crew Quarters STARFLIGHT COMMAND"':
- generic: "Interprise-G: Crew Quarters"
- generic: STARFLIGHT COMMAND
- 'button "USS Wayfarer: Bridge STARFLIGHT COMMAND"':
- generic: "USS Wayfarer: Bridge"
- generic: STARFLIGHT COMMAND
- 'button "USS Wayfarer: Class-N Worp Core STARFLIGHT COMMAND"':
- generic: "USS Wayfarer: Class-N Worp Core"
- generic: STARFLIGHT COMMAND
- 'button "USS Defiance: Tactical Bridge STARFLIGHT COMMAND"':
- generic: "USS Defiance: Tactical Bridge"
- generic: STARFLIGHT COMMAND
- 'button "Deep Space 8: Ops Center STARFLIGHT COMMAND"':
- generic: "Deep Space 8: Ops Center"
- generic: STARFLIGHT COMMAND
- 'button "Interprise NCC-1701.5: Bridge (TOS) STARFLIGHT COMMAND"':
- generic: "Interprise NCC-1701.5: Bridge (TOS)"
- generic: STARFLIGHT COMMAND
- 'button "Interprise NCC-1701.5: Engineering (TOS) STARFLIGHT COMMAND"':
- generic: "Interprise NCC-1701.5: Engineering (TOS)"
- generic: STARFLIGHT COMMAND
- 'button "Interprise NS-01: Command Bridge STARFLIGHT COMMAND"':
- generic: "Interprise NS-01: Command Bridge"
- generic: STARFLIGHT COMMAND
- generic: "INTERPRISE-G: MAIN BRIDGE"
- generic: Warm, low-frequency 50Hz hull tone with gentle ventilation and soft LCARD computer chirps.
- generic: AUDIO ENGINE
- generic: STANDBY
- generic: CORE FREQ
- generic: 58.0 Hz
- button "▶ ENGAGE":
- generic: ▶
- generic: ENGAGE
- button "WARP JUMP"
- button "RED ALERT"
- button "YELLOW ALERT"
- button "WATCH EXPERIENCE"
- generic: Full-screen procedural visuals, soundscape, telemetry, events, and optional local AI announcements.
- 'generic "Toggle starship viewport window frame (ON: framed starship lounge / OFF: pure deep space)"':
- generic: VIEWPORT
- checkbox "Toggle Observation Viewport Frame" [checked]
- generic: "ON"
- 'generic "Toggle vertical structural window pillars / mullions (OFF: unobstructed panoramic view / ON: structural posts)"':
- generic: PILLARS
- checkbox "Toggle Window Pillars"
- generic: "OFF"
- generic "Controls how frequently and intensely Observation generates transient visual activity":
- generic: ACTIVITY
- slider "Observation activity level"
- generic: 60%
- generic "Keep OBSERVATION profile/status information visible. Turn off to fade it out over 30 seconds.":
- generic: HUD HOLD
- checkbox "Keep Observation information visible" [checked]
- generic: "ON"
- generic: MAIN MASTER VOLUME
- generic: 75%
- generic: "-2.5 dB"
- button "MUTE"
- button "25%"
- button "50%"
- button "75%"
- button "MAX"
- button "−"
- slider "Main Volume"
- button "+"
- generic: FNC // FUTURISTIC NOICE CANCELLATION
- generic: ACTIVE
- button "FNC ENABLED" [pressed]
- generic: FNC LEVEL
- slider "Futuristic Noice Cancellation level"
- generic: 65%
- generic: "FNC comfort filter remains applied. Adaptive watchdog memory reset: preset change."
- generic: ACOUSTIC FREQUENCY SPECTRUM
- generic: PROCEDURAL HARMONIC ANALYSIS
- generic: "SPECTRUM BIN: 32 CH // REAL-TIME FFT"
- generic: PROCEDURAL SOUND ENGINE MIXER
- generic: LIVE PARAMETER MODULATION
- generic: 1. HULL DRONE
- generic: 65%
- generic: LEVEL
- slider
- generic: BASE TONE
- generic: 50 Hz
- slider
- generic: DAMPING CUTOFF
- generic: 105 Hz
- slider
- generic: 2. WORP CORE
- generic: 35%
- generic: LEVEL
- slider
- generic: PULSE RATE (BPM)
- generic: 48 BPM
- slider
- generic: REACTOR PITCH
- generic: 58 Hz
- slider
- generic: 3. LIFE SUPPORT
- generic: 55%
- generic: LEVEL
- slider
- generic: AIRFLOW AIR FILTER
- generic: 1600 Hz
- slider
- generic: 4. TELEMETRY
- generic: 45%
- generic: LEVEL
- slider
- generic: BACKGROUND CHIRP DENSITY
- generic: 65%
- slider
- complementary:
- generic: INTERMIX CASCADE
- generic: INTERMIX CHAMBER // ACTIVE
- generic: GENERATIVE EXPERIENCE
- generic: LOCAL WEBLLM + KOKORO TTS
- generic: LOCAL GENERATIVE SYSTEM
- generic: STANDBY
- text: LANGUAGE MODEL
- text: Qwen3-1.7B-q4f16_1-MLC
- text: Automatically prepared when the experience starts. No model selection required.
- text: WEBLLM
- generic: "OFF"
- text: KOKORO
- generic: "OFF"
- button "PREPARE AI"
- button "GENERATE NOW" [disabled]
- checkbox "AUTO UPDATES" [checked]
- text: AUTO UPDATES
- checkbox "SPEAK" [checked]
- text: SPEAK
- combobox "Kokoro voice":
- option "Kokoro voice loads on preparation" [selected]
- generic: VOICE AUTOMATION
- generic: 84%
- slider "Robotic voice effect intensity"
- generic: AUTO CADENCE
- generic: 90-180 SEC
- slider
- generic: AI and neural voice models load only when needed and are cached by the browser when supported.
- generic: GENERATIVE CHANNEL STANDBY
- generic: TV PRESENTATION
- generic: CAST-FRIENDLY 16:9
- checkbox "LOCK EXPERIENCE TO 16:9" [checked]
- text: LOCK EXPERIENCE TO 16:9
- generic: RENDER DENSITY
- generic: 1080P TARGET
- combobox:
- option "720P PERFORMANCE"
- option "1080P STANDARD" [selected]
- option "1440P HIGH"
- option "2160P ULTRA"
- generic: The scene keeps a canonical 16:9 layout on phones, PCs, and cast displays. Chrome still negotiates the final Cast stream resolution.
- generic: SLEEP TIMER
- generic: TIMER INACTIVE (CONTINUOUS)
- button "15M"
- button "30M"
- button "60M"
- button "OFF"
- generic: LCARD KEYPAD
- button "COM BADGE CHIRP"
- button "DOOR PNEUMATIC SWISH"
- button "BOSUN'S PIPE WHISTLE"
- button "MEDBAY ECG MONITOR"
- button "CARDASSIAN BULKHEAD DOOR"
- button "TURBOCHUTE WHOOSH"
- button "FABRICATOR SHIMMER"
- button "TRANSLOCATOR CYCLE"
- button "LCARD SINGLE CHIRP"
- contentinfo:
- generic: "SYSTEM STATUS: NORMAL"
- link "VIBE ENGINEERED BY LABYRICORN STUDIOS":
- /url: https://www.labyricorn.com/
- generic: "SPACE: PLAY/PAUSE | M: MUTE | ↑/↓: VOLUME"
- heading "Exhibit controls (61)" [level=2]
- generic "Capabilities"
- paragraph: Reported values are authoritative. New values are drafts; select Set or Invoke to submit. Rediscovery resets drafts.
- heading "audio" [level=3]
- article:
- heading "Master Volume" [level=3]
- code: mix.master
- paragraph: range · readable · writable
- status: "Reported value: 0.75"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.75"
- button "Set"
- article:
- heading "Hull Drone Level" [level=3]
- code: mix.hull.level
- paragraph: range · readable · writable
- status: "Reported value: 0.65"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.65"
- button "Set"
- article:
- heading "Hull Drone Frequency" [level=3]
- code: mix.hull.frequency
- paragraph: range · readable · writable
- status: "Reported value: 50"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "50"
- button "Set"
- article:
- heading "Hull Drone Cutoff" [level=3]
- code: mix.hull.cutoff
- paragraph: range · readable · writable
- status: "Reported value: 105"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "105"
- button "Set"
- article:
- heading "Drive / Core Level" [level=3]
- code: mix.drive.level
- paragraph: range · readable · writable
- status: "Reported value: 0.35"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.35"
- button "Set"
- article:
- heading "Drive Pulse Rate" [level=3]
- code: mix.drive.pulse-rate
- paragraph: range · readable · writable
- status: "Reported value: 48"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "48"
- button "Set"
- article:
- heading "Drive Carrier Frequency" [level=3]
- code: mix.drive.carrier
- paragraph: range · readable · writable
- status: "Reported value: 58"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "58"
- button "Set"
- article:
- heading "Environmental Airflow Level" [level=3]
- code: mix.environment.level
- paragraph: range · readable · writable
- status: "Reported value: 0.55"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.55"
- button "Set"
- article:
- heading "Environmental Filter Cutoff" [level=3]
- code: mix.environment.cutoff
- paragraph: range · readable · writable
- status: "Reported value: 1600"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "1600"
- button "Set"
- article:
- heading "Telemetry Level" [level=3]
- code: mix.telemetry.level
- paragraph: range · readable · writable
- status: "Reported value: 0.45"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.45"
- button "Set"
- article:
- heading "Telemetry Density" [level=3]
- code: mix.telemetry.density
- paragraph: range · readable · writable
- status: "Reported value: 0.65"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.65"
- button "Set"
- article:
- heading "Futuristic Noise Cancellation Level" [level=3]
- code: fnc.level
- paragraph: range · readable · writable
- status: "Reported value: 0.65"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.65"
- button "Set"
- article:
- heading "Futuristic Noise Cancellation Active" [level=3]
- code: fnc.enabled
- paragraph: state · readable · writable
- status: "Reported value: true"
- generic "Target descriptor"
- paragraph
- text: New value
- checkbox "New value" [checked]
- button "Set"
- heading "speech" [level=3]
- article:
- heading "Speech Robotic Modulation" [level=3]
- code: speech.robot-amount
- paragraph: range · readable · writable
- status: "Reported value: 0.84"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.84"
- button "Set"
- article:
- heading "Speak Text Line" [level=3]
- code: speech.say
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Generate Ambient AI Announcement" [level=3]
- code: speech.generate-announcement
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- heading "observation" [level=3]
- article:
- heading "Observation Visual Activity" [level=3]
- code: view.activity
- paragraph: range · readable · writable
- status: "Reported value: 0.6"
- generic "Target descriptor"
- paragraph
- text: New value
- spinbutton "New value": "0.6"
- button "Set"
- article:
- heading "Observation Viewport Active" [level=3]
- code: view.observation
- paragraph: state · readable · writable
- status: "Reported value: false"
- generic "Target descriptor"
- paragraph
- text: New value
- checkbox "New value"
- button "Set"
- article:
- heading "Starship Bezel Frame Framing" [level=3]
- code: view.viewport-frame
- paragraph: state · readable · writable
- status: "Reported value: true"
- generic "Target descriptor"
- paragraph
- text: New value
- checkbox "New value" [checked]
- button "Set"
- heading "transport" [level=3]
- article:
- heading "Audio Engine Online" [level=3]
- code: transport.playing
- paragraph: state · readable · writable
- status: "Reported value: false"
- generic "Target descriptor"
- paragraph
- text: New value
- checkbox "New value"
- button "Set"
- article:
- heading "Master Mute" [level=3]
- code: transport.muted
- paragraph: state · readable · writable
- status: "Reported value: false"
- generic "Target descriptor"
- paragraph
- text: New value
- checkbox "New value"
- button "Set"
- heading "alert" [level=3]
- article:
- heading "Active Tactical Alert Status" [level=3]
- code: alert.active
- paragraph: selection · readable · writable
- status: "Reported value: \"none\""
- generic "Target descriptor"
- paragraph
- text: New value
- combobox "New value":
- option "Condition Green (Normal)" [selected]
- option "Yellow Alert"
- option "Red Alert"
- button "Set"
- heading "universe" [level=3]
- article:
- heading "Active Sci-Fi Universe" [level=3]
- code: universe.selected
- paragraph: selection · readable · writable
- status: "Reported value: \"starfleet\""
- generic "Target descriptor"
- paragraph
- text: New value
- combobox "New value":
- option "Starfleet / Galaxy" [selected]
- option "Whataverse / Tardix"
- option "Industrial / Weyland"
- option "Bioships / Leviathan"
- option "Retro Future / 1960s"
- option "Colonial Military"
- option "Deep Space Generation"
- option "Frontier & Salvage"
- option "Orbital Stations & Docks"
- option "Whimsical Fleet"
- button "Set"
- heading "preset" [level=3]
- article:
- heading "Active Audio Preset" [level=3]
- code: preset.selected
- paragraph: selection · readable · writable
- status: "Reported value: \"tng-bridge\""
- generic "Target descriptor"
- paragraph
- text: New value
- combobox "New value":
- 'option "Interprise-G: Main Bridge" [selected]'
- 'option "Interprise-G: Main Engineering"'
- 'option "Interprise-G: Crew Quarters"'
- 'option "USS Wayfarer: Bridge"'
- 'option "USS Wayfarer: Class-N Worp Core"'
- 'option "USS Defiance: Tactical Bridge"'
- 'option "Deep Space 8: Ops Center"'
- 'option "Interprise NCC-1701.5: Bridge (TOS)"'
- 'option "Interprise NCC-1701.5: Engineering (TOS)"'
- 'option "Interprise NS-01: Command Bridge"'
- option "1962 Classic Console (1st / 2nd Doctors)"
- option "Edwardian Secondary Console (4th Doctor)"
- option "The Coral Living TARDIX (9th / 10th Doctors)"
- option "The Bronze Workshop (11th Doctor)"
- option "The Cool Machine (12th Doctor)"
- option "The Humming Crystal Console (13th Doctor)"
- option "The Endless White (14th / 15th Doctors)"
- 'option "USCSS Nostramo: Ore Refinery Bridge"'
- 'option "Serenety: Firewing-Class Cargo Hold"'
- 'option "Red Dwarve: Main Drive Corridor"'
- 'option "Starbug Z: Cockpit Environment"'
- 'option "The Rasa: Dark Matter Bridge"'
- 'option "Rocinanta: Combat Ops & Epsilon Drive"'
- 'option "Hawk Translocator: Command Module"'
- 'option "Valley Foundry: Agro-Dome Forest Hub"'
- 'option "Meya: Leviathon Central Nexus"'
- 'option "Talym: Gunship Neural Bridge"'
- 'option "The Lexxi: Primary Organ Bridge"'
- 'option "Vorlan Cruiser: Sentient Core"'
- 'option "Wraithe Hive Ship: Throne Chamber"'
- 'option "Species 8675309: Fluid Bioship"'
- 'option "Jupiter Duece: Upper Deck Astrogator"'
- 'option "The Liberation: Zen Flight Bridge"'
- 'option "USS Cygnis: Victorian Engine Hall"'
- 'option "USS Palomina: Deep Research Pod"'
- 'option "Discovery Zero: Habitation Centrifuge"'
- 'option "Dim Star: Bomb Bay & Quarters"'
- 'option "Gunstarr: Tactical Combat Cockpit"'
- 'option "The Seeker: 25th Century Flagship"'
- 'option "USS Solaco: Conestega Hangar Deck"'
- 'option "Battlestar Galactica: Combat Information Center (CIC)"'
- 'option "Pale Star: Minbara/Vorlan Hybrid Bridge"'
- 'option "EAS Agamemnon II: Omega Destroyer Bridge"'
- 'option "Andromeda Ascending: Command Deck"'
- 'option "Excaliber: Triumph-Class Heavy Combat Core"'
- 'option "Colonial Adder Mk II: Cockpit Atmosphere"'
- 'option "The Avalin: Interstellar Cruise Concourse"'
- 'option "The Nightflier: Telepathic Corridor"'
- 'option "USS Ascention: Generation Ship Promenade"'
- 'option "Ark Zero: Evacuation Ark Bridge"'
- 'option "Icarus I: Solar Shield Core"'
- 'option "Event Boundary: Gravity Singularity Core"'
- 'option "Lewis & Clarke: Rescue Cutter Bridge"'
- 'option "The Betsy: Salvage Freighter Mess"'
- 'option "BeBoppa: Living Quarters & Hangar"'
- 'option "Outlaw Sun: Grapple Bridge"'
- 'option "Scorpius: Wanderer Salvage Vessel"'
- 'option "The Raider: Havoc Shuttle Bridge"'
- 'option "The Milan: M-Ship Cockpit Lounge"'
- 'option "Babylon 4: Core Control & Zocolo"'
- 'option "Moonbase Beta: Main Mission Control"'
- 'option "Sebastopol Station: Habitation Deck"'
- 'option "Tyco Station: Asteroid Construction Bay"'
- 'option "Ceres Minor Station: Sub-Crustal Tunnels"'
- 'option "Gatehouse Station: Quarantine Transfer Deck"'
- 'option "USS Norval: Command Bridge"'
- 'option "NSEA Protractor: Beryllium Orb Engine Room"'
- 'option "Heart of Silver: Unlikelihood Bridge"'
- 'option "HMS Camden Key: Flight Deck & Mess"'
- 'option "Spaceorb One: Mega-Warship Bridge"'
- button "Set"
- heading "display" [level=3]
- article:
- heading "Display Ticker Message (Transient)" [level=3]
- code: display.ticker
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- heading "event" [level=3]
- article:
- heading "Red Alert Impulse" [level=3]
- code: event.alert-red
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Warp Jump Impulse" [level=3]
- code: event.warp-jump
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Demat Cycle Impulse" [level=3]
- code: event.demat
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Time Vortex Impulse" [level=3]
- code: event.vortex
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Cloister Bell Impulse" [level=3]
- code: event.cloister
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Flak Barrage Impulse" [level=3]
- code: event.flak-barrage
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "FTL Jump Impulse" [level=3]
- code: event.ftl-jump
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Singularity Engage Impulse" [level=3]
- code: event.singularity
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Solar Flare Roar Impulse" [level=3]
- code: event.solar-roar
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Afterburner Ignite Impulse" [level=3]
- code: event.afterburner
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Ludicrous Speed Impulse" [level=3]
- code: event.ludicrous-speed
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Improbability Drive Flip" [level=3]
- code: event.improbability-flip
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- heading "sfx" [level=3]
- article:
- heading "Comm Badge Chime" [level=3]
- code: sfx.comm-badge
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Pneumatic Door Swish" [level=3]
- code: sfx.door-swish
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Bosun Pipe Call" [level=3]
- code: sfx.bosun-whistle
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Medical Vital Monitor" [level=3]
- code: sfx.medical-monitor
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Heavy Bulkhead Door" [level=3]
- code: sfx.cardassian-door
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Turbochute Whoosh" [level=3]
- code: sfx.turbolift
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Fabricator Materialize" [level=3]
- code: sfx.replicator
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Translocator Beam" [level=3]
- code: sfx.transporter
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Console Single Chirp" [level=3]
- code: sfx.console-chirp
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Sonic Acoustic Screwdriver" [level=3]
- code: sfx.sonic
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Console Mechanical Lever Clunk" [level=3]
- code: sfx.lever-clunk
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Tardix Wood & Lock Door" [level=3]
- code: sfx.tardix-door
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Demat Switch Rotor" [level=3]
- code: sfx.demat-switch
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Telepathic Circuit Chime" [level=3]
- code: sfx.telepathic-chime
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Air Handler Valve Thud" [level=3]
- code: sfx.air-handler
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Mag-Boot Solenoid Latch" [level=3]
- code: sfx.mag-boot
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Comlock Electronic Tone" [level=3]
- code: sfx.comlock
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Solar Radiation Wind" [level=3]
- code: sfx.solar-roar
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Cassette Magnetic Transport Clunk" [level=3]
- code: sfx.tape-clunk
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Thruster Burner Pulse" [level=3]
- code: sfx.afterburner
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Radiation Geiger Counter" [level=3]
- code: sfx.geiger
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Air Valve & Dock Clamp" [level=3]
- code: sfx.dock-clamp
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "Dradis Combat Sonar Ping" [level=3]
- code: sfx.dradis-ping
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- article:
- heading "HAL Logic Melodic Chime" [level=3]
- code: sfx.hal-chime
- paragraph: impulse · not readable · not writable
- status: No persistent value reported.
- generic "Target descriptor"
- paragraph
- button "Invoke"
- heading "Presentation surfaces" [level=2]: Presentation surfaces
- paragraph: Open Contract 5.3 presentation surfaces locally below. URLs resolve against the supplying exhibit. Disconnecting or switching exhibits closes these views. Remote/cast displays remain deferred.
- paragraph: No presentation surfaces advertised.
- heading "State and metadata" [level=2]
- button "Refresh state"
- generic "Session and exhibit metadata"
- generic "Current persistent state"
- heading "Protocol diagnostics" [level=2]
- generic "Incoming events"
- generic "Protocol and errors"
@@ -0,0 +1,180 @@
Step 6.6 — Museum Gallery end-to-end validation through the NGN operator UI
Server: pre-existing `npm start` server (node server/serve.js) on http://127.0.0.1:4173,
started before this session and left running. A second instance started for
validation failed with EADDRINUSE and exited; the served state was unchanged.
NGN UI: http://127.0.0.1:4173/
Exhibit: http://127.0.0.1:4173/test-fixtures/reference-exhibits/museum-gallery/control.html
Replacement exhibit: http://127.0.0.1:4173/test-fixtures/reference-exhibits/scifi/index.html
Method: live browser session against the served page; values read from the live DOM, the
exhibit frames, and NGN's own diagnostics panes. No test doubles.
--------------------------------------------------------------------
1. Initial connection (Load exhibit)
--------------------------------------------------------------------
status: connected · synchronized
identity: Museum Gallery · 0.1.0 · Contract 5.3
metadata: { sessionId: "sess-1f54f",
contract: { major: 5, minor: 3 },
exhibit: { product: "Museum Gallery", version: "0.1.0", build: "reference-exhibit" },
registryRevision: 1, stateRevision: 0, sequence: null }
capabilities: render: ready
targets (5): artifact.selected (selection, r/w), lighting.level (range, r/w),
rotation.speed (range, r/w), labels.enabled (state, r/w),
action.spotlight-flash (impulse, not readable, not writable)
state: { "artifact.selected": "the-orrery", "lighting.level": 0.6,
"rotation.speed": 0.4, "labels.enabled": true }
error log: one SESSION entry, no errors
--------------------------------------------------------------------
2. Surface discovery and primary handling
--------------------------------------------------------------------
Presentation surfaces (3):
surface.control Control Room Primary Role: control URL: control.html
surface.artifact Artifact Display Non-primary Role: ambient URL: artifact.html
surface.info-wall Information Wall Non-primary Role: information URL: info-wall.html
Primary card buttons: Open disabled, Reload disabled, Close disabled
Primary card status: "Open in the authoritative control frame. Use Connection controls to
reload or disconnect."
Non-primary panes rendered and each reported: "Attached to Control Room."
Control Room readout "Attached non-primary surfaces": 2
--------------------------------------------------------------------
3. Lifecycle (participant count in the authoritative Control Room)
--------------------------------------------------------------------
open both -> 2
reload -> 2
reload again -> 2
close one -> 1
reopen -> 2
Reload freshness probe: a marker written to the secondary frame contentWindow was absent
after reload (fresh document), and the document re-attached and re-rendered current state.
--------------------------------------------------------------------
4. Shared-state synchronization
--------------------------------------------------------------------
Control -> secondaries
Control Room combobox -> "star-map":
event { type: "selection.changed", sequence: 1, stateRevision: 1,
target: "artifact.selected", value: "star-map", source: "ui" }
Control Room "Star Map"; Artifact Display "Star Map"; Information Wall "Star Map"
Control Room lighting range -> 0.25:
event { type: "state.changed", sequence: 2, stateRevision: 2,
target: "lighting.level", value: 0.25, source: "ui" }
Control Room "25%"; Artifact Display "Lighting: 25%"
Secondary -> primary -> secondaries
Real mouse click on Artifact Display "Cycle artifact" (authoritative value "star-map"):
Control Room combobox became "meteorite"; Control Room label "Meteorite Fragment"
event { type: "selection.changed", sequence: 3, stateRevision: 3,
target: "artifact.selected", value: "meteorite", source: "ui" }
Information Wall -> "Meteorite Fragment"; Artifact Display re-rendered authoritative result
Sustained convergence (both secondaries open, alternating origins)
step 1 control select the-orrery -> all views "The Orrery" revision 7 count 2
step 2 info-wall toggle labels -> labels.enabled true revision 8 count 2
step 3 control rotation 0.6 -> rotation.speed 0.6 revision 9 count 2
step 4 artifact-display cycle -> artifact.selected star-map revision 10 count 2
Control Room, Artifact Display, Information Wall and NGN reported state all agreed
after every step.
Late join
close Information Wall -> count 1
mutate: rotation 1.7, labels OFF -> stateRevision 5
reopen Information Wall -> immediately rendered "Meteorite Fragment" / "Labels: OFF",
count back to 2
Reload recovery
mutate: lighting 0.9 -> stateRevision 6
reload Artifact Display -> fresh document returned with "Meteorite Fragment",
"Lighting: 90%", "Rotation: 1.7x" (current state, not defaults); count still 2
--------------------------------------------------------------------
5. NGN host commands
--------------------------------------------------------------------
Refresh state (state.get): succeeded; stateRevision 10, status connected · synchronized,
no error
set lighting.level = 0.35: succeeded; Control Room "35%" (range 0.35),
Artifact Display "Lighting: 35%";
event { type: "state.changed", sequence: 11, stateRevision: 11,
target: "lighting.level", value: 0.35,
source: "host", correlationId: "ngn-2-4" }
set artifact.selected = meteorite: succeeded; Control Room / Artifact Display /
Information Wall all "Meteorite Fragment";
event { type: "selection.changed", sequence: 12, stateRevision: 12,
target: "artifact.selected", value: "meteorite",
source: "host", correlationId: "ngn-2-6" }
invoke action.spotlight-flash: succeeded;
event { type: "action.executed", sequence: 13,
target: "action.spotlight-flash", args: {},
source: "host", correlationId: "ngn-2-8" };
exhibit gallery.spotlightFlashCount incremented;
Control Room and both secondaries announcement nodes flashed
"Spotlight flashed." (captured by a DOM mutation observer on the
Artifact Display announcement node: seen transitions
["Spotlight flashed.", "Waiting for shared state."])
--------------------------------------------------------------------
6. Reconnect and exhibit replacement
--------------------------------------------------------------------
Disconnect:
status: disconnected · not synchronized
catalog: "Connect an exhibit to discover its controls."
surfaces: "No presentation surfaces advertised."; surface cards 0; surface iframes 0
control frame removed; state {}; metadata all null; no error entries
Reconnect:
status: connected · synchronized; session sess-15cf1; contract { major: 5, minor: 3 }
targets (5); surfaces (3) with surface.control primary; participant count 0
no stale panes; both secondaries reopened -> "Attached to Control Room.", count 2
Switch to SciFi:
identity: SciFi-XZBT · 5.2.0 · Contract 5.3
metadata: sessionId "sess-2akzu3a7", contract { major: 5, minor: 3 },
registryRevision 1, stateRevision 0
status: connected · synchronized; targets (61); surfaces: none advertised
iframes referencing museum-gallery: 0
Switch back to Museum Gallery:
session sess-126c6; contract { major: 5, minor: 3 }; targets (5); surfaces (3) with
correct primary; participant count 0; iframes referencing scifi: 0
state: fresh exhibit defaults, stateRevision 0
--------------------------------------------------------------------
7. Failure isolation (live)
--------------------------------------------------------------------
Artifact Display document globals:
XZBTContractCore: undefined
MuseumGalleryContract: undefined
MuseumGalleryExhibit: undefined
XZBTHostTransport: undefined
MuseumGallerySurfaceBus: present
__museumGalleryDebug.core: absent
Forged protocol messages posted directly to the secondary window:
{ xzbt: "5.3", type: "hello", requestId: "probe-secondary", supportedContractMajors: [5] }
{ xzbt: "5.3", type: "set", requestId: "probe-set", sessionId: "x",
target: "artifact.selected", value: "meteorite" }
-> responses received: none; authoritative selection unchanged ("The Orrery")
Surface-local failure: Artifact Display frame navigated to
/test-fixtures/reference-exhibits/museum-gallery/does-not-exist.html (served "Not found")
-> NGN status stayed "connected · synchronized" on session sess-126c6;
control frame still control.html; registry/state unaffected; no error entry;
participant count 2 -> 0 with no stale entry
NGN per-surface Reload on the failed pane:
-> frame back at artifact.html, "Attached to Control Room.", participant count 1,
session still synchronized, no error entry
Automated-only isolation evidence (not re-injected live): malformed/invalid descriptor
catalogs, isolated HTTP/frame/reload failures, external frame removal detection, stalled
surface resource, redirect refusal on resource check, presentation-window impersonation
refusal, transport source/origin validation.
--------------------------------------------------------------------
8. Automated verification
--------------------------------------------------------------------
Focused: node --test tests/museum-gallery.test.js tests/local-surfaces.test.js
tests/surface-validation.test.js tests/postmessage-interop.test.js
tests/connection.test.js
tests 107 / pass 107 / fail 0
Full: node --test
tests 129 / pass 129 / fail 0
git diff --check -> clean (exit 0)
python devlog_editor.py --validate -> devlog-editor: devlog is valid (exit 0)