Repository navigation
fix(chat): recover report quota refusals across retained contexts - #7724
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).
未发现阻塞代码问题;APPROVE 这个有界恢复增量。真实订阅切换和生产送达仍需原服务证据。
动机 / Motivation
受影响者是启用周期报告、在额度拒绝后更换原生模型上下文的管家和单项目 Session。
例如报告只写入原用户输入便遇到额度耗尽,随后上下文换新;旧实现只查新线程,安全的旧失败被遗漏,修复后沿同一会话保留的来源查证并续办一次。
已验证的改善是合法旧上下文可以恢复,当前上下文仍可恢复,外来线程及有执行效果的失败仍被拒绝。
本次只修复查证来源与准入关联,不执行订阅切换、不重放原失败,也不证明真实模型遵从或实际报告已送达。
真实订阅切换后的自然触发、安装采用与原受众实际送达仍由原服务验收。
改动思路 / Approach
原生来源由现有 Session 写入,Host 只负责读取,是否允许新报告继续由共享 typed owner 决定;复用这两个边界比再造恢复器更小。
本 PR 的可用边界是:在已有报告恢复入口查到已登记旧上下文,并在原规则下执行一次新续办;真实额度切换与报告内容质量仍属原服务验收。
保持现状会持续遗漏合法失败;直接复用普通上下文恢复器则混入表示版本迁移、外部消息来源及其他错误策略。这里使用已有会话来源、原生只读 reader 和原报告 typed gate,新增查询列表与来源成员校验,没有第二个执行器、配置或状态表。旧上下文用于查证,新报告在当前上下文执行;原生5秒读取边界不变,缺少证明时保留失败。
| 同一合成请求 | 基线 | 当前 head |
|---|---|---|
| 原失败在当前上下文 | 一次续办 | 一次续办 |
| 原失败在已登记旧上下文 | 只查新线程,未续办 | 查原来源,一次续办 |
| 外来线程或已有执行效果 | 拒绝 | 继续拒绝且原记录不变 |
表格归纳 dc47894 的受控用例,模型与投递是合成边界,不代表生产自然事件。
具体改动 / Changes
关键代码讲解
- StewardTurnHost.report_quota_request 保留原报告候选检查,从同一 Session 读取当前线程及按近到远排列的历史线程,去重后交给既有原生只读 reader。只有稳定原用户输入、usageLimitExceeded 和当前可用额度才返回一次相关请求;没有恢复旧线程或重写原失败。
- admitReportQuotaRecovery 继续由共享 Core 核对 actor、Task、窗口、失败 journal 和零效果。改动把只能当前线程换为属于原 Session 已登记来源,并验证历史结构;外来来源、工具效果、过期观察和第二次恢复仍拒绝。普通请求在处理历史之前返回。
- 测试复用真实 File/SQLite 和两种既有报告入口,覆盖当前/旧上下文、成功/失败续办、后续独立窗口和来源并发变化;反例核对原消息、journal、模型调用与发布状态不变。生产改动20行新增/2行删除,测试73行新增/5行删除,没有新生产模块。
独立规格是 docs/product/periodic-reports.md,不可变 revision 5b224f0,其额度恢复段落未由本 PR 改写。QR-PROOF、QR-IDENTITY、QR-BOUND 映射原文未编号条款:原生无效果与额度证明;原身份和失败记录保留;单次相关续办、未知效果保留及普通验证/原路回传。三项均 implemented,并由上述入口和正反例支持;真实模型质量与生产原受众送达继续由现有服务验收。
对主干的风险 / Risks
最强反例是原报告执行过工具,但本地增量计数仍为零。原生 reader 要稳定读回原 Turn 的完整 item;Host 和 typed gate 都继续要求只有原用户输入。独立协议测试拒绝工具、回答、未知项、冲突或活动状态。已存在的实际有工具效果失败,在独立只读查证中仍没有无效果证明,未被重放。
PASS:最终同一夹具在未修改的 5b224f0 上复现只查当前线程、期望一次而实际零次;当前线程控制用例通过。修复版32项报告回归、52项 TypeScript、15项原生协议/来源回归通过。默认 standard premerge 的6项直接检查和10项选中检查全部通过,保留原120秒限制;Ruff/diff 通过,未查询或等待 CI。
早期固定线程 ID 的夹具会在恢复连接时提前失败,修正后才形成有效基线证据。另一次中断运行只留下失败标记、没有 traceback 或完成记录;原因仍未知,不声称已修好该中断。修正夹具后,在原基线和当前依赖上分别有完整32项通过,原身份与拒绝规则另有15项验证。无 Git 用例的一次失败来自临时目录继承外层工作树;使用默认临时目录后同一断言通过,没有删断言、改代码或调时限。宿主中断可靠性仍未验收。
语义与 CI 对齐
本差异复用既有 report recovery、原生来源字段和 typed owner,没有新 actor、授权、持久版本或自动义务。来源由正常 Session 替换写入,store 强制保留原前缀;普通外部消息恢复器保留其不同的版本与错误规则。主干其他旧评审的120秒失败记录继续保留;本评审使用当前内容在同一预算下通过的检查,不因旧 PR 合入就改写其结论。
我的整体评价 / Verdict
交付判断为 justified_increment:long_horizon improved,安全失败在上下文替换后可以推进,续办失败不递归,后续独立窗口仍可运行;user_experience improved,复用已有意图与授权,没有新增必需输入或确认轮次。旧来源有实际持久消费者,保留该关系比增加索引、协议或另一个恢复器更合适。原生来源由现有 Session 写入,Host 只负责读取,是否允许新报告继续由共享 typed owner 决定;复用这两个边界比再造恢复器更小。
No rendered presentation changes: only steward_turn.py, typed steward admission and tests changed; the report reader and renderers are unchanged. 真实模型内容、安装后的自然触发与原会话阅读体验尚未由本差异验证。 测试中的模型、额度可用信号和投递是合成边界,不能代替实际订阅切换或业务回传;父级可靠性目标保持未闭。当前3文件内容与验证时一致,评审发布前还需核对同一远端 head。
English verdict: APPROVE — dc47894; safe report recovery follows retained same-Session native provenance. Base counterfactual fails,32 report cases,52 TS,15 protocol/provenance cases and default premerge pass; live handoff and publication remain unverified.
同一周期报告在额度拒绝后更换原生上下文时,恢复探针只查当前 thread,会遗漏同一 Session 已登记的旧 thread 中可安全恢复的拒绝。现在沿 Session 保留的原生上下文来源查证,typed admission 同时验证该来源,续办仍使用当前上下文。
保留原请求、失败与窗口;仅明确只有原用户输入、无执行效果、额度可用的 usageLimitExceeded 才能续办一次。外来 thread、有工具效果的失败和已续办窗口继续拒绝。
验证:
上述模型与投递为隔离合成输入;真实订阅切换后自然触发和实际报告送达仍需原服务证据。