Repository navigation
Conversation
…n demand PR wait and turn-outcome hooks import one owner submodule each, but the package facades eagerly imported every workflow (report sources, PR descriptions, evaluation, dogfood, Codex App staging). Resolve facade exports through _EXPORTS and module __getattr__ so each export stays identical to its owner while unselected workflows are not imported. Signed-off-by: lusendong.6789 <lusendong.6789@bytedance.com> Co-authored-by: TRAE CLI <traecli@bytedance.com>
songoow
left a comment
There was a problem hiding this comment.
Reviewer: model_agent; GPT-6; OpenAI; self_reported.
动机 / Motivation
受影响的是每次唤醒都加载 issue-fix 或 reward-memory 子模块的 CLI 进程。以前导入一个子模块会展开整个包的公开facade;本项把未选择的导出推迟到首次访问。已验证所有公开导出仍解析到原所有者对象,轻量hook导入不再展开未选中的工作流。本项不改变召回、写入、奖励评估策略,也不证明完整任务延迟或token费用下降。
这次判断绑定PR #7749的完整head 52fa115。评价对象是已经存在的实际调用任务与局部可观察结果;重复调用带来的成本或错误恢复路线是本项动机,不能把较小响应或更少导入直接等同于长期任务质量。
改动思路 / Approach
使用有限显式名称映射和模块级 getattr;首次访问导入原模块并缓存原对象,__all__和dir保留发现性。本 PR 的合理边界是两个包facade的导入时机;业务函数和状态所有者保持原位。
沿入口跟踪到原所有者、返回值和失败恢复后,这个实现仍在现有边界上处理问题。无改动会保留原成本或错误指引;另起一套业务规则、持久化状态或通用缓存会增加同步义务,此处没有这类必要性。新增说明和投影应服务原调用方完成任务,不能改变原来的准入、权限、结算或来源完整性要求。
具体改动 / Changes
关键代码讲解
- getattr:将原公开函数名映射到原模块,未知名称继续抛出AttributeError。 输入与拒绝分支沿用现有调用路径;这一处的返回内容或依赖时机改变,不把局部投影提升为新的业务判定。
- getattr:按需返回原class/function对象并缓存,不包装或复制业务实现。 输入与拒绝分支沿用现有调用路径;这一处的返回内容或依赖时机改变,不把局部投影提升为新的业务判定。
调用者公开名称、对象身份和业务实现保持;导入时的异常时机有意变为首次真正访问相应导出。正向场景是:分别访问每个公开导出并比较原所有者对象身份。负向场景是:只导入轻量hook时禁止未选择的heavy模块;未知属性保持拒绝。这些是依据实际源码与已有调用测试核对的行为边界;失败和恢复继续由原owner负责,没有以返回字段存在代替真实状态读取。
规范依据为原公开调用行为、既有所有者和相应回归;已检索改动路径与周边文档,没有为这次局部性能/适配修正找到另一个已接受专项RFC。作者的量测叙述不充当独立功能合同。
实际验证 / Validation
3 项 facade/导出身份/导入隔离测试 PASS;所有改变Python源码编译和 diff hygiene PASS。
执行命令:python -m pytest -q tests/test_cli_entrypoint.py -k 'facade or reward_memory or issue_fix'。本轮统计只包含上述实际执行;作者PR内微基准、旧head完整回归和旧review的历史量测都已阅读,但不冒称本轮重新执行的结果。
对主干的风险 / Risks
调用者公开名称、对象身份和业务实现保持;导入时的异常时机有意变为首次真正访问相应导出。最需要防止的情况是:只导入轻量hook时禁止未选择的heavy模块;未知属性保持拒绝。已核对相关调用方和已有review,未重复发布旧head意见;本轮对新增head的源代码与局部回归单独作判断。原持久化状态和业务所有者保持,仍然不能由小范围通过推断整仓或所有部署入口已经合格。
当前精确head失败证据:test-shard (6)、test-shard (3)、test-shard (2)、chat-bundle-browser (1)、dashboard-browser (2)。当前多个test-shard失败日志未成功取得,且chat与dashboard存在实际失败;源码与局部导入测试不足以归因全部当前失败。 未取得的分片日志明确留作未知;同名错误或改动文件不相交都不足以建立pre_existing归因。
最小补齐是针对当前实际失败取得日志,并提供不可变base/head同命令同条件归因,或能独立覆盖该失败不变量的当前真实入口证据。已完成的聚焦回归不应无条件重做,也不要求无关功能重写;如果归因确认是回归,再修相应最小代码路径。未完成的检查不是单凭pending就要求改代码的理由。
我的整体评价 / Verdict
REQUEST_CHANGES:当前阻断是具体的验证证据缺口。聚焦审查尚未发现可复现的阻断性生产代码缺陷,不能把未归因红灯写成代码finding。 审查仅适用于exact head 52fa115。
本 PR 的合理边界是两个包facade的导入时机;业务函数和状态所有者保持原位。 已验证所有公开导出仍解析到原所有者对象,轻量hook导入不再展开未选中的工作流。 已检查 loopx/capabilities/issue_fix/init.py:getattr;loopx/capabilities/reward_memory/init.py:getattr;变更是CLI/内部读取或文本协议,没有修改浏览器页面布局,视觉截图不适用。
当前多个test-shard失败日志未成功取得,且chat与dashboard存在实际失败;源码与局部导入测试不足以归因全部当前失败。 本项不改变召回、写入、奖励评估策略,也不证明完整任务延迟或token费用下降。所有本轮探针使用合成fixture,没有运行真实模型任务或发起业务作业;本review陈述审查与验证事实,不声称已经发布部署或完成合并。
English verdict: REQUEST_CHANGES — exact head 52fa115. Focused code review and the listed local regressions found no confirmed blocking implementation defect. Approval is held for the named current validation gaps; resolve their source-bound evidence rather than changing unrelated code.
Delivery brief
issue_fix.pr_wait_hook,reward_memory.turn_hooks). Python first initializes the package. Both package__init__facades eagerly re-exported every workflow: report sources, PR descriptions, issue-fix reward memory, evaluation, dogfood and Codex App staging. Those modules were imported onquota should-runandheartbeat-promptwithout being called.loopx/capabilities/issue_fix/__init__.pyandloopx/capabilities/reward_memory/__init__.py. This uses the existing_EXPORTS+ module__getattr__idiom already used byloopx/capabilities/periodic_report/__init__.py. It does not change TS authority, scheduling, settlement, defaults or output contracts.Change
__all__to owner submodules in_EXPORTS.__getattr__imports the owner on first access, then caches the value in module globals. Lazyfrom . import nameinturn_hooksandmonkeypatch.setattron the facade keep working.__dir__lists all exports.__all__.tests/test_cli_entrypoint.py:issue_fix.{periodic_report,pr_description,reward_memory}orreward_memory.{codex_app_outcome,dogfood,evaluation};dir();Evidence
All measurements use a synthetic SQLite fixture on macOS. Base is
04c5799b8; head swaps only the two facade files inside the same checkout.Output parity: for
quota should-run,heartbeat-prompt --thinandstatus, base and head JSON outputs are equal once timestamps are normalized. The compressed scheduler host-facts chunks also match after decoding and normalizing timestamps.Modules imported per command:
quota should-runheartbeat-prompt --thinstatusissue_fix: periodic_report, pr_description, reward_memory, repository_snapshot, repository_commit_evidence, metrics_supplement, outcome_projection;domain_packs,domain_state;reward_memory: decision, dogfood, evaluation, evaluation_fixtures, health, memory_utility, utility_reducer.reward_memorycodex_app_outcome, decision, dogfood, evaluation, evaluation_fixtures, health, memory_utility, outcome_lifecycle, read_authority, runtime_hooks, utility_reducer.Isolated hook import cost (n=20, alternating order, after importing
effect_runtime): 348 ms → 179 ms median. Head was faster in 20/20 pairs, and 227 → 162 loopx modules were loaded.End-to-end CLI time is not distinguishable from noise at this sample size. Most of the deferred modules are still imported by other paths in the full command.
should-runheartbeat-promptstatusThe expected per-command gain is tens of milliseconds, not the ~110 ms this Todo originally estimated.
Validation at head:
pyteston the reward-memory, issue-fix, PR-wait, outbound-guidance and agent-turn-recall capability suites, plustests/test_cli_entrypoint.py,tests/test_loopx_turn_driver.py, the import-boundary/owner architecture tests and the compact-identifier owner test: 1022 passed.examples/reward-memory-*-smoke.py(8),issue-fix-pr-description-builder-smoke.pyandopenviking-project-peer-provider-smoke.py.loopx canary premerge --from-git-diff --git-diff-base origin/main(standard tier): 6 direct and 9 selected checks, 0 failures, 0 manual holds.Not covered
loopx/**, so it needs maintainer review and merge authorization. It is not self-merged.