Prerelease quirks
September 2, 2026 · View on GitHub
This file lists everything that changed or broke since the last stable
release, 8.0.0. It is version-stamped and newest first. If you install an
alpha of ovos-workshop, read this before you file a bug: the behavior you
are seeing may be documented here already.
This file resets at the next stable release. At that point its contents
become upgrade notes for the 8.0.0 -> next-stable jump, and a new, empty
quirks log starts.
9.6.2a4 — intent_files decorator registrations now carry context gates
A decorated handler's intent_files entries reach register_intent_file
with its requires_context/excludes_context declarations attached; the
intents branch of _register_decorated already forwarded them, but the
intent_files branch silently dropped them, so a decorated skill gating an
.intent-file handler had its OVOS-CONTEXT-1 §6/§6.1 declaration lost
before it ever reached the wire.
9.6.2a1 — common-query pong carries the ratified fields
The ovos.common_query.pong a common-query skill emits now includes the
ARCHITECTURE common-query.md §6.2 fields — utterance (echoed from the
ping) and can_answer — alongside the pre-spec skill_id/is_classic_cq
keys, which are kept for one stable cycle and removed at the next major.
ovos-common-query-pipeline-plugin's OVOSCommonQAPipeline.handle_skill_pong
still only reads skill_id/is_classic_cq at registration time, so the
new keys are additive and change nothing for that consumer today.
can_answer is always True here: the pong the workshop fires is a
registration-time announcement ("this skill has a common-query handler"),
not a per-utterance verdict — the classic protocol's real accept/decline
happens later, per phrase, via question:query/question:query.response.
latency_ms is omitted; no synchronous timing estimate is available at
this point in the flow.
9.6.0a4 — skill teardown (shutdown + default_shutdown) is re-entrant
BaseSkill now guards its whole teardown pair with a lock and a
_shutdown_done flag, set only by default_shutdown(). __del__ only
checks the flag, never sets it, before calling the skill-authored
shutdown(). This covers both races without breaking the common case:
if SkillManager.unload_skill() already ran skill.shutdown() then
default_shutdown() explicitly, a later GC-triggered __del__() sees the
flag set and returns immediately instead of re-running the skill's own
cleanup (closing sockets, unsubscribing callbacks, stopping threads) and
settings.store()/gui.shutdown()/event_scheduler.shutdown() a second
time; if GC alone drops the last reference with no prior explicit unload,
the flag is still unset, so __del__ runs the full teardown pair exactly
once and default_shutdown() sets the flag on its way through.
9.5.5a3 — intent registration carries OVOS-CONTEXT-1 gating
@intent_handler accepts requires_context/excludes_context kwargs —
OVOS-CONTEXT-1 §6/§6.1 gating declarations, each entry a bare key string
or a {"key": ..., "scope": "private"|"shared"} mapping. They ride the
ovos.intent.register.template / legacy padatious:register_intent
payloads for .intent file handlers, and the ovos.intent.register.keyword
/ legacy register_intent payloads for IntentBuilder (Adapt) handlers,
as additional fields (INTENT-4 §5.3/§5's unknown-field tolerance),
defaulting to an empty list when undeclared. Adapt has no
OVOS-CONTEXT-1-aware matcher, so the declaration currently has no effect
on Adapt's own matching, but per CONTEXT-1 §6 "an engine that does not
implement OVOS-CONTEXT-1 ignores them and matches as if absent" — the
field still reaches the wire rather than being stripped at the producer.
Enforcement is engine-side; workshop only carries the declaration.
9.5.0a3 — spec template registration carries slot_blacklist
The ovos.intent.register.template emission now includes the
slot_blacklist dict, matching the legacy padatious:register_intent
payload. It was omitted, so the §4.3 slot-value exclusion feature only
worked through the legacy emit and would have silently died with the
legacy path's planned removal. Engines already read the field.
9.5.0a3 — blacklist files expand bare template syntax
BlacklistFile.load now enumerates alternation and optional groups written
without a <vocab> reference — (it|this|that) becomes three entries
instead of one verbatim string that could never match (the blacklist was
silently inert). Any loaded entry still carrying unexpanded template syntax
logs a warning naming the source file.
9.5.0a1 (#541)
Every .entity file a skill ships is now auto-registered for its locale on
first resource load, with no filtering by whether an .intent file
declares a matching slot. Files in subdirectories are registered too.
- Disable via config:
{"skills": {"auto_register_entity_files": false}}. - Padatious closed-vocabulary hazard: on
ovos-padatious<= 2.0.2a1, a registered entity can make a previously-unconstrained wildcard slot reject inputs it used to accept. Pinovos-padatious>= 2.0.3a1 alongside this release, or disable the config gate. - A bare
#placeholder line (old mycroft-core digit-wildcard convention) is dead:read_resource_filealready strips it as a comment beforesamplesis built, so it was never a wildcard. It now logs a deprecation warning instead of silently doing nothing.
9.4.0a1 (#534)
ConversationalSkill now answers the converse broadcast poll
(OVOS-CONVERSE-1 §4.2).
9.3.14a1 (#542)
Hotfix. The #538 import swap in converse.py moved to
ovos_spec_tools.standardize_lang but missed the call site inside
_handle_converse_request, which kept calling the no-longer-imported
standardize_lang_tag. Every live converse request raised NameError,
silently swallowed by the handler's own except-clause into a
{result: False, error: ...} wire response — converse never actually ran.
Fixed with a regression test that drives the real handler over the bus.
9.3.13a2 (#538, #537)
Closed out a completed deprecation-warnings survey: OVOSSkill.set_context
and remove_context now delegate to a private, non-warning path on
IntentServiceInterface instead of tripping their own deprecation warning
on every call from inside the base class. Suites that deliberately exercise
the legacy register_adapt_*/register_padatious_* facade get scoped
filterwarnings so their expected warnings don't pollute the rest of the
run.
9.3.13a1 (#535)
set_context/remove_context now delegate to the session API instead of
racing skill-reply forwards against the legacy add_context/
remove_context bus topic (finding 29). A registry write for a positive
timeout carries a real expires_at timestamp; an immortal entry (no
timeout) carries none.
9.3.11a2 - 9.3.12a1
Canonical intent-topic registration moved to ovos-spec-tools, with
compat left in place (#500). register_entity_file emits the clean entity
name, not the raw filename (#528).
9.3.9a1 - 9.3.11a1
FallbackSkill is now abstract: a skill without can_answer cannot load
(#523). Language matching routed through ovos-spec-tools (#512).
Context-only requires no longer leaks into the INTENT-4 keyword emit
(#525). set_context carries the original context key through so
CONTEXT-1 gating stays reachable (#527).
9.3.4a1 - 9.3.8a1
enable_intent rebinds the handler after disable_intent (#508).
killable_intent/killable_event no longer leak a thread or bus listener
on natural completion (#513). OVOSSkill._wait_response is now bounded so
get_response cannot hang forever (#514). A change to silently disable
fallback skills predating can_answer was reverted (#515, #517) — see
9.3.9a1 above for the final (abstract-class) approach.
9.3.0a1 - 9.3.2a2
Intent dispatch handlers bind to canonical INTENT-4 intent names (#497).
Padacioso floor bumped so dangling <name> template refs raise
MalformedTemplate instead of silently matching nothing (#493).
9.2.10a1 (#431, dual-emit landed 9.3.0a1)
OVOS-INTENT-4 registration topics are emitted dual with the legacy ones.
9.2.0a1 - 9.2.9a1
ovos.utterance.handled is now gated in converse/fallback so it fires only
when core owns the emit (PIPELINE-1 §9.5, #486). Inline <voc> references
are expanded before intents register to the engine, and re-registration is
deduped (#470). .blacklist locale resource support added for intents
(#450), with the OVOS-INTENT-2 §4.3 entity/slot blacklist emitted on
registration (#454).
9.0.0a1 - 9.0.4a1
Intent layers now gate via intent context instead of enable/disable
(#427). ovos-padacioso cap widened <2.0.0 -> <3.0.0 (#433).
8.1.0a1 - 8.3.0a1
ovos-bus-client cap widened <2.0.0 -> <3.0.0 (#416). Word-list joining
uses JSON-based euphony rules (#405). New yesno/selection agent plugins
(#390). New spec topic ovos.utterance.speak emitted (#425).
8.0.1a1 - 8.0.4a4
Locale folder names normalized to canonical BCP-47 form, with lookups and tests updated to match (#392, #395).