Skip to content

ATTACH-RACE: survive a control-socket reconnect during the first attach - #6682

Merged
eshurakov merged 2 commits into
mainfrom
triage/attach-race
Sep 24, 2026
Merged

eshurakov merged 2 commits into
mainfrom
triage/attach-race

Conversation

@eshurakov

Copy link
Copy Markdown
Contributor

Summary

  • A control-plane session whose wrapper control socket dropped and reconnected during the first attach could have its first turn terminalized while the runtime was still alive and heartbeating.
  • Two paths treated an unconfirmed admission as a hard failure: the prompt reconciliation path mapped an unperformed session.operation.get to a rejected observation and terminalized the queued turn as prompt_exhausted; and repeated pre-send not_ready refusals consumed the prompt failure budget.
  • One predicate, isUnconfirmedReachabilityFailure (services/cloud-agent-next/src/sandbox-session/control-dispatch.ts), now owns "retryable ControlRequestError without a confirmed rejection is a reachability failure" and is used at both boundaries, so the turn is retried within its existing head deadline instead of failing. No classifier change; no new flag or persisted state.

Verification

  • Unit tests that fail on the base branch for both boundaries (session-message-queue.test.ts, session-operation.test.ts, and new cases under test/unit/e2e/).
  • New E2E fault primitive (SIGUSR1 -> recycleConnection() -> production retireConnection) and scenario control-socket-recycle-boot, with an ordered attach-window oracle.
  • Local, at the commit: pnpm typecheck (incl. wrapper tsgo), pnpm lint, pnpm test, test/unit/e2e all green.

Visual Changes

N/A

Reviewer Notes

  • The E2E scenario also passes on base behaviour: it exercises a real drop/reconnect during the first attach but is not by itself a discriminator for the fix. The base-failing evidence is in the unit tests.
  • The E2E oracle as amended has no live pass in this environment (unrelated local harness failures); its live proof is from the pre-amendment revision.

@kilo-code-bot

kilo-code-bot Bot commented Sep 24, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The production fix and its amended tests remain sound, and the new commit resolves the earlier retry-on-miss warning by observing the discarded attempt's durable status until it settles; the one remaining warning is in the new E2E attach-drop correlation, which can miss the retired socket's socket_closed record when a fast reconnect supersedes it before the close is logged.

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/test/e2e/capabilities-local.ts 400 Close/reconnect correlation can miss the socket_closed record when the reconnect supersedes the retired socket before its close is logged (supersede rewrites handshakeComplete:false and drops connectionId/wrapperInstanceId), causing a non-retryable false failure.
Files Reviewed (5 files)
  • services/cloud-agent-next/test/e2e/capabilities-local.ts - 1 issue (carried forward)
  • services/cloud-agent-next/test/e2e/scenarios-shared-faults.ts - previous retry-on-miss warning resolved by the settle loop
  • services/cloud-agent-next/test/e2e/scenarios-shared.test.ts
  • services/cloud-agent-next/test/unit/e2e/attach-window-evidence.test.ts
  • services/cloud-agent-next/test/unit/e2e/drop-control-socket-during-attach.test.ts

Fix these issues in Kilo Cloud

Previous Review Summaries (2 snapshots, latest commit a907b9e)

Current summary above is authoritative. Previous snapshots are kept for context only.

Previous review (commit a907b9e)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0

The production fix is unchanged in the latest revision and remains sound: isUnconfirmedReachabilityFailure suppresses the delivery-failure increment at the SandboxSession boundary and maps an unconfirmed session.operation.get to uncertain/transport in the reconcile path, without masking confirmed rejections (rejectionReceived === true always falls through to rejected). The amended session-message-queue.test.ts expectation (preparation_timeout instead of prompt_exhausted, promptFailures === 0) is consistent with retrying an unconfirmed reachability failure to the existing head deadline, and the sibling accepted message is preserved. No new issues were introduced by the amendment; both warnings are in the new E2E fault infrastructure.

Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/test/e2e/capabilities-local.ts 401 Close/reconnect correlation can miss the socket_closed record when the reconnect supersedes the retired socket before its close is logged (supersede rewrites handshakeComplete:false and drops connectionId/wrapperInstanceId), causing a non-retryable false failure.
services/cloud-agent-next/test/e2e/scenarios-shared-faults.ts 977 A single non-terminal sample before retrying a window miss can discard a post-signal failure that materializes later, contradicting the documented "a later attempt cannot pass over it" guarantee.
Files Reviewed (19 files)
  • services/cloud-agent-next/src/sandbox-session/SandboxSession.ts
  • services/cloud-agent-next/src/sandbox-session/control-dispatch.ts
  • services/cloud-agent-next/src/sandbox-session/session-message-queue.test.ts
  • services/cloud-agent-next/src/sandbox-session/session-operation.test.ts
  • services/cloud-agent-next/src/sandbox-session/session-operation.ts
  • services/cloud-agent-next/test/e2e/README.md
  • services/cloud-agent-next/test/e2e/attach-window-evidence.ts
  • services/cloud-agent-next/test/e2e/capabilities-local.ts - 1 issue
  • services/cloud-agent-next/test/e2e/idle-stop-evidence.ts
  • services/cloud-agent-next/test/e2e/sandbox-control.ts
  • services/cloud-agent-next/test/e2e/scenario-capabilities.ts
  • services/cloud-agent-next/test/e2e/scenarios-shared-faults.ts - 1 issue
  • services/cloud-agent-next/test/e2e/smoke.ts
  • services/cloud-agent-next/test/unit/e2e/attach-window-evidence.test.ts
  • services/cloud-agent-next/test/unit/e2e/drop-control-socket-during-attach.test.ts
  • services/cloud-agent-next/test/unit/e2e/scenario-capabilities.test.ts
  • services/cloud-agent-next/test/unit/e2e/scenarios-shared.test.ts
  • services/cloud-agent-next/wrapper/src/control/main.ts
  • services/cloud-agent-next/wrapper/src/control/sandbox-control-client.ts

Fix these issues in Kilo Cloud

Previous review (commit 84e8e67)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0

The production fix is sound: isUnconfirmedReachabilityFailure correctly suppresses the delivery-failure increment and maps an unconfirmed session.operation.get to uncertain/transport without masking confirmed rejections, and it does not leave a queued turn hanging. Both findings are in the new E2E fault infrastructure.

Issue Details (click to expand)

WARNING

File Line Issue
services/cloud-agent-next/test/e2e/capabilities-local.ts 401 Close/reconnect correlation can miss the socket_closed record when the reconnect supersedes the retired socket before its close is logged (supersede rewrites handshakeComplete:false and drops connectionId/wrapperInstanceId), causing a non-retryable false failure.
services/cloud-agent-next/test/e2e/scenarios-shared-faults.ts 977 A single non-terminal sample before retrying a window miss can discard a post-signal failure that materializes later, contradicting the documented "a later attempt cannot pass over it" guarantee.
Files Reviewed (20 files)
  • services/cloud-agent-next/src/sandbox-session/SandboxSession.ts
  • services/cloud-agent-next/src/sandbox-session/control-dispatch.ts
  • services/cloud-agent-next/src/sandbox-session/session-message-queue.test.ts
  • services/cloud-agent-next/src/sandbox-session/session-operation.test.ts
  • services/cloud-agent-next/src/sandbox-session/session-operation.ts
  • services/cloud-agent-next/test/e2e/README.md
  • services/cloud-agent-next/test/e2e/attach-window-evidence.ts
  • services/cloud-agent-next/test/e2e/capabilities-local.ts - 1 issue
  • services/cloud-agent-next/test/e2e/idle-stop-evidence.ts
  • services/cloud-agent-next/test/e2e/sandbox-control.ts
  • services/cloud-agent-next/test/e2e/scenario-capabilities.ts
  • services/cloud-agent-next/test/e2e/scenarios-batches.ts
  • services/cloud-agent-next/test/e2e/scenarios-shared-faults.ts - 1 issue
  • services/cloud-agent-next/test/e2e/smoke.ts
  • services/cloud-agent-next/test/unit/e2e/attach-window-evidence.test.ts
  • services/cloud-agent-next/test/unit/e2e/drop-control-socket-during-attach.test.ts
  • services/cloud-agent-next/test/unit/e2e/scenario-capabilities.test.ts
  • services/cloud-agent-next/test/unit/e2e/scenarios-shared.test.ts
  • services/cloud-agent-next/wrapper/src/control/main.ts
  • services/cloud-agent-next/wrapper/src/control/sandbox-control-client.ts

