fix(push): persist presented activity across native restarts #94
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/01a155ed-presentation-state"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Prevent previously presented activity from returning as a fresh Android alert after process reconstruction or dismissal. Snapshots identify the latest eligible activity independently of refresh revisions, preview text and capped unread counts.
The history holds at most512 source/version identities under noBackupFilesDir with the existing AES-GCM codec, bounded at128KiB. It stores no preview/credential. Foreground reconciliation receives all groups plus focused source keys, so focused sources are withheld without assuming focus proves a read. Unpresented activity remains eligible after leaving if the server still reports it unread. Independent focus registrations preserve simultaneous task/conversation suppression and clear on background/teardown.
Evidence
Merge danger
Door: two-way for source, preserving applied migration history and the unchanged existing session/ACK filenames, aliases and default codec bounds.
Blast radius: app/server notification snapshot contract.
Requires the matching app/server version field and native bridge array signature. All callers are in this private app. Previously presented versions remain consumed when their OS notification is absent; this is not an instruction to rebuild old alerts after reboot. Actual hardware Keystore, reboot, JobScheduler and bundled-JS behavior still need device acceptance.
Rollback and verification
Scoped review of
d53cf5567dagainstb5f2133fec: no blocking Standards or Spec findings. Full review follows in a comments-only review record; hardware/full-APK acceptance remains outstanding and no operational approval is implied.Scoped security review completed for PR94 at
d53cf5567dagainstb5f2133fec. Prior reviews unchanged.Standards
No blocking findings. Checked the three-dot diff and surrounding implementation against Mission Control AGENTS.md, Homelab secret/perimeter/operations rules and the role checklist. No new exposure, permissions, image sources, schema or copied activity history. Snapshot version subqueries use the existing eligible organization/destination/member and unread predicates; conversation ownership and task subscription/read/archive filtering remain intact. Versions are strings bounded to 1–64 characters at server schema/native parsing. Native response/page/group limits remain.
The new file contains generation plus at most 512 source/version identities, no preview, endpoint or credential. AES-GCM uses the file-specific alias/AAD and noBackupFilesDir; corruption/wrong-key reads discard metadata. Generation replacement/logout clears history and alerts; same-generation reconstruction preserves existing alerts. Session/ACK filenames, aliases, ciphertext layout and default 2KiB write/4KiB read bounds remain unchanged. New codec: 128KiB plaintext write limit, 28-byte ciphertext overhead, 130KiB defensive read ceiling.
Non-blocking, UNKNOWN (verification limit): hardware Keystore, reboot, JobScheduler and bundled-JS/full-APK behavior were not verified here. This is not evidence of an exploitable defect or a waiver of device acceptance. No cluster mutation or secret reads performed; no live deployment claim.
Spec
No blocking findings. Latest eligible UUID selection has explicit same-millisecond tie ordering (conversation rowid; task kind then rowid). Stable versions are independent of revision, preview visibility and capped counts. Reviewed regression cases cover stable/new/removed activity, malformed versions, dismissal/reconstruction, existing-alert updates, 512-entry eviction, corrupt/wrong-key history and permission re-grant. Absent previously presented versions are suppressed; active alerts can update. Focused groups are excluded before remembering, so focus alone does not consume unread activity. JS tracks independent focus registrations and sends only source-key arrays; background/cleanup and native background/destroy clear suppression. The interface adds no read, credential or arbitrary execution capability.
Non-blocking, UNKNOWN (acceptance limit): inspected lifecycle source and native adapter tests, not actual React Native bridge/device execution. Owner must retain the explicit device gate and bounded-history limitation: evicted identities may reappear. Permission denial clears history so unread activity remains eligible after grant.
Evidence and next steps
Read-only
tea api repos/ai/mission-control/pulls/94confirmed exact head/base, open/unmerged.tea api repos/ai/mission-control/commits/d53cf5567dbc087cf96067c5bd188e842e5cbbc8/statusreturned success for all nine current contexts, including PR649 native-push/quality and push648.git diff b5f2133...HEAD --checkpassed. Tests were inspected, not rerun locally (no Java or installed worktree dependencies). Woodpecker CLI exists but is unconfigured; pipeline-detail queries failed. PR651/test counts are author evidence; never merge PR93.CI: https://woodpecker.olsen.cloud/repos/32/pipeline/649
After separately approved migration/install, owner verifies real-device background receipt, dismissal/restart/reboot, simultaneous focus/leave/background, read-elsewhere, permission re-grant and logout. Rollback this slice coherently across server/app/native bridge; preserve applied migrations and session/ACK compatibility. Production 043/044, release and installation decisions remain separate. Owner retains merge/build/rollout; no operational approval or waiver given.
Standards: 0 blocking, 1 non-blocking UNKNOWN verification limit. Spec: 0 blocking, 1 non-blocking UNKNOWN acceptance limit.