@senguoyun/dsh-arkme 0.1.83 → 0.1.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. package/docs/recognized-speaker-directory-backend-handoff-2026-09-28.md +157 -0
  2. package/docs/recognized-speaker-entry-and-visits.md +47 -0
  3. package/docs/recognized-speaker-presence-delivery.md +51 -0
  4. package/docs/recognized-speaker-sorting.md +30 -0
  5. package/lib/client.js +1194 -253
  6. package/lib/client.js.map +1 -1
  7. package/lib/harness-model-client.js +51 -7
  8. package/lib/harness-native-selection-client.js +35 -0
  9. package/lib/harness-sidebar-client.js +20 -0
  10. package/lib/index.js +154 -77
  11. package/lib/persistent-extension.js +1 -1
  12. package/lib/{persistent-runtime-B6vPAaiG.js → persistent-runtime-CuKplHIv.js} +101 -262
  13. package/lib/sdk.js +20 -0
  14. package/lib/types/arkme-service.d.ts +1 -1
  15. package/lib/types/arkme-service.d.ts.map +1 -1
  16. package/lib/types/client/ArkmeAccountUsage.d.ts.map +1 -1
  17. package/lib/types/client/ArkmeModelPricing.d.ts +9 -0
  18. package/lib/types/client/ArkmeModelPricing.d.ts.map +1 -0
  19. package/lib/types/client/ArkmeModelSelect.d.ts.map +1 -1
  20. package/lib/types/client/ArkmeNoteDetails.d.ts.map +1 -1
  21. package/lib/types/client/ArkmeRecognizedSpeakersSurface.d.ts +6 -2
  22. package/lib/types/client/ArkmeRecognizedSpeakersSurface.d.ts.map +1 -1
  23. package/lib/types/client/ArkmeRecordingSurface.d.ts.map +1 -1
  24. package/lib/types/client/ArkmeSidebar.d.ts.map +1 -1
  25. package/lib/types/client/ArkoModelMenu.d.ts.map +1 -1
  26. package/lib/types/client/locales/en.d.ts.map +1 -1
  27. package/lib/types/client/reaction-preview-store.d.ts +1 -0
  28. package/lib/types/client/reaction-preview-store.d.ts.map +1 -1
  29. package/lib/types/client/recognized-speaker-directory.d.ts +36 -0
  30. package/lib/types/client/recognized-speaker-directory.d.ts.map +1 -0
  31. package/lib/types/client/recognized-speaker-order.d.ts +28 -0
  32. package/lib/types/client/recognized-speaker-order.d.ts.map +1 -0
  33. package/lib/types/client/recognized-speaker-tracker.d.ts +33 -0
  34. package/lib/types/client/recognized-speaker-tracker.d.ts.map +1 -0
  35. package/lib/types/client/recordings/RecognizedSpeakerEntry.d.ts +12 -0
  36. package/lib/types/client/recordings/RecognizedSpeakerEntry.d.ts.map +1 -0
  37. package/lib/types/client/recordings/SpeakerSelfGuide.d.ts +8 -0
  38. package/lib/types/client/recordings/SpeakerSelfGuide.d.ts.map +1 -0
  39. package/lib/types/client/recordings/recording-speaker-options-store.d.ts.map +1 -1
  40. package/lib/types/sdk/index.d.ts +10 -0
  41. package/lib/types/sdk/index.d.ts.map +1 -1
  42. package/lib/types/services/chat-service.d.ts.map +1 -1
  43. package/lib/types/services/recording-service.d.ts +2 -5
  44. package/lib/types/services/recording-service.d.ts.map +1 -1
  45. package/lib/types/services/unmarked-speaker-service.d.ts.map +1 -1
  46. package/lib/types/tools/business/recordings/index.d.ts +1 -1
  47. package/lib/types/tools/business/recordings/index.d.ts.map +1 -1
  48. package/lib/types/tools/business/recordings/speaker-presence.d.ts +2 -0
  49. package/lib/types/tools/business/recordings/speaker-presence.d.ts.map +1 -0
  50. package/lib/types/tools/ports/recordings.d.ts +4 -0
  51. package/lib/types/tools/ports/recordings.d.ts.map +1 -1
  52. package/lib/types/types.d.ts +18 -7
  53. package/lib/types/types.d.ts.map +1 -1
  54. package/package.json +5 -5
  55. package/lib/types/recording-speaker-presence.d.ts +0 -28
  56. package/lib/types/recording-speaker-presence.d.ts.map +0 -1
@@ -0,0 +1,157 @@
1
+ # 已识别说话人:统一目录、总数、新增提醒与跨端同步——后端交接
2
+
3
+ 日期:2026-09-28
4
+
5
+ 范围:录音板块的「已识别说话人」。不涉及聊天已读、消息通知或 AI Token 用量。
6
+
7
+ **结论:已标记说话人的出现天数、最近发声时间已接入,不需要重新开发一套统计。当前主要缺统一目录查询和目录级查看进度。建议优先提供统一摘要、统一分页列表、查看确认三个能力;接口路径和字段名均为建议,可扩展现有接口实现。**
8
+
9
+ 核对依据:当前插件实现、3100 预览的本轮实际结果,以及本地 `jotmo-audio` 源码。源码存在不代表所有线上环境已部署;下文单独列出需要确认的项目。旧版 `recognized-speaker-presence-api-handoff-2026-09-27.md` 中「只缺统计/尚未部署」属于当时记录,不能继续当作本轮需求状态。
10
+
11
+ ## 1. 要达到的用户体验
12
+
13
+ - 录音页入口直接显示「已识别说话人 N」。多个原始识别身份标记成同一人后只计一人;同名不同人不能合并。
14
+ - 自上次打开目录后有真正新增时,第二行显示「新识别 M 个」。打开目录并成功展示后清除;同账号其他设备随后也应同步清除。
15
+ - 「经常出现」:出现天数降序,同天数按最近发声时间降序。
16
+ - 「最近出现」:最近发声时间降序,同时间按出现天数降序。
17
+ - 已确认是本人的身份在全部/已标记列表置顶;搜索仍尊重搜索条件,未标记筛选不强行插入本人。
18
+ - 首屏即可得到正确全局排序,不需要前端把几千人全部读完后再排序。后续返回立即展示缓存,只检查更新。
19
+
20
+ 这里的总数是**当前目录合并口径下的可展示身份数**:没有可靠绑定关系的匿名候选仍分别计数,不能承诺已经识别出真实世界全部不重复的人。
21
+
22
+ ## 2. 已有能力与需要确认的项目
23
+
24
+ | 能力 | 当前证据与状态 | 本轮处理 |
25
+ | --- | --- | --- |
26
+ | 已标记身份及绑定账号 | 插件使用 `POST /api/v1/audio/get-speaker-ls`,按绑定账号或独立 Speaker 归组 | 复用,不另造身份系统 |
27
+ | 已标记人的出现天数、最近发声时间 | 插件使用 `POST /api/v1/audio/speaker-presence/list`;本轮预览已显示全历史统计;本地聚合已处理同一绑定用户的多 Speaker 日期并集 | 已有,不重复提为新缺口 |
28
+ | 未标记候选及统计 | `POST /api/v1/audio/unmarked-speakers/list` 已有分页、日期统计、候选标识及投影状态 | 扩展排序/搜索/统一目录能力 |
29
+ | 未标记轻量总数 | 本地后端已注册 `POST /api/v1/audio/unmarked-speakers/count`,含 `total_count/state/published_version/updated_at/retry_after_ms` | 请确认部署和灰度;插件当前尚未专门接入这个 count 路由,这部分是前端可补接,不是要求从零开发 |
30
+ | 已标记者关联的原始识别身份详情 | 插件已对接 `/speaker-presence/detail`,支持 `speaker_id/expected_version`;本次核对的本地后端路由未找到该 detail 注册 | 请后端确认实际分支、部署环境及契约,不直接认定线上不存在,也不默认已验收 |
31
+ | 本人判断、声纹状态及录入 | 当前可从绑定账号判定本人,已有 `/voiceprint/my` 及录入流程 | 置顶和引导本身不需要新接口;统一分页时需把本人信息随目录返回 |
32
+
33
+ 已有候选 ID 跨请求稳定,也已有部分聚类成员信息。**真正缺少的是整个目录跨设备可用的统一身份,以及标记、合并、拆分、重聚类时对「是否新增、是否已查看」的继承规则**,不是完全没有候选 ID。
34
+
35
+ ## 3. 当前前端临时方案及体验边界
36
+
37
+ 1. 总数暂由「已标记人去重数+未标记候选数」拼接。它们不保证来自同一个后端快照,标记与重建交错时可能短暂不一致。
38
+ 2. 新增提醒保存在当前浏览器源、当前账号下。首次完整读取静默建立基准;换设备不能同步查看状态。
39
+ 3. 前端无法准确识别「旧候选消失+新身份出现」究竟是合并还是新发现,因此保守抑制这次新增;同时发生合并和真正新增时可能漏报。
40
+ 4. 全局排序、搜索目前依赖读取全部元数据;最多 40 页/2,000 个未标记候选是**插件当前的保护上限,不是后端产品上限**。超过上限只展示部分结果,不能保证全局排序与搜索完整。
41
+ 5. 已实现入口/列表共享缓存、分页复用和限流退避。本轮真实账号完整读到 1,990 个目录身份,再次进入能直接显示;但首次补齐仍慢,不能靠缓存解决首次正确排序。
42
+ 6. 现有后端已有 `scan_truncated`、整理中数量等信息;插件适配层也应完整透传,不能将已有字段未接入误列为后端缺失。
43
+
44
+ ## 4. P0:本轮优先补齐的能力
45
+
46
+ ### A. 统一轻量摘要
47
+
48
+ 建议能力名:`speaker-directory/summary`。
49
+
50
+ 一次读取返回账号级、同快照的:
51
+
52
+ | 字段示意 | 含义 |
53
+ | --- | --- |
54
+ | `total_count`、`marked_count`、`unmarked_count` | 当前可展示目录去重数;三个字段必须同快照且口径一致 |
55
+ | `unseen_count` | 自目录查看基准之后的新增身份数,按当前合并结果计数,不是「总数之差」 |
56
+ | `snapshot_version`、`updated_at` | 与列表绑定的快照版本及更新时间 |
57
+ | `state`、`coverage` | `fresh/stale/building/failed`;数据是否完整,不能把截断结果称为全量 |
58
+ | `change_cursor` | 这个快照覆盖到的变化边界,供查看确认和后续增量使用 |
59
+ | `retry_after_ms` | 整理中、失败或限流时的重试建议 |
60
+
61
+ 要求:入口统计不遍历名单、不逐人查询、不在每次读取时同步扫描全部录音。无可用快照时返回明确的未知值/状态,不能用 `0` 冒充空目录。存在旧快照时可返回旧数值并明确标记为过期。
62
+
63
+ 可复用现有未标记 count 与已标记 presence 投影,但需要后端给出两者一致的合并结果;单纯把两个不同时点的接口相加不能替代统一摘要。
64
+
65
+ ### B. 已标记+未标记的统一分页、全局排序和搜索
66
+
67
+ 建议能力名:`speaker-directory/list`。
68
+
69
+ 请求支持:`filter=all|marked|unmarked`、`sort=frequent|recent`、`query`、`limit`、`cursor`,以及与摘要一致的 `snapshot_version` 或等效机制。
70
+
71
+ 每行至少包含:稳定的账号内 `person_key`、类型、展示名称/编号、头像引用、`is_self`、`day_count`、`last_seen_at`、详情定位引用。稳定身份 ID 不是授权凭据;任何详情/标记请求仍需验证当前登录账号。
72
+
73
+ 关键规则:
74
+
75
+ - 先按实际身份合并,再排序分页。全部列表必须混排,而不是「已标记排完再排未标记」。
76
+ - frequent:`day_count DESC, last_seen_at DESC, person_key ASC`;recent:`last_seen_at DESC, day_count DESC, person_key ASC`。本人按前述筛选规则优先,仍只出现一次。
77
+ - 当前未标记固定排序在同天数时先比较发声总时长,不符合本次「同天数看最近时间」规则;不能只给现有排序改一个名字。
78
+ - `last_seen_at` 统一指最后一个有效发声片段的时间,不能混成文件结束、身份修改或入库时间;天数继承已确认的录音自然日去重口径。
79
+ - 游标绑定登录账号、快照、筛选、搜索、排序;换排序不复用旧游标。快照失效时明确返回失效状态,不静默拼接新旧结果。
80
+ - 超过 2,000/10,000 身份也可持续分页;只加载第一屏就能得到该筛选下正确的第一屏排序。搜索应覆盖完整目录,而非前端已加载部分。
81
+ - 只有声纹授权、通讯录联系人、从未在录音出现的空身份,不应自动算作已识别的人;保留旧空身份如有产品需要,请返回明确类别并单列口径。证据不足/处理中是否进总数也必须与可展示列表一致,不能计数却无法查看。
82
+
83
+ ### C. 目录级「新增」及跨端查看确认
84
+
85
+ 建议能力名:`speaker-directory/seen`。确认请求携带**已成功展示快照的** `through_cursor`,不使用客户端时间。
86
+
87
+ - 「已查看」表示用户已打开该目录,不代表逐人读过每一张卡片,更不是录音消息已读。
88
+ - 为匹配「点进去提示就去掉」,第一屏成功展示后,可确认该目录快照覆盖到的新增事件;后续分页无需全部滚到底。不能拿一个新摘要的游标去确认仍在显示的旧快照。
89
+ - 同账号各端共享,确认幂等、只向前推进;旧设备较晚提交旧游标不能覆盖新游标。
90
+ - 用户打开快照 C 后,新身份 D 才到达:确认 C 不能清除 D。加载失败、离线、账号切换后的迟到响应都不能推进查看边界。
91
+ - 发布此能力时设定账号级首次基准,不把已有几年历史全部报成新增;后续换设备或重装不重新初始化。
92
+
93
+ 新增必须依据服务端首次发现/进入目录的事件序号,而不是录音发生的 `first_seen_at`:今天上传旧录音发现新对象,应按今天发现处理。已知人再次讲话、改名、重新转写、引用过期不算新增。
94
+
95
+ ### D. 身份继承:为上述统计提供正确依据
96
+
97
+ 可内部维护事件和映射,不强制将全部关系暴露给前端。需明确:
98
+
99
+ - 未标记 A、B 标记成同一人 P:目录只剩 P,计 1;标记动作本身不新增一人。
100
+ - A、B 都未查看时合成 P,待查看数按 1;已查看身份的纯合并不能重新提醒。
101
+ - 已查看身份拆分或技术重聚类,继承其已知/查看状态;不能因换 ID 把历史全变成新增。若确实发现之前未覆盖的新对象,由后端明确产生发现事件。
102
+ - 合并与真正新增 X 同时发生,仍正确提示 X;不能因为总数没增加就漏报。
103
+ - 同昵称但无绑定关系不能合并;同一绑定用户的多个 Speaker 或多个候选归属同一正式人,按确认关系合并。
104
+ - 删除、恢复、取消标记、重新绑定、撤销合并需有明确继承规则。已看过对象的恢复默认不当新发现;有效名单和统计随录音删除/恢复更新。
105
+
106
+ ## 5. P1:更及时的更新与更稳的服务保障
107
+
108
+ 1. **变化检查/增量读取**:摘要支持条件版本检查,或提供 `changes(since_cursor)` 返回新增/更新/移除以及新版本。版本未变无需下发完整名单。若使用推送,只推账号级「目录变了」通知即可,不需推音频或 ASR 原文。
109
+ 2. **可解释的退避**:请在 429 返回明确错误码、`Retry-After` 或 `retry_after_ms`。区分限额耗尽、旧路径计算锁占用、基础设施异常;前端能保留内容并按服务端建议重试。
110
+ 3. **确认轻量投影已覆盖目标环境**:本地源码存在新投影读取和旧同步读取两条路径,限频不同。请确认灰度、部署版本及 count/list 的一致性;不要单纯取消限流。前端发生过 429,尚未取得服务端日志,不能断定线上一定走哪条路径。
111
+ 4. **原始身份详情核验**:确认 `/speaker-presence/detail` 对应分支及部署,返回与列表一致的版本、全历史关联编号、统计、分页或明确覆盖范围;不要为已有接口重复开发另一条同义接口。
112
+
113
+ 本人置顶、无本人时显示引导、按钮布局和空态都可由前端完成。后端只需可靠的账号绑定及声纹状态;可选在摘要中返回 `self_person_key/self_state` 减少额外请求,不是首期必需的新模块。
114
+
115
+ ## 6. 迁移和客户端配合
116
+
117
+ - 当前插件的 `personKey/identityKey/candidateRef` 有本机密钥封装,不能直接作为各端通用 ID。后端提供账号内稳定身份,插件 Host 负责适配;前端不上传本机 HMAC 并假定后端能还原。
118
+ - 本机新增记录不是权威历史。最小迁移方案是后端统一一次性静默基准,之后各端共用后端游标;不要每台新设备把全量旧人重新报新。
119
+ - 如果必须保留上线前每台设备尚未查看的提醒,需要另定可验证映射和幂等迁移流程,不能悄悄以客户端列表覆盖后端查看状态。
120
+ - 后端统一查询落地后,插件移除「为全局排序扫描全部名单」的降级路径,改用服务端分页;保留同账号缓存、请求合并、失效保护和退避。
121
+ - 同步透传已有版本、截断、状态与退避字段,并接入已部署的轻量 count;这是客户端对接工作,不全部算成后端新增需求。
122
+
123
+ ## 7. 联调验收清单
124
+
125
+ | 场景 | 预期 |
126
+ | --- | --- |
127
+ | 3 个候选标记为同一人 | 总数相应合并为 1;摘要和列表一致 |
128
+ | 多轨道同一天有讲话 | 人级出现 1 天,最近时间取最后有效片段 |
129
+ | 同天数但发声时长不同 | frequent 仍按最近时间作为第二排序条件 |
130
+ | 本人不在普通排序第一页 | 全部/已标记第一页仍置顶本人,后续页不重复 |
131
+ | 超过 2,000/10,000 身份 | 首屏全局排序正确,跨页无漏项/重复,搜索可命中后部数据 |
132
+ | 同一个人又说了几天、改名 | 天数/时间更新,不增加新增人数 |
133
+ | 合并两个未查看候选 | 新增人数由 2 变 1,不额外产生第三个新人 |
134
+ | 已查看人重聚类+真正新增同时发生 | 旧人不重报,新人不漏报 |
135
+ | 今天导入上月录音发现新对象 | 按发现事件计新增,不因录音日期旧而漏报 |
136
+ | A 端打开目录,B 端检查 | 两端查看状态一致,无需重新加载全部身份 |
137
+ | A 确认旧快照时又来了新人 | 新人提示保留;重复确认安全,旧确认不回退状态 |
138
+ | 初始化/换设备/重装 | 历史不全部报新,不重置其他端已查看状态 |
139
+ | 构建中、截断、429、服务故障 | 不把未知显示为 0;保留旧快照并明确状态,按建议重试 |
140
+ | 伪造其他账号身份或游标 | 拒绝访问;缓存、计数、详情和查看状态均账号隔离 |
141
+
142
+ 以上均可使用合成身份/录音夹具验收,不应为测试擅自修改真实用户的说话人归属或声纹。
143
+
144
+ ## 8. 请后端回复的交付信息
145
+
146
+ 1. 哪些能力可直接扩展现有接口,哪些需要新接口;最终请求/响应示例和字段口径。
147
+ 2. P0(三个读取/确认能力及其身份继承规则)的排期,以及 P1 的拆分计划。
148
+ 3. 已部署环境、版本或分支、灰度范围;特别是 count 和 presence/detail 的当前状态。
149
+ 4. 身份合并/拆分/首次基准规则、快照和游标失效方式、限流退避约定。
150
+ 5. 可用的合成测试账号与验收结果,避免将「本地有代码」等同「插件已能在线调用」。
151
+
152
+ ### 核对入口(仓库相对路径)
153
+
154
+ - 插件:`src/client/recognized-speaker-directory.ts`、`recognized-speaker-tracker.ts`、`recognized-speaker-order.ts`、`ArkmeRecognizedSpeakersSurface.tsx`。
155
+ - 插件适配:`src/services/unmarked-speaker-service.ts`、`src/services/recording-service.ts`。
156
+ - Audio:`gin/api/router.go`、`gin/api/audio_unmarked_speaker.go`、`gin/api/audio_speaker_presence.go`。
157
+ - Audio 数据口径:`internal/audio/unmarked_speaker_candidates.go`、`internal/audio/speaker_presence_stats.go`、`internal/audio/repository.go`。
@@ -0,0 +1,47 @@
1
+ # 已识别说话人:入口统计、本机新增提醒与本人引导
2
+
3
+ ## 本轮交互
4
+
5
+ - 录音页入口显示合并后人数:已标记按稳定 personKey 去重,加未标记候选总数。同名不同身份不合并,同一个人关联多个说话人只算一个。
6
+ - 有尚未查看的新增时,入口第二行显示「新识别 N 个」;无新增不占用第二行。加载失败不伪装为零。
7
+ - 本人按账号归属 isCurrentUser 判断,在「全部/已标记」中始终排第一;其余按用户选择排序。搜索仍筛选本人,「未标记」不混入已标记本人。
8
+ - 未找到本人时,读取现有 voiceprint.status,区分未录入、处理中、已录入但尚未匹配。状态请求失败不声称没有声纹。
9
+ - 复用「从录音中标记我」和「录入我的声纹/管理声纹」。前者返回录音页,明确引导先试听、点击说话人名称并选择自己;不会把创建同名角色当作账号身份绑定。后者进入现有声纹流程,不自动打开麦克风或提交录音。
10
+
11
+ ## 本机新增口径与边界
12
+
13
+ - 按环境和账号在当前 Web 源保存已知身份、上次完整名单、待查看身份;首次完整读取静默建立基准,不把全部历史报为新增。
14
+ - 未标记新增使用 Host 签发的稳定只读 identityKey,不使用 30 分钟到期的 candidateRef。identityKey 通过本机持久密钥、环境、账号、上游候选 ID 生成;不是权限凭据,不被标记等写接口接受,不存姓名、录音正文或声纹音频。
15
+ - 只有完整且 fresh 的名单才能产生新增统计;部分加载、上限截断、游标异常或网络失败时不提供精确新增数。总数可先使用服务端轻量汇总,不必等所有元数据加载完。
16
+ - 正常进入并成功呈现列表后清除已知待查看提示;后续完整名单成功呈现后更新已查看基准。失败或账号切换后的迟到响应不确认未知数据。
17
+ - 同一身份继续讲话、改名、临时引用轮换不产生新增。曾见过的身份消失后再出现也不重复提醒。
18
+ - 现有接口缺少合并和重聚类的身份继承关系。一次快照里同时有旧身份消失、新身份出现时,本机版保守不报这些新身份,避免把合并误当新识别。因此同时发生合并和真正新增时可能漏报,不承诺严格事件级统计。
19
+ - 仅本机、当前浏览器源保存查看进度;退出/切换账号清理内存列表,持久查看进度仍按账号隔离。禁用本地存储时降级到本次运行记忆。
20
+ - 录音页活跃且页面可见时每分钟检查本机缓存;已标记名单缓存一分钟,完整候选名单缓存五分钟,到期后后台更新。入口和列表共用同账号快照及进行中的读取,不因切换入口重读;显式刷新或标记变更使缓存失效。仍沿用单次 40 页/2,000 个候选上限;跨端登录不会同步已查看进度。
21
+
22
+ ## 后端后续建议(字段是建议,不是已上线接口)
23
+
24
+ 建议增加按当前登录账号授权的统一轻量目录摘要和查看游标:
25
+
26
+ 1. 摘要:deduplicated_total、unseen_count、snapshot_version、state、latest_change_cursor。总数与新增必须在同一身份合并规则和快照中计算。
27
+ 2. 稳定 person/identity key,以及 merged_into、split_from 或等效身份继承信息;新增事件采用首次识别入库序号,不使用录音发生时间或可重算的 first_seen_at。
28
+ 3. 查看确认:按已成功展示的 change_cursor 幂等确认,不以服务端收到请求的当前时间清除未来新增;离线、失败不推进游标。
29
+ 4. 明确跨端已读是否共享。建议同账号共享,但与录音消息已读分离;合并已看过的身份不产生新提醒,多个尚未查看身份合成一人时仅计一人。
30
+ 5. 列表返回与摘要一致的快照版本,并支持服务端 frequent/recent 排序;失败或构建中的摘要不得返回误导性的 0。
31
+
32
+ ## 验证
33
+
34
+ 覆盖总数合并去重、同名不合并、首次基准、累计新增、点开清除、稳定身份、跨账号隔离、重启与存储禁用、部分结果/失败、合并保守降级、本人置顶和三种声纹状态。只使用合成数据验证标记相关逻辑,不在真实账号执行标记或声纹录入。
35
+
36
+ ### 2026-09-28 本地验证结果
37
+
38
+ - 类型检查、构建通过;相关 23 个测试文件共 304 项通过。最终入口排版调整后,另复跑其中 3 个文件的 36 项,全部通过。
39
+ - 3100 独立预览已更新,产物与工作区构建结果一致;桌面客户端未改动,既有登录保持。
40
+ - 浏览器确认入口总数单行呈现、返回录音页后总数保留;切换两种排序时已标记本人均在首位。真实账号未制造新候选,新增提示及无本人引导使用合成数据验证。
41
+ - 初版浏览器打开列表时未标记接口返回 HTTP 429,页面保留已标记结果,并明确提示列表不完整。该次不能据此声称真实账号全量排序/新增统计均已验证。
42
+ - 读取路径核对:入口和列表分别执行候选分页扫描,进入列表会从第一页重读;每次最多 40 页。Host 页缓存仅 10 秒,第一页请求带 refresh。后端本地源码有投影读取每分钟 120 次、旧读取每分钟 20 次的限流;尚未确认线上命中的分支及阈值。重复扫描最可能放大了请求量,但不能断言是此次 429 的唯一原因。
43
+ - 用户确认后的收尾已实现:入口和列表共享读缓存;切换页面给予 250ms 请求交接窗口,无消费者时中止网络读取。成功分页保留五分钟,失败重试复用已读页;过期或后端报告游标失效时重建,不混用快照。
44
+ - 网络分页间隔至少 750ms。HTTP 429 等待至少 60 秒重试,连续失败指数退避,最多五分钟;其他读取失败从 15 秒开始退避。手动刷新不绕过退避。旧完整名单在后台刷新期间保留,新完整快照完成后整体替换;失败不清空列表,不把旧缓存当作本次新读取成功。
45
+ - 缓存只驻留当前页面运行内存,不写入录音或服务端资料。退出/切换账号清空快照并中止请求;晚到响应不得重新写入。标记操作后使相关读取失效。限流恢复不重试任何标记/写操作。
46
+ - 收尾新增 12 项自动测试,相关 24 个文件共 **316 项通过**,类型检查、构建和差异检查通过。覆盖入口与列表往返复用、进行中请求交接、失败分页续读、刷新不绕过退避、过期快照替换、账号清理、游标失效与自动恢复。
47
+ - 收尾浏览器验证:3100 真实账号完整呈现 **1,990 人**,完整加载后的状态提示和错误均为空;「最近出现」下本人仍优先于最近时间更新的其他候选。返回录音再进入名单后立即展示首批 100 行,无重新加载/不完整提示;总数仍为 1,990。测试后恢复「经常出现」排序。首次大名单扫描仍有等待,不能宣称解决了后端全局分页排序能力;新增提醒及限流自动恢复另由合成数据测试验证,未在真实账号制造新人或故意触发限流。
@@ -0,0 +1,51 @@
1
+ # 已识别说话人全历史统计
2
+
3
+ 本次延续用户指定的 dev 基线与任务 worktree。UI 布局、标记、搜索、筛选和导航保留;临时七天扫描替换为 Audio 全历史 owner。统计表示 system ASR 中已确认人物的出现,不能与声纹调用账本或授权目录混用。
4
+
5
+ | 能力面 | 接入方式 | 完成证据 |
6
+ | --- | --- | --- |
7
+ | UI | 既有已识别说话人列表与人物原始声音详情 | 原始布局实机验收;列表/详情统一全历史,版本变化刷新、非 fresh 数字隐藏、账号切换、卸载取消测试通过 |
8
+ | Tools | arkme_speaker_presence,只读列表/详情,不透明 Speaker 引用 | 正式 catalog/schema/grant 注册;官方未修改 DSH 0.1.5-rc.2 的真实 agent session 发现并调用成功 |
9
+ | SDK | recordingSpeakerCandidates/Presence/Members,speakerPresence capability,AbortSignal | 隔离安装 tgz 的仓外 Consumer,strict/NodeNext 编译执行;不支持 capability 与取消场景通过 |
10
+ | Host owner | RecordingService | UI/Tool/SDK 共用权限、账号绑定引用、字段校验与后端;服务测试和真实本地 Audio 联调通过 |
11
+
12
+ 无新增配置项、版本号修改或旧服务七天回退。不改变既有 OpenAPI 转写读取的 owner;新 Tool 只暴露本目录统计,不提供第二套转写/日历读取接口。
13
+
14
+ ## 验证
15
+
16
+ - Node 24.19.0;typecheck、build 通过。
17
+ - 全量:最终 dev `bcf37019` 合并后,811 个文件通过、11 个跳过;9,547 条测试通过、15 条跳过。
18
+ - `tests/consumers/speaker-presence-consumer.mts` 仅导入公开 SDK。Consumer 在仓外、含空格目录,以 strict/exactOptionalPropertyTypes/NodeNext 编译并执行。
19
+ - `tests/e2e/speaker-presence.e2e.mjs` 经正式 CLI 安装的 tgz,使用官方 DSH 的公开 boot fallback 和原测试 Scaffold。统计转发真实本地 Audio/Mongo,鉴权及其他无关上游为隔离桩;列表和详情都返回 2 天、原始声音 12;正式取消接口使统计减为 1 天,再经原候选 UI 确认标记恢复 2 天;正式 Audio 软删除后隐藏统计,恢复后重新显示 2 天。
20
+ - E2E 需要 `ARKME_DSH_CHECKOUT`、`ARKME_PACKED_PROFILE`、仅允许 127.0.0.1 的 `ARKME_AUDIO_E2E_ORIGIN`、测试 TLS key/cert 与固定种子账号。它不在默认单元测试中访问真实服务。
21
+ - DSH 源码、用户 Profile、常驻 DSH、插件版本、根 README 未修改。tgz 的旧 peer 自动安装在当前 registry 不完整,隔离安装关闭自动补齐 peer,并通过官方 `healProfilesModuleFallback` 接入运行时已有依赖;没有手写运行时软链或产品 fallback。
22
+
23
+ ## 运行边界
24
+
25
+ 后端先更新全部源写入进程及清理 cron,再发布本批插件。后端未就绪会显式失败,不返回近七天数据冒充全历史。统计版本校验为读取观察到的完整版本,不承诺数据库事务快照。
26
+
27
+ Audio 热读仍为 O(Child + 摘要桶),本地五次采样约 8,760 分片 130–206ms、52,560 分片 0.99–1.36s、525,600 分片 11.31–19.89s。不是 P95;高密度性能是发布前需按实际负载确认的边界,未宣称所有账号秒级。固定后端读取预算 25 秒,无新增配置开关。
28
+
29
+ 本次开发与修复已提交到任务开发分支并推送;未合并、创建 PR 或部署。正式发布前仍需实际环境容量验收。
30
+
31
+ ## 合并前复审(2026-09-28)
32
+
33
+ - 已同步 dev 的 AI points 改动(独立 SDK import/export 均保留),以及后续 `bcf37019` 的快记/群互动修复;后者自动合并无冲突,重新完成全量验证。
34
+ - 修复手动刷新未中止旧统计轮询的竞争,以及旧分页请求结束后误释放新请求的忙碌状态;原 UI 和交互入口不变。
35
+ - 真实写链路发现 Audio 取消例外字段 `qu` 未读取、候选确认只改轨道却未重新标记取消片段;两项在 Audio owner 修复,前端不伪造统计来补偿写入错误。
36
+ - E2E 种子由 Audio `tools/fixtures/speaker_presence_e2e.js` 提供,只可用于任务隔离 Mongo 测试库。页面测试需匹配本批 Audio 版本。
37
+ - 验收范围为 macOS Chrome、官方未修改 DSH 0.1.5-rc.2、正式安装的不可变 tgz;不据此声称 Windows/Linux 或生产环境已经验收。
38
+
39
+ 最新合并前容量复测:525,600 个 Child 串行 5 次读取为 10.27–10.92 秒;与本机其他测试并发时一次读取触发 25 秒截止。两者均非生产 P95。高密度及目标机器并发性能门禁仍未关闭,当前不能无条件建议上线合并。完整场景矩阵和五项审查修复记录在同任务 Meta 的合并前复审文档。
40
+
41
+
42
+ ## 原页面业务口径复核
43
+
44
+ 最近出现时间保持原交接和原临时统计的有效片段结束时间最大值;日期仍按录音本地开始日去重。Audio 摘要算法 3 修正了开发算法 2 曾使用开始时间的问题。原未标记卡片本就优先读取 latest_day_end_at,本轮不改其计算、排序或交互。插件产品代码没有额外修改,仅 E2E 增加列表/详情和取消、重标前后的精确结束时间断言。
45
+
46
+ 原不可变包连接修正后的真实本地后端,SDK、Tool 和 Chrome 页面完整链路通过(14.19 秒);相关 UI/服务测试 5 文件 / 131 条通过。高密度性能限制仍按上节保留。
47
+
48
+
49
+ ## 最终审核补充
50
+
51
+ 任务分支已合入 dev `8c48a6b8`(v0.1.83 来自上游),类型检查、完整测试 9,550 条、构建和打包通过。新不可变包在官方 DSH 原运行时连接本地 Audio 的 SDK、Tool 与页面写读链通过(18.17 秒),仓外 SDK Consumer 编译执行通过。本轮没有额外前端产品改动。Audio 修复单候选确认后的历史天数被最近六个展示日期截断的回归,并修正多候选日期并集;原 UI 操作入口与流程保持一致。高密度账号性能阻断仍未关闭。
@@ -0,0 +1,30 @@
1
+ # 已识别说话人排序
2
+
3
+ ## 交互
4
+
5
+ - 搜索框右侧提供「经常出现」「最近出现」;默认经常出现。
6
+ - 经常出现:出现天数降序,同天数按最近时间降序。
7
+ - 最近出现:最近时间降序,同时间按出现天数降序。
8
+ - 完全相同的统计按名称自然序和稳定引用排序;未知或失效统计不冒充 0 天。
9
+ - 全部、已标记、未标记共用规则,全部不再把已标记固定排在前面。后续本人置顶:账号确认归属的本人在全部/已标记筛选内优先,其余仍遵循排序;搜索和未标记筛选不额外插入本人。
10
+ - 选择按账号保存在当前 Web 源的 localStorage,不承诺跨端同步;筛选、搜索不重置选择。
11
+
12
+ ## 数据和分页
13
+
14
+ 已标记使用正式全历史 presence 统计。未标记目录额外透传已有的 appearanceDays、latestAtMillis 数值,禁止解析展示文案来排序。
15
+
16
+ 现有 Audio 未标记接口固定按 day_count、total_speech_duration_ms、last_seen_at 排序,无 sort 参数。插件串行读取列表元数据,不读取音频或逐人详情;补齐后才具有完整排序覆盖。读取中、失败、投影未就绪和游标版本变化均明确标识不完整;旧版本游标重启一次,取消或账号切换后忽略晚到结果。
17
+
18
+ 单次自动遍历最多 40 页、2,000 个未标记候选,与 Host 当前候选引用容量对齐。到达边界而仍有更多数据时保留「列表尚未完整」提示,不宣称全量排名。显示每批 100 行只是渲染限制,搜索和排序仍覆盖所有已加载记录。
19
+
20
+ 2026-09-28 补充共享读缓存:录音页入口与名单页共用分页和完整快照;失败保留已读取页面,限流退避后续读,不因反复进入页面从头发起全部请求。完整名单保留五分钟后后台更新,标记后失效重读。详见 `recognized-speaker-entry-and-visits.md`。
21
+
22
+ ## 后端后续能力
23
+
24
+ 大于上述边界或希望避免扫描全部元数据时,需要 Audio 列表正式提供服务端排序:frequent = day_count DESC、latest_day_end_at DESC、candidate_id ASC;recent = latest_day_end_at DESC、day_count DESC、candidate_id ASC。游标应绑定账号、投影版本、筛选及排序规则;切换排序不得复用旧游标。若提供统一的已标记/未标记轻量索引,可直接支持混合全局分页。当前插件没有发送未经支持的 sort 参数,也没有修改 Audio 服务。
25
+
26
+ ## 验证范围
27
+
28
+ 排序比较、本机记忆、全量元数据遍历、跨页最新人物、混合分类、搜索、分批渲染、游标失效、刷新竞争、取消、失败和读取上限均有自动测试。8 个相关测试文件共 154 项通过,类型检查、构建和差异检查通过。
29
+
30
+ 2026-09-28 在固定 3100 独立 Web 预览验证:两种排序均切换实际名单;已标记和未标记按统计混合排列;筛选、搜索可配合排序;刷新并重新进入后保留「最近出现」选择。测试后恢复「全部+经常出现」并清空搜索。当前账号分批加载结束后,加载及不完整提示均消失;大名单的加载等待仍依赖现有固定顺序分页接口,不能据此承诺首屏即获得完整最近排名。仅进行只读列表检查,未修改录音或说话人标记。