test(lark): pin the manager context window's bounds and order - #4900
huangruiteng merged 1 commit into
Conversation
`manager_context_materials()` is the read side of loopx-project#4318's capture/authority split, and its contract is three named limits -- at most MANAGER_CONTEXT_ITEM_LIMIT messages, at most MANAGER_CONTEXT_CHARACTER_LIMIT characters, consumed newest-first so the surviving set stays chronological. None of the three had a test: searching the suite for the constants, the per-item cap or `context_window_exceeded` returns nothing, and only the `_for_ids` replay sibling is exercised directly. Each case is written from the contract rather than from current output, and each is checked by mutation: taking the oldest slice instead of the newest fails the window case, dropping the final chronological restore fails all three, and letting addressed messages into the window fails the exclusion case. No production behavior changes. Refs loopx-project#4318 Signed-off-by: hahahahahayesyeseys <95999512+hahahahahayesyeseys@users.noreply.github.com>
huangruiteng
left a comment
There was a problem hiding this comment.
动机
#4318 已交付 Lark manager 的“context capture 与 Turn authority 分离”,但它要求后续 authorized Turn 只读取有界的近期上下文。现有测试覆盖 retention、receipt-bound replay 和 capture/authority 分离,却没有直接调用 manager_context_materials() 来约束三个关键性质:最多 8 条、总计最多 4000 字符、从最新消息一侧消费预算后按时间顺序返回。这个 PR 只补这一真实 coverage gap,不改变生产行为。
改动思路
三个测试都从公开的持久行为设计 oracle,而不是照抄当前输出:超出 item limit 时必须丢最旧三条并保持 survivor arrival order;字符预算必须优先保护最新消息,只有最旧 survivor 可被截断;current/addressed authority-bearing 消息不得同时作为 quiet context,而 historical_context_only replay 仍可进入窗口。测试直接走生产 read helper,没有新增 fixture framework、mock owner 或第二套规则。
具体改动
- 在既有
test_lark_manager_reply_delivery.py中增加一个小型_chat_windowsynthetic fixture。 - 增加 newest-window/order 用例,直接绑定
MANAGER_CONTEXT_ITEM_LIMIT。 - 增加 newest-side character-budget 用例,绑定
MANAGER_CONTEXT_CHARACTER_LIMIT和截断方向。 - 增加 current/addressed exclusion 与 historical replay inclusion 用例,守住 context/authority 分界。
关键测试讲解
test_context_window_keeps_the_newest_messages_in_arrival_order 同时防止“取 oldest slice”和“返回 reverse order”;test_context_character_budget_is_spent_from_the_newest_side 让 8×1200 字符触发 4000 限制,期望 chronological sizes 为 [400, 1200, 1200, 1200];test_context_materials_exclude_the_addressed_and_the_current_message 用同一 projection 同时证明 current/addressed 被排除而 explicit historical context 被保留。
对主干的风险
这是 test-only diff,无 schema、runtime、permission、quota 或 UI 变化。独立覆盖扫描确认 merge base 上只有 _for_ids replay sibling 被直接调用,item/character constants 没有测试;同作者当前只有这一项 open PR,没有 same-shape batch farming。exact head 的 changed file suite 8 passed,Ruff、py_compile、diff check 与 public boundary scan通过;标准 canary通过。由于该分支基于旧 merge base,我还把 patch 干净合入最新 origin/main@0d464d2ac,保留主干后来新增的 proposal-delivery test,合并态 suite 6 passed。
有一个非阻塞的证据表述需要更正:PR body 说 production file 和 test file 在旧 base 与当前 main 间都 byte-identical;独立 blob hash 显示 production manager_context.py 的确相同,但 test file 不同(主干后来新增了其它测试)。这不影响 patch 的可合并性或测试结论,因为合并态已单独验证,但建议作者把 body 改成“production file identical,test patch cleanly integrates”。
我的整体评价
这 82 行不是一次性 walkthrough:它给已发布的 manager context window 增加三条互补、可产生突变敏感性的长期 contract tests,位置与现有 retention/replay suite一致,且没有重复覆盖或批量灌水。除 PR body 的非阻塞 base 描述修正外,未发现 blocker,我赞成在当前 exact head 上 APPROVE;合并动作仍由 maintainer 决定。
English verdict: APPROVE - head 4496de4; three durable tests now pin newest-first bounds, chronological output, and context/authority exclusion, while the stale-base body note should be corrected; exact-head 8/8 and latest-main integration 6/6 passed with static and boundary checks clean.
Goal And Delivered Outcome
manager_context_materials(). Its contract is three named limits -- at mostMANAGER_CONTEXT_ITEM_LIMITmessages, at mostMANAGER_CONTEXT_CHARACTER_LIMITcharacters, consumed newest-first so the surviving set is returned in chronological order. None of the three was tested: searching the suite for the constants, the per-item cap orcontext_window_exceededreturns nothing, and only the_for_idsreplay sibling is exercised directly. So the issue's "bounded" clause had no enforcement behind it.Scope And Continuation
MANAGER_CONTEXT_RETENTION_LIMIT = 32andMANAGER_CONTEXT_MAX_AGEare partially covered by the retention test in the same file, and thecontext_window_exceededlabel still has no case of its own. Those belong to the retention path, not to this window, and none of them is a blocker here.Validation
unittests/extensions/test_lark_manager_reply_delivery.py: 8 passed, of which the 3 added here are newunittests/extensions: 952 passed at this head -- the added file is collected with its neighbors unchangedregression_paritystaticruff checkclean on the changed file;py_compileclean;git diff --checkclean;loopx check --scan-pathon the changed file reports 0 errors04ba65ac1, which is behindmain. The two files it depends on --loopx/extensions/lark/manager_context.pyand this test file -- are byte-identical between that revision and currentmain(verified by blob hash), so nothing here is measured against stale behavior. It is based there because pushing a current-mainbranch from this fork requires a token scope this author's token does not carry, while a fork sync is pending.Type of Change
LoopX Area
Technical Direction
Shared-authority RFC fixture impact
Boundary Checklist
none. -- UI impact: none; no presentation surface is touched, the change is a test file.Signed-off-bytrailer.