Repository navigation
fix(reports): retain original authority across partial source reads - #7218
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 | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=max
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
动机
已经授权周期报告、但部分项目来源暂时读不到的原会话用户。 两个 Goal 都获准读取,但其中一个来源缺失。旧服务把只读到的一个 Goal 当作完整授权范围,导致有效稿件既不能结算也不能送达;修复版沿原授权恢复,仍明确保留缺读来源。 来源暂时不完整不再被误判为撤权,已有稿件可以经原事务和原受众返回,无需重复调用模型或人工补发。 不增加权限、来源、调度器、任务库、消费者或模型工作,也不把缺读项目记为已经覆盖。 生产采用和原消息实际送达仍需独立验收;完整来源覆盖、通用任务自然语言入口和下一独立周期由现有工作继续。
改动思路
完整授权由原绑定与 canonical Goal 身份决定,读取覆盖由现有 source reader 决定;新稿把两者的关系冻结在已有 request digest 中,原生结算和 sender 保留原职责,没有第二套状态权威。 本 PR 只修复原报告读取覆盖与授权身份混淆,并保留历史稿件的严格恢复边界。 直接跳过授权检查会放过真正撤权;只比较整个当前范围又会把后来合法加入的项目当成撤权。因此当前 producer 在冻结输入时保存完整原授权 ID 集合,并核对它与已准入的 canonical 身份摘要一致。sender 仍逐段检查原授权成员和身份,source reader 继续单独报告缺读。这个派生见证不需要用户维护,也不是新的权限声明。
对照表基于 659c1fd4 与 1d9380ee 的相同原生入口和 fixture,表示合成验证,不表示生产送达证明。
| 相同输入 | 基线 | 本次 head |
|---|---|---|
| 部分来源缺读,原完整授权不变;新输入与历史稿件 | 六个正向用例失败,原稿无法送达 | 原事务提交并经原 sender 全文读回,模型次数和冻结稿不变 |
| 未读 Goal 撤权/替换、未知历史增长及普通关闭路径 | 十三个反例/兼容用例通过 | 同样十三个用例通过,未放宽原身份和停止条件 |
具体改动
规范为 periodic reports contract,revision 659c1fd441abf5bd9171f22d9a84981497856a63。Daily portfolio report 的覆盖缺口和授权分离已实现;Original private report settings and execution 的原身份、冻结稿与合法增长约束已实现;Acceptance boundaries 的安装、实际原私聊返回及下一自然周期仍 deferred。文档说明了历史缺少完整身份见证时的严格限制,不将它补写成“已完整覆盖”。
关键代码讲解
StewardReports.delivery_current保留原订阅、受众、请求/来源摘要及现有可读 Goal 的成员检查。新稿再检查完整原授权集合仍在当前授权中,并按现有 canonical Goal 实例/创建身份重算原摘要。撤销或替换的项目即使没有读到,也会阻止投递。StewardReports.prepare从原绑定读取完整授权,而非从可读的 source rows 推导权限。集合对应的 canonical 摘要必须与该原生 Turn 的已准入摘要一致,才能进入原有来源冻结过程;不创建授权、不选择其他业务 Agent。prepare_private_report是唯一当前生产 caller 使用的内部 writer,新写入必须提供见证并将它纳入已有 request digest;可读 source IDs 必须包含于该授权。旧请求存在时仍读原内容,不重写其 digest、正文、窗口或生成结果。历史部分稿件只在完整当前授权摘要仍精确等于原摘要时恢复;无法识别原成员的后续变化继续保留。
对主干的风险
关键反例是来源缺失隐藏了一个已撤权或已替换的项目,修复却错误允许发送。本次实际移除/替换的是“获准但未读”的 Goal;两种后端均拒绝,journal、模型调用和 sender 写入保持原状。合法的新项目加入则与撤权分开:有原完整见证的新稿可以沿旧内容完成,新增项目留给下一窗口;没有完整见证的历史部分稿件遇到范围变化仍拒绝,不能猜出原授权成员。
相同十九项原生入口比较中,基线六项失败、十三项通过,本版十九项通过;最终报告与原路 sender 回归 78 项通过。standard exact-source premerge 六项直接、十一项选中检查通过,含编译、语义、维护边界、RFC bilingual 和四个文件的 public-boundary 检查。测试只在来源 IO 层注入缺读;租约、native journal、任务完成、结算和 sender/readback 都经过真实 File/SQLite 路径,未 mock 送达或提交后置条件。历史输入格式在任何模型/生成前构造,再由真实旧 child-validator 失败及原 pump 恢复。
语义与 CI 对齐
这复用现有 canonical scope、私有 request digest 和原生恢复词汇,未新增公共协议、任务 authority、调度或 generic kernel 规则。当前 writer 与消费者同包采用,不保留旧 writer 模式;保留的是确有义务的历史冻结数据读取。source coverage 与权限仍是不同事实,新增见证不会把 unknown 改成 complete。当前 managed policy 为 wait_for_ci=false,没有查询或等待 GitHub CI;必要本地检查和精确 head readiness 仍执行。
我的整体评价
完整授权由原绑定与 canonical Goal 身份决定,读取覆盖由现有 source reader 决定;新稿把两者的关系冻结在已有 request digest 中,原生结算和 sender 保留原职责,没有第二套状态权威。 本 PR 只修复原报告读取覆盖与授权身份混淆,并保留历史稿件的严格恢复边界。 长程效果 improved:原模型成果能沿原事务继续,sender 和后续窗口仍保持各自身份,重复观察不增加模型或重复已核验发送。用户体验 improved:已有意图无需补确认、重新整理材料或人工代发;未知旧范围与来源缺口依然明确。visual_review 为 not_applicable:Only private report identity metadata and its host authorization check change; no rendered page, report formatting or controls change. unverified_scope:Installed original-message receipt and live report completeness remain outside this source review.
范围与成本相称:两个现有 production 模块复用原身份摘要和冻结输入,新增字段是由真实 producer 派生的不可变见证,没有第二份可编辑 authority。旧文件仍可审计,较便宜但放宽权限的替代方案被实际反例否定。结论为 APPROVE,仅覆盖准确 head 1d9380eea126ce2c43deac56a54b971685092ff3;生产安装、原受众实际收到全文和更广通用任务入口继续分别验收。
English verdict: APPROVE — 1d9380eea126ce2c43deac56a54b971685092ff3 separates partial read coverage from original authorization, while preserving unread-Goal revocation/identity checks and immutable historical reports. Matched File/SQLite base six failures versus head nineteen passes, 78 report/sender regressions and exact-source premerge passed. Live installed delivery and complete source coverage remain separate acceptance work.
Goal And Delivered Outcome
An original report can have a valid frozen body and unchanged authorization while its portfolio read is incomplete. The old publication guard compares the full authorization digest with only the readable Goal IDs, so it mistakes partial coverage for revoked permission and strands the report. For example, two authorized Goals with one unreadable source cannot publish even an honest partial report.
main. No scheduler, task store, worker, consumer or permission is added.Author Declaration
659c1fd441abf5bd9171f22d9a84981497856a63.StewardReports.prepare,prepare_private_reportStewardReports.delivery_current, existing original journal recoveryScope And Continuation
New writers always provide the original authorization witness. Older frozen requests are read unchanged: a full-coverage request retains existing growth behavior; a partial legacy request without a witness requires the complete current scope to match its original digest exactly. Unknown original identities are never guessed.
This closes the demonstrated authorization/coverage mismatch. Actual installation and original-message readback follow reviewed merge; broader managed periodic-task authoring and complete portfolio source coverage remain with their existing delivery work.
Validation
1d9380eea126ce2c43deac56a54b971685092ff3.real_entrypointintegrationregression_paritystaticmanualFrontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Existing original-report authorization and native recovery. The canonical authorization hash remains authority; the immutable ID list is its frozen verification witness, and the separate source reader still owns coverage.
Shared-authority RFC fixture impact
N/A: no authority promotion, backend routing or compatibility projection changes. File and SQLite fixtures exercise the original report lifecycle; PostgreSQL promotion rehearsal is outside this change.
Boundary Checklist
none.Signed-off-bytrailer.