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>
Layered polish on top of 593d142f (Tier 2 deterministic dispatchers)
plus the systemd-supervised launcher that realises the SystemExit(2)
restart contract in production.
Code:
- Promote `_opencode_worker.list_sessions(server_url)` to public so the
coexistence guard no longer reaches into private `_request`.
- `assert_no_legacy_supervisor` truncates with `(showing first N)` and
takes `Iterable[str]` for supervisor_tags.
- Collapse `_sanitize_release_detail` to a single `str.replace()`
(substitute has no backticks; second pass was always a no-op).
- Telemetry `_api_cycles` routes through a single `_DISPATCH_TABLES`
dict so the rows query and breakdown query can never drift onto
different tables.
- `dispatch_one` docstring now lists `labels-fetch-failed` alongside
the other terminal states.
- `_loader.load_sibling` raises `ImportError` up front for a missing
file (was bubbling `FileNotFoundError` from `exec_module`).
Operations:
- `scripts/dispatchers-launcher.sh` supervises both dispatchers in one
process, restarts on non-zero exit with backoff, enforces a
per-child crash-loop budget, and forwards SIGTERM cleanly.
- `contrib/systemd/cleveragents-dispatchers.service` wires that into a
systemd unit with hardening defaults and journalctl visibility.
Tests (350 pass, 1 skipped):
- New `tests/auto_agents/test_loader.py` (4 cases).
- New `tests/auto_agents/test_telemetry_server.py` (5 synthetic-row
cases covering both tables, composite breakdown, unknown driver,
table isolation).
- Extended `test_dispatch_runtime.py` with truncation-suffix and
`list_sessions` direct tests; refit existing supervisor-guard tests
to monkeypatch the public helper.
Docs:
- AGENTS.md cross-links the launcher / systemd unit.
- CHANGELOG.md entry under [Unreleased] dated 2026-05-07.
Co-authored-by: Cursor <cursoragent@cursor.com>
Replaces the long-running pr-review-supervisor / implementation-
supervisor LLM polling loops with host-level Python dispatchers that
own queueing, claim ownership, watchdogs, and SQLite telemetry. The
LLM workers retain sole responsibility for review judgment and code
generation; Python owns only orchestration. The hard merge invariant
is unaffected — these dispatchers do not touch master.
Driver surface
- _opencode_worker.run_session_blocking — outcome-agnostic OpenCode
session lifecycle (completed / timeout / transport-error). Used
directly by reviewer / implementer dispatchers whose workers do
not emit the conflict-driver JSON exit schema.
run_worker_blocking is now a thin wrapper that adds the
conflict-specific JSON-outcome classification.
- _dispatch_runtime — shared Python runtime (work-group polling,
claim helpers, dispatch loop, telemetry). Pre-checks issue labels
before claiming and refuses when any auto/claimed-* is already
present, distinguishing already-claimed vs labels-fetch-failed
vs claim-failed terminal states. Frozen DispatchConfig.
- dispatch_review.py / dispatch_implementer.py — per-pipeline work
groups, prompts, and CLIs. Each refuses startup when a competing
AUTO-REV-SUP / AUTO-IMP-SUP legacy supervisor is live on the
same OpenCode server (override:
{REVIEW,IMPLEMENTER}_DISPATCHER_ALLOW_SUPERVISOR_COEXIST=1).
- _loader.py — shared sibling-module loader; replaces the three
duplicated copies in the dispatcher entry points.
Operational hardening
- run_outer_loop tracks consecutive cycle exceptions against
cycle_failure_budget (default 5, env-tunable per driver) and
exits 2 on exhaustion for supervisor-driven restart.
- _sanitize_release_detail strips control bytes and neutralises
triple-backtick fences before quoting worker raw_response in
Forgejo claim-release comments.
- scripts/opencode-builder.sh: OPENCODE_BUILDER_SERVER_ONLY=1 keeps
only the OpenCode HTTP API up so the Python dispatchers own
queue orchestration without auto-agents running concurrently.
Telemetry
- _forgejo_cache.py schema v4: dispatch_review_cycles,
dispatch_implementer_cycles. One row per cycle with cycle_id,
driver, candidates_count, claims_acquired, swept_count,
processed_count, terminal_state, worker_outcome, session_id,
worker_wallclock_seconds, raw.
- .opencode/telemetry/server.py wires the new tables into
/api/cycles?driver=dispatch_review|dispatch_implementer and
surfaces a composite terminal_state/worker_outcome 24h breakdown
so dashboards can distinguish session-level vs work-level
outcomes.
Tests
- 31 new tests in tests/auto_agents/test_dispatch_runtime.py
covering: candidate priority/dedup, claim/release labels,
foreign-claim refusal, same-kind-claim refusal,
labels-fetch-failed terminal state, sanitization, supervisor
coexistence guard (pass/refuse/override/unreachable-server),
session timeout / transport-error propagation,
JSON-vs-no-JSON worker exits, cycle failure budget exit and
reset, heartbeat cadence, end-to-end --once --dry-run /
--status CLI smoke, and full prompt-snapshot tests for
_review_prompt and _implementation_prompt (PR-fix + issue-impl).
- test_telemetry_schema.py asserts schema v4 and the presence of
the two new dispatcher cycle tables.
338 auto_agents tests pass (was 322 before Tier 2). Conflict driver
regression suite unchanged. Dispatchers run cleanly under
--status / --once --dry-run with no Forgejo or OpenCode HTTP traffic.
Co-authored-by: Cursor <cursoragent@cursor.com>