> 2026-09-30：录音目录已迁移到后端 `speaker-directory/summary`、`list`、`seen`。下文的本机新增记录、全名单扫描及 2,000 人上限是旧版实现记录；当前实现与验证范围见 [统一目录对接](speaker-directory-integration-2026-09-30.md)。

# 已识别说话人：入口统计、本机新增提醒与本人引导

## 本轮交互

- 录音页入口显示合并后人数：已标记按稳定 personKey 去重，加未标记候选总数。同名不同身份不合并，同一个人关联多个说话人只算一个。
- 有尚未查看的新增时，入口第二行显示「新识别 N 个」；无新增不占用第二行。加载失败不伪装为零。
- 本人按账号归属 isCurrentUser 判断，在「全部／已标记」中始终排第一；其余按用户选择排序。搜索仍筛选本人，「未标记」不混入已标记本人。
- 未找到本人时，读取现有 voiceprint.status，区分未录入、处理中、已录入但尚未匹配。状态请求失败不声称没有声纹。
- 复用「从录音中标记我」和「录入我的声纹／管理声纹」。前者返回录音页，明确引导先试听、点击说话人名称并选择自己；不会把创建同名角色当作账号身份绑定。后者进入现有声纹流程，不自动打开麦克风或提交录音。

## 本机新增口径与边界

- 按环境和账号在当前 Web 源保存已知身份、上次完整名单、待查看身份；首次完整读取静默建立基准，不把全部历史报为新增。
- 未标记新增使用 Host 签发的稳定只读 identityKey，不使用 30 分钟到期的 candidateRef。identityKey 通过本机持久密钥、环境、账号、上游候选 ID 生成；不是权限凭据，不被标记等写接口接受，不存姓名、录音正文或声纹音频。
- 只有完整且 fresh 的名单才能产生新增统计；部分加载、上限截断、游标异常或网络失败时不提供精确新增数。总数可先使用服务端轻量汇总，不必等所有元数据加载完。
- 正常进入并成功呈现列表后清除已知待查看提示；后续完整名单成功呈现后更新已查看基准。失败或账号切换后的迟到响应不确认未知数据。
- 同一身份继续讲话、改名、临时引用轮换不产生新增。曾见过的身份消失后再出现也不重复提醒。
- 现有接口缺少合并和重聚类的身份继承关系。一次快照里同时有旧身份消失、新身份出现时，本机版保守不报这些新身份，避免把合并误当新识别。因此同时发生合并和真正新增时可能漏报，不承诺严格事件级统计。
- 仅本机、当前浏览器源保存查看进度；退出／切换账号清理内存列表，持久查看进度仍按账号隔离。禁用本地存储时降级到本次运行记忆。
- 录音页活跃且页面可见时每分钟检查本机缓存；已标记名单缓存一分钟，完整候选名单缓存五分钟，到期后后台更新。入口和列表共用同账号快照及进行中的读取，不因切换入口重读；显式刷新或标记变更使缓存失效。仍沿用单次 40 页／2,000 个候选上限；跨端登录不会同步已查看进度。

## 后端后续建议（字段是建议，不是已上线接口）

建议增加按当前登录账号授权的统一轻量目录摘要和查看游标：

1. 摘要：deduplicated_total、unseen_count、snapshot_version、state、latest_change_cursor。总数与新增必须在同一身份合并规则和快照中计算。
2. 稳定 person/identity key，以及 merged_into、split_from 或等效身份继承信息；新增事件采用首次识别入库序号，不使用录音发生时间或可重算的 first_seen_at。
3. 查看确认：按已成功展示的 change_cursor 幂等确认，不以服务端收到请求的当前时间清除未来新增；离线、失败不推进游标。
4. 明确跨端已读是否共享。建议同账号共享，但与录音消息已读分离；合并已看过的身份不产生新提醒，多个尚未查看身份合成一人时仅计一人。
5. 列表返回与摘要一致的快照版本，并支持服务端 frequent/recent 排序；失败或构建中的摘要不得返回误导性的 0。

## 验证

覆盖总数合并去重、同名不合并、首次基准、累计新增、点开清除、稳定身份、跨账号隔离、重启与存储禁用、部分结果／失败、合并保守降级、本人置顶和三种声纹状态。只使用合成数据验证标记相关逻辑，不在真实账号执行标记或声纹录入。

### 2026-09-28 本地验证结果

- 类型检查、构建通过；相关 23 个测试文件共 304 项通过。最终入口排版调整后，另复跑其中 3 个文件的 36 项，全部通过。
- 3100 独立预览已更新，产物与工作区构建结果一致；桌面客户端未改动，既有登录保持。
- 浏览器确认入口总数单行呈现、返回录音页后总数保留；切换两种排序时已标记本人均在首位。真实账号未制造新候选，新增提示及无本人引导使用合成数据验证。
- 初版浏览器打开列表时未标记接口返回 HTTP 429，页面保留已标记结果，并明确提示列表不完整。该次不能据此声称真实账号全量排序／新增统计均已验证。
- 读取路径核对：入口和列表分别执行候选分页扫描，进入列表会从第一页重读；每次最多 40 页。Host 页缓存仅 10 秒，第一页请求带 refresh。后端本地源码有投影读取每分钟 120 次、旧读取每分钟 20 次的限流；尚未确认线上命中的分支及阈值。重复扫描最可能放大了请求量，但不能断言是此次 429 的唯一原因。
- 用户确认后的收尾已实现：入口和列表共享读缓存；切换页面给予 250ms 请求交接窗口，无消费者时中止网络读取。成功分页保留五分钟，失败重试复用已读页；过期或后端报告游标失效时重建，不混用快照。
- 网络分页间隔至少 750ms。HTTP 429 等待至少 60 秒重试，连续失败指数退避，最多五分钟；其他读取失败从 15 秒开始退避。手动刷新不绕过退避。旧完整名单在后台刷新期间保留，新完整快照完成后整体替换；失败不清空列表，不把旧缓存当作本次新读取成功。
- 缓存只驻留当前页面运行内存，不写入录音或服务端资料。退出／切换账号清空快照并中止请求；晚到响应不得重新写入。标记操作后使相关读取失效。限流恢复不重试任何标记／写操作。
- 收尾新增 12 项自动测试，相关 24 个文件共 **316 项通过**，类型检查、构建和差异检查通过。覆盖入口与列表往返复用、进行中请求交接、失败分页续读、刷新不绕过退避、过期快照替换、账号清理、游标失效与自动恢复。
- 收尾浏览器验证：3100 真实账号完整呈现 **1,990 人**，完整加载后的状态提示和错误均为空；「最近出现」下本人仍优先于最近时间更新的其他候选。返回录音再进入名单后立即展示首批 100 行，无重新加载／不完整提示；总数仍为 1,990。测试后恢复「经常出现」排序。首次大名单扫描仍有等待，不能宣称解决了后端全局分页排序能力；新增提醒及限流自动恢复另由合成数据测试验证，未在真实账号制造新人或故意触发限流。
