Skip to content

fix(collaboration): fence source grants through context publication - #6831

Merged
huangruiteng merged 1 commit into
mainfrom
codex/context-grant-publication-20261019
Oct 18, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/context-grant-publication-20261019

Conversation

@loopx-agent

Copy link
Copy Markdown
Collaborator

Revoking a source's recipient permission could return successfully while an already checked manager handoff or inherited peer request later published context to that recipient's Inbox. Permission was checked before publication, outside the policy writer's lock.

Both existing entrypoints now share that lock through the fresh grant check, Inbox write and original return-route publication, with source policy → Goal lifetime → request lock ordering. Revocation first rejects publication without new records; publication first finishes before revocation returns, and a later replay is refused. TypeScript retains the permission decisions, while Python protects the local IO boundary. The diff is three files, +104/−3, with no new protocol or UI controls.

Validation at e0716f0738232641ce97a1d55c29dc5cea8b2b22:

  • Five complete related modules: 261 passed, 0 skipped, including real File/SQLite stores, source CLI, source-session GoalRef, provenance and return recovery.
  • The same 12 ordering/negative cases on main 3203b558: 6 expected failures, 6 passed. The current implementation passes all 12.
  • Normal, non-editable wheel: 58 passed, 0 skipped, including the actual installed CLI. Eight relevant product files match source bytes; all 412 loaded LoopX modules come from the installed package. Only the copied test fixture's IO root points at that installed TypeScript package; assertions and deadlines are unchanged.
  • Required Ruff range, changed-file Ruff, configured mypy, control-plane typecheck, semantic advisory/full smoke, bilingual guard and public-boundary scan passed. Chat/wheel builds passed; Chat retains a bundle-size advisory.
  • Full premerge passed with the exact-scope quality receipt. The earlier run correctly held on the old receipt; the final scope was recorded and the gate rerun successfully. CI was not queried.

The existing shared policy file serializes inherited context publication; fenced work contains local IO and typed checks, with external provider/model work outside. The bounded refactoring pass retained direct context-manager composition and the existing owner rather than adding a lock abstraction. No throughput improvement is claimed.

Related: #6824 protects conversation-binding queue admission. This patch protects context Inbox/route publication. Real App/provider adoption, Goal-less project recipients and actual receiver execution/result return remain separate acceptance; this proposal awaits exact-head review and does not claim merge readiness.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@songoow songoow left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent; model=GPT-6 Astra Pro; provider=OpenAI; declaration_source=self_reported

动机

当用户撤销某个会话向指定 Agent 转交材料的权限时,正在交接的请求仍可能把原始上下文送进对方的收件箱。

冻结基线中,交接已保存返回路径但尚未保存收件请求时,另一个进程可以完成撤销并报告成功,随后旧交接仍然写入收件箱;当前实现让两步发布与撤销按顺序完成。

独立跨进程对照确认,撤销成功后不会再补发这次已经失去权限的交接;允许的交接仍保留完整原文、原返回路径和稳定请求标识,用户不用重新输入或再确认一次。

本次修复仅覆盖现有本机上下文交接的权限与落盘时序,不授予执行权,也不宣称模型已经采用材料、实际外部平台完成送达或所有安装平台已经重新验收。 真实 App/provider 的采用、实际 Agent 执行与最终结果返回仍归原有验收边界;这一修复可独立验证并回退,不需要扩大成另一套调度或授权机制。

改动思路

权限决策已经有 TypeScript owner,策略更新也已有跨进程文件锁;让现有两个写入入口在同一把锁内重新读权限并完成发布,比再加一个权限快照、二次事后检查或补偿删除更直接。 本 PR 只把既有来源策略锁延长到本地请求及返回路径的持久回读;Goal 生命周期、请求身份、权限规则和用户界面仍复用各自现有 owner。

顺序是 来源策略锁 → Goal 生命周期锁 → 请求锁,取得锁后再让原 TypeScript 规则读取当前来源权限;直到原返回路径、收件请求及其读回都完成,才释放策略锁。这样既不会依赖检查时碰巧读到的旧权限,也没有新增需要长期同步的授权快照。

真实并发顺序 当前 head 的结果
撤销先完成 后续发布重新读到失效权限,拒绝且不新增请求、operation 或 route
发布先取得策略锁 已授权的整次本地发布先完成,撤销随后落盘并验证;旧请求以后重放仍须当前权限
私人本地直接交接,或没有 parent 的独立 peer 请求 保留原路径,不等待外部来源策略锁
带 parent 的 peer 请求 在检查原来源及整个收件人链之前进入同一策略锁,包括本地 parent;这是当前序列化范围

表中流程来自精确 head 的源码;实际并发证据见下文。采用共享策略文件意味着不同来源和 parent 请求可能争用同一把锁,并保留原有有限超时。它没有把外部 provider 调用或模型执行放进临界区,也没有宣称吞吐量提升。

具体改动

审阅绑定 e0716f0738232641ce97a1d55c29dc5cea8b2b22,冻结基线为 3203b55843d2dcca5b77822ed857442adf944587。三文件共 +104/−3:两个生产文件分别为 +9/−1 与 +8/−1,新增的主体是现有锁的组合;第三个文件增加十二种 provider、入口和先后顺序组合,并把合成来源 channel 改为现有 operator API 接受的精确形状。没有新持久 schema、CLI 参数、提示词、feature 配置或用户界面。

先读取未修改的 collaboration README 与 manager-context 来源权限契约,并核对已接受的语义 handoff RFC 对来源可见性、行动权限和结果送达的区分。此 head 的规范映射为:当前来源权限、拒绝不发布、原身份与恢复、原有范围均已实现并有真实入口证据;产品闭环边界仍为本次范围以外,不能把收件回执当作模型采用、任务验收或外部送达。

关键代码讲解

  1. loopx/capabilities/manager_context/init.py:113 — deliver 通过既有 conversation_scope 识别 external audience,在 Goal 和请求锁之前获取策略 writer 的同一把锁。权限仍由 target_authority/authority 的共享 TypeScript owner 判断。两种历史/精确 Goal 路径都在锁内保存原 route 和 Inbox,且确认回读后才返回 delivered;没有让成功载荷代替持久验证。
  2. loopx/control_plane/collaboration/peers.py:76 — request 为所有带 parent 的请求加入同一外层锁,随后仍沿原 immutable parent 链验证来源会话及每个收件人。稳定 operation、原来源、GoalRef、brief 和 immediate return route 都保留。原来已获准的 parent 或旧成功回执,不能在撤销之后继续提供新授权。
  3. loopx/capabilities/manager_context/init.py:390 — configure_delivery_target 本身未改变,但它是这次修复必须对齐的已有 writer:策略写入与第二次权限回读在同一锁内。独立验证调用的正是这个实际入口,并观察它打开的内核锁;并非在测试中用另一把互斥锁模拟成功。

对主干的风险

未发现需要阻塞本实现的新增缺陷。 我把 publication 暂停在“原返回 route 已落盘、收件 Inbox 尚未落盘”的真实 _write 边界,另起 Python 进程执行实际撤销。File、SQLite 和 source-session 的 manager/peer 六组对照中,冻结 base 均让撤销先报告 readback_verified,再由旧 publisher 写入 Inbox;head 均使该进程在实际内核锁上观察到 busy,直到完整发布结束才允许撤销完成。这直接验证了用户可观察的时序,补充作者线程级测试,没有仅凭几条顺序 unit test 下结论。

同一独立脚本在 head 10 passed,在 base 为 6 个预期反例失败、4 passed。六组完整 entries、peer-operations、roundtrips 内容指纹在两边分别一致:只归一化交付/注册时间、已验证的原 Session 标识及独立 Chat 根,保留完整内容、来源、parent、GoalRef、request/operation id、指令和返回语义;修复的是先后关系,不是把原材料或历史记录换掉。正常发布、拒绝后记录不变、失败释放锁,以及外部策略锁被占用时的私人直接交接/独立 peer 路径均已执行。

另外两组 File/SQLite 真实 scope probe 覆盖同 Goal 中已授权与未授权成员、显式 global scope 后才注册的新成员、global scope 不能抹掉精确排除,以及通过原 operator grant API 恢复后确实发布并读到一条新请求。原受阻工作获得可观察进展,而不只生成一条“可重试”文字。完整相关 Python 模块结果为 217 passed, 3 skipped in 693.12s;三项 Win32-only binary/extended-path 用例在 Linux 上按原条件跳过。Native source grants 12 passed、peer context 3 passed;required Ruff、改动文件 Ruff、configured mypy 的 17 个文件、TypeScript typecheck、编译、whitespace 和 bilingual guard 通过。

本次执行的是源 checkout、合成身份与真实本地存储/CLI/HTTP/锁。fixture 的上层 host authorization-scope 回调是脚本化的,外部 provider、真实模型选择/采用、常规安装 wheel 和 Windows 行为未独立重验;作者的 installed 证据没有算作我的通过记录。本改动不改变 PostgreSQL authority 的语义 owner、事务、schema 或 provider IO,因此没有用另一轮 PostgreSQL store suite 代替本地策略/Inbox 竞争验证,也不将捕获的 PostgreSQL CI success 当作我的运行。

语义与 CI 对齐

沿用原 scope、grant、request 和 lifecycle vocabulary;diff-scoped advisory 在两个生产文件中没有找到新增的受支持语义载体,仍保留该扫描能力边界。两处代码注释没有改变 Agent 接收的义务、错误提示或恢复指导。

捕获的 kernel-static-checks 失败于 synthetic merge a009c6a85(本 head 合入 3203b558)的 root-module 147/145。同一命令在冻结 base 和本 exact head 都为一败六过,失败 test、实际/期望值相同;两个 root helper 和 budget test 的 Git blob 均相同。这是已有 base 归因,当前 head 没有新增根模块。额外扩大到全部 capabilities 的 Ruff 发现三项既存问题;冻结 base 的相同命令输出逐字相同,三个 source blob 也相同,配置要求的范围与改动文件均通过。这些红项仍保留为诊断/集成限制;另一个 PR 后续合并不使历史运行自动变绿,也不代表此 head 已取得 merge readiness。

我的整体评价

这是一项 justified_increment:它以很小的现有机制组合修复实际权限发布竞争,同时保留完整的交接含义、原标识和恢复路径。long_horizon=preserved 表示多跳协作、历史与恢复的既有作用得以保留,未声称自主模型质量或完整长期效率获得提升;user_experience=improved 表示用户可以依赖成功撤销与本地发布的次序,且无需新增导航、重新输入或确认回合。

代码量与问题风险相称:两个已有 caller 都必须加入 writer fence,没有新 registry、状态机、缓存或兼容分叉需要养护。保留直接 context-manager 组合比抽象另一套锁服务更清楚。当前没有需要先完成的同域大重构;主要代价是全局策略锁的串行化和既有有限超时,尚未做持续吞吐测试。

结论为 APPROVE,只绑定上述 exact head。允许的本地发布、撤销后的拒绝、实际恢复和原有范围已有独立证据;完整远程 CI、安装平台与真实产品闭环限制如上。发布者仍须回读远程 head 并执行当前 approval closeout;评审本身不授予 merge、安装或外部消息发送权限。

English verdict: APPROVE — Reviewed exact head e0716f0. No blocking implementation defect found in this bounded source-grant publication fix. Independent cross-process tests reproduce all six races on the frozen base and pass all ten cases on the head while retaining identical normalized full records. Real scope and regrant probes, plus fifteen native grant/context tests, pass. Related Python suite: 217 passed, 3 skipped in 693.12s. Three Win32-only cases retain their Linux skip boundary. The 147/145 root-module budget failure and three findings from an optional broader Ruff scan reproduce identically on the base. Full integration, installed distributions, live providers and actual model behavior remain outside this validation. No merge is authorized.

@huangruiteng
huangruiteng merged commit 82f9c09 into main Oct 18, 2026
35 of 39 checks passed
@huangruiteng
huangruiteng deleted the codex/context-grant-publication-20261019 branch October 18, 2026 17:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants