Skip to content

Improve modem path handling and message processing - #18

Merged
frankwei98 merged 3 commits into
mainfrom
codex/auto-modem-path
Aug 6, 2026
Merged

frankwei98 merged 3 commits into
mainfrom
codex/auto-modem-path

Conversation

@frankwei98

@frankwei98 frankwei98 commented Aug 6, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Improve modem path handling across runtime, messaging, and inbound message flows
  • Update message APIs and persistence metadata integration
  • Refine modem and storage coordination

Testing

Not run (not requested)

Summary by CodeRabbit

  • Bug Fixes
    • Improved modem detection and recovery when device identities change or become temporarily unavailable.
    • Prevented duplicate inbound messages during modem path changes and supported migration of existing modem records.
    • Added safer handling for ambiguous, quarantined, or mismatched modems.
  • Reliability
    • Runtime modem identity is refreshed while inbound monitoring is active.
    • Message sending now uses the currently available modem connection and rejects unavailable runtime paths safely.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@frankwei98, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 49 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0f6c9082-97c3-4b2c-a223-926bedb93ed0

📥 Commits

Reviewing files that changed from the base of the PR and between 18435a7 and cd57862.

📒 Files selected for processing (2)
  • src/inbound.rs
  • src/storage/metadata.rs
📝 Walkthrough

Walkthrough

Changes

Modem target resolution

Layer / File(s) Summary
Modem targets and persistence contracts
src/modem.rs, src/persistence/mod.rs, src/storage/metadata.rs
ModemService now stores separate runtime and action paths. Persistence supports runtime fingerprints, identity mismatches, dedupe namespaces, and legacy migration.
Inbound modem discovery and refresh
src/inbound.rs
Inbound resolution scans modem identities, handles mismatches and ambiguity, publishes ModemTargets, preserves dedupe namespaces, and refreshes runtime identity during active subscriptions.
Messaging and runtime integration
src/messaging.rs, src/runtime.rs, src/api/mod.rs, src/api/messages.rs
Messaging and interactive sending use the runtime modem path through with_modem_service. API tests now configure and expect the runtime path.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant InboundWorker
  participant Store
  participant ModemManager
  participant ModemService
  InboundWorker->>Store: Load modem identity and dedupe metadata
  InboundWorker->>ModemManager: Scan available modem identities
  ModemManager-->>InboundWorker: Return modem paths and fingerprints
  InboundWorker->>Store: Persist runtime identity and mismatch state
  InboundWorker->>ModemService: Publish runtime and action targets
  InboundWorker->>ModemService: Refresh runtime target during subscription
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 describes the main changes to modem path handling and message processing.
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 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/auto-modem-path

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.

@coderabbitai coderabbitai Bot left a comment

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.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/storage/metadata.rs (1)

163-166: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the assertion message to match the renamed test.

The test now covers dedupe namespace resolution, but the failure message still says "fingerprint query error". Align the message with the resolver under test.

💚 Proposed message fix
         assert!(
             error.to_string().contains("no such table: meta"),
-            "expected the fingerprint query error, got: {error:#}"
+            "expected the dedupe namespace query error, got: {error:#}"
         );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/storage/metadata.rs` around lines 163 - 166, Update the assertion failure
message in the renamed dedupe namespace resolution test to refer to the
namespace resolver rather than a fingerprint query, while preserving the
existing error detail and assertion condition.
🧹 Nitpick comments (4)
src/storage/metadata.rs (1)

60-85: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Share the metadata key names instead of repeating string literals.

This migration hardcodes 'modem_fingerprint' and 'modem_dedupe_namespace'. src/persistence/mod.rs defines the same names as constants (MODEM_FINGERPRINT_META_KEY, MODEM_DEDUPE_NAMESPACE_META_KEY). A rename in one place will not update the other, and the migration would then silently stop matching. The same literals also appear in inbound_dedupe_namespace_on at lines 121-140.

Define the key names once in the storage layer and bind them as parameters, or re-export the existing constants for use here.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/storage/metadata.rs` around lines 60 - 85, Replace the hardcoded metadata
key literals in migrate_legacy_modem_fingerprint and inbound_dedupe_namespace_on
with the shared MODEM_FINGERPRINT_META_KEY and MODEM_DEDUPE_NAMESPACE_META_KEY
constants from the persistence layer, re-exporting them through storage if
needed. Bind the keys as SQL parameters so both migrations and lookups remain
synchronized with the canonical names.
src/inbound.rs (3)

149-164: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the duplicated resolve-and-publish block.

The same six-line sequence (call resolve_monitor_path, publish on success, log and clear targets on error) appears at lines 149-164 and again at lines 180-194. Extract one private helper so both call sites share a single failure policy.

async fn resolve_and_publish(&self) -> Option<String> {
    match resolve_monitor_path(
        &self.settings.configured_modem_path,
        &self.modem_service,
        &self.store,
    )
    .await
    {
        Ok(resolved) => publish_resolved_path(&self.modem_service, resolved),
        Err(error) => {
            error!("modem resolution failed: {}", error);
            self.modem_service.set_modem_targets(ModemTargets::default());
            None
        }
    }
}

Also applies to: 180-194

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/inbound.rs` around lines 149 - 164, Extract the duplicated
resolve-and-publish logic into a private async helper such as
resolve_and_publish on the containing type. Move the resolve_monitor_path call,
success publication, error logging, target reset, and None return into that
helper, then replace both current call sites with the helper while preserving
their existing control flow.

454-462: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Update the doc comment to describe the target split.

The comment still describes a single resolved path. The function now returns ModemTargets with two independent meanings, and the safety-relevant rule is not stated: a modem selected only by an observed runtime fingerprint, or a sole available modem at a different path, becomes a runtime target but never an action target.

State the return contract explicitly, including when verified, separate, runtime_only, action_only, and the empty default are produced. Readers of run_action depend on this rule.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/inbound.rs` around lines 454 - 462, Update the doc comment for
resolve_monitor_path to document the ModemTargets split: verified identifies the
configured target, separate indicates a distinct runtime modem, runtime_only is
used when selection relies only on an observed fingerprint or a sole modem at a
changed path and must never be an action target, action_only represents the
configured action target without a separate runtime modem, and the empty default
is returned when no modem can be resolved.

258-328: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the repeated fingerprint-comparison block.

Lines 264-282 and lines 291-315 implement the same three-way decision on store.modem_fingerprint(): enrol when absent, do nothing when equal, revoke and persist a mismatch when different. Only the extra namespace pinning at lines 308-313 differs.

Extract one helper that takes the path to enrol or quarantine and returns whether a mismatch was recorded. The caller then performs the namespace pinning. A single implementation prevents a future correctness fix from landing in only one of the two branches.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/inbound.rs` around lines 258 - 328, Extract the duplicated modem
fingerprint three-way decision from observe_runtime_identity into a helper that
accepts the path to enroll or quarantine and reports whether a mismatch was
recorded. Reuse this helper for both action-path and runtime-path comparisons,
preserving enrollment, no-op, revocation, and persist_identity_mismatch
behavior; keep the runtime-only namespace pinning and runtime fingerprint
updates in observe_runtime_identity, gated by the helper’s mismatch result.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/inbound.rs`:
- Around line 1474-1481: Replace the fixed 50 ms sleep in the test with a
bounded poll using the existing timeout/polling pattern from nearby tests,
waiting until runtime_modem_fingerprint() returns the expected target
fingerprint. Keep the final fingerprint and verified_path assertions, and fail
when the timeout expires.

---

Outside diff comments:
In `@src/storage/metadata.rs`:
- Around line 163-166: Update the assertion failure message in the renamed
dedupe namespace resolution test to refer to the namespace resolver rather than
a fingerprint query, while preserving the existing error detail and assertion
condition.

---

Nitpick comments:
In `@src/inbound.rs`:
- Around line 149-164: Extract the duplicated resolve-and-publish logic into a
private async helper such as resolve_and_publish on the containing type. Move
the resolve_monitor_path call, success publication, error logging, target reset,
and None return into that helper, then replace both current call sites with the
helper while preserving their existing control flow.
- Around line 454-462: Update the doc comment for resolve_monitor_path to
document the ModemTargets split: verified identifies the configured target,
separate indicates a distinct runtime modem, runtime_only is used when selection
relies only on an observed fingerprint or a sole modem at a changed path and
must never be an action target, action_only represents the configured action
target without a separate runtime modem, and the empty default is returned when
no modem can be resolved.
- Around line 258-328: Extract the duplicated modem fingerprint three-way
decision from observe_runtime_identity into a helper that accepts the path to
enroll or quarantine and reports whether a mismatch was recorded. Reuse this
helper for both action-path and runtime-path comparisons, preserving enrollment,
no-op, revocation, and persist_identity_mismatch behavior; keep the runtime-only
namespace pinning and runtime fingerprint updates in observe_runtime_identity,
gated by the helper’s mismatch result.

In `@src/storage/metadata.rs`:
- Around line 60-85: Replace the hardcoded metadata key literals in
migrate_legacy_modem_fingerprint and inbound_dedupe_namespace_on with the shared
MODEM_FINGERPRINT_META_KEY and MODEM_DEDUPE_NAMESPACE_META_KEY constants from
the persistence layer, re-exporting them through storage if needed. Bind the
keys as SQL parameters so both migrations and lookups remain synchronized with
the canonical names.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 0c6756f8-f0cf-4be4-94c3-117d956a63a4

📥 Commits

Reviewing files that changed from the base of the PR and between 8661358 and 18435a7.

📒 Files selected for processing (8)
  • src/api/messages.rs
  • src/api/mod.rs
  • src/inbound.rs
  • src/messaging.rs
  • src/modem.rs
  • src/persistence/mod.rs
  • src/runtime.rs
  • src/storage/metadata.rs

Comment thread src/inbound.rs
@frankwei98
frankwei98 merged commit d7fa32a into main Aug 6, 2026
6 checks passed
@frankwei98
frankwei98 deleted the codex/auto-modem-path branch August 6, 2026 09:19
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