← APPENDIX.md · Non-normative
These specifications are prescriptive. Some of what they prescribe matches the reference implementation verbatim; some is a deliberate cleanup from which the implementation diverges. This section catalogues the known divergences between the specifications and the reference implementation.
Formalizations of behaviour in the reference implementation that need no change:
- The Message envelope (
type/data/context) — matchesovos-bus-client.Message. source,destinationsemantics including theMessage.replyswap — matchesovos-bus-client/message.py.context.sessionas a serialized Session object — matchesovos-bus-client/client/client.py'smessage.context["session"] = sess.serialize().session.session_id == "default"for device-local origin — matchesovos-audio/utils.py'srequire_default_sessiondecorator.session.langas the user's preferred language — matches the Session class'slangattribute.forward/reply/responsederivation semantics — matchesovos-bus-client.Message.{forward,reply,response}.- The
.responsesuffix convention — pervasive across OVOS topics. ovos.utterance.cancelledandovos.utterance.handled(PIPELINE-1) — match current topic names verbatim.- Per-utterance first-match-wins iteration (PIPELINE-1) —
matches
ovos-core/intent_services/service.py'shandle_utterance/get_pipeline. - Per-session pipeline configuration (PIPELINE-1) — matches
Session.pipeline. - The
<skill_id>:<intent_name>dispatch topic shape (PIPELINE-1) — matches OVOS practice; skills subscribe to these topics.
| Spec | Current | Prescribed | Notes |
|---|---|---|---|
| INTENT-3 v1.1 | "host" | "orchestrator" | Editorial; conformance unchanged. |
| PIPELINE-1 | mycroft.skill.handler.start / .complete / .error |
ovos.intent.handler.start / .complete / .error |
Renamed into the ovos.intent.* namespace for uniformity. Breaks every existing handler-lifecycle observer; the migration cost is real. |
| PIPELINE-1 | recognizer_loop:utterance |
ovos.utterance.handle |
See §5.4 entry. Migration touches ovos-dinkum-listener, ovos-simple-listener, ovos-audio, and ovos-core/intent_services/service.py. |
| PIPELINE-1 | complete_intent_failure |
ovos.intent.unmatched |
Follows ovos.intent.* namespace; pairs with ovos.intent.matched. |
The following topics exist in current ovos-core but are not defined by any spec and should be removed or replaced:
ovos.session.update_default— emitted bySessionManagerto broadcast the default session. SESSION-2 §5.4 acknowledges that an orchestrator MAY emit default-session state on a deployer-defined topic but assigns no normative name. This ad-hoc topic should be retired: any component that needs the default-session state can subscribe toovos.utterance.handled(PIPELINE-1 §9.5) and read the session it carries, or listen to any other assistant-emitted Message on the default session. See §5.7 for the migration mapping. Note:ovos.session.syncserves a distinct purpose — explicit out-of-utterance state sync — and is formalized by SESSION-2 §2.7; see §5.5 for its entry as a topic without direct precedent.
- Keyword intent registration is atomic (INTENT-4 §5).
Today a keyword intent is built up via multiple
register_vocabmessages followed by aregister_intentwith an AdaptIntentBuilder.__dict__payload. INTENT-4 collapses this into a single message with structured{required, optional, one_of, excluded}arrays of vocabulary descriptors. Every skill's keyword-intent path needs to be rewritten in the workshop layer. - Template intent registration uses structured identity
(INTENT-4 §6). Today
padatious:register_intentcarries{name, samples, file_name, lang, blacklisted_words}; the prescribed shape uses the structured(skill_id, intent_name, lang)triple plussamples|fileandblacklist|blacklist_file. - Dispatch payload is minimal (PIPELINE-1 §7.1). Today
dispatch carries
skill_idandintent_namein the payload. PIPELINE-1 drops both from the payload — they are already in the topic (<skill_id>:<intent_name>); a consumer that needs them splits the topic. The prescribed payload is{lang, utterance, slots}. For plugin-bundled handlers (pipeline_id == skill_id), the same uniform dispatch applies. - Handler-lifecycle payload updated (PIPELINE-1 §8.2).
Today the trio payload is
{name: <handler_func_name>}. Prescribed:{skill_id, intent_name, optional exception}.
- The orchestrator maintains a passive registration index
(INTENT-4 §10). Today there is no central index — each
plugin knows what it consumed; nothing aggregates that
view. INTENT-4 prescribes the orchestrator subscribe to
all registration topics in parallel with plugins and serve
ovos.intent.list/ovos.intent.describefrom the passive view. This is a new orchestrator responsibility, not a change to existing behaviour. - The match contract is the single obligation (PIPELINE-1
§4.2). The plugin's
matchoperation has one MUST: return aMatchornull. Bus emissions duringmatchare allowed — converse plugins, LLM-backed matchers, and agent-backed shapes are all conformant. Session mutation duringmatchgoes viaMatch.updated_sessionso declined matches' mutations never escape. Match.updated_sessionas the match-phase session channel (PIPELINE-1 §4.1, §4.2). Promotes the existing ovos-core code patternsess = match.updated_session or SessionManager.get(message)to a normative Match field. The plugin that produces a claiming match composes any session mutations it needs (clearing or settingsession.response_mode, pre-promoting an active-handler to the head, setting intent_context alongside the match) into a fresh snapshot returned inMatch.updated_session. The orchestrator uses that snapshot for the dispatch and every downstream stage; a declined-match (plugin returnsnull) drops the snapshot at the plugin boundary. This is what makes match-phase mutation safe under §6.2 first-match-wins iteration.ovos.utterance.handledon every terminal path (PIPELINE-1 §9.5). Currentovos-workshop's_on_event_errordoes not emit it on the handler-error path (ovos.py:1478-1497). PIPELINE-1 §8 places trio emission on the orchestrator-wrapper around the handler, not on the handler itself — workshop is the wrapper in current OVOS, and the spec contract requires the wrapper to emitovos.utterance.handledunconditionally.- Handler-trio is orchestrator-owned (PIPELINE-1 §8).
The orchestrator that invokes the handler wraps the call
and emits
ovos.intent.handler.start/.complete/.erroraround it. Third-party handler code carries no normative obligation to participate in trio emission. Skill authors are not protocol authors; the wrapper observes start / return / exception around an opaque callable. - Per-pipeline_id intent introspection (PIPELINE-1 §10).
Pull-query / scatter-response surface keyed on
pipeline_id, giving consumers visibility into which intents a particular pipeline plugin's matcher has compiled, distinct from the orchestrator's manifest of declared intents (INTENT-4 §10). No current OVOS analogue. - CONTEXT-1 scope and ownership encoded in the key shape
(CONTEXT-1 §2, §3). A bare key
Personis shared; a prefixed keymusic.skill:Personis private tomusic.skill. The:is load-bearing — mirroring the<skill_id>:<intent_name>dispatch topic. Drops separatescopeandoriginfields on stored entries (both were redundant with the key shape).requires_contextandexcludes_contextdeclarations take an OPTIONALscope: private|shareddiscriminator (defaultprivate) to express which lookup the gate uses; bare-string declarations default to private to prevent shared-leak. - Skill self-identification on every emission (INTENT-4
§3.1). Current OVOS skills set
context.skill_idon some emissions but not uniformly. Enforcement is structural on the dispatch path: the orchestrator stampscontext.skill_idfrom the<skill_id>:<intent_name>dispatch topic prefix, and skill emissions viaforward/replyinherit automatically. Loader-side interception covers off-dispatch emissions. - Entry-point topic renamed
ovos.utterance.handle(PIPELINE-1 §9.1).recognizer_loop:utterancefails MSG-1 §2.1.1 naming conventions::as a segment separator, an implementation-role prefix, and no pairing with the terminalovos.utterance.handled. Migration cost is real — every audio-input service and intent-service handler is affected. A transitional deployment MAY subscribe to both names during migration.
ovos.intent.matched(PIPELINE-1 §9.2). The positive-match broadcast notification. No current equivalent.ovos.intent.unmatched(PIPELINE-1 §9.4). Renamed fromcomplete_intent_failure; follows theovos.intent.*namespace for symmetry withovos.intent.matched.ovos.utterance.speak(PIPELINE-1 §9.6). The NL output exit point; symmetric toovos.utterance.handle. No current equivalent — TTS trigger is currently implicit.ovos.utterance.speak.b64(AUDIO-1 §3.4). Variant ofovos.utterance.speakfor remote-client delivery: the audio output service runs the same TTS pipeline but emits synthesised audio as base64 viaovos.audio.speechinstead of queuing for local playback. Used by bridges serving satellites without TTS (BRIDGE-1 §4.2.4).ovos.audio.speech(AUDIO-1 §4.3). Base64-encoded synthesised audio broadcast; emitted in response toovos.utterance.speak.b64. Carries alistenflag. Remote clients (e.g. satellites relayed by a bridge) decode and play the audio themselves.ovos.audio.queue/ovos.audio.play_sound(AUDIO-1 §4.1, §4.2). Sound-effect playback topics. Payloads accept either aurior inline base64audiofield, enabling cross-host audio delivery without shared filesystem access.ovos.intent.list/ovos.intent.describe(INTENT-4 §10). Introspection topics served from the orchestrator's passive registration index.ovos.context.set/.unset/.clear/.list(CONTEXT-1 §5). Skill-facing API replacing Adapt-specificadd_context/remove_contextplusmycroft.skill.set_cross_context.ovos.transformer.{type}.list(TRANSFORM-1 §6). Per-type introspection of loaded transformers.- Materialize-default-session rule on
forward/reply/response(MSG-1 §5). Formalizes a "MAY" convenience for in-process subsystems; compatible with existing behaviour. ovos.session.sync(SESSION-2 §2.7). Explicit out-of-utterance session-state sync emitted by a component that has mutated session state outside the normal utterance lifecycle and needs the change propagated. No spec-conformant predecessor —ovos.session.update_default(retired, see §5.2.1) served an overlapping purpose for the default session only.ovos.session.syncis generalised to any session.
- The session object's internal shape is owned by
OVOS-SESSION-1; the field set is the closed set defined
there plus whatever future specs claim via SESSION-1 §2.1.
The "extra" fields current OVOS Session carries
(
persona_id,system_unit,time_format,date_format, …) ride through as non-normative pass-through and may be claimed by future per-domain specs. - The
mycroft.*topic prefix outside the intent layer (e.g.mycroft.audio.*) — these are not part of any spec here. - The
<skill_id>:<intent_name>dispatch topic — kept verbatim from current OVOS so no skill needs to migrate its handler subscription. - Engine-specific introspection topics. The standard
plugins expose their own debug / inspection topics — for
example
intent.service.adapt.reply,intent.service.adapt.manifest,intent.service.adapt.vocab.manifest, andintent.service.padatious.get. These are plugin-specific surface, parallel to the spec's genericovos.intent.list/ovos.intent.describe(INTENT-4 §10). The specs do not claim authority over them — they remain plugin-defined and may continue to coexist with the orchestrator's generic index.
The bus topics formalized by INTENT-4 and PIPELINE-1 replace a number of predecessor names. The mapping:
| Predecessor topic | v1 replacement | Notes |
|---|---|---|
register_vocab |
folded into ovos.intent.register.keyword |
Vocabularies in v1 are inline samples or file-by-path inside the registration. |
register_intent (Adapt parser) |
ovos.intent.register.keyword |
Adapt's IntentBuilder.__dict__ payload replaced by the structured shape. |
padatious:register_intent |
ovos.intent.register.template |
Same content, structured payload. |
padatious:register_entity |
ovos.entity.register |
Entities are not Padatious-specific. |
detach_intent |
ovos.intent.deregister |
Identity now expressed as the structured triple, not the munged skill_id:intent_name string. |
detach_skill |
ovos.skill.deregister |
|
mycroft.skill.enable_intent / mycroft.skill.disable_intent |
ovos.intent.enable / ovos.intent.disable |
First-class topics under v1, with the prefix dropped. |
| Predecessor topic | Status |
|---|---|
recognizer_loop:utterance |
renamed to ovos.utterance.handle (see §5.4) |
complete_intent_failure |
renamed to ovos.intent.unmatched — follows ovos.intent.* namespace. |
ovos.utterance.cancelled |
unchanged — kept as the cancellation signal. |
ovos.utterance.handled |
unchanged — kept as the universal end-marker. |
<skill_id>:<intent_name> |
unchanged — dispatch topic; a plugin-bundled handler has skill_id == pipeline_id. |
mycroft.skill.handler.start / .complete / .error |
renamed to ovos.intent.handler.start / .complete / .error |
ovos.session.update_default |
retire — subscribe to ovos.utterance.handled (PIPELINE-1 §9.5) to read updated default-session state; or to any assistant-emitted Message on the default session. See §5.2.1. |
| Predecessor topic | Status |
|---|---|
add_context / remove_context |
Replaced by ovos.context.set / .unset under CONTEXT-1. |
mycroft.skill.set_cross_context / remove_cross_context |
Replaced by ovos.context.set / .unset with scope: "shared" under CONTEXT-1. |
<skill_id>.activate |
Activity-tracking emit currently in ovos-core; not part of any spec here. |
| Predecessor topic | v2 replacement | Notes |
|---|---|---|
recognizer_loop:record_begin |
ovos.listener.record.started |
Capture start. : segment separator and implementation-role prefix dropped; no payload. |
recognizer_loop:record_end |
ovos.listener.record.ended |
Capture end; pairs with the start signal. |
recognizer_loop:sleep |
ovos.listener.sleep |
Controller-to-listener sleep request. |
mycroft.awoken |
ovos.listener.awoken |
Sleep→awake transition; moved into the ovos.listener.* namespace. |
- BRIDGE-1 defines source-stamping and destination-based routing;
current HiveMind bridges route primarily by session_id.
HiveMind groups messages by
session_idand delivers them to the peer that owns that session. BRIDGE-1 prescribesdestinationas the primary signal because two peers sharing the samesession_id(including"default") cannot be distinguished by session_id alone. HiveMind deployments that use per-peersession_ids are conformant with either model; deployments that share the"default"session across multiple peers must migrate to destination-based routing for client isolation. - No existing implementation fully conforms to OVOS-BRIDGE-1. The bridge spec formalizes a role that exists in deployments (the HiveMind gateway, the bus client, any inbound message fan-in) with a tighter normative core — source-stamping and session-preservation requirements — than current implementations provide.