Repository navigation
Avoid repeated private delivery body scans in reply discovery - #8172
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; Codex (GPT-6 family); OpenAI; self_reported (host observation unavailable: session_not_found).
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机 / Motivation
私聊积累历史记录后,现有飞书回复 worker 每轮仍会解析已经交付的旧正文。 这会反复消耗文件读取、JSON 解析和内存分配,争用处理当前问题的资源。旧路径重复读取未变化的交付正文;新路径复用文件未变化的少量路由信息,新消息和待处理记录继续直接读取。 可验证的改善是减少重复正文 IO,并保持发现的工作集合和顺序一致。 本次不增加队列、重放业务、改变授权或声称所有积压任务已经完成。 安装后的持续服务时延与完整业务补办仍需分别验收。
改动思路 / Approach
文件观察属于现有飞书 provider 的 IO;缓存只保存可重新推导的提示,Core 继续独占恢复资格、授权和执行。 本 PR 完整交付可失效的历史扫描提示与原 worker 接入,保留完整正文复核,不扩展业务恢复策略。 原目录和磁盘文件继续是工作来源,没有内存队列替代它们。已交付文件只有在设备、inode、修改时间、变更时间和大小一致时才复用少量信息;缺少或失效的提示回到原文件读取。待处理文件持续直接读,旧恢复项仍按原间隔重新询问 Core。与增加轮询间隔、删除历史或保存完整正文相比,这个范围减少重复成本,同时保留新输入响应和原失败证据。
具体改动 / Changes
关键代码讲解
PrivateDeliveryDiscovery.rows在读取前后核对文件指纹,只保留少量路由字段和原纯函数的展示修复提示。它不会保存完整正文、grant 或已作出的执行决定。删除的文件也会从提示集合移除。pending_delivery_paths复用同一扫描器,仍保留原新消息顺序、60 秒恢复探测和新的 Core observer。发现资格不代表获准执行,实际 worker 继续完整读回原记录。_web_projection_paths用提示选择源文件位置,再读完整源记录并重新检查可用绑定、Session、私聊类型和状态,才进入原 outbox 路径。它不把精简提示误当成完整源。
规范依据:docs/architecture/rfcs/app-conversation-and-async-inbox-v0.md,spec_revision 39770a9604836cc323087f47cd1eb0b8465cda21,见 Acceptance and failure matrix。Result:原受众、完整回传和未知回执保护保持;Authority:撤销和源变化仍由原 owner 阻止;Acceptance:原请求相关性和单一逻辑执行保留。三项均以现有完整私聊/原生运行时回归核验,不把发现路径相等当成授权正确的唯一证据。
冻结文件 fixture 的同入口对照中,旧、新路径的发现集合与顺序一致,恢复资格变为可用再撤销时也一致;旧路径热扫描读取 121 个正文,新路径只读 1 个待处理正文,独立重复 IO 断言在父版本失败、在本精确头通过。真实历史的只读对照也保持相同发现结果,原始内容和日志留在私有诊断目录。
对主干的风险 / Risks
未发现阻断问题。主要风险是陈旧提示遮住变更或被误当成发送许可,因此回归覆盖保持 mtime 的同大小原地修改与原子替换、读取期间更换文件、删除、新输入、读失败,以及源变化、撤销、未知写回和满 worker 池的后续工作。最终完整套件 PASS:408 项;Ruff、编译、RFC 配对和原生 premerge PASS。抽取期间发现的测试 hook 错位已恢复原捕获读路径,最终完整回归没有删断言或放宽时间限制。
全仓 ratchet 留有一项原有 _admitted_interaction_next_cli_actions 函数大小诊断;相同命令在不可变父版本与精确头得到同一身份和明细,当前 native gate 归为 inherited advisory。本次没有提高任何预算或登记豁免;原私聊模块增长问题通过局部抽取解决。按 Goal 策略不查询或等待远端 CI。第一次冷扫描仍需解析全部原记录,缓存只占少量按文件派生的内存;不能据此声称整页延迟或所有后台成本已解决。
语义与 CI 对齐
此变化是 local_only provider IO 提示,复用既有 status 和恢复谓词,不新增共享协议、开关或另一套 Core 决策。原目录完整扫描、持久记录、授权、错误和原发送/回执 owner 保持。当前必要不变量有独立通过证据,未相关的基线诊断保留,最终合并仍单独核验精确头与权限。
我的整体评价 / Verdict
这是有可测收益、可独立回滚的合理增量。long_horizon 改善在于减少重复历史读取,同时保留新工作、公平调度和后续恢复;user_experience 保持原会话、原受众和零额外配置步骤。只改变飞书 provider 的扫描读取,设置页、消息正文和渲染代码均无改动,因此本 PR 不需要视觉变更截图。 未验证安装后的持续设置页时延和原生 App 视觉表现。 安装采用和持续延迟验证属于后续同一交付的读回,不能以本次测试替代。实现已经在现有 provider 边界内合并两个相同读取需求,不需要更大的持久索引、权限缓存或通用决策框架。
English verdict: APPROVE — unchanged delivery authority and discovery semantics, with verified reduction of repeated body reads. Installed sustained performance remains a separate acceptance check.
Private-message discovery parses every historical delivery journal on each worker pass, including unchanged completed records. As history grows, those repeated body reads and JSON allocations compete with current replies and settings reads.
Reuse a small process-local routing view only while a delivered file's device, inode, timestamps and size match. Pending and new files stay fresh, deleted entries are removed, and changed files invalidate the hint. Recovery still uses the existing fresh Core observer and admission checks. App projection rereads the selected complete source journal before building its outbox; no bodies, grants, delivery acknowledgments or execution decisions become cache authority.
Validation: final private-conversation/progress suites pass (408 tests), Ruff passes, and native premerge passes with one independently reproduced inherited advisory in the unchanged interaction-contract owner. No budget or exception was relaxed. The frozen-file counterfactual has identical discovery paths and native eligibility transitions: parent warm scan reads 121 bodies and fails the duplicate-IO oracle, while this head reads only the pending body and passes. Preserved-mtime in-place edits and replacements, concurrent capture, new inputs, read failures, restart, source revocation and App delivery recovery are covered.
The helper stays in the existing Lark provider, avoiding further growth of the near-ceiling conversation module. Cold scans still parse the original files; sustained installed service latency and completion of pending business work remain separate acceptance checks.