Skip to content

feat(mobile): complete source-session clone and Android sheet fixes - #5440

Merged
iscekic merged 50 commits into
mainfrom
consolidated-kilo-workflow-2ade
Aug 23, 2026
Merged

feat(mobile): complete source-session clone and Android sheet fixes#5440
iscekic merged 50 commits into
mainfrom
consolidated-kilo-workflow-2ade

Conversation

@iscekic

@iscekic iscekic commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Summary

  • The back button and the session title on the session screen are now separate, larger tap targets. You can go back or rename the session without tapping the wrong control.
  • When you start a new session, repositories you have used most often and most recently now appear first in the repository list.
  • Continue in a new session now copies the whole previous conversation into a new cloud session, without asking you to choose a destination. The new session opens without a pre-written first message and waits for your next prompt. If the copy cannot finish, the button shows a retry message or a clear next step instead of failing silently.
  • On Android, the session detail sheets still open full height, but their content now stays below the system status bar. On iOS, the sheets keep their current look.
  • On Android, the pull request review screen now keeps its bottom buttons and lists clear of the system navigation bar.

The prepareSession contract gains a clone-only variant keyed on cloneFromKiloSessionId. A clone create requires autoInitiate true and a stable operationKey, forbids prompt, initialMessageId, and initialPayload, and registers no synthetic initial turn, so the copied transcript is the session state and the destination waits for the user's next prompt. Old callers that omit the field keep the empty-session bootstrap unchanged.

Files
  • apps/web/src/lib/cloud-agent-next/cloud-agent-client.ts — splits the prepare input type into non-clone and clone-only variants.
  • apps/web/src/routers/cloud-agent-next-schemas.ts — adds the discriminated clone variant to the shared prepare schema.
  • services/cloud-agent-next/src/router/schemas.ts — adds the clone-only prepare variant and includes it in the prepare input union.
  • services/cloud-agent-next/src/session/session-requests.ts — makes the initial turn optional and adds the clone source field.
  • services/cloud-agent-next/src/persistence/session-metadata.ts — adds the clone metadata schema holding the source session ID.
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts — registers metadata with an optional message and a clone field, so a clone records no synthetic initial turn.
  • services/cloud-agent-next/src/router/handlers/session-prepare.ts — maps a clone create to an undefined initial turn and threads the clone source into the session create request.
  • services/cloud-agent-next/src/session-service.ts — treats a clone as requiring snapshot restore and forwards the git URL and clone source to session-ingest.
  • services/cloud-agent-next/src/shared/wrapper-bootstrap.ts — adds the requireSnapshot workspace flag to the wrapper bootstrap contract.
  • services/cloud-agent-next/wrapper/src/session-bootstrap.ts — fails a clone bootstrap when the required snapshot is missing instead of falling back to an empty import.

The session-ingest service gains a bounded, resumable clone that copies a source session's ingest rows into a destination Durable Object before the PostgreSQL row is written. The copy rewrites session, message, and part identities, verifies a SHA-256 digest of the source against the staged rows, and returns typed rejection codes (source_access_denied, organization_mismatch, malformed_source_data, missing_source_body, source_digest_changed, destination_conflict, clone_setup_failed) that are a stable contract. A failed clone resets the destination stage and deletes its R2 bodies, leaving no PostgreSQL row behind.

Files
  • packages/session-ingest-contracts/src/rpc-contract.ts — adds cloneFromKiloSessionId to the create schema, the rejection-code union, and the ready/in_progress/rejected result shape.
  • services/session-ingest/src/clone/session-clone.ts — new bounded, resumable clone orchestrator with digest verification and typed rejection.
  • services/session-ingest/src/dos/SessionIngestDO.ts — adds clone stage meta plus exportCloneBatch, stageCloneBatch, inspectCloneStage, finalizeCloneStage, and resetCloneStage.
  • services/session-ingest/src/session-ingest-rpc.ts — runs the clone before the row insert, idempotently claims existing destinations, and rolls back a clone only when it matches its source.
  • services/session-ingest/src/ingest/metadata.ts — tracks whether a git_url write was actually applied so a refused Cloud Agent write no longer emits a phantom session.updated event.

The clone-only create path now settles correctly after a lost response. A Session already registered rejection is treated as idempotent success instead of rolling back a committed clone, and a fully-succeeded clone-only reconcile settles completed instead of returning creation_in_progress forever.

Files
  • services/cloud-agent-next/src/session/session-registration.ts — treats the lost-response registration rejection as idempotent success and settles a fully-succeeded clone-only reconcile as completed.

