Repository navigation
fix(chat): keep report quota checks outside publication locks - #7714
Conversation
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; model=gpt-6.1-sol; provider=OpenAI; declaration_source=runtime_reported; reasoning_effort=max.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval).
动机 / Motivation
管家报告等待额度查询时,其他会话的用户也会遇到输入和授权配置被阻塞。例如原报告正在等待额度结果时,用户给另一个会话发消息;旧路径无法取得发布锁,新路径允许入队,并在授权变化后拒绝沿用旧恢复观察。最终测试证明查询暂停时可取得两把发布锁并保存普通输入,原记录或授权变化会阻止恢复,合法的一次恢复及后续独立窗口仍通过。本PR不证明真实账号切换、安装采用或自然报告已经送达。真实账号切换后的自然恢复与原会话送达仍由现有服务验收,未知效果窗口继续保留。
改动思路 / Approach
锁外查询复用现有transport,原有typed owner继续决定恢复资格;只在本次调用保存可重读的快照,避免第二套状态与消费者。当前PR仅修复原报告额度观察的全局锁边界及并发复核,不改变账号选择、重试政策或业务回传。原泵仍读取原订阅、窗口与失败记录,元数据读完后重新核对原始事实,再经普通准入启动原worker。只释放锁会留下过期授权风险,另建服务又会重复已有生命周期;复用既有prepare/observe/admit调用点是当前更小的完整修复。原生元数据属于外部观察,既不创建义务,也不能将未知失败改称无副作用。
具体改动 / Changes
关键代码讲解
_prepare_submission原来直接做慢查询,现在返回本次查询需要的原记录与绑定。查询后及身份校验后都检查执行相关字段和原授权;可重读的SSE计数不作为执行变化,所以正常读回不会错误阻塞。submit在两把发布锁之外进行一次元数据检查,然后进入原短事务,复核请求、会话、队列、恢复关联与授权。若原请求在身份等待期间才出现,保留原结果,不在最终发布事务里追加一次查询。report_quota_request继续只读取原生元数据和当前可用额度。实际恢复资格仍由既有TS owner检查原始user-only拒绝、原journal、窗口和一次关联,两个现存报告调用者没有产生第二套业务规则。
独立规格是 docs/product/periodic-reports.md,revision 2f544f969236f5dbbe858720108c41d07be60a6c 的原额度恢复合同。R-original:implemented,原失败记录、journal和窗口关联保留,改变原响应会拒绝;R-user-priority:implemented,等待查询期间无关输入可持久入队,原会话已有用户工作会阻止恢复;R-one-recovery:implemented,既有合法恢复、再次失败保留及下一独立窗口回归通过。原生本地Session使用单会话adapter锁,与本次全局发布锁问题不同,原路径保持共享typed资格检查。
对主干的风险 / Risks
未发现阻塞问题。最强反例是锁释放后原授权或失败记录已变化,旧观察仍发起模型工作;最终测试覆盖授权修改、原响应修改、身份观察后再修改,以及原会话排队输入,并检查原journal/model捕获字节未变、无新关联Turn。无关会话和只读计数变化也经过真实存储读回,避免只修越权而留下过度阻塞。
PASS:最终26项File/SQLite定向回归;固定base的两项原恢复及六项普通native对照;六项直接和两项catalog预合并检查;Ruff及公开边界检查。最终同一测试在字节准确的base产品上再次因发布锁不可用而失败,恢复head后工作区逐字节一致。测试使用真实host、内核及存储,元数据和模型为合成边界。一次中间运行的两个15秒等待超时保留,未宣称其历史成因已修复;固定base对照与最终完整组合在原预算内通过,标准语义扫描也没有放宽120秒限制。当前CI策略不咨询远端CI,change-quality policy为disabled;这不赋予合并权限。
我的整体评价 / Verdict
这是 justified_increment:限定到本PR的锁可用性和当前源复核得到验证,long_horizon与user_experience在该边界改善。查询等待时独立工作可继续,原失败、一次恢复和后续窗口仍由原owner负责;没有增加用户配置、复制、确认或恢复轮次。代码只增加本次调用的派生快照,不增加持久格式、CLI、scheduler或共享词汇。当前机制应保留,兼容版本拆分和新runner都不需要。
锁外查询复用现有transport,原有typed owner继续决定恢复资格;只在本次调用保存可重读的快照,避免第二套状态与消费者。当前PR仅修复原报告额度观察的全局锁边界及并发复核,不改变账号选择、重试政策或业务回传。检查了完整差异和原调用链,未修改任何页面或渲染组件,visual_review不适用。尚未验收的范围是实际账号切换、安装采用和自然报告送达。真实未知效果窗口继续保留;合成恢复成功不代表用户已收到业务结论。当前source head为 7b64579ec432da987b095cd292d5730d1727ed0f,没有继承旧PR批准或清除其他交付门禁。
English verdict: APPROVE. The publication-lock repair and stale-observation fences are verified at 7b64579; real provider switching and natural delivery remain separate qualification.
Goal And Delivered Outcome
管家检查报告的额度恢复资格时,会在全局会话锁和绑定发布锁内等待原生元数据及额度查询。查询等待会阻塞其他会话的普通输入和授权配置。现在先保存原请求与绑定,锁外完成一次查询,再在短发布事务中复核原授权、执行记录及当前准入条件。
范围是现有原生报告 transport 的 IO 边界;不增加重试资格、执行器、消费者或配置。基于
main,直接修复本描述中的可复现缺陷。Author Declaration
Written by: model_agent, GPT-6 family (OpenAI).
Implemented against
规格:
docs/product/periodic-reports.md的额度恢复合同,revision2f544f969236f5dbbe858720108c41d07be60a6c;锁可用性要求以本 PR 的复现为基础。StewardTurnHost.submit_prepare_submissionScope And Continuation
此 IO 边界修复可独立回退。真实账号切换后的自然到期恢复、安装采用及原会话实际送达,需要各自的运行验收;合成测试不证明这些结果。原有未知效果保护继续生效。
Validation
Tested revision:
7b64579ec432da987b095cd292d5730d1727ed0f。Input classes: synthetic。StewardTurnHost.submit、实际 File/SQLite 存储、原生内核和合成模型路径,共26项定向回归loopx canary premerge --from-git-diff:六项直接检查、两项选中检查全部通过;语义扫描在原120秒限制内完成一次中间运行有两项原生等待超过原15秒预算;固定基线对照及最终修复版26项均在该预算下通过,未放宽等待或恢复条件。原失败证据保留,不据此宣称解决了所有环境时序问题。
Frontend / Visual Evidence
UI impact: none。现有恢复 transport 内部边界发生变化,页面、文案与展示组件没有修改;视觉验收不适用。
Type And Boundary
Bug fix; capability / host runtime integration。未改变共享协议、TypeScript决策owner、权限边界或受保护发布。所有提交包含DCO;未变更成对RFC。代码与本说明已检查公开/私有边界。