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.
257 lines
12 KiB
Markdown
257 lines
12 KiB
Markdown
# XZBT-NGN Step 6.6 — Reference Exhibit End-to-End Validation
|
|
|
|
Status: PASS — no implementation changes were required.
|
|
|
|
Step 6.6 validates Museum Gallery end-to-end as a complete Contract 5.3 reference
|
|
exhibit operating through the normal NGN operator UI. It is a validation task: no
|
|
architecture was redesigned, no features were added, and no source file was modified.
|
|
|
|
## A. Environment
|
|
|
|
| Item | Value |
|
|
| --- | --- |
|
|
| NGN UI | `http://127.0.0.1:4173/` |
|
|
| Server | The already-running `npm start` server on port 4173 (started at 16:43, before this session). A second instance started for validation failed to bind with `EADDRINUSE` and exited, so the served state was unchanged and the running server was left untouched. |
|
|
| Exhibit under test | `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` |
|
|
| Working tree | Step 6.3/6.4/6.5 uncommitted work preserved as found; HEAD `ed76cf6` |
|
|
| Method | Real NGN UI in a browser, driven through the served page (no test doubles) |
|
|
|
|
## B. Initial connection
|
|
|
|
Observed through the served NGN page after `Load exhibit`:
|
|
|
|
- Status: `connected · synchronized`
|
|
- Session: `sess-1f54f`
|
|
- Negotiated contract: `{ major: 5, minor: 3 }`
|
|
- Exhibit metadata: `Museum Gallery · 0.1.0 · build reference-exhibit`
|
|
- `registryRevision` 1, `stateRevision` 0
|
|
- Capabilities: `render: ready`
|
|
- Target registry discovered (5):
|
|
|
|
| Target | Kind | Access |
|
|
| --- | --- | --- |
|
|
| `artifact.selected` | selection | readable · writable |
|
|
| `lighting.level` | range | readable · writable |
|
|
| `rotation.speed` | range | readable · writable |
|
|
| `labels.enabled` | state | readable · writable |
|
|
| `action.spotlight-flash` | impulse | not readable · not writable |
|
|
|
|
- State snapshot received: `artifact.selected="the-orrery"`, `lighting.level=0.6`,
|
|
`rotation.speed=0.4`, `labels.enabled=true`
|
|
- Protocol/error log: one `SESSION` entry, no errors
|
|
|
|
## C. Surface discovery and primary handling
|
|
|
|
`Presentation surfaces (3)` discovered, exactly the three the exhibit advertises:
|
|
|
|
| id | Label | Primary | Role | URL |
|
|
| --- | --- | --- | --- | --- |
|
|
| `surface.control` | Control Room | yes | control | `control.html` |
|
|
| `surface.artifact` | Artifact Display | no | ambient | `artifact.html` |
|
|
| `surface.info-wall` | Information Wall | no | information | `info-wall.html` |
|
|
|
|
Primary handling: the primary is not duplicated as a local pane. Its card carries the
|
|
`Primary` badge, shows `Open in the authoritative control frame. Use Connection controls
|
|
to reload or disconnect.`, and its Open/Reload/Close buttons are disabled. The two
|
|
non-primary surfaces open as local panes and each renders and reports
|
|
`Attached to Control Room.`
|
|
|
|
The Control Room's own `Attached non-primary surfaces` readout (the exhibit's participant
|
|
count) became `2` when both panes were open.
|
|
|
|
## D. Lifecycle validation
|
|
|
|
Measured participant count in the authoritative Control Room:
|
|
|
|
```text
|
|
open both: 2
|
|
reload: 2
|
|
reload again: 2
|
|
close one: 1
|
|
reopen: 2
|
|
```
|
|
|
|
Each reload produced a fresh secondary document (verified by a marker placed on the
|
|
frame's `contentWindow` disappearing after reload), which then re-attached and rendered
|
|
the current authoritative state. No ratcheting and no stale participant entries were
|
|
observed at any point.
|
|
|
|
## E. Shared-state validation
|
|
|
|
### Control -> secondaries
|
|
|
|
| Change made in Control Room | Observed propagation |
|
|
| --- | --- |
|
|
| Selected artifact -> Star Map | `selection.changed`, sequence 1, `stateRevision` 1, `source: "ui"`; both secondaries rendered `Star Map` |
|
|
| Lighting level -> 25% | `state.changed`, sequence 2, `stateRevision` 2, `source: "ui"`; Artifact Display rendered `Lighting: 25%` |
|
|
|
|
Control Room, Artifact Display, Information Wall and NGN's reported state all agreed
|
|
after each change.
|
|
|
|
### Secondary -> primary -> secondaries
|
|
|
|
A real mouse click on the Artifact Display's native `Cycle artifact` control while the
|
|
authoritative selection was `star-map`:
|
|
|
|
- Control Room's authoritative selection became `meteorite` (its combobox followed)
|
|
- `selection.changed`, sequence 3, `stateRevision` 3, `source: "ui"`
|
|
- Information Wall updated to `Meteorite Fragment`
|
|
- Artifact Display re-rendered from the authoritative result
|
|
|
|
The secondary remained a mirror: it holds no Core (see section H) and only routes
|
|
mutations back through the owner's canonical path.
|
|
|
|
### Late join
|
|
|
|
Information Wall closed (count 1) -> authoritative state mutated (rotation 1.7,
|
|
labels OFF, `stateRevision` 5) -> Information Wall reopened: it immediately rendered
|
|
`Meteorite Fragment` and `Labels: OFF`, and the count returned to 2.
|
|
|
|
### Reload recovery
|
|
|
|
Lighting mutated to 90% (`stateRevision` 6) -> Artifact Display reloaded: a fresh
|
|
document (marker gone) returned showing `Meteorite Fragment`, `Lighting: 90%`,
|
|
`Rotation: 1.7x` — current state, not exhibit defaults — with the count still 2.
|
|
|
|
### Sustained convergence
|
|
|
|
Four consecutive normal changes alternating between the primary and both secondaries
|
|
(control selection, Information Wall toggle, control rotation, Artifact Display cycle)
|
|
left Control Room, Artifact Display, Information Wall and NGN all in agreement at every
|
|
step, with revisions advancing 7 -> 8 -> 9 -> 10 and the count steady at 2.
|
|
|
|
## F. Host-command validation (NGN UI)
|
|
|
|
| Operation | NGN control used | Result |
|
|
| --- | --- | --- |
|
|
| Readable state query | `Refresh state` (`state.get`) | Succeeded; snapshot matched, `stateRevision` 10, status `connected · synchronized`, no error |
|
|
| `set` (range) | `lighting.level` -> `0.35` + `Set` | Succeeded; Control Room 35%, Artifact Display `Lighting: 35%`, `state.changed` revision 11, `source: "host"`, `correlationId: ngn-2-4` |
|
|
| `set` (selection) | `artifact.selected` -> Meteorite Fragment + `Set` | Succeeded; all surfaces `Meteorite Fragment`, `selection.changed` revision 12, `source: "host"`, `correlationId: ngn-2-6` |
|
|
| `invoke` (impulse) | `action.spotlight-flash` + `Invoke` | Succeeded; `action.executed` sequence 13, `source: "host"`, `correlationId: ngn-2-8`; exhibit `spotlightFlashCount` incremented; Control Room and both secondaries flashed `Spotlight flashed.` |
|
|
|
|
Each command left NGN's own state synchronized and produced no error entry. Instrumenting
|
|
the Artifact Display's announcement node with a DOM observer confirmed the host-initiated
|
|
`action.executed` event actually reached the secondary (it flashed, then returned to idle
|
|
after the announcer's 2.6 s window).
|
|
|
|
## G. Reconnect and replacement
|
|
|
|
### Disconnect / reconnect
|
|
|
|
- `Disconnect`: status `disconnected · not synchronized`; catalog reset to
|
|
`Connect an exhibit to discover its controls.`; surfaces reset to
|
|
`No presentation surfaces advertised.`; both local panes removed (0 surface iframes
|
|
remaining); control frame removed; reported state `{}`; no error entries.
|
|
- `Reconnect`: new session `sess-15cf1`, Contract 5.3, all three surfaces rediscovered
|
|
with correct primary handling, control frame re-established, participant count `0`
|
|
(fresh authoritative document), no stale panes or counts.
|
|
- Both secondaries reopened and attached to the new session (count 2), each rendering the
|
|
new session's current state.
|
|
|
|
### Exhibit replacement
|
|
|
|
- Museum -> SciFi (`scifi/index.html`): no Museum pane survived (0 iframes referencing
|
|
the Museum exhibit), the surface catalog became `No presentation surfaces advertised.`
|
|
(SciFi advertises none), and SciFi negotiated Contract 5.3 as
|
|
`SciFi-XZBT · 5.2.0 · build production`, session `sess-2akzu3a7`,
|
|
`connected · synchronized`, 61 targets, state snapshot received.
|
|
- SciFi -> Museum (`museum-gallery/control.html`): new session `sess-126c6`, Contract 5.3,
|
|
5 targets, 3 surfaces rediscovered with the correct primary, participant count `0`,
|
|
0 SciFi frames left, 0 stale Museum panes.
|
|
|
|
## H. Failure isolation
|
|
|
|
Live-tested through the served UI:
|
|
|
|
- **A non-primary surface holds no authority.** Inside the Artifact Display document:
|
|
`XZBTContractCore` undefined, `MuseumGalleryContract` undefined,
|
|
`MuseumGalleryExhibit` undefined, `XZBTHostTransport` undefined; only the surface bus is
|
|
present, and `__museumGalleryDebug` exposes a `link` but no core.
|
|
- **A secondary cannot act as a protocol peer.** A forged `hello` and a forged `set`
|
|
posted directly to the Artifact Display's window produced zero responses, and the
|
|
authoritative selection was unchanged.
|
|
- **One broken presentation surface does not harm the control session.** The Artifact
|
|
Display frame was navigated to a missing page (`does-not-exist.html`, served as
|
|
`Not found`): the authoritative session stayed `connected · synchronized` on
|
|
`sess-126c6`, the Control Room kept rendering, the registry/state were unaffected, and
|
|
the surface's participant slot was released (count 2 -> 0) with no stale entry.
|
|
- **Reload failure is surface-local and recoverable.** NGN's per-surface `Reload` brought
|
|
the pane back to `artifact.html`; it re-attached and the count returned to 1 while the
|
|
session remained synchronized. No error was raised against the session.
|
|
|
|
Automated-only (covered by the suites below, not re-injected live):
|
|
|
|
- malformed / individually-invalid surface descriptors and catalog-level rejection
|
|
(`surface-validation.test.js`, `museum-gallery.test.js` — 50 validation cases)
|
|
- isolated HTTP, frame and reload failures, external frame removal detection, and a
|
|
stalled surface resource (`local-surfaces.test.js`)
|
|
- resource-check refusal of redirects before frame navigation (`local-surfaces.test.js`)
|
|
- presentation window cannot impersonate the authoritative peer over the production
|
|
transport (`local-surfaces.test.js`)
|
|
- source/origin validation on the real postMessage transport
|
|
(`postmessage-interop.test.js`)
|
|
|
|
## I. Automated verification
|
|
|
|
Focused run (Museum Gallery, local surfaces, surface validation, postMessage interop,
|
|
connection lifecycle):
|
|
|
|
```text
|
|
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 suite (run once):
|
|
|
|
```text
|
|
node --test
|
|
# tests 129
|
|
# pass 129
|
|
# fail 0
|
|
```
|
|
|
|
Other validation:
|
|
|
|
```text
|
|
git diff --check -> clean (exit 0)
|
|
python devlog_editor.py --validate -> devlog-editor: devlog is valid (exit 0)
|
|
```
|
|
|
|
## J. Files changed
|
|
|
|
None. Validation found no defect, so per the Step 6.6 fix policy no implementation file
|
|
was modified. The only additions are this report and its raw evidence record
|
|
(`test-fixtures/evidence/step6.6-museum-gallery-validation.txt`).
|
|
|
|
## K. Limitations
|
|
|
|
1. Failure isolation was live-tested only for the three cases in section H; malformed
|
|
descriptor catalogs, redirect refusal, stalled resources and peer impersonation remain
|
|
automated-only, and no risky manual failure injection was performed for them.
|
|
2. The `Spotlight flashed.` announcement on secondaries is transient (2.6 s idle timeout).
|
|
It was confirmed with a DOM mutation observer rather than by a raw text read after the
|
|
event, so the recorded evidence is the observer transition sequence.
|
|
3. All live checks were same-origin over `http://127.0.0.1:4173`. Cross-origin exhibits,
|
|
`file://` documents, and non-`http` schemes were not exercised live.
|
|
4. The exhibit instance is recreated by `Disconnect`/`Reconnect` and by exhibit switching,
|
|
so post-reconnect state is the exhibit's documented default state (`stateRevision` 0).
|
|
No cross-session state persistence exists in the reference exhibit; this is expected
|
|
standalone behavior, not a regression.
|
|
5. Local surfaces were exercised in one browser window; casting/remote displays remain
|
|
out of scope for Step 6.6 and were not tested.
|
|
|
|
## L. Verdict
|
|
|
|
PASS. Museum Gallery behaves as a complete Contract 5.3 reference exhibit through the
|
|
normal NGN operator UI: connection and synchronization succeed, Contract 5.3 is
|
|
negotiated, the surface catalog and primary handling are correct, both secondaries render
|
|
locally and report attachment, participant counts stay correct across reload/close/reopen,
|
|
Control -> secondary and secondary -> primary -> secondaries synchronization are both
|
|
proven, late join and reload recovery return current state, representative host commands
|
|
work, disconnect/reconnect and exhibit switching clean up completely, SciFi still connects
|
|
and synchronizes, and the focused and full automated suites pass.
|