Skip to content

fix(mobile): bind Kilo Chat effects to local access - #5664

Closed
iscekic wants to merge 1 commit into
mobile-context-lock-758a-s3from
mobile-context-lock-758a-s4
Closed

fix(mobile): bind Kilo Chat effects to local access#5664
iscekic wants to merge 1 commit into
mobile-context-lock-758a-s3from
mobile-context-lock-758a-s4

Conversation

@iscekic

@iscekic iscekic commented Aug 28, 2026

Copy link
Copy Markdown
Contributor
  • Signing out or switching accounts stops mobile chat actions that have not been sent. This includes messages, edits, deletions, reactions, typing updates, and conversation changes.
  • When your sign-in changes, late chat results and live updates no longer change the conversations for your new sign-in.
  • After your sign-in changes, delayed file choices, photo selections, and pasted images cannot add attachments or update upload progress for the new account.
  • Delayed read confirmations from your earlier sign-in no longer change unread conversations or the notification count for your current account.
  • While the mobile app is inactive, chat delivery, conversation, and attachment errors do not open new pop-ups.

Summary

KiloChatOperation keeps immutable dispatch admission through queues and unauthorized retries; owner-only publication lets already accepted work settle without renewed foreground access.
KiloChatClientConfig adds optional captureOperationAdmission and canPublish callbacks, preserving existing callers; reads, typing cleanup, and status refresh require ownership only.
KiloChatClient.captureOperation rejects foreign operations, canStartOperation gates announcements, and dispose aborts requests, clears queues, and removes subscriptions.

Files
  • packages/kilo-chat/src/client.ts — Source, modified, 280 lines changed; guards token waits, response decoding, events, and mutation dispatch while preserving per-conversation send order.
  • packages/kilo-chat/src/types.ts — Source, modified, 12 lines changed; adds the readonly operation type and optional constructor callbacks.
  • packages/kilo-chat/test/client.test.ts — Test, modified, 255 lines changed; extends the shared client tests.

MobileKiloChatConfig makes both guards mandatory in createMobileKiloChatClients, keeping connections, callbacks, and recovery tied to one AuthenticatedOwner.
KiloChatProvider remounts on ownership changes and replaces disposed clients during effect replay, rather than restoring old queues.
KiloChatTokenErrorState.retry checks admission at invocation; denial leaves the existing error and does not schedule that retry after access returns.

Files
  • apps/mobile/src/components/kilo-chat/kilo-chat-provider.tsx — Source, modified, 267 lines changed; scopes clients and token identity by authentication epoch, generation, and user; guards subscriptions, reconnects, resyncs, activation, and teardown.
  • apps/mobile/src/components/kilo-chat/kilo-chat-admission.test.ts — Test, added, 387 lines changed; adds mobile admission tests.
  • apps/mobile/src/components/kilo-chat/kilo-chat-provider.mounted.test.tsx — Test, modified, 783 lines changed; extends the mounted provider tests.

TokenCache now includes AuthenticatedOwner; clearKiloChatTokenCache invalidates older pending fills, and cache reuse or request sharing requires matching credentials and ownership.
TokenResponseListener receives the owner, while kiloChat.getToken carries localAccessOwner and rejects stale or mismatched user responses.
TokenResponseGetter accepts an optional dispatch check; useKiloChatTokenGetter and useKiloChatTokenResponseGetter accept optional owners and capture the current owner when omitted.

Files
  • apps/mobile/src/components/kilo-chat/hooks/use-kilo-chat-token.ts — Source, modified, 143 lines changed; rechecks ownership around waits and listeners, matches authentication generations, and retains the early-expiry rule.
  • apps/mobile/src/components/kilo-chat/hooks/use-kilo-chat-token.local-access.test.ts — Test, added, 134 lines changed; adds token access tests.

useKiloChatMutation and KiloChatMutationOptions capture variables, callbacks, and admission before React Query queues work, so rerenders cannot redirect settlement.
mutate and mutateAsync retain stable identities, accept an optional third KiloChatOperation, and preserve existing call forms and rejected variables.
canPublish gates cache settlement, original admission gates per-call success/error callbacks, and onSettled can release pending controls for the same locked owner.

Files
  • packages/kilo-chat-hooks/src/use-messages.ts — Source, modified, 261 lines changed; guards sends, edits, deletions, reactions, redelivery, action execution, and message reads. It suppresses blocked notices and reuses the action-resolution helper.
  • packages/kilo-chat-hooks/src/use-conversations.ts — Source, modified, 40 lines changed; guards creation, rename, leave, and mark-read; keeps reconciliation and suppresses blocked error notices.
  • packages/kilo-chat-hooks/src/use-messages.test.ts — Test, modified, 270 lines changed; extends the message hook tests.
  • packages/kilo-chat-hooks/src/use-conversations.test.ts — Test, modified, 144 lines changed; extends the conversation hook tests.

