test(scheduler): migrate ACK rules into decision tables - #3288
Conversation
Signed-off-by: Ray Tien <ray.tien0907@gmail.com>
Signed-off-by: Ray Tien <ray.tien0907@gmail.com>
Signed-off-by: Ray Tien <ray.tien0907@gmail.com>
huangruiteng
left a comment
There was a problem hiding this comment.
评审结论(Verdict)
按 exact head 9826b3e1dc44ec00c4d67c061fcf5e3132ab8e8d 评审,无 P0/P1 阻断项;发现 1 个 P2 覆盖缺口,建议合入前补充聚焦测试。CI 6/6 通过,本地 scheduler 相关 259 个测试与保留的 101 行 CLI 公共 round trip smoke 均通过。
动机
原 quota-scheduler-state-ack-smoke.py 膨胀到 1600+ 行,把稳定规则和一次性 CLI 演示混在一起,难以定位回归。该 PR 将稳定规则迁移到 pytest 决策表,只保留一条最短公共 CLI 路径,方向正确。
改动思路
把 cadence/ACK/state-scope/host-binding/recovery 规则拆成可参数化的决策表,并让 state_transition_rules.py 对非法 progression_index 明确 fail-closed;大段 smoke 断言由既有或新增 pytest 承接。
具体改动
loopx/control_plane/scheduler/state_transition_rules.py:越界/非法的progression_index统一回退为-1;无目标 RRULE 时current_cadence_acknowledged不再误判为已确认。行为更保守,与现有枚举/状态机语义一致。examples/control_plane/quota-scheduler-state-ack-smoke.py:从约 1600 行精简为 101 行,覆盖quota should-run→scheduler-ack-current→ settled readback 的完整公共 CLI 往返。- 新增/扩展 pytest:host-binding CLI 路径、ACK 决策表、backoff 收敛、状态迁移决策表;同时补了非法索引和越界索引的负例。
对主干的风险
主要风险来自大删除。逐项核对后,原 smoke 中的 policy progression、monitor 收敛、stale ACK、state-scope、failure cache、host transition、lookback 等场景已有既有或新增 pytest 承接;保留的 CLI smoke 覆盖了唯一一条端到端公共契约。运行时改动仅 5 行,且方向为 fail-closed,未发现默认行为静默变化。
唯一明确缺口:原 smoke 中关于 user_gate_notification_cooldown 的时序断言(notification_suppressed/notification_due、cooldown_minutes=30、reminder_window_minutes=3)随大段删除消失,新 pytest 未补上。该字段是公开状态契约的一部分,目前没有直接回归测试。
我的整体评价
这是一次高质量的测试右移:规则进入决策表后更易审查,运行时变更小且保守。合入前建议补一个聚焦的 cooldown 时序测试(可直接测 _user_gate_notification_cooldown 或保留一小段 CLI 场景);补上后我没有其他阻断意见。
P2 finding
- severity: P2
- trigger: 原 smoke 中
assert_cli_scheduler_failure_circuit_breaker的 cooldown 断言被整体删除,未在新 pytest 中找到等价覆盖 - code_path:
examples/control_plane/quota-scheduler-state-ack-smoke.py→loopx/control_plane/scheduler/scheduler_hint.py:_user_gate_notification_cooldown - incorrect_or_risky_outcome:
notification_suppressed/notification_due、cooldown_minutes、reminder_window_minutes未来回归时没有测试兜底 - location: 大删除 diff 中
user_gate_notification_cooldown相关断言段 - minimum_repair: 新增一个聚焦 pytest,覆盖 suppressed → due → after-window 的时序与字段值
- regression_test:
tests/control_plane/test_scheduler_cooldown_timing.py(或等价命名),断言cooldown_minutes=30、reminder_window_minutes=3及三态转换
English summary: No blocking findings. The smoke-to-decision-table migration is well executed and the 5-line runtime fix is fail-closed. One P2 gap: the only user_gate_notification_cooldown timing assertions were deleted without a pytest replacement; add focused coverage before merge.
Summary
quota should-runthroughscheduler-ack-currentand settled readbackprogression_indexIssue Or Task
Why
The scheduler ACK smoke had grown into a large collection of pure assertion workflows, which made stable rules harder to review and allowed current implementation output to act as the test oracle. Persisted cadence state also accepted an out-of-range progression index far enough for Python indexing behavior to influence acknowledgement detection.
This change gives each stable rule an independently authored, semantics-based pytest case with negative or mutation coverage. The retained smoke now checks only the durable public CLI seam, while corrupt cadence state recovers at the initial interval instead of being treated as acknowledged.
Validation
PYTHONPATH=$PWD uv run pytest -q tests/control_plane/test_scheduler_ack_decision_table.py tests/control_plane/test_scheduler_state_transition_rules.py tests/control_plane/test_scheduler_backoff_convergence.py tests/control_plane/test_scheduler_host_failure_cache.py tests/control_plane/test_scheduler_ack_current_host_binding.py— 55 passeduv run python examples/control_plane/quota-scheduler-state-ack-smoke.pyPYTHONPATH=$PWD uv run loopx canary premerge --from-git-diff— 18/18 passed, zero failures and manual holdsgit diff --check origin/main...HEADpython3 examples/full-public-smokes-workflow-smoke.pycompared on the branch and cleanorigin/main; both have the same pre-existing catalog-capacity failure at line 75:AssertionError: (700, 484)Type of Change
LoopX Area
Technical Direction
Core control-plane hardening
Long-horizon benchmark evidence
Operator surface and IM integration
Shared Goal Authority and cross-host coordination
Architecture and research incubator
Target base branch:
mainDirection tracker or promotion unit: contributor task
GH-C68Boundary Checklist
.loopx/,.codex/goals/, liveACTIVE_GOAL_STATE.md, credentials, private benchmark traces, verifier output, raw agent sessions, internal document links, or local machine paths.Signed-off-bytrailer (git commit -s).