From 0370a13a1b059939640c40392ca99039f149030c Mon Sep 17 00:00:00 2001 From: huangruiteng <14976749+huangruiteng@users.noreply.github.com> Date: Wed, 16 Sep 2026 22:50:16 +0800 Subject: [PATCH] chore(canary): record chat_runtime's reviewed module ceiling `examples/control_plane/control-plane-maintainability-ratchet-smoke.py` fails on main: `loopx/chat_runtime.py` is 1560 lines against its checked-in ceiling of 1502, and 35 `Any` against 33. The growth is exactly #4533's team-preview admission facts - one 51-line rule plus its 7-line wiring - and nothing else in the module moved, so this is reviewed growth rather than drift. The ceiling is the remedy the ratchet itself provides for that case. A module metric budget is settled in the checked-in ledger, not through `REVIEWED_MAINTAINABILITY_EXCEPTIONS`: an evaluated finding still counts in `category_counts` even when an exception covers it, so the ledger edit is the reviewer-visible act. The repository already works this way - `loopx/todos.py` was refreshed 2165 -> 2190 -> 2229 -> 2249 -> 2285, `#2896` is a baseline refresh, and `#2953` grandfathers a module. Relocating the rule was considered first and is not enough on its own: moving the whole method and its call site out of the module leaves 1504 lines, still above the frozen 1502, so the ledger would have to be edited either way and the extra churn would not restore the ceiling. The failure output also now names the ledger to refresh next to the finding. Main sat red here because nothing in the CI text pointed at `loopx/canary/module_metric_baseline.json`, and both the new line and the negative case are locked by focused tests. Verified: pytest tests/canary/test_maintainability_ratchet.py tests/control_plane/test_m6_quality_gates.py -q -> 12 passed; examples/control_plane/control-plane-maintainability-ratchet-smoke.py -> ok, unreviewed: 0. Follow-up (deferred, recorded rather than bundled): `loopx/chat_runtime.py` stays a hot module with no headroom, so the next change that touches the manager turn prologue - the turn context assembly and the `ManagerInspection` wiring around it - should extract that bounded context builder instead of growing the controller again. Signed-off-by: huangruiteng <14976749+huangruiteng@users.noreply.github.com> --- loopx/canary/maintainability_ratchet.py | 20 ++++++++ loopx/canary/module_metric_baseline.json | 4 +- tests/canary/test_maintainability_ratchet.py | 49 ++++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/loopx/canary/maintainability_ratchet.py b/loopx/canary/maintainability_ratchet.py index b6a79ca04b..8ee74b566a 100644 --- a/loopx/canary/maintainability_ratchet.py +++ b/loopx/canary/maintainability_ratchet.py @@ -788,4 +788,24 @@ def render_control_plane_maintainability_report(payload: Mapping[str, Any]) -> s ) for exception_id in payload.get("invalid_exceptions") or []: lines.append(f"- invalid exception metadata: {exception_id}") + # A module metric budget is settled in the checked-in ledger rather than by + # a reviewed exception, so name that file next to the finding: it is the + # reviewer-visible edit that decides whether the growth is accepted. + if any( + str(finding.get("category") or "") == "module_metric_budget" + for finding in payload.get("findings") or [] + ): + lines.append( + "- module metric debt: refresh the reviewed ceiling in " + f"{_module_metric_baseline_name(payload)} for the growth this review accepts" + ) return "\n".join(lines) + "\n" + + +def _module_metric_baseline_name(payload: Mapping[str, Any]) -> str: + policy = payload.get("policy") + if isinstance(policy, Mapping): + declared = str(policy.get("module_metric_baseline_path") or "").strip() + if declared: + return declared + return MODULE_METRIC_BASELINE_PATH.name diff --git a/loopx/canary/module_metric_baseline.json b/loopx/canary/module_metric_baseline.json index 9ffe5aa7e4..989df62710 100644 --- a/loopx/canary/module_metric_baseline.json +++ b/loopx/canary/module_metric_baseline.json @@ -36,9 +36,9 @@ "lines": 1590 }, "loopx/chat_runtime.py": { - "any_count": 33, + "any_count": 35, "dict_any_count": 0, - "lines": 1502 + "lines": 1560 }, "loopx/chat_server.py": { "any_count": 25, diff --git a/tests/canary/test_maintainability_ratchet.py b/tests/canary/test_maintainability_ratchet.py index 46f6ddea1c..3eb8bcaf09 100644 --- a/tests/canary/test_maintainability_ratchet.py +++ b/tests/canary/test_maintainability_ratchet.py @@ -94,6 +94,55 @@ def test_module_metric_ratchet_rejects_growth_above_checked_in_baseline( assert module_metrics(module_path)["any_count"] == 1 +def test_module_metric_debt_names_the_reviewed_ledger_to_refresh( + tmp_path: Path, +) -> None: + """Module metric growth is settled in the checked-in ledger, not by exception.""" + + module_path = tmp_path / "loopx" / "sample.py" + module_path.parent.mkdir(parents=True) + module_path.write_text("\n".join(["# padding"] * 1501), encoding="utf-8") + + payload = evaluate_maintainability_findings( + collect_module_metric_findings(tmp_path, tracked_paths={module_path}), + reviewed_exceptions={}, + ) + rendered = render_control_plane_maintainability_report( + { + **payload, + "policy": { + "module_metric_baseline_path": "loopx/canary/module_metric_baseline.json" + }, + } + ) + + assert payload["ok"] is False + assert "module metric debt" in rendered + assert "loopx/canary/module_metric_baseline.json" in rendered + + +def test_review_without_module_metric_debt_keeps_the_report_unchanged() -> None: + finding = { + "id": "compatibility_facade:loopx.sample", + "category": "compatibility_facade", + "path": "loopx/sample.py", + } + + rendered = render_control_plane_maintainability_report( + evaluate_maintainability_findings( + [finding], + reviewed_exceptions={ + finding["id"]: { + "reason": "A public compatibility window still exists.", + "retirement_plan": "Delete the edge after the window closes.", + } + }, + ) + ) + + assert "module metric debt" not in rendered + + def test_reviewed_exception_lifecycle_rejects_new_debt_and_stale_entries() -> None: finding = { "id": "dependency_debt:loopx.sample->loopx.presentation",