RuntimeLoop 43 参数收进 RuntimeLoopConfig(不拆类) #113

Merged
Yushu merged 2 commits from refactor/105-runtime-loop-config-dataclass into main 2026-08-11 03:54:37 +00:00
Member

Closes #105

RuntimeLoop 构造函数 43 个 keyword-only 参数里,"只被恰好一个方法读、本质是
静态配置常量"的 22 个收进新的 RuntimeLoopConfig(同 reflection.ReflectionCycleConfig
既有先例)。不拆 RuntimeLoop,42 个方法的行为一行不改,构造函数从 43 参数
降到 22(config 本身 + 21 个独立参数)。

判断标准:按类型,不是按读取次数

设计阶段自己抓到一处误判,记录下来是因为它正是 issue 复核引言块点名过的那类错误
的另一个实例:delegate_enabled 单读(_run_tool_loop)、类型是 bool,「端口/
客户端/回调/registry 排除」这条规则不拦它——但它的真实值是
config.arise_delegate_enabled and delegate_available,后半是按本次调用现查的
熔断状态,不是纯静态配置,跟 spontaneous_goal_unlocked 被排除在外是同一类。

变异验证确认这条判断本身有回归测试保护:把它错误并入纯静态值(去掉
and delegate_available),test_a_broken_delegate_pool_hides_the_tool_from_the_model
立刻变红。

验证

  • 机械核对:写脚本把 22 个搬迁字段的新组装表达式(loop_factory.py
    _runtime_loop_config)与 git show HEAD 拿到的旧版 RuntimeLoop(...) 调用点
    逐字 AST 比对,全部一致;21 个保留字段同样核对,43 = 22 + 21 一个不多一个不少。
  • 6 个公开方法签名(run/run_callback/run_light/run_environment_signal/
    run_immediate_followup/assemble_context)用 diff 逐字核对零差异。
  • 方法数不变(__init__ 前后各 42 处 def 匹配,含 __init__ 本身)。
  • 全量 1546 passed(随机序 + 并行各两遍,一次并行跑撞到已知的
    test_debounce_e2e.py 高负载偶发 flake,单独重跑与二次全量重跑均绿),
    ruff check 干净。
  • 3 项变异按预期表现(run_limit 改坏会红;delegate_enabled 错误并入静态值会红)。

两轴 review(sonnet):1 条 minor,已修

Standards 轴零发现(逐字段核对 22+21=43 无搬错/漏搬/误分类)。Spec 轴 1 条:
RuntimeLoopConfig docstring 说 spontaneous_goal_unlocked「同样单读」来类比
delegate_enabled 的排除理由,但它实际被两个方法读取,不是单读——排除结论本身
没错(都是 per-call 现算而非静态),只是给对的结论配了一条经不起核实的证据。已修。

Not in scope(确认未越界)

不拆 RuntimeLoop 类;不碰 storage.py;不碰 __init__.py 拆分(#97 范围);
不新增/不改写任何既有断言(tests/ 目录唯一改动是 runtime_loop_helpers.py
的内部实现,无一处 assert);不涉及 docs 分支(本票无设计决策变更)。

🤖 Generated with Claude Code

Closes #105 `RuntimeLoop` 构造函数 43 个 keyword-only 参数里,"只被恰好一个方法读、本质是 静态配置常量"的 22 个收进新的 `RuntimeLoopConfig`(同 `reflection.ReflectionCycleConfig` 既有先例)。**不拆 `RuntimeLoop` 类**,42 个方法的行为一行不改,构造函数从 43 参数 降到 22(config 本身 + 21 个独立参数)。 ## 判断标准:按类型,不是按读取次数 设计阶段自己抓到一处误判,记录下来是因为它正是 issue 复核引言块点名过的那类错误 的另一个实例:`delegate_enabled` 单读(`_run_tool_loop`)、类型是 `bool`,「端口/ 客户端/回调/registry 排除」这条规则不拦它——但它的真实值是 `config.arise_delegate_enabled and delegate_available`,后半是按本次调用现查的 熔断状态,不是纯静态配置,跟 `spontaneous_goal_unlocked` 被排除在外是同一类。 变异验证确认这条判断本身有回归测试保护:把它错误并入纯静态值(去掉 `and delegate_available`),`test_a_broken_delegate_pool_hides_the_tool_from_the_model` 立刻变红。 ## 验证 - **机械核对**:写脚本把 22 个搬迁字段的新组装表达式(`loop_factory.py` 的 `_runtime_loop_config`)与 `git show HEAD` 拿到的旧版 `RuntimeLoop(...)` 调用点 逐字 AST 比对,全部一致;21 个保留字段同样核对,`43 = 22 + 21` 一个不多一个不少。 - 6 个公开方法签名(`run`/`run_callback`/`run_light`/`run_environment_signal`/ `run_immediate_followup`/`assemble_context`)用 diff 逐字核对零差异。 - 方法数不变(`__init__` 前后各 42 处 `def` 匹配,含 `__init__` 本身)。 - 全量 **1546 passed**(随机序 + 并行各两遍,一次并行跑撞到已知的 `test_debounce_e2e.py` 高负载偶发 flake,单独重跑与二次全量重跑均绿), `ruff check` 干净。 - 3 项变异按预期表现(`run_limit` 改坏会红;`delegate_enabled` 错误并入静态值会红)。 ## 两轴 review(sonnet):1 条 minor,已修 Standards 轴零发现(逐字段核对 22+21=43 无搬错/漏搬/误分类)。Spec 轴 1 条: `RuntimeLoopConfig` docstring 说 `spontaneous_goal_unlocked`「同样单读」来类比 `delegate_enabled` 的排除理由,但它实际被两个方法读取,不是单读——排除结论本身 没错(都是 per-call 现算而非静态),只是给对的结论配了一条经不起核实的证据。已修。 ## Not in scope(确认未越界) 不拆 `RuntimeLoop` 类;不碰 `storage.py`;不碰 `__init__.py` 拆分(#97 范围); 不新增/不改写任何既有断言(`tests/` 目录唯一改动是 `runtime_loop_helpers.py` 的内部实现,无一处 `assert`);不涉及 `docs` 分支(本票无设计决策变更)。 🤖 Generated with [Claude Code](https://claude.com/claude-code)
只被恰好一个方法读、本质是静态配置常量的 22 个参数收进新的 RuntimeLoopConfig
(同 reflection.ReflectionCycleConfig 既有先例)。构造函数从 43 参数降到 22
(config 本身 + 21 个独立参数)。不拆类,42 个方法一行没改,6 个公开方法签名
逐字比对零差异。

按类型判断而不是按读取次数判断哪些字段该收——过程中抓到自己的一处误判:
delegate_enabled 单读、类型是 bool,两条既有筛选规则都不拦它,但它的值不是纯
静态配置,生产构造点算的是 config.arise_delegate_enabled and delegate_available,
后者是按本次调用现查的熔断状态。这与 spontaneous_goal_unlocked 被排除在外是
同一类判断,已在设计阶段自查揪出并改正,变异验证(M3)确认这条判断本身有回归
测试保护。

验证:
- 22 个搬迁字段的组装表达式与旧版 RuntimeLoop(...) 调用点用 AST 逐字比对,
  全部一致;21 个保留字段同样逐字核对。
- 全量 1546 passed(随机序 + 并行各两遍),ruff 干净。
- 3 项变异按预期表现(run_limit / delegate_enabled 排除 均正确变红)。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Standards 轴零发现。Spec 轴 1 条 minor:RuntimeLoopConfig docstring 说
spontaneous_goal_unlocked「同样单读」来类比 delegate_enabled 的排除理由,
但它实际被 _pending_intents_snapshot/_run_tool_loop 两个方法读取,不是单读。
排除结论本身没错(都是 per-call 现算而非静态),只是给对的结论配了一条经不起
核实的证据——同本仓反复点名的那类问题,这次出现在解释性文字里。

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Yushu merged commit 41123205ab into main 2026-08-11 03:54:37 +00:00
Yushu deleted branch refactor/105-runtime-loop-config-dataclass 2026-08-11 03:54:38 +00:00
Sign in to join this conversation.
No description provided.