PerformUpload, AddFileInput.operation, and UseAttachmentQueueOptions.captureOperation carry captured admission from attachment selection through initialization and final upload dispatch, without renewing permission after waits.
mobilePerformUpload requires an operation; shared callers retain the optional form, and owner checks prevent stale progress, completion, or failure updates.
UseAttachmentQueueResult.retryFile accepts an optional operation; explicit retries validate supplied admission or capture a new operation while retaining local bytes.

Files
  • packages/kilo-chat-hooks/src/use-attachment-queue.ts — Source, modified, 203 lines changed; pins upload ownership and validates initialization, final dispatch, and retries with cached upload links. It guards progress and settlement while retaining local bytes.
  • apps/mobile/src/components/kilo-chat/message-input-attachment-queue.tsx — Source, modified, 86 lines changed; captures admission before camera, library, file, or clipboard preparation; carries it through selection and gates attachment error notices.
  • apps/mobile/src/components/kilo-chat/mobile-perform-upload.ts — Source, modified, 15 lines changed; rejects missing admission before calling the shared uploader.
  • packages/kilo-chat-hooks/src/use-attachment-queue.test.ts — Test, modified, 188 lines changed; extends the attachment queue tests.
  • packages/kilo-chat-hooks/src/xhr-perform-upload.test.ts — Test, modified, 29 lines changed; extends the shared upload adapter tests.
  • packages/kilo-chat/test/client.attachments.test.ts — Test, modified, 47 lines changed; extends the attachment request tests.

useConversationMarkRead keeps each scheduled attempt's original KiloChatOperation and callback, cancelling retries when access, ownership, focus, or the message marker changes.
useMarkRead adds an optional operation argument; MarkReadInput preserves that operation, the user, and the inner mutation before the outer queue waits.
Badge updates, native counts, diagnostics, and invalidation require the original owner; accepted responses can settle without foreground access, with existing freshness checks intact.

Files
  • apps/mobile/src/components/kilo-chat/hooks/use-conversation-mark-read.ts — Source, modified, 113 lines changed; retains the scheduled retry closure and admission; cancels invalid timers and removes listeners on unmount.
  • apps/mobile/src/components/kilo-chat/hooks/use-mark-read.ts — Source, modified, 96 lines changed; captures the user and inner mutation before queuing; guards badge effects, diagnostics, invalidation, and returned results.

Tests: 9 files: 2 added, 7 modified; 2,237 changed lines across client.test.ts, kilo-chat-admission.test.ts, kilo-chat-provider.mounted.test.tsx, use-kilo-chat-token.local-access.test.ts, use-messages.test.ts, use-conversations.test.ts, use-attachment-queue.test.ts, xhr-perform-upload.test.ts, and client.attachments.test.ts.
Generated: 0 files.


Visual Changes

Visual Changes: N/A

Verification

  • No manual runtime verification ran for this level. Full iOS and Android verification runs on the final stack level.
  • No end-to-end (E2E) report accompanies the handoff.

Reviewer Notes

  • Scope: level 4 only, from mobile-context-lock-758a-s3 to mobile-context-lock-758a-s4.
  • Repository: Kilo-Org/cloud; worktree: /Users/igor/Projects/.worktrees/mobile-context-lock-758a.
  • Size: 20 changed files, with 3,081 insertions and 672 deletions. File sizes count added and removed lines.
  • Automated evidence: the handoff reports that 137 targeted tests and seven new mounted regressions passed. These are automated checks, not manual runtime evidence.
  • This level does not establish device proof or integrated tool-bridge protection.
  • The section uses eight levels; levels 6–8 remain unfinished.

Human steps

  • before merge: No required human setup step.
  • after merge, for an existing mobile checkout: Refresh the copied hooks with pnpm install --filter kilo-app... from the repository root.
  • after merge, for an existing mobile checkout: Clear the Metro cache with rm -rf "$TMPDIR/metro-cache" "$TMPDIR"/metro-file-map-*.
  • after merge, for an existing mobile checkout: Restart Metro through the repository dev runner.
  • after merge, for an existing mobile checkout: Force-quit the app.

Notes

This level adds Kilo Chat admission and ownership boundaries without exposing biometric controls. Full iOS and Android verification runs on the final stack level.

Runtime verification remains bot-e2e, not human delegation.

Stacked PRs — merge bottom to top. Each level shows only its own diff.

Runtime verification (E2E, user advocacy, simplify) runs on the tip PR over every level.
Every level keeps its own checks, its own bot review, and its own threads; each one is answered on its own PR.
Each level is its own deliverable: it builds and passes its own checks alone.
A finding on a level is repaired on that level, then carried upward with stack.sh forward.

  1. mobile-context-lock-758afeat(mobile): add account-owned local access state #5642
  2. mobile-context-lock-758a-s2fix(mobile): bind restored context and drafts to account scope #5651
  3. mobile-context-lock-758a-s3fix(mobile): enforce local access at final transport dispatch #5658
  4. mobile-context-lock-758a-s4fix(mobile): bind Kilo Chat effects to local access #5664 ← this PR
  5. mobile-context-lock-758a-s5feat(mobile): protect native privacy and accessibility boundaries #5683 (tip)

} catch {
toast.error(buildAttachmentUnreadableToast(attachment.filename));
if (client.canStartOperation()) {
toast.error(buildAttachmentUnreadableToast(attachment.filename));

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.

WARNING: Stale admission denials are toasted as unreadable files after unlock

assertDispatch() failures in this loop are caught together with materialize errors. After lock/unlock, canStartOperation() succeeds, so a delayed multi-select continuation toasts buildAttachmentUnreadableToast instead of staying silent. Treat LocalAccessDeniedError (or getLocalAccessDenial) as a silent drop.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

);
if (client.canStartOperation()) {
toast.error(
error instanceof Error ? error.message : i18n.t('chat.attachment.attachFailed')

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.

WARNING: Delayed picker admission failures surface internal error messages

A camera/library/file return hits addSelectedAttachments's assertDispatch(). After unlock, canStartOperation() is true, so LocalAccessDeniedError is toasted as error.message (Local access denied: stale) instead of a silent drop. Gate on the denial type, not whether a new operation can start.


Reply with @kilocode-bot fix it to have Kilo Code address this issue.

@kilo-code-bot

kilo-code-bot Bot commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

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
apps/mobile/src/components/kilo-chat/message-input-attachment-queue.tsx 92 Stale admission denials toasted as unreadable files after unlock
apps/mobile/src/components/kilo-chat/message-input-attachment-queue.tsx 109 Delayed picker admission failures surface internal error messages
Files Reviewed (20 files)
  • apps/mobile/src/components/kilo-chat/hooks/use-conversation-mark-read.ts
  • apps/mobile/src/components/kilo-chat/hooks/use-kilo-chat-token.local-access.test.ts
  • apps/mobile/src/components/kilo-chat/hooks/use-kilo-chat-token.ts
  • apps/mobile/src/components/kilo-chat/hooks/use-mark-read.ts
  • apps/mobile/src/components/kilo-chat/kilo-chat-admission.test.ts
  • apps/mobile/src/components/kilo-chat/kilo-chat-provider.mounted.test.tsx
  • apps/mobile/src/components/kilo-chat/kilo-chat-provider.tsx
  • apps/mobile/src/components/kilo-chat/message-input-attachment-queue.tsx - 2 issues
  • apps/mobile/src/components/kilo-chat/mobile-perform-upload.ts
  • packages/kilo-chat-hooks/src/use-attachment-queue.test.ts
  • packages/kilo-chat-hooks/src/use-attachment-queue.ts
  • packages/kilo-chat-hooks/src/use-conversations.test.ts
  • packages/kilo-chat-hooks/src/use-conversations.ts
  • packages/kilo-chat-hooks/src/use-messages.test.ts
  • packages/kilo-chat-hooks/src/use-messages.ts
  • packages/kilo-chat-hooks/src/xhr-perform-upload.test.ts
  • packages/kilo-chat/src/client.ts
  • packages/kilo-chat/src/types.ts
  • packages/kilo-chat/test/client.attachments.test.ts
  • packages/kilo-chat/test/client.test.ts

Fix these issues in Kilo Cloud


Reviewed by grok-4.6 · Input: 134.3K · Output: 27.3K · Cached: 1.3M

Review guidance: REVIEW.md from base branch mobile-context-lock-758a-s3

@iscekic

iscekic commented Aug 29, 2026

Copy link
Copy Markdown
Contributor Author

Retired. The owner cancelled this section and restarted the work with a tighter brief. The biometric gate scope grew into a full native-action admission audit; the replacement covers initial app unlock only.

@iscekic iscekic closed this Aug 29, 2026
@iscekic
iscekic deleted the mobile-context-lock-758a-s4 branch August 29, 2026 10:39
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