reference.md

August 13, 2026 · View on GitHub


← APPENDIX.md · Non-normative

6. Implementer reference

Material an implementer reaches for repeatedly: cross-spec tables that don't fit cleanly in any single normative spec.

6.1 Topic-name conventions across the family

The naming conventions of OVOS-MSG-1 v2 §2.1.1 — dot-separated hierarchy, stable root, verb-tense pattern for the trailing segment, request/terminal pairs sharing a root verb, .response suffix — apply across the family. One rule sits above the rest: identifiers appear in a topic only in the <skill_id>:<intent_name> dispatch shape, and every dotted topic is a static string. A consumer classifies any topic by a single test — a : anywhere means dispatch, no : means an ordinary dotted topic — and the complete topic surface of a deployment is enumerable from the specifications alone. The four-way collision of the word "intent" in introspection topics deserves an explicit callout:

  • ovos.intent.list (INTENT-4 §10) — list of registered intents (skills declare them; data entries name intent_name).
  • ovos.pipeline.<pipeline_id>.intents.list (PIPELINE-1 §10) — list of intents currently compiled by one plugin's matcher (data entries name intent_name).
  • ovos.transformer.intent.list (TRANSFORM-1 §6) — list of intent-transformer plugins loaded at the intent-transformer injection point (data entries name transformer_id). Despite the topic shape, this is not an intent-listing surface; it follows the per-chain pattern ovos.transformer.<type>.list where <type> happens to be intent for this chain (alongside audio, utterance, metadata, dialog, tts).

The collision is at the human-reading level only; payload shapes are distinct and a consumer subscribing to one cannot accidentally parse responses from another.

6.2 Session-field cheat-sheet

Every spec in the family that claims a session field does so via the OVOS-SESSION-1 §2.2 registry mechanism. The full set spans four specs; this table consolidates them. All fields follow the canonical SHOULD-omit / []-equivalent-to-omission wire-weight rule of OVOS-SESSION-1 §3.4.

FieldOwnerRoleEmpty-array semantics
session_idSESSION-1 §3.1identity / channeln/a (string; "default" reserved)
langSESSION-1 §3.2.1preference (user)n/a (string)
secondary_langsSESSION-1 §3.2.2preference (user)≡ absent
output_langSESSION-1 §3.2.3preference (renderer)n/a (string)
stt_langSESSION-1 §3.2.4signal (per-utterance)n/a (string)
request_langSESSION-1 §3.2.5signal (emitter hint)n/a (string)
detected_langSESSION-1 §3.2.6signal (lang-detect)n/a (string)
site_idSESSION-1 §3.3opaque group identifiern/a (string)
pipelinePIPELINE-1 §5.1preference (ordering)≡ absent
blacklisted_pipelinesPIPELINE-1 §5.2policy (denylist)≡ absent
blacklisted_skillsPIPELINE-1 §5.3policy (denylist)≡ absent
blacklisted_intentsPIPELINE-1 §5.4policy (denylist)≡ absent
audio_transformersTRANSFORM-1 §5.1preference (chain)≡ absent
utterance_transformersTRANSFORM-1 §5.1preference (chain)≡ absent
metadata_transformersTRANSFORM-1 §5.1preference (chain)≡ absent
intent_transformersTRANSFORM-1 §5.1preference (chain)≡ absent
dialog_transformersTRANSFORM-1 §5.1preference (chain)≡ absent
tts_transformersTRANSFORM-1 §5.1preference (chain)≡ absent
blacklisted_audio_transformersTRANSFORM-1 §5.2policy (denylist)≡ absent
blacklisted_utterance_transformersTRANSFORM-1 §5.2policy (denylist)≡ absent
blacklisted_metadata_transformersTRANSFORM-1 §5.2policy (denylist)≡ absent
blacklisted_intent_transformersTRANSFORM-1 §5.2policy (denylist)≡ absent
blacklisted_dialog_transformersTRANSFORM-1 §5.2policy (denylist)≡ absent
blacklisted_tts_transformersTRANSFORM-1 §5.2policy (denylist)≡ absent
intent_contextCONTEXT-1 §2per-session stateobject; absent ≡ empty

Role glossary:

  • Preference — populated by the session origin to request specific behaviour. Orchestrator narrows the request by availability and policy.
  • Policy — populated by deployment / layer-2 substrate to enforce constraints. Overrides preference at the composition stage (PIPELINE-1 §5.5, TRANSFORM-1 §5.3).
  • Signal — recorded by a producer or earlier lifecycle stage to communicate information about this specific utterance.
  • Identity / channel — names the session itself; not a preference or policy knob.

6.3 Component-identity stamp-rule cheat-sheet

Each component type self-identifies via a reserved context key. The keys coexist freely on a single Message when the derivation chain crosses component boundaries; attribution consumers apply the eight-level lifecycle-position precedence of CONTEXT-1 §5.2 to pick a single owner when needed.

Context keyOwnerStamps on (origination + modify-in-place).reply / .response.forward
skill_idINTENT-4 §3.1yesyes (authorial — overwrite)no (preserve inherited)
pipeline_idPIPELINE-1 §3.1yesyes (authorial — overwrite)no (preserve inherited)
six <type>_transformer_ids (list-valued)TRANSFORM-1 §1.3yes (append)yes (append)no (list rides through)

The <type>_transformer_ids list-valued form preserves the full per-type chain provenance on the wire (every transformer of that type that touched the Message, in order of touch). Single-string skill_id / pipeline_id reflect that those component types originate Messages rather than chain over them.

6.4 Introspection patterns

Several specs in this set define pull-query / scatter-response introspection surfaces. The shapes are intentionally similar but serve different scopes:

SpecTopicScopeAuthoritative responder
INTENT-4 §10ovos.intent.list / .describeDeclared intents observed on the busOrchestrator (the manifest)
PIPELINE-1 §10ovos.pipeline.<pipeline_id>.intents.listIntents currently compiled inside a specific plugin's matcherThe pipeline plugin
TRANSFORM-1 §6ovos.transformer.<type>.listLoaded transformers per injection pointThe orchestrator process implementing that chain

Three properties hold across these surfaces:

  1. Pull-query is the source of truth. Producers MAY broadcast load-time announcements; consumers MUST NOT rely on having received them. The bus is asynchronous and gives no delivery guarantee; a consumer that started late missed the broadcast.
  2. No completeness signal. A consumer that wants completeness keeps its own roster of expected responders and times out non-responders.
  3. Per-process slices under split orchestrators. When the orchestrator is split (PIPELINE-1 §2), each process responds from its own slice; consumers aggregate.

All of these surfaces share the ovos.<domain>. prefix; verb segments vary by domain (some nest, some don't). The uniformity is in the namespace, not in a fixed depth.

6.5 Message derivation cheat-sheet — forward vs reply

Use forward when a Message travels in the same direction as the source (handler → client). Use reply when a Message travels back toward the sender of the source (responder → requester). Using the wrong derivation produces messages that work on a single-node local bus but silently mis-route through layer-2 transports (see appendix/patterns.md §3.1.2).

EmissionDerivationRule
Handler speak, GUI events, session mutations during dispatch (PIPELINE-1 §7)forwardSame direction as the inbound dispatch
Handler-lifecycle trio .start / .complete / .error (PIPELINE-1 §8)forwardSame direction as the inbound dispatch
ovos.stop.pong (STOP-1 §4.2)replySkill answers back to the stop plugin that sent the ping
ovos.converse.pong (CONVERSE-1 §4.2)replyCandidate answers back to the converse plugin that polled
ovos.fallback.pong (FALLBACK-1 §6.1)replySkill claims or declines back to the fallback plugin
ovos.common_query.pong / ovos.common_query.response (COMMON-QUERY-1 §6.2, §7.1)replySkill answers back to the common-query plugin
Pipeline introspection response (PIPELINE-1 §10.2)replyPlugin answers back to the observer that requested

Deriving a pong with reply also carries context.utterance_id (PIPELINE-1 §9.1.1) back to the poller untouched, which is what makes the answer correlatable to its round. A pong assembled as a fresh Message loses it and is discarded.