Skip to content

fix(mobile): keep one organization selection value per account - #8564

Open
iscekic wants to merge 11 commits into
mainfrom
drain/organization-selection-single-value
Open

iscekic wants to merge 11 commits into
mainfrom
drain/organization-selection-single-value

Conversation

@iscekic

@iscekic iscekic commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

Evidence

Evidence: demonstrated — on the Android emulator against the local dev stack, a seeded non-production account with two organization memberships switched account scopes repeatedly, the device held exactly one selection entry, the Home header showed the last choice, and the same held through force-stop plus relaunch for both an organization and the Personal scope.

Run at head 015dcd608, with Metro on this VM serving the branch bundle:

  • Stack: local services on this VM (web 3000, Metro 8081). Emulator omp36 at its default 1080x2400 / 420 dpi.
  • Account: seeded local user with two organization memberships, signed in on the device. Optional analytics left off.
  • The account sheet listed Personal and both organizations, with the current one marked selected.
  • Switched to the first organization: the header showed it, and shared_prefs/SecureStore.xml held only the organization entry.
  • Switched scopes back to back (Personal, then the second organization). The header ended on the second organization and the store held only the organization entry.
  • Force-stop plus relaunch: the header restored the second organization, and the account sheet marked it selected.
  • Chose Personal: the header showed Personal and the store held only the Personal entry, with the organization entry removed.
  • Force-stop plus relaunch: the header still showed Personal, and the store was unchanged.
  • Repeated the burst once more: the header ended on the last choice, with one selection entry.

Store assertions read shared_prefs/SecureStore.xml through run-as and compare the selection key names; Expo SecureStore encrypts the values, so the assertion is which of the two entries is present, together with the header before and after relaunch. Screenshots are attached in a comment below.

Tests

  • pnpm --filter kilo-app exec vitest run → 1314 files, 19283 tests passed, 2 skipped.
  • src/lib/organization-context.test.ts covers two cases with storage calls the test holds open: a Personal choice saved while the token rotates, and two selections queued while the token rotates. Both assert the stored pair and the published selection.

Change

Organization selection keeps its established organization-key and Personal-marker format, which the other readers of that key already consume.

Selection saves are ordered and fenced. They run one at a time, check the auth epoch before each of the two metadata writes, and only the newest selection is written, so the stored pair always names the selection the provider publishes. A restore loads the pair after the selection save the queue already holds has settled, and keeps its generation and auth-epoch publication fence.

The proxy recommended reading the pair literally inside the queue; the restore instead awaits the settle signal of the save on that queue and then reads, which keeps the same ordering.

The branch changes only apps/mobile/src/lib/organization-context.tsx and its test.

Production prerequisites

None.

Proxy answers

The owner's proxy gave these answers in the owner's place.

  1. Question: Storage representation for the selection and its Personal marker.
    Answer: Collapse into one stored value.
    Confidence: 0.60 · Precedent: Prefer clean cutovers, update affected consumers, and address behavior across affected surfaces.
  2. Question: Whether the restore reads take part in the selection queue.
    Answer: Read both keys inside the queue.
    Confidence: 0.80 · Precedent: Apply the fix across affected behavior.
  3. Question: What end-to-end proof should the PR carry?
    Answer: Android emulator; selection survives relaunch.
    Confidence: 0.85 · Precedent: Require end-to-end proof on the default Android VM lane.
  4. Question: How should the canceled iOS build check be handled?
    Answer: Do not block readiness on a pending or canceled iOS native build; note the cancellation, retry once after the shared slot frees, and fix the scheduling cause.
    Confidence: 0.70 · Precedent: Pending native checks should not block progress; address the underlying cause.
  5. Question: How should native build requests avoid blocking one another?
    Answer: Use a unique concurrency group per run.
    Confidence: 0.60 · Precedent: Prefer the smallest quality-preserving change; independent requests can occasionally duplicate build work instead of introducing a durable coordinator.
  6. Question: How to proceed when no current-head review object is available but existing remarks are addressed?
    Answer: Proceed with resolved remarks.
    Confidence: 0.72 · Precedent: Ready when prior review remarks are addressed, there are no conflicts, and other required checks pass; pending native build work does not block progress.

Answer 1 and the owner's later review direction differ on the storage representation: the owner asked to keep the established representation, which this change does. Answer 2 asks for the restore reads to be ordered with the pending save; this change orders them by awaiting that save's settle signal rather than by holding the queue slot.

The mobile organization selection is now a single account-scoped
SecureStore value: an organization id, the Personal choice, or nothing
for "not chosen yet". Every reader decodes it through
lib/organization-selection, so the Personal choice is never taken for an
organization id.

Saves run on the shared serialized save queue and re-check their
generation and auth epoch once the queue settles, so the stored value
matches the selection the provider publishes even when two selections
are made in quick succession. A legacy Personal marker is read once for
upgrades, recorded as the selection value, and cleared with the rest of
the account metadata on sign-out.
@iscekic iscekic added drain Work item from the findings drain janitor:trust Janitor finding: trust boundary hardening labels Oct 22, 2026
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Android emulator, dev client against the local stack, signed in with a test account that belongs to two organizations.

  • Account picker: Personal plus both organizations.
  • The second organization selected in the header.
  • The same organization after a relaunch.
  • Personal selected after returning to the Personal scope.
  • Personal after a relaunch.

The unit and mounted suites cover the storage path headlessly as well.

Account picker with Personal and two test organizations

Home header showing the second test organization

Home header showing the second test organization after a relaunch

Home header showing the Personal scope

Home header showing the Personal scope after a relaunch

Comment thread apps/mobile/src/lib/organization-selection.ts Outdated
@kilo-code-bot

kilo-code-bot Bot commented Oct 22, 2026 •

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: No Issues Found | Recommendation: Merge

Executive Summary

The follow-up splits save fencing from restore fencing (saveGeneration) and makes restore() wait for any save that began earlier (savesSettled), so a same-account token rotation no longer cancels an in-flight selection save or publishes a half-written pair; the two new tests exercise exactly those two rotations.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, or lint. The review read the full provider, save-chain.ts, account-metadata-write.ts, auth-epoch.ts, and the auth sign-in/sign-out paths to confirm the epoch is not bumped on token refresh and that deletes complete before credentials publish.

Files Reviewed (2 files)
  • apps/mobile/src/lib/organization-context.tsx
  • apps/mobile/src/lib/organization-context.test.ts
Previous Review Summaries (9 snapshots, latest commit 256b7c0)

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

Previous review (commit 256b7c0)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The ordered, fenced selection save treats a same-account token refresh as a superseding operation, so restore() can cancel an in-flight save and leave an explicit Personal choice unwritten; the CI/workflow commits from the previous head are reverted, so the PR now touches only the organization context and its test.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, or lint. The refresh path is inferred from setToken(outcome.token) in apps/mobile/src/lib/auth/auth-context.tsx:677 and :761 (no bumpAuthEpoch() there) plus the provider's [token, restore] effect.

Overview

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

WARNING

File Line Issue
apps/mobile/src/lib/organization-context.tsx 169 A token refresh re-runs restore(), which bumps generation and cancels a queued/in-flight selection save; the selection reverts to the stored value, and an abort between the two writes deletes the organization key without writing PERSONAL_MARKER, turning an explicit Personal choice into "not chosen yet".
Files Reviewed (2 files)
  • apps/mobile/src/lib/organization-context.tsx - 1 issue
  • apps/mobile/src/lib/organization-context.test.ts

Fix these issues in Kilo Cloud

Previous review (commit 5ccdea9)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change updates only comments and a test name in dev/local/mobile-native-gate.ts and dev/local/mobile-native-gate.test.ts, and the new wording matches the workflow: heavy jobs re-check with --published before building and no longer take a job-level concurrency slot. The prior SUGGESTION about the stale concurrency-slot documentation is resolved.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, lint, or the GitHub workflow. I verified the comment claims against .github/workflows/mobile-native-build.yml:127-131, :194, and :212-220 and the --published handler at dev/local/mobile-native-gate.ts:226-237. The previously raised active threads on apps/mobile/src/lib/organization-context.tsx:183 and the gate --published/promote output warnings remain addressed in current HEAD (organization-context.tsx:169-183 re-checks generation and auth epoch before each write; mobile-native-gate.ts:264-266 emits the promote outputs).

Files Reviewed (2 files)
  • dev/local/mobile-native-gate.ts
  • dev/local/mobile-native-gate.test.ts

Previous review (commit 43161b6)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The selection queue and its per-write generation/epoch fences hold, and the earlier promote/--published workflow warnings are resolved by the merged gate script; the only new issue is stale documentation that still describes the job-level concurrency this PR removes.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, lint, or the GitHub workflow; the concurrency removal, the --published CLI mode, and the promote_* outputs were verified by reading current HEAD, the gate script, and its tests. The prior review's two WARNINGs on the promote jobs and the --published step are resolved: dev/local/mobile-native-gate.ts:225-233 implements the mode and :257-264 emits the promote outputs. The prior regex SUGGESTION on the job conditions is now moot because the conditions are multi-line always() expressions. The two old inline threads on the deleted organization-selection.ts are outdated.

Overview

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

SUGGESTION

File Line Issue
.github/workflows/mobile-native-build.yml 194 The ios/android jobs no longer take a per-hash concurrency slot, but dev/local/mobile-native-gate.ts:18-22, :211-215, and dev/local/mobile-native-gate.test.ts:628 still document the re-check as waiting on a concurrency slot.
Files Reviewed (4 files)
  • .github/workflows/mobile-native-build.yml - 1 issue
  • apps/mobile/src/lib/organization-context.tsx - no issues
  • apps/mobile/src/lib/organization-context.test.ts - no issues
  • dev/local/mobile-native-gate.test.ts - no issues

Fix these issues in Kilo Cloud

Previous review

Status: 3 Issues Found | Recommendation: Address before merge

Executive Summary

The new native-build promote path is inert: the workflow consumes promote_* outputs and a --published CLI mode that dev/local/mobile-native-gate.ts does not implement, so promote never runs and the artifact check never skips a build.

Assumptions: [INFERENCE] I did not run the workflow or execute dev/local/mobile-native-gate.ts; the finding rests on reading the current workflow, the unchanged gate script, and its tests. The two stale inline comments on the deleted apps/mobile/src/lib/organization-selection.ts are outdated and were not carried forward. The earlier sign-out fence finding on organization-context.tsx:183 stays resolved.

Overview

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

WARNING

File Line Issue
.github/workflows/mobile-native-build.yml 133 Gate declares promote_ios/promote_android outputs but the unchanged gate script never emits them, so the promote jobs never run and push runs still rebuild.
.github/workflows/mobile-native-build.yml 219 mobile-native-gate.ts has no --published mode, so steps.published.outputs.published is never set and the build-skip guards are always true.

SUGGESTION

File Line Issue
dev/local/mobile-native-gate.test.ts 116 Regex assertions accept `always()
Files Reviewed (2 files)
  • .github/workflows/mobile-native-build.yml - 2 issues
  • dev/local/mobile-native-gate.test.ts - 1 issue

Fix these issues in Kilo Cloud

Previous review (commit 6e184c9)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change since 9a17f63 touches only organization-context.test.ts: it gives the ordered-save regression test explicit one-at-a-time gate releases and a documented file-level max-lines disable; the three storage gates are all released and the final assertions still cover the last-written selection, so no new issue was found.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, or lint. The persist fence at organization-context.tsx:169 and :178 was confirmed in current code, so the previous sign-out race finding stays resolved; the two existing comments on the deleted organization-selection.ts are outdated.

Files Reviewed (1 file)
  • apps/mobile/src/lib/organization-context.test.ts - no issues

Previous review (commit 9a17f63)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change adds a generation/auth-epoch re-check between the organization key and Personal marker writes, closing the sign-out race the prior review raised; no new issues were found on the changed lines.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, or lint. The PR description still describes the earlier single-value storage design, while HEAD (commit 1db1bba) restored the two-key contract (selected-organization plus the Personal marker); the previously reported decodeSelection header defect no longer exists under that contract because the organization key only ever holds an organization id or is deleted.

Files Reviewed (1 file)
  • apps/mobile/src/lib/organization-context.tsx

Previous review (commit 1db1bba)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The queue serializes selections correctly, but its generation/epoch fence runs only before the two-key pair, so a sign-out that lands between the writes can let the Personal marker be re-created after the sign-out cleanup.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, or lint. The net diff against the merge base touches only organization-context.tsx and its test; the PR description still describes the earlier single-value storage design, while HEAD stores an organization id under selected-organization and the Personal choice as a separate marker.

Overview

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

SUGGESTION

File Line Issue
apps/mobile/src/lib/organization-context.tsx 179 The save fence is checked once before the pair, so a sign-out during the first write lets the second write re-create the Personal marker after sign-out cleanup.
Files Reviewed (2 files)
  • apps/mobile/src/lib/organization-context.tsx - 1 issue
  • apps/mobile/src/lib/organization-context.test.ts - no issues

Fix these issues in Kilo Cloud

Previous review (commit efd6523)

Status: No Issues Found | Recommendation: Merge

Executive Summary

The incremental change routes the voice-input catalogue/upload scope and the tool-summary translation scope through decodeSelection, closing the previously reported Personal-scope leak; both paths now omit the organization header when the selection is Personal, each with a covering test.

Assumptions: [INFERENCE] I did not run the mobile vitest suite, typecheck, or lint; the header omission and the undefined catalogue argument were verified by reading gateway-transcription-client.ts:91-93 and fetchTranscriptionModels (use-transcription-models.ts:83), which drop the header for null/undefined.

Files Reviewed (4 files)
  • apps/mobile/src/lib/tool-summary-translation/tool-summary-translation-client.ts
  • apps/mobile/src/lib/tool-summary-translation/tool-summary-translation-client.test.ts
  • apps/mobile/src/lib/voice-input/gateway/native-gateway-voice-input.ts
  • apps/mobile/src/lib/voice-input/gateway/native-gateway-voice-input.test.ts

Previous review (commit ec76606)

Status: 1 Issue Found | Recommendation: Address before merge

Executive Summary

The single-value selection contract is not applied to two remaining scope readers, so an explicit Personal choice is sent to the gateway as an organization id and breaks dictation and tool-summary translation.

Assumptions: [INFERENCE] I did not run the app or the test suites; the gateway rejection is traced through the UUID validation in validateUserAuthorization (packages/web-shared/src/lib/user/server.ts:458-462), not observed on a device.

Overview

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

CRITICAL

File Line Issue
apps/mobile/src/lib/organization-selection.ts 9 The new "every reader decodes the selection" contract is not met: voice-input/gateway/native-gateway-voice-input.ts and tool-summary-translation/tool-summary-translation-client.ts read ORGANIZATION_STORAGE_KEY raw, so the stored personal sentinel is sent as X-KiloCode-OrganizationId: personal.
Files Reviewed (14 files)
  • apps/mobile/src/components/context-control.mounted.test.tsx - no issues
  • apps/mobile/src/components/profile-credits-card.mounted.test.tsx - no issues
  • apps/mobile/src/glanceable-android/session-stored-context.ts - no issues
  • apps/mobile/src/glanceable-ios/adopt-activity.ts - no issues
  • apps/mobile/src/glanceable-ios/interaction.ts - no issues
  • apps/mobile/src/lib/glanceable/activity-kit-prompt.ts - no issues
  • apps/mobile/src/lib/glanceable/scope.test.ts - no issues
  • apps/mobile/src/lib/glanceable/scope.ts - no issues
  • apps/mobile/src/lib/glanceable/widget-actions.ts - no issues
  • apps/mobile/src/lib/organization-context.mounted.test.tsx - no issues
  • apps/mobile/src/lib/organization-context.test.ts - no issues
  • apps/mobile/src/lib/organization-context.tsx - no issues
  • apps/mobile/src/lib/organization-selection.ts - 1 issue
  • apps/mobile/src/lib/storage-keys.ts - no issues

Fix these issues in Kilo Cloud


Reviewed by deepseek-flash-latest · Input: 67K · Output: 15.5K · Cached: 481.8K

Review guidance: REVIEW.md from base branch main

…elper

The voice-input catalogue read and the tool-summary translation resolve
their organization scope through the same helper every other reader uses,
so each request runs in the scope selected in the app.
@iscekic

iscekic commented Oct 22, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Scope of the on-device run, for the record.

The Android run above exercised the selection path end to end: the picker, saving a choice, and the choice surviving a relaunch, for both an organization and the Personal scope.

It did not complete a gateway round trip in either direction. The local ai-gateway in this environment answers 500 for the transcription catalogue with or without an organization header (its upstream is unreachable here), so the voice-input catalogue resolve and the tool-summary translation request could not finish on the device. Their scope mapping is covered by unit tests on the request shape:

  • the catalogue read is called without an organization scope on the personal choice;
  • the translation request omits the organization header on the personal choice.

Mobile vitest on this head: 1252 files, 18595 passed, 2 skipped. Typecheck and lint are clean.

@iscekic iscekic added merge:human Substantive functional risk requires human review. merge:blocked:insufficient-e2e Verification does not cover the change labels Oct 22, 2026

@iscekic iscekic left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Request changes: ordered saves are the fix and should stay, so the last selection always wins. Keep the existing two-key stored format and the separate Personal marker instead of migrating every reader to a new stored value.

Saves of the mobile organization selection now share one queue slot per
account, so a later choice is written after an earlier one and the
organization key and Personal marker go out as a single pair. The stored
format is unchanged.

The regression test parks every storage call and shows the second
selection is written after the first pair.
@iscekic iscekic removed merge:human Substantive functional risk requires human review. merge:blocked:insufficient-e2e Verification does not cover the change labels Oct 23, 2026
Comment thread apps/mobile/src/lib/organization-context.tsx Outdated
Keep each organization selection save ordered and verify the active
selection before each account metadata write. The saved keys retain their
existing format.
The ordered selection save checks the current generation and auth epoch
before each storage write. Organization selection remains in its established
key-and-marker format.
@iscekic

iscekic commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Follow-up retains the established organization key and Personal marker. Selection saves share one ordered queue and check the active generation and auth epoch before each metadata write.

Android verification: signed in with a local test account, selected Local Team Two, force-stopped and relaunched the app, and confirmed the Home header still showed Local Team Two after Metro loaded the current bundle. The regression test uses deferred storage writes to verify ordered completion.

Home after relaunch

Selected organization after app relaunch

Allow each platform build request to run independently instead of sharing a
native-hash concurrency group. The existing artifact check still reuses a
published build. Update the workflow assertion for the expanded job condition.
Comment thread .github/workflows/mobile-native-build.yml
Comment thread .github/workflows/mobile-native-build.yml
Comment thread dev/local/mobile-native-gate.test.ts
…lection-single-value

# Conflicts:
#	.github/workflows/mobile-native-build.yml
@iscekic

iscekic commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Current-head Android proof: selected Local Team Two, force-stopped and relaunched the app, and confirmed the Home header still showed Local Team Two after the merged-head bundle loaded. The local test account and services were non-production.

Selected organization after app relaunch

@iscekic iscekic added merge:blocked:judge-unavailable Risk assessment unavailable merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. and removed merge:blocked:judge-unavailable Risk assessment unavailable labels Oct 23, 2026
Comment thread .github/workflows/mobile-native-build.yml Outdated
The heavy jobs check for an already published artifact right before they build, and concurrent runs of one nativeHash may build at once. The gate script header, the check's comment, and its test now say that instead of describing a job-level concurrency group that no longer exists.
@iscekic iscekic removed the merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. label Oct 24, 2026
@iscekic iscekic added merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. and removed merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head labels Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Android emulator against the local dev stack with an owned test account.

  • The account picker lists the available account scopes.
  • After choosing a scope and restarting the app, the Home header shows the chosen scope.
  • The same holds for the personal scope.

The app served the branch bundle from Metro on this VM for the run.

Account picker

Home header after app restart

Home header after app restart, personal scope

@iscekic iscekic added the merge:blocked:insufficient-e2e Verification does not cover the change label Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Android emulator against the local dev stack, seeded non-production account with two organization memberships.

  • The account sheet lists the available scopes, with the current one selected.
  • After switching scopes back to back, the Home header shows the last choice.
  • After a force-stop and relaunch, the header shows that same choice again.
  • The Personal scope also survives a relaunch.

The device store held exactly one selection entry after each step (checked through shared_prefs/SecureStore.xml); its values are encrypted, so the header after relaunch is the read-back assertion.

Account sheet listing the available scopes

Home header after switching scopes

Home header after relaunch

Home header after relaunch, personal scope

@iscekic iscekic added merge:human Substantive functional risk requires human review. and removed merge:blocked:insufficient-e2e Verification does not cover the change merge:bot Bot-owned review; merge when ready once readiness passes and a review approves. labels Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

Changes requested: remove the out-of-scope CI changes.

  • This PR removes the per-nativeHash job concurrency groups in .github/workflows/mobile-native-build.yml and rewrites the related comments in dev/local/mobile-native-gate.ts and its test. fix(ci): dedupe mobile native builds per nativeHash #8638 added those groups on purpose to stop duplicate macOS builds of the same native hash.
  • Restore .github/workflows/mobile-native-build.yml, dev/local/mobile-native-gate.ts and its test to match main.
  • Keep the organization-context.tsx ordered-save fix and its test unchanged.
  • A queued or cancelled native build check on this PR does not block merge, so no workflow change is needed for this fix.

The organization selection fix does not need a workflow change.
@iscekic iscekic removed the merge:human Substantive functional risk requires human review. label Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Removed the workflow and gate changes. .github/workflows/mobile-native-build.yml, dev/local/mobile-native-gate.ts and dev/local/mobile-native-gate.test.ts now match main exactly (git diff origin/main -- <those paths> is empty).

The pull request now changes only apps/mobile/src/lib/organization-context.tsx and its test. Body updated to match.

Comment thread apps/mobile/src/lib/organization-context.tsx Outdated
@iscekic iscekic added merge:blocked:insufficient-e2e Verification does not cover the change merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head merge:human Substantive functional risk requires human review. labels Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Android emulator against the local dev stack, seeded non-production account with two organization memberships.

  • The account sheet lists the available scopes.
  • After switching scopes back to back, the Home header shows the last choice.
  • After a force-stop and relaunch, the header shows that same choice again.
  • The Personal scope also survives a relaunch.

The device store held exactly one selection entry after each step (checked through shared_prefs/SecureStore.xml); its values are encrypted, so the header after relaunch is the read-back assertion. The app served the branch bundle from Metro on this VM.

Account sheet listing the available scopes

Home header after switching scopes back to back

Home header after choosing the personal scope

Home header after a relaunch, personal scope

Home header after a relaunch, organization scope

A selection save now carries its own order, so a restore that runs for the
same account while a save is pending leaves that save to finish and reads
the pair it wrote. Saves stay ordered among themselves and stay fenced by
the auth epoch.
@iscekic iscekic added merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head merge:human Substantive functional risk requires human review. merge:blocked:insufficient-e2e Verification does not cover the change and removed merge:human Substantive functional risk requires human review. merge:blocked:insufficient-e2e Verification does not cover the change merge:blocked:kilobot-not-ready Review bot has not recommended merge at this head labels Oct 24, 2026
@iscekic

iscekic commented Oct 24, 2026

Copy link
Copy Markdown
Collaborator Author

bot: Android emulator (omp36, default 1080x2400 / 420 dpi) against the local dev stack on this VM, seeded non-production account that belongs to two organizations, with Metro serving the branch bundle.

  • The account sheet lists Personal and both organizations, with the current scope marked selected.
  • After switching scopes back to back, the Home header shows the last choice.
  • Force-stop and relaunch: the header shows that same choice, and the account sheet still marks it.
  • The Personal scope also survives a relaunch.

shared_prefs/SecureStore.xml (read through run-as) held exactly one selection entry after each step: the organization entry after an organization choice, the Personal entry after the Personal choice. Expo SecureStore encrypts the values, so the header before and after relaunch is the read-back assertion.

Account sheet listing the available scopes

Home header after a relaunch with the organization scope selected

Home header after a relaunch with the Personal scope selected

Home header after switching scopes back to back

01-picker

04-relaunch-org

06-relaunch-personal

07-header-after-rotation-burst

@iscekic iscekic removed the merge:blocked:insufficient-e2e Verification does not cover the change label Oct 24, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

drain Work item from the findings drain janitor:trust Janitor finding: trust boundary hardening merge:human Substantive functional risk requires human review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant