Files
cleveragents-core/tools/_implementer_metadata_classifier.py
T
drew 0bc734c020 style: ruff format the controller-state-machine branch (288 files)
Applies `ruff format` to the accumulated formatting debt on this branch.
Formatting-only — no behavioral changes. Required for CI/lint's format
gate (`nox -s format -- --check`), which the branch was failing on 288
tracked files that drifted from ruff's canonical style.

In-progress WIP files are intentionally excluded so this commit stays a
clean formatting-only diff.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 00:09:17 -04:00

82 lines
3.5 KiB
Python

"""Metadata-only diversion classifier.
Extracted from :mod:`dispatch_implementer` (C2 harvest 2026-05-15)
as the first cohesive unit moved out of the 3.2k-line driver toward
the ~500-line per-module budget the rest of ``tools/`` honours.
The function is pure: takes a Forgejo item dict + an
``ImplementerPrefetchResult``-shaped carrier, returns a strict
``bool``. No I/O, no LLM, no module-level state — the natural
candidate for the first extraction.
Re-exported through ``dispatch_implementer._classify_metadata_only``
for backwards-compatibility with the G1 tests, so test imports and
call sites land in one place.
Caller pattern: see the inline call in ``_prefetch_prompt`` —
result is stashed on the per-item context as
``metadata_only_candidate`` for cycle telemetry and any future
diversion path to consume.
"""
from __future__ import annotations
from typing import Any
def classify_metadata_only(item: dict[str, Any], prefetch: Any) -> bool:
"""G1 harvest (2026-05-15) — return ``True`` when this work item
appears to be **metadata-only** (no code work required), based on
deterministic signals already in the prefetch carrier. Returns
``False`` whenever any signal hints at code work or any signal is
ambiguous: the harvest plan's explicit tie-breaker is "when in
doubt, classify as code work — the cost of an unnecessary
code-work attempt is much lower than incorrectly skipping
legitimate implementation."
Signals consulted (all from the carrier; no new network calls):
1. ``item`` must be PR-shaped — ``new_issue`` work always
requires a fresh implementation, so it is never metadata-only.
2. CI overall state must NOT be ``failure`` or ``error``. A
failing CI is by definition something the worker has to fix.
3. Per-check ``ci_detail`` rows must NOT include any
``failure`` / ``error`` status, even if the overall combined
state happens to be ``success`` (defensive against Forgejo
race windows where the combined state lags an individual
check).
4. No active ``request_changes_reviews``: a REQUEST_CHANGES
review is feedback the worker must respond to. (A label-only
request would be a code review smell on the reviewer's part,
so we conservatively assume any RC review references source.)
When all four hold the item is a candidate for diversion to a
grooming-style path. The actual no-clone handling is wired
separately and may be deferred — this classifier ships first so
an operator can observe how often the diversion would fire on
real PRs before any behaviour change.
Pure function; safe to call from anywhere in the dispatch path.
"""
if not isinstance(item.get("head"), dict):
return False
if prefetch is None:
return False
ci_status = getattr(prefetch, "ci_status", None) or {}
if isinstance(ci_status, dict):
state = str(ci_status.get("state") or "").lower()
if state in ("failure", "error"):
return False
ci_detail = getattr(prefetch, "ci_detail", None) or []
if isinstance(ci_detail, list):
for check in ci_detail:
if not isinstance(check, dict):
continue
status = str(check.get("status") or "").lower()
if status in ("failure", "error"):
return False
rc_reviews = getattr(prefetch, "request_changes_reviews", None) or []
if isinstance(rc_reviews, list) and len(rc_reviews) > 0:
return False
return True