fix(session-ingest): resolve a forwarded exit_cli when ownership ends - #4827
Open
iscekic wants to merge 2 commits into
Open
fix(session-ingest): resolve a forwarded exit_cli when ownership ends#4827iscekic wants to merge 2 commits into
iscekic wants to merge 2 commits into
Conversation
A successful remote /exit was reported to the app as "Session owner
changed": the CLI ACKs exit_cli only after the detach heartbeat that
removes the session, so the relay always failed the pending command
first. For a forwarded exit_cli, ownership ending is the requested
outcome, so resolve it with result: {} (the CLI's own ACK shape) when
the owner-change path sees no next owner or when the owning socket is
really gone. Genuine takeovers, reconnect replacements, and every other
command keep failing with SESSION_OWNER_CHANGED.
A CLI too old to advertise itself is connected but never offered as a Run on target, and the empty state only said nothing was connected. Name both recoveries: run kilo remote, or update Kilo CLI if one is already running.
Contributor
Code Review SummaryStatus: No Issues Found | Recommendation: Merge Executive SummaryThe relay fix for forwarded Files Reviewed (3 files)
Reviewed by claude-sonnet-5 · Input: 30 · Output: 5.7K · Cached: 812.1K Review guidance: REVIEW.md from base branch |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Two remote-CLI defects, one small fix each.
Defect A — a successful
/exitreported as "Session owner changed". Root cause: the CLI ACKsexit_clionly after the detach heartbeat that removes the session, so the relay always failedthe pending command first and the user saw "Session owner changed" for an exit that had succeeded.
The relay now treats ownership ending as the requested outcome for a forwarded
exit_cli:failPendingCommandsForOwnerChangeresolves it withresult: {}(byte-identical to the CLI's ownACK, and the only shape the SDK's strict
exitSessionResponseSchemaaccepts) when no next ownerappears, and
failPendingCommandsForSocketdoes the same when the owning CLI socket is reallygone (
cliGone = !replaced). Genuine takeovers, reconnect socket replacements, and every othercommand keep failing with
SESSION_OWNER_CHANGEDexactly as before. No mobile or SDK change: withthe relay fixed, the client's existing error classification is already correct.
Defect B — a remote CLI missing from the "Run on" targets — splits in two:
kiloTUI with/remote, or config auto-enable) is already fixed upstream.In the released CLI (
@kilocode/cli7.4.16) only thekilo remotecommand path advertises theinstance; kilocode
maincommita19d44c3ef(PR Advertise the instance from enableRemote and report attention status on the heartbeat kilocode#12532) moved advertisementinto
KiloSessions.enableRemote(), so every enable path advertises. That commit is not anancestor of the v7.4.16 release tag — the fix awaits a CLI release, and no code change is
warranted in either repository.
kilo remoteon ≤ 7.4.16) is not reproducible on the current baseline. On7.4.16 the
kilo remotehandler already advertises beforeenableRemote(), and it was observedworking: a headless
kilo remoteappeared in the picker, while a relay-enabled TUI on the sameversion did not (observation run 2026-07-28, iOS simulator, personal context, account
e2e-mobile-remote-cli-69f6@example.com). The most likely reading of the report is that theuser's "kilo remote" was the TUI's
/remote— i.e. Half 1. Remaining open candidates: orgcontext (the Run-on selector is intentionally hidden for any organization), and a degraded
heartbeat that omits
instance, which wipes a previously advertised row until the next fullheartbeat. Neither is settled here and neither is chased.
Why Defect B ships only one string. The upstream fix exists and re-implementing it would
collide with
a19d44c3ef; relaxinggetConnectedInstances()to synthesize rows would inventhostname/project/version only the CLI knows. What no upstream commit solves is the empty state:
today a user whose CLI is connected but cannot advertise is told "No CLI instances connected" —
full stop. The description now names both recoveries: run
kilo remote, or update Kilo CLI ifone is already running. No new snapshot test for one display literal — the picker's four states
are already covered as pure logic by
resolveInstancePickerViewState, and a snapshot here would becoverage theatre.
Verification
exit_cli"failed with
SESSION_OWNER_CHANGEDbefore the fix, then passed after (the fix, not thevalidation, changed — the relay's
exit_clivalidation is untouched).services/session-ingest:pnpm test(612 passed),pnpm typecheck,pnpm lint— green;pre-existing owner-change tests unmodified.
apps/mobile:pnpm format && pnpm typecheck && pnpm lint && pnpm check:unused && pnpm test(2337 passed) — green.
kilo remoteappeared in the Run-on picker (
Igor-MacBook.local / remote-cli-69f6); with the TUI'srelay additionally enabled the picker still showed only that one instance — Half 1
reproduced, Half 2 refuted in one screen. (Two screenshots were captured; GitHub's API
cannot attach binaries to PRs, so their content is transcribed here — nothing else in them
is load-bearing.)
/exitE2E on the simulator (plan 1.7): in progress; results will be added beforemerge.
origin/main(detached worktree,
merge-baseguard ona19d44c3efpassed); in progress.E2E note: simulator sign-in relied on the documented throwaway Maestro workaround (type the
address, then
pressKey: Enter— the Send-code button sits under the keyboard window).apps/mobile/e2e/**was not edited; the real harness fix is #4820.Visual Changes
Instance-picker empty state (zero connected CLIs), description only:
Reviewer Notes
UserConnectionDO.tsfailPendingCommandsForOwnerChange/failPendingCommandsForSocket— the only behavioral change is the payload branch for forwardedexit_cli; call sites did not move, send/delete ordering is unchanged, and the'CLI disconnected'string path is preserved.SESSION_OWNER_CHANGEDinhandleWebCommandis deliberately untouched: nothingwas sent there, and reporting success would claim an exit worked when it was never forwarded.
exit_clion purpose: the CLIprocess is alive and the exit's outcome is genuinely unknown.