Skip to content

Fall back to legacy registration on the real missing-method answer - #1935

Merged
realtonyyoung merged 2 commits into
mainfrom
tonyyoung/ai-4268-legacy-registration-fallback
Oct 25, 2026
Merged

realtonyyoung merged 2 commits into
mainfrom
tonyyoung/ai-4268-legacy-registration-fallback

Conversation

@realtonyyoung

@realtonyyoung realtonyyoung commented Oct 24, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #1858 — AI-4268

What & why

Against a server without AgentRegisteredAcked, launches died after spawning. The legacy fallback only recognised Unknown hub method, but a JSON-protocol server cannot bind the arguments of a method it lacks. Its dispatcher answers Failed to invoke 'AgentRegisteredAcked' due to an error on the server. HubException: Method does not exist. instead. IsUnknownHubMethod now takes the invoked method's name and accepts either dispatcher answer only for that method, only as a HubException. A handler's refusal, another method's absence, an authorization failure, a cancellation or a non-hub exception carrying the same text never reads as a missing method. The per-connection memo, the re-probe after reconnect, explicit refusals and null outcomes are unchanged

Where to look

ReportParticipantParkedAsync shares the classifier and had the same gap: a server without ReportParticipantParked answered with the binding wording, which read as ambiguous and retried the park. Both answers now map to Rejected, so the reviewer falls back to the normal reap as intended

Verification

Run Result
ServerConnectionLegacyHubWireTests (real Kestrel SignalR hub with only AgentRegistered, detailed errors off), before fails with exactly the logged HubException
Same, after registration lands on AgentRegistered and reads as accepted
ServerConnectionAgentRegisteredTests + ServerConnectionParkProxyTests + the wire test 26/26 pass, including a classifier table and both park answers
Daemon dotnet publish -c Release 0 IL warnings

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved compatibility with servers that lack newer hub methods. Agent registration can fall back to the legacy method, and parking requests now follow the normal reap path when the server does not support the requested method.
    • Missing-method responses are distinguished from unrelated server errors, preventing other failures from being mistaken for unsupported methods.

…1858)

A JSON-protocol server cannot bind a method it lacks, so it answers "Method does not exist." rather than "Unknown hub method"

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Oct 24, 2026

Copy link
Copy Markdown

AI-4268

@coderabbitai

coderabbitai Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

The included review limit has been reached and this organization has disabled usage-based review continuation. Wait for reviews to reset or ask a billing admin to change After included review limits.

Next included review available in 7 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: b3f2f6f4-6d2f-4013-a27e-f59d96a92347
Commits

Reviewing files that changed from the base of the PR and between 4e3d68d and 54d8484.

Files selected for processing: 1
  • test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs

No actionable comments were generated in the recent review.

Recent review info
Run configuration
  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: Organization UI
  • Review profile: ASSERTIVE
  • Plan: Advanced
  • Run ID: ad1c9fd6-4e88-44d1-b06e-3a2d2afe8b82
Commits

Reviewing files that changed from the base of the PR and between f130862 and 4e3d68d.

Files selected for processing: 4
  • src/Capacitor.Cli.Daemon/Services/ServerConnection.cs
  • test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionAgentRegisteredTests.cs
  • test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs
  • test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionParkProxyTests.cs

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

Walkthrough

ServerConnection now recognizes two missing-hub-method error formats only when they match the invoked method. Registration and parking provide their method names to the classifier. Tests cover classification, parking behavior, and registration against a legacy hub.

Changes: Hub method fallback

Layer / File(s) Summary
Method-specific detection and invocation
src/Capacitor.Cli.Daemon/Services/ServerConnection.cs
The classifier recognizes the wrapped “Method does not exist” error and the “Unknown hub method” prefix for the invoked method. Registration and parking pass their method names to the classifier and use constants for raw invocations.
Fallback behavior validation
test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionAgentRegisteredTests.cs, test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionParkProxyTests.cs, test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs
Tests cover supported and rejected error cases, parking rejection, and successful registration against a SignalR hub with only the legacy method.

Priority: Normal

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix · Severity of issue fixed: Medium

Possibly related PRs

Suggested reviewers: alexeyzimarev, inok

Merge Risk: Minimal · up to 4e3d6

The change is ready to merge after normal checks; no unresolved fallback issue was established.

Security architecture risk: Low · up to 4e3d6

The fallbacks remain within the existing server connection, with method-specific matching and preserved handling of refusals and uncertain outcomes. No introduced security bypass was established. Server-side authorization and the provenance of matching error messages remain unverified.

Retained concerns
No architecture-level concerns identified.

Security review details

Security Blast Radius

  • inferred — A registration capability decision can affect subsequent agent registrations on the same connection through the existing memo. The parking decision affects the specified reviewer's cleanup path. These consequences warrant lifecycle review even though no new transport or privilege boundary is introduced.

Trust Boundaries and Controls

  • inferred — The classifier consumes server-provided exception type and text, not independently authenticated dispatcher provenance. A client-visible exception with identical accepted text would be indistinguishable at this boundary. The inspected evidence does not establish that an unauthorized caller can produce that response or bypass the legacy handler's authorization.

Resilience and Maintainability Implications

  • observed — The negative test cases distinguish ordinary registration refusal, another or similarly named method, non-hub exceptions, and cancellation from missing-method responses. These cases support containment of fallback decisions but do not prove server-side error provenance.
Pre-merge checks: Passed 3 · Failed 2

Failed Failed checks: 2 warnings

Check name Status Explanation Resolution
Linked Issues check Warning The implementation satisfies the main #1858 behavior. IsUnknownHubMethod matches both dispatcher responses only for the invoked method and only for HubException. Registration fallback memoization,… Add a focused automated test that starts an ordinary hosted session through the legacy-only SignalR hub and verifies that the session remains active after registration. Keep the existing exact-error, fallback, reconnect, refusal, null, and …
Docstring Coverage Warning Docstring coverage is 46.67% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 15 functions across 4 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
Passed Passed checks: 3 passed
Check name Status Explanation
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly summarizes the main change: fallback to legacy registration when the server returns the real missing-method response.
Out of Scope Changes check Passed All changes are connected to #1858. The classifier update, the two caller updates, unit cases, park regression cases, and the real legacy-hub wire test implement or validate the requested fallback and…
Full details: Out of Scope Changes check

Explanation

All changes are connected to #1858. The classifier update, the two caller updates, unit cases, park regression cases, and the real legacy-hub wire test implement or validate the requested fallback and shared-classifier behavior. No unrelated production behavior or unrelated test area was added.

Full details: Linked Issues check

Explanation

The implementation satisfies the main #1858 behavior. IsUnknownHubMethod matches both dispatcher responses only for the invoked method and only for HubException. Registration fallback memoization, reconnect re-probing, refusals, null outcomes, and unrelated failures remain covered in ServerConnectionAgentRegisteredTests.cs. ServerConnectionLegacyHubWireTests.cs uses a real SignalR hub without AgentRegisteredAcked. The issue also requires verification that an ordinary hosted session survives registration. The added wire test verifies registration only and does not verify a hosted session.

Resolution

Add a focused automated test that starts an ordinary hosted session through the legacy-only SignalR hub and verifies that the session remains active after registration. Keep the existing exact-error, fallback, reconnect, refusal, null, and unrelated-failure coverage.

  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@realtonyyoung
realtonyyoung marked this pull request as ready for review October 24, 2026 22:45
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Recognize legacy servers’ missing-method SignalR response

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Recognize both SignalR missing-method responses so registration falls back on legacy servers.
• Treat an unavailable park-report method as rejected, allowing normal reviewer reaping.
• Add real-hub and unit tests for fallback behavior and error classification.
Diagram

graph TD
  A["ServerConnection"] --> B["Hub invocation"] --> C{"Missing hub method?"} -- "No" --> D["Normal handling"]
  C -- "Registration" --> E["Legacy registration"]
  C -- "Park report" --> F["Reject park"]
Loading
High-Level Assessment

Keep the method-specific response classifier. Server-side capability negotiation would require changes to the legacy servers this fallback must support; matching the observed dispatcher answers fixes compatibility without broadening fallback to unrelated failures.

Files changed (4) +122 / -34

Bug fix (1) +18 / -19
ServerConnection.csClassify both missing-method responses for legacy hub calls +18/-19

Classify both missing-method responses for legacy hub calls

• Recognizes the JSON-protocol dispatcher response as well as the unknown-method response, scoped to a HubException for the invoked method. Registration can fall back to AgentRegistered, and an unavailable park-report method maps to Rejected rather than Ambiguous.

src/Capacitor.Cli.Daemon/Services/ServerConnection.cs

Tests (3) +104 / -15
ServerConnectionAgentRegisteredTests.csCover registration fallback and classifier boundaries +27/-1

Cover registration fallback and classifier boundaries

• Uses the JSON-protocol missing-method response in registration fallback tests. Adds cases for both recognized responses and for unrelated methods, refusals, cancellation, and non-hub exceptions.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionAgentRegisteredTests.cs

ServerConnectionLegacyHubWireTests.csVerify fallback against a real legacy SignalR hub +70/-0

Verify fallback against a real legacy SignalR hub

• Starts a local hub with AgentRegistered but no AgentRegisteredAcked and detailed errors disabled. Confirms registration reaches the legacy method and returns an accepted response.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs

ServerConnectionParkProxyTests.csCover both missing-method park-report responses +7/-14

Cover both missing-method park-report responses

• Parameterizes the park-report fallback test for both dispatcher responses. Confirms each maps to Rejected, enabling normal reviewer reaping.

test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionParkProxyTests.cs

@qodo-code-review

qodo-code-review Bot commented Oct 24, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. A test comment relies on release history ✗ Dismissed
Description
ServerConnectionLegacyHubWireTests describes its fixture as a server that `predates
AgentRegisteredAcked` instead of stating the current missing-method behavior. This historical
release framing makes the rationale depend on when the server was introduced rather than on the
observable dispatcher response.
Code

test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs[R12-15]

+/// <summary>
+/// A server that predates <c>AgentRegisteredAcked</c>, as a real SignalR hub: the method-missing answer is the
+/// one its dispatcher actually sends, not a string a test double chose. Detailed errors stay off, as on a tenant.
+/// </summary>
Relevance

●●● Strong

Recent history accepts rewriting historical comments into durable current-behavior invariants.

PR-#977
PR-#876
PR-#724

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The compliance rule prohibits comments that narrate historical change context such as what a server
predates; the newly added test summary uses that wording instead of describing only current
behavior.

Rule 2897915: Avoid time-sensitive or process-reference metadata in code comments
test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs[12-15]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The added test summary uses release-history wording by describing the fixture as a server that predates `AgentRegisteredAcked`, which makes the comment dependent on historical metadata rather than current behavior.

## Fix Focus Areas
- test/Capacitor.Cli.Daemon.Tests.Unit/Services/ServerConnectionLegacyHubWireTests.cs[12-15]

## Recommended Fix
Rewrite the summary to describe the observable compatibility condition directly: the hub does not expose `AgentRegisteredAcked`, the dispatcher emits the missing-method response, and detailed errors are disabled.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Context sources
⚠️ Tickets: not configured — No jira, linear integration is connected for the linked tickets
✅ Compliance rules (platform): 59 rules
✅ Cross-repo context — repo relationships
  Explored: repo: kurrent-io/kcap-server (sha: ee98c349) — View relationship
Review mode: Auto: ⚖️ Balanced: Behavioral compatibility fix affects registration, parking, and SignalR error classification.

Grey Divider

Tip of the day
💡 Did you know, you can enable the Remediation agent and Qodo fixes findings in a dedicated fix PR

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 24, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@realtonyyoung
realtonyyoung merged commit 5a31af2 into main Oct 25, 2026
13 checks passed
@realtonyyoung
realtonyyoung deleted the tonyyoung/ai-4268-legacy-registration-fallback branch October 25, 2026 00:09
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.

daemon: Preserve session launch compatibility when AgentRegisteredAcked is unavailable

1 participant