Repository navigation
fix(quota): fence primary Monitor writes with scoped gates - #6803
Conversation
Signed-off-by: Lihua <1017343802@qq.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
Exact head: 8e36f0f7be8496115f27bcc9052e8b8e4eb170ce
动机
需要自动观察外部状态的 Agent,会遇到“当前用户待办明确阻塞了这个 Monitor,但观察写入仍成功”的不一致。
例如先允许一次观察,再把用户 gate 关联到该 Monitor:旧代码的 guard 已拒绝,monitor-poll 却仍增加观察记录;本修改让新的写入也拒绝,同时允许无依赖的独立观察继续。
同一合成输入在源码和普通安装包中均表现为:被关联、全局或无法判定独立性的 gate 阻塞时不写入观察;无 gate、其他 Agent 的 gate 和明确独立的 Monitor 正常观察,已提交结果可幂等重放。
范围是 quota Monitor 的准入与提交一致性,不关闭用户 gate、不把诊断注释当授权、不授予执行或合并权限,也不声称完整长期运行、所有外部 provider 或当前用户安装已验收。
改动思路
把已有 auxiliary gate 规则提升为共用的类型化判断,并让新 primary 和历史未提交 dispatch 复用现有 provider 完整快照校验,能堵住两个阶段的同一漏洞;新增另一套持久 gate 状态或 Python 决策源都没有必要。
当前 PR 只交付 primary/auxiliary Monitor 的依赖范围、提交前复核和既有回执恢复,不扩展 gate 生命周期或 Monitor 业务范围。
既有 guard 只读准入,provider 提交前仍需读完整当前状态。共享判断处理 primary 和 auxiliary;已提交回执先进入恢复路径,新 dispatch 统一走现有 gate_scope_guard。禁止写入和允许独立工作两侧都要验证,不能用更严格就更安全替代范围判断。
具体改动
完整 a54c030ee79ea9270fed4ca94f9592f32a19232a → 8e36f0f7be8496115f27bcc9052e8b8e4eb170ce 差异:1 typed runtime file; bilingual protocol; repair-pattern row; focused existing tests and provider expectation; five paths total,+194/-23。
- monitorGateAllowsObservation:Auxiliary-only rule becomes common;输入 typed MonitorDecision gate facts,关键条件 no gate OR explicitly independent AND not globally blocked。结果由 primary and auxiliary admission 消费,失败仍由 existing rejection owner 处理。
- admission:Primary now receives same scope test;输入 due Monitor plus current decision,关键条件 historical committed replay is earlier; new work cannot inherit it。结果由 quota monitor-poll 消费,失败仍由 existing no-write rejection 处理。
- providerPlanFor:gateGuard defaults true for primary and auxiliary;输入 admitted uncommitted observation,关键条件 full provider head checked before mutation。结果由 File/SQLite/PostgreSQL authority 消费,失败仍由 transaction recovery/CAS rejection 处理。
- providerDispatchPlan:adds guard to dispatched copy without rewriting identity;输入 persisted provider plan,关键条件 retain intended event, WAL and settlement identity。结果由 recovery path 消费,失败仍由 committed-business replay is unchanged 处理。
规范来源 https://github.com/loopx-project/loopx/blob/a54c030ee79ea9270fed4ca94f9592f32a19232a/docs/reference/protocols/quota-monitor-observation-receipt-v0.md,spec_revision=a54c030ee79ea9270fed4ca94f9592f32a19232a。Eligibility:观察必须来自当前准入的 Monitor,独立性由已有 typed gate facts 决定。(implemented,monitorGateAllowsObservation / admission;source paired CLI + monitor scope counterfactuals);Canonical recovery:新 canonical provider 写入必须复核提交快照;历史已提交结果可恢复但不产生新授权。(implemented,providerPlanFor / providerDispatchPlan;transaction-recovery tests + installed-wheel replay)。基线规范在完整 diff 前读取;本 PR 对文档的修改也作为被审内容,并未当作独立授权。
5 个路径还包括英文/中文协议说明、repair-pattern 说明行以及原有 provider 请求断言更新;这些文档不生成机器授权。新写入复用既有 provider request v3,已提交业务/settlement replay 保留原身份,旧的未提交 plan 只在 dispatch 副本补 guard。新未晋升 legacy 写入按当前规则拒绝,没有承诺这类写入兼容。
对主干的风险
Same common baseline fixture: four source/global × File/SQLite linked-gate baseline counterexamples; exact head passes 20 real CLI cases. Ordinary noneditable wheel passes 8 real CLI cases; File/SQLite scope-recovery counterfactuals also pass.
86 Python tests passed (273.68s); 21 TypeScript tests passed; TypeScript typecheck passed. 5 direct + 19 selected checks passed; zero failing commands/manual holds. Managed qualification is held only by quality_receipt_missing.
隔离真实 PostgreSQL 16.2 上 365 store+2 service integration 全通过、零 skip,服务器已停止。File/SQLite 的关联/未知/全局 gate 负例、独立/无 gate/peer 正例、过期缓存、提交竞态、历史 pending/business/settled replay 均按各自边界验证;拒绝时检查 canonical revision、Todo/Markdown 和业务 index,无 quota spend。新独立 subject 在 gate 激活后创建,先合法结清旧 Turn 再观察,避免把绕过旧 Turn 恢复误当成功。
正常 dashboard Chat build 与普通非 editable wheel 构建通过,改变的生产文件与 wheel 逐字节一致,隔离安装后重跑实际入口。初次从仓库根误调用不存在的 npm build:chat 脚本,改到真实 dashboard 目录后才完成构建;没有把该调用错误归因于产品。补充探针中的回执路径/旧 Turn 前置条件也按真实契约修正,原失败保留,未移除独立 oracle。
No remote CI consulted. Exact-scope managed quality receipt is missing; no merge authority, full fleet, real external poll adoption or long soak is qualified. Legacy unpromoted new writes are deliberately rejected, not certified compatible. New primary writes intentionally use the existing guarded provider request v3, so no wire-byte parity claim.
本轮没有查询、轮询、等待或触发 CI。最新 main 与相关工作核对后,没有发现生产 owner 已完成的同义修复;共享文档的其他行或无关 successor passthrough 不构成本 PR 的重复。
我的整体评价
把已有 auxiliary gate 规则提升为共用的类型化判断,并让新 primary 和历史未提交 dispatch 复用现有 provider 完整快照校验,能堵住两个阶段的同一漏洞;新增另一套持久 gate 状态或 Python 决策源都没有必要。
当前 PR 只交付 primary/auxiliary Monitor 的依赖范围、提交前复核和既有回执恢复,不扩展 gate 生命周期或 Monitor 业务范围。
有界目标判定 goal_achieved:交付了可读回的拒绝和继续路径,不以文件数、测试数或回执存在代替结果。long_horizon=improved,重放/恢复/独立新 subject 的实际验证支持后续继续;user_experience=improved,沿既有 CLI 读回真实状态和恢复建议,无新增配置、复制信息或确认步骤。
有界未来重构检查:本次已合并 primary/auxiliary 的同一 gate 规则;继续复用 provider 完整快照,不需要另起框架。代码层面 APPROVE 仅对本 exact head;托管质量凭据、原生 merge readiness 与维护者显式合并授权仍是独立条件。
English verdict: APPROVE at 8e36f0f7be8496115f27bcc9052e8b8e4eb170ce. Same common baseline fixture: four source/global × File/SQLite linked-gate baseline counterexamples; exact head passes 20 real CLI cases. Ordinary noneditable wheel passes 8 real CLI cases; File/SQLite scope-recovery counterfactuals also pass. 86 Python tests passed (273.68s); 21 TypeScript tests passed; TypeScript typecheck passed. 5 direct + 19 selected checks passed; zero failing commands/manual holds. Managed qualification is held only by quality_receipt_missing. No remote CI consulted. Exact-scope managed quality receipt is missing; no merge authority, full fleet, real external poll adoption or long soak is qualified. Legacy unpromoted new writes are deliberately rejected, not certified compatible. New primary writes intentionally use the existing guarded provider request v3, so no wire-byte parity claim.
Goal And Delivered Outcome
A due Monitor can be denied by
quota should-rununder a dependent User gate while a directquota monitor-poll --executestill writes its result and cadence. This proposal applies the existing typed dependency rule to primary as well as auxiliary admission, and checks every new quota Monitor provider dispatch against its commit snapshot. Independent observations and exact committed replay remain available.a54c030ee; this head rejects linked, unknown and global gate cases without a business or settlement write. A gate committed after preflight also prevents the observation.main. The later860e42d4baccount-surface integration has no touched-owner overlap and merges cleanly with this head.Author Declaration
docs/reference/protocols/quota-monitor-observation-receipt-v0.mdata54c030ee, Contract and Canonical leased observations/recovery; the demonstrated primary-Monitor inconsistency is this PR's repair basis.gate_scope_guard; File/SQLite preflight and CAS interleavingsSelf-check: reviewed the changed admission, provider-plan recovery, bilingual protocol and semantic regressions. Reused the existing guard, dependency vocabulary and v3 provider request. The small refactor shares the primary/auxiliary predicate; Python remains a transport adapter.
Scope And Continuation
Maintainer review approved exact head
8e36f0f7be8496115f27bcc9052e8b8e4eb170ce, and this PR merged asd6343dbfbeaad07c56d9347edd64401bd5740d61on 2026-10-18 at 12:38 UTC. The verified later main55d633748contains that merge. Shared installed-runtime adoption and complete hosted regression remain separate and unqualified. No migration, provider promotion, new capability, setting or frontend journey is introduced.Validation
8e36f0f7be8496115f27bcc9052e8b8e4eb170ce; local runs finished, synthetic inputs only.Retained initial failures: four baseline product counterexamples; six new fixture setup errors corrected by supplying required status-reader arguments; one native expected-plan assertion updated for the intentional guard extension. Deliberate semantic-mutation failure is retained as negative evidence. Broader CI is not claimed green.
Frontend / Visual Evidence
UI impact: none. Before/after, viewport, preview and craft review: N/A; the diff changes CLI/effect admission, tests and protocol guidance. Source data: synthetic.
Type Of Change / LoopX Area
Technical Direction / Shared-authority RFC fixture impact
S2 typed-kernel correctness. No migration, runtime routing, compatibility projection or production-scale qualification is claimed; shared-authority RFC fixture promotion/rehearsal fields are N/A. File/SQLite and exact-head real PostgreSQL results are listed above.
Boundary Checklist
Post-Merge CI Attribution / 合并后的 CI 归因
The original exact-head CI remains red: six failed checks, 23 successful and eight skipped. The Chat browser shard 2, Dashboard browser shard 2 and release build all stop at the same existing
private-steward-scopescenario: after switching to a 390px viewport and reloading, its settings helper cannot find the Settings button. Thechecksaggregate rejects the skipped Dashboard acceptance, and thepytestaggregate sees failed prerequisites; the actual Python shards were skipped. This is not evidence of Python test failures. Python workflow, release workflow.The unchanged stock scenario reproduces the identical locator timeout on both immutable base
a54c030ee79ea9270fed4ca94f9592f32a19232aand head8e36f0f7be8496115f27bcc9052e8b8e4eb170ce, using the same Node/browser/dependencies and synthetic fixture in separate temporary processes. Browser sources, helpers and dependency locks are unchanged across this PR. This bounded comparison is one isolated development scenario with coverage off; it does not qualify the full shard, a paired packaged workload, full regression or installed-runtime adoption. No unrelated browser repair is included here, and the failed CI history is retained.当前提交已评审并合入主干。三条根因作业均在同一移动端设置场景失败,基线与本 PR 提交也复现相同超时;Python 分片因前置验收失败而未执行。这里只完成有界归因,完整 CI、混合旅程和已安装运行时验收仍未通过。