Fix these issues in Kilo Cloud


Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0

Review guidance: REVIEW.md from base branch main

… control-socket reconnect

An unconfirmed admission while the wrapper control socket was activating or
reconnecting was treated as a hard prompt failure. The prompt reconciliation
path mapped an unperformed session.operation.get to a rejected observation and
terminalized the queued turn as prompt_exhausted, and repeated pre-send
not_ready refusals consumed the prompt failure budget.

Treat a retryable control error without a confirmed rejection as a
reachability failure, owned by one predicate used at both boundaries, so the
turn is retried within its existing head deadline instead of failing.

Adds an E2E fault primitive that recycles the wrapper control socket during
the first attach and asserts the first turn still completes, with an ordered
log oracle that refuses to report an already-settled attach as recovery.

ATTACH-RACE
…re retry

Observe the discarded attempt's durable status until it reaches a terminal
state instead of sampling it once, so a failure that materializes after a
window miss cannot be retried away. Apply oxfmt to the E2E test files.

ATTACH-RACE
@eshurakov
eshurakov merged commit 780aaa5 into main Sep 24, 2026
27 checks passed
@eshurakov
eshurakov deleted the triage/attach-race branch September 24, 2026 10:55
iscekic pushed a commit to Kilo-Org/kilocode that referenced this pull request Sep 26, 2026
…4554)

## Automated docs sync — 2026-09-25

This PR keeps kilo.ai/docs in sync with features merged to [Kilo-Org/cloud](https://github.com/Kilo-Org/cloud) and [Kilo-Org/kilocode](https://github.com/Kilo-Org/kilocode). Every change below links to the merged PR it documents.

- Window: `2026-09-24T07:08:33.639Z` → `2026-09-25T07:05:29.302Z`
- Verification (docs build + tests): **passing**

### Surface: `cloud-mobile`

- Assignees / requested reviewers: @iscekic and @eshurakov
- Derivation: Derived from the repository layout. A product surface is a package under packages/ that ships a distinct client, plugin, backend, or hosted service: cli = packages/opencode/ + packages/tui/ + packages/server/ + packages/sdk/ + packages/plugin/; vscode = packages/kilo-vscode/ + packages/kilo-web-ui/ + packages/kilo-ui/; jetbrains = packages/kilo-jetbrains/; gateway = packages/kilo-gateway/; web = packages/kilo-console/ + packages/kilo-indexing/ + packages/kilo-memory/ + packages/kilo-sandbox/. Docs route from the IA tree packages/kilo-docs/pages/ plus docs/jetbrains-vscode-settings-parity.md: each surface lists the pages sections that document it, and the per-platform pages under packages/kilo-docs/pages/code-with-ai/platforms/ map to the matching extension surface (the vscode/ directory to vscode, jetbrains.md to jetbrains). A doc path belongs to the surface with the longest matching prefix; a path that matches none of those prefixes falls to `other` (the explicit other prefixes are listed under other.docs). The cloud surfaces are derived the same way from the Kilo-Org/cloud layout: cloud-mobile = apps/mobile/, cloud-web = apps/web/, cloud-extension = apps/extension/, and cloud-agent = the cloud-agent packages under packages/ (packages/cloud-agent-sdk/ + packages/cloud-agent-profile/). A cloud source names its repository while a bare string still means this repository. The pages under packages/kilo-docs/pages/collaborate/ document the cloud web app (app.kilo.ai: teams dashboard, billing, SSO, adoption dashboard), so they route to cloud-web. No page under packages/kilo-docs/pages/ documents the browser side-panel extension yet, so cloud-extension lists no docs prefix.
- Map: `.github/docs-sync/surfaces.json`
- Surface map: `cli`, `vscode`, `jetbrains`, `gateway`, `web`, `cloud-mobile`, `cloud-web`, `cloud-extension`, `cloud-agent`, `other`
- Source prefixes: `apps/mobile/` (Kilo-Org/cloud)
- Doc prefixes: `packages/kilo-docs/pages/code-with-ai/platforms/mobile.md`
- Paths that fall to `other`: `packages/kilo-docs/pages/community/`, `packages/kilo-docs/pages/kiloclaw/`, `packages/kilo-docs/pages/contributing/`, `packages/kilo-docs/LEARNINGS.md`, `docs/`
- Reviewers are ranked from `Kilo-Org/cloud`; the workflow needs a token with `contents: read` on that repository (repository secret `CROSS_REPO_ACCESS_TOKEN`, exposed to the upsert step as `CLOUD_REPO_TOKEN`).
- How the two were computed: Reviewers for `cloud-mobile` are ranked from `Kilo-Org/cloud` git history over `apps/mobile/` (a commit 180 days old counts half as much, half-life 180 days). Bots (author type "Bot" or a login matching /\[bot\]$/i) and people without admin, write, or maintain permission are excluded.

### Changes

<!-- docs-sync:changes:start -->
| Docs change | Source |
| --- | --- |
| updated pages/code-with-ai/platforms/mobile.md | [Kilo-Org/cloud#6386](Kilo-Org/cloud#6386) |
| updated pages/ai-providers/openai-chatgpt-plus-pro.md | [Kilo-Org/cloud#6702](Kilo-Org/cloud#6702) |
| updated pages/code-with-ai/platforms/cloud-agent.md | [Kilo-Org/cloud#6683](Kilo-Org/cloud#6683) |
| updated pages/getting-started/byok.md | [Kilo-Org/cloud#6692](Kilo-Org/cloud#6692) |
<!-- docs-sync:changes:end -->

### Pending — will retry

<!-- docs-sync:pending:start -->
_None._
<!-- docs-sync:pending:end -->

### Considered, no docs change needed

<!-- docs-sync:skipped:start -->
| PR | Reason |
| --- | --- |
| [Kilo-Org/cloud#6658](Kilo-Org/cloud#6658) | Internal sandbox lifecycle fix with no user-visible workflow or setting. |
| [Kilo-Org/cloud#6673](Kilo-Org/cloud#6673) | Internal container CA trust plumbing, no user-facing behavior. |
| [Kilo-Org/cloud#6672](Kilo-Org/cloud#6672) | Internal sandbox launch/recovery fix with no documented workflow change. |
| [Kilo-Org/cloud#6660](Kilo-Org/cloud#6660) | Internal cloud-agent queue delivery fix; no new command, setting, or workflow for users. |
| [Kilo-Org/cloud#6226](Kilo-Org/cloud#6226) | Internal gateway alias-routing change, not user-visible. |
| [#14490](#14490) | Tool-call animation and streaming UI polish; users do not need to learn a new workflow. |
| [#14530](#14530) | Bug fix restoring intended worktree-pool behavior, no doc change needed. |
| [#14529](#14529) | Bug fix restoring tab/panel state across project switches. |
| [#14531](#14531) | Reconnect recovery bug fix, restores already-documented behavior. |
| [#14532](#14532) | Bug fix keeping session tab title in sync on rename. |
| [Kilo-Org/cloud#6088](Kilo-Org/cloud#6088) | Removes internal/admin model-experiment surfaces, not public product docs. |
| [Kilo-Org/cloud#6682](Kilo-Org/cloud#6682) | Internal control-socket reconnect race fix, no user-facing change. |
| [#14534](#14534) | Transcript re-render performance bug fix. |
| [#14535](#14535) | Bug fix preserving the loaded browser page across context switches. |
| [Kilo-Org/cloud#6684](Kilo-Org/cloud#6684) | Reverted by Kilo-Org/cloud#6685. |
| [Kilo-Org/cloud#6678](Kilo-Org/cloud#6678) | Dead-code constant removal, no user-visible effect. |
| [Kilo-Org/cloud#6687](Kilo-Org/cloud#6687) | Removes internal model-experiment maintenance and retains tables, no user-facing change. |
| [#14515](#14515) | JetBrains plugin unload crash fix, no documented behavior change. |
| [#14520](#14520) | JetBrains transcript/list rendering performance work. |
| [Kilo-Org/cloud#6614](Kilo-Org/cloud#6614) | Mobile PR Review header and session title bug fix, no doc change needed. |
| [Kilo-Org/cloud#6625](Kilo-Org/cloud#6625) | Internal mobile secure-store error-handling refactor. |
| [Kilo-Org/cloud#6624](Kilo-Org/cloud#6624) | Mobile auth bug fix that stops a retry loop; restores expected sign-in behavior with no new setting or workflow. |
| [#14310](#14310) | Contributor/CI fix making the kilo-v2 checkout installable; not user-visible product behavior. |
| [Kilo-Org/cloud#6611](Kilo-Org/cloud#6611) | Mobile notification-tap fix that selects the session's organization; restores correct behavior rather than adding a learnable feature. |
| [Kilo-Org/cloud#6644](Kilo-Org/cloud#6644) | Mobile sign-in layout/alignment polish; no change to what a user must do. |
| [Kilo-Org/cloud#6601](Kilo-Org/cloud#6601) | Mobile layout fix keeping empty states clear of the tab bar; purely visual. |
| [#14543](#14543) | CI/release infrastructure adding Windows binary code signing; no public docs impact. |
| [Kilo-Org/cloud#6616](Kilo-Org/cloud#6616) | Mobile visual defect fixes and a session-title fallback; no new user workflow or setting. |
| [Kilo-Org/cloud#6630](Kilo-Org/cloud#6630) | Reports an edge-case partial worktree restore; failure-path plumbing with no new user-facing workflow, target setting, or config. |
| [Kilo-Org/cloud#6699](Kilo-Org/cloud#6699) | Cloud Agent e2e stabilization plus internal idle-sandbox capacity handling; not user-visible. |
| [#14545](#14545) | Automated JetBrains release/changelog PR; underlying user-facing changes are triaged from their own PRs. |
| [Kilo-Org/cloud#6708](Kilo-Org/cloud#6708) | Internal AI-gateway request-logging policy change in the admin panel; no existing public docs surface and no change to how users run Kilo Code. |
| [#14533](#14533) | Documentation already shipped with the merged PR. The experimental.task_model_selection flag is gone from the current source, and pages/code-with-ai/agents/model-selection.md, pages/code-with-ai/agents/context-mentions.md, and pages/getting-started/settings/index.md already describe per-task selection as default-on with no stale experiment references. |
| [#14510](#14510) | Documentation already shipped with the merged PR. Marketplace companion-skill support is present in the current source (packages/opencode/src/kilocode/marketplace/companions.ts and installer), and pages/customize/marketplace.md already documents installing, publishing, and removing MCP servers with companion skills. |
<!-- docs-sync:skipped:end -->

---

(bot) Generated by the docs-sync workflow. Humans review and merge; while this PR stays open, the next daily run appends new changes here. Branch: `docs/auto-sync-2026-09-25`.
<!-- docs-sync: processed-through 2026-09-25T07:05:29.302Z -->
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.

2 participants