Repository navigation
Conversation
b1d3138 to
dacbc33
Compare
3aedcaa to
04fc080
Compare
PR loopx-project#7549 stopped collapsing whitespace in the operator message, so the native model input now carries the original line breaks instead of a single collapsed line. The assertion in tests/test_lark_native_reply_context.py still matched the collapsed form and could no longer be satisfied by the shipped prompt. Assert against the recorded text blocks so the check states the preserved-material contract directly. Signed-off-by: xiaoan17 <anbc1224@gmail.com>
04fc080 to
8c9b636
Compare
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
未发现阻塞 finding,建议 APPROVE。对象 8c9b6364b8321d2d5ffb0c303465fa97de67a01f,基线 9dcdc0bacd455a8cf6f6146f052ffc4df0f5d04a;本次未查询 GitHub CI。
动机 / Motivation
维护飞书私聊和群聊回复的开发者会遇到同一段输入同时被要求保留换行、又被要求变成单行的测试矛盾。用户回复 Approved 时,原请求已按含换行的文本送入 native Turn,旧断言却在 JSON 转义后的字符串中寻找折叠形式;修正后直接检查实际 text block 中的原换行。本次实测闭合这两个过期断言,并能在原文被再次折叠时重新报错。只修现有测试,不改变产品输入、引用权限、回复目标或其它发布失败项。
改动思路 / Approach
复用既有 native 请求捕获,直接拼接 text block 的文本再检查原始换行。JSON 编码会把换行转义,不能用编码结果中的单行拼法代表实际模型输入。恢复产品里的空白折叠会损坏粘贴代码和原文;删除断言又会丢掉这个边界的保护。当前修法只改矛盾的期待,并保留来源、权限、重放和回复目标的其余断言。
具体改动 / Changes
规范依据是 docs/architecture/rfcs/controller-executor-unified-contract-v0.md,spec_revision 9dcdc0bacd455a8cf6f6146f052ffc4df0f5d04a。§5 的 What the executor must know 要求交付原始材料;已合并的 #7549 将普通 Chat 的原文保留修正作为独立切片交付。本 PR 只补齐这条已生效行为的测试,不宣称完成整个 Controller/Executor RFC。
关键代码讲解
test_native_reply_retains_exact_reference_and_original_authority 在私聊、群聊两种路径中先核对持久化请求,再读取实际 turn/start 参数。新断言在这里寻找含换行的 Current user message 与 Approved,检查对象仍是送给 native 的输入。CodexChatAgentSession.send 的现有 str(user_message or "") 和 _turn_prompt 保留原文,产品代码在本次 diff 中没有变化。
原有 workspace_read grant、引用无授权含义、同一回复来源和重复送达只保留一个 session 的检查均未删除。现有四模式完整原文与队列重启测试补足更复杂的空白、代码缩进和持久化路径,无须新造一套测试框架。
对主干的风险 / Risks
最值得反驳的是“只把测试改绿,却掩盖 native 输入仍可能损坏”。我在原生 renderer 入口做了仅内存生效的空白折叠反例:私聊和群聊都在新换行断言处失败;未改动的 head 则通过。不可变基线的整个模块为2 failed/13 passed,失败都来自旧单行期待;当前整个模块15项通过,连同四模式原文和真实本地队列重启,共20 passed。
PASS:标准 premerge 的5项直接检查、changed-file Ruff;catalog 未选择额外 smoke。协议服务响应是确定性 double,来源接收、Chat 存储和运行时路径实际执行;没有调用真实模型或飞书。其它 steering 和发布资格失败不能由这20项结果核销。
同作者本批其它修复分别涉及 HTTP 组合、语义注册表和维护性账本,未发现重复造 smoke 或脚手架;本 PR 修现有断言,独立保留便于审核与回滚。
我的整体评价 / Verdict
long_horizon 与 user_experience 均 preserved:运行时不变,原有恢复、来源权限和重复送达限制继续受测。未改任何渲染、布局或产品提示;这是现有 native-input 回归断言修复,视觉评审不适用。未调用真实模型或飞书服务,也未重新验收已安装界面。这条修正有明确维护价值,且没有通过放宽范围、删除来源断言或改回错误产品行为来换取绿色。剩余发布资格应继续由原候选的完整证据判断。
English verdict: APPROVE 8c9b636; the stale assertion is corrected, 20 focused checks pass, and deliberate whitespace collapse still fails both native reply cases.
动机 / Motivation
main当前在tests/test_lark_native_reply_context.py::test_native_reply_retains_exact_reference_and_original_authority[False/True]上是红的。
来源是 PR #7549(commit
6f8f47638,fix(chat): preserve original operator material in native turns),它让 operator message 不再被折叠空白:
于是 native model input 里保留的是原始换行,而不再是被压成一行后的形式。
当前缺口 / Current gap
tests/test_lark_native_reply_context.py里那一条断言写的是折叠后的单行形式:它再也不可能被满足:同文件上一行断言的
row["message"]用的就是换行形式(
endswith("Current user message:\nApproved")),两条断言描述的是同一段 material,只有后一条停留在旧格式上。
改动思路 / Approach
不改产品行为,只把这条过期断言对齐到 #7549 之后已经生效的契约:原始 operator material
逐字进入模型输入,包括它自己的换行。
断言直接作用在录下来的 text block 上(
native_input的text字段),而不是json.dumps()之后被转义的字符串,这样表达的是"material 逐字保留"这件事本身。具体改动 / Changes
tests/test_lark_native_reply_context.py只改测试,不改产品代码、schema、wire 或默认值。
验证证据 / Evidence
origin/main=2a2323756(含 refactor(turn): qualify receipts and continuation in the typed owner #7523)。本分支已 rebase 到该基线。tests/test_lark_native_reply_context.py— 改动前 2 failed, 13 passed,改动后 15 passedgit bisect定位首个坏提交是6f8f47638(PR fix(chat): preserve original operator material in native turns #7549):42102e1e1上通过,6f8f47638之后失败...Operator user message:\nReferenced message (context only; ...):\n{"message_id":"om_preview",...}\n\nCurrent user message:\nApproved——即换行形式,与新断言一致
对主干的风险 / Risks
不会掩盖新的回归。
English verdict: the assertion was written against the whitespace-collapsed prompt that PR #7549
replaced with the preserved original operator material. It could never be satisfied by the shipped
prompt. This PR asserts the preserved material directly against the recorded text blocks.
评审请求 / Review request
请按 exact head
3aedcaaef8d1fb184e4078a2e03e10e815162727评审。本 PR 与 #7621、#7631 一起修复 main 上剩余的 pytest 红项。
Rebase and re-validation (2026-10-29)
mainat9dcdc0bacd455a8cf6f6146f052ffc4df0f5d04a8c9b6364b8321d2d5ffb0c303465fa97de67a01fThis is one of six pull requests that together restore
mainto green. Onmainat9dcdc0bacd455a8cf6f6146f052ffc4df0f5d04athe repository is red in exactly eight places, and this one owns the two stale native-reply assertions:tests/test_lark_native_reply_context.py::test_native_reply_retains_exact_reference_and_original_authority[False]tests/test_lark_native_reply_context.py::test_native_reply_retains_exact_reference_and_original_authority[True]The other six are owned by #7621, #7631, #7640, #7642 and #7646. None of the eight is caused by a pull request in this set.
All nine pull requests in this set were rebased onto
mainat9dcdc0bacd455a8cf6f6146f052ffc4df0f5d04aand merged together in a local worktree. The merged state passestests/architecture/,tests/canary/,tests/test_manager_context_roundtrip.py,tests/test_lark_native_reply_context.py,tests/control_plane/test_host_adapter_settlement_step_vocabulary.pyandtests/control_plane/test_host_adapter_settlement_partial_steps.py— 1805 passed, 0 failed.python scripts/generate_rfc_status_index.py --checkis clean.