Repository navigation
fix(chat): continue a refused native monitor observation once - #7532
Conversation
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
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)
未发现阻塞精确头 ef598681fd440928d32f2ff1079037d77072661e 的缺陷。这是作者自审,不是独立审核或 GitHub formal approval。
动机 / Motivation
使用已启用原生监控的管家用户会遇到本问题。授权快照在读取期间变化时,本次观察被正确拒绝,但后续检查始终拿回旧失败,监控停在同一个到期窗口;修复后,原服务在安全证据齐全时自动做一次新观察。可验证结果是原窗口只提交一次监控结果,旧失败保持,随后新的独立周期仍可继续,且没有模型调用或业务重放。本次不放宽授权快照、真实撤权、暂停、用户任务优先和未知效果门禁,也不修改日报内容、会话同步或账号切换。实际安装后的原服务自然接续仍须独立验收;这次修复也不保证持续源变化下必能在一次有界续办中成功。“监控”在这里仅观察已授权状态,不应因一次可证明未提交的读取拒绝永久停住,也不能借恢复去重跑模型或业务。
改动思路 / Approach
恢复资格仍由既有TypeScript owner判定,Python只严格读原journal和原生poll回执;复用同一幂等身份及一次新载体,避免重复执行权威。当前PR交付已证明无提交的单次观察恢复;源快照如何保持稳定仍由既有collector负责,完整通用周期任务和原私聊业务结果仍在各自原任务中。普通用户已有启用意图与授权,恢复需要零次额外提问、复制、配置或确认;原暂停入口和用户任务优先保持。新建重试任务、消费者或绕过授权检查都比复用现有恢复边界更危险。
| 相同原窗口 | 精确旧版 | 当前头 |
|---|---|---|
| 授权快照变化且无提交 | 始终返回旧失败 | 严格证明后一次新观察 |
| 未知效果、暂停、撤权、排队用户任务 | 保留 | 继续保留 |
| 续办再次失败 | 无本次续办 | 保留新失败,不再循环 |
这是已运行对照的说明表,不是另画的执行证据。原始失败、当前新载体和原生提交分别保留;原生poll身份与deadline没有换名,后续新窗口仍由原Todo调度。
具体改动 / Changes
关键代码讲解
admitMonitorRestartRecovery(loopx/control_plane/collaboration/steward_managed_mode.ts:20)仍是共享资格owner。新增分支同时要求原错误精确匹配、原actor是bound steward,以及唯一 manager_turn_context_v1 明确为空、coverage未完成且只有 external_authorization_changed。没有scope id,不能把不完整读取当完整状态;后面原有的失败/无response/无upstream/无delta、事件白名单、poll缺席、旧worker排除、lease可用及用户队列检查全部保留。匹配错误字符串只用于兼容历史失败,单靠文字绝不能启动。
StewardTurnHost.monitor_restart_basis(loopx/capabilities/native_chat/steward_turn.py:121)沿现有旧worker锁严格读取完整journal、原生运行索引、各poll回执及租约,再附送原context。它只做IO,不把“没看到”自行解释成无效果。monitor_restart_request(:167)允许runtime_error候选进入该typed检查;候选不是许可,真正accept仍在当前 _admit 之后。submit 先保留既有准入拒绝的专用恢复,再考虑新的runtime_error观察候选;原 .restart-recovery 载体关联和相同native效果键不变,第二次失败不能递归创建第三次尝试。
规范为 docs/product/periodic-reports.md,spec_revision=a85a804aa93ec937cc5fdd715fd8e746ed8b4770。按修改前 Native status monitoring 条款映射:native-observation-identity 保留原身份、窗口和失败;native-no-effects-proof 保留完整journal/旧worker排除/无待定或已提交poll;native-current-authority 保留现权、lease代际、用户工作及暂停撤权。三项均沿原owner实现并用真实File/SQLite路径验收。文档新增四行明确披露本次资格扩展,不能倒用新文字作为独立预期。
对主干的风险 / Risks
最强反例是仅凭错误字符串或丢失事件就重放未知效果。这里必须有原collector完整的单一空拒绝记录,且现有无模型、无poll、worker锁和当前授权共同成立。缺失/重复/错误context、不同错误、模型已启动、pending receipt、破损history、忙旧worker、排队用户任务、暂停及撤权都被拒绝;一次新续办仍失败后保留,不无限重试。持久化原请求不迁移,新contexts只是由原事件派生的临时证据;读取成本存在,未声称性能或费用收益。
PASS:26项定向File/SQLite、299项相邻native monitor/host/managed/report、17项TS、完整control-plane typecheck/Ruff;standard premerge六项direct与十五项selected全过,无失败或manual hold。FAIL(预期回归证据):不可变旧base的两个后端恢复正例及两个“只尝试一次再失败”oracle,共4失败,22拒绝控制通过;准确头26全过。首次baseline命令从head cwd运行,模块来源不合格,明确不作旧版证据;随后从不可变base目录核模块来源并重跑同一最终fixture。早期头8a的完整相邻回归另暴露4项旧准入恢复被抢先分类,152项通过后中止定位;最终ef头显式保留旧路径优先级,完整四套重新验证,不能继承早期头通过或抹掉失败。旧失败与误路由运行记录保留,未放松断言。
当前 wait_for_ci=false,未查询或等待CI;源码测试不冒充安装、实际模型内容或持续变化环境保证。最近相关代码、原生caller及当前PR完整diff已核,没有另加恢复决策owner。
我的整体评价 / Verdict
long_horizon 为 improved:已拒绝且未提交的观察能形成真实结果,旧失败及后续独立周期可持续;user_experience 为 improved:现有授权下不增加人工恢复轮次。此diff没有渲染或布局变化,visual_review为not_applicable;现有设置/结果界面已检查,实际安装和原服务自然续办仍须单列,未宣称通过。恢复资格仍由既有TypeScript owner判定,Python只严格读原journal和原生poll回执;复用同一幂等身份及一次新载体,避免重复执行权威。当前PR交付已证明无提交的单次观察恢复;源快照如何保持稳定仍由既有collector负责,完整通用周期任务和原私聊业务结果仍在各自原任务中。本次保留真实持久关联字段,未引入新版本分支、调度器、模型worker或状态权威;后续collector稳定性是独立边界。合并还需当前精确头、授权及fresh readiness,安装后再核原服务自己接续,不能把合成测试当原消息业务全部完成。
English verdict: APPROVE — ef598681fd440928d32f2ff1079037d77072661e safely continues the precise pre-poll scope refusal once; real File/SQLite host, immutable-base counterfactual and negative checks qualify the bounded recovery change.
A native steward watch can be stranded at its original deadline after the portfolio collector refuses a changed authorization snapshot: the next pump sees the existing failed Chat request and cannot continue it. Extend the existing one-carrier monitor recovery to this precise pre-poll refusal, preserving the failed request, native observation identity and deadline.
The shared TypeScript owner requires the exact failure plus one empty typed
external_authorization_changedcontext. Python only transports strict original journal observations. Worker-lock exclusion, absent native poll receipts, current provider/actor authority, lease generation, idle user-work priority and the one-attempt limit remain enforced. No model, business replay, new scheduler, consumer or state authority is introduced; other runtime errors remain held.Validation at
ef598681fd440928d32f2ff1079037d77072661e: 26 focused File/SQLite cases pass, including automatic continuation through the existing host after reopening, one native poll, unchanged failure, zero model/execution spend and the next independent window. Negative cases cover missing/duplicate/wrong context, unknown errors/effects, pending receipts, corrupt history, a live worker, queued work, pause, revocation and a failed continuation. 299 adjacent native monitor/host/managed/report tests, 17 TypeScript owner tests, full control-plane typecheck and Ruff pass. Standard premerge passes 6 direct and 15 selected checks with no failures or manual holds. The same final 26-case fixture on immutable base has 4 expected recovery-oracle failures and 22 passing refusal controls; the exact head passes all 26. Existing admission-refusal recovery retains precedence over the new candidate path. Installation and natural production continuation are separate acceptance.Scope-fit: reuse the existing typed recovery owner and persisted correlation field; the added context observation avoids inferring safety from an error string alone. The larger collector snapshot policy is unchanged. Existing App/Lark monitoring settings and results are reused without a new interaction or UI. This repairs a bounded recovery gap; it does not establish complete periodic-task, report-content or conversation-sync acceptance.