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.
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
d3363009a7bee30ac37b8acde3ac93fb04009260unitpassedpytestcollaboration and manager-context suite: 94 passed.unitpassedintegrationpassedsource_session_v1tests cover A-to-B recreation isolation, late A result routing, concurrent drain admission, provider readback without resend, MCP capture, and the realmanager-inboxCLI subprocess.regression_paritypassedstaticpassedunitpassedstaticpassedloopx.canary.premergeandloopx.canary.maintainability_ratchetpassed.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).