Skip to content

Feat: rendez#103

Draft
JarbasAl wants to merge 3 commits into
devfrom
feat/rende
Draft

Feat: rendez#103
JarbasAl wants to merge 3 commits into
devfrom
feat/rende

Conversation

@JarbasAl
Copy link
Copy Markdown
Member

@JarbasAl JarbasAl commented Mar 23, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added rendezvous polling to enable asynchronous message delivery from hive members that are not simultaneously connected via configurable rendezvous server URLs.
    • Enhanced encryption with optional recipient binding and sender signature verification for improved message security and integrity.
  • Documentation

    • Added comprehensive guides, configuration reference, and usage examples for rendezvous messaging.
  • Tests

    • Added unit tests validating rendezvous polling and encryption features.

AI-Generated Change:
- Model: claude-sonnet-4-6
- Intent: enable bus client to periodically retrieve INTERCOM messages from
  one or more rendezvous servers without requiring a simultaneous connection
- Impact:
  - New __init__ kwargs: rendezvous_urls (List[str], default None),
    rendezvous_poll_interval (float, default 60.0 seconds)
  - Background daemon thread (_rendezvous_poller) starts automatically when
    rendezvous_urls is provided; stops on on_close()
  - _poll_rendezvous(): signs proof-of-ownership, POSTs to /retrieve,
    feeds each returned HiveMessage into _handle_hive_protocol()
  - Errors (HTTP 4xx/5xx, connection refused) are logged and swallowed —
    polling continues on next interval
  - _stop_rendezvous_polling() guards against missing attrs for legacy
    __new__-constructed instances (no regression in existing tests)
  - 12 new unit tests covering thread lifecycle, injection, and error paths
- Verified via: uv run pytest test/ -q (289 passed, 4 skipped)
AI-Generated Change:
- Model: claude-sonnet-4-6
- Intent: bring all docs in sync with the rendezvous_urls polling feature added
  in the previous commit
- Impact:
  - docs/index.md: added Rendezvous Polling to Key Features list
  - docs/api.md: added HiveMessageBusClient constructor parameters table;
    added Rendezvous Polling subsection with _start/_stop/_poll methods;
    updated RENDEZVOUS HiveMessageType description from "Reserved" to accurate
  - docs/client_api.md: added §1 Rendezvous Polling subsection with usage example
  - docs/message_types.md: added RENDEZVOUS row to HiveMessageType table;
    added RENDEZVOUS section explaining HTTP plugin, polling flow, and privacy
  - docs/examples.md: added two examples — receiving via polling, depositing
    a message from the sender side
- Verified via: manual review
…vous polling

AI-Generated Change:
- Model: claude-sonnet-4-6
- Intent: resolve four cryptographic soundness issues

Fix 1 & 2 — Server-bound ownership proof in rendezvous polling (client.py):
  _fetch_rendezvous_server_pubkey() added — fetches and caches GET /pubkey.
  _poll_rendezvous() passes server_pubkey to sign_ownership() so proof is
  bound to the specific server (prevents cross-server replay within 60s window).

Fix 3 — hybrid_decrypt signature verification (encryption.py):
  New optional param verify_key: when provided AND envelope has "signature",
  verifies PSS-SHA256 over ciphertext before decryption. Raises ValueError on
  failure or if signature is absent when verify_key is supplied.
  handle_intercom() in protocol.py now passes sender's pubkey (from HiveMapper)
  as verify_key when the envelope carries a signature and the sender is known.

Fix 4 — Recipient binding via AES-GCM AAD (encryption.py):
  hybrid_encrypt() gains optional recipient_pubkey: SHA-256 fingerprint of
  recipient's PEM used as GCM AAD; stored as "recipient_fingerprint" in
  envelope. hybrid_decrypt() gains optional expected_recipient: verifies AAD
  before returning plaintext — GCM auth fails if envelope was intended for
  a different recipient.
  emit_intercom() passes recipient_pubkey=pubkey so all sent INTERCOM messages
  carry the binding. handle_intercom() passes expected_recipient=own_pubkey
  when recipient_fingerprint is present.

Backward compatibility: all new params default to None/off; unsigned or
unbound legacy envelopes continue to decrypt without error.

Tests:
  - test_encryption.py: 8 new tests (Fix 3: 4, Fix 4: 4)
  - test_rendezvous_polling.py: _make_client updated with server pubkey cache
  296 passed, 4 skipped.

- Verified via: uv run pytest test/ -q (296 passed, 4 skipped)
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 23, 2026

📝 Walkthrough

Walkthrough

This pull request introduces asynchronous rendezvous polling to HiveMessageBusClient, enabling clients to retrieve messages from hivemind-rendezvous HTTP servers via background daemon threads. The implementation extends hybrid encryption with recipient-binding and signature-verification parameters, updates the protocol handler to support conditional decryption checks, and provides comprehensive documentation and test coverage.

Changes

Cohort / File(s) Summary
Documentation – Feature Overview
docs/index.md, docs/message_types.md, docs/api.md, docs/client_api.md
Updated feature lists and added detailed documentation for the RENDEZVOUS message type, explaining the async dead-drop mechanism, polling configuration (rendezvous_urls, rendezvous_poll_interval), and proof-of-ownership signature behavior.
Documentation – Usage Examples
docs/examples.md
Added two new code examples: receiving INTERCOM messages via rendezvous polling and depositing INTERCOM messages to a rendezvous server using HTTP POST with hybrid encryption.
Core Client Implementation
hivemind_bus_client/client.py
Extended HiveMessageBusClient.__init__ with rendezvous_urls and rendezvous_poll_interval parameters, implemented three new private methods (_start_rendezvous_polling, _stop_rendezvous_polling, _poll_rendezvous) for background polling, added server pubkey caching, and updated on_close to stop polling threads. Modified emit_intercom to pass recipient_pubkey to encryption.
Encryption Module
hivemind_bus_client/encryption.py
Enhanced hybrid_encrypt with optional recipient_pubkey parameter for recipient-binding via SHA-256 fingerprint AAD, replaced encrypt_AES call with direct AES-GCM cipher construction. Enhanced hybrid_decrypt with optional verify_key and expected_recipient parameters for signature verification and recipient-binding validation, using GCM authentication to reject mismatched recipients.
Protocol Handler
hivemind_bus_client/protocol.py
Modified HiveMindSlaveProtocol.handle_intercom to conditionally apply signature verification and recipient-binding checks during decryption by deriving sender pubkey from HiveMapper and passing appropriate parameters to hybrid_decrypt.
Unit Tests – Encryption
test/unittests/test_encryption.py
Added test classes TestHybridDecryptSignatureVerification and TestHybridRecipientBinding validating signature verification behavior, recipient-binding via recipient_fingerprint, and GCM authentication failures for mismatched recipients or invalid signatures.
Unit Tests – Rendezvous Polling
test/unittests/test_rendezvous_polling.py
Added comprehensive unit tests for _start_rendezvous_polling, _stop_rendezvous_polling, and _poll_rendezvous using mocked HTTP retrieval and key loading, verifying thread lifecycle, message deserialization/handling, HTTP error handling, and stop-event integration.

Sequence Diagram

sequenceDiagram
    participant Client as HiveMessageBusClient
    participant BgThread as Polling Thread
    participant Server as Rendezvous Server
    participant Handler as _handle_hive_protocol()

    Note over Client,Handler: Initialization
    Client->>Client: __init__(rendezvous_urls=...)
    Client->>BgThread: _start_rendezvous_polling()
    activate BgThread

    Note over BgThread,Server: Polling Loop
    loop Every rendezvous_poll_interval seconds
        BgThread->>Server: GET /pubkey (fetch RSA public key)
        Server-->>BgThread: pubkey (cached)
        BgThread->>BgThread: Create ownership signature<br/>(pubkey + timestamp)
        BgThread->>Server: POST /retrieve { signature, ... }
        Server-->>BgThread: [serialized HiveMessage, ...]
        Note over BgThread: For each message
        BgThread->>BgThread: Deserialize HiveMessage
        BgThread->>Handler: _handle_hive_protocol(message)
        Handler->>Handler: Route to subscribers
    end

    Note over Client,Handler: Shutdown
    Client->>BgThread: _stop_rendezvous_polling()<br/>(on_close event)
    deactivate BgThread
    BgThread->>BgThread: Exit polling loop
Loading

Estimated Code Review Effort

🎯 4 (Complex) | ⏱️ ~90 minutes

Possibly Related PRs

Suggested Labels

feature

Poem

🐰 Hops through the rendezvous garden

Async dead-drops, now they're in,
Background threads poll and spin,
Signatures prove who's who at the gate,
Recipient-binding seals our fate—
A rabbit's burrow, forever secure!

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Feat: rendez' is vague and does not clearly convey the main purpose of the changes, which implement rendezvous polling functionality for async communication via HTTP dead-drop mechanism. Expand the title to be more descriptive, such as 'Feat: Add rendezvous polling for async message delivery' or 'Feat: Implement rendezvous dead-drop mechanism with background polling'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/rende

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 and usage tips.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented Mar 23, 2026

The bots have finished their work. Take a look! 🤖

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

📋 Repo Health

Checking the pulse of the repository's maintenance. 💓

⚠️ Some required files are missing.

Latest Version: 0.6.0a1

hivemind_bus_client/version.py — Version file
README.md — README
LICENSE — License file
pyproject.toml — pyproject.toml
setup.py — setup.py
CHANGELOG.md — Changelog
requirements.txt — Requirements
hivemind_bus_client/version.py has valid version block markers

🏷️ Release Preview

Ensuring our release notes are clear and concise. ✍️

Current: 0.6.0a1Next: 0.7.0a1

Signal Value
Label (none)
PR title Feat: rendez
Bump minor

✅ PR title follows conventional commit format.


🚀 Release Channel Compatibility

Predicted next version: 0.7.0a1

Channel Status Note Current Constraint
Stable Not in channel -
Testing Compatible hivemind-bus-client>=0.4.4,<1.0.0
Alpha Compatible hivemind-bus-client>=0.6.0a1

🔒 Security (pip-audit)

Locking the doors and checking the windows... 🔒

✅ No known vulnerabilities found (61 packages scanned).

🔍 Lint

The results are fresh out of the pipeline. 🏗️

ruff: issues found — see job log

📊 Coverage

Charting the progress of our testing efforts. 📉

56.8% total coverage

⚠️ Some tests failed — coverage figures may be incomplete.

Files below 80% coverage (6 files)
File Coverage Missing lines
hivemind_bus_client/http_client.py 0.0% 308
hivemind_bus_client/scripts.py 0.0% 215
hivemind_bus_client/version.py 0.0% 5
hivemind_bus_client/protocol.py 45.4% 161
hivemind_bus_client/client.py 54.1% 168
hivemind_bus_client/serialization.py 70.4% 32

Full report: download the coverage-report artifact.

🔨 Build Tests

Checking the alignment of our build components. 📏

Python Build Install Tests
3.10 ⚠️
3.11 ⚠️
3.12 ⚠️
3.13 ⚠️
3.14 ⚠️

❌ 3.10: Install OK, tests failed
❌ 3.11: Install OK, tests failed
❌ 3.12: Install OK, tests failed
❌ 3.13: Install OK, tests failed
❌ 3.14: Install OK, tests failed
Check job logs for details.


An automated high-five for your latest changes! 🖐️

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (2)
test/unittests/test_encryption.py (1)

196-211: Consider extracting tempfile key loading to a helper to reduce duplication.

The pattern of writing PEM to tempfile, calling load_RSA_key, then unlinking is repeated ~10 times. A fixture or helper would improve maintainability.

♻️ Optional: Extract helper fixture
`@pytest.fixture`
def load_key_from_pem():
    """Helper to load RSA key from PEM string via tempfile."""
    import tempfile, os
    from poorman_handshake.asymmetric.utils import load_RSA_key
    
    def _load(pem: str):
        with tempfile.NamedTemporaryFile(delete=False, suffix=".pem", mode="w") as f:
            f.write(pem)
            tmp = f.name
        try:
            return load_RSA_key(tmp)
        finally:
            os.unlink(tmp)
    return _load

Then use: sender_priv = load_key_from_pem(sender_priv_pem)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unittests/test_encryption.py` around lines 196 - 211, The test repeats
writing PEM strings to temp files, calling load_RSA_key, and unlinking; extract
that logic into a helper/fixture (e.g., load_key_from_pem) that takes a PEM
string, creates the NamedTemporaryFile, writes the PEM, calls
load_RSA_key(path), unlinks the temp in a finally, and returns the loaded key;
then replace repeated blocks (where sender_priv = load_RSA_key(tmp) and
recipient_priv = load_RSA_key(tmp2), etc.) with calls to the helper (e.g.,
sender_priv = load_key_from_pem(sender_priv_pem), recipient_priv =
load_key_from_pem(recipient_priv_pem)).
hivemind_bus_client/client.py (1)

282-289: Polling loop has correct stop semantics but initial poll is delayed.

The wait(timeout=...) call means the first poll happens only after rendezvous_poll_interval seconds. If immediate polling on startup is desired, consider polling once before entering the loop.

♻️ Optional: Poll immediately on startup
 def _rendezvous_poll_loop(self) -> None:
     """Background loop: poll every configured rendezvous URL at the configured interval."""
+    # Initial poll immediately on startup
+    for url in self._rendezvous_urls:
+        try:
+            self._poll_rendezvous(url.rstrip("/"))
+        except Exception:
+            LOG.exception("Rendezvous poll error for %s", url)
     while not self._rendezvous_stop_event.wait(timeout=self._rendezvous_poll_interval):
         for url in self._rendezvous_urls:
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hivemind_bus_client/client.py` around lines 282 - 289, The loop in
_rendezvous_poll_loop currently waits before the first poll so the initial
rendezvous is delayed; call _poll_rendezvous(url.rstrip("/")) once for each url
in self._rendezvous_urls (wrapping each call in the same try/except that logs
via LOG.exception) before entering the existing while not
self._rendezvous_stop_event.wait(timeout=self._rendezvous_poll_interval) loop so
you perform an immediate startup poll while preserving stop semantics and
existing error handling.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/examples.md`:
- Around line 273-275: The example calls hybrid_encrypt(recipient_pubkey,
HiveMessage(...).serialize(), sign_key=private_key) but does not pass the
recipient_pubkey as the named parameter required to include
recipient_fingerprint; update the call to supply recipient_pubkey (e.g.,
recipient_pubkey=recipient_pubkey) so hybrid_encrypt produces an envelope bound
to the recipient; keep the rest (HiveMessage, HiveMessageType.BUS,
HiveMessageType.INTERCOM, payload=envelope, sign_key=private_key) unchanged.

In `@docs/index.md`:
- Line 13: The markdown contains a literal "\n- " sequence in the bullet list
(around the "Binary Support" and "Rendezvous Polling" items) so "Rendezvous
Polling" is not on its own line; edit the docs index content where the list is
defined and replace the escaped newline sequence with an actual newline so each
bullet (e.g., the "Binary Support" and "Rendezvous Polling" items) is on its own
line, ensuring standard Markdown list formatting.

In `@hivemind_bus_client/client.py`:
- Line 324: The import of sign_ownership from hivemind_rendezvous.auth is
unguarded and the package isn't listed as a dependency; either add
hivemind_rendezvous to the project dependencies (pyproject.toml/requirements) or
make the import optional by wrapping "from hivemind_rendezvous.auth import
sign_ownership" in a try/except ImportError that sets sign_ownership = None (or
a no-op) and update any callers in this module to check for None and raise a
clear, actionable error or skip signing when unavailable; locate the import and
its usages (symbol: sign_ownership) and implement the conditional handling to
gracefully degrade or fail with an instructive message.

In `@test/unittests/test_rendezvous_polling.py`:
- Around line 102-104: The tests fail because patching
"hivemind_rendezvous.auth.sign_ownership" tries to import a module that may not
be installed; update each use of patch for _PATCH_SIGN (and any `@patch`
decorators targeting hivemind_rendezvous.auth.sign_ownership) to pass
create=True (i.e., patch(_PATCH_SIGN, ..., create=True)), or alternatively add a
pytest fixture that injects a dummy hivemind_rendezvous module with an
auth.sign_ownership attribute so that calls to patch() succeed without raising
ModuleNotFoundError.

---

Nitpick comments:
In `@hivemind_bus_client/client.py`:
- Around line 282-289: The loop in _rendezvous_poll_loop currently waits before
the first poll so the initial rendezvous is delayed; call
_poll_rendezvous(url.rstrip("/")) once for each url in self._rendezvous_urls
(wrapping each call in the same try/except that logs via LOG.exception) before
entering the existing while not
self._rendezvous_stop_event.wait(timeout=self._rendezvous_poll_interval) loop so
you perform an immediate startup poll while preserving stop semantics and
existing error handling.

In `@test/unittests/test_encryption.py`:
- Around line 196-211: The test repeats writing PEM strings to temp files,
calling load_RSA_key, and unlinking; extract that logic into a helper/fixture
(e.g., load_key_from_pem) that takes a PEM string, creates the
NamedTemporaryFile, writes the PEM, calls load_RSA_key(path), unlinks the temp
in a finally, and returns the loaded key; then replace repeated blocks (where
sender_priv = load_RSA_key(tmp) and recipient_priv = load_RSA_key(tmp2), etc.)
with calls to the helper (e.g., sender_priv =
load_key_from_pem(sender_priv_pem), recipient_priv =
load_key_from_pem(recipient_priv_pem)).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: a0618109-f2d9-4047-8c4c-78f8ce157dc6

📥 Commits

Reviewing files that changed from the base of the PR and between 68f1e48 and 0b3af8d.

📒 Files selected for processing (10)
  • docs/api.md
  • docs/client_api.md
  • docs/examples.md
  • docs/index.md
  • docs/message_types.md
  • hivemind_bus_client/client.py
  • hivemind_bus_client/encryption.py
  • hivemind_bus_client/protocol.py
  • test/unittests/test_encryption.py
  • test/unittests/test_rendezvous_polling.py

Comment thread docs/examples.md
Comment on lines +273 to +275
envelope = hybrid_encrypt(recipient_pubkey, HiveMessage(HiveMessageType.BUS, inner).serialize(),
sign_key=private_key)
msg = HiveMessage(HiveMessageType.INTERCOM, payload=envelope)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add recipient_pubkey to enable recipient binding in the example.

The example encrypts for recipient_pubkey but doesn't pass it as the recipient_pubkey parameter, so the envelope won't include recipient_fingerprint for binding. This should match the new API.

📝 Proposed fix
 envelope = hybrid_encrypt(recipient_pubkey, HiveMessage(HiveMessageType.BUS, inner).serialize(),
-                          sign_key=private_key)
+                          sign_key=private_key,
+                          recipient_pubkey=recipient_pubkey)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
envelope = hybrid_encrypt(recipient_pubkey, HiveMessage(HiveMessageType.BUS, inner).serialize(),
sign_key=private_key)
msg = HiveMessage(HiveMessageType.INTERCOM, payload=envelope)
envelope = hybrid_encrypt(recipient_pubkey, HiveMessage(HiveMessageType.BUS, inner).serialize(),
sign_key=private_key,
recipient_pubkey=recipient_pubkey)
msg = HiveMessage(HiveMessageType.INTERCOM, payload=envelope)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/examples.md` around lines 273 - 275, The example calls
hybrid_encrypt(recipient_pubkey, HiveMessage(...).serialize(),
sign_key=private_key) but does not pass the recipient_pubkey as the named
parameter required to include recipient_fingerprint; update the call to supply
recipient_pubkey (e.g., recipient_pubkey=recipient_pubkey) so hybrid_encrypt
produces an envelope bound to the recipient; keep the rest (HiveMessage,
HiveMessageType.BUS, HiveMessageType.INTERCOM, payload=envelope,
sign_key=private_key) unchanged.

Comment thread docs/index.md
- **CASCADE Aggregation**: Collects responses from all nodes with timeout and early resolution via `HiveMapper`.
- **PING Discovery**: Flood-based topology mapping with public key and locale announcement.
- **Binary Support**: Optimized handling for binary payloads such as TTS audio and file transfers.
- **Binary Support**: Optimized handling for binary payloads such as TTS audio and file transfers.\n- **Rendezvous Polling**: Optional background thread that periodically retrieves INTERCOM messages from one or more `hivemind-rendezvous` servers, enabling async communication with nodes from non-simultaneously-connected hives.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Fix inline \n — should be an actual line break.

The literal \n- string appears in the markdown source. This should be a proper newline to render the "Rendezvous Polling" feature as a separate bullet point.

📝 Proposed fix
-- **Binary Support**: Optimized handling for binary payloads such as TTS audio and file transfers.\n- **Rendezvous Polling**: Optional background thread that periodically retrieves INTERCOM messages from one or more `hivemind-rendezvous` servers, enabling async communication with nodes from non-simultaneously-connected hives.
+- **Binary Support**: Optimized handling for binary payloads such as TTS audio and file transfers.
+- **Rendezvous Polling**: Optional background thread that periodically retrieves INTERCOM messages from one or more `hivemind-rendezvous` servers, enabling async communication with nodes from non-simultaneously-connected hives.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- **Binary Support**: Optimized handling for binary payloads such as TTS audio and file transfers.\n- **Rendezvous Polling**: Optional background thread that periodically retrieves INTERCOM messages from one or more `hivemind-rendezvous` servers, enabling async communication with nodes from non-simultaneously-connected hives.
- **Binary Support**: Optimized handling for binary payloads such as TTS audio and file transfers.
- **Rendezvous Polling**: Optional background thread that periodically retrieves INTERCOM messages from one or more `hivemind-rendezvous` servers, enabling async communication with nodes from non-simultaneously-connected hives.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/index.md` at line 13, The markdown contains a literal "\n- " sequence in
the bullet list (around the "Binary Support" and "Rendezvous Polling" items) so
"Rendezvous Polling" is not on its own line; edit the docs index content where
the list is defined and replace the escaped newline sequence with an actual
newline so each bullet (e.g., the "Binary Support" and "Rendezvous Polling"
items) is on its own line, ensuring standard Markdown list formatting.

Args:
base_url: Rendezvous server base URL (trailing slash already stripped).
"""
from hivemind_rendezvous.auth import sign_ownership
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check if hivemind_rendezvous is declared as a dependency
echo "=== Checking setup.py ==="
cat setup.py 2>/dev/null | grep -i rendezvous || echo "Not found in setup.py"

echo "=== Checking pyproject.toml ==="
cat pyproject.toml 2>/dev/null | grep -i rendezvous || echo "Not found in pyproject.toml"

echo "=== Checking requirements*.txt ==="
cat requirements*.txt 2>/dev/null | grep -i rendezvous || echo "Not found in requirements"

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 252


🏁 Script executed:

# Check what dependencies are actually declared
echo "=== Checking setup.py dependencies ==="
head -100 setup.py 2>/dev/null || echo "setup.py not found or too small"

echo -e "\n=== Checking pyproject.toml ==="
cat pyproject.toml 2>/dev/null || echo "pyproject.toml not found"

echo -e "\n=== Checking for any requirements files ==="
ls -la requirements*.txt 2>/dev/null || echo "No requirements files found"

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 4183


🏁 Script executed:

# View the code context around line 324 in hivemind_bus_client/client.py
echo "=== Code context around line 324 ==="
sed -n '310,340p' hivemind_bus_client/client.py 2>/dev/null || echo "File or lines not found"

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 1447


🏁 Script executed:

# Check requirements.txt content
cat requirements.txt

# Get more context around line 324 to check for error handling
echo -e "\n=== Broader context (lines 300-360) ==="
sed -n '300,360p' hivemind_bus_client/client.py

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 2977


Add hivemind_rendezvous to dependencies or implement graceful error handling.

The import from hivemind_rendezvous.auth import sign_ownership at line 324 is missing error handling. The package is not listed in pyproject.toml or requirements.txt. Either add hivemind_rendezvous to project dependencies, or wrap the import in a try-except block to gracefully degrade if the package is unavailable (since the method uses a lazy import pattern suggesting optional functionality).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hivemind_bus_client/client.py` at line 324, The import of sign_ownership from
hivemind_rendezvous.auth is unguarded and the package isn't listed as a
dependency; either add hivemind_rendezvous to the project dependencies
(pyproject.toml/requirements) or make the import optional by wrapping "from
hivemind_rendezvous.auth import sign_ownership" in a try/except ImportError that
sets sign_ownership = None (or a no-op) and update any callers in this module to
check for None and raise a clear, actionable error or skip signing when
unavailable; locate the import and its usages (symbol: sign_ownership) and
implement the conditional handling to gracefully degrade or fail with an
instructive message.

Comment on lines +102 to +104
_PATCH_URLOPEN = "hivemind_bus_client.client.urllib.request.urlopen"
_PATCH_LOAD = "hivemind_bus_client.client.load_RSA_key"
_PATCH_SIGN = "hivemind_rendezvous.auth.sign_ownership"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Check how sign_ownership is imported in client.py to determine correct patch target

# Find the import statement for sign_ownership
rg -n "sign_ownership" --type py -C 3

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 2175


🏁 Script executed:

#!/bin/bash
# Check the test file structure and how the patches are used
cat -n test/unittests/test_rendezvous_polling.py | head -180

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 8007


🏁 Script executed:

#!/bin/bash
# Check if hivemind_rendezvous is listed as a dependency
find . -name "setup.py" -o -name "setup.cfg" -o -name "pyproject.toml" -o -name "requirements*.txt" | head -10

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 130


🏁 Script executed:

#!/bin/bash
# Check dependencies in setup files
cat setup.py 2>/dev/null || cat setup.cfg 2>/dev/null || cat pyproject.toml 2>/dev/null

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 2677


🏁 Script executed:

#!/bin/bash
# Check requirements.txt to see if hivemind_rendezvous is listed
cat requirements.txt

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 264


🏁 Script executed:

#!/bin/bash
# Check if there are test-specific requirements
cat requirements-test.txt 2>/dev/null || echo "No test requirements file found"

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 115


🏁 Script executed:

#!/bin/bash
# Check pyproject.toml for optional dependencies
cat pyproject.toml

Repository: JarbasHiveMind/hivemind-websocket-client

Length of output: 1407


Use create=True in the patch() calls or add a mock fixture for hivemind_rendezvous to avoid ModuleNotFoundError when the module is not installed.

Since hivemind_rendezvous is not listed as a dependency, the tests fail when patch("hivemind_rendezvous.auth.sign_ownership") tries to import the non-existent module. The simplest fix is to pass create=True to each patch() call targeting this path, or set up a module mock in a pytest fixture.

Patch approach (minimal change)

Replace all with patch(_PATCH_SIGN, ...) calls with with patch(_PATCH_SIGN, ..., create=True):, or add create=True to the @patch(_PATCH_SIGN) decorator if used as a decorator elsewhere.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@test/unittests/test_rendezvous_polling.py` around lines 102 - 104, The tests
fail because patching "hivemind_rendezvous.auth.sign_ownership" tries to import
a module that may not be installed; update each use of patch for _PATCH_SIGN
(and any `@patch` decorators targeting hivemind_rendezvous.auth.sign_ownership) to
pass create=True (i.e., patch(_PATCH_SIGN, ..., create=True)), or alternatively
add a pytest fixture that injects a dummy hivemind_rendezvous module with an
auth.sign_ownership attribute so that calls to patch() succeed without raising
ModuleNotFoundError.

@JarbasAl JarbasAl marked this pull request as draft May 7, 2026 00:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant