Spec adoption matrix

September 6, 2026 · View on GitHub

docs/coverage.md proves the harness holds a suite for every spec and knows which clauses each suite asserts. It says nothing about which OVOS repos actually put a spec's wire surface on the bus. This page answers that question, one table per spec: which repos emit or consume the spec's canonical topics, whether that adoption is the spec-native form or a transitional bridge over a legacy topic, and a commit-pinned link to the line that proves it.

Facts here come from grepping each repo's checkout at origin/dev (or the repo's actual default branch, noted per row) for the spec's canonical topic strings — never from memory, prose in docs/coverage.md, or the spec document's own examples. A "not adopted" note means the grep found no producer or consumer of that spec's topics anywhere in the swept workspace; it is a finding, not a placeholder to be filled in later. The table for a spec is a representative sample of the repos that implement its core verbs, not an exhaustive census of every file that mentions a topic in passing (a docstring, a comment, a changelog entry).

Two specs (OVOS-INTENT-1, OVOS-INTENT-3) define no wire topic at all by design — grepping for a topic string is the wrong test for them, and their sections say so explicitly and point at the semantic adoption path instead (the definition model and the one-owner registration binding).

The test_adoption_matrix_sync.py meta-test keeps this page honest going forward: every spec section here must exist for every spec section in docs/coverage.md, every evidence link must be a commit-pinned GitHub blob URL (never a branch URL, which drifts under the reader) whose referenced line actually contains the topic string the row claims, and every repo named here must resolve to a local checkout or a small allow-list.

OVOS-PIPELINE-1

Canonical topics: ovos.utterance.handle, ovos.utterance.handled, ovos.utterance.cancelled, ovos.intent.matched, ovos.intent.unmatched.

RepoRoleStateEvidence
ovos-coreemits ovos.utterance.handled at pipeline completion (_emit_utterance_handled, §9.5)adoptedovos_core/intent_services/service.py#L408
ovos-audioconsumes ovos.utterance.handled to restore playback volumeadoptedovos_audio/audio.py#L190
ovos-guiforwards ovos.utterance.handled/ovos.utterance.cancelled to the GUI client as spec topicsadoptedovos_gui/namespace.py#L466
pyhtmx-gui-clientconsumes ovos.utterance.handled/.cancelled as typed constantsadoptedsrc/pyhtmx_gui/types.py#L40 (default branch main)
ovoscopeuses ovos.utterance.handled as the default end-of-flow topic in its test harnessadoptedovoscope/init.py#L33

OVOS-STOP-1

Canonical topics: ovos.stop, ovos.stop.ping, ovos.stop.pong.

RepoRoleStateEvidence
ovos-audioconsumes ovos.stop directly; also bridges the legacy mycroft.stop alias at the bus-client boundarytransitional (legacy mycroft.stop still mirrored)ovos_audio/audio.py#L174
ovos-pydantic-modelsmodels ovos.stop as the canonical stop message typeadoptedovos_pydantic_models/audio/audioservice.py#L443

OVOS-INTENT-4

Canonical topics: ovos.intent.register.keyword, ovos.intent.register.template, ovos.intent.deregister, ovos.entity.register/.deregister, ovos.intent.disable/.enable, ovos.intent.list, ovos.intent.describe.

Per-plugin adoption for the keyword/template registration surface already has its own detail table in docs/coverage.md's OVOS-INTENT-4 (per-plugin) section; this table only adds the framework-level rows that table omits.

RepoRoleStateEvidence
ovos-coreemits ovos.intent.register.keyword/.template as the registration bus contractadoptedovos_core/intent_services/manifest.py#L36
ovos-workshopskill base classes still register via the legacy padatious:register_intent/register_entity calls pending direct pipeline adoptiontransitional (legacy padatious:register_intent)ovos_workshop/intents.py#L377
ovos-markov-pipeline-pluginconsumes ovos.intent.register.template, .deregister, .disableadoptedovos_markov_pipeline/init.py#L606
padaciosoconsumes the template registration topic via the SpecMessage.INTENT_REGISTER_TEMPLATE enum value (ovos.intent.register.template, §6), alongside the legacy in-process registration pathtransitional (legacy in-process register_intent)padacioso/opm.py#L84
ovos-control-panelqueries ovos.intent.list for its intent-inspection admin viewadopted (consumer)ovos_webui/intents.py#L58

OVOS-CONVERSE-1

Canonical topics: ovos.converse.ping, ovos.converse.pong, ovos.converse.active.list.

RepoRoleStateEvidence
ovos-workshopskill base class answers ovos.converse.ping with ovos.converse.pongadoptedovos_workshop/skills/converse.py#L60

OVOS-FALLBACK-1

Canonical topics: ovos.fallback.register, .deregister, .ping, .pong.

No repo outside the harness's own conformance suite and spec-authoring tooling (ovos-spec-tools) was found emitting or consuming these topics. ovos-core's fallback pipeline still operates purely on the legacy in-process FallbackSkill registration path. Not adopted.

OVOS-SESSION-1 / OVOS-SESSION-2

Canonical wire fields: session.active_handlers, session.pipeline, session.response_mode, session.intent_context (SESSION-1); ovos.session.start (SESSION-2, client-authority session creation).

SESSION-1 defines the session field registry rather than a dedicated topic, so adoption here means a repo reads or writes these fields on the Session object rather than subscribing to a topic string.

RepoRoleStateEvidence
ovos-bus-clientsession.intent_context is the adapt-facing frame-stack registry field, held on the Session objectadoptedovos_bus_client/session.py#L411
ovos-corefilters the active pipeline matchers by session.pipeline while dispatchingadoptedovos_core/intent_services/service.py#L340
ovos-workshopskill converse handling reads session.active_handlers while looking for a still-active skilladoptedovos_workshop/skills/converse.py#L153

SESSION-2's ovos.session.start topic (client-authority session creation) had no producer or consumer anywhere in the swept workspace, including ovos-spec-tools and the harness's own conformance suite. Not adopted as a distinct wire event; session creation in the checked-out repos is still implicit (first-message-creates-session), not an explicit ovos.session.start emit.

OVOS-GUI-1

Canonical topics: gui.page.show, gui.value.set, gui.clear.namespace.

RepoRoleStateEvidence
ovos-bus-clientemits gui.page.show / gui.value.set via the GUIInterface APIadoptedovos_bus_client/apis/gui.py#L398
ovos-plugin-manageremits gui.clear.namespace from the GUI plugin templateadoptedovos_plugin_manager/templates/gui.py#L77
ovos-guiconsumes gui.page.show to render pagesadoptedovos_gui/namespace.py#L453
ovos-gui-api-clientconsumes gui.page.show in its client libraryadoptedovos_gui_api_client/init.py#L525
ovos-gui-plugin-ag-uiconsumes gui.value.set / gui.clear.namespace to drive AG-UI state deltasadoptedovos_gui_plugin_ag_ui/init.py#L258

OVOS-BRIDGE-1

The bridge role (relaying the bus across an external transport while preserving session and routing fields) is implemented by the HiveMind family of repos. hivemind-core (published as HiveMind-core, org JarbasHiveMind) is the reference bridge implementation.

RepoRoleStateEvidence
HiveMind-corestamps context["source"]/context["peer"] on every message injected from an external client, the bridge identity-stamping duty (§3.1)adoptedhivemind_core/protocol.py#L2400
HiveMind-corepreserves "session" in message.context across the bridge boundary when relaying an inbound messageadoptedhivemind_core/protocol.py#L2924
hivescopeasserts context["source"] identity in its bridge conformance test harnessadopted (consumer, test tooling)hivescope/assertions.py#L1015

hm-core-v3 (a parallel rewrite under the same org) also carries a protocol.py implementing this role; it is not tabled separately here because it has not been independently diffed against the spec clauses the way hivemind-core was for this page.

OVOS-MSG-1

Canonical surface: the Message envelope (type/data/context) and its forward/reply derivations, plus the context.source/context.destination routing keys.

RepoRoleStateEvidence
ovos-bus-clientdefines Message, forward, reply, and bridges legacy topic pairs via NamespaceTranslatortransitional (dual-emits spec + legacy topic pairs)ovos_bus_client/client/client.py#L29

Every other repo in the workspace that imports ovos_bus_client.Message inherits this envelope by construction; this table lists only the repo that defines and translates it, not the transitive closure of Message importers.

OVOS-AUDIO-IN-1

Canonical topics: ovos.listener.wakeword, ovos.listener.record.started/.ended, ovos.listener.awoken/.sleep, ovos.mic.listen, ovos.stt.failed.

RepoRoleStateEvidence
ovos-audioemits ovos.mic.listen when a b64-audio response requests a follow-up listenadoptedovos_audio/service.py#L311
ovos-ui-enclosure-protocoldocuments its handler against ovos.listener.awokenadopted (consumer)ovos_ui_enclosure_protocol/listener.py#L45
ovoscopeasserts ovos.mic.listen ordering in its test harnessadopted (consumer, test tooling)ovoscope/audio.py#L823

ovos-dinkum-listener and ovos-simple-listener — the two listener implementations checked out in this workspace — had no direct match on these topic strings at origin/dev; their wake-word/VAD pipeline surfaces these events through ovos-audio/ovos-bus-client rather than emitting the topics themselves in-process.

OVOS-AUDIO-1

Canonical topics: ovos.audio.is_speaking, ovos.audio.output.started/.ended, ovos.audio.play_sound, ovos.audio.queue, ovos.audio.speech, ovos.audio.stop.

RepoRoleStateEvidence
ovos-audioanswers ovos.audio.is_speaking via SpecMessage.AUDIO_IS_SPEAKING, and dual-emits the legacy mycroft.audio.is_speaking reply alongside ittransitional (dual-emits legacy mycroft.audio.is_speaking)ovos_audio/service.py#L504
ovos-mediaconsumes ovos.audio.output.started/.ended from ovos-audio to serialise OCP playback around TTSadoptedovos_media/bus/api.py#L240
ovos-ui-enclosure-protocoldocuments handlers against ovos.audio.output.started/.endedadopted (consumer)ovos_ui_enclosure_protocol/listener.py#L43

OVOS-COMMON-QUERY-1

Canonical topics: ovos.common_query.ping/.pong, .request, .response.

RepoRoleStateEvidence
ovos-pydantic-modelsmodels ovos.common_query.ping/.pong as typed messagesadoptedovos_pydantic_models/skills/common_query.py#L75
ovos-workshopCQS skill base class subscribes to ovos.common_query.ping and answers with .pongadoptedovos_workshop/skills/ovos.py#L969

OVOS-INTENT-1

This spec defines the sentence-template grammar — an authoring syntax and a §6 training-data wire contract, not a topic of its own. Grepping for a topic string is the wrong test here; the honest adoption path is: which repo implements the grammar's expansion algorithm, and which repo carries expanded templates onto the wire.

RepoRoleStateEvidence
ovos-spec-toolsimplements the template expand/iter_expand grammar (§3–§4) that other repos importadopted (definition model)ovos_spec_tools/expansion.py#L60
padaciosocarries expanded templates over the §6 wire contract, consuming the template registration topic via SpecMessage.INTENT_REGISTER_TEMPLATE (same registration path tabled under OVOS-INTENT-4)adopted (consumer)padacioso/opm.py#L84

confirm.dialog/confirm.intent — the illustrative topic names the spec document uses as examples, not part of the grammar itself — had no hit outside the harness's own OVOS-INTENT-2 conformance suite, consistent with them being examples rather than a contract this spec defines.

OVOS-INTENT-2

Canonical topics: confirm.dialog, confirm.intent, person.blacklist.

RepoRoleStateEvidence
ovos-workshopdocuments the "person.blacklist" example of the "<entity>.blacklist" locale-file convention, rather than emitting a dedicated bus topictransitional (documented convention, not a dedicated bus topic yet)ovos_workshop/skills/ovos.py#L1557

OVOS-INTENT-3

This spec is explicit that an intent "is therefore not an event... not a message that any component may emit, and not a topic that any component may subscribe to" (intent-3.md §1). Grepping for a topic string cannot find an adopter for a spec that defines none by design; the honest adoption path is the one-owner/one-handler registration binding the spec does mandate.

RepoRoleStateEvidence
ovos-spec-toolsdefines the Intent model (name, required/optional slots, one bound handler) this spec's data model maps ontoadopted (definition model)ovos_spec_tools/intent.py#L75
ovos-workshopintent_handler decorator binds exactly one handler function to one intent, the one-owner rule this spec mandatesadopted (consumer)ovos_workshop/decorators/init.py#L64

OVOS-CONTEXT-1

Canonical surface: session.intent_context (declarative intent context frames) and the ovos.intent.register.template registration topic it rides on.

RepoRoleStateEvidence
ovos-bus-clientsession.intent_context is projected as the adapt-facing frame-stack viewadoptedovos_bus_client/session.py#L411
ovos-coreconsumes ovos.intent.register.template, the registration topic the context frames ride onadoptedovos_core/intent_services/manifest.py#L37

OVOS-OCP-1

Canonical topics: ovos.common_play.play/.pause/.resume/.stop/.next/.previous/.seek, .search/.search.start/.search.end, .announce, .media.state, .player.state, .track.state.

RepoRoleStateEvidence
ovos-mediafull player implementation: ovos.common_play.play and the rest of the ovos.common_play.* surface are emitted and consumedadoptedovos_media/player/now_playing.py#L96
ovos-plugin-manageraudio-backend template emits ovos.common_play.player.stateadoptedovos_plugin_manager/templates/audio.py#L284
ovos-workshopovos.common_play.play is emitted by the OVOSCommonPlaybackSkill base classadoptedovos_workshop/skills/common_play.py#L458
ovos-bus-clientovos.common_play.play is forwarded by the OCPInterface APIadoptedovos_bus_client/apis/ocp.py#L391
ovos-skill-alertsconsumes ovos.common_play.play to trigger an alarm's audioadopted (consumer)util/media.py#L74
ovoscopedrives ovos.common_play.play and asserts the resulting state topics in its test harnessadopted (consumer, test tooling)ovoscope/media.py#L459

OVOS-PERSONA-1

Canonical topics: ovos.persona.query/.register/.deregister/.list, .activated/.answer/.dismissed.

ovos-persona (the pipeline plugin, distinct from ovos-persona-server's unrelated ovos.persona.tools.* agent-tool-discovery surface) subscribes to and emits five of the seven canonical topics.

RepoRoleStateEvidence
ovos-personaconsumes ovos.persona.query to answer an out-of-band persona queryadoptedovos_persona/init.py#L136
ovos-personaconsumes ovos.persona.list and answers with ovos.persona.list.responseadoptedovos_persona/init.py#L137
ovos-personaemits ovos.persona.activated / ovos.persona.dismissed on persona lifecycle changesadoptedovos_persona/init.py#L733
ovos-personaemits ovos.persona.answer in reply to a queryadoptedovos_persona/init.py#L800

ovos-persona's register_persona/deregister_persona are in-process methods, not bus topics — ovos.persona.register/.deregister themselves had no producer or consumer anywhere in the swept workspace. Partially adopted: query/list/activated/dismissed/answer are live on the bus; register/deregister remain in-process-only (transitional).

OVOS-TRANSFORM-1

Canonical topics: ovos.transformer.audio.list, .dialog.list, .intent.list, .metadata.list, .tts.list, .utterance.list (each with a .response counterpart).

No producer or consumer was found in the workspace outside architecture and ovos-spec-tools's own message-model tests. Transformer plugin discovery in the checked-out repos still runs through ovos-plugin-manager's in-process plugin loading rather than a bus introspection topic. Not adopted.

OVOS-SCHEDULER-1

Canonical topics: ovos.scheduler.schedule, .cancel, .list, .fire, .missed (each request with a .response counterpart).

The harness has no suite for this spec, so nothing here was measured against a running stack. ovos-workshop's scheduled-event API and the legacy mycroft.scheduler.* adapter are the surfaces a survey would start from. Not surveyed.


← Coverage · Home