# SciFi-XZBT XZBT Contract Implementation Plan ## Version 5.2 **Status:** Proposed implementation plan **Product:** SciFi-XZBT **Contract:** XZBT Exhibit Contract 5.2 **Primary goal:** Make the existing standalone exhibit contract-addressable without turning it into XZBT-NGN. --- ## 1. Purpose SciFi-XZBT will implement the XZBT Exhibit Contract while remaining a self-contained standalone HTML exhibit. Version 5.2 is grounded in the v5.1 codebase review and deliberately corrects the remaining ambiguity around: - current control-bus inventory; - absolute state versus toggles; - mutation/event emission; - state revision semantics; - observation versus viewport-frame control; - universe/preset behavior; - display ticker behavior; - host validation; - packaging-runtime compatibility. The implementation should extend the real application foundation rather than create a parallel control system. --- ## 2. Standalone Guarantee SciFi-XZBT MUST continue to operate normally without: - XZBT-NGN; - a host handshake; - a web server; - webhooks; - external telemetry; - scenario files; - external automation. The contract layer is dormant when no host is attached. --- ## 3. Existing Verified Foundation and Verification Boundary The current codebase is known to include: - `XZBTControlBus`; - MIDI routing through that bus; - a set of range controls; - a set of action controls; - speech/TTS; - universe/preset setters; - universe events; - soundboard actions; - Observation mode; - an Observation viewport-frame toggle; - existing bus listeners; - no general host bridge; - no general scenario/recording system; - no structured fictional telemetry model. ### 3.1 Control-bus inventory safeguard Review materials conflict on the exact total count. One review states **22 targets: 14 range + 8 action**, but the same review explicitly names only seven action targets: ```text master-play fnc-enable watch-experience observation-viewport red-alert generate-announcement mute ``` Therefore v5.2 MUST NOT hard-code 21 or 22 as a normative implementation fact. Phase 0 MUST enumerate the actual `register()` / `rangeTarget()` calls in the target commit and produce the authoritative inventory. The implementation plan below accounts for the known named targets and requires any additional verified target to be added before coding proceeds. --- ## 4. Scope Version 5.2 implementation includes: - canonical external target registry; - direct adapters to existing setters where possible; - new absolute setters where required; - `describe`; - target descriptors; - state snapshot; - state revision; - event stream; - source normalization; - capability reporting; - host attachment; - explicit speech target; - sound/event exposure; - universe/preset exposure; - safe ticker text exposure; - compatibility with current MIDI and native UI behavior. Structured telemetry remains optional and does not block first conformance. --- ## 5. Explicitly Out of Scope The normal SciFi-XZBT HTML will not gain: - scenario authoring; - general scenario file loading; - scenario recording; - scenario library management; - timeline editing; - webhook endpoints; - third-party connectors; - Streamer.bot integration; - Internet-facing authentication; - remote administration; - external telemetry acquisition; - scenario scheduling; - scenario chaining; - host-side queue management; - NGN administration; - casting server functionality. These remain XZBT-NGN responsibilities. --- ## 6. Canonical External Target Registry The external registry is the single source of truth for: - `describe`; - validation; - state readers; - state writers; - event target IDs; - NGN discovery. Existing internal IDs are not renamed. ### 6.1 Known range mappings The following known range targets are pure external-to-internal mappings in concept, but their current synthetic-DOM application path must be replaced by direct setter calls during convergence. ```text mix.master -> master-vol mix.hull.level -> hull-vol mix.hull.frequency -> hull-freq mix.hull.cutoff -> hull-cutoff mix.drive.level -> warp-vol mix.drive.pulse-rate -> warp-bpm mix.drive.carrier -> warp-carrier mix.environment.level -> air-vol mix.environment.cutoff -> air-cutoff mix.telemetry.level -> telemetry-vol mix.telemetry.density -> telemetry-density speech.robot-amount -> ai-robot-amount fnc.level -> fnc-level view.activity -> observation-activity ``` Phase 0 MUST confirm all 14 names against the repository before implementation. ### 6.2 Known action/state adapters These are not simple renames: ```text transport.playing transport.muted fnc.enabled view.observation view.viewport-frame event.alert-red alert.active speech.say ``` Known internal candidates include: ```text master-play mute fnc-enable watch-experience observation-viewport red-alert generate-announcement ``` The external semantics are defined below and MUST NOT be implemented as blind DOM clicks. ### 6.3 Universe and preset selection Add new canonical targets: ```text universe.selected preset.selected ``` These wrap the existing verified universe/preset setter functions. They are new contract registrations, not mappings of pre-existing bus targets. --- ## 7. Absolute State Semantics Persistent contract state MUST be idempotent. ### 7.1 Transport playing Add: ```text setPlaying(on, source) ``` It MUST: - read current playing state; - do nothing on a no-op; - await startup/shutdown transition completion; - not silently drop a request because a transition is already in progress; - surface failure to the contract adapter. ### 7.2 Transport muted Add: ```text setMuted(on, source) ``` It MUST be absolute and idempotent. ### 7.3 FNC enabled Use the existing absolute FNC setter directly where verified. Do not synthesize a DOM click. ### 7.4 Observation mode `view.observation` means entering or exiting the overall Observation experience. Use existing absolute enter/exit functions where available. Add a readable getter for current Observation state. ### 7.5 Viewport frame `view.viewport-frame` means the viewport/bezel-frame state inside Observation. It is separate from `view.observation`. ### 7.6 Alert `event.alert-red` is an impulse. `alert.active` is persistent state, preferably a selection: ```text none red yellow ``` The two semantics MUST remain separate. --- ## 8. Fixed Target Catalog Decision SciFi-XZBT v5.2 adopts a **fixed canonical target catalog**. Universe-specific actions and sound effects remain discoverable across universe changes. If a target is not valid in the current context, an attempt to invoke it returns `CAPABILITY_UNAVAILABLE` or another appropriate context error. A universe change SHOULD NOT remove and re-add large sections of the target registry. Therefore `registryRevision` remains stable unless target definitions themselves actually change. This prevents unnecessary NGN re-description churn. --- ## 9. Describe Implementation Add a contract description provider containing: - exhibit identity; - build/version metadata; - contract version; - registry revision; - state revision; - capability descriptors; - target descriptors. The canonical external registry is the source of truth. Descriptors MUST NOT be duplicated in separate hand-maintained tables. --- ## 10. State Snapshot Create one authoritative function that returns contract-visible persistent state. Initial expected fields include: ```text transport.playing transport.muted mix.master mix.hull.level mix.hull.frequency mix.hull.cutoff mix.drive.level mix.drive.pulse-rate mix.drive.carrier mix.environment.level mix.environment.cutoff mix.telemetry.level mix.telemetry.density speech.robot-amount fnc.enabled fnc.level view.observation view.viewport-frame view.activity alert.active universe.selected preset.selected ``` Phase 0 must verify each read path. Known required additions include: - readable Observation state; - canonical universe getter; - canonical preset getter; - canonical alert-state reader if not already directly exposed. --- ## 11. Universe and Preset Behavior When `universe.selected` changes: 1. validate the universe ID against the real registry; 2. apply the universe; 3. select that universe's defined default preset; 4. commit both values in one mutation transaction; 5. emit the resulting selection/state events with one resulting `stateRevision`. The system MUST NOT leave `preset.selected` pointing at a preset invalid for the current universe. Unknown universe or preset IDs return `INVALID_VALUE`. --- ## 12. Mutation Chokepoint All contract-visible persistent mutations MUST pass through one canonical mutation service in `js/app.js`. Recommended conceptual API: ```text applyMutation(targetId, value, source, context) ``` The implementation may use a class or object rather than this exact function name, but there MUST be one authoritative mutation path. Responsibilities: - validate target and value; - call the direct underlying setter; - detect no-op writes; - commit one mutation transaction; - increment `stateRevision` once when state changes; - emit normalized state/selection events; - preserve authoritative source; - return success/failure. The existing `XZBTControlBus.listeners` mechanism should be reused or extended as an event-subscription foundation where practical. --- ## 13. Remove Synthetic-DOM Mutation as the Canonical Path Existing range bus application currently reaches real setters by assigning DOM values and dispatching synthetic `input` / `change` events. Version 5.2 MUST separate programmatic state mutation from DOM event simulation. The canonical mutation path MUST call the real setter directly. UI listeners should call the canonical mutation path, not the other way around. This prevents double application and makes source attribution reliable. --- ## 14. UI, MIDI, Hotkey, and Host Convergence Required architecture: ```text UI MIDI Hotkey Host Contract Scenario-originated local runtime | v Canonical Mutation / Invoke Service | v Existing SciFi-XZBT subsystem ``` Every path that changes contract-visible state MUST use the canonical service. Every path that performs a contract-visible impulse MUST use the canonical invoke service. The phrase "where practical" is removed for contract-visible behavior. --- ## 15. State Revision SciFi-XZBT follows the contract's mutation-transaction rule. One top-level mutation transaction produces at most one new `stateRevision`. A no-op produces no revision increment. The revision increments after commit and before resulting events are emitted. Universe changes plus default-preset selection are one transaction. Preset application may update multiple exposed values in one transaction. --- ## 16. Event Surface SciFi-XZBT MUST emit normalized events. At minimum: ```text state.changed action.executed selection.changed capability.changed registry.changed error ``` Each event includes: - sequence; - timestamp; - target where applicable; - value or args; - authoritative source; - state revision where applicable; - correlation ID when directly caused by a host request. Session event sequence resets on new contract session. --- ## 17. Source Normalization Use: ```text ui midi hotkey host scenario internal system ``` A host-supplied `source` is ignored. The bridge assigns `host`. Packaged scenario runtime assigns `scenario`. Existing MIDI routing retains `midi`. --- ## 18. Speech Expose: ```text speech.say ``` This calls the existing explicit `speak(text)` implementation. Do not confuse it with "generate announcement." If generated-announcement behavior is exposed separately, it receives a distinct impulse target such as: ```text speech.generate-announcement ``` SciFi-XZBT remains responsible for: - TTS loading; - preferred engine; - fallback synthesis; - selected voice; - robotic voice processing; - spoken-unit normalization; - interruption behavior; - playback. ### 18.1 Speech capability state Add a readable capability state field to the generative/speech subsystem. Use: ```text available loading ready busy error ``` Use `unsupported` only when speech is not implemented at all. ### 18.2 Queue behavior Current behavior interrupts prior speech. Preserve that behavior in the first implementation. A successful `speech.say` means accepted and started, not completed. ### 18.3 Length limit Set a conservative maximum accepted text length. Recommended first limit: ```text 2000 characters ``` This limit is an implementation constant and may be tuned later. Over-limit requests return `INVALID_VALUE`. --- ## 19. Sound Effects Build a verified stable public inventory from the current soundboard and synthesis dispatch. Do not automatically expose every internal synthesis helper. The fixed external catalog may include targets that are contextually unavailable in the current universe. Unavailable invocation returns a defined error instead of removing the target. --- ## 20. Universe Events Build a verified stable public event catalog from current universe `events[]` definitions and actual dispatch behavior. Do not treat examples as authoritative inventory. Keep persistent alert state separate from alert impulses. --- ## 21. Display Ticker Expose: ```text display.ticker ``` as a **transient write**. Semantics: - text is immediately displayed; - it remains subject to normal exhibit ticker replacement; - the contract does not claim persistence; - the exhibit SHOULD emit a state/action event indicating the accepted write; - a future persistent-host-caption feature would use a different target. Use safe `textContent`-style assignment. Recommended maximum: ```text 512 characters ``` Over-limit input returns `INVALID_VALUE`. Do not invent `display.status` or `display.transient` until real surfaces exist. --- ## 22. Telemetry The current codebase does not yet have structured fictional display telemetry fields. Version 5.2 keeps two stages. ### Stage A - Contract readiness Ensure future `telemetry.*` targets can be added cleanly. ### Stage B - New exhibit feature Later create real structured telemetry fields with meaningful visible representation. Only then advertise writable telemetry capabilities. Structured telemetry is not required for first conformance. --- ## 23. Host Attachment Initial host attachment uses: 1. same-origin parent/frame `postMessage`; 2. optional explicit trusted wrapper binding. The bridge MUST validate: - `event.origin`; - `event.source`; - contract version; - session; - message type; - target; - value type; - numeric bounds; - args schema; - unexpected args keys; - selection membership; - capability state; - text length limits. The base exhibit does not automatically connect to remote services. No webhook listener belongs in the HTML. --- ## 24. Capability Model Initial capabilities may include: ```text audio speech midi observation display-text ``` Do not advertise telemetry-write until it exists. A target's `requires` list references these capability IDs. Context-specific target unavailability does not require capability removal. --- ## 25. Registry Revision Because v5.2 uses a fixed canonical target catalog, ordinary universe changes SHOULD NOT change `registryRevision`. Increment it only when: - a target is added or removed; - target descriptor metadata changes; - option metadata genuinely changes in a way that changes the registry contract. Use contextual availability errors rather than registry churn where practical. --- ## 26. Build and Packaging The existing PowerShell packaging process remains authoritative for the ordinary single-file standalone artifact. Contract integration MUST preserve the packaging script's expected include patterns. Ordinary free packaging remains independent of XZBT-NGN. Future NGN scenario packaging is separate. --- ## 27. Implementation Phases ### Phase 0 - Repository verification Produce an authoritative inventory from the target commit. Required output: - every control-bus registration; - all internal IDs; - range/action counts; - direct backing setter; - current source paths; - universe/preset accessors; - event/sound catalogs; - package-script assumptions. Do not proceed while target count remains disputed. ### Phase 1 - Canonical registry Create the single source of truth for canonical external target descriptors and internal adapters. ### Phase 2 - Direct setters and absolute state Implement direct range mutation and absolute setters for toggle-like state. ### Phase 3 - Mutation service Implement the canonical mutation/invoke chokepoint and transaction semantics. ### Phase 4 - State and discovery Implement: - `describe`; - `state.get`; - `stateRevision`; - `registryRevision`; - capabilities. ### Phase 5 - Input convergence Rewrite all contract-visible UI, MIDI, and hotkey mutation paths to call the canonical service. This is a substantial refactor, not a small wiring task. No contract-visible inline listener may bypass the canonical mutation path at phase completion. ### Phase 6 - Event normalization Publish normalized events with source, sequence, revision, and correlation. ### Phase 7 - Speech, SFX, universe events, ticker Expose verified exhibit functions through canonical targets. ### Phase 8 - Host bridge Implement same-origin messaging and validation. ### Phase 9 - Standalone verification Confirm complete application behavior without any host. ### Phase 10 - Optional structured telemetry Only after intentionally designing real telemetry fields. --- ## 28. First Contract-Compatible Acceptance Criteria The first compatible release succeeds when: - SciFi-XZBT still runs normally by itself; - a test host completes handshake; - a test host calls `describe`; - the authoritative target inventory matches the repository; - persistent state can be read; - representative ranges can be set directly; - toggle-like targets are absolute and idempotent; - setting a boolean state to its current value twice leaves the same state; - universe changes select a valid default preset; - Observation and viewport-frame controls are distinct; - representative sound and visual impulses can be invoked; - `speech.say` accepts explicit text; - `display.ticker` behaves according to its transient contract; - UI, MIDI, hotkey, and host changes emit normalized events; - event source is accurate; - session sequence and state revision work; - no-op sets do not increment revision; - malformed commands fail safely; - unexpected origins are ignored; - no scenario engine or webhook system has been added. Structured telemetry is not required. --- ## 29. Future Telemetry Acceptance Criteria When structured telemetry is later added: - each field has a real visible or meaningful exhibit representation; - metadata is discoverable; - read-only and writable fields are explicit; - external ownership prevents immediate simulation overwrite; - stale or released ownership returns cleanly to simulation; - NGN remains responsible for acquiring real telemetry. --- ## 30. Architectural Test When considering a future feature: **Does SciFi-XZBT need this to remain a complete standalone exhibit?** If yes, it may belong in SciFi-XZBT. **Does the feature coordinate, automate, connect, record, author, distribute, or externally control the exhibit?** If yes, it belongs primarily in XZBT-NGN. --- ## 31. Version 5.2 Summary Version 5.2 does not change the Version 5 architecture. It makes the SciFi-XZBT implementation plan concrete enough to begin coding after Phase 0 verification. The implementation must normalize the real application rather than pretending that existing DOM-click proxies and synthetic events already satisfy the contract.