Repository navigation
fix(status): skip settlement reads without matching run receipts - #5952
huangruiteng merged 2 commits into
Conversation
Signed-off-by: mika <211269698+mikamikasuki@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=xhigh
Exact head: cad1983; base: 060f023.
动机
使用 history/status 查看历史证据和工作状态的用户。 用户查看含无关损坏历史行的状态时,旧版整体报错;本版先找对应运行准入回执,没有候选时可继续显示状态。 File、SQLite 的真实 CLI 状态读取已恢复,但新的早返回错误接受相对运行根目录,输入边界仍需修复。 不更改配额扣款、重规划阈值、权限、持久化格式或新增配置;不宣称安装态、App 或整个恢复目标完成。
没有匹配准入回执的历史行本来不能贡献已结算工作次数,却能因无关坏行让用户反复失去状态与证据视图。这个修复有实际价值;不过状态恢复不能以扩大非法输入的接受范围为代价。
改动思路
回执筛选放在现有 typed adapter 合理,严格账本仍由原 owner 判断;输入不变量必须在两条分支之前执行。 本 PR 只修复无匹配回执时的历史状态读取,补回输入校验后即可独立交付。
复用现有 rollout snapshot、quota Goal owner、严格 settlement reader 和重规划 reducer。做法是先按当前 Goal、Agent、Turn 与 GoalRef 找候选,再把同一个事件快照交给原结算 owner;没有新状态、缓存、Python 决策源或全局容错解析器。直接放松严格账本会损坏结算契约,因此不是合适替代。
具体改动
关键代码讲解
projectSettledReplanHistory(line11)先过滤当前实例的历史,再建立回执 key 集合;line43 的无候选分支只传空资格集合,保留原 typed history policy。readQuotaSettlementSnapshot(line336)仍解析严格账本并调用 settlementScope 校验输入,但现在只有有候选的分支到达它。projectReplanHistory(line304)保留 ACK cutoff、去重和触发优先级,既有 snapshot RPC 也到同一 adapter。
整个 PR 两文件 +65/-4:生产 +23/-4、测试 +42,无生成物、格式迁移、权限或阈值变化。独立参考 docs/reference/protocols/goal-vision-replan-contract-v0.md,spec_revision: 060f023。criterion_id: Default review cadence 的有效结算次数、criterion_id: History-trigger ownership and retry semantics 的 owner/ACK/去重仍由原 owner 执行;本次实测这些路径通过,不能用新增测试反向定义规范。新增输入缺口则按改动前已执行的绝对根目录契约判断。
File/SQLite 实际 CLI 历史测试 head 8 passed;相同 base 2 failed、6 passed,两失败都是 status 的 line1002 损坏账本。额外 13 组相同磁盘 fixture 的 base/head 对照覆盖无回执、别的 Goal/Agent/Turn、alias/精确实例隔离、重复 Turn、未扣款、缺 guard、legacy 单位、匹配损坏账本与恢复:无关账本跳读是有意差异,匹配损坏仍拒绝,恢复合法日志后只计一次;读操作未写入两个日志。124 项 settlement TS、19 项 provider/policy、typecheck、advisory 与 standard premerge 3 direct+16 selected 均通过。
对主干的风险
[P2] 无匹配回执分支绕过 runtime_root 的绝对路径校验
给 work_item.replan_history.project 一个有效 envelope、非空相对 runtime_root、runs=[] 和无回执状态,真实 Effect Runtime RPC 在 base 返回 runtime_root must be absolute,head 却返回 replan_history_result_v0、trigger=null。事件路径读取会先按进程工作目录解析这个根;line43-44 随后早返回,跳过 line46 原来必经的 settlementScope。因此不是正常状态修复,也不能由已有绿测试排除。普通 Python codec 已把根目录绝对化,风险主要在直接 RPC 和未来错误配置的 caller;没有证据表明权限升级或活动数据损坏。
最小修复:在回执发现和早返回前恢复 runtime_root 必须为绝对路径的校验;以真实 work_item.replan_history.project RPC 补上空 runs、无匹配回执的拒绝测试,同时保留合法根目录的跳读及匹配回执的严格失败。
语义与 CI 对齐
这是既有共享输入契约被绕过,不是新 vocabulary。advisory 零候选不能证明语义正确,124 个 TS 绿测试也没有覆盖这条早返回。无远程 CI 查询、轮询或等待。既有 dashboard/Chat/Lark 消费相同 status 形状,无新增设置;本轮真实 CLI/RPC 与 File/SQLite 已测,packaged frontend、Lark、安装态、PG、付费模型及完整多平台套件未测,不把它们写成通过。
我的整体评价
REQUEST_CHANGES。长程状态可用性确实改善,但 caller 配置校验退化;上述有用结果不抵消这个具体阻塞项。机制规模和 owner 放置合理,未来重构检查确认共享 snapshot/原 reducer 已足够,所需伴随修复只是把原输入不变量放回共同入口。请修复后重跑真实 RPC 反例和现有合法根目录/严格结算用例;无需扩为迁移、全局放宽 parser 或重写配额 owner。本轮不合并。
English verdict: REQUEST_CHANGES - cad1983. Candidate-first reading restores File/SQLite status and preserves matched strict settlement, but the no-candidate early return bypasses the existing absolute runtime-root validation. The same real Effect Runtime RPC rejects the relative root at the immutable base and succeeds at this head. Restore input validation before receipt IO/early returns and retain both valid-root recovery and strict matched-settlement coverage.
Signed-off-by: mika <211269698+mikamikasuki@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=xhigh
English verdict: APPROVE — e818a6984af503b9bdaafa6877318cc5cc9f16c1. The existing absolute-scope invariant now precedes candidate IO/early returns. Independent actualRPC18 paired cases and File/SQLite CLI qualify no-candidate recovery while preserving strict matched settlement, ACKs and once-only counts. Four pre-existing scripted-fixture failures remain a separate quality hold; no CI queried or merge performed.
动机
使用 history/status 查看证据和剩余工作的操作者。
用户查看历史证据和当前工作状态,旧版因没有参与结算的坏历史行整体报错;本版没有匹配准入回执时继续显示状态,有匹配回执时仍严格拒绝坏账本。
真实 File/SQLite CLI 在基线2失败6通过、当前8项通过;独立18组实际RPC对照的五类无候选恢复,其余合法/拒绝/去重/ACK行为保持,两日志字节均未改变。
不更改配额扣款、重规划单位和阈值、权限、账本格式或配置;不宣称整个恢复目标完成。
完整安装态、packaged App/Lark、PG和长期成本未测;较宽Python选择中的四项既有脚本transport失败在同一基线也失败,保留为独立质量hold。
这避免一次无关损坏让人长期看不到工作和证据;没有对应准入回执的历史行本来不能计入已结算工作。减少无用解析有合理方向,但本轮没有测量长期延迟、模型费用或总体净效率。
改动思路
既有 typed replan IO adapter 先筛当前owner准入回执,沿用严格quota settlement owner与原history reducer;共享输入校验在所有分支之前复用,不增缓存或第二权威。
本 PR 只修复无匹配回执时的状态读取,并在共同入口保留非法scope拒绝。
合法scope进入原source admission后,先按当前Goal实例/Agent/Turn建立回执候选,空候选只向原typed reducer传空资格集合;有候选把同一事件快照交给严格settlement owner。直接放宽账本parser会弱化权威;新缓存会引入新鲜度问题,均无需加入此修复。非法root/Goal、坏rollout、匹配坏ledger继续报错;日志不存在或partial work不会变成成功结算。
具体改动
全量三文件 +122/-9:两个现有TS runtime owner和一个测试文件。scope facade8行复用原函数,adapter34行让candidate在ledger前,80测试行补无候选坏ledger与实际handler拒绝相对root。无Python新决策源、持久化字段、CLI参数、UI设置或capability开关。
不可变 goal-vision-replan contract,spec_revision 060f02300159955932e3d2c3b4e4e60dc0539603;criterion_id Default review cadence、History-trigger ownership and retry semantics、Existing settlement input contract 全部implemented。前两项保留原owner、单位/阈值、Agent先于ACK和同Turn一次;后一项沿用基线生产scope validator的绝对root/单segment Goal拒绝,不能由新测试反向定义规范。
关键代码讲解
projectSettledReplanHistory(replan_history_settlement.ts:15)入口先验证scope,再按current-owner严格rollout建立Agent/Turn key。没有candidate返回原reducer与空qualified集合,不能把跳读当作已结算。validateQuotaSettlementScope(settlement_readback.ts:129)只是原settlementScope的窄facade。相对root、path-traversal Goal在IO和任一分支前拒绝;没有第二套验证规则。readQuotaSettlementSnapshot(settlement_readback.ts:344)仍严格校验并索引run ledger,且收到同一rollout snapshot;matched candidate的坏ledger/directstrict read继续失败,原GoalRef、borrowed lock与receipt owner不变。
独立18组真实Effect Runtime RPC:五种无/外Goal/外Agent/外Turn/空history候选的坏ledger由旧error变为trigger=null;其余13组输出完整相同,包括匹配坏ledger、坏rollout、缺writeback/spend、已settled一次、阈值2、重复history不重复计数、同ownerACK与peerACK、relative/traversal拒绝、legacy无source和directstrict。两日志字节哈希在36次读取前后全部保持,临时runtime仅清理自己的服务。既有150typed含125settlement项进一步覆盖exact instance、stale owner和borrowed admission。
对主干的风险
原评审的相对root早返回缺口已经独立复验修复;原review/inline仍作为历史公开证据,不继承旧批准。实际history/status模块在不可变base是2失败6通过(File/SQLite status均line1002坏账本),当前8通过,证据/限制窗口同时保持。150typed、types、advisory、native premerge3direct+16selected全部通过。
较宽三个Python模块为128通过4失败。四失败属于同一个composition scripted transport fixture,在相同不可变base同module也4失败19通过、相同四case/错误位置;其源与脚本actor字节未改,PR全diff只有上述三TS路径。transport是测试占位和本地脚本,不是外部模型调用。保留失败与归因,单独质量hold不算通过;改动不变量已由真实RPC/FileSQLite及原typed owner证明,不以挑绿重跑替代。首次独立directstrict夹具漏schema前缀及必需bool,未进入ledger,已保存为无资格诊断;只有更正后同18case基线/当前用于结论。
本修复默认作用在现有receipt-backed read路径,已在描述披露;legacy无settlement_source路径和strictdirectAPI实际配对保持。无capability配置、自动side-effect、措辞缩减或权限扩张;既有frontend/Lark消费status形状,当前源码CLI/RPC已测,整套packaged App/Lark/安装PG/多平台和长期成本未测。未获取、轮询或等待CI。
我的整体评价
交付方向 justified_increment,当前 APPROVE。long_horizon/user_experience的有界正向是:无关坏历史不再让状态失明,非法配置和真实结算仍严格;不能外推全局恢复完成或模型净收益。未来重构检查确认原snapshot/reducer/validator足够,当前共享facade与snapshot复用已完成相关窄改进,无需新框架/全局容错parser。保留四个基线质量失败和完整product/cost gap,合并readiness与maintainer操作另行判断,本轮不合并。
|
既有批准的 finding closeout,精确 head 同一隔离磁盘探针中,非法 Goal 路径仍拒绝;合法绝对根目录、无回执且有无关坏账本时,两版本均返回 trigger=null,账本字节未改变。当前 settlement 文件的 125 个 TS 用例通过,包括严格结算和该 RPC 反例。两个专用验证 runtime 均已停止。旧 finding 已解决,保留现有 APPROVED review 5454946086。本轮不合并、不查询 CI;完整 App/长期运行资格未在此复验。 English closeout: the relative-root RPC regression is reproduced at cad1983 and rejected at e818a69. Valid no-receipt skip and invalid-Goal rejection are preserved; 125 focused TS cases pass. The existing exact-head approval remains. |
Goal And Delivered Outcome
quota_should_runreceipt.060f02300159955932e3d2c3b4e4e60dc0539603,test_public_history_and_status_keep_artifacts_with_canonical_todosfailed for both File and SQLite providers withsettlement readback line 1002 is malformed, despite no matching should-run receipt. The projection now checks current-owner receipt identity first and skips the strict quota-ledger read when there is no settlement candidate; the history/status cases pass for both providers.CONTRIBUTING.md#find-workpermits a direct PR for this self-contained reproduced defect. Base:mainat060f02300159955932e3d2c3b4e4e60dc0539603.Author Declaration
Implemented against
tests/test_history_artifact_observation.pyat060f02300159955932e3d2c3b4e4e60dc0539603are the task basis.projectSettledReplanHistorytest_public_history_and_status_keep_artifacts_with_canonical_todosvalidateQuotaSettlementScopereplan history RPC rejects a relative runtime root before empty-receipt early returnprojectSettledReplanHistoryeffective cadence scopes settlement and ACKs to its admitted Goal instancereadQuotaSettlementSnapshotquota_settlement_readback.test.tsScope And Continuation
Validation
060f02300159955932e3d2c3b4e4e60dc0539603plus final heade818a6984af503b9bdaafa6877318cc5cc9f16c1.regression_paritysettlement readback line 1002 is malformed. Current main05af21ddreproduces the File CLI failure intest_public_history_and_status_keep_artifacts_with_canonical_todos[file]; final heade818a698passes the same test. The full history artifact module passes 8 tests on the final head.unittests/control_plane_ts/quota_settlement_readback.test.ts: 125 passed on final heade818a6984af503b9bdaafa6877318cc5cc9f16c1.integrationtests/test_history_artifact_observation.py: 8 passed, includinghistoryandstatusCLI entrypoints for File and SQLite providers.staticnpm run typecheck:control-planeandgit diff --checkpassed.integrationcad19838: 4,232 passed, 32 skipped, zero failures. The final review-fix head reran the affected test file and typecheck.Review follow-up
The no-candidate optimization initially bypassed the canonical settlement scope check, allowing the real
work_item.replan_history.projectRPC to accept a relativeruntime_root. The final head reuses the canonical validator before receipt reads and either candidate branch.060f0230: the RPC rejects the relative-root request withruntime_root must be absolute; prior PR headcad19838incorrectly returnedtrigger: null.e818a698: the same regression passes, and the existing valid-root no-receipt and exact-owner settlement cases remain green.npm run typecheck:control-planeandgit diff --checkpass. Fresh GitHub checks are running.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
none.Signed-off-bytrailer.