OVOS-BRIDGE-1: Bus Bridge and Opaque Relay Specification#43
Draft
JarbasAl wants to merge 28 commits into
Draft
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Bus bridge and opaque relay specification defining the contract for relaying messages between the internal assistant bus and external participants, covering identity stamping, session fidelity, message ordering, and conformance. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
…nce/policy split, and context pre-population Three new subsections detail the session-resident fields a layer-2 system can inject at the bridge boundary: - §4.2.1: full denylist catalog (9 blacklisted_* fields) with cross-references to PIPELINE-1 and TRANSFORM-1 - §4.2.2: preference/policy split for pipeline and transformer overrides - §4.2.3: context pre-population via session.intent_context - §4.2.4: separation of concerns — bridge enforces, layer-2 decides Also: removed project-name references (HiveMind -> generic), tightened subscription language, added SESSION-1 to dependencies, added participant-identifier fallback rule. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
Describes the pattern where the remote side is also a spec-compliant deployment (satellite) that handles audio capture, STT, transformer chains, and/or TTS locally. The lifecycle partition is encoded transparently in the session fields flowing through the bridge; the bridge itself needs no lifecycle awareness. §1 scope list updated to reflect the new subsection. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
Reframe peer-to-peer section to emphasize that each participant is a first-class voice OS, audio stays local, and what crosses the bridge are the same bus-native messages (utterances, dispatches, session mutations, speak requests). Three topology patterns: satellite/hub, cascading intelligence, and multi-brain. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
This is a major restructuring of the spec based on the observation that the bridge carries almost no normative weight of its own. Structural changes: - §3 split into "Normative core": exactly two MUST obligations (source stamping, session preservation). Everything else is emergent. - §4 "Emergent patterns": policy injection and multi-deployment topologies are explicitly framed as compositions of other specs (SESSION-2 + PIPELINE-1 + TRANSFORM-1 + CONTEXT-1), not new protocol defined by BRIDGE-1. - §4.1 policy injection catalogues the 9 blacklisted_* fields from SESSION-1 §3 but makes clear they are owned by other specs. The bridge just carries them. - §4.2 multi-deployment topology: three patterns (satellite/hub, cascading intelligence, multi-brain), each citing which specs combine to produce it. Audio stays local; the bridge carries bus-native messages only. - §5 ordering softened from MUST to SHOULD. Network jitter is real; FIFO is a best practice, not a hard protocol invariant. - §6 conformance shrinks to 2 MUST, 3 SHOULD, 3 MAY. The old mandatory subscription topic requirement is now a SHOULD since what topics to subscribe to is deployment-specific. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
Default mode: subscribe to all topics, filter by destination — the client receives everything addressed to it as a true bus peer. Hardened mode: restrict to utterance lifecycle topics (PIPELINE-1 §9) plus plugin dependencies for reduced attack surface. Conformance updated to match: SHOULD subscribe to all topics (default), MAY restrict to hardened minimum. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
Routing (§3.2): session_id is the primary matching signal (not destination), because all lifecycle messages (speak, handled, unmatched) are broadcasts that carry the session but no destination. Default mode relays by session match across all topics; hardened mode restricts to an explicit 5-topic minimum set (ovos.utterance.handle, speak, handled, ovos.intent.unmatched, ovos.session.sync). Topology patterns (§4.2): - Satellite/hub corrected: partition is by message type, not session fields. Satellite emits ovos.utterance.handle (not ovos.utterance). - Cascading intelligence reframed as satellite-and-hub variant, without the incorrect PIPELINE-1 §5.2 cross-reference (blacklisting does not cause forwarding). - Multi-brain removed (not a well-defined pattern for bridges). - Topology transparency paragraph folded into §4.2 intro. Minor: peer-neutral language in §2 (no more "gateway to the assistant"), Scope does not count "two obligations" explicitly, all §3.2 cross-references updated to §3.3 after renumbering. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
…site_id as complements Per maintainer feedback: - destination is the primary/recommended routing signal (MSG-1 §3) - session_id is a secondary signal for catching session-scoped broadcasts that lack destination (speak, handled, unmatched) - site_id MUST be used when grouping participants into clusters - Bridges MAY perform session_id NAT (translate participant-local IDs to hub-side values and back) - Hardened minimum topic table restored with 5 lifecycle topics - Conformance updated: destination-based relay is SHOULD, session_id/ site_id matching is MAY Co-Authored-By: big-pickle <big-pickle@opencode.ai>
Destination-based routing gives the orchestrator explicit control over what crosses the bridge. Session_id-based routing would leak internal messages that share the session but target different consumers (e.g. handler-lifecycle notifications). The "default" session case is particularly exposed: a remote home-automation client using session_id:default would receive every bus message unless destination gates it. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
…leak The key benefit of destination-based routing is client isolation: each participant gets only messages whose destination matches its own unique source. Two participants sharing the same session_id (e.g. multiple remotes using "default") cannot impersonate each other because the bridge stamps unique source per participant. Co-Authored-By: big-pickle <big-pickle@opencode.ai>
The "topology hiding" MAY item referenced source overwriting but did not cite the normative section. Cross-reference added. Also: correct commit authorship — prior commits incorrectly identified the agent as "Claude Code"
- §2: replace "two things" with reference to §6 conformance - §3.2: replace topic table with cross-reference to PIPELINE-1 §9 (removes drift risk when lifecycle topics change) - §3.2: tighten "internal routing metadata" with explicit examples (pipeline_id, skill_id, internal source → strip; session, destination → preserve) - §3.3: add session materialization guidance for participants that send no session (MAY materialize per SESSION-1 §4.1) - §4.1.1: replace explicit 9-field denylist catalog with cross-reference to SESSION-1 §3 (removes drift risk) - §4.2.3: add session identity note — multiple participants sharing session_id:"default" share the orchestrator default-session store - §5: add disconnect handling guidance (drop undeliverable messages, do not buffer indefinitely) - §6: add missing "relay every matched message" MUST Co-Authored-By: big-pickle <big-pickle@opencode.ai>
…ADME) New-spec metadata per AGENTS.md §2.1 exception: a new spec MAY combine its normative file with the metadata sweep. Additions: - appendix/rationale.md §4.9: bridge design rationale (minimalism, client isolation, session_id as MAY convenience, layer-2 injection, hardened-set trade-off) - appendix/divergences.md §5.8: HiveMind comparison (session_id vs destination-based routing) and conformance note - appendix/gaps.md: bridge-specific gaps (multi-hop cascade, wire format, health/heartbeat) - README.md: OVOS-BRIDGE-1 row in orchestrator stack table
- §3.2: SHOULD→MUST for destination relay (body now matches §6 MUST) - §3.3 inbound: MAY materialize default session → MUST (closes gap where bridge had no conformant path for sessionless inbound payload) - §4.1: add SHOULD constraining layer-2 mutation to SESSION-1 §3 registered fields; overwriting client-owned fields violates SESSION-2 §2 client-authority rule - §3.2 hardened set: cite SESSION-2 §2.7 for ovos.session.sync (was incorrectly attributed to PIPELINE-1 §9 only) - §4.2.3: fix SESSION-2 §5 → §3.1 (session-keyed-on-session_id) - §5: collapse MUST NOT buffer + SHOULD discard into a single MUST - §6: update conformance list to match corrected body levels - divergences §5.2.1: preserve retirement rationale for ovos.session.update_default; add cross-ref to §5.5 and §5.7 - divergences §5.5: add ovos.session.sync as new formalized topic - divergences §5.7: add ovos.session.update_default → retire row - rationale §4.9: fix "2 MUSTs" → "3 MUSTs"; fix MSG-1 §5 abbreviated citations → OVOS-MSG-1 §5 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document two concrete patterns that justify the site_id mandate: - indoor geolocation via Wi-Fi/Bluetooth scan data resolved at the bridge boundary - home-automation canonical area names (e.g. "living_room") used directly as site_id, giving skills a stable location key without requiring participants or skills to understand network topology. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add §3.4 site_id assignment: client MAY report site_id, bridge MAY respect it or override with its own determination (geolocation, home-automation area names, etc.) - Downstream MUST NOT overwrite once set; absent site_id means unknown group, no default inferred - Update §3.2 group-signal reference from SESSION-1 §3.3 → §3.4 - Rename former §3.3 (session preservation) → §3.5 and update all internal self-references - Update §1 scope summary to mention site_id assignment Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
site_id's normative definition (assignment rules, bridge vs. client authority, consumer constraints) is now owned by OVOS-BRIDGE-1 §3.4. Thin §3.3 to a registry pointer; retain the consumer MUST NOT parse/overwrite rules for in-pipeline consumers who never interact with the bridge spec directly. Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- §4.2 preamble: drop over-prescriptive "each captures audio/STT" description; scope audio claim to the bridge only (a deployment MAY run a separate audio channel — outside this spec's scope) - §4.2.1: drop hardware prescription (microphone/STT/TTS); add ovos.utterance.handled as the second message the satellite must receive — without it the satellite cannot do session merging (SESSION-2 §4) or know when to accept the next utterance - §4.2.2: correct wrong claim that cascading is "the satellite-and-hub pattern applied to the intent stage" — they are architecturally distinct (satellite has no local pipeline; cascading deployment does); replace "pipeline state" undefined term with concrete session fields (intent_context, active_handlers) - §4.2.3: remove site_id from the list of session isolation mechanisms — site_id is a routing group signal, not a session boundary; only distinct session_id values or NAT provide isolation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A bridge may operate in two fundamentally different modes depending on whether its participants are spec-aware: - Relaying mode (§3.5.1): participant runs OVOS-compliant code and manages its own session (satellite, peer deployment). Bridge is a transparent carrier; client is SESSION-2 authority; bridge MUST NOT overwrite a client-supplied session. - Managing mode (§3.5.2): participant has no concept of OVOS sessions (chat room, SMS gateway, non-OVOS client). Bridge owns the session lifecycle: assigns session_id per participant/channel, synthesizes session on inbound, and propagates session updates from ovos.utterance.handled back into its store for the next utterance. Both modes must produce a SESSION-1-conformant session on the bus. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A single hub utterance round can produce N distinct spoken responses, one per satellite, each grounded on the same orchestrator output but shaped by that satellite's dialog transformer chain (e.g. an LLM persona rewriter). No bridge-level protocol is needed — the pattern emerges from session-per-participant isolation (§4.2.3) combined with per-session transformer configuration (TRANSFORM-1 §5.1) and the hub executing each session's transformer chain independently. The bridge's only role is transparent session relay (§3.5.1). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Dialog transformers run in the audio-output layer just before TTS (TRANSFORM-1 §3.5), not in the hub's utterance lifecycle. In the satellite-and-hub topology this means personalisation happens on the satellite, not the hub: the hub emits the same base ovos.utterance.speak text to all satellites; each satellite's local audio-output service applies its own dialog transformer chain (persona rewriting, tone adjustment, translation) before TTS. The session carried in ovos.utterance.speak back to the satellite supplies the satellite's own dialog_transformers preference to its local audio-output layer. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add non-normative note to §4.2.4: when a deployment transmits audio over the bus (e.g. base64-encoded), the full audio stack including dialog/TTS transformers runs on the hub rather than the satellite. This is architecturally distinct from the local-audio-stack model described in §4.2.4 and is outside BRIDGE-1's scope (§1 excludes audio I/O). Add gap entry pointing to OVOS-AUDIO-1 as the appropriate future home for this topology's bus surface definition. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
§4.2.1: document that STT and audio-output placement are independent choices. Local stack: satellite runs STT, injects utterance.handle, runs TTS locally. Hub-side stack: raw audio transmitted to hub, hub runs STT and full audio-output layer including dialog/TTS transformers, satellite receives final audio. Both models use the same ovos.utterance.handle / speak / handled message types; the difference is what originates the handle and what the satellite does with the speak response. gaps.md: expand audio-transmission gap entry to cover both STT and audio-output symmetry (four combinations); point to OVOS-AUDIO-1. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Document transparent satellite skill registration: bridge forwards registration messages unchanged; orchestrator keys them by the satellite's session_id (INTENT-4 §11.1); dispatch of session-scoped intents routes back through the bridge via existing destination-based routing (§3.2); bridge SHOULD emit ovos.skill.deregister on satellite disconnect for cleanup. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Normative fixes: - §2: drop incorrect "two MUSTs" enumeration; point to §6 - §3.2: define "known participant" lifecycle (source assigned → grace period expires); add NAT cleanup SHOULD (emit deregister with hub-side session_id before dropping bijection) - §3.4: clarify site_id assignment ordering (bridge overrides client if it has higher-confidence data; downstream MUST NOT overwrite) - §3.5.1: layer-2 policy injection is a deliberate layer on top of the transparent bridge, not a violation of it; add ordering note - §3.5.2: MUST assign distinct session_id per participant (required for ovos.utterance.handled correlation); MUST apply handled updates → SHOULD with explicit race allowance (stale session ok if next utterance arrives first) - §4.2.3: add SHOULD distinct session_id per satellite with explanation of routing consequence - §4.2.4: drop redundant numbered list - §4.3 (new, was part of §4.3): out-of-utterance session sync — bridge SHOULD relay ovos.session.sync to satellites - §4.4 (renumbered from §4.3): satellite skill registration — scope to intent-based skills; note pipeline plugins out of scope; add disconnect/reconnect/bridge-own-session guidance - §5: FIFO SHOULD conditioned on transport ordering capability - §6 MAY: simplify routing bullets to reference §3.2 Appendix: - gaps.md: add session-scoped pipeline plugin registration gap, managing mode concurrent utterance race gap, NAT bijection cleanup gap Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- §3.2: client isolation argument: 7 sentences → 3 - §3.4: site_id ordering list collapses duplicate absence sentence; consumer MUST-treat-absent obligation moved into step 3 - §3.5: drop framing sentence (obvious from subheadings) - §4.2: drop "patterns not prescribed" paragraph (redundant with §1) - §4.2.1: drop "both models use the same types" summary (restates bullets) - §4.2.4: shorten dialog transformer description; drop redundant TRANSFORM-1 re-explanation; cite §3.5 for bridge role - §4.3: drop mode-consequence sentences that follow from §3.5 definitions - §4.4: replace effective-pool restatement with INTENT-4 §11.2 citation; drop "no additional routing mechanism" (obvious from §3.2 MUST) - §6 MUST: collapse two overlapping relay bullets into one; promote MSG-1 conformance from SHOULD to MUST - §6 SHOULD: remove MSG-1 entry (now MUST); simplify FIFO wording Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This was referenced May 28, 2026
Bridge MAY translate ovos.utterance.speak → ovos.utterance.speak.b64 for satellites without local TTS; hub synthesises and emits ovos.audio.speech (b64); bridge relays audio to satellite. §4.2.1 cross-reference, §6 MAY bullet, See also updated. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Standardize filename: drop ovos- prefix consistent with other specs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Companion issue: #42
Summary
Defines the bus bridge — a participant on the internal message bus that terminates an external communication channel and relays messages between the bus and remote participants.
The spec carries minimal normative weight. Most of what it documents are emergent patterns that arise from composing MSG-1 + SESSION-1/2 + PIPELINE-1 + TRANSFORM-1 + CONTEXT-1 + INTENT-4 at a bus boundary.
What the spec covers
source)destination(primary, MUST),session_id(secondary, MAY),site_id(group, MUST when grouping). Known-participant lifecycle. NAT/session-id bijectionsite_idassignment — bridge evaluates client-supplied value vs. its own determination (geolocation, home-automation area names); downstream MUST NOT overwriteovos.session.syncrelay)Key design decisions
.reply()settingdestinationto the originalsource; two participants sharingsession_id: "default"are distinguished bydestinationalonesession_idper participant)site_idowned by BRIDGE-1. Bridge is the natural assignment point; client MAY report, bridge MAY overrideovos.utterance.speakcarries the session back so each satellite's transformer preferences apply locallyCompanion PR
INTENT-4 §11 (PR #45) defines session-scoped registration that §4.4 depends on.