feat(collaboration): bind inbox continuity to GoalRef - #5106
Conversation
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
Exact-head self-review for
Validation at this head: 122 focused Python tests passed; 3104 TypeScript control-plane tests passed with 30 environment-dependent skips; TypeScript typecheck, Ruff, premerge, and maintainability checks passed. |
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
CI follow-up at The Python 3.11 adapter-contract failure came from The fix keeps eager GoalRef capture when the registry exists. If the registry does not exist yet, the service captures and caches the GoalRef under a lock on the first real collaboration operation. Invalid worker arguments still fail before file or process I/O. Local validation:
|
…3-collaboration Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
Synced |
…3-collaboration Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
Synced |
huangruiteng
left a comment
There was a problem hiding this comment.
动机
本次评审 exact head:d3363009a7bee30ac37b8acde3ac93fb04009260,不可变 base:96892b71cbf2a46328653fbc0c425969f2ab4865。覆盖完整 14 文件(+2822/-241)。依据是 Goal instance identity and orphan recovery RFC:alias 不是 lifetime identity;A 删除/重建成 B 后,B 不应收取或修改 A 的 request/result,但 A 的合法迟到结果仍可返回原来保存的对话。这不是通过 GoalRef 给 peer 更多权限,既有 receiver/grant/Todo ownership 校验必须继续存在。
本 PR 是 source_session_v1 的 collaboration adoption 切片,不是默认启用、完整 activation/migration/outbox 交付。切片有明确使用价值和可逆边界;然而 feature-off continuity 和慢发送下的重复 effect 都未满足其当前承诺。
改动思路
TS lifecycle decision 统一判断 current、historical、missing instance 的操作资格;Python scope adapter 持 source lifetime fence,I/O 层给 request、read/ack/link/report/consume/history 带 exact GoalRef。manager initial delivery 与 peer request 使用 instance-scoped identity;MCP 注册/Delegations 捕获 caller lifetime,避免旧 worker 重新按 alias 绑定 B。
返回链路拆成短 admission、provider I/O、短 settlement,以免远端 I/O 一直占 Goal lifetime lock。这个方向合理,但 request effect 本身不能因为 admission 时间到期就被另一个 drainer再次发送。
关键代码讲解
goal_instance_lifecycle.ts::decideCollaborationLifecycle:操作枚举与 GoalRef 对照决定 new work、historical inspection、original-route return 是否允许;typed owner 没有给 alias-only caller 隐式权限。goal_instance_scope.py::collaboration_goal_scope:读取 source codec、登记/active 状态,在 exact mode 捕获或使用 caller GoalRef;把资格判断交给 TS,并由 lifetime fence 保护文件操作。inbox.py::pending与peers.py::read_inbox:实例目录和 request receipt隔离是正确边界,但 cursor 的共享构造同时改了 legacy 模式,见下面 P2。roundtrip.py::_exact_return_context/_write_exact_return_state/_drain_exact:读取保存的 conversation/initial delivery evidence,短锁下发 admission token,释放锁再调用 transport,回写时检查 token;token 检查发生在 external effect 之后,见下面 P1。collaboration_mcp.py::register_collaboration_tools/Delegations与 manager-inbox CLI:把捕获的 caller identity 贯穿实际入口;没有另造前端配置项。现有 UI/Lark 使用这些共用 backend,identity adoption 本身不需要新开关,但 Lark transport 的 effect/retry 顺序仍是验收边界。
具体改动
全部生产变化包括 manager authority/deliver/hook、roundtrip return、tracking/link/query、inbox/peer request/read/ack/return/consume、CLI strict registry load、MCP/delegation caller binding、TS handler 注册,以及 TS/Python 生命周期与 delegation 测试。既有 brief normalizer、项目 registry codec、chat store、delivery-attempt/verification contract被复用。无需强制完整 TS 重构才能评审,但 effect admission 的存活与恢复必须有一个明确 owner,而非只靠过期时间和事后 token 检查。
[P1] admission 到期不能证明首个 external send 已结束。 位置:_exact_return_context,L450–L495,provider call,L755–L760。
独立 real-filesystem/ChatSessionStore 探针创建已验证 initial manager delivery、adopt 与 conclusion,首次 drain(now=t) 进入 sender 后保持未完成;第二次 drain(now=t+61s) 在释放首次 sender 前完成。实际观测是 sender 调用两次,两个 drain 各 processed=1,最终 state=delivered。第一次 settlement 的 token 检查失败,也不能撤回已经发生的调用。时间通过 drain 的公开 now 参数注入,不靠睡眠制造竞态。
现有“释放 lifetime lock”用例只检查 admission 尚未到期的第二次 drain,因而全套绿色仍会漏这个情况。实际 Lark send/attempt recorder 也是先调用发送再持久化 attempt;provider I/O、preflight/readback 可以跨过该时窗。探针证明的是两个 sender invocation,不冒充 live Lark 双消息证据。
最小修复:释放 Goal lifetime lock 的同时保持同一 request effect 的互斥或可证幂等性;过期 takeover 必须先处理 active writer/uncertain external write,不能把 TTL 等同“没发送”。可在不持 Goal lock 的情况下保留 per-request effect fence,或用真实 provider idempotency 与不确定发送的 reconciliation。补“首个仍在飞行且跨 TTL、竞争 drainer、restart/reconcile 不盲目重发”的负例,保留 Goal recreate 不受慢 I/O 阻塞的正例。
[P2] feature-off 的 legacy v1 cursor 被升级拒绝。 位置:pending cursor scope,L127–L142。
base scope 是 ["pending_requests_v1", runtime, goal_id, agent_id];head 无条件变成 ["pending_requests_v1", runtime, _target(...)],连 scope=None/legacy 也改 hash。独立探针在 base 实际创建 21 个 peer requests,从第一页保存 v1 cursor,再把同一份未改的 registry/runtime/entries/cursor交给 head:
- base resume:accepted=true、second_count=1、duplicate=false。
- head resume:
pending request cursor scope mismatch。
这是未激活 source_session_v1 时的真实 continuation regression,不是新 profile 的有意隔离。保留 legacy/None 的原 v1 scope;exact profile 才用实例维度。增加“旧 revision 发出的 cursor → 新 revision 续页”测试,并保留跨 GoalRef cursor 拒绝,不能通过放宽 scope 校验修复。
对主干的风险
正向链路:A request → A adopt/report → A return;recreate B 后默认 inbox 不见 A,明确 A 的历史结果只返回已保存、已证明的旧 conversation。负向链路:B 不能 ack/link/report A、同 operation_id 在 A/B 生成不同 request、缺 route/initial-delivery evidence 拒绝旧返回。新增资格检查可阻止 ABA,但必须同时保证不让既有 legacy 工作丢 continuation、不让原对话承担重复 effect。
语义与 CI 对齐
- exact-head focused Python:45 passed;相同 legacy 四个 suite在不可变 base:36 passed。
- 新 TS lifecycle tests:8 passed;control-plane typecheck 通过。
- 两项独立 oracle 都反驳了共享当前承诺:旧 cursor 在 base 通过而 head 失败;head 的 slow-send at-most-one oracle 失败。
- 原生外部 Lark API 没有执行,使用真实文件/Chat store加受控 provider callback;因此报告边界是 sender invocation 与 durable state,不声称已覆盖 live provider 幂等/reconciliation。
- 当前 capability 为
wait_for_ci=false,没有查询/轮询远端 CI;REQUEST_CHANGES 只依据本 PR 改动直接引起的反例,不因无关红 CI。 - 未来维护性检查:围绕本次修复将 exact-return effect admission/reconciliation 收敛到最近的 collaboration/return-delivery owner,保持 typed lifetime decision 与文件 effect adapter 的职责分离。不能用单纯提取 helper 掩盖 TTL 规则错误;更大的 roundtrip 模块拆分可非阻塞后续处理。
我的整体评价
instance-aware identity 和原对话迟到结果回传是合理、可独立验证的 adoption 切片;它不授权更广的 actor lifecycle,也不要求把尚未启用的 parent RFC 一次全部实现。但 legacy 默认路径已经漂移,external-return effect 的 lease expiry 有实质重复窗口。请修复这两个边界,再重跑整个切片的正向/负向与 base-issued cursor 对照。未执行合并。
English verdict: REQUEST_CHANGES - exact head d336300. A slow in-flight return can invoke the sender twice after admission expiry, and feature-off upgrades reject existing legacy cursors. Focused tests/typecheck pass; both defects were independently reproduced.
…3-collaboration Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com> # Conflicts: # loopx/capabilities/manager_context/__init__.py # loopx/capabilities/manager_context/roundtrip.py # loopx/collaboration_mcp.py # loopx/control_plane/collaboration/peers.py
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
Updated exact head P1: exact return delivery now holds a separate per-request effect lock across provider send or verification without holding the Goal lifetime lock. A competing drain at P2: legacy mode again hashes the original v1 cursor scope as Exact-head validation:
No live external-provider write was performed. The provider assertions use the real file and Chat stores with a controlled transport callback, so the evidence covers sender invocation count and durable recovery state. |
Signed-off-by: duanjialing.777 <duanjialing.777@bytedance.com>
|
Exact-head CI follow-up at The prior Local validation on this exact head:
The new GitHub CI run is in progress. Maintainer review remains requested; no self-merge will be performed. |
huangruiteng
left a comment
There was a problem hiding this comment.
APPROVE:当前 head 未发现阻断回归。慢发送 single-flight、崩溃后的不重发恢复和 legacy cursor 兼容性有独立真实入口证据;中途发现的 registry census 缺口已在新 head 修正并重新验证。
精确 head:8b7af90a1381408da516fc164fbe898cd5f18c1c;不可变比较基线:6643f367064b9921c864db75a042979fddc4b8c3。本轮完整审视 base→head,另读前次 review→head 修复和 4e962db→当前 head;不继承作者声明,不查询 GitHub CI。
动机
按 Goal-instance RFC 的 M3 同源协作边界、前次两项阻断 与 作者修复说明,本次解决同一个 Goal 别名重建后 inbox/request/return 串入新实例,以及旧慢发送和 cursor 恢复问题。它是 peer/inbox continuity 的可用增量,不关闭整个 M3;outbox/host binding 和 global activation 仍归既有资格计划。
改动思路
复用 ExactGoalRef、现有 peer authorization/registration、manager-context entry/route/receipt 和 source lifetime lock;TypeScript 决定 current/historical eligibility,Python 适配本地 File-v0 和 provider effect。request 身份、route、reply 与 admission 固定在原 GoalRef,不从当前别名反推历史意图。短 Goal guard 内先准入和保存 token,网络外层用 request/phase 的 effect single-flight 锁;这样重建不会被长网络 I/O 阻塞,另一进程也不能把仍发送中的 admission 当作可恢复崩溃记录。
具体改动
关键代码讲解
goal_instance_lifecycle.ts:234 / decideCollaborationLifecycle以 exact tuple、typed operation 和 record/route facts 区分当前新工作与历史 return,拒绝 stale、unstamped 和 route mismatch;既有 registered-peer 权限仍是独立前置条件。goal_instance_scope.py:93 / collaboration_goal_scope在已有跨 runtime lifetime guard 内重新加载 source,生成 current/caller scope。新请求必须匹配当前实例;历史返回必须匹配保存的 request 与 route,不修改新实例。roundtrip.py:602 / _drain_exact在网络发送/核验/settlement 全程持有 request+phase 的 SINGLE_FLIGHT 锁,同时释放 Goal guard。独立竞争进程在逻辑时间加 61 秒也不能发送或改写在途 admission。进程真正退出后,有 locator 只 verify;没有 locator 明确 explicit_unverified,不猜成功也不重发。peers.py:554 / read_inbox按捕获的 GoalRef 筛选同源记录;仅 exact 模式加 v2 身份,legacy 的 request id、entry/route 字节和既有 cursor hash 保留。长驻 stdio MCP 在 A→B 后读不到 B、不能新建 B,但仍能保存 A 的历史结果。
其余改动包括 manager delivery/tracking、CLI 的 manager-inbox、delegation/MCP capture 和 typed Effect dispatch;没有另建 peer actor、自动授予跨 Agent 权限或修改 quota/scheduler。最新提交同步了 8 个新增/替换的 registry I/O site 与 6 个 direct-loader owner;该同步与当前 production caller 一起审视,不以加 allowlist 代替行为验证。
对主干的风险
当前 head 的 typecheck、mypy、906 项 focused collaboration/manager/peer/MCP 与全量 architecture 检查通过;17 个 changed paths 的原生 public-boundary/13 个 Python 文件编译通过。独立验证真实 File-v0、typed Effect、真实子进程与 stdio MCP:在慢 provider 回调期间 canonical M2 重建完成,第二个进程零发送且 admission 字节不变,原调用只发送一次;分别用 os._exit 终止有/无 locator 的进程,恢复后零重发,并准确区分核验成功与 explicit_unverified。新 B peer request 被处理并 consume,历史 A 只回原 conversation。
同一独立 harness 用 immutable base 创建 21 个 legacy request 和第一页 cursor;当前 head 读取同一 fixture 的完整第一页结果与原值一致,旧 cursor 继续读取最后 1 条,重复读取一致,entry/route/operation 持久化字节未改变。禁用 effect single-flight 的 mutation 会把 live admission 错改为 explicit_unverified,真实入口 oracle 失败,恢复锁后的当前 head 通过。
同一真实 runtime 中,另一个 ordinary legacy Goal 的 request 只在自己的 recipient inbox 可见,原 exact inbox 不变;foreign GoalRef 被拒绝且零业务写入,随后当前合法 request 能被读回。删除 disposable source 后,request 和 recipient read 均拒绝而不改业务记录,没有把来源不完整解释为没有权限边界。
语义与 CI 对齐
采用已有 GoalRef、return-delivery 和 registry codec vocabulary,不新建更广的 actor lifecycle。旧 head 的 architecture 确有 3 个失败:base 的原始 contract.py metadata mismatch 之外,head 新增了 5 个 stale 和 8 个 unregistered I/O site,以及 6 个未登记 direct-loader owner;不能把新增失败归到旧 base。当前 head 的 manifest/owner 修复后,完整 architecture 重新通过,这些旧问题只保留为历史证据,不发布过期 Request Changes。
先前全量 typed suite 的 SQLite 失败发生在磁盘耗尽期间;串行复跑 SQLite real-store、changed lifecycle 与 handlers 共 339 项通过。capacity rehearsal 在 base/current head 同条件仍因现有 5 GiB reserve 失败,runner 与 causal owner 未改,独立 changed-invariant 通过。质量 receipt 如实非通过,merge-readiness 仍有独立 hold;既不下调预算,也不因无关红检查要求本 PR 改代码。
我的整体评价
APPROVE 这个完整、可回滚的 continuity 切片:长期工作不丢旧承诺、不重复 provider effect,新实例可继续有效工作;用户的普通 legacy 接入不被新字段或 cursor 破坏。机制成本主要是必须保存的历史身份与 effect admission,不能用当前 registry 临时推导;不需要另起抽象框架。bounded future-facing pass 保留共享 typed lifecycle,较大的 roundtrip 分拆延后;旧 prose exception fallback 仍有“conversation timeout”被误判为 route 不可用的风险,但它在 base 已存在、已有 typed ReturnResolutionBlocked 迁移说明,不把无关兼容债当作本次 blocker。真实外部 provider/live outbox 和整项 M3 激活未宣称合格。本轮不合并、不升级。
English verdict: APPROVE - 8b7af90; exact-head registry census/denial-owner repair revalidated. Native checks, real cross-process single-flight and crash recovery, canonical A/B return, stdio MCP and baseline-issued legacy cursor parity passed. Unrelated disk-reserve capacity failure remains a separate quality/merge hold; no stale request-changes verdict is carried over.
|
按 M3 同源协作 RFC 和 前次评审框架,当前 exact head
因此 APPROVE 当前 bounded increment;正式双语 review 与验证说明见本次 exact-head review。不合并、不升级、不扩大权限。 |
Goal And Delivered Outcome
goal_idalias, so a deleted and recreated Goal could observe or mutate work from the prior Goal instance.source_session_v1, requests, decisions, links, peer returns, and delivery receipts now bind to{goal_id, goal_instance_id}. A long-lived worker can still publish a late result for the original instance through its saved route, but the recreated Goal cannot read or change that work.main.Scope And Continuation
handoff_inbox_outboxinventory row.Validation
4e962db9346965564200c0506a56133db9e2814dunitpassedunitpassedintegrationpassedsource_session_v1tests cover A-to-B recreation isolation, late A result routing, sender single-flight beyond admission expiry, crash recovery with and without a provider locator, MCP capture, and the realmanager-inboxCLI subprocess.regression_paritypassedstaticpassedunitpassedstaticpassedloopx canary premerge --from-git-diff --git-diff-base origin/main: 13 selected checks passed with no failures or manual holds.staticnot_applicablescripts/ci/review_gate.py verifyrequires the CI-onlyNEEDS_JSONenvironment value.Frontend / Visual Evidence
Type of Change
LoopX Area
Technical Direction
goal-instance-identity-and-orphan-recovery-v0.md.Shared-authority RFC fixture impact
Boundary Checklist
.loopx/,.codex/goals/, and liveACTIVE_GOAL_STATE.md).none.Signed-off-bytrailer (git commit -s).