generated from Labyricorn/labyricorn-project-template
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.
181 lines
10 KiB
Plaintext
181 lines
10 KiB
Plaintext
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)
|