Continue in a new session now clones the full source session through the cloud prepare path instead of seeding a synthetic prompt or spawning a remote session. The hook resolves one destination, retries retryable clone failures with a fixed backoff, and surfaces terminal guidance or a retry message, so the read-only session footer always shows the right next step. The multi-destination continue picker and its bridge are deleted.

Files
  • apps/mobile/src/components/agents/use-continue-session.ts — rewrites the hook to resolve a single cloud destination, retry with backoff, and emit terminal or retry guidance.
  • apps/mobile/src/components/agents/continuation-seed.ts — replaces destination enumeration with a single-outcome resolver that keeps the failure reason.
  • apps/mobile/src/components/agents/use-continue-cloud-create.ts — sends the clone-only prepare input with a hoisted operation key and a persisted safe-retry row.
  • apps/mobile/src/components/agents/session-detail-content.tsx — renders the guidance states and the Connect repository action.
  • apps/mobile/src/components/agents/session-detail-content-helpers.ts — adds the Connect repository action that opens GitHub setup and clears terminal guidance.
  • apps/mobile/src/app/(app)/_layout.tsx — removes the continue-picker route registration.
  • apps/mobile/src/app/(app)/agent-chat/continue-picker.tsx — deleted; the multi-destination picker screen is gone.
  • apps/mobile/src/components/agents/continue-picker-bridge.ts — deleted; the picker bridge module is gone.
  • apps/mobile/src/components/agents/continue-picker-rows.ts — deleted; the picker row mapper is gone.

Repository lists from the cloud-agent routers are now ordered by the caller's Cloud Agent usage history. Used repositories sort by session count descending, latest use descending, then normalized key; unused repositories keep provider order, and a rank-read failure returns the original order unchanged. The ordering is a backend contract consumed by web and mobile.

Files
  • apps/web/src/lib/cloud-agent/order-repositories.ts — new usage-ranking helper reading cli_sessions_v2 usage grouped by normalized git URL.
  • apps/web/src/routers/cloud-agent-next-router.ts — applies the ranking to personal GitHub and GitLab repository lists.
  • apps/web/src/routers/organizations/organization-cloud-agent-next-router.ts — applies the ranking to organization GitHub, GitLab, and Bitbucket repository lists.
  • apps/mobile/src/lib/use-new-session-repos.ts — drops a type assertion now that the tRPC result is typed.

One shared sheet surface now hosts all six session-page sheets. On Android it renders an opaque full-window modal whose surface pads the top safe-area inset, so the content clears the system status bar; on iOS it keeps the native pageSheet modal, so each sheet keeps its existing content and safe-area footer.

Files
  • apps/mobile/src/components/agents/session-page-sheet.tsx — new shared surface with the iOS pageSheet and the full-height Android variant padded by the top inset.
  • apps/mobile/src/components/agents/session-context-sheet.tsx — swaps its own modal for the shared surface.
  • apps/mobile/src/components/agents/part-detail-sheet.tsx — swaps its own modal for the shared surface.
  • apps/mobile/src/components/agents/message-details-sheet.tsx — swaps its own modal for the shared surface and routes the select-text view through it.
  • apps/mobile/src/components/agents/child-session-sheet.tsx — swaps its own modal for the shared surface.
  • apps/mobile/src/components/agents/file-part-renderer.tsx — hosts the file preview modal on the shared surface.
  • apps/mobile/src/components/agents/attachment-preview-strip.tsx — hosts the attachment text preview on the shared surface.

The subagent sheet keeps its Modal mounted after close, so the dismissal animation runs before the sheet identity is released. Android has no Modal.onDismiss, so it releases on a 350-millisecond timer; iOS releases from the native callback.

Files
  • apps/mobile/src/components/agents/child-session-sheet-state.ts — adds the sheet mount lifecycle helpers.

The session screen header now gives the back control and the rename title separate 44-point tap targets. The back button is a fixed 44-point square and the title pressable carries its own hit slop, so the two controls no longer overlap and neither is clipped.

Files
  • apps/mobile/src/components/screen-header.tsx — sizes the back control to 44 points and gives the title pressable an asymmetric hit slop.

The PR review screen now clears the Android bottom system navigation or taskbar inset across its Overview, Discussion, and Files tabs and their form footers. List footers, floating actions, empty and error states, and the form-sheet footer add the system bottom inset, so the last control never sits under the system bar.

Files
  • apps/mobile/src/lib/form-sheet.ts — computes the Android top inset only on Android for the full-sheet detent.
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list-loading.tsx — adds bottom clearance to the first-page skeleton.
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list.tsx — adds bottom clearance to the reconnect and retryable first-page states.
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-navigator.tsx — applies the inset-aware list content style.
  • apps/mobile/src/components/pr-review/diff/pr-diff-floating-actions.tsx — includes the Android bottom inset in the bar's padding.
  • apps/mobile/src/components/pr-review/diff/pr-diff-hunk-rows.tsx — adds bottom clearance to the tab-state and empty-files views.
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.tsx — adds bottom clearance to the list footer.
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.tsx — adds the Android bottom inset to the form-sheet footer.
  • apps/mobile/src/components/pr-review/pr-review-discussion-tab.tsx — adds bottom clearance to the loading, empty, and error states.
  • apps/mobile/src/components/pr-review/pr-review-screen.tsx — switches the Overview tab to the detail-screen scroll view that owns the bottom inset.

Two new seed fixtures support the E2E flows. The frequent-repository-order fixture records one deterministic Cloud Agent repository use so the ordering E2E can assert the used repository moves ahead, and the mobile-sheet fixture seeds four read-only transcripts through the local session-ingest worker for the sheet hit-area E2E.

Files
  • dev/seed/app/frequent-repository-order.ts — new seed topic with before, used, and cleanup states.
  • dev/seed/lib/frequent-repository-order-fixture.ts — fixture helpers that read the user's GitHub integration and insert or delete the fixture session row.
  • dev/seed/app/mobile-sheet-fixtures.ts — new seed topic that resets and ingests four deterministic transcripts.
  • dev/seed/lib/mobile-sheet-fixtures.ts — pure fixture builders and status parsing with no side effects.

Tests: 44 test files changed (3 deleted, 13 added, 28 modified).
Generated: none.


Verification

The Android and iOS rounds ran 10 cases across four verification rounds; all 10 passed.

Case What it proves Platform Result
a1 The Back button and the session title are separate tap targets that each run only their own action. Android passed
a2 The repository picker lists the used repository first, keeps that order under search, and explains an empty search. Android passed
a3 Continue shows a cloning state, then opens a clone with the copied transcript and no added user turn, and leaves the source session unchanged. Android passed
a4 Continue on an unsupported repository session shows Connect repository guidance and keeps the source session on screen. Android passed
a5 An empty session renders without a Continue control. Android passed
b1 Android sheets open full height, Done stays below the status bar, and long content scrolls inside the sheet. Android passed, rerun on the full-height sheet
b2 Android Back dismisses the subagent sheet with no white frame and returns to the session. Android passed, rerun three times
b3 On a content-rich PR, the Overview, Files, and Discussion content and the review form sheet all clear the bottom system inset. Android passed
b4 On an empty PR, the empty-state chrome on all three tabs clears the bottom system inset. Android passed
c1 iOS sheets keep the native pageSheet geometry and show no Android surface. iOS passed

The rounds reproduced no defect on the unfixed build, so none remains.

Cases b1 and b2 were rerun on the full-height Android sheet; both passed. The b1 rerun drove the same five sheets (part detail, file preview, context usage, message details, child session) and asserted for each that the surface spans the whole window, that Done sits below the 136-pixel status bar, and that the removed scrim is absent. The context sheet scrolled its long content with the header fixed. The b2 rerun confirmed Back dismisses the child sheet and returns the session; no frame of the recording shows a white flash.

The b2 rerun then removed the Android dismiss layer and ran three more recorded dismissals. Every frame of all four recordings was measured: the blank frames stay at the cream background (mean blue 242), and no frame reaches white (mean blue 252 or more). The layer was dead weight on the opaque sheet, so it is deleted.

Recording: /Users/igor/Projects/.scratch/kilo-workflow-consolidated-kilo-workflow-2ade.sOVgsu/e2e-android-b-KBS5Nv/b2-dismiss.mp4 shows the Android Back dismissal of the subagent sheet.

Visual Changes

Android session screen sheets (part detail, file preview, context, message details, child session). Each sheet opens full height and starts below the system status bar. In the picture, the Context usage sheet fills the window, the clock and the status icons stay visible above it, and Done sits at its top right.

b1-android-full-height-sheet.png

Android subagent sheet dismiss. Back dismisses the child sheet without a white frame and returns the session screen. The picture is the last recorded frame after Back: the transcript and Continue are on screen, with no white area.

b2-src-22.png

Android PR review form sheet on a content-rich PR. The Submit review form sheet now keeps its footer controls above the bottom system navigation bar. In the picture, the Submit review and Cancel controls sit mid-screen, far above the bottom gesture bar. The handoff names these candidates for the tab insets, but both candidates show the form sheet; no picture shows the Overview, Files, or Discussion tab lists.

b3-form-sheet.png

Android PR empty state. The empty PR Overview content now ends above the bottom system navigation bar. In the picture, the +10 / -2 head footer row sits above the bottom bar; a dev-only toast at the bottom does not cover it.

01-b4-1-overview-empty.png

iOS session screen sheets. iOS sheets keep the native pageSheet geometry: a rounded-top sheet below the status bar. In the picture, the Context usage sheet starts with rounded corners below the status bar, and Done sits at its top right.

02-c1-context-sheet-open.png

Reviewer Notes

No human steps required.

Notes: none.

iscekic added 30 commits August 22, 2026 08:55
…agent create

Add an optional cloneFromKiloSessionId to the create schema and change the RPC method to return a discriminated ready/in_progress/rejected result. Old callers can ignore the returned value.
Add cloneFromKiloSessionId to PrepareSessionInput, map it into the grouped SessionCreateRequest clone object, and persist it in grouped session metadata via registerSession. Old inputs without the field keep the empty-session bootstrap.
Add a bounded source export method and destination stage/inspect/finalize/reset methods to SessionIngestDO. Export reads only session, message, part, and session_diff rows in (ingested_at, id) order with a stable digest; reset wipes SQLite before the R2 delete await.
Add cloneFromKiloSessionId to basePrepareSessionNextSchema; both personal and organization prepare forward it unchanged to the worker.
Add a bounded resumable clone helper that copies source ingest rows to the destination DO with identity rewriting and destination-owned R2 bodies. Wire it into createSessionForCloudAgent with the typed result, detect destination claims before any write, and add matching-source delete for clone rollback.
…ership

Forward cloneFromKiloSessionId into the session-ingest create call and map
its typed result: rejected to BAD_REQUEST session_clone_failed, a missing
acknowledgement to SERVICE_UNAVAILABLE session_clone_unavailable, and
in_progress to CONFLICT creation_in_progress. Route retryable and unknown
clone outcomes through the reconcile-pending ledger hook, persist sandbox
allocation progress before the ingest call, include the clone source in the
create-intent fingerprint and registration command, and make rollback
allocation-aware with a matching-source delete.
Extract the post-allocation registration and admission effect into a
helper, rebuild a clone allocation from ledger progress with the stored
initial message id, resume a clone with its stored ids in reconcile step
(b) when the ownership row is absent, and tombstone destination ids after
an explicit rejection so the next intent never resumes them.
Prefer snapshot restore when session metadata carries a clone or a
preparedAt, set requireSnapshot for clones, and reject a missing clone
snapshot with a typed error instead of importing an empty session on both
the worker and wrapper sides. Non-clone sessions keep the 404 fallback.
Replace the bounded text-seed continuation with a full Cloud Agent clone.
The continue action sends cloneFromKiloSessionId with a fixed continuation
prompt and a fresh initial message id, never drains history, never queries
connected instances, and never writes a share payload. A missing Cloud Agent
destination shows a terminal message. Delete the continuation seed and the
remote continuation builders.
The back Pressable used h-13 w-13 (52 points). The shipped icon-button
geometry is h-11 w-11 (44 points). The mounted test now derives the title
font size from the rendered class and fails when title size plus top and
bottom slop drops below 44 points.
Overview uses DetailScreenScrollView. Discussion and Files state chrome
use useDetailScreenBottomPadding. Files floating actions and form-sheet
footers add the system inset directly. The file navigator list carries the
Android inset in its bottom content padding. Mounted tests cover zero and
nonzero insets across the named states.
iOS keeps the native pageSheet Modal. Android gets a transparent Modal with
a dimmed blocking scrim and a bottom-aligned half-height surface. Part
detail, session context, and message details migrate to the wrapper.
File part preview, attachment text preview, and the child session sheet
render through SessionPageSheet, keeping their loading, retry, terminal,
and empty states.
Add a subagent-only bg-background layer that stays mounted while the
sheet identity is held and visible is false, so the Android slide-out
dismissal never reveals session content as a white frame. iOS keeps its
native pageSheet dismissal. Extract the layer into a focused component
and cover its lifetime with a mounted test.
Make PrepareSessionInput a discriminated union: the clone-only variant
requires the source session, autoInitiate true, and an operationKey, and
forbids prompt, initialPayload, and initialMessageId. prepareInputTo
SessionCreateRequest omits initialTurn for a clone, the fingerprint
hashes the omitted turn as { type: 'none' }, and clone-only creation
registers the session without admitting an initial message.
Make basePrepareSessionNextSchema and the web PrepareSessionInput type two-variant unions. The clone-only variant requires cloneFromKiloSessionId, autoInitiate true, and operationKey, and forbids prompt, initialPayload, and initialMessageId.
@iscekic iscekic self-assigned this Aug 22, 2026
@kilo-code-bot

kilo-code-bot Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Files Reviewed (6 files)
  • apps/mobile/src/components/agents/child-session-dismiss-layer.mounted.test.tsx
  • apps/mobile/src/components/agents/child-session-dismiss-layer.tsx
  • apps/mobile/src/components/agents/child-session-sheet-state.test.ts
  • apps/mobile/src/components/agents/child-session-sheet-state.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/lib/form-sheet.ts
Previous Review Summaries (5 snapshots, latest commit 3b3d771)

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

Previous review (commit 3b3d771)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (5 files)
  • apps/mobile/src/components/agents/attachment-preview-strip.mounted.test.tsx
  • apps/mobile/src/components/agents/child-session-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/file-part-renderer.mounted.test.tsx
  • apps/mobile/src/components/agents/session-page-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/session-page-sheet.tsx

Previous review (commit 62c6b6d)

Status: No Issues Found | Recommendation: Merge

Files Reviewed (2 files)
  • services/cloud-agent-next/src/session/session-prepare.test.ts
  • services/cloud-agent-next/src/session/session-registration.ts

Previous review (commit 861925f)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
services/cloud-agent-next/src/session/session-registration.ts 959 withDORetry around non-idempotent registerSession can roll back a clone that already registered
services/cloud-agent-next/src/session/session-registration.ts 1590 Clone reconcile never settles a successful clone-only create when ownership and metadata already exist
Files Reviewed (11 files)
  • apps/mobile/src/app/(app)/_layout.tsx
  • apps/mobile/src/app/(app)/agent-chat/continue-picker.tsx
  • apps/mobile/src/components/agents/continuation-seed.ts
  • apps/mobile/src/components/agents/continue-picker-bridge.ts
  • apps/mobile/src/components/agents/continue-picker-rows.test.ts
  • apps/mobile/src/components/agents/continue-picker-rows.ts
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-navigator.tsx
  • apps/mobile/src/lib/form-sheet.test.ts
  • apps/mobile/src/lib/form-sheet.ts
  • apps/mobile/src/lib/pr-review/diff/navigator-list-content-style.ts
  • services/cloud-agent-next/src/session/session-registration.ts - 2 issues

Fix these issues in Kilo Cloud

Previous review (commit 8bb7ab6)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
services/cloud-agent-next/src/session/session-registration.ts 959 withDORetry around non-idempotent registerSession can roll back a clone that already registered
services/cloud-agent-next/src/session/session-registration.ts 1590 Clone reconcile never settles a successful clone-only create when ownership and metadata already exist
Files Reviewed (94 files)
  • apps/mobile/src/app/(app)/agent-chat/__tests__/continuation-seed-draft-proof.mounted.test.tsx
  • apps/mobile/src/components/agents/attachment-preview-strip.mounted.test.tsx
  • apps/mobile/src/components/agents/attachment-preview-strip.tsx
  • apps/mobile/src/components/agents/child-session-dismiss-layer.mounted.test.tsx
  • apps/mobile/src/components/agents/child-session-dismiss-layer.tsx
  • apps/mobile/src/components/agents/child-session-sheet-state.test.ts
  • apps/mobile/src/components/agents/child-session-sheet-state.ts
  • apps/mobile/src/components/agents/child-session-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/child-session-sheet.tsx
  • apps/mobile/src/components/agents/continuation-seed.test.ts
  • apps/mobile/src/components/agents/continuation-seed.ts
  • apps/mobile/src/components/agents/continue-picker-bridge.ts
  • apps/mobile/src/components/agents/continue-remote-spawn-input.test.ts
  • apps/mobile/src/components/agents/file-part-renderer.mounted.test.tsx
  • apps/mobile/src/components/agents/file-part-renderer.tsx
  • apps/mobile/src/components/agents/message-details-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/message-details-sheet.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts
  • apps/mobile/src/components/agents/part-detail-sheet-host.mounted.test.tsx
  • apps/mobile/src/components/agents/part-detail-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/part-detail-sheet.tsx
  • apps/mobile/src/components/agents/session-context-sheet.tsx
  • apps/mobile/src/components/agents/session-detail-content-helpers.test.ts
  • apps/mobile/src/components/agents/session-detail-content-helpers.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/session-page-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/session-page-sheet.tsx
  • apps/mobile/src/components/agents/use-continue-cloud-create.ts
  • apps/mobile/src/components/agents/use-continue-session.test.ts
  • apps/mobile/src/components/agents/use-continue-session.ts
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list-loading.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list-loading.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-navigator.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-navigator.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-floating-actions.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-floating-actions.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-hunk-rows.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-hunk-rows.tsx
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.test.tsx
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.tsx
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.test.tsx
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.tsx
  • apps/mobile/src/components/pr-review/pr-review-discussion-tab.test.tsx
  • apps/mobile/src/components/pr-review/pr-review-discussion-tab.tsx
  • apps/mobile/src/components/pr-review/pr-review-screen.test.tsx
  • apps/mobile/src/components/pr-review/pr-review-screen.tsx
  • apps/mobile/src/components/screen-header.mounted.test.tsx
  • apps/mobile/src/components/screen-header.tsx
  • apps/mobile/src/lib/form-sheet.test.ts
  • apps/mobile/src/lib/form-sheet.ts
  • apps/mobile/src/lib/pr-review/diff/navigator-list-content-style.ts
  • apps/mobile/src/lib/repo-picker-filter.test.ts
  • apps/mobile/src/lib/use-new-session-repos.ts
  • apps/web/src/lib/cloud-agent-next/cloud-agent-client.ts
  • apps/web/src/lib/cloud-agent/order-repositories.test.ts
  • apps/web/src/lib/cloud-agent/order-repositories.ts
  • apps/web/src/routers/cloud-agent-next-router.test.ts
  • apps/web/src/routers/cloud-agent-next-router.ts
  • apps/web/src/routers/cloud-agent-next-schemas.test.ts
  • apps/web/src/routers/cloud-agent-next-schemas.ts
  • apps/web/src/routers/organizations/organization-cloud-agent-next-router.test.ts
  • apps/web/src/routers/organizations/organization-cloud-agent-next-router.ts
  • dev/seed/app/frequent-repository-order.ts
  • dev/seed/app/mobile-sheet-fixtures.ts
  • dev/seed/lib/frequent-repository-order-fixture.test.ts
  • dev/seed/lib/frequent-repository-order-fixture.ts
  • dev/seed/lib/mobile-sheet-fixtures.test.ts
  • dev/seed/lib/mobile-sheet-fixtures.ts
  • packages/session-ingest-contracts/src/rpc-contract.ts
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts
  • services/cloud-agent-next/src/persistence/session-metadata.test.ts
  • services/cloud-agent-next/src/persistence/session-metadata.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.test.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.ts
  • services/cloud-agent-next/src/router/schemas.test.ts
  • services/cloud-agent-next/src/router/schemas.ts
  • services/cloud-agent-next/src/session-prepare.test.ts
  • services/cloud-agent-next/src/session-service.test.ts
  • services/cloud-agent-next/src/session-service.ts
  • services/cloud-agent-next/src/session/session-prepare.test.ts
  • services/cloud-agent-next/src/session/session-registration.ts - 2 issues
  • services/cloud-agent-next/src/session/session-requests.ts
  • services/cloud-agent-next/src/shared/wrapper-bootstrap.ts
  • services/cloud-agent-next/wrapper/src/session-bootstrap.test.ts
  • services/cloud-agent-next/wrapper/src/session-bootstrap.ts
  • services/session-ingest/src/clone/session-clone.ts
  • services/session-ingest/src/dos/SessionIngestDO.test.ts
  • services/session-ingest/src/dos/SessionIngestDO.ts
  • services/session-ingest/src/ingest/metadata.test.ts
  • services/session-ingest/src/ingest/metadata.ts
  • services/session-ingest/src/session-ingest-rpc.test.ts
  • services/session-ingest/src/session-ingest-rpc.ts

Fix these issues in Kilo Cloud

Previous review (commit e6c4e63)

Status: 2 Issues Found | Recommendation: Address before merge

Overview

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

WARNING

File Line Issue
services/cloud-agent-next/src/session/session-registration.ts 959 withDORetry around non-idempotent registerSession can roll back a clone that already registered
services/cloud-agent-next/src/session/session-registration.ts 1590 Clone reconcile never settles a successful clone-only create when ownership and metadata already exist
Files Reviewed (94 files)
  • apps/mobile/src/app/(app)/agent-chat/__tests__/continuation-seed-draft-proof.mounted.test.tsx
  • apps/mobile/src/components/agents/attachment-preview-strip.mounted.test.tsx
  • apps/mobile/src/components/agents/attachment-preview-strip.tsx
  • apps/mobile/src/components/agents/child-session-dismiss-layer.mounted.test.tsx
  • apps/mobile/src/components/agents/child-session-dismiss-layer.tsx
  • apps/mobile/src/components/agents/child-session-sheet-state.test.ts
  • apps/mobile/src/components/agents/child-session-sheet-state.ts
  • apps/mobile/src/components/agents/child-session-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/child-session-sheet.tsx
  • apps/mobile/src/components/agents/continuation-seed.test.ts
  • apps/mobile/src/components/agents/continuation-seed.ts
  • apps/mobile/src/components/agents/continue-picker-bridge.ts
  • apps/mobile/src/components/agents/continue-remote-spawn-input.test.ts
  • apps/mobile/src/components/agents/file-part-renderer.mounted.test.tsx
  • apps/mobile/src/components/agents/file-part-renderer.tsx
  • apps/mobile/src/components/agents/message-details-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/message-details-sheet.tsx
  • apps/mobile/src/components/agents/new-session-configure-form.test.ts
  • apps/mobile/src/components/agents/part-detail-sheet-host.mounted.test.tsx
  • apps/mobile/src/components/agents/part-detail-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/part-detail-sheet.tsx
  • apps/mobile/src/components/agents/session-context-sheet.tsx
  • apps/mobile/src/components/agents/session-detail-content-helpers.test.ts
  • apps/mobile/src/components/agents/session-detail-content-helpers.ts
  • apps/mobile/src/components/agents/session-detail-content.tsx
  • apps/mobile/src/components/agents/session-page-sheet.mounted.test.tsx
  • apps/mobile/src/components/agents/session-page-sheet.tsx
  • apps/mobile/src/components/agents/use-continue-cloud-create.ts
  • apps/mobile/src/components/agents/use-continue-session.test.ts
  • apps/mobile/src/components/agents/use-continue-session.ts
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list-loading.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list-loading.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-list.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-navigator.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-file-navigator.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-floating-actions.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-floating-actions.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-hunk-rows.test.tsx
  • apps/mobile/src/components/pr-review/diff/pr-diff-hunk-rows.tsx
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.test.tsx
  • apps/mobile/src/components/pr-review/discussion/pr-review-discussion-list.tsx
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.test.tsx
  • apps/mobile/src/components/pr-review/pr-form-sheet-chrome.tsx
  • apps/mobile/src/components/pr-review/pr-review-discussion-tab.test.tsx
  • apps/mobile/src/components/pr-review/pr-review-discussion-tab.tsx
  • apps/mobile/src/components/pr-review/pr-review-screen.test.tsx
  • apps/mobile/src/components/pr-review/pr-review-screen.tsx
  • apps/mobile/src/components/screen-header.mounted.test.tsx
  • apps/mobile/src/components/screen-header.tsx
  • apps/mobile/src/lib/form-sheet.test.ts
  • apps/mobile/src/lib/form-sheet.ts
  • apps/mobile/src/lib/pr-review/diff/navigator-list-content-style.ts
  • apps/mobile/src/lib/repo-picker-filter.test.ts
  • apps/mobile/src/lib/use-new-session-repos.ts
  • apps/web/src/lib/cloud-agent-next/cloud-agent-client.ts
  • apps/web/src/lib/cloud-agent/order-repositories.test.ts
  • apps/web/src/lib/cloud-agent/order-repositories.ts
  • apps/web/src/routers/cloud-agent-next-router.test.ts
  • apps/web/src/routers/cloud-agent-next-router.ts
  • apps/web/src/routers/cloud-agent-next-schemas.test.ts
  • apps/web/src/routers/cloud-agent-next-schemas.ts
  • apps/web/src/routers/organizations/organization-cloud-agent-next-router.test.ts
  • apps/web/src/routers/organizations/organization-cloud-agent-next-router.ts
  • dev/seed/app/frequent-repository-order.ts
  • dev/seed/app/mobile-sheet-fixtures.ts
  • dev/seed/lib/frequent-repository-order-fixture.test.ts
  • dev/seed/lib/frequent-repository-order-fixture.ts
  • dev/seed/lib/mobile-sheet-fixtures.test.ts
  • dev/seed/lib/mobile-sheet-fixtures.ts
  • packages/session-ingest-contracts/src/rpc-contract.ts
  • services/cloud-agent-next/src/persistence/CloudAgentSession.ts
  • services/cloud-agent-next/src/persistence/session-metadata.test.ts
  • services/cloud-agent-next/src/persistence/session-metadata.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.test.ts
  • services/cloud-agent-next/src/router/handlers/session-prepare.ts
  • services/cloud-agent-next/src/router/schemas.test.ts
  • services/cloud-agent-next/src/router/schemas.ts
  • services/cloud-agent-next/src/session-prepare.test.ts
  • services/cloud-agent-next/src/session-service.test.ts
  • services/cloud-agent-next/src/session-service.ts
  • services/cloud-agent-next/src/session/session-prepare.test.ts
  • services/cloud-agent-next/src/session/session-registration.ts - 2 issues
  • services/cloud-agent-next/src/session/session-requests.ts
  • services/cloud-agent-next/src/shared/wrapper-bootstrap.ts
  • services/cloud-agent-next/wrapper/src/session-bootstrap.test.ts
  • services/cloud-agent-next/wrapper/src/session-bootstrap.ts
  • services/session-ingest/src/clone/session-clone.ts
  • services/session-ingest/src/dos/SessionIngestDO.test.ts
  • services/session-ingest/src/dos/SessionIngestDO.ts
  • services/session-ingest/src/ingest/metadata.test.ts
  • services/session-ingest/src/ingest/metadata.ts
  • services/session-ingest/src/session-ingest-rpc.test.ts
  • services/session-ingest/src/session-ingest-rpc.ts

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 46.6K · Output: 4.4K · Cached: 271.5K

Review guidance: REVIEW.md from base branch main

@iscekic iscekic added the human-ready The PR is ready for human review. label Aug 22, 2026
…tus bar

Replace the half-height scrim sheet with an opaque full-window Modal. The
surface pads the top safe-area inset, so the content clears the system
status bar. iOS keeps the native pageSheet.
The next line already discards the Android detent on iOS, so the guard
changed nothing.
The layer covered the session while the transparent Android Modal slid
out. The Modal is now opaque and full height, so the cover is dead
weight. Three recorded Back dismissals show no white frame without it.
@iscekic
iscekic enabled auto-merge (squash) August 22, 2026 19:51

// Delete the captured R2 objects last, after the SQLite wipe is complete.
if (r2Keys.length > 0) {
await this.env.SESSION_INGEST_R2.delete(r2Keys);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot: wipeStorage() (shared by clear() and resetCloneStage(), used to roll back a failed clone) calls this.env.SESSION_INGEST_R2.delete(r2Keys) with no try/catch, unlike the sibling cleanup path deleteDestinationR2Bodies in session-clone.ts which deliberately swallows R2 delete errors. If this R2 delete throws (transient R2 error), it propagates out of resetCloneStage()/clear() and turns what should be a clean typed rejected clone result (or a normal destination reset) into an unhandled exception at the RPC boundary, even though the SQLite wipe has already committed by that point.

Suggested fix: Wrap the R2 delete in wipeStorage() in a try/catch that logs and swallows the error (mirroring deleteDestinationR2Bodies), so a transient R2 failure during rollback/reset never surfaces as an uncaught exception; the SQLite state is already consistent at that point regardless.

});
}

// `Session already registered` means the registration already committed on a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bot: A 'Session already registered' rejection from the per-session DO is treated as idempotent success for both clone and non-clone create paths, based solely on the error string with no request-identity correlation (e.g. matching operationKey) confirming the already-registered state belongs to this caller's own retried attempt. This is scoped fairly tightly because the DO name is derived from allocation.cloudAgentSessionId, which is unique per create attempt, but the comment's justification ("the DO method is not idempotent, so the retry returns this rejection") is asserted rather than verified against an explicit request-identity check.

Suggested fix: Consider confirming (or adding a code comment cross-referencing) that cloudAgentSessionId allocation guarantees this DO name can only ever be hit by a retry of the same logical create request, so a future refactor doesn't accidentally let an unrelated conflict be swallowed as success.

@iscekic
iscekic merged commit 479a2d5 into main Aug 23, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

human-ready The PR is ready for human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants