fix: answer the STOP-1 broadcast ovos.stop.ping - #612
Conversation
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks 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 |
Greetings, human! The automated checks are complete. 👾I've aggregated the results of the automated checks for this PR below. 📋 Repo HealthEnsuring the repo's immune system is strong (aka security checks). 🛡️ ✅ All required files present. Latest Version: ✅ 📡 Channel Compat — testingThe results are in the bag! 🎒 🚧 Channel unresolvable with this checkout — the repo's dependency floors exceed what the channel pins (fleet finding; see the install log). Constraints: https://raw.githubusercontent.com/OpenVoiceOS/OpenVoiceOS/main/constraints-testing.txt 🔒 Security (pip-audit)Ensuring no malicious actors are hitching a ride. 🎭 ✅ No known vulnerabilities found (72 packages scanned). ⚖️ License CheckVerifying the SPDX identifiers for correctness. 🆔 ✅ No license violations found. Policy: Apache 2.0 (universal donor). StrongCopyleft / NetworkCopyleft / WeakCopyleft / Other / Error categories fail. MPL allowed. 🔍 LintThe latest findings are now at your fingertips. ⌨️ ❌ ruff: issues found — see job log 📡 Channel Compat — stableThe automated checks have finished their work. 🏁 🚧 Channel unresolvable with this checkout — the repo's dependency floors exceed what the channel pins (fleet finding; see the install log). Constraints: https://raw.githubusercontent.com/OpenVoiceOS/OpenVoiceOS/main/constraints-stable.txt 🔨 Build TestsRunning the forge to see if the code tempers correctly. 🔥 ✅ All versions pass
Making code review just a little bit easier. 💆♂️ |
fa47be1 to
54d43f8
Compare
OVOS-STOP-1 §4.2 makes `ovos.stop.ping` the stop cascade's poll topic and treats a handler that does not subscribe to it as `can_handle: false` for that round. OVOSSkill subscribed only to the pre-spec per-skill `<skill_id>.stop.ping`, so every skill's stoppability rested on the compatibility twin ovos-core still emits alongside the broadcast; once that twin goes, generic stop falls back to the recency rule for the whole fleet. OVOSSkill now subscribes to both pings and answers on `ovos.stop.pong` with the §4.2 payload. A core emitting both in one round draws exactly one pong: STOP-1 §4.2 binds the poll to PIPELINE-1 §4.5, which keys round state by the `session_id` of `context.session` and by `context.utterance_id` (§9.1.1) — both propagate to either ping by reply derivation — and rules that the first valid pong per candidate wins. A pre-spec core that stamps no `utterance_id` names no round, so its pings are answered one for one as before. Fail-before: the broadcast test fails on dev (0 pongs, nothing subscribes); with the subscription but no dedupe the single-pong test fails 2 != 1; a session-only round key fails two rounds in one session, 1 != 2. Suite: 708 passed, 1 pre-existing failure in test_scheduler_delegation (KeyError 'owner', PR #608). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
54d43f8 to
65e9789
Compare
OVOS-STOP-1 §4.2:
OVOSSkillsubscribed only to the pre-spec per-skill<skill_id>.stop.ping, so every skill's stoppability rested on the compatibility twin ovos-core forwards alongside the broadcast (stop_service.pyemits thereply-derivedovos.stop.pingat :249 and theforward-derived twin at :262). The day that twin goes, every skill on the fleet iscan_handle: falseand generic stop falls back to the §4.1 step 5 recency rule. The skill now subscribes to both pings and answers onovos.stop.pongwith the §4.2 payload,{skill_id, can_handle}. The twin subscription stays for cores that predate the broadcast.A core emitting both pings in one round draws exactly one pong. §4.2 binds the poll to PIPELINE-1 §4.5, which supplies the round identity: "the plugin keys poll state by
session_idfromcontext.sessionand bycontext.utterance_id(§9.1.1), which the ping carries by reply derivation and the pong carries back the same way", and "where one candidate answers twice in a round, the first valid pong wins". Both pings derive from the same entry Message, so both carry that pair, and the skill drops the second. Core enforces the same key from the other side, discarding a pong whoseutterance_iddoes not match the round (stop_service.py:210). A pre-spec core that stamps noutterance_idnames no round, so its pings are answered one for one and its behaviour is unchanged.dev, 0 pongs — nothing subscribesAssertionError: 2 != 1utterance_idAssertionError: 1 != 2utterance_idanswered every timeAssertionError: 1 != 2can_handle: truetest/unittestson the merged tree: 708 passed, 1 failed —test_scheduler_delegationKeyError: 'owner', pre-existing ondevand fixed by #608.The only consumer that counts pongs is core's
handle_ack, which already deduplicates by payloadskill_id;ovos-pydantic-modelsonly declares the message shape.