Skip to content

feat(ios): reconcile restored cache as stale until a live snapshot - #441

Merged
BunsDev merged 4 commits into
mainfrom
feat/ios-stale-live-reconciliation
Sep 11, 2026
Merged

feat(ios): reconcile restored cache as stale until a live snapshot#441
BunsDev merged 4 commits into
mainfrom
feat/ios-stale-live-reconciliation

Conversation

@BunsDev

@BunsDev BunsDev commented Sep 11, 2026

Copy link
Copy Markdown
Member

Summary

  • restore cached iOS workspace projections into an explicit stale/recovering/live store liveness state instead of treating restored state as live
  • gate workspace mutations through the live-state guard and keep UI remote-action entrypoints behind the same liveness authority
  • add a dedicated stale-recovery fixture and UI coverage for stale banner/accessibility, disabled controls, deterministic live snapshot reconciliation, and vanished-pane selection cleanup

Acceptance criteria

Criterion Evidence
Cached state is never presented as live WorkspaceLiveness.stale on cache restore; testRestoredCacheIsPresentedAsStaleUntilAuthoritativeSnapshotArrives; testStaleFixtureShowsDisabledControlsThenClearsAfterLiveSnapshot
Successful snapshot clears stale state and persists fresh state existing cache persistence path remains gated on non-stale committed host; testRestoredCacheIsPresentedAsStaleUntilAuthoritativeSnapshotArrives; testAuthoritativeSnapshotRecoversSavingAndDismissalKeepsPreservedData covered in app tests
Disconnect preserves viewable bounded cache and disables live actions testDisconnectKeepsStateButMarksItStale; new mutation guard coverage in testEveryMutationCommandRefusesStaleWorkspaceBeforeSending and testRefusesRitualLaunchWhileWorkspaceIsStale
Deleted/renamed panes reconcile safely existing selection/draft reconciliation tests plus stale-recovery UI fixture moves from cached-pane to live-pane without carrying stale drafts

Commands and results

Command Result
git show --stat 3f104272 inspected predecessor bounded protected workspace cache commit
xcodebuild test -project native/ios/Psyche.xcodeproj -scheme PsycheCore -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:PsycheCoreTests/WorkspaceStoreTests -only-testing:PsycheCoreTests/WorkspaceStoreCommandsTests -derivedDataPath /tmp/psyche-core-targeted passed: 61 tests
xcodebuild test -project native/ios/Psyche.xcodeproj -scheme PsycheApp -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:PsycheAppTests/AppModelTests -only-testing:PsycheAppTests/CreatePaneFormTests -only-testing:PsycheAppTests/PaneComposerTests -derivedDataPath /tmp/psyche-app-targeted passed: 51 tests
xcodebuild test -project native/ios/Psyche.xcodeproj -scheme PsycheApp -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -only-testing:PsycheAppUITests/PsycheAppUITests/testStaleFixtureShowsDisabledControlsThenClearsAfterLiveSnapshot -derivedDataPath /tmp/psyche-ui-targeted3 passed: 1 UI test
xcodebuild test -project native/ios/Psyche.xcodeproj -scheme PsycheCore -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -derivedDataPath /tmp/psyche-core-full passed: 451 tests
pnpm ios:project:check passed
git diff --check passed
xcodebuild -version Xcode 26.6, build 17F113
xcodebuild test -project native/ios/Psyche.xcodeproj -scheme PsycheApp -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -derivedDataPath /tmp/psyche-app-full-2 failed in full UI target after simulator runner restarts/timeouts; stale UI test passed separately
xcodebuild test -project native/ios/Psyche.xcodeproj -scheme PsycheApp -destination 'platform=iOS Simulator,name=iPhone 16 Pro' -parallel-testing-enabled NO -derivedDataPath /tmp/psyche-app-full-serial failed with Mach error -308 - (ipc/mig) server died after app connection loss/restarts on iOS 26.5 simulator runtime

Proof gaps

  • Simulator-only validation; no physical-device run.
  • Local Xcode is 26.6 (17F113), not CI-pinned Xcode 26.2 (17C52).
  • Full PsycheApp UI target did not complete locally because the simulator runner repeatedly lost the app/helper connection on the available iOS 26.5 runtime. The new stale-recovery UI test passed in isolation.

Rollback

Revert commit e566fb444097682efa556a69f55e7551969af899 to remove the liveness enum, mutation gate changes, stale-recovery fixture, and associated tests.

References

Bead psyche-i7c.10.2 (mirror #211); outcome #200

Copilot AI lite review requested due to automatic review settings September 11, 2026 14:15
@vercel

vercel Bot commented Sep 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
psyche-build-docs Ready Ready Preview Sep 11, 2026 3:49pm UTC

Request Review

Copilot AI left a comment

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.

🟡 Changes recommended

One or more issues must be addressed before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds explicit stale/recovering/live liveness handling for restored iOS workspace state, gates mutations, and adds stale-recovery UI coverage.

Changes:

  • Marks restored/disconnected workspace data stale until an authoritative snapshot arrives.
  • Blocks stale workspace mutations and remote controls.
  • Adds stale-recovery fixtures, accessibility coverage, and reconciliation tests.
File summaries
File Description
native/ios/PsycheCore/Tests/PsycheCoreTests/WorkspaceStoreTests.swift Updated as part of this pull request.
native/ios/PsycheCore/Tests/PsycheCoreTests/WorkspaceStoreCommandsTests.swift Updated as part of this pull request.
native/ios/PsycheCore/Sources/PsycheCore/State/WorkspaceStore.swift Updated as part of this pull request.
native/ios/PsycheCore/Sources/PsycheCore/Fixtures/WorkspaceFixtures.swift Updated as part of this pull request.
native/ios/PsycheApp/Tests/PsycheAppUITests/PsycheAppUITests.swift Updated as part of this pull request.
native/ios/PsycheApp/Sources/PsycheApp/Views/PaneControls.swift Updated as part of this pull request.
native/ios/PsycheApp/Sources/PsycheApp/Views/NowView.swift Updated as part of this pull request.
native/ios/PsycheApp/Sources/PsycheApp/DemoStore.swift Updated as part of this pull request.
Review details

Suppressed comments (1)

native/ios/PsycheApp/Sources/PsycheApp/Views/PaneControls.swift:203

  • This check only protects the initial menu tap. The async task below can run after a disconnect marks the store stale, and RemoteActionStore.start/respond do not consult WorkspaceStore.liveness; an already-open action sheet can therefore still send startAction or respondToAction against stale workspace state. Recheck the shared liveness authority at the async send/response boundary and invalidate pending action sessions when the store becomes stale.
        guard store.liveness.allowsLiveActions else {
            errorMessage = WorkspaceStoreError.staleWorkspace.localizedDescription
            return
        }
  • Files reviewed: 8/8 changed files
  • Comments generated: 3
  • Review effort level: Lite

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread native/ios/PsycheApp/Sources/PsycheApp/Views/PaneControls.swift
Comment thread native/ios/PsycheCore/Sources/PsycheCore/State/WorkspaceStore.swift
Comment thread native/ios/PsycheCore/Sources/PsycheCore/State/WorkspaceStore.swift Outdated
BunsDev and others added 4 commits September 11, 2026 10:49
Bead psyche-i7c.10.2 (mirror #211)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bead psyche-i7c.10.2 (mirror #211)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Bead psyche-i7c.10.2 (mirror #211)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
When disconnect is called during an existing teardown, await that teardown before returning so callers do not immediately attempt stored reconnect while the manager is still disconnecting and later observe the old disconnected final state instead of the refused-readiness failure.

References: Bead psyche-i7c.10.2 (mirror #211); outcome #200

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@BunsDev
BunsDev force-pushed the feat/ios-stale-live-reconciliation branch from 7ff49c8 to 84b1105 Compare September 11, 2026 15:49
@BunsDev
BunsDev merged commit 28aadb3 into main Sep 11, 2026
10 checks passed
@BunsDev
BunsDev deleted the feat/ios-stale-live-reconciliation branch September 11, 2026 16:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants