# 社交手机号缓存修复

基线：official/dev eb306f5443f7c6376c42e548bc34795f2692ed40。

范围：沿用现有按钮、绑定提示和账号设置。只修复 UI 提交前的绑定状态缓存，不修改登录强绑策略、Host 权限或服务端接口，不自动重放用户操作。

| 能力面 | 本次处理 |
| --- | --- |
| UI | 复用现有社交操作 guard，持久保存确认状态和时间；过期后台刷新，失败保留旧状态；绑定/解绑确认后立即同步 |
| Host owner | 复用既有 user.profile / user.profile.refresh 和 auth.phone.verify / auth.phone.unbind；无新增查询、命令、存储或授权能力 |
| Tools / SDK | N/A：本次只改变内置 UI 状态与操作提示，没有新增 Host 业务能力；既有业务授权与错误合同保持基线 |
| Client / Harness | 无原生桥或装配变化，不修改客户端及常驻运行实例 |

缓存不是服务端授权。跨设备解绑由后台刷新及业务服务端权限校验处理；既有服务端校验覆盖缺口不在本次 UI 小修中伪装为已解决。

性能验证针对重复发送、缓存过期、慢/失败刷新、多组件挂载及账号切换。按 L2 验证请求次数、共享刷新、超时释放和快路径不等待远端；不以单次墙钟时间宣称吞吐改善。缓存有效期先沿用现有资料缓存的 60 秒；刷新总等待 5 秒，失败重试间隔退避至 60 秒。只在活跃页面持有一个刷新调度器，卸载清理监听和计时器。

## 行为

- 已确认绑定：直接进入原发送流程，不等待过期缓存刷新。
- 已确认未绑定：保留原按钮及原绑定弹窗；草稿保持原样，不生成假发送记录，也不自动重放。
- 首次没有任何状态：先读取既有本地资料，必要时请求服务端；总等待上限 5 秒。失败显示暂时无法确认，不误判为未绑定。
- 缓存过期：共享一次后台刷新；失败保留原值和原确认时间，按 5、10、20、40、60 秒退避重试。
- 绑定/解绑成功：立即更新内存、持久缓存和其他窗口，取消旧读取的覆盖资格；不等待后续完整资料刷新。
- 账号切换：隔离账号状态、取消旧读取；隐藏页面暂停定时刷新，恢复可见或网络恢复后检查过期。

## 验证

- 最终全量 `NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=4`：981 个文件通过、15 个跳过；11,585 项通过、20 项跳过，无失败。
- 缓存、guard、启动及既有社交策略专项：4 个文件、56 项通过；另一次聊天重新编辑、guard 和缓存回归 129 项通过。
- `pnpm run build` 通过，包含类型声明构建、Windows credential helper 校验、插件打包及 timeline worker 冒烟。
- `pnpm pack` 生成本地 3.0.9 测试包，未修改产品版本号、根 README 或锁文件。包 SHA-256：`e022ed31a52aa71c6d2fbafa77febac313e93c6a2e59ad8b433efa90961ea0d5`。
- 使用未修改的官方 DSH 0.1.5-rc.2，经 `dsh plugin --profile web add <tgz>` 安装至独立 DSH_HOME/Profile；依赖固定为该官方运行时版本。安装后的 client.js / index.js 与本次构建逐字节相同，这两个 bundle 未包含本机绝对路径；包清单未混入 .env、.npmrc、.git 或路径穿越条目。
- 独立账号状态目录、钥匙串命名空间、loopback 业务地址，关闭更新、远端和 MCP；实际浏览器显示 Arkme 3.0.9 导航和未登录界面，无控制台 error。验收后关闭本任务页面并停止临时进程。
- Node 25 本机测试使用 `NODE_OPTIONS=--no-experimental-webstorage`，避免实验性全局 localStorage 干扰 jsdom；没有为此修改产品源码。
- 独立 `tests/e2e/social-access.e2e.mjs` 已将“每次 focus/navigation 等待本地资料查询”改为等待真实 TTL/失败冷却后的后台刷新，并保留草稿与绑定流程检查；`node --check` 通过。本次未执行该独立浏览器场景，不纳入以上通过数。

该验证区分 React DOM 发送/绑定回归与实际插件安装激活：尚未使用真实账号/SMS 完成端到端验收。未发布、未推送、未替换用户安装版本。
