# 本地消息缓存与同步复查

2026-10-10 对本次缓存、同步、Worker、主列表/预览、阅读位置和公开适配层作完整复查。复查前为基于 dev `41d4713c` 的任务工作区；主体实现提交为 `87b80f0d`，随后合入 dev `eb364395` 并补齐完整命令的队列预算。未改变客户端、DSH、插件版本、根 README 或依赖。

## 本轮修复

- 完整校准删除正文后，旧请求可能在其他窗口重建已删除事件。补充持久化会话 ticket 围栏；Host 明确拒绝过期提交，不能用网络降级结果重新发布旧正文。
- 共享 canonical 正文中的 token 可能污染其他窗口。读回与 gap 保留现在使用窗口引用自己的 coverage token，同时保持共享正文更新。
- 历史锚点原先通过正文 JSON 扫描查找，改为稳定事件身份索引查询；兼容身份只扫描一次 canonical 内容。
- 重叠窗口 gap 保留重复解析同一正文，改为 SQL 事件去重后解析，跨 token 重复事件也不会再次解析。
- 文本选择结束但没有新滚动时，可见块可能不更新。补充 selectionchange 恢复与卸载清理，布局排序前每候选只读取一次几何位置。
- Worker 排队字节预算原先只统计正文，遗漏刷新 token 等命令参数。现在 admission 统计完整命令，超大参数在 structuredClone 前拒绝，不能绕过队列预算。
- 块身份原先包含末条消息 ID，追加一条消息会重挂整个末块。改为稳定首行身份，1,999→2,000 条追加测试从重挂 40 行降为仅挂载新行，已有 39 行无需释放和重建媒体/反应 owner。

上述场景均先以失败回归复现，再修复通过。另覆盖真实 Host 并发网络结果晚于完整删除校准的拒绝路径。

## 性能证据

macOS、Node 25.5.0，本机同一 worktree、相同 SQLite/WAL 配置。每组 256 窗口 × 40 事件，每事件正文约 1 KiB，20 次操作；审查前后都用单 worker 的 Vitest 执行。数字是本地样本，不是跨平台 SLO。

| 操作 | 审查前 p50 / p95 (ms) | 修复后 p50 / p95 (ms) |
| --- | --- | --- |
| 未变化窗口写入 | 0.298 / 0.852 | 0.226 / 0.357 |
| 历史稳定锚点读取 | 13.059 / 19.082 | 0.150 / 0.220 |
| 40 条正文变化写入 | 1.713 / 3.904 | 1.956 / 7.912 |
| 满容量写入与淘汰 | 1.655 / 3.888 | 1.553 / 3.853 |

正文变化写入尾延迟有抖动，不能据此宣称所有路径提升；该路径未新增随缓存窗口数量重复解析正文的操作。锚点路径的扫描已从热路径移除。确定性测试还确认：

- 256 个重叠窗口、40 条共享事件：gap 保留的 JSON 解析次数从 10,240 降为 40，正文不丢失。
- 256 个满容量窗口继续写入：窗口数保持 256、没有孤立正文、引用计数与窗口事件数一致。
- 未变化窗口连续写 10 次：无整页 metadata 更新。
- 120 条失效通知合并为 20 次写入，峰值并发 1；等待可取消。
- Worker admission、窗口/字节/页数上限、卸载释放、长列表最多 240 行、阅读位置持久化均有回归。

SQL、数据库清理和大部分持久化 JSON 工作在唯一存储 Worker；UI 仍需进行有界投影和内存预算估算，整个进程 RSS 不等于正文预算。

另以隔离编译的真实 Worker 连续进行 20 次 2,000 事件窗口的变更提交与读回（序列化 2,376,339 字节）：功能校验全部通过，p50 82.84 ms、p95 103.09 ms。调用方事件循环监测分辨率 10 ms，观察 p95 11.12 ms、最大 16.65 ms，期间 1 ms timer 获调 1,357 次。该轮与完整测试同时运行，没有对应旧版同负载曲线，仅证明所测窗口的功能、异步存储和主线程存活，不声明全局延迟提升。

最终浏览器 fixture 复验 2,000 条消息：10 次 A→B→A、正文刷新、重载后均保留 `A:1002` / `-15px`。选择文本后跳滚，取消选择即恢复目标可见块，观察最多 120 行，未超过结构上限 240。

## 验证边界

完整测试、类型检查、编译后 Worker、官方 DSH 安装和仓外 SDK Consumer 结果记录在对应 OpenSpec change 的 verification.md。真实账号、常驻客户端、Windows/Linux 和长时运行不由本机 fixture 代替；本次复查结论限定于代码、确定性边界及已测工作负载。


## 2026-10-12 实时刷新修复

真实测试客户端在列表底部连续收消息时发现两层竞争：UI 在读取进行中直接丢弃刷新需求，失败路径不补读；Host 又把普通 sessions-delta 与内容撤回共用提交失效围栏，密集到达时整个读取窗口反复作废。第一轮仅修 UI 的真实 100 条测试确认了后者：网络读取峰值为 1，但连续发送期间出现 12 次 stale 拒绝，发送结束后才追上。该轮不作为实时验收通过证据。

- 每个当前会话只保留一个待刷新标记、一个 250ms 尾随定时器，所有分页读取共享读者计数。读取成功或失败后均能补读，相同版本的通知复用当前请求；账号、会话和导航作用域切换会取消旧任务。定时器不会被后续到达无限推迟，同一版本的 stale 重试最多两次。
- sessions-delta 仅要求后续追赶，允许已确认窗口提交并显示；已观察到的删除、撤回、编辑、成员变化、账号切换仍严格拒绝旧结果。SQL 的硬围栏及完整校准事务不变。
- SQLite 新增有界 refresh_hints 元数据（最多 1,024 个作用域），将“窗口还需追赶”与“结果已被撤销”分开持久化。读取仍返回真实 committed/stale 状态；重启不会把未追平窗口误报为最新。
- 冷加载期间不消费或保存空列表的 viewport。真实页面刷新暴露了空占位提前覆盖历史锚点的问题；完整 Surface 延迟缓存回归先失败，修复后通过。真实客户端切换对话、同源页面刷新后的消息锚点及 -3.125px 偏移完全一致。
- 不新增 Host 路由或 SDK/Tool 能力；UI、现有 SDK 和 Tool 仍共用同一 UnifiedChatTimelineService。客户端与 DSH 源码未修改，插件版本与根 README 未修改。

回归覆盖：100 次读取中到达通知的成功/失败收尾、底部跟随及历史位置；1,000 次通知的固定资源上限；切换会话后的迟到结果；四轮各 100 次到达期间持续提交；硬失效覆盖软刷新；SQLite 重启后的 stale/撤销状态；真实 ArkmeService 的通知路由。

相关 566 条测试全部通过。原有刷新性能用例的请求数保持 40 行 / 40 次事件为 21 次读取，400 行 / 40 次事件为 84 次读取（每次四页）；输入路径没有新增 Host 请求。该轮本机 SQLite 256 窗口基准中，锚点读取 p50/p95 为 0.170/0.194 ms；未变化窗口写入为 0.224/0.366 ms。耗时仅为本机样本，读取次数、队列容量和并发上限是确定性门禁。

阅读位置仍使用既有按浏览器 origin 隔离的 localStorage；本地开发客户端重启后若随机服务端口变化，不会跨 origin 迁移几何数据。消息 SQLite 不受端口变化影响。这一既有边界不等同于同源页面刷新与会话切换的恢复验收。

### 最终验证

- 完整插件测试：915 个文件、10,766 条通过；13 个文件、17 条既有跳过。类型检查、打包构建及官方 DSH 隔离安装通过。运行制品 SHA-256 为 `4abb5da96f1ab132abaaa14d398b6989d1a4790d1e512eab8fb374b857f1ebdf`，安装后的 Browser bundle 与制品一致。
- 全量测试曾出现一次目录读取 22/21 的计时抖动；性能用例改用受控时钟，固定显式通知负载，未放宽原有请求次数断言。完整重跑通过。计数包括消息读取、目录读取、输入期间 Host 请求和组件保留。
- 用户授权追加批次 `20261012-024001`：测试账号 3020 → 3016 连续发送 100 条，序列 33774–33873。3016 服务端回读及本地 SQLite 均逐 UID、序列、正文匹配 100/100，数据库 `quick_check=ok`。
- 发送期间正文先后自动显示到第 12、32、49、68、85 条；发送未结束前已经多次更新，底部跟随阶段 gap 为 0。上翻历史后的 83 次采样中锚点最大漂移为 0px；回到底部可见第 100 条。UI、服务端与 SQLite 共同完成验收。
- 约 49 秒观测内，时间线请求 8 次、峰值并发 1、错误 0；消息 DOM 最多 80 行。请求耗时样本约 1.9–7.0 秒；PerformanceObserver 记录 61 次长任务，最大 80ms。观测含自动化采样及既有页面工作，没有同负载旧版帧耗时对照，因此不据此宣称零卡顿或全局性能提升。结构门禁与此次连续接收验收通过。

原始全测日志、发送 ledger、真实 UI/阅读位置报告、SQLite 核对和截图保存在本任务隔离运行目录，客户端保持在本批第 100 条供人工查看；本轮未发布或替换正式客户端。

### 两条“幽灵未读”的来源

后续截图中的 `2` 来自群互动提醒：当时私聊 `latestSequence=readSequence=33972`、`unreadCount=0`；`private-interaction.summary` 和目录均返回 `attentionCount=2`。指定联系人的完整未读互动查询恰好返回两条“共同群聊分页测试-3016-3020-001”测试 @：`control_before` 与 `control_after`，均为 `unread=true, attention=true`，没有下一页。

产品语义已由用户明确修正：私聊卡片只反映直接私聊消息未读。此前将数字换成 `@2` 的方案不成立，已撤销。移除群互动数兜底角标，以及直接消息有未读时附加的群互动绿点；普通与紧凑目录的数字、免打扰红点、读屏提示均只由当前会话未读决定。群互动摘要与活动排序保留，原群提醒仍由原群管理，不为清除私聊角标写入原群已读游标。

此修正只改变 Browser UI 对已有字段的展示，不新增请求、订阅、定时器或缓存。普通/紧凑、免打扰开/关、有群互动时私聊未读 0→3→103→0 均有回归，并验证全局计数不重复、群互动事实不被清零。

| 能力面 | 本次影响 |
| --- | --- |
| UI | 私聊未读指示只消费私聊事实；原群未读和 @ 预览保留 |
| Host / Tools / SDK | 无新业务入口；已有群互动事实查询语义不变，N/A 新适配 |
| Client / Harness | 沿用当前承载合同；仅安装插件制品，不修改客户端或 DSH 源码 |

最终验证：62 条相关测试通过；类型检查通过；完整测试为 915 个文件、10,770 条通过，13 个文件、17 条既有跳过。命令为 `NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=2 --testTimeout=30000 --hookTimeout=30000`。刷新性能用例仍为 40 行 / 40 次事件读取 21 次、400 行读取 84 次，目录读取均为 21 次；输入期间无新增 Host 请求。

打包构建、归档检查及官方 DSH 安装通过，制品 SHA-256 为 `b4814a1681ed3a2a052b8638ce0349b602896352456bb6da00c2d009ecf48410`，安装后的 Browser bundle 与归档完全一致。隔离测试客户端已重启：宏顺卡片读屏名仅为“宏顺”，头像旁未读指示数量为 0；私聊 `readSequence=latestSequence=34072`、`unreadCount=0`。验收时群互动计数已为 4，仍未投射到私聊角标；原群仍有 1,409 条未读和 @ 提醒。截图与 DOM、Host 事实共同确认结果。本次没有额外发测试消息，也没有推进原群已读游标。


### 提交前复审

2026-10-12 在 `codex/c20261010-local-message-sync` 上重新核对全部待提交修复，相对官方 `dev` 的基线仍为 `eb364395`，复审未发现新的阻塞项。

- 未读：私聊数字、免打扰红点及读屏描述均只使用当前会话未读；群互动不会兜底或附加私聊角标，也不额外计入全局未读；打开私聊不推进原群已读游标。
- 性能与一致性：普通到达只标记需追赶，编辑、删除、成员变化及账号切换保留硬失效；提交 ticket 与原子校准保持不变。UI 待刷新状态为单一标记，尾随 timer 最多一个，同一版本竞争最多重试两次，分页及定位的读者完成后继续处理合并需求，作用域切换释放旧任务。Host 失效队列 512、Worker 请求 32、队列字节 64 MiB、持久刷新提示 1,024 的边界仍受控。已测请求次数及输入期间无新增 Host 请求的结论保持，不能外推为所有设备零卡顿。
- 阅读位置：再次使用当前安装制品完成真实会话切换和同源页面刷新；同一消息锚点保持，偏移从 -50.6484375px 变为 -50.7109375px，差 0.0625px。列表总高度变化未覆盖阅读锚点。冷加载占位不保存空几何数据。随机开发端口变化时仍不跨 origin 恢复位置。
- 验证：本次复审未改变源码、测试、依赖或测试配置，复用上一节最终状态的完整 10,770 条通过 / 17 条跳过、类型检查、构建和制品安装结果。当前客户端复验私聊无角标且原群提醒仍在；没有追加发送测试消息。客户端与 DSH 源码、版本号和根 README 均未修改。

## 2026-10-12 连续性与左侧导航复验

本轮发现前面的“收齐 100 条”不能替代持续运行和帧开销验证。实际旧实例累积了 855 个统一事件，停在验收消息 72/100。随后发送 100 条的基线测试中，3 次完整校准均以 `chat-timeline-window-limit` 失败，UI 没有显示该批新消息：活跃窗口不断累积，每次刷新都重新校准整个历史，触及 4 MiB 响应上限。

左侧导航没有被删除。真实 DOM 中导航宽 60px、位置 x=-61px，外层 Harness frame 的 `scrollLeft=61`；折叠右栏的溢出让本不应滚动的外框可以横向移动。导航相关布局 CSS 与 `dev` 基线一致。本轮在插件已有的外框选择器上使用 `overflow: clip`，不修改 DSH。实际安装包上再次设置 `scrollLeft=61`，得到 `scrollLeft=0`、导航 x=0、宽 60px。

### 实现与一致性边界

- 底部追新使用现有 Host 统一时间线的完整最新页（常规 40 条），同步成本不再随以前浏览过的历史增长。读取前后都检查追新意图；期间上翻、定位、around 窗口或来源不完整时，保留原来的完整窗口校准与阅读位置。旧消息可继续通过正确的 older cursor 加载。
- SQLite、Worker、账号作用域、ticket、删除/权限硬失效及提交后读回保持原 owner。UI 不从推送提示伪造正文、不把未持久化结果标记成已缓存。缩小的是底部活跃显示窗口，不执行数据库清库。
- 滑动窗口裁剪和前插时保留幸存行的分块归属；观察器只在分块身份变化时重建。可见预算改为 200 行加最多 40 行强制锚点，删除造成短分块时也能填满视口。
- 同一滚动区域只有一个动画帧 owner；到达底部后停止帧任务，但保留追新意图以应对异步高度变化。滚轮、触摸、指针或键盘操作立即取消，作用域退出释放监听；显式阅读恢复仍即时按锚点定位。动画中的临时距离不会被保存为历史阅读，也不会闪现“回到底部”。
- CPU 采样定位到侧边栏 `conversationTimeLabel`：25 秒采样里自耗时合计约 8.93 秒。现在只保留当前语言的三个日期格式化器，时间戳不进缓存；按每个日期的本地偏移处理系统时区变化与夏令时。另一轮 25 秒实测中该函数自耗时约 0.26 秒。两轮阅读动作不完全相同，函数采样用于定位热点，不作为整机统一基准。

能力矩阵：本轮仅调整 UI 的读取策略、呈现、滚动状态与格式化；Host 仍使用既有 `source.timeline` 契约，未新增服务、查询参数或持久化能力。Tools/SDK 无新增产品能力，N/A；现有数据授权与缓存 owner 未改变。客户端仓与 DSH 源码无修改，使用官方 Harness 与已安装的不可变插件包验证。

### 真实负载与测量

测量采用 3020 向 3016 的现有私聊顺序发送，每批 100 条、每条确认后间隔 120ms；记录消息 UID/序号，并用接收方接口核验。消息发送需要网络确认，所以不是固定每秒 8.3 条。监测只在本次测试客户端启用，结束后断开观察器，不引入常驻生产日志。

- 最终性能批次 `20261012-034729`：100/100 接收核验并显示，25 次可见尾部推进；26 次时间线请求，峰值并发 1、错误 0，每次 40 个事件；新增消息 DOM 100 个，已有消息 DOM 重挂 0 次。请求耗时 p50 1333ms、p95 2012ms。
- 同为底部接收 100 条的前一版与最终版，RAF 间隔 p95 分别为 49.3ms、14.3ms，超过 50ms 的帧间隔分别为 127、9 次；主线程长任务分别为 76、3 次，最终最长 69ms。最终仍观测到 829ms 的最大帧间隔，不能声称零掉帧或零卡顿。两轮受实际网络、其他应用及诊断开销影响，不能外推为其他设备的 SLO。
- 最终可见批次边界推算的消息首次显示上界：100 条 p50 1142ms、p95 2065ms、最大 2533ms；这是接收显示测量，不是网络服务单独耗时，也不是逐条绘制截图。
- 格式化回归验证 3 种语言、5 个时区、午夜和两次夏令时切换；另验证 3000 个标签只构造 3 个格式化器。滑动窗口连续追加 300 条，幸存行无重复挂载；短分块、动画取消、延迟布局、history/around/请求期间上翻、partial 来源均有回归。

测试包 `continuity-optimized-v2.tgz` 的 SHA-256 为 `82cc08a0e1018d2bbc103f966614e3dd42c113278f643907e171c0e080a2044d`，安装包客户端模块 SHA-256 为 `526d2592ac3cf3437bb96927d56085a00f10bfb4e4a2061fb8149b6321e240f3`。它是本地隔离测试产物，未发布生产渠道。

收口补充：会话进入时先检查已保存的阅读意图，避免共用 DOM 仍显示上一个会话底部而额外发起最新页读取；中断自动追新会立即保存当前视口，作用域清理不伪造滚动事件。最终代码完整测试命令为 `NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=2 --testTimeout=30000 --hookTimeout=30000`：917 文件通过、13 文件跳过；10,785 用例通过、17 既有跳过，耗时 430.70s。试验性 4-worker 运行出现无改动的导览/心跳计时用例不稳定，已停止该诊断运行；最终门禁完整使用 2-worker 跑完，没有过滤、改跳过名单或以局部测试代替。

真实 SQLite 只读核对：账号 3016 的该私聊有 188 个缓存窗口、1,220 个事件，最新消息序号 34872；全库孤立正文、悬空条目和引用计数不一致均为 0，缓存数据约 5.09 MiB。页面切换与同源重新加载的阅读锚点偏移均为 0；该结果不扩大到临时客户端更换 HTTP 端口后的 localStorage 迁移。

最终交付包 `continuity-release.tgz`（SHA-256 `96394cb5e64ce1ff78b680f5112328f83813dc99bdd0451b0eaf95cef165ec3b`）已通过官方 DSH CLI 安装到本任务隔离 Profile，并重启本任务测试客户端。安装后的 `lib/client.js` SHA-256 为 `7f0b0633363a80c9d570a94b2694fbed75778ff7e2781c97901050f80bbee88f`。最终源码类型检查、构建及打包均成功；随后仅补写本验收记录，未再改动源码与测试。

该最终包综合批次 `20261012-041357`：3020 → 3016 的 100 条全部服务端确认、接收方逐条核验且 UI 显示至 100/100（消息序号 34873–34972）。23 次列表推进；27 次时间线读取、峰值并发 1、错误 0。前半段底部追新保持 40 行；第 51 条后主动上翻，中途继续收消息且保留阅读窗口，110 次锚点采样最大偏差 0px，本轮最多挂载 89 条消息。5 个主线程长任务，最长 70ms。测试结束后独立执行会话切换与同源重载，锚点 `a1b7ba2a-f2e8-4673-ae63-fa73a431e035` 偏移均为 -3.203125px（0px 漂移）；导航仍在 x=0，当前私聊没有未读角标。客户端已回到最新消息并保持运行。实时负载测试与阅读恢复测试顺序执行，未重叠操作页面。

## 2026-10-12 最新端固定与逐帧连续性复核

用户实测指出追加后仍有明显滚动感，上一节“全部收到、无重挂、低长任务”不足以证明连续性。本轮继续在同一任务分支修复，基线为 `c822a219`。参考 Jotmo 移动端主仓 `8f4df914c0` 的 `JotmoMobileMessageTimeline`：会话布局使用 native reverse viewport，尾端偏移为 0；`ChatSessionMessageTimeline._scheduleScrollToTail` 在已经位于最新端时直接返回，不会每次收消息再播放追赶动画。参考仓的本地修改仅只读避让。

同机、同测试账号私聊、前台暖缓存、每次确认后间隔 120ms 的 100 条负载，基线逐帧记录 4,923 帧，670 帧尚未对齐最新端，最大落后 427px；24 次消息提交产生 776 次脚本滚动写入。当次主线程长任务为 0、RAF 间隔 p95 为 9.2ms，因此本次不自然滚动有独立于掉帧的直接原因：为保留旧尾部几何而先退回，再逐帧追到底部。

修复仅改变插件 UI 的呈现时机：移除追底 RAF 和旧尾部补偿，最新端由提交布局与 ResizeObserver 在绘制前直接对齐；没有新增轮询、人工消息播放队列或显示延迟。仍保留用户输入取消、历史锚点、读取前后意图检查与 40 条追新窗口。Host、SQLite、Tools/SDK 和客户端装配契约未变化（Tools/SDK 新能力 N/A）。回归覆盖连续 100 次窗口滑动、首帧对齐且无后续帧任务、延迟高度变化、上翻中断及生命周期清理。

最终包逐帧批次 `20261012-043449`（3020 → 3016，序号 35173–35272）100 条均发送确认、接收方逐条核验并显示。完整测试结束后才开始该轮，测量期间前台焦点保持，未同时运行构建或测试。与基线采用相同的账号、窗口、文本长度和“每条确认后 120ms”策略；受真实网络影响，发送及接收核验总耗时分别为 35.86s、51.62s，不能将请求总数差异直接解释为代码引起的吞吐变化。

| 指标 | 基线 `c822a219` | 本轮修复包 |
| --- | ---: | ---: |
| 逐帧样本数 | 4,923 | 6,964 |
| 最新端落后超过 2px 的帧数 | 670 | 0 |
| 最新端最大落后 | 427px | 0px |
| 消息/高度未变时的后续滚动帧数 | 516 | 0 |
| 脚本滚动写入 | 776 | 43 |
| 消息窗口提交 / 请求数 | 24 / 27 | 43 / 48 |
| 时间线请求峰值并发 / 错误 | 1 / 0 | 1 / 0 |
| RAF 间隔 p95 / 最大 | 9.2ms / 50.9ms | 9.3ms / 74.2ms |
| 主线程长任务 | 0 | 0 |
| 全部 100 条首次显示延迟上界 p50 / p95 / 最大 | 1077 / 1868 / 2202ms | 1016 / 2028 / 2811ms |

“首次显示延迟上界”从发送前到包含该条消息的首个采样帧计算，包含实际网络与同步读取耗时；不能声称亚秒必达。该证据证明本轮消除了新内容出现后的追底动画，没有为平滑观感延迟消息显示。仍存在系统调度造成的较长帧间隔，不宣称所有设备零掉帧。

最终源码完整测试：`NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=2 --testTimeout=30000 --hookTimeout=30000`，917 文件通过、13 文件跳过；10,787 用例通过、17 既有跳过，356.47s。相关 429 条回归与类型检查、构建打包成功。测试制品 `motion-fixed-v1.tgz` SHA-256 为 `4c0bef15978a5a5e8fd870f5b745877af033ad05f4a9db4abd5bf4287ce58f2c`，安装客户端模块 SHA-256 为 `bde4ae201d3bc46ad0b7c3b8ea42ada6521c80966cc2cef4b9bbdc78c47602a6`。客户端仓无修改，DSH tracked 状态未变；本轮未发布生产渠道。

综合阅读批次 `20261012-043616` 再发 100 条（序号 35273–35372）并全部核验、显示；第 50 条后主动上翻，138 次锚点采样最大漂移 0px。窗口推进 32 次、时间线请求 35 次，峰值并发 1、错误 0，最多挂载 90 条消息，主线程长任务 0。该批结束后另行验证切换会话与同源重载：锚点 `1c0c0128-2c08-4630-b6a8-75a9eaefa153` 偏移在三次观察中均为 -3.34375px。最终再次通过类型检查；截图确认导航可见、当前私聊无未读角标且位于 100/100 最新消息。客户端保持运行。所有临时逐帧/长任务监听均已断开，并在最终页面重载后清除，不进入发布包。


## 2026-10-12 连续正文投影与前台未读语义复核

用户继续实测发现消息按批弹出，当前对话的未读随批次增加后消失。本轮基线为 `8a971d1e`，沿用同一隔离任务分支。修复 owner 为 Plugin Host 与 Browser UI；客户端和 DSH 源码不变，不调整请求协调器并发上限。

### 已确认原因与修复

1. 实时事件已有经过 Host 校验的消息正文，但 unified 窗口仍等第二次网络读取才显示。新增 mounted-conversation live tail：仅在完整最新窗口、原生序号严格连续且身份完整时立即呈现；缺号、历史窗口、不完整来源仍走原有权威校准。live tail 不拥有分页覆盖证明，也不直接写 SQLite，明确标记 `network/deferred/stale`；随后由原有单个校准 owner 提交持久化窗口。校准以读取开始时的 revision 为边界，保留与读取并发的新消息，删除和权威遗漏不得复活。
2. 当前对话只有离散的打开已读动作，目录先到而正文/ACK 后到时产生角标闪烁。目录发布前投影连续阅读意图，只有前台可见、窗口在最新端且没有阻断覆盖层时生效；真实 ACK 仍等待正文显示，且只推进实际显示的原生序号。离开/隐藏恢复尚未显示的未读，已经显示的游标继续有界排空；失败恢复服务器未读，历史模式不吞掉新消息。
3. ACK 的剩余未读可能对应更靠后的服务器序号，旧实现把剩余数量放到较旧目录序号上。Host 返回经过校验的 `latestSequence`，Host/Browser 均将剩余未读与该服务器前沿一起投影，并保留较新的目录和已读水位。部分 ACK 更新未见消息的备份数量，乱序旧 ACK 不得反向增加该数量。
4. 原 `sourceRef` 含会话活动时间和最新序号，每条消息都会改变引用，误触发成员页、文件任务和重编辑恢复的初始化读取。新增账号签名的 `conversationRef`，仅去掉目录活动证据；会话 kind/owner/name/subject/bot 绑定与原授权校验保留。目录隐藏/恢复继续使用原始动态 `sourceRef`；正文消费者使用稳定引用，旧 Host 无该字段时保持旧路径。
5. 本机已读写入及其事件回声原来重复触发正文投影。成功 ACK 不再拉取正文，自己已确认或正在提交的游标回声只做有界去重；不确定写入、其他设备推进和未被覆盖的游标仍触发目录校准。跟踪器不能切换账号 owner，晚到的旧账号完成回调不得污染新账号。日历自动失效读取使用已有后台请求通道，初次打开与显式重试保持前台语义。

### 资源与兼容边界

- live tail 与当前账号/会话同寿命，沿用 2,000 事件窗口上限；不生成新的 coverage token，不改变 500 token 上限。没有人为逐条播放队列、延迟动画或新增轮询连接。
- 权威窗口刷新仍单飞；实时正文立即显示，持久校准在空闲时采用 1 秒的固定合并期限，连续事件不会重置计时；已有读取在途时等待其结束，紧急失效仍可提前。
- 已读 ACK 为一个在途请求加一个最新待提交游标，两次启动至少间隔 1 秒；离开只立即排空已经观察到的游标，账号变化后旧请求结果丢弃。Timer 在排空后清理。
- Host 本机回声跟踪最多 512 会话，每会话最多 128 个并发 ticket；容量不足回退普通目录校准，不丢写。账号切换、订阅释放和 dispose 均清理。
- 默认关闭的诊断只增加阶段耗时、数量和协调器统计，无正文与凭据；关闭时不采集统计。临时逐帧、网络和长任务监听仅在本地验收脚本中，未进入发布包。

| 能力面 | 本轮变化 | 验证 |
| --- | --- | --- |
| Host / Tools / SDK | 沿用同一 source 服务和账号签名引用；`conversationRef`、已读结果 `latestSequence`、tail 排序字段为可选加法字段，无新 endpoint/grant | 原工具/SDK 契约完整测试、跨账号签名拒绝、旧字段缺失回退 |
| Browser | 稳定引用、已确认连续 tail 即时显示、连续阅读意图、单飞 ACK | 阻塞校准仍连续呈现、删除/缺口、前后台/失败/乱序 ACK、成员/文件/重编辑请求计数 |
| SQLite / Worker | 原持久化 owner 和原子 reconcile 不变；临时 tail 不伪装已提交 | 完整缓存回归及真实数据库只读核对 |
| Client / DSH | 装配协议与源码无改动 | 官方 DSH 安装隔离 Profile 后运行真实 Electron 客户端 |

### 运行证据

相同 macOS、测试账号 3020 → 3016 私聊、前台暖缓存、每条发送确认后间隔 120ms，独立批次各 100 条；记录发送开始、正文事件到达、逐帧首次显示。正文事件不是发送端通知，HTTP 成功也不代替 UI 显示核验。测量期间本任务不运行测试/构建。网络响应与同机其他进程负载仍会变化，因此总请求数、总耗时和更新次数不能单独证明吞吐改善。

基线批次 `20261012-062710`（序号 36473–36572）：100 条接收方核验，23 次可见更新；4,439 帧中 3,759 帧当前会话有未读，正文事件到首次显示 p95 1,406ms；发送开始到显示 p50/p95 为 976/1,899ms，发送跨度 31.949s。

中间验证包 `delivery-v7.tgz` 批次 `20261012-073702`（37473–37572）：100 条接收方核验、74 次可见更新；6,085 帧未读闪烁为 0、底部偏离超过 2px 为 0。正文到显示 p95 4ms，发送到显示 p50/p95 563/1,031ms，发送跨度 45.324s。仍有 1–3 条同时出现，不能表述为网络逐条必达；本轮去掉 UI 在已收到正文后额外等待整页的阶段。1 个 116ms 主线程长任务，因此不宣称全程零掉帧。实时负载期间成员页、文件任务、重编辑恢复的额外初始化读取均为 0；修复前定位轮三类各有 48 次冗余读取。

综合历史批次 `20261012-074114`（37573–37672）：100 条发送确认且接收方核验，31 次时间线请求、峰值并发 1、错误 0；第 50 条后上翻，114 次锚点采样漂移 0px，未向服务器确认后续未看的消息。最多挂载 92 条消息、1 个 50ms 长任务。独立切换会话和同源重载后，阅读锚点 `5f0fe5c9-dff6-4bb5-acf2-8ae86b390bad` 偏移始终 -3.3125px；完整测试期间停止实时性能采样。

真实 SQLite 只读核对：综合历史批次保留的 92 条消息（37581–37672）均有 durable contents，包含最后一条；这表示当前保留窗口已持久化，不表示所有曾接收的消息永不淘汰。

首次完整测试暴露两类接入遗漏：前后台测试仍要求每次恢复立即发 ACK（更新为跨越合并间隔的独立恢复场景，继续断言无隐藏 ACK/无额外 timeline 读取），以及服务文件清单漏登记共享身份模块。另 11 条真实 Git fixture 因系统默认 Git 的 Xcode 许可未接受而失败；测试进程 PATH 指向本机已可用的 CommandLineTools Git，无需修改系统许可。上述四个失败文件单独复验 62 条全部通过，随后再次执行完整测试。

最终源码完整测试命令（为进程选择 CommandLineTools Git）：`env PATH="/Library/Developer/CommandLineTools/usr/bin:$PATH" NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=2 --testTimeout=30000 --hookTimeout=30000`。918 个文件通过、13 个既有跳过；10,811 条用例通过、17 条既有跳过，266.98s。`pnpm typecheck` 通过。完整测试后不再修改业务源码或测试。

最终制品 `delivery-v8.tgz`（SHA-256 `d1f6a92bbac150efd5142fc45fd515e4919bb163fe9ff13fe99141f8ad9502f5`）构建/打包成功，官方 DSH CLI 安装至本任务隔离 Profile。安装后 `lib/client.js` 与构建输出逐字节一致，SHA-256 `793e4b298d5ebb0332be9f809c4ff388ce51a155d644e1558bbedbe23fa684a1`。Client ref `566ac5986b0d8dbf6cfff2a6da274535716d9021`、Electron 43.2.0、DSH 0.1.5-rc.2；只重启本任务窗口，诊断日志关闭。

最终包批次 `20261012-075513`（37673–37772）再次发送 100 条并逐条核验接收；5,192 帧采样，未读闪烁 0、底部偏离超过 2px 0、最大底部差 0.5px、主线程长任务 0，RAF 间隔 p95 9.2ms、最大 34.2ms。58 次可见更新，每次 1–3 条；正文事件到显示 p95 4ms，发送到显示 p50/p95 555/1,098ms，发送跨度 37.946s。事件到达与帧记录跨 Node/Renderer 时间戳存在几毫秒误差，且权威页可能早于对应 tail 事件显示，因此负差值不能解释为“负延迟”。这些数据证明没有 UI 额外等待整页的阶段，不证明网络永远逐条投递或所有机器永远无卡顿。

该轮 43 次 timeline、39 次 ACK（两类合计峰值并发 2），成员页/文件任务/重编辑恢复初始化额外读取均为 0。窗口当前保留的最新 40 条（37733–37772）已在 SQLite durable contents 中核验。最终包再单独验证会话切换与同源重载，锚点 `18b66bb6-1eba-4f6b-a830-c7d2795ac989` 屏幕偏移均为 -3.3125px；随后回到最新消息并保持客户端运行。完整测试后仅补写验收文档；未发布生产渠道。

## 2026-10-12 正文调度与跨会话阻塞追查（基线 aa24b826）

用户标注“仍有少量 2–3 条一起显示”后继续追查。上一轮正文到 Browser 很快，不代表 Host 拉取正文前没有等待；本轮新增默认关闭的运输层排队/HTTP 耗时日志，沿真实提示、正文读取、目录投影、Browser 首次显示拆开测量。日志只含路径、时刻、队列和耗时，无正文和凭据。

定位到三个可独立复现的问题：

- 目录后续分页、私密互动目录、日历、表情附属信息和持久窗口校准占用正文前台队列。其中 UI 已标为后台的操作，有两个 Host 路由未向上游转发优先级；最新窗口校准的 cursor 仍是 `initial`，不能仅凭 `mode=refresh` 判断。现在通过可选 `background` 参数传递调度意图，不改游标、窗口身份、覆盖证明或缓存键。首次打开与历史定位继续使用前台通道。
- 每条会话活动重复查询已确认可见条目的隐藏偏好；日历在连续失效时重复取消已发出的 HTTP。前者复用账号内网络确认的可见性，隐藏/未知/显式偏好变更和恢复仍查询；保留 mutation fence 防止较旧扫描结果覆盖新活动。后者保留一个在途读取和一个脏版本，完成后做一次尾随校准，隐私硬失效仍立即撤销。
- 不同会话共用一个投影批次，批次等待所有会话正文及原生通知结束后才接受下一轮。现在保留一个近期读取会话的独立 flight，以及一个有界后台批次；相同会话仍串行，最多 51 个在途会话，运输层的并发和速率上限不变。读取偏好仅为 30 秒单条调度提示，不能激活账号或授权已读；账号切换/释放清除。失败退避按会话隔离，旧 flight 不能在 reset/dispose 后重新排队。

新回归覆盖慢会话不阻塞当前会话、同会话不重叠、100 个在途提示合并到最新序号、单会话失败退避、偏好到期、跨账号拒绝、旧请求完成丢弃，以及后台参数沿 UI/Host/SDK 到真实 HTTP lane 的传递。没有提高请求限额、增加轮询或人工消息播放队列。阅读锚点、前台已读授权和 SQLite 原子提交 owner 不变。

进一步发现普通私聊正文已经返回时，原实现仍等待 `display-snapshots` 返回。新增加法事件 `timeline-items`：仅对已识别的 human direct 会话，复用同一次 tail 转换结果先发布正文，不写目录、不伪造未读、不授予 ACK、不改变 durable coverage；摘要完成后的原 `sessions-delta` 保留，旧消费者继续兼容。未知会话、Bot 和群聊继续走原资料投影路径。Browser 沿既有账号/instance/revision 检查接收正文，后台可以缓存而不能确认已读；账号重置后在途正文丢弃。该路径没有新增网络请求或正文转换。

还补到了一个目录恢复竞态：慢分页返回的旧活动引用与当前引用不同，即使旧可见性结果和较新的网络确认结果都为可见，也会触发全量重新扫描。在持续收消息时这一轮扫描可能始终无法收敛。回归先复现 `syncing` 而非 `complete`，修复后仅忽略有更新 mutation fence 且隐藏值完全相同的旧引用结果；未知/未确认/隐藏值冲突仍走原有恢复。包含已有隐藏/旋转引用冲突测试在内的 124 条相关回归通过。

诊断随后确认，额外的摘要 HTTP 来自同一次 registered read 收到 `arkme-code-1002` 后重试，而非第二个查询 owner。仅提前发布当前正文仍不足以解决下一条正文等待该摘要的问题。因此同一个 human-direct 正文 worker 在摘要未完成时继续响应已有新消息提示：事件唤醒、单飞 tail、按已收到序号续读，并复用正文与通知身份；累计最多 50 条正文/提示，超过上限交给下一批。摘要与原生通知保持原有生命周期，目录最终再校准最新事实。没有新增连接、轮询、人工播放延迟或请求并发额度。回归覆盖摘要始终阻塞时逐条可见、无重复 tail、51 条越界后继续处理、reset 后 wakeup 清理。

实际第 15–18 条的时间线进一步显示：tail 在 `09:48:41.160` 已返回上一条正文，但下一次 tail 直到 `09:48:42.749` 才启动；期间正在串行完成系统通知。仅隔离 HTTP 摘要不够。现在实时调度在正文/目录投影完成后释放 flight，原生通知独立占用最多 3 个槽，同会话串行；等待的已解析通知继续存放在原有每会话最多 256 个提示的合并容器，忙时不做轮询、不重新拉正文。通知完成事件唤醒剩余提示，失败仍沿原幂等 key 和退避重试。reset/dispose 清除旧 flight，迟到回调不重排。新增回归验证系统通知一直挂起时同会话后续正文持续显示、跨会话总并发不超过 3、恢复后通知不重复且无额外 tail，以及账号重置/释放后旧通知不补发。

### 本轮运行复验

消除原生通知串行阻塞后的 `dispatch-v10.tgz`（主干业务逻辑与最终包相同，最终包另补 stop 生命周期清理）批次 `20261012-100222`，序号 38773–38872，测试账号 3020 → 3016：100 条发送确认、接收方逐条核验且全部显示，98 次独立可见更新，仅第 1/2、82/83 条两次合并。两对消息均由同一次 tail HTTP 返回为两个正文，HTTP 分别为 300/305ms，排队均为 0ms，Browser 收到后一帧呈现；不是客户端继续攒条。不会为制造逐条外观延迟已经收到的消息。

该轮正文请求 100 次，排队 p50/p95/最大值 0/1/1ms，HTTP p50/p95/最大值 86/264/527ms；正文事件到首次显示 p95 1ms，发送开始到显示 p50/p95 485/825ms，跨度 44.621s。未读闪烁 0、底部偏离超过 2px 为 0，RAF 间隔 p95 9.3ms。4 个主线程长任务，最大 107ms，因此不宣称全程零卡顿。目录最终 phase 为 complete。对照移除原生通知等待前的 `dispatch-v9.tgz` 同类 100 条批次，只有 81 次更新，最大 4 条一起显示；网络与机器负载会变化，单次延迟数字仅作为本机运行证据。

真实 SQLite 只读核验当前保留的最新 40 条（38833–38872）正文和序号全部匹配，包含最后一条，`PRAGMA quick_check=ok`。不是承诺所有历史永不淘汰。重审生命周期时补齐订阅 stop 的优先级、在途 flight、唤醒回调和 native 槽清理，与 reset/dispose 保持一致；52 条实时服务回归通过，含通知挂起、跨会话上限、stop/reset/dispose 和旧结果丢弃。

最终制品 `dispatch-v11.tgz` SHA-256 `80d05b6655523940227ac91ce464359910db20669f8555679ec219b9041da080`，官方 DSH CLI 安装后 `lib/index.js` 为 `839f4a1b7cee643f89c0e9961bb3323345f76a33f1778c71b96f0cd5309a11cd`，`lib/client.js` 为 `a47d6979bf074b0247c0b5df8266668255c6f25c8af829ee8d6477faa86fd2f4`，均与构建输出逐字节相同。仅重启本任务隔离客户端，诊断开关为 0。

历史验收保留一次失败：首个 100 条批次 `20261012-100752` 上翻后约数秒返回了底部并确认后续消息。用户已确认期间没有操作。当时没有记录滚动调用栈，不能据此确认触发路径；“后台校准导致”的初步判断未获证实。没有基于猜测再改阅读 owner。随后同一包增加临时滚动输入/赋值栈监听：`20261012-101057` 的 100 条核验通过，84 个历史锚点采样漂移 0px，时间线读取 19 次、峰值并发 1、错误 0，未确认历史停留期间的新消息。再用 `20261012-101413` 主动将第 40 条后的后台校准延迟 6 秒，并在第 50 条上翻：100 条核验通过，109 个锚点采样漂移 0px，读取 16 次、峰值并发 1、错误 0，未越过已观察的已读序号。最多挂载 99 行，SQLite 核对保留的 99 条（39074–39172）和最后一条，quick_check 为 ok。首次跳动未再次复现，原因仍未确认，不能称其已修复。

会话切换与同源重载另行验证锚点 ID 和屏幕偏移一致；重载清除了临时页面监听。带滚动调用栈、网络路由延迟的验收只验证功能和位置，不拿该轮长任务数量与无监听性能轮作比较。后续完整滚动调用栈轮和冷启动轮仅用于功能排查，不作为运行时性能结论。


### 缓存物理容量复查

后续四轮同版本历史测试（含延迟校准、完整滚动入口监听和冷启动）均保持历史锚点，末轮 145 个采样漂移 0px；这仍不能解释或关闭首次自动回底异常。检查 SQLite 时另行发现明确故障：真实缓存 256 个窗口，逻辑字节统计仅 7,166,105 bytes，但实际已占 32,765 个 4 KiB 页面，空闲页为 0，接近 128 MiB 上限；`entries` 和 `entries_token` 分别约 51/52 MiB。覆盖 token 在窗口关系和索引中重复存储，旧逻辑未计入它们。新网络窗口因此返回 persistence=unavailable，重载无法恢复最近阅读位置。

容量回归在修改前复现 `database or disk is full`。修复在 Worker 内按 `page_count - freelist_count` 管理实际占用，提交后控制在 96 MiB，保留 32 MiB 给单个有界窗口及索引的事务写入；原 128 MiB 文件上限、256 窗口和单窗口 4 MiB/2,000 事件限制不变。打开旧库时先在事务内淘汰最久未用窗口，持续写入时保护当前窗口。既有撤销 fence、原子覆盖、账号隔离保留；不在 Host 主线程运行 SQL，不执行全量 VACUUM，不新增轮询。

两条新增回归分别覆盖持续写入耗尽覆盖索引，以及打开旧格式近满缓存、保留最近锚点并继续写入。真实故障库副本在 685ms（含 Worker 启动与前后只读统计）内从 134,205,440 bytes 占用降至 100,507,648 bytes，窗口从 256 降至 193；旧库文件未删除。该问题解释了后续重载失败，尚不能证明它导致首次历史阅读期间的自动滚动。

新包 `dispatch-v12.tgz` SHA-256 `c4cb622fd8ec61a24d1d61a154c9eac7f40d97080693e3295b424fb77ccd425c`；Host 与 Browser bundle 哈希同 v11，storage Worker 为 `c21c28cc42af7db3b14fdd5ceaec65f577925a9fca3de4879b68959f2a95831a`，已安装产物与构建输出一致。


v12 最终底部连续轮批次 `20261012-105126`（39373–39472）：100 条发送确认、接收端内容/身份核验、100 次独立可见更新。5,796 帧中选中会话与前台焦点均持续有效；未读闪烁 0、底部偏移 >2px 为 0、Long Task 0，RAF p95 9.9ms；正文事件到显示 p95 2ms，发送开始到显示 p50/p95 413/758ms，首末显示相隔 43.637s。时间线窗口读取 13 次，Host 请求错误 0。SQLite 最后 40 条身份/正文/序号一致、最后一条已持久化、quick_check=ok。这是本轮实测，不承诺任意网络下永远逐条独立到达。

v12 历史轮批次 `20261012-105232`（39473–39572）：第 50 条上翻，后续 127 个采样锚点漂移 0px，未确认上翻后的新消息；时间线请求 10 次、峰值 1、错误 0，最多挂载 96 行；100 条均核验，SQLite 保留 96 条（39477–39572），包括最后一条，quick_check=ok。


v12 会话切换/同源重载复验通过：锚点 `314f3431-f034-4226-a630-c4010e317bc4` 三次屏幕偏移均为 -3.3125px，重载前后布局高度虽变化，阅读位置保持。额外在浏览器 CPU 降速 4 倍下发送 100 条（`20261012-105518`，39573–39672）：106 次锚点采样漂移 0px、未越界确认已读、13 次窗口读取峰值 1/错误 0；SQLite 95 条保留数据逐条匹配。该压力轮有 113 个 Long Task（最大 181ms），不作为流畅度性能证据。测试结束已解除 CPU 降速并同源重载清除临时监听。

### 最终验证状态

- `pnpm typecheck` 通过；`pnpm pack --out .../dispatch-v12.tgz` 执行构建/声明产出并成功，安装哈希见上文。
- 最终源码/测试 diff SHA-256：`8326f5cf0327b78e91348578e21f48552314418817d4de32793e13cb7b498a59`（相对 aa24b826，不包含后续补写的本验收文档）。
- 完整入口：`NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=1 --testTimeout=30000 --hookTimeout=30000`，2026-10-12 18:54:27 开始，474.38s 完成；918 文件通过、13 文件跳过，10,840 用例通过、17 用例跳过，无失败。显式单用例超时配置未改动。
- 之前双 worker 全量有 2 个文件/3 条失败（大日志流测试 30 秒超时；通知激活动态导入 15 秒超时及其连带状态）；两文件独立 31 条通过，之后串行完整入口通过。未以筛选用例替代最终全量入口。
- 客户端仓无改动，DSH 上游无修改（原有未跟踪 arkme-id.json 保留）。只更新本任务隔离 Profile；没有发布线上制品。诊断关闭、CPU 降速解除、临时 Browser 调用栈监听已清除。
- 连续正文投影、满缓存恢复、正常阅读及压力阅读有通过证据。首次 18:08 的自动回底仍未获根因证据；用户明确未操作，不能归因于用户，不能因后续通过而标记该异常已修复。本轮改动暂未提交/推送。

## 2026-10-13 连续呈现与滚动运动复验

用户在真实验收中仍观察到攒条和跳动。重新分析 v12 原始数据发现，100 次独立 DOM 更新之间仍有 2,276ms 的空档和 74ms 的紧邻更新；“始终贴底”和“无 Long Task”不足以证明连续呈现。此次改用真实可见区域逐帧行坐标、发送开始/回执、Host 提示/请求/正文、Browser 事件和录屏联合核验。录屏采集本身有开销，功能录屏与最终无录屏性能轮分开报告。

对照 jotmo-frontend `8f4df914c0637c6d540acd078ed588b80a56fcee`：`chat_session_message_timeline.dart` 在更新前读取跟随意图，定位和用户滚动取消尾部跟随；共享 timeline 区分初始定位、后续尾部跟随及保留锚点，非原生反向视口路径使用 180ms easeOutCubic。Arkme 采用这一意图/运动/锚点分工，不复制 Flutter 滚动实现。

本轮 owner/覆盖：滚动、阅读可见性与角标仍归 Browser 既有 owner；Host 补默认关闭、无正文/凭据的阶段计时。后续冷启动实测另确认阅读几何跨端口丢失，修复见下文；客户端/Harness 仅消费不可变插件包，不改客户端或 DSH 源码。

旧包诊断轮 `continuity13-baseline` 共 100 条、450ms 目标发送间隔（请求变慢时记录实际间隔，不并发抢发）。录像确认第一组 6 条同时出现，逐帧保留行最大位移 512px，54 帧超过 50px；100 条均到达，未读角标异常帧 0。采集期间有相关测试运行，因此该轮绝对 CPU/长任务指标不能作为纯性能基线。Host 的请求等待与网络/处理耗时继续分开定位，不能把所有停顿归为渲染。

实现中的约束：一个视口最多一个可取消的 RAF；相同目标的重复 commit/resize 不重启时钟，新的目标复用该任务，完成/用户输入/会话退出释放。正文即时提交，不增加消息播放队列。裁剪窗口前保存可见行位置，布局后补偿锚点再跟随；首次进入和历史位置恢复仍直接定位。遵循减少动态效果偏好。跟随意图只能抑制暂时的角标，持久已读确认还要求视口实际到达最新底部。

首次候选包 `continuity13-v1.tgz` 的录屏批次 `20261013-024524`（39873–39972）100 条收件方核验、100 条进入可见区，当前会话未读闪烁 0。仍有 18 帧保留行位移超过 50px，最大 81px，因此该候选包未通过连续性验收。逐帧记录复现：一次主线程停顿后，按墙钟时间计算的 180ms 动画已接近结束，第一次实际移动就跳过了 81px。新增红测试得到 98.9px 单步；修复为每帧最多消耗 24ms 动画进度，延迟帧不补跳，仍只有一个可取消动画且不缓存待播放消息。

同一轮运输日志：tail 排队 p95/max 为 1/3ms、HTTP p50/p95 为 256/701ms，通知收到至正文事件 p50/p95 为 253/706ms；发送开始至通知 p50/p95 为 1,042/2,118ms。6 组相邻消息共用同一次正文事件。不能把网络合并归因为 Browser 定时器，也不能用 UI 人工排队来伪造逐条网络到达。发送是单飞，目标起始间隔 450ms，该轮实际发送间隔中位数 883ms、发送 ACK 中位数 871ms。录屏期间有 26 个主线程长任务，不能宣称零卡顿。此前基线与本轮机器负载不同，不作百分比性能提升比较。

历史阅读/CPU 采样批次 `20261013-025012`（39973–40072）：第 35 条确认后上翻，3,668 次采样中可见锚点漂移 0px，后续 ACK 为 0，最终 66 条未读符合未看到后续消息的语义；100 条均在 SQLite `contents` 核验，`quick_check=ok`。采样进一步发现导航条在跟随动画中把中间位置当作历史阅读，活动标记在历史/最新之间切换；原生导航条随之重复滚动、读取尺寸。插件现在以既有跟随意图固定活动标记至最新行，避免逐行几何扫描；点击导航条历史位置明确取消跟随。DSH 源码未改，导航和预览继续使用公开原生组件。单测覆盖跟随时零历史行几何读取、取消后恢复可见行定位、导航点击取消跟随。

最终源码完整测试和最终包实测尚在进行，不能把上述中间包数据当成最终验收通过。

### 冷启动恢复缺陷与持久化边界

同源重载与会话切换均恢复了相同锚点，但本任务隔离客户端进程重启后 Harness Origin 端口改变，浏览器 localStorage 随 Origin 隔离，导致历史位置丢失并回到最新。这是新确认的独立缺陷，不用于推断前述 18:08 未定位异常的原因。

阅读几何现由现有账号本地 SQLite owner 保存：环境/账号/窗口分区，每窗口最多 40 个会话、64 KiB UTF-8 几何；每账号最多 40 个窗口、全库最多 80 个窗口（5 MiB payload 上限）。不含正文、凭据、签名 cursor，最新底部位置规范化为零、不写每帧坐标。Browser 保留 localStorage 降级；250ms 合并、同 scope 只保留最新待写快照、写入单飞、总待写 scope 上限 40，失败后等后续变化重试，无轮询。冷读取在选择缓存锚点前完成，scope epoch 隔离旧账号响应；新用户滚动覆盖迟到恢复，切换会话不取消共享读取，切换账号/窗口才取消。读取超时 5 秒，持久化失败不阻断正文。

能力覆盖按当前仓既有最近表情/布局缓存的展示偏好边界执行：`conversation.viewport.read/write` 只读写当前账号的本地展示几何，不查询业务消息、不标记已读、不提供远端定位能力。UI/Host 共用该 SQLite owner；已有业务查询、同步与 ACK 的 Tools/SDK 合同不变。Tools/SDK 为 N/A：把某台设备的像素坐标作为业务工具会引入无产品语义的 UI 控制面，因此未扩展。此处依据当前仓展示偏好合同，采用用户 AGENTS.md 的“当前代码/合同优先于 Skill 默认建议”规则；不把持久化本身误报为新增消息业务能力。

回归覆盖真实带空格目录 SQLite 关闭/重开、账号/环境/窗口隔离、40/80 个窗口容量、UTF-8 上限、跨 Origin 恢复、旧账号迟到结果、用户滚动抢先、会话请求取消、失败读写重试，以及 100 次底部坐标变化只产生一次最新意图写入。

### 滚动修复复测（持久化集成前）

v2 录屏批次 `20261013-033904`（40073–40172）：100 条发送/收件方核验、100 条可见。逐帧最大保留行位移 38px，超过 50px 为 0，未读异常帧 0；最多挂载 49 行，RAF p95 9.2ms，1 个 50ms Long Task。已回看最大位移前后画面，左侧主导航存在、当前会话无未读，正文从底部连续进入，没有旧轮一次跳过整块内容的画面。

逐阶段耗时 p50/p95：发送→Host 提示 346/533ms，提示→正文事件 92/185ms，tail 排队 0/1ms，tail HTTP 85/174ms，正文事件→首次可见 p95 65ms，发送→可见 471/710ms（最大 797ms）。共用一个正文事件的第 26/27 条首次可见间隔 26ms；另第 34/35 条间隔 160ms。保留并即时显示网络返回的一组消息，未增加人工逐条播放延迟。这一轮不等同于最终持久化集成版验收。

v3 集成录屏批次 `20261013-035435`（40173–40272）再次捕获未通过项：第 81/82 条同批返回，单次延迟帧后保留行位移 54px。新增两条/三条合批红测试，三条场景复现 73px；动画现按距离延长 180ms 基础运动，easeOutCubic 的峰值速度不超过 1.5px/ms，单帧最多推进 24ms。单个常见高度的消息仍是 180ms；不排队正文，不增加消息缓存，不改变初始直接定位或历史恢复。

该轮另记录到 12 次 `interaction-version-changed`：每次目录查询约 3–4 秒，期间已读变更不断产生新 revision；旧请求的错误因 revision 过期直接丢弃，后续失效又马上重试。修复只针对“请求期间有新失效且服务端明确报告版本冲突”：保留一个脏标记与一个可取消尾沿定时器，状态连续稳定 5 秒后再读；正常失效/正常响应保持原有调度，显式点击重试立即走前台。最初 1 秒窗口仍不足，真实 read-ack 间隔最大 2,922ms，v4 仍有 8 次冲突；补充 1.5–3 秒连续失效红测试后修正为 5 秒。冲突时清除失效投影并显示既有重试入口，不把不完整状态当作零未读/完整结果。修复后 100 次连续失效期间只有初始查询，稳定后恰好一个新查询，显式重试不被延迟。

跨进程冷启动实际验证：v3 退出后 Harness 使用不同 Origin 端口，仍恢复至相同锚点，偏移 -3.3125px；后续会话切换和同源重载也完全一致。SQLite 中的 anchor 与屏幕身份对应，未退化为仅浏览器缓存。最终带限速/冲突修复的完整测试及录屏尚未收口。

v5 历史轮 `20261013-043314`（40473–40572）第 35 条发送确认后上翻；4,615 个采样锚点漂移 0px，后台校准响应被额外延迟 6 秒、总计约 11 秒后返回，也未回底。只看到前 34 条，ACK 最大序号 40506，历史期间 ACK 请求为 0，最终 66 条未读。窗口切换和重载均恢复同一锚点 -3.09375px。

复测同时发现“再点已选中的历史会话”会把角标隐藏但不产生 ACK，不能仅凭 ACK 正确判定未读显示正确。真实重复点击 5 秒采样均复现。目录选择原先无条件调用 `markReadOptimistic`，但并未把普通历史滚动窗口带到最新；现在目录选择只负责导航，乐观角标和已读确认统一交给实际消息视口的既有 reading-intent owner。新增导航红测试覆盖预览、正常选择、历史重复选择、原生总数和迟到 Host 回放；最新视口仍立即抑制持续收消息的角标，历史选择不会凭点击清零。相关导航/目录/消息回归共 463 条通过，最终包复验及最终源码全量入口待完成。

### v6 最终包真实验收数据

只在本任务隔离客户端和测试服账号 3020→3016 上验证。插件包 `continuity13-v6.tgz` SHA-256 为 `a024cc27412db25356963bade6f5fd127e06ee03094a2ed7c1945b7971bf13a9`；已安装 Browser bundle `44619678b049550fe2ce60026a2ed629c208655c364c0939686b7c00f9589e94`、Host bundle `00f770fff913da0a02c3dababcc1262dc2eb27a94deb91f94b1d98842581be72` 与包内一致。源码及测试（含两个新增文件）指纹为 `96d37cf6eca1d3d9958e7f64fc141f603a107ca3cfa4317e68b2142359e701f4`，基于 HEAD `aa24b826140085ef0da458249392d999e9ae0858`。

| 场景 | 真实批次/序号 | 可见/未读 | 性能与位置 |
| --- | --- | --- | --- |
| 连续收消息并录屏 | 20261013-044822，40573–40672 | 100 条核验，100 次独立 DOM/可见更新，当前会话未读异常帧 0 | 发送→可见 p50/p95 375/464ms；正文事件→可见 p95 46ms；单帧保留行最大位移 30px；Long Task 0；活跃 RAF p95 9.9ms，最多挂载 55 行 |
| 历史阅读及迟到响应 | 20261013-044933，40673–40772 | 100 条核验；上翻后 ACK 0，最大已读序号 40706，剩余 66 条未读 | 4,168 个锚点采样，漂移/缺失均 0；一次后台响应额外延迟 6 秒、总耗时 9,722ms 后仍保持位置；最多挂载 106 行；录屏期间 3 个 Long Task，最大 59ms |
| 无录屏性能轮 | 20261013-045137，40773–40872 | 100 条核验，100 次独立 DOM/可见更新，当前会话未读异常帧 0 | 发送→可见 p50/p95 373/461ms；正文事件→DOM/可见 p95 13/35ms；单帧最大位移 27px；Long Task 0；活跃 RAF p95 10ms，最多挂载 52 行 |

两轮最新阅读均无输入干预、后台失焦或 <180ms 的紧邻呈现。实时 tail 调度等待 p95 为 0ms、最大 1ms；无录屏轮发送→Host 提示 p95 350ms、提示→正文事件 p95 107ms、tail HTTP p95 106ms。数据同时保留 WebSocket 与 checkpoint RPC 两条通路；个别消息先由 checkpoint 显示，早于后续 WebSocket，负的事件→可见差值保留、不伪造为零。测量期间保留默认关闭的阶段诊断；无录屏轮仍有轻量逐帧采样，因此这些是本机本轮数据，不是任意设备/网络保证。

已回看录屏中最大位移前后以及迟到响应前后的真实图像：左侧主导航存在，最新会话无角标；历史锚点没有移动。完整逐帧 JSON 覆盖全部采样，不用三张静态图替代运动数据。两份可回放视频为 `/Users/apple/hehs/arkme-runtime-c20261012-timeline-test/continuity13-motion6.mp4` 和 `continuity13-history3.mp4`。没有增加消息播放队列；未来网络一次返回多条时仍即时投影，滚动运动受峰值速度与单帧进度约束。

历史轮会话切换、同源重载都恢复到 `993e8309-b072-4142-9af0-534d25f67b11`、偏移 -42.8125px，仍为 66 条未读、无 ACK。另从 v5 退出、v6 冷启动，Origin 从 58503 变成 52840，先前历史锚点 -3.09375px 完全恢复；连续三次重选已选会话、5 秒共 50 次采样中 66 条未读与位置均不变，ACK 0。

SQLite：历史批次全部 100 条身份/正文/序号逐条一致；无录屏轮有界窗口保留最后 40 条，全部一致且末条持久化；两次 `quick_check=ok`。最新阅读两轮没有 `conversation.viewport.write` 请求，历史滚动轮仅 1 次，未引入每帧 SQLite 写入。

后台互动目录的服务端版本冲突仍可能出现：三轮分别 3/1/1 次 409，后续均有成功分页响应；每轮总请求 7/6/7（包含分页以及采集结束时未完成的一次调用），未复现此前持续冲突重试。所有消息 `source.timeline` 请求成功。此处不把正常的版本冲突重试写成“所有 HTTP 请求零错误”。

最终源码 `pnpm typecheck`、`pnpm pack`、`git diff --check` 已通过；真实验收断言脚本 `verify-continuity-final.cjs` 已通过三批 300 条、未读、阅读恢复与 SQLite 核验。真实性能采集结束后运行最终源码完整入口：`NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=2 --testTimeout=30000 --hookTimeout=30000`，2026-10-13 12:52:40 开始，258.10 秒完成，退出码 0；919 文件/10,858 用例通过，13 文件/17 用例按既有配置跳过。日志 `continuity13-full-v8.log`。测试后源码及测试指纹、安装包 Browser/Host 哈希复核均未变化。

测试客户端已关闭诊断后重新常驻启动，Origin 58432；最后一条 40872 可见且已读确认达到 40872，底部间隙 0、当前会话无未读，临时采样函数不存在。客户端仓无改动，DSH 上游无修改；本轮插件改动保留在既有任务分支，未提交推送、未发布线上。验收汇总和运行画面位于 `/Users/apple/hehs/arkme-runtime-c20261012-timeline-test/continuity13-final-acceptance.json`、`continuity13-final-ready.png`。

边界：上述最终源码及实际环境三轮通过，不追溯宣称 10-12 18:08 那次未知触发链已得到根因证实。用户当时明确未操作，该事实保留；本轮迟到响应、历史切换/重载、跨 Origin 冷启动均有通过证据。


### 2026-10-13 超时提示归属与恢复修复

排查范围仍是 `codex/c20261010-local-message-sync`、隔离客户端 `c20261012-timeline-test-run` 和测试服 3020→3016。当前运行 v6 的原截图没有失败请求日志，只能确认页面残留错误；Electron 早先 TLS 错误不能直接作为这次超时的根因。超时映射 `Arkme 服务请求超时` 在初始提交 `82c5bee2` 已存在；共同基线 `eb364395` 的 Sidebar 8665/8670 两处分支已重复渲染同一错误。当前分支没有改变远端 HTTP 30 秒超时或协调器的恢复预算。

在测试客户端 Host 进程加载一次性 fetch 探针，只记录服务/path、状态、耗时和取消；不记录正文、token、query 或用户身份。探针通过本地受控文件仅阻塞指定只读接口一次，超时后恢复正常响应，未修改远端服务或客户端/DSH 源码。探针不打入插件包。

- 修复前时间线复现：批次 `20261013-064131`，40973–41072，100 条发送与收件方核验成功。`/api/v1/chat/timeline/unified` 受控阻塞 30,008ms；Browser 返回 `arkme-timeout`，Host 已耗尽一次总截止时间。后续 5 次后台读取均 200，页面仍保留两份错误；历史锚点始终同一条，偏移漂移 0px。证据 `timeout13-reproduce.json` / `timeout13-fetch.ndjson`。
- 修复前成员复现：`source.members.page` 30,326ms 返回 504，错误文案与截图一致；随后 page 661ms、presentation 537ms 成功，消息页仍显示两份错误。证据 `timeout13-member-before.json`。这是可复现的错误归属缺陷，不等同于已确认原截图当时的具体接口。

修复内容：时间线读取错误与发送/操作错误分开归属，读取成功只清自己的错误；持有已确认窗口时，后台临时读取失败保留内容和几何、将缓存 freshness 标为 stale，不再插入超时横幅、不在 Browser 添加重试链。Host 原有有界恢复、实时增量投递、ACK 与持久化窗口合同保持不变。成员读取错误只由成员面板展示/重试，不污染消息列表。删除重复错误块；无缓存的首次读取失败和明确操作/权限失败仍有一处可操作反馈。浏览器总截止时间改成有类型的错误并禁止再次重试，避免文案匹配或额外重试放大。

新增 `conversation_read` 诊断沿用默认关闭的 `ARKME_CHAT_NOTIFICATION_DIAGNOSTICS` 开关，只记录固定会话读取操作名、请求序号、耗时和安全错误码；最多 120 条/分钟、常数状态、无额外定时器/每条消息扫描，关闭时不读性能时钟。新增回归覆盖 Host/Browser 超时后的 pending hint 排空、历史位置、缓存失败不插提示、冷加载失败可重试、权限失败只显示一次、成员错误隔离、后台成功不清发送失败、日志脱敏/限量/默认关闭。

相关测试 8 文件 / 557 项通过（`timeout13-targeted2.log`）；完整门禁和安装包真实验收结果见下方后续记录。


完整入口第一次运行：`timeout13-full.log`，920 个有效文件中 919 个通过，10,865 项通过；唯一失败为未修改的 `plugin-updater-helper.test.ts:747` 安装/回滚集成用例自身 15 秒截止时间。独立复跑同样触及边界，但 helper 日志记录安装和回滚最终均完成；当时机器 load average 约 42，不能把它等同于消息路径回归。未修改该用例或提高其 15 秒阈值，清理该失败用例留下的专属 fake DSH 子进程，并停止本任务测试客户端以减少资源竞争。

最终源码单并发完整复跑：`env PATH="/Library/Developer/CommandLineTools/usr/bin:$PATH" NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=1 --testTimeout=30000 --hookTimeout=30000`，2026-10-13 15:08:07 开始，1,342.78 秒，920 文件 / 10,866 项通过，13 文件 / 17 项原有跳过，失败 0（`timeout13-full-serial.log`）。第一次全量与独立复跑的失败记录仍保留，未通过删除、过滤或修改超时掩盖。

安装包 timeout13-v1 实测：成员接口实际阻塞 30,000ms，失败及随后成功恢复时消息区超时提示均为 0，锚点与偏移不变（`timeout13-member-after-confirmed.json`）。时间线超时期间发送 100 条（41073–41172），全部到达并可见，提示/未读异常帧 0，最大保留行位移 33.5px。但不能据此宣布连续性通过：随后无录屏轮（41173–41272）出现 23 次整行跳动、最大 85.5px，无用户输入。该失败作为继续定位的依据保留。

滚动调用追踪：稳定阅读时录屏与无录屏轮没有整行跳动；重新进入对话后无录屏轮（41473–41572）稳定出现 21 次 >50px 位移、最大 170.5px，JS 写入追踪没有对应的向下大幅滚动，唯一大幅写入是一次向上的锚点校正。控制实验仅把消息滚动容器 `overflow-anchor` 设为 `none` 后重新进入、再次发送 100 条（41573–41672），大幅跳动归零、最大位移 30px、Long Task 0、当前会话未读异常 0。证据 `continuity13-reentry-perf-report.json` 与 `continuity13-anchor-perf-report.json`；该控制实验不是最终安装包验收。

最终代码把浏览器锚定排除限制在 latest-follow 生命周期内：在第一帧前设置 `overflow-anchor:none`，两条消息之间仍保留滚动所有权；滚轮、触摸、键盘、指针干预或会话卸载立即还原原 inline 值及 priority，使历史阅读继续使用浏览器锚定。没有添加帧队列、定时器或逐条消息延迟。新增两个先失败回归验证该所有权及完整恢复；同时补全既有非 DOM 测试夹具的 style 接口。最终安装包、全量测试和历史阅读验收见后续记录。

测试账号隔离补充：用户确认另一个任务同时使用 3016/3020。该并发会同步群聊/目录工作，并且测试历史轮中服务端 `read_seq` 被其他客户端推进到 41972，而本客户端最后一次 ACK 为 41906、上翻后 Host HTTP 和 Browser ACK 均为 0。因此本轮历史锚点（4,991 次采样、0px 漂移）和错误提示测试仍有效，但“应剩 66 条未读”的端到端结论未通过隔离验收，不能据此声称通过。`timeout13-authoritative-read.json` 保留了远端真实已读快照。

用户随后指定接收账号 333331、发送账号 3020。停止旧客户端及 3016 的实机写入，准备独立 App Data `account-333331`；最终未读、阅读位置和性能复验以新的私聊及独立客户端为准。并发期间的长任务/发送延迟仅作为混合负载证据保留，不直接归因本次修复。

最终 v2 源码完整入口（单并发）于 2026-10-13 15:57:52 开始，564.92 秒完成：920 文件 / 10,868 项通过，原有 13 文件 / 17 项跳过，失败 0。日志 `timeout13-v2-full.log`。源码与测试指纹 `e3fb26e88c2bff16529bb6f075b80b250f8af26ee25c1823e8b19d4a52c753f8`，期间仅追加验证文档，源码/测试未变。类型检查及打包通过；安装包 `timeout13-v2.tgz` SHA256 `9443e78ecff7d0ddbcbb4cc1bc2ce07ee7dd1bbae0bfdcfd84a2407de84fa1ab`，安装后 Browser/Host bundle 与包内逐字节一致。

### timeout13-v2 独立账号最终验收

接收端改为用户指定的 333331，发送端仍为用户指定的 3020；客户端使用独立 `account-333331` 数据目录。四批合计 400 条均逐条核对收件方、消息身份、正文和服务端序号，未继续向 3016 发送。最终两轮关闭 Host 诊断和受控故障探针，不录屏，仅保留临时性能采样；采样结束后监听全部释放。

| 场景 | 批次与序号 | 实际结果 |
| --- | --- | --- |
| 最新阅读、逐帧录屏 | 20261013-081120，835–934 | 100 次独立 DOM 更新、100 次独立可见更新；消息区错误与当前会话未读异常帧均为 0；保留行最大单帧位移 27.5px，整行跳动 0；Long Task 0，活跃 RAF p95 9.2ms，最多挂载 45 行 |
| 历史阅读、真实截止时间 | 20261013-081237，935–1034 | 后台时间线读取触及 30 秒总截止时间，随后恢复成功；4,279 次历史锚点采样漂移/缺失均为 0；上翻后 Browser ACK 与 Host 已读请求均为 0；服务端 read_seq=968、latest=1034、真实未读 66，消息区错误提示 0 |
| 默认关闭诊断、无录屏最新阅读 | 20261013-081604，1035–1134 | 100 条核验；99 次 DOM 更新、100 次独立可见更新（有一组网络合并返回，未人为延迟拆播）；错误与当前会话未读异常帧均为 0；最大单帧位移 33.5px、整行跳动 0；Long Task 0，活跃 RAF p95 9.8ms，最多挂载 49 行 |
| 默认关闭诊断、无录屏历史阅读 | 20261013-081720，1135–1234 | 4,160 次历史锚点采样漂移/缺失均为 0；上翻后 ACK 0，服务端 read_seq=1168、latest=1234、真实未读 66；错误提示 0，Long Task 0，RAF p95 9.2ms，最多挂载 109 行；阅读几何只写入 1 次 |

录屏历史轮有 5 个 Long Task、最大 94ms，保留该实测结果；后续默认关闭诊断、无录屏历史轮为 0，不将录屏轮写成零长任务，也不据此单独断言全部长任务均由录屏造成。最后两轮仍有正常互动目录版本冲突及有界恢复，不声称所有请求零错误。

阶段耗时：录屏最新轮发送→可见 p95 806.4ms，正文事件→DOM/可见 p95 16.6/48.3ms；Host tail 排队 p95 0ms、最大 1ms。无录屏最新轮发送→可见 p95 553.1ms、正文事件→可见 p95 76.4ms。均为本机、本次测试服网络的测量；没有通过播放队列伪造网络逐条到达。已查看录屏中相邻帧，左侧主导航存在，当前会话无未读，内容从底部连续进入；同时以全量逐帧坐标确认未出现旧版本的整行跳动。

受控故障注入位于 Host HTTP 阶段，探针记录阻塞 28,234ms 后被取消；请求此前的排队计入 Browser 30 秒总截止时间，不能把该 HTTP 段耗时误报为改变了总预算。故障及恢复过程没有插入消息区横幅，后续 100 条全部核验成功。

历史恢复：超时历史轮锚点 `96a399c7-ddb5-48d6-8d88-ad8aa72c2822`、偏移 -3.3125px，在会话切换、同源重载和客户端进程重启后均一致；冷启动 Origin 从 56858 变为 60198，仍保留 66 条真实未读且没有 ACK。历史阅读的 `overflow-anchor` 恢复为 `auto`；最新跟随时为 `none`。SQLite 核验四轮均 `quick_check=ok`，保留的消息身份/正文/序号全匹配且末条已持久化；最新无录屏轮按有界窗口保留 40 条，其余三轮核验 100 条，未把窗口裁剪误报为丢消息。

最终客户端关闭诊断后常驻，账号 333331，测试环境；已回到 `3020 remark` 最新位置，read_seq=latest=1234、unread=0、底部间隙 0，40 行挂载，错误提示与临时采样函数均为 0。最后画面已人工查看。证据根目录 `/Users/apple/hehs/arkme-runtime-c20261012-timeline-test`：`timeout13-isolated-acceptance.json`（前三轮断言）、第四轮 `continuity13-v2-isolated-history-perf-summary.json` 和权威已读快照、`timeout13-isolated-final-ready.json/png`、各批次 `-report/-send/-sqlite/-reading` 文件。客户端与 DSH 源码未改，本轮修复未提交推送或发布线上。

归因边界：重复提示及成员错误污染消息区是基线已有、此次已复现并修复的缺陷；原截图缺乏当时失败请求日志，不能追溯断言具体慢接口，也不能据此笼统排除分支对当时请求负载的影响。此次移除的是已有内容时的后台超时提示及重复渲染；无缓存首屏读取失败仍保留一处重试反馈，发送/操作失败不被后台成功掩盖。

## 2026-10-13：新会话加载与独立消息请求队列

用户在账号 333331 首次打开 `3333333` 群聊感觉耗时 3–4 秒。原始点击未保留逐阶段 trace；下列为同一客户端后续对照，不能冒充原始点击的精确拆分。

- 对话目录已经持久化到 SQLite `conversation_directory` / `conversation_directory_meta`，按账号隔离。`sources.list(localFirst=true)` 有缓存时先返回快照，后台扫描分页；实测该账号已有 13 条目录行。目录缓存不代表每个会话正文已经下载。
- 群聊当前有一页 40 个统一事件（7 条消息、32 个入群事件、1 条公开记录）。直接上游读取三次为 452 / 279 / 176 ms；Host 某轮本地读取 2872 ms、网络读取 4860 ms、后续本地读取 79 ms。
- 原实现把所有会话、包括 `cacheOnly`，都放入账号级 `chat.timeline.window` 串行 route。两轮同时启动“群聊网络读取”和“另一会话本地读取”，网络分别耗时 2071 / 2729 ms，本地分别等待 2020 / 2680 ms，确认本地缓存也被网络挡住。
- 首次没有内存快照的打开被标为 `background`；群成员全量分页及资料补全还会占用共享后台读队列。不能把直接上游耗时和 Host 总耗时之差全部归为某一个 HTTP 请求。

参考 `jotmo-frontend` 的 `server_fetch_api.dart` 独立消息同步池，在插件的 `ServiceRuntime` 内建立独立队列，总传输并发 4、最多排队 128，继续保留前后台 lane 的速率和并发限制。精确匹配统一时间线和 tail；实时 display-snapshots 显式指定消息流量。仅在统一时间线投影的异步上下文内，让必需的用户/机器人资料读取进入该池并继承优先级，群成员全量列表仍使用共享队列。没有新增依赖或改动 HTTP 凭据/重试实现。

消息 composite owner 只占有有限 route 名额，不重复占用子 HTTP 的传输名额；不同会话最多 4 个 owner 并行，参数相同仍 single-flight。通用队列保持原有同 route 串行默认值，不为每个 sourceRef 建立永久队列。两池同时接受账号失效、写后失效和 dispose，排队取消、最后消费者取消、总 deadline 与旧账号结果拦截仍生效。

`cacheOnly` 直接进入既有 SQLite Worker 的有界队列，保留 scope/revision/账号凭据检查。前端首次打开使用前台优先级，维持后台加载原有的目标定位和窗口保护；一旦从 SQLite 恢复窗口，后续核对降为后台。未改消息顺序、已读提交或滚动动画算法。

能力面：本次仅调整既有 Host 查询的内部调度与 UI 加载优先级，无新增路由、权限、持久化字段或公开业务能力；Tools / SDK 沿用同一 `source.timeline` owner，Host / UI 原生合同测试参与完整门禁。客户端与 DSH 源码不改。

新增回归覆盖：本地读取不经过网络 owner、共享后台饱和时消息正文及投影资料仍可完成、另一会话慢 owner 不阻挡新打开、前后台合计并发上限与前台排队优先、跨服务排队上限及取消释放、共享请求最后消费者取消、账号失效中止消息请求、首次 UI cache miss 使用前台而后续刷新仍为后台。

完整门禁首次执行 933 文件：917 通过、3 失败、13 跳过；10865 测试通过、9 失败、17 跳过，耗时 1277 秒。一个真实兼容遗漏是 `requestStats()` 拆池后改变了既有统计键，现已改为按原 lane/service 汇总两池，并新增跨池求和测试；消息通知断言与队列测试复跑通过。SQLite 容量断言首次因 33 秒超过既有 30 秒上限失败，原断言、上限及 SQLite 实现未改，复跑通过。引导页首次 7 项失败、复跑换为另一项失败，trace 显示固定 200 ms 的测试等待早于两次稳定 RAF 采样完成；仅将测试 `settle` 改为显式等待三帧并逐帧提交 React，不改引导产品代码或断言。

安装包实测（账号 333331，既有隔离客户端；未清理用户缓存）：

- 目录本地优先返回 13 行，3.6 ms。
- `3333333` 群聊三次强制前台网络读取分别 993.9 / 678.3 / 832.7 ms；对应本地读取 56.5 / 3.8 / 4.8 ms。这里的网络读取始终向 owner 请求并重新投影，不把 SQLite 命中伪称为首次网络加载。
- 三组并行对照：群聊后台网络读取 631.1 / 1609.8 / 2039.3 ms；延后约 50 ms 发起的另一会话本地读取分别 12.0 / 13.5 / 50.0 ms，均早于网络完成，消除了此前本地跟随网络等待 2 秒以上的阻塞。
- 清空浏览器内存状态（reload，保留 SQLite），点击群聊至首个目标消息挂载约 664.2 ms；本地 HTTP 282 ms，随后后台网络核对 767 ms。截图已查看：左侧产品导航、群聊正文、输入区正常。此项是冷内存/热 SQLite，不冒充空 SQLite 的首次会话打开。
- 私聊上翻 900 px 后 1446 帧同一锚点漂移 0 px，切换会话、页面 reload、完整客户端重启（Origin 改为 `http://127.0.0.1:55199`）都恢复相同消息和 -32.59375 px 偏移，记录的已读确认数为 0。
- 包 SHA256 `3a89f8f364c59ab901542fa3ec98ee4b4f2c1e0602736e44d10e24a18a1c12f4`；安装后 Host `47ef63804898f505f0807efdf707a0a78c884cdf89cfe6653c3144f5eed37a5c`、Client `9cc3b1e6df9d864c600b2aee2d84c9c5a06d8933bec584d4814f496094ab1cc5`；源码/测试目录指纹 `b04f318601733e50229b2fa2b3ecd8aec7e3ba624abc4aed81364e49c79187f3`。

证据位于既有 runtime 目录：`message-queue13-live.json`、`message-queue13-group-ui.json/png`、`message-queue13-routing.json`、`message-queue13-reading.json`、`message-queue13-cold-restore.json`、`message-queue13-package.json`。独立消息队列在真实 Host 日志中生效；连续消息的追加实发与最终完整门禁结果另记，不能由本段加载耗时推导为通过。

### 独立消息队列最终门禁和实际收消息验证

最终源码完整入口于 2026-10-13 17:39:46 开始，728.26 秒完成：920 文件 / 10,875 项通过，原有 13 文件 / 17 项跳过，失败 0。命令为 `env PATH="/Library/Developer/CommandLineTools/usr/bin:$PATH" NODE_OPTIONS=--no-experimental-webstorage pnpm test --maxWorkers=1 --testTimeout=30000 --hookTimeout=30000`，日志 `message-queue13-final-full.log`。最终 `pnpm typecheck`、`pnpm pack` 已通过；前述首次全量失败及修复记录保留，没有过滤失败用例。

用户确认直接模拟 3020 向 333331 发送。最终安装包关闭 Host 诊断和故障探针，批次 `20261013-094953`（1335–1434）实际发送 100 条，接收方逐条核对消息身份、正文与序号 100/100；SQLite 同样保留并匹配 100 条，末条已持久化，`quick_check=ok`。没有向 3016 私聊发送测试消息。

- 前 35 条在底部观察：35 次独立可见更新，当前会话未读异常帧 0；发送到可见 p50/p95 为 582/868 ms，正文事件到可见 p95 为 132 ms。有一组网络事件包含两条消息，分别在两个 DOM 更新中进入视口，可见间隔 163 ms；不能声称所有网络响应均逐条返回。
- 保留行单帧最大位移 31.5 px，超过 50 px 的整行跳动帧为 0。已查看紧邻消息到达前、中、后的真实录屏帧以及历史阅读首尾画面，左侧主导航存在，底部内容依次进入。
- 上翻后的 4,331 帧中锚点漂移/缺失均为 0，已读请求 0。服务端最终 `read_seq=1368`、`session_last_seq=1434`、真实未读 66；普通重选、切换会话和页面重载后仍保持 66 条未读、原锚点 `ef6720b1-4933-4c78-9ad7-9bbabe367daa` 与 -40.3125 px 偏移，没有 ACK。上翻瞬间第 35 条已经进入画面但尚未完成原有可见确认，因此读点只推进 34 条，与 66 条真实未读一致。
- 本轮约 60 秒逐帧采样并录屏，同时本机仍在跑全量测试，也收到其他群聊流量。RAF p95 为 16.8 ms，最新消息活跃段为 25.6 ms；14 个 Long Task、最长 86 ms，最多挂载 106 行。保留这些结果，不宣称零长任务或任意机器无性能回归。历史位置仅持久化 1 次，没有逐帧写 SQLite。
- 互动目录有一次 `interaction-version-changed` 409，保留该请求记录；消息时间线请求没有 HTTP 错误。录屏结束后的页面重载释放临时采样监听。

另三组并行网络验证中，群聊读取耗时 1014 / 701 / 914 ms，约 50 ms 后发起的另一会话前台网络读取分别 432 / 262 / 260 ms，均先于群聊完成，证明确实解除不同会话的网络串行限制。

本轮证据：`continuity13-queue-history-motion-{send,report,summary,reading,sqlite,authoritative-read}.json`、相邻原始帧和同名 `.mp4`，以及 `message-queue13-concurrent-network.json`。最终客户端继续常驻于隔离的账号 333331，源码/测试保留在既有任务分支；本阶段未提交、推送或发布线上。

### 2026-10-14 继续实机测试

继续使用同一已验证安装包，重启本任务隔离客户端，账号 333331，发送端 3020。包及 Host/Browser 文件摘要与 10 月 13 日记录一致；产品源码、测试和配置没有变化，本轮只追加实机脚本和验证记录，不把昨日全量测试冒充今日重跑。关闭 Host 诊断、故障探针和录屏，不同时运行构建或全量测试。

第一轮 `20261014-010337`，序号 1435–1534：实际 100 条连续发送、接收方核对 100/100；100 次独立 DOM 更新和 100 次独立可见更新，当前会话未读异常帧 0、整行跳动帧 0。发送→可见 p50/p95 403/527 ms，正文事件→DOM/可见 p95 28/60 ms；RAF p95 9.3 ms，最大保留行单帧位移 32.5 px，最多挂载 45 行。两次 Long Task 为 59/72 ms，发生在首条发送后约 487/555 ms；不能将这轮写成零长任务。三个 <180 ms 的相邻呈现分别属于不同事件、不同 DOM 更新，没有把它们误计为一次批量呈现。SQLite 有界窗口保留末 40 条，身份/正文/序号逐条一致、末条已持久化，`quick_check=ok`。

真实缓存未命中验证：`修改昵称1` 和 `3008` 在打开前均返回 `chat-timeline-cache-miss`，点击至首条正文挂载约 350/162 ms。第二个会话完整采集到本地 404 耗时 9 ms、前台网络读取 99 ms，结果 `origin=network,persistence=committed`，之后正常后台核对 106 ms。第一个会话的请求监听因使用不稳定 sourceRef 做精确过滤而未捕获请求，因此只报告实际缓存未命中、正文显示和点击耗时，不填造其网络耗时。两个会话均为小窗口（6/2 条），不能替代大型群聊首开压力结论；截图已查看。

`3333333` 群聊三次强制网络读取 731/597/698 ms，对应本地读取 45/2.4/9.6 ms；13 行目录本地优先返回 107 ms。并行对照中群聊后台请求耗时 565/1560/2002 ms，另一会话本地读取分别 3.6/3.3/5.1 ms，均先完成，未重新出现本地读取被网络队列阻挡。

第二轮 `20261014-010607`，序号 1535–1634：第 73 条直接发送请求收到 HTTP 200、业务码 1002“服务器繁忙”，脚本按未知写结果规则停止，72 条已确认。三次收件方回查未找到第 73 条；只读确认 Chat owner 通过 record/rel 双重稳定身份防重后，保留原 ID、正文和 send_at 恢复一次，并继续剩余 28 条。最终收件方核验 100/100、连续序号 1535–1634，没有第二条关系或重发新 ID。原失败 ledger、日志和采样保留，不将该批次报告为无中断连续 100 条；本轮共新建 200 条消息。

第二轮历史阅读在恢复前后均稳定：前段 3297 帧、恢复段 2517 帧，锚点缺失/漂移均为 0，上翻后已读确认均为 0。服务端最终 `read_seq=1569,session_last_seq=1634,unread_count=65`，与侧边栏一致。切换会话、页面重载仍保留同一锚点 `3560b3c0-fd71-4acd-8380-b7536c4691a6`、-3.171875 px 偏移和 65 条未读。前段 CPU 采样期间 Long Task 为 0，恢复段 1 次 81 ms；每段 RAF p95 均 9.3 ms，最多挂载 104 行。恢复采样首帧已有 8 条旧消息，已将这些旧消息的发送到显示耗时及呈现间隔标为不适用；新恢复的 28 条全部投影到 DOM、留在历史视口下方。SQLite 核验该批全部 100 条一致、`quick_check=ok`。

证据仍在既有 runtime 目录，前缀为 `continuity13-queue14-latest-perf`、`continuity13-queue14-history-profile-perf`、`continuity13-queue14-history-resume-perf`，另含 `message-queue14-cold-open*.json/png`、`message-queue14-live.json`、`message-queue14-uncertain-send.json` 和 `message-queue14-history-authoritative-read.json`。`continuity13` 是脚本兼容前缀，实际批次日期及发送时间均为 2026-10-14。

完整客户端重启后 Origin 从 `http://127.0.0.1:64788` 变为 `http://127.0.0.1:54086`，仍恢复同一历史锚点及 -3.171875 px 偏移，65 条未读保持、已读请求为 0；再次切换和重载验证通过。最后通过正常“回到最新”操作将读点推进至 1634，未读归零，底部间隙 0、末条可见、40 行挂载，超时提示和临时采样监听均不存在。客户端保留运行。最终断言与就绪画面为 `message-queue14-acceptance.json`、`message-queue14-final-ready.json/png`，所有包/安装文件摘要再次匹配。本轮没有修改产品源码、提交或推送。

### 2026-10-14 验收发送空档复核

用户在人工验收批次 `20261014-091804` 中反馈“几秒没有新消息，然后继续出现”。该批 100 条均收到（1635–1734），但旧发送器逐条等待 HTTP 回执后再等待 120 ms。第 33/38/46 条请求分别等待 1977/3688/2995 ms，使下一条实际发起间隔达到 2098/3809/3117 ms；这些窗口内发送器确实没有发出下一条。此前仅用 p95 和独立 DOM 更新次数判断连续性不充分，必须同时检查实际发出间隔和最慢尾部。该人工批次没有逐帧采样，不能据此排除所有独立的客户端卡顿。

随后补做两轮诊断，各 100 条，均由接收方逐条核验。串行对照 `continuity13-queue14-stall-trace`（1735–1834）未重现数秒发送空档，重型 Trace 记录到 9 次 51–97 ms 长任务；截图仅覆盖开始约 10 秒，实际查看了其中消息推进画面，不能写成完整视频验收。其最初“首个 DOM 后一帧即判定可见”探针早于自动跟随滚动，不能用该探针的零可见计数判定漏展示。后一轮已改为持续跟踪新行直至进入视口。

固定节奏对照 `continuity13-queue14-cadence-trace`（1835–1934）每 500 ms 发起请求，最多 3 个在途，本轮实测最多 2 个。实际发起间隔 469–544 ms；100 条均捕获正文事件、DOM 挂载和首次进入视口，服务端序号无逆序。发送至首次进入视口 p50/p95/max 为 442/690/1072 ms，DOM 挂载至首次进入视口最长 93 ms；相邻可见间隔仍有两处约 1 秒（1018/1024 ms），没有观察到 2–4 秒空档。正文 WebSocket 事件有 23 条晚于 DOM 挂载，说明不能将这一个事件通道当成全部消息的因果起点，因此不使用含负值的事件→DOM 分布作为渲染性能结论。“进入视口”是 RAF 几何观测，不能等同合成器实际呈现时刻。

该轮未开启 Trace 截图，仍保留 CPU/时间线及有界帧采样：收消息阶段 RAF p95 16.8 ms、最大 91.9 ms，Long Task 为 0；没有数秒主线程阻塞证据，不代表所有帧都流畅。此探针未逐帧采集未读角标，不能声称整轮零闪烁；结束后的独立断言确认末条可见、读点/末条均为 1934、未读 0、底部间隙 0、40 行挂载、无超时提示、采样监听已释放。SQLite 有界保留末 40 条，逐条核对一致、末条已持久化、`quick_check=ok`。最终画面和状态为 `message-queue14-stall-final-ready.png/json`。

测试工具修正保存在既有 runtime 目录：`send-arkme-acceptance.mjs <unique-batch>` 默认固定 500 ms、最多 3 个在途；容量恢复后不补发积压时钟造成突发，失败后停止新请求、等待已发出的请求结束，不自动重放未知写结果。每批独立账本与运行锁，已完成批次再次调用只返回原结果。`acceptance-send-cadence.test.mjs` 的 3 项确定性测试通过，覆盖慢回执不串行阻塞、并发上限及容量恢复不突发、失败停止且不重试。完成批次重入验证没有新增消息。原人工验收 100 条之外，本次诊断额外发送了 200 条，均保留账本。

本次只修正测试发送器与验收记录，产品源码、测试、配置和安装包均未改变；阅读恢复结论沿用同版本当日已完成的切换/重载/完整重启实测，不冒充此次重新执行。全量测试沿用 10 月 13 日最终版本 920 文件、10875 通过、13 文件/17 用例跳过的记录，不宣称今天重跑。不能把这轮对照提升为网络完全匀速或整体性能无问题的结论。
