Repository navigation
fix(lark): bind periodic report routes to the managed session - #7353
Conversation
Filter original-route candidates by the managed actor's canonical Session and source before selection. Preserve provider checks, saved-route identity and default owner notification routing, with File/SQLite regressions. Related to #7179. Signed-off-by: Codex <codex@openai.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
loopx-agent
left a comment
There was a problem hiding this comment.
Reviewer: model_agent · gpt-6.1-sol · OpenAI · runtime_reported · max
动机
在同一私聊使用 /new 后,首次准备新管家执行身份并启用定时报表的用户。
旧会话的合法记录按哈希排序领先时,旧实现选中它再拒绝新会话;本头先按当前执行身份筛选,原启用流程可完成。
真实 File/SQLite 的预览、应用及单独读取确认原会话绑定,HTTP 来源拒绝和恢复成立,未额外调用模型或发送消息。
不修改日历、额度、执行器、权限、通知默认或前端布局;不宣称真实飞书发送、安装态或自然定时交付通过。
这解决的是一个确定的配置阻断:用户已经有合法的新会话来源,继续重试却不能改变旧记录的哈希排序。本轮先读原7179纠正发现及既有原始来源合同,再审整个提案,没有取消身份检查来让启用成功。
改动思路
在既有 provider 路由发现中加入精确筛选,并让已保存报表复用同一个原身份校验;无需第二扫描器、状态或调度 owner。
本 PR 完成首次准备新会话后的报表路由修复;后续再次 /new 仍受原 canonical Session 身份失效检查约束,不自动迁移订阅。
原来先选一个“同私聊合法”记录,再问它是否属于报表执行身份;新代码在选择时便使用 Core 已持有的会话和来源。通知仍只需要原来的私聊范围。这个差异属于既有 provider IO 的筛选,不把身份、日历、配置、执行或发布的决策搬到第二个 Python owner,也无需为这一修复重写整个 typed 内核。
| 路径 | 旧行为 | 本头行为 |
|---|---|---|
| 新会话首次准备后启用 | 领先旧记录令外层拒绝 | 找到当前 actor 的验证来源 |
| 已冻结报表恢复 | 通用私聊记录验证 | 同一原 actor 验证,禁止换会话回退 |
| 普通 owner 通知 | 原私聊路由选择 | 省略筛选参数,完整结果与调用保持 |
该表来自代码和下面的执行对照,不是独立的运行证据。无需额外填写已知 Goal、收件人或新增确认;既有设置预览/应用仍负责原权限事务。
具体改动
规格是 docs/product/periodic-reports.md,spec_revision 2b72d30fca7f452a71dffb723ebf6d1e2e878484。其“原私聊、原执行身份、当前来源验证、保留未知发送和原历史”是本头判据。下列名称是本次映射标签,原规范没有这些编号:current-session-route、provider-source-audience、frozen-original-route、owner-notification-parity 四项均由下面的实际路径覆盖;原自然定时、安装与真实模型报告资格没有被加入本修复结论。
关键代码讲解
LarkOwnerAttention._route:94:在原完整候选遍历里增加两个可省略筛选。使用 canonical Core request 的session_id和source.source_ref,不相信文件名或 transport 记录里复制的会话字段;原 native source 相等、App/owner 与原消息验证继续执行。LarkStewardReports._original_route:31:把 actor 的两个身份传入共享选择器,仍保留返回后的原会话/来源核对。新增 saved 参数表示只验证那个冻结候选,不能遇到不符便另找一个。reconcile的已保存分支:原original_route也走同一个 verifier;原 committed Turn、生成验证、当前授权、完整 provider readback、锁和 publication cursor 均保留。
整 PR 为四文件 +136/-4,其中生产代码仅 +13/-4、116 行具名回归、7 行合同澄清。没有新生产模块、持久字段、枚举、CLI、UI 或迁移版本。搜查了通知配置/恢复和报表配置/恢复的全部共享调用;当前队列中其它同作者修复属于取消与观察 owner,没有重复实现这条来源选择。5940/5944 的经验只用于核对真实用户结果和 owner 分工;不继承历史结论,也不声称记忆改善了本评审。
对主干的风险
最强反例是“新启用成功了,但旧发送恢复悄悄借了另一个会话”。我独立跑了三个完整相关模块:79 passed,0 skip,包括本头全部18个路由用例、原私聊完整发送、partial/unknown-send、重启与普通通知回归。额外用实际 HTTP Server、Core/native 状态和 File/SQLite 跑预览、应用、独立配置读回;foreign Origin/Goal、owner 暂不可用和过期 plan 被拒绝,来源恢复后原合法 plan 可用。
对保存后的实际报表,我先形成真实本地 generation/window 和待发记录,再放入一个合法旧会话 route:重启 reconcile 不写 provider、不改冻结记录、不推进 cursor。恢复原来那份精确冻结证明后仅完成一次发布;再次 reconcile 不重发、不重跑模型。native/Lark 传输是合成的,未向真实账号发送。
我还以同一真实合成状态加载不可变 base 的完整 _route 实现,与本头逐项对照:两种存储、五类既有输入、四种 provider/来源状态,共 40 对完整返回或异常类型/消息及 provider argv 序列完全相同,未做语义归一。新签名的显式 None 参数另与本头省略参数对照;旧 API 不接受新关键字,不能把该有意接口扩展伪称旧输入相同。
旧缺陷控制使用完整未改的本头回归,在最新目标主干 56cedb4c886d1fceaddea4113f4a1c56fa934aee 上得到 2 个预期失败,分别为 File/SQLite 在启用前抛出原始会话不符。该主干相对 PR merge-base b95223532af1cc3cc6bd9558f96750c79f581e1b 的变更只在独立 native-account 包,路由和此回归依赖未变。回到 000e4ca3dcf3e39875a8f9911d31423b398dad22 后原完整模块通过。没有改产品、超时或删断言来获得通过。
另一次真实 /new 发生在已启用报表之后,原 canonical binding 返回 canonical bound Session identity changed。原 actor、订阅及历史保持,没有自动转交未来会话。我的初始探针误假定旧订阅仍能继续读取,两个失败原样保留;按照原 source-bound 合同修正预期后,真实 File/SQLite 证明这个既有拒绝仍生效。此 PR 修的是首次准备新会话的候选选择,不宣称改变后续会话迁移。
语义与 CI 对齐
三个改动 Python 文件的 Ruff/编译、配置中的17文件 mypy、双语 RFC diff 和 whitespace 检查通过;mypy 不是所有改动模块的类型覆盖。标准 premerge 6直接、2catalog、8risk、1boundary 执行均通过,初次总门仍为前一 head 收据造成的 quality_stale_receipt,不能写成总门通过。
必需的完整工作流 Ruff 命令在精确主干 56cedb4c886d1fceaddea4113f4a1c56fa934aee 与本头均报相同 tests/presentation/test_linked_goal_sources.py:23:5 F401;完整 stdout/stderr、检查命令、配置/工作流与失败文件 blob 相同。该文件不在本 PR 的因果路径,独立改变的不变量已通过,故按当前 review 规则归为 pre_existing_unrelated,不要求本 PR 混入另一修复。**必需检查仍失败;严格精确 CQR cqr_c0587fd2a9006197c00e 为 FAIL,verify 不合格,合并质量门保留。**未合入的 #7351 不能当成本头已有修复。
没有查询、轮询或等待远端 CI。作者报告的其它全套失败按作者来源保留,我没有把它们声明为本轮已独立归因或已通过。
我的整体评价
对 000e4ca3dcf3e39875a8f9911d31423b398dad22:APPROVE,具名的首次准备/路由修复已达成,本范围未发现新增代码阻断;这与未通过的必需 lint、严格质量门及维护者合并权限分别判断。
long_horizon 为 improved,限于旧历史不再挡住合法配置、原恢复继续保持一次效果;没有完整成本或长期净收益测量。user_experience 为 improved,原启用流程可达,来源错误及未来会话失效仍准确拒绝。未改渲染与布局;检查了既有报表设置 HTTP 入口、原会话和源验证,视觉审查在本差异中不适用。 未进行真实飞书发送、安装态、自然定时或模型内容质量验收。
在既有 provider 路由发现中加入精确筛选,并让已保存报表复用同一个原身份校验;无需第二扫描器、状态或调度 owner。 本 PR 完成首次准备新会话后的报表路由修复;后续再次 /new 仍受原 canonical Session 身份失效检查约束,不自动迁移订阅。
有界整理已经落实为冻结路径复用原 verifier。没有新增通用框架或并行授权状态,现有 schema/领域词汇继续复用;更大迁移不构成本次修复前置。原 source 核验仍是强制身份不变量,不能称为可忽略的指引。批准不清除质量失败,不授予合并、安装或其它会话权限。
English verdict: APPROVE — 000e4ca3dcf3e39875a8f9911d31423b398dad22 fixes the reproduced first-preparation route-selection failure while retaining canonical actor, provider and frozen-audience checks. Independent79 local tests, actual File/SQLite HTTP and retained-delivery recovery pass;40 complete default-route/IO pairs match immutable base, and the old regression fails on exact target main. A later /new still invokes the existing canonical-source refusal. Required full Ruff is independently pre-existing but remains red; exact strict CQR is FAIL. This review does not clear quality/merge authority or qualify live Lark, installed behavior, natural deadlines or real-model report quality.
Goal And Delivered Outcome
After an owner used
/new, sent an ordinary message and first prepared the managed actor in the new Session, enabling periodic reports could fail even though an eligible original source existed. The shared private-route finder returned the first valid historical receipt in hash order, and the report adapter rejected its older Session before examining the current actor's receipt.Report route discovery now filters by the managed actor's exact canonical Session and source before selecting a candidate. Provider, owner and original-message verification still run. Saved original routes use the same actor check and cannot be replaced with another Session's route. Owner Todo notifications retain their existing default route selection.
main; reviewed baseline2b72d30fca7f452a71dffb723ebf6d1e2e878484./new→ message → first prepare → report preview/apply flow fails on both File and SQLite at baseline and succeeds with this patch, without model invocation or external writes.Author Declaration
docs/product/periodic-reports.mdat that revision.session_idandsource_refselectors inLarkOwnerAttention._route; report adapter supplies both/new_original_routeScope And Continuation
Complete within this scope. The repair stays in the existing Lark provider adapter. Hash ordering, typed report planning, calendar behavior, Goal configuration, publication ownership and report payloads are unchanged. The product contract documents exact-actor selection and frozen-route behavior. No successor is required for this repair.
Validation
000e4ca3dcf3e39875a8f9911d31423b398dad22; its source tree is identical to the locally validated tree.finished.synthetic.The branch was rebased onto
b95223532af1cc3cc6bd9558f96750c79f581e1b; the only intervening main change is an unrelatedteam-evidence.mjsbrowser test. All fix file blobs are unchanged. The key File/SQLite route regressions (18 passed) were rerun after the rebase. Broader checks below were run on the same fix files over the earlier reviewed baseline; they were not rerun solely for that unrelated test change.tests/test_lark_steward_report_route.py. Actual admission,/new, first preparation and report preview/apply use isolated File/SQLite persistence; native and Lark peers are synthetic.git diff --check. No paired RFC changed.python examples/control_plane/cli-output-budget-regression-smoke.py.loopx check --scan-path loopx/ --scan-path tests/ --scan-path examples/ --scan-path docs/completed with 43 non-literal credential-reference warnings and no blocking scan error.explore_history_rowsimport intests/presentation/test_linked_goal_sources.py:23; changed files pass.benchmark/tests/test_native_checkpoint.py::test_interrupted_cursor_requires_exact_unreleased_final_guard[None-legacy]fails identically on clean main and this branch. The remainder was not run.loopx canary premerge --from-git-diff --git-diff-base origin/main --fail-fast, standard tier: direct checks, 2 catalog canaries, 8 risk-profile smokes and the changed-path public-boundary scan passed.All synthetic runs used
LOOPX_USAGE_PING=0. No real Lark account, live notification/report delivery, paid model, browser or installed package was used. The actual file/SQLite entrypoint tests cover the reported flow and identity rejection; saved-route helper assertions are complemented by existing recovery tests and review of the frozen-route checks.Initial GitHub CI
DCO Sign-off passed. The branch's kernel-static-checks fails on the same unused
explore_history_rowsimport as the exact base's own CI. Dependent test/merge summary gates therefore fail or skip; this PR does not claim a green full CI run.Frontend / Visual Evidence
none; this changes provider-route selection behind the existing report actions, with no UI source or layout change.nonefor visual evidence.Type / Area
Bug fix, persistent regressions and product-contract clarification. Lark provider integration for managed-steward periodic reports.
Shared-authority RFC fixture impact
N/A: this does not change canonical-store routing, authority promotion, compatibility projections or the TypeScript migration.
Boundary Checklist
Signed-off-bytrailer.