Skip to content

fix(app): preserve local runtime choice on rehydrate#2529

Open
YOMXXX wants to merge 3 commits into
tinyhumansai:mainfrom
YOMXXX:fix/2473-runtime-choice-loop
Open

fix(app): preserve local runtime choice on rehydrate#2529
YOMXXX wants to merge 3 commits into
tinyhumansai:mainfrom
YOMXXX:fix/2473-runtime-choice-loop

Conversation

@YOMXXX
Copy link
Copy Markdown
Contributor

@YOMXXX YOMXXX commented May 23, 2026

Summary

  • Preserve the synchronous local runtime marker during redux-persist rehydrate.
  • Prevent stale persisted coreMode.mode=unset from sending users back to the runtime picker after choosing Local.
  • Add a focused regression test that exercises the real redux-persist reconciler despite the global Vitest mock.

Problem

Solution

  • Handle persist/REHYDRATE in coreModeSlice for the coreMode persist key.
  • Re-derive the synchronous marker from localStorage during rehydrate and let any concrete marker (local or fully configured cloud) win over stale async persisted state.
  • Leave normal persisted rehydrate behavior unchanged when no synchronous marker exists.

Submission Checklist

If a section does not apply to this change, mark the item as N/A with a one-line reason. Do not delete items.

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — changed lines (Vitest + cargo-llvm-cov merged via diff-cover) meet the gate enforced by .github/workflows/coverage.yml. Targeted coverage covers coreModeSlice.ts changed lines at 100%; CI remains authoritative.
  • Coverage matrix updated — N/A: behavior-only startup persistence fix, no feature row added/removed/renamed.
  • All affected feature IDs from the matrix are listed in the PR description under ## Related — N/A: no matrix feature ID changed.
  • No new external network dependencies introduced (mock backend used per Testing Strategy)
  • Manual smoke checklist updated if this touches release-cut surfaces (docs/RELEASE-MANUAL-SMOKE.md) — N/A: no release smoke checklist surface changed.
  • Linked issue closed via Closes #NNN in the ## Related section

Impact

  • Desktop startup/runtime picker behavior only.
  • No new network calls, migrations, or API changes.
  • Returning users with a valid synchronous runtime marker keep their selected runtime instead of falling back to the picker because of stale persisted Redux state.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/2473-runtime-choice-loop
  • Commit SHA: 21f781bf82a435732ddb83f67980717cbede87ca

Validation Run

  • pnpm --filter openhuman-app format:check
  • pnpm typecheck
  • Focused tests: pnpm --filter openhuman-app test:unit src/store/coreModeSlice.test.ts; pnpm --filter openhuman-app exec vitest run --coverage --config test/vitest.config.ts src/store/coreModeSlice.test.ts
  • Rust fmt/check (if changed): pnpm format:check includes root cargo fmt --all --check; no Rust code changed.
  • Tauri fmt/check (if changed): GGML_NATIVE=OFF git push -u origin fix/2473-runtime-choice-loop pre-push ran cargo check --manifest-path app/src-tauri/Cargo.toml successfully; no Tauri code changed.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: Runtime mode rehydrate now prefers a concrete synchronous runtime marker over stale async persisted unset state.
  • User-visible effect: Users who choose Local runtime should not be bounced back to the runtime picker because of this rehydrate race.

Parity Contract

  • Legacy behavior preserved: Existing persisted coreMode still rehydrates normally when no synchronous marker exists.
  • Guard/fallback/dispatch parity checks: Handler is scoped to the coreMode rehydrate action and only overrides when deriveInitialMode() returns a concrete mode.

Duplicate / Superseded PR Handling

  • Duplicate PR(s): None found for fix/2473-runtime-choice-loop.
  • Canonical PR: This PR.
  • Resolution (closed/superseded/updated): N/A

Summary by CodeRabbit

  • Bug Fixes

    • Improved reliability of mode preference persistence across app rehydration cycles, ensuring settings remain consistent during session restoration.
  • Tests

    • Added validation test for state rehydration behavior.

Review Change Stack

@YOMXXX YOMXXX requested a review from a team May 23, 2026 11:35
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 23, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e45f9773-435f-438e-879e-700be4608437

📥 Commits

Reviewing files that changed from the base of the PR and between 7745d58 and 21f781b.

📒 Files selected for processing (2)
  • app/src/store/coreModeSlice.test.ts
  • app/src/store/coreModeSlice.ts

📝 Walkthrough

Walkthrough

When redux-persist rehydrates state from storage, the coreModeSlice now re-derives the core mode from localStorage via a new extraReducers handler listening for REHYDRATE. This ensures the synchronous in-memory marker takes precedence over any stale persisted data and a test validates this precedence behavior.

Changes

Redux-persist rehydration safeguard

Layer / File(s) Summary
Persist rehydration handler
app/src/store/coreModeSlice.ts
REHYDRATE action is imported and an extraReducers handler re-derives the synchronous core mode from localStorage on rehydration, conditionally overwriting the slice state so non-unset localStorage values override stale persisted data.
Rehydration test
app/src/store/coreModeSlice.test.ts
New test sets localStorage to local, wraps the slice with persistReducer, simulates persist/REHYDRATE with a stale unset payload, and verifies the slice state remains local.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Suggested labels

bug

Poem

🐰 A state rehydrated, stale and worn,
localStorage whispers: "I'll reset the morn."
REHYDRATE listens, derives anew,
Sync beats persist—what localStorage knew.
Redux learns: fresh beats what was cached before.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix(app): preserve local runtime choice on rehydrate' accurately and specifically describes the main change—handling Redux rehydration to preserve the user's selected local runtime.
Linked Issues check ✅ Passed The changes directly address issue #2473 by implementing a rehydration handler that prevents stale persisted state from overriding the synchronous local runtime marker stored in localStorage.
Out of Scope Changes check ✅ Passed All changes are focused on fixing the Redux rehydration logic for coreMode; no unrelated modifications to other features or systems are present.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@YOMXXX
Copy link
Copy Markdown
Contributor Author

YOMXXX commented May 23, 2026

@graycyrus @senamakel Ready for review.

Latest state for #2529 (fix(app): preserve local runtime choice on rehydrate):

  • all required checks are green
  • no unresolved review threads
  • CodeRabbit has no actionable comments on the latest head

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

win11 下载了exe启动之后选择运行时本地之后重新跳回选择运行时页面

2 participants