12 KiB
A. Executive result
The first Step 4 host is implemented and verified against three unrelated reference exhibits using the same production host, transport, and descriptor-driven UI. Twenty automated tests pass. The repeatable real-browser suite passes for all three fixtures.
The owner resolved the initial argument-schema blocker as an authoritative Contract 5.2 clarification. It is now recorded in contract section 9.5. Work stops at the first MVP; no higher-level NGN features were added.
B. Repository / stack overview
Stack: Node.js 22+ standard library, browser-native JavaScript modules, HTML/CSS, and Node's built-in test runner. There are no npm dependencies or build step. The NGN implementation plan established local hosting and discovery but did not prescribe a framework; this stack meets that scope with minimal tooling.
Run npm start, then open http://127.0.0.1:4173. The server binds to loopback and serves only public/, src/, and test-fixtures/. An alternate port can be selected through PORT.
The existing Labyricorn publishing template remains present. Its exhibition metadata is still template content; publishing it is outside this implementation milestone.
C. Transport implementation
src/transport/post-message.js implements a replaceable send/subscribe/close transport. Only this module knows about Window message events. Incoming traffic must match both the expected frame window and the host's origin; outgoing traffic uses an explicit target origin.
The first milestone loads same-origin HTML exhibits in an iframe. No remote exhibit connector or external filesystem mount is implemented.
D. Session handling
The host sends hello with supported major 5 and records the actual exhibit-issued session, negotiated major/minor, and product/version/build metadata. Requests have unique correlation IDs, expected response types, and timeouts.
Reconnect cancels old requests, creates a new session, clears session event tracking, and reloads discovery/state. Old-session events are ignored. INVALID_SESSION makes controls unavailable until reconnect. A real-browser test replaces the session at the exhibit, verifies INVALID_SESSION, and reconnects successfully.
E. Discovery / describe handling
The host validates describe metadata, revisions, target IDs, kinds, capabilities, and kind-specific control metadata. The catalog has no hard-coded target IDs or count. Metadata, raw descriptors, capability snapshots, and registryRevision are visible.
StateRevision is displayed from accepted snapshots and persistent-state events rather than treating the description alone as a complete state snapshot.
F. Dynamic target rendering
The UI renders numeric inputs from range bounds/step, boolean state checkboxes, supported scalar state inputs, selection options, and impulse buttons. Read-only targets have no write controls. Descriptor text is rendered with textContent.
Impulse arguments follow the owner's array-based arguments clarification. Supported types are string, number, integer, and boolean; enum, bounds, step, and length constraints are validated. Optional arguments have explicit include controls. Missing arguments metadata is treated as empty. Unsupported future schemas leave the impulse visible with an explanation and disabled invocation.
G. State handling
The local Map is a cache of reported exhibit values. It is populated by state.result and updated by state.changed / selection.changed. No requested value is optimistically fabricated.
Snapshots and events validate known value types and constraints. Invalid snapshots preserve the prior cache and mark synchronization uncertain. Regressive snapshots cannot roll back an observed revision. Events received while a snapshot is pending are replayed after that snapshot to avoid dropping intervening changes.
Sequence/revision gaps and malformed events schedule fresh state.get. Multiple target events sharing a transaction revision are accepted. Successful operations refresh state to include other reported consequences. A manual refresh is also available.
H. Set / invoke behavior
Set requires a writable persistent descriptor. Invoke requires kind impulse regardless of the descriptor's writable flag. Bounds, step, types, selection membership, required arguments, unknown keys, and declared constraints are checked without clamping.
Successful responses do not substitute for exhibit state reports. Protocol errors are displayed. Timed-out operations are treated as uncertain and trigger state resynchronization.
I. Event handling
All six base event types are accepted: state.changed, selection.changed, action.executed, capability.changed, registry.changed, and error. The event log exposes the complete received envelope, including source/correlation when present.
Event sequence is tracked separately from persistent-state revision. Gaps, duplicates, and out-of-order sequences are diagnosed; older events are not applied. The first observed sequence establishes the new session's baseline. No missing events are invented.
J. Capability handling
Capability IDs and lifecycle states are displayed exactly as discovered. Unsupported/error requirements disable operations while leaving targets visible. Available/loading states do not universally prove usability, so attempts may receive the exhibit's own unavailability error; this preserves the contract's allowance for fallback behavior.
Because Contract 5.2 does not standardize capability.changed payload fields, the host uses that event to request a fresh describe snapshot instead of interpreting a fixture-specific payload shape.
Real-browser verification observed Haunted House audio as available, a rejected host action, native loading/ready events, a refreshed ready display, and a successful later host action.
K. Registry-change handling
registry.changed schedules describe plus state.get through a 100 ms debounce. Normal state changes do not rediscover the catalog. Automated tests verify burst coalescing and replacement of targets/cache entries.
The supplied reference exhibits have fixed registries. Dynamic registry changes were tested with a synthetic peer, not claimed as a naturally occurring reference-exhibit browser scenario.
L. Error handling
The visible protocol console records stable codes and explanatory messages. Covered failures include INVALID_SESSION, INVALID_VALUE, CAPABILITY_UNAVAILABLE, UNSUPPORTED_VERSION, malformed responses/state, timeout, and unsupported schemas.
Local input checks and exhibit-returned rejections are separately exercised. Browser tests bypass local value validation for selected requests to prove that real exhibit errors survive the transport.
M. Genericity verification
The owner selected the AbacusAI reference set from G:/.vibe/SciFi-XZBT/exhibit-test/abacusai/reference-exhibits/. Copies reside under test-fixtures/reference-exhibits/; no source repository was modified and no SciFi application source was used to infer host architecture.
| Fixture | Discovered targets | Result |
|---|---|---|
| Aquarium | 12 | Browser suite and admin UI operations passed |
| Planetarium | 14 | Browser suite and numeric argument operation passed |
| Haunted House | 13 | Browser suite and live capability lifecycle passed |
Product source checks found no aquarium/planetarium/haunted-house/SciFi names or domain target prefixes in src/, public/, or server/. Exhibit selection in the repeatable test harness is test configuration only.
The copied fixtures needed narrow documented corrections: undeclared telemetry kinds became read-only state descriptors; Planetarium's args metadata became arguments; fixture invocation gained clarified argument validation; and Planetarium's stale magnitude ID was aligned with its canonical descriptor. These are local fixture repairs, not host-specific exceptions. See test-fixtures/PROVENANCE.md.
N. Browser/runtime verification
Verified on 2026-09-14 in the Codex in-app Chromium browser with the local Node server.
The repeatable page /test-fixtures/host-verification.html reported 3/3 real exhibits passed. It imports the production host and transport and loads actual exhibit HTML, scripts, state, and behavior in iframes. Checks include incompatible major rejection, handshake, catalog, state, representative state/range/selection writes, no-op revision, impulse execution, delivered arguments where declared, error responses, events, reconnect, forced session invalidation, and recovery.
Separate admin UI checks verified:
- Aquarium population 12 to 16, paused false to true, species to Blue Tang, feed invocation, rejected population 41, native species change to Guppy, native resume event, and reconnect with preserved revision.
- Planetarium discovered optional minutes control delivering 30 and azimuth write to 0.75.
- Haunted House unavailable audio action before a gesture, native capability initialization, ready display, and subsequent host invocation.
A screenshot inspection confirmed readable control layout. The browser error/warning log was empty during the checked Haunted House run. This is local Chromium evidence, not a cross-browser certification.
O. Tests
npm test: 20 tests passed, zero failures.
Repository checks: python devlog_editor.py --validate reported "devlog is valid";
git diff --check passed for tracked changes. New application files remain
untracked until the owner requests staging/commit.
Coverage includes negotiation/correlation, all persistent kinds, argument constraints, no-op revisions, exhibit errors, invalid sessions, unsupported version, timeouts, native-style events, shared revisions, gap detection/resync, debounced rediscovery, snapshot/event races, stale sessions, malformed events, origin/source checks, server boundaries, invalid reported values, regressive snapshots, dynamic catalog replacement, future argument types, and capability gating.
The real-browser suite passed 3/3 actual exhibits and supplements these synthetic unit cases. It is run through the documented browser page rather than npm test. No success claim relies on mocks alone.
P. Files created/changed
- Added
package.json. - Added
server/serve.js. - Added
public/index.htmlandpublic/style.css. - Added
src/host.js,src/validation.js,src/ui.js, andsrc/transport/post-message.js. - Added
tests/host.test.js. - Added three reference fixture directories and shared dependencies, upstream README, local provenance, and the browser verification HTML/JS.
- Added the owner-authorized section 9.5 clarification to the supplied Contract 5.2 document.
- Updated README with run/test instructions and this report with implementation evidence.
Pre-existing AGENTS.md edits and copied architectural/reference documents were preserved. No commit, push, external exhibit edit, or publishing-record edit was performed.
Q. Known limitations
This is an engineering MVP: one trusted same-origin exhibit, in-memory state/logs, no saved connection, and no external mount configuration. The UI uses numeric inputs rather than separate range sliders. Draft fields are distinct from reported values and reset on rediscovery.
The fixture copies have compatibility repairs. Their continuously changing derived readings are refreshed from snapshots; this milestone does not certify the upstream exhibits' complete event/revision conformance. SciFi-XZBT and other browsers were not tested.
Reference fixtures do not naturally exercise changing registries or every future argument type; those host paths have focused synthetic tests. No timed idle snapshot polling is enabled; recovery is driven by messages, request timeouts, operations, reconnect, and explicit refresh.
R. Next Step 4 work
The first MVP is finished. Await owner direction. Reasonable follow-up within Step 4 is independent review of fixture conformance and additional browser/exhibit interoperability testing. Publishing metadata can be authored separately once requested. MIDI, scenarios, webhooks, telemetry acquisition, packaging, and later phases remain deferred.
S. Final verdict
STEP 4 MVP COMPLETE — MINOR FOLLOW-UP REQUIRED