问题与范围
桌面聊天的两个同服务设置视图会各自保留挂载时的通知偏好。视图 A 已将通知设为“关闭”,视图 B 仍持有旧的 notifications;B 随后只修改“静默时段”,却整份写回旧偏好,将 mode 一并恢复为 notifications。A 仍显示关闭,持久设置已经不同。
按 P2 跟踪跨桌面视图的用户偏好覆盖。2026-09-30 的原组件共享内存存储 fixture 已确认该序列;没有触发真实 OS 通知、音频或授权提示,没有生产通知事故或私有内容展示证据,不报告 P0/系统权限绕过。范围仅为 desktop-owned 聊天通知设置及偏好状态协调;现有 Web 文件作定位,不要求本轮修改 Web 或后端。
已核验的原组件证据
fixture 原样转译并执行两个独立上下文中的 NotificationSettings 与 threadNotifications。React test renderer 只替换 HeroUI、图标等渲染叶组件,原 hooks、事件处理、偏好读写和通知判断逻辑保留。两个假 window 共享合成内存 StorageLike,没有接入真实 localStorage、Notification 或 AudioContext。
- 两视图均从 notifications、静默时段关闭开始。
- 调用 A 的原模式处理函数切换 off,存储确实为 off。
- B 仍显示 notifications;调用 B 的原静默时段 checkbox 处理函数后,存储变成 notifications,quietHours.enabled=true。A 的界面仍为 off。
- 在合成当地中午、无活跃线程的条件下,原
shouldNotifyInboxEvent 读取此结果后重新判定一个合成审批事件 eligible;没有调用 dispatch 或创建通知。
- 对照先重新挂载 B,再编辑静默时段:B 正确读到 off,编辑后仍为 off,原判断为 mode-off。
完整存储轨迹、输入/输出、组件状态与源码哈希保存在本地 ignored artifact。假 storage 没有模拟真实 StorageEvent 分发;原组件也没有注册 storage 或偏好变化监听。该证据是原状态/写回逻辑验证,尚未实际操作桌面两个设置窗口。
根因、桌面前提与保护
NotificationSettings.tsx:46–64 仅挂载时读取,persist 整份写回;静默时段处理函数使用闭包中的旧 prefs 展开,带回未编辑的 mode。threadNotifications 每次判断重新读取存储,因此实际使用的偏好可以与 A 的显示不一致。
当前桌面 guardContents 给允许的同 origin 子窗设置相同 partitionFor(origin),这为同服务多个视图共享偏好的场景提供源码依据;本轮没有创建原生窗口。其他 origin 的 partition 分开,不把跨服务身份串用作为本项。
OS 通知授权仍独立校验,native 权限处理仍要求可信 origin,默认取消;mode 被恢复不会授予系统权限。确定的问题是用户明确关闭的应用偏好被另一视图的无关编辑覆盖。若系统权限已由用户授予,通知是否真实出现仍需单独 UI 验收,不能从 eligible 推断已投递。
桌面优化方案与验收
- 同一服务/profile 的偏好由统一 desktop store 管理并向视图广播;订阅变化使 UI 反映已提交状态。
- 提交用户编辑的字段,而非整个陈旧快照;提交前读取当前版本或由单一 owner 合并,保留其他视图刚作出的决定。多个同时编辑必须有清楚的版本/冲突合同。
- 在同类隔离原组件 fixture 中重跑 A 关闭、B 编辑静默时段:持久 mode 仍为 off,两视图最终一致,原通知判断仍为 mode-off。反向修改 mode 不覆盖已经保存的静默时段。
- 补充独立可弃置 desktop profile 的双窗口验收,先只检查合成设置和 eligibility,不请求系统许可或显示真实内容;另外验证 origin/profile 隔离。
- 继续保留 OS 权限和 quiet-hours 的现有判断,本项不以放宽权限解决设置同步。
去重与源码
#42 是通知权限已拒绝后的恢复路径及重复提示;这里使用不存在 Notification API 的 fixture,单独证明应用偏好陈旧写回。#67 为审批意图协调,不覆盖通知设置存储。#41 为外观设置滚动和保存范围。本条只保留“跨视图整份陈旧偏好覆盖”一个主因,关联 Epic #31。
公开固定提交用于导航;当前源文件哈希是此次逻辑证据,不宣称发行包或实际 OS 通知事故:NotificationSettings、threadNotifications、main.cjs、policy.cjs。
问题与范围
桌面聊天的两个同服务设置视图会各自保留挂载时的通知偏好。视图 A 已将通知设为“关闭”,视图 B 仍持有旧的 notifications;B 随后只修改“静默时段”,却整份写回旧偏好,将 mode 一并恢复为 notifications。A 仍显示关闭,持久设置已经不同。
按 P2 跟踪跨桌面视图的用户偏好覆盖。2026-09-30 的原组件共享内存存储 fixture 已确认该序列;没有触发真实 OS 通知、音频或授权提示,没有生产通知事故或私有内容展示证据,不报告 P0/系统权限绕过。范围仅为 desktop-owned 聊天通知设置及偏好状态协调;现有 Web 文件作定位,不要求本轮修改 Web 或后端。
已核验的原组件证据
fixture 原样转译并执行两个独立上下文中的
NotificationSettings与threadNotifications。React test renderer 只替换 HeroUI、图标等渲染叶组件,原 hooks、事件处理、偏好读写和通知判断逻辑保留。两个假 window 共享合成内存 StorageLike,没有接入真实 localStorage、Notification 或 AudioContext。shouldNotifyInboxEvent读取此结果后重新判定一个合成审批事件 eligible;没有调用 dispatch 或创建通知。完整存储轨迹、输入/输出、组件状态与源码哈希保存在本地 ignored artifact。假 storage 没有模拟真实 StorageEvent 分发;原组件也没有注册 storage 或偏好变化监听。该证据是原状态/写回逻辑验证,尚未实际操作桌面两个设置窗口。
根因、桌面前提与保护
NotificationSettings.tsx:46–64仅挂载时读取,persist 整份写回;静默时段处理函数使用闭包中的旧 prefs 展开,带回未编辑的 mode。threadNotifications每次判断重新读取存储,因此实际使用的偏好可以与 A 的显示不一致。当前桌面
guardContents给允许的同 origin 子窗设置相同partitionFor(origin),这为同服务多个视图共享偏好的场景提供源码依据;本轮没有创建原生窗口。其他 origin 的 partition 分开,不把跨服务身份串用作为本项。OS 通知授权仍独立校验,native 权限处理仍要求可信 origin,默认取消;mode 被恢复不会授予系统权限。确定的问题是用户明确关闭的应用偏好被另一视图的无关编辑覆盖。若系统权限已由用户授予,通知是否真实出现仍需单独 UI 验收,不能从 eligible 推断已投递。
桌面优化方案与验收
去重与源码
#42 是通知权限已拒绝后的恢复路径及重复提示;这里使用不存在 Notification API 的 fixture,单独证明应用偏好陈旧写回。#67 为审批意图协调,不覆盖通知设置存储。#41 为外观设置滚动和保存范围。本条只保留“跨视图整份陈旧偏好覆盖”一个主因,关联 Epic #31。
公开固定提交用于导航;当前源文件哈希是此次逻辑证据,不宣称发行包或实际 OS 通知事故:NotificationSettings、threadNotifications、main.cjs、policy.cjs。