Skip to content

fix: a CASCADE this node answers itself is routed back to the relay - #397

Merged
JarbasAl merged 1 commit into
devfrom
fix/cascade-local-answer-routes-back-to-the-relay
Oct 21, 2026
Merged

JarbasAl merged 1 commit into
devfrom
fix/cascade-local-answer-routes-back-to-the-relay

Conversation

@openvoiceos-bot

@openvoiceos-bot openvoiceos-bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

🤖 Auto-generated by Claude Sonnet 5.5 (claude-sonnet-5-5) via Claude Code, reviewed by Claude Opus 5.5 — NOT human-reviewed. Verify before acting.

Governing clause, HIVEMIND-MSG-1 §5.2: "Otherwise walk route from the most recent hop backwards and deliver the answer to the first return-path hop (§5.1) that names a directly connected peer other than the one the answer arrived from." and "A node delivers the answer to the return path it recorded".

A CASCADE that a relay forwards to a single upstream node was never answered, even with a client-supplied query_id. The upstream node logged "dropping CASCADE response with no authorized return path". Its own answer was passed to _route_query_response with the asking connection as the arrival connection. The route walk skips the hop equal to that sender, and for a relayed CASCADE that hop is the only authorized return path.

A locally produced answer arrived on no connection. handle_cascade_message now passes None as the arrival connection for it. Routing of answers that arrive from a peer or from upstream does not change. A directly connected asker is still served by the default route.

The test file tests/e2e/test_cascade_relay_answer_e2e.py runs asker, R0 and M0 in hivescope, with only M0 answering. The first test sends a client-supplied query_id. It fails on dev with "the CASCADE answer never reached the asker" and passes with the change.

The shipped hivemind-bus-client sends a CASCADE with no query_id. The second test covers that shape. It depends on the query_id fix that is already in dev. With the source change in this PR reverted, both tests fail.

The suite on this branch gives 684 passed and 2 skipped.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Fixed relayed CASCADE responses so answers reliably return to the original asker.
    • Improved handling for requests with and without an explicit query ID.
  • Tests

    • Added end-to-end coverage for multi-node CASCADE message routing.
    • Verified that relayed speech responses reach the originating asker.

@github-actions github-actions Bot added the fix label Oct 21, 2026
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 301fb0fe-7330-430d-a934-ef125768adb5
📥 Commits

Reviewing files that changed from the base of the PR and between 0e8bf33 and 1c71d9b.

📒 Files selected for processing: 2
  • hivemind_core/protocol.py
  • tests/e2e/test_cascade_relay_answer_e2e.py

Included review availability: This review used your included allowance. Your plan provides up to 1 included review per hour; 0 remain after this review.

📝 Walkthrough

Local CASCADE answers now use the recorded return path to reach the peer that forwarded the request. New end-to-end tests verify delivery to the asker through a relay, with and without an explicit query ID.

Changes: CASCADE Relay Answers

Layer / File(s) Summary
Route and verify relayed answers
hivemind_core/protocol.py, tests/e2e/test_cascade_relay_answer_e2e.py
Local answers are routed without the requesting client connection. End-to-end tests verify that answers reach the asker through a relay for messages with and without a query ID.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: jarbasal

Merge Risk: ⚪ Minimal · up to 1c71d

Local CASCADE answers can return through the relay without disrupting direct replies. No merge-blocking issue remains from the reviewed change.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 28.57% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 7 functions across 2 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 4 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly identifies the main change: locally generated CASCADE answers are routed back through the relay. It is specific and related to the pull request.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches: 💡 1
📝 Generate docstrings: 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added fix and removed fix labels Oct 21, 2026
@github-actions

github-actions Bot commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

I've scrutinized every line of your PR. Here's the report. 🧐

I've aggregated the results of the automated checks for this PR below.

🏷️ Release Preview

Ensuring the release notes correctly reflect your contribution. 🖋️

Current: 5.3.9a1 → Next: 5.3.10a1

Signal Value
Label fix
PR title fix: a CASCADE this node answers itself is routed back to the relay
Bump build

✅ PR title follows conventional commit format.


🚀 Release Channel Compatibility

Predicted next version: 5.3.10a1

Channel Status Note Current Constraint
Stable ⚪ Not in channel -
Testing ❌ Too new (must be <5.0.0) hivemind-core>=4.0.0,<5.0.0
Alpha ✅ Compatible hivemind-core>=5.3.7a1

📋 Repo Health

Ensuring the repo's joints are well-oiled (aka CI/CD). ⚙️

✅ All required files present.

Latest Version: 5.3.9a1

✅ hivemind_core/version.py — Version file
✅ README.md — README
✅ LICENSE — License file
✅ pyproject.toml — pyproject.toml
⚠️ setup.py — setup.py
✅ CHANGELOG.md — Changelog
✅ hivemind_core/version.py has valid version block markers

🔨 Build Tests

Mixing the ingredients and seeing if the cake rises! 🎂

✅ All versions pass

Python Build Install Tests pytest
3.10 ✅ ✅ ✅ 683 passed, 3 skipped, 1164 warnings, 61 subtests passed in 459.73s (0:07:39)
3.11 ✅ ✅ ✅ 683 passed, 3 skipped, 1167 warnings, 61 subtests passed in 343.20s (0:05:43)
3.12 ✅ ✅ ✅ 683 passed, 3 skipped, 1167 warnings, 61 subtests passed in 436.50s (0:07:16)
3.13 ✅ ✅ ✅ 683 passed, 3 skipped, 1164 warnings, 61 subtests passed in 425.27s (0:07:05)

🔒 Security (pip-audit)

Shields up! Scanning for potential threats. 🛡️

✅ No known vulnerabilities found (87 packages scanned).

🔍 Lint

A detailed summary of the latest automation run. 📝

❌ ruff: issues found in 110 file(s) — see job log
✅ actionlint: 11 workflow file(s), no finding

📊 Coverage

Ensuring every logical path is accounted for. 🛣️

❌ 36.3% total coverage

Per-file coverage (9 files)
File Coverage Missing lines
hivemind_core/__init__.py 0.0% 2
hivemind_core/__main__.py 0.0% 24
hivemind_core/database.py 0.0% 62
hivemind_core/scripts.py 0.0% 468
hivemind_core/service.py 0.0% 244
hivemind_core/version.py 0.0% 5
hivemind_core/config.py 47.4% 41
hivemind_core/policy.py 50.0% 68
hivemind_core/protocol.py 51.6% 837

Full report: download the coverage-report artifact.

⚖️ License Check

Ensuring our CLA requirements are met. 🖋️

✅ No license violations found.

Policy: Apache 2.0 (universal donor). StrongCopyleft / NetworkCopyleft / WeakCopyleft / Other / Error categories fail. MPL allowed.


Your loyal script, at your command 🫡

@JarbasAl
JarbasAl force-pushed the fix/cascade-local-answer-routes-back-to-the-relay branch from dcec0c2 to c00df67 Compare October 21, 2026 04:45
@github-actions github-actions Bot added fix and removed fix labels Oct 21, 2026
A CASCADE forwarded by a relay was never answered by the upstream node.
The node's own answer was routed as if it had arrived on the asking
connection, and the route walk in _route_query_response skips the hop
equal to that sender. For a relayed CASCADE the only authorized hop is
the relay, which is that connection, so the answer was dropped with "no
authorized return path". This also happened when the client supplied its
own query_id.

A locally produced answer arrived on no connection, so it is now routed
with no sender (HIVEMIND-MSG-1 section 5.2: an answer goes to the recorded
return path, never back to the peer it arrived from).

Fail-before: the new asker -> R0 -> M0 test fails on dev with "the CASCADE
answer never reached the asker" and passes with the fix.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
@JarbasAl
JarbasAl force-pushed the fix/cascade-local-answer-routes-back-to-the-relay branch from c00df67 to 1c71d9b Compare October 21, 2026 10:28
@github-actions github-actions Bot added fix and removed fix labels Oct 21, 2026
@JarbasAl
JarbasAl marked this pull request as ready for review October 21, 2026 10:48
@github-actions github-actions Bot added fix and removed fix labels Oct 21, 2026
@JarbasAl
JarbasAl merged commit 4112567 into dev Oct 21, 2026
23 of 24 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants