Skip to content

Confirm a loose-end claim held under an encoded ACP session id - #1859

Merged
realtonyyoung merged 2 commits into
mainfrom
tonyyoung/ai-4231-encoded-claim-confirm
Oct 22, 2026
Merged

realtonyyoung merged 2 commits into
mainfrom
tonyyoung/ai-4231-encoded-claim-confirm

Conversation

@realtonyyoung

@realtonyyoung realtonyyoung commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

AI-4231 (no GitHub issue)

What & why

With ACP id encoding on, the server stores a hosted agent's sess-1 under a senc1… token and resolves the raw id it is sent to that token (kurrent-io/kcap-server#2579). A claimed completion then reports the token as session_id, and the worker-filtered list reports claims under it, so complete_loose_end said the completion could not be confirmed and list_loose_ends refused the claim rows, though the server had done the work. SessionIds.SameSession accepts the reported id when it is the sent id or its server token.

Where to look

ServerToken must match the server's SessionIdToken.Encode byte for byte; the test vector for sess-1 pins it.

Verification

  • SessionIdsTests 9/9, LooseEndClaimToolResultsTests 5/5
  • The server side of the same flow: LooseEndClaimLifecycleEndpointTests.An_acp_worker_claims_lists_and_completes_by_its_raw_session_id in kurrent-io/kcap-server#2579 asserts the completion reports the token

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Session matching now recognizes equivalent raw, canonical, and encoded IDs, so completion confirmations and worker-filtered claim lists correctly identify the same session.

The server reports a hosted ACP agent's session under the token it encodes the raw id to, so the CLI computes that token to recognise its own session

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

linear-code Bot commented Oct 22, 2026

Copy link
Copy Markdown

AI-4231

@coderabbitai

coderabbitai Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Warning

Review limit reached

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

Next included review available in 41 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review 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: c902c165-541a-4095-9a53-5b0c4ad536ac
📥 Commits

Reviewing files that changed from the base of the PR and between 7a518a6 and ba810a9.

📒 Files selected for processing: 2
  • src/Capacitor.Cli.Core/SessionIds.cs
  • test/Capacitor.Cli.Core.Tests.Unit/SessionIdsTests.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: c9453907-ee6f-4d66-86ac-83176aff5db1
📥 Commits

Reviewing files that changed from the base of the PR and between cfc4b4b and 7a518a6.

📒 Files selected for processing: 4
  • src/Capacitor.Cli.Core/SessionIds.cs
  • src/Capacitor.Cli/Commands/LooseEndClaimToolResults.cs
  • test/Capacitor.Cli.Core.Tests.Unit/SessionIdsTests.cs
  • test/Capacitor.Cli.Tests.Unit/Commands/LooseEndClaimToolResultsTests.cs

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

Adds session matching for sent IDs and derived server tokens. Loose-end claim completion and worker confirmation use the new matching logic. Tests cover raw, encoded, mismatched, and null identifiers.

Changes: Session matching

Layer / File(s) Summary
Session ID matching
src/Capacitor.Cli.Core/SessionIds.cs, test/Capacitor.Cli.Core.Tests.Unit/SessionIdsTests.cs
Adds SameSession and server-token generation. Tests cover matching raw and GUID forms, encoded tokens, mismatches, and a null reported ID.
Loose-end claim result checks
src/Capacitor.Cli/Commands/LooseEndClaimToolResults.cs, test/Capacitor.Cli.Tests.Unit/Commands/LooseEndClaimToolResultsTests.cs
Completion and worker-filtered claim checks use SameSession. Tests cover raw, encoded, and mismatched session IDs.

Priority: ➖ Normal

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

Change: Bug fix

Suggested reviewers: alexeyzimarev

Merge Risk: ⚪ Minimal · up to 7a518

No actionable merge-blocking issue was found. Server compatibility remains unconfirmed by the available repository evidence.

Pre-merge checks: Passed 4 · Failed 1

Failed Failed checks: 1 warning

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 11 functions across 4 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 and concisely describes the main change: confirming loose-end claims that use an encoded ACP session ID.
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.
  • 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.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Confirm loose-end claims reported under encoded ACP session IDs

🐞 Bug fix 🧪 Tests 🕐 20-40 Minutes

Grey Divider

AI Description

• Recognize server-encoded session IDs when confirming loose-end completions and worker claims.
• Preserve raw and canonical session ID matching while rejecting unrelated sessions.
• Pin the server token format with a test vector and cover both claim responses.
Diagram

graph TD
  A["Sent session"] --> B{"Canonical match?"} -->|No| C["Compute token"] --> D{"Token match?"} -->|Yes| E["Confirm claim"]
  B -->|Yes| E
  D -->|No| F["Reject confirmation"]
Loading
High-Level Assessment

Keep the local, deterministic comparison: these responses report the server token, so canonical comparison alone cannot confirm ownership. Sharing the encoder across repositories or making another server request would add coordination or latency for this focused protocol compatibility fix; the pinned test vector guards against encoding drift.

Files changed (4) +68 / -2

Bug fix (2) +29 / -2
SessionIds.csMatch reported sessions against raw IDs or server tokens +26/-0

Match reported sessions against raw IDs or server tokens

• Adds SameSession to accept canonical ID matches or the server-compatible SHA-256/base32 token derived from the sent ID. Unrelated reported IDs remain unmatched.

src/Capacitor.Cli.Core/SessionIds.cs

LooseEndClaimToolResults.csUse token-aware matching for loose-end claim confirmation +3/-2

Use token-aware matching for loose-end claim confirmation

• Uses SameSession when validating a completed claim and claims in a worker-filtered list. Encoded server responses can now confirm the worker without relaxing the other response checks.

src/Capacitor.Cli/Commands/LooseEndClaimToolResults.cs

Tests (2) +39 / -0
SessionIdsTests.csCover canonical and encoded session identity matching +10/-0

Cover canonical and encoded session identity matching

• Tests raw IDs, GUID normalization, a pinned encoded token for sess-1, unrelated IDs, and a missing reported ID.

test/Capacitor.Cli.Core.Tests.Unit/SessionIdsTests.cs

LooseEndClaimToolResultsTests.csTest encoded IDs in completion and worker-list responses +29/-0

Test encoded IDs in completion and worker-list responses

• Adds response-level tests showing that raw or encoded IDs confirm the appropriate worker while unrelated IDs do not.

test/Capacitor.Cli.Tests.Unit/Commands/LooseEndClaimToolResultsTests.cs

@qodo-code-review

qodo-code-review Bot commented Oct 22, 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. Padded IDs fail encoded session checks ✗ Dismissed
Description
SameSession canonicalizes sent for direct equality but computes ServerToken(sent) from its
untrimmed bytes. When a caller supplies " sess-1 " and the server reports the token for canonical
"sess-1", the encoded response is rejected even though the direct ID comparison accepts the same
padded input.
Code

src/Capacitor.Cli.Core/SessionIds.cs[19]

+        Canonical(reported) is { } id && (id == Canonical(sent) || sent is not null && id == ServerToken(sent));
Relevance

●●● Strong

Trim sent before token hashing so padded IDs match the server token; this is a deterministic
correctness fix.

PR-#1230

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
Canonical trims opaque IDs, while the newly added token path hashes its argument byte-for-byte.
The added test establishes the token for sess-1, and the existing canonicalization test
establishes that padded sess-1 names that same ID.

src/Capacitor.Cli.Core/SessionIds.cs[9-13]
src/Capacitor.Cli.Core/SessionIds.cs[18-25]
test/Capacitor.Cli.Core.Tests.Unit/SessionIdsTests.cs[9-16]

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

## Issue description
`SameSession` trims the sent ID for direct comparison but hashes the untrimmed ID for token comparison, so padded IDs cannot match their server token.

## Fix Focus Areas
- src/Capacitor.Cli.Core/SessionIds.cs[18-25]
- test/Capacitor.Cli.Core.Tests.Unit/SessionIdsTests.cs[12-20]

## Recommended Fix
Canonicalize `sent` once and use that non-null value for both comparisons, including `ServerToken`. Add a test pairing a padded sent ID with the known token for `sess-1`.

ⓘ 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 (branch: tonyyoung/ai-4231-acp-body-session-id, sha: 0717f603) — View relationship
Review mode: Auto: ⚖️ Balanced: Behavioral session identity logic warrants a careful single-pass review.

Grey Divider

Tip of the day
💡 Did you know, you can ask Qodo to dismiss a finding you disagree with, with your reason on record

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/Capacitor.Cli.Core/SessionIds.cs Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes Oct 22, 2026
The worker-filtered list sends the trimmed id, so the token it is reported under is the trimmed id's

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@realtonyyoung
realtonyyoung merged commit f3a3067 into main Oct 22, 2026
11 checks passed
@realtonyyoung
realtonyyoung deleted the tonyyoung/ai-4231-encoded-claim-confirm branch October 22, 2026 20:28
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