Conversation
ovos-core never emitted a legacy twin of anything: the intent layer already
speaks the spec topics, and the legacy copies were re-delivered by the
bus-client bridge. With the bridge removed, what is left is the handful of
places that still wrote a legacy topic literal.
Flipped to the SpecMessage constant:
* mycroft.audio.play_sound -> ovos.audio.play_sound (cancel + no-match
error sound in the intent service, install/error sounds in the skill
installer)
* mycroft.stop -> ovos.stop (STOP-1 §5.3)
* skill.stop.pong -> ovos.stop.pong (STOP-1 §4.2)
* mycroft.audio.speech.stop -> ovos.audio.stop (AUDIO-1 §6)
Left alone, because none of them ever rode the bridge: the per-skill
{skill_id}.stop.ping / {skill_id}.stop placeholders, the PIPELINE-1 §8
mycroft.skill.handler.* done-signals, mycroft.skills.abort_question, and the
"complete_intent_failure" metrics label in the opendata payload.
The send_complete_intent_failure docstring promised the bridge would
re-deliver the legacy topic to old consumers. It no longer does, and the
docstring says so.
Unit tests that asserted the legacy spelling now assert the spec one;
test_handle_global_stop additionally asserts mycroft.stop is absent. The
end-to-end suite ran every scenario twice, once per namespace, because the
bus bridged them - the "legacy" path is removed from every NAMESPACE_PATHS
and pinned instead by test/end2end/test_no_legacy_wire_compat.py, which
proves a legacy injection starts no pipeline and a no-match emits no
complete_intent_failure twin. test_intent_alias_backcompat.py keeps its
engine-side blacklist half and inverts its dispatch half: the legacy
suffixed topic now reaches nobody.
BREAKING CHANGE: ovos-core emits and consumes OVOS-MSG-1 spec topics only.
ovos-audio must consume ovos.audio.play_sound and ovos.audio.stop, and
skills must listen on ovos.stop and answer on ovos.stop.pong.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The stop end-to-end suites expected the legacy mycroft.stop broadcast; the orchestrator now emits ovos.stop (STOP-1 §5.3), so the expectations follow. ovoscope's TTS mock still emits the legacy recognizer_loop:audio_output_* and nothing bridges it any more, so both spellings are filtered in the ignore lists until ovoscope adopts AUDIO-1 §5.1/§5.2. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
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 |
Hello! The automated checks have been performed. 👋I've aggregated the results of the automated checks for this PR below. 🏷️ Release PreviewThe release tag is ready to be minted. 🏷️ Caution Breaking change — this PR will bump the MAJOR version ( Current:
✅ PR title follows conventional commit format. 🚀 Release Channel Compatibility Predicted next version:
🔎 Type CheckI've performed a routine sweep of your changes. 🧹 ❌ mypy: 280 error(s) found
Errors (showing first 10/280)📋 Repo HealthEnsuring the codebase stays lean and mean. 💪 ✅ All required files present. Latest Version: ✅ 📚 DocsI've distilled the results into this summary. 🧪 ✅ All required documentation files present. ✅ 📊 CoverageQuantifying the quality of our test suite. 🧪 Files below 80% coverage (9 files)
Full report: download the 🔌 Plugin DetectionThe OPM check is now finished. 🏁 ❌ Plugin Status: ERRORS (1) Plugin Info:
OPM Detection:
Entry Point Validation:
⊘ No Issues:
🔨 Build TestsThe build pipeline has reached its destination. 📍 ✅ All versions pass
🔌 Skill Tests (ovoscope)A detailed report on the skill's intent-matching accuracy. 📝 ❌ 3/43 passed, 5 failed ❌ **TestAdaptIntent** — 0/4
❌ **TestCancelIntentMidSentence** — 0/1
❌ **TestConverse** — 0/1
❌ **TestCountSkills** — 0/4
❌ **TestDeactivate** — 0/3
❌ **TestFallback** — 0/1
❌ **TestGlobalStopVocWithActiveSkill** — 0/1
❌ **TestGlobalStopVocabulary** — 0/2
❌ **TestIntentPipelineRouting** — 0/4
❌ **TestLangDisambiguation** — 0/4
❌ **TestLegacyIntentIdBackCompat** — 0/2
❌ **TestNoLegacyWireCompat** — 1/3
❌ **TestNoSkills** — 0/2
❌ **TestPadatiousIntent** — 0/4
❌ **TestStopNoSkills** — 0/3
❌ **TestStopServiceNotASkill** — 0/1
❌ **TestStopSkillCanHandleFalse** — 0/1
🚌 Bus CoverageA comprehensive review of the skill's bus-level interactions. 🚌 🔴 Coverage Summary
📊 Per-Skill Breakdown
🔍 Detailed Message Type Breakdown
|
The dropped legacy-wire-compat guard tests (test_no_legacy_wire_compat.py, test_activate.py, test_intent_alias_backcompat.py) fail against the released ovos-bus-client/ovos-utils/ovos-workshop because those still bridge the legacy bus namespace. The bridge removal is split across sibling PRs (ovos-bus-client#272, ovos-utils#412, ovos-workshop#501) that haven't merged/released yet. Use the ovoscope reusable workflow's post_install_pip hook to re-pin those three packages from their companion dev branches after the normal test-extras install, so CI exercises the full post-kill-switch stack this PR assumes. Remove once the companions merge and release. AI-Generated Change: Model: claude-sonnet-4-6
… for the migration window The skill-addressed fallback ping/pong machinery landed with no compatibility window: any released ovos-workshop (pre-OpenVoiceOS#465, broadcast-only) paired with this branch never gets its fallback ping answered, since the broadcast ping/pong collector was dropped outright. FALLBACK-1 §6.1 makes the addressed topics normative but explicitly sanctions the broadcast poll as an observably-equivalent optimisation, so restore it for one deprecation window (kill-switch OpenVoiceOS#837 conventions): - emit the general `ovos.skills.fallback.ping` broadcast once per poll round alongside the addressed pings, and keep a `ovos.skills.fallback.pong` collector with the same session filter as the addressed collectors. - dedup pongs by skill_id: a skill running fixed ovos-workshop (OpenVoiceOS#465) answers BOTH ping families during the window, and must only count once (first answer wins). - delete the end2end `_wire_skill_addressed_probe` fake and let the real (released) ovos-workshop installed by the test run answer the ping honestly; expected_messages updated to reflect the addressed ping being emitted-but-unanswered against a pre-OpenVoiceOS#465 workshop. - fix the CodeRabbit-flagged flaky session-lock unit test's docstring (it exercises the session-id filter, not the lock) and add a real same-session lock serialization test. - revert the unrelated pipeline-blacklist normalization change to intent_services/service.py (and its test) that had leaked into this branch; it is being split into its own PR. Executed matrix (probe-free harness, real ovoscope + real workshop): fixed-core+fixed-ws, fixed-core+ws-dev, core-dev+fixed-ws, and fixed-core+PyPI ovos-workshop==9.3.9a1 are all GREEN (ping answered, dispatched exactly once, skill spoke exactly once). Narrows OpenVoiceOS#807 (same-session stale-pong residue remains; needs a round nonce -- pre-existing on dev). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The kill-switch
This is a prepared trigger, not a change to merge today. It makes
ovos-corespec-pure on the wire, so the stack-wide legacy-compat drop can be tested at
any time and pulled the moment the fleet upgrades.
Do not merge until then, and merge it together with its sibling drop PRs.
The surprise: ovos-core emitted no legacy twins
Worth stating plainly, because it changes what this PR is.
ovos-coreneveremitted a legacy twin of anything.
send_complete_intent_failureemitsovos.intent.unmatchedalone; the legacycomplete_intent_failurewasre-delivered by the bus-client bridge, not by this repo. Same for the rest
of the intent layer.
So the work here is not deletion. It is the handful of places where
ovos-corestill writes a legacy topic literal and relied on the bridge to reach a
spec-side consumer — or would strand a spec-side consumer once the bridge goes.
What changed
intent_services/service.py'mycroft.audio.play_sound'(×2: cancel + no-match error sound)SpecMessage.AUDIO_PLAY_SOUNDintent_services/stop_service.py"mycroft.stop"SpecMessage.STOP(STOP-1 §5.3)intent_services/stop_service.py"skill.stop.pong"SpecMessage.STOP_PONG(STOP-1 §4.2)intent_services/stop_service.py"mycroft.audio.speech.stop"SpecMessage.AUDIO_STOPskill_installer.py"mycroft.audio.play_sound"(×2)SpecMessage.AUDIO_PLAY_SOUNDPlus the docstring at
send_complete_intent_failure, which promised thebridge would re-deliver the legacy topic. It no longer does, and the docstring
now says so.
What is deliberately left
{skill_id}.stop.ping/{skill_id}.stop— runtime-assembled per-skillplaceholders, DELIBERATE EXCLUSION 2 in
MIGRATION_MAP. Replacing them withthe STOP-1 broadcast is engine adoption, not a bridge dependency.
mycroft.skill.handler.complete/.errorsubscriptions indispatcher.py— the PIPELINE-1 §8 trio is orchestrator-owned andintentionally NOT migrated. The framework keeps these as a private
done-signal.
mycroft.skills.abort_question— not inMIGRATION_MAP, never bridged."complete_intent_failure"atservice.py:463— a metrics label inthe opendata upload payload, not a bus topic.
ovos-padatious(_canonicalize_blacklist), not bus compat. Still works,still tested.
Downstream this now requires
Flipping the producer means the consumer must have adopted the spec topic.
This is the "fleet upgraded" precondition, spelled out:
ovos-audiomust consumeovos.audio.play_soundandovos.audio.stop(AUDIO-1 §4.2 / §6);
ovos.stopand answer onovos.stop.pong— that halfships in the sibling ovos-workshop drop PR.
Tests
Unit tests that asserted the legacy topic are flipped to assert the spec one,
and
test_handle_global_stopadditionally assertsmycroft.stopis notemitted.
The end-to-end suite used to run every scenario twice, once per namespace,
because the bus bridged them. The
"legacy"entry is removed from everyNAMESPACE_PATHS, and the other half is pinned in one new file:test/end2end/test_no_legacy_wire_compat.py— injecting onrecognizer_loop:utterancestarts no pipeline; a no-match emitsovos.intent.unmatchedwith nocomplete_intent_failuretwin.test/end2end/test_intent_alias_backcompat.pyis half-inverted:test_legacy_dispatch_topic_fires_handlerbecomestest_legacy_dispatch_topic_reaches_nothing, since both mechanisms that madeit work are gone (workshop's dual-bind, dropped by ovos-workshop#500, and the
bus twin, dropped here). The blacklist half stays green — it is engine-side.
Also flipped: the stop end-to-end expectations (
mycroft.stop->ovos.stop), and both spellings ofrecognizer_loop:audio_output_*are nowfiltered in the ignore lists — ovoscope's TTS mock still emits the legacy one
and nothing bridges it. Follow-up for ovoscope: adopt AUDIO-1 §5.1/§5.2,
and stop passing
emit_legacy/modernizetoFakeBus.Results on this branch, with the sibling drop branches stacked:
test/unittests/test/end2end/test_stop.py+test_stop_refactor.pytest/end2end/test_no_legacy_wire_compat.pytest/end2end/test_no_skills.pytest/end2end/test_intent_alias_backcompat.pysetUp— see belowtest_intent_alias_backcompat.pycannot run in this environment at all: itssetUptouchesovos_padatious.opm._warned_legacy_blacklist_entries, whichthe installed ovos-padatious does not have. That is environment drift on
dev, not something this PR causes — the failure happens before any changedcode runs.
To test the post-compat world, stack the branches:
export PYTHONPATH=/path/to/ovos-spec-tools:\ /path/to/ovos-bus-client@feat/drop-legacy-wire-compat:\ /path/to/ovos-utils@feat/drop-fakebus-legacy-compat:\ /path/to/ovos-workshop@feat/drop-legacy-compat pytest test/unittests/ pytest test/end2end/test_no_legacy_wire_compat.py test/end2end/test_intent_alias_backcompat.pyOrder
Merging any drop PR alone breaks the stack. They go in as one flip.
Implemented by Claude (opus), orchestrated by Claude Fable.
🤖 Generated with Claude Code
The four drop PRs
They flip together, or the stack breaks.
devThe compat train they undo: OpenVoiceOS/ovos-spec-tools#88 (merged),
OpenVoiceOS/ovos-bus-client#271, OpenVoiceOS/ovos-utils#411,
OpenVoiceOS/ovos-workshop#500.
ovos-spec-tools keeps its helpers.
MIGRATION_MAP,SPEC_TO_LEGACY,migration_counterpartandovos_spec_tools.intent_topicsare pure functionsthe spec linter and migration tooling use. Nothing is dropped there.
Red CI diagnosis (ovoscope check). The single failing check is pre-existing on
dev, independent of this branch:dev's ownOvoscope End-to-End Testsworkflow fails the same way on unrelated recent pushes (runs 30673793131, 30672760305, 30094248519 — allfailure), with the same signature —test_activate.py::TestDeactivate::test_deactivate/test_activatetiming out waiting forovos.utterance.handled, plustest_intent_alias_backcompat.pysubfailures. This branch touches neither activation/deactivation dispatch nor the intent-alias backcompat path. Not fixed in-branch; tracked as a pre-existingdevissue.