Repository navigation
fix(js/net): a scoped handle that closes reports its received routes offline - #8504
Conversation
Quest-Claim: 5a05b3572e71ee92
…offline Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Warning Review limit reachedYou'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 2 minutes. View limit details
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. |
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes
Read the complete 4-file diff, traced the route-entry lifecycle it touches, and verified the Rust counterpart before concluding.
js/net/src/origin.ts: the lost reason moved into the release callback registered with#hold(let lost = !originated), so every teardown path — the claim's ownclose()and a borrowedProducerscope closing — writesentry.lostbeforeremove(...); onlyend()clears it for an explicit wire end.releasekeeps itsif (!ended)guard, so a lateend()after teardown cannot overwrite the reason.js/net/src/origin.test.ts: regression test receives a route throughorigin.scope(...), closes the scope, and expectsoffline; it fails on the pre-fix code withkind: "end", so the coverage is real rather than incidental.quest/m1/offline-js-handle.md,quest/m1/offline-cursor-fallback.md: quest completed by deletion with its inboundRelatedlink dropped;grepfinds no remaining references to the slug.
The change matches the documented contracts: wire.ts says closing a received route's handle means its session lost it, and announced.ts maps that to offline ("this side let go of the path"), while end is reserved for the origin withdrawing it. Rust has no gap to mirror — Producer::scope there shares state without a release registry, and a forwarded route retracts Retract::Lost when its own RouteState drops.
Verified locally: pre-fix fails / post-fix passes for the new test, and bun test js/net/src reports 3207 pass, 1 skip, 0 fail.
deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

Summary
A route a session received through a scoped
Producernow goesofflinewhen that scoped handle closes, instead ofend. The scoped close ran the raw release#holdregistered and skippedclose(lost), soentry.loststayed false. The reason now lives in the shared release transition: a received route defaults to lost, and onlyend()(an explicit wire end) selects withdrawal.Test:
a route received through a scoped handle goes offline when the handle closesinjs/net/src/origin.test.ts(failed before the fix).Rust
No same gap. A Rust
Producer(scoped or not) never tears down routes it created; a route retracts only when its ownRoutedrops, andRouteState::dropalready picksRetract::Lostfor forwarded routes. The cursor-fallback misreport is /quest/m1/offline-cursor-fallback.md, handled separately.Impact
Public API: none. Wire: none.
Caused by
Notes
origin.ts; small (a few lines in#serving).offline-cursor-fallback.md, which another agent is editing in parallel; a trivial conflict there is possible.Models
Size: S
Implementer: Claude Code, Opus 5.5, low effort
🤖 Generated with Claude Code
(Written by Opus 5.5 with low)
Review
Rewritten by
quest reviewafter each round.01a1c9e8-d239-7e81-b35d-6f7f50402650, round 1The shared release transition correctly reports scoped received-route teardown as offline while preserving explicit wire ends and idempotent cleanup, with a focused regression test covering the bug, though tests were not run as instructed.