Files
cleveragents-core/tools
drew 3e269ce011 feat(controller): Phase 1j — deterministic CI summarizer + priority parsers
Replaces "ci_summary=None / failing_gates=[]" placeholders from Phase
1h with a real summarizer that maps Forgejo combined-status →
CISummary V1 dict by running per-tool deterministic parsers on each
failing gate's log.

Priority parsers shipped (cover lint/format/typecheck/unit_tests, the
4 most-failed gates):
- ruff      — F+E codes from `nox -s lint`; Would-reformat lines from
              `nox -s format`. Aggregates to single error_class when
              all findings share one code, else RuffMixed.
- pyright   — error/warning/information diagnostics; rule name pulled
              from trailing `(reportName)` parens. Abs-path
              normalization strips container prefixes.
- behave    — failing scenarios (file:line + name), AssertionError
              extraction. Feature/scenario summary line aggregation.

Stub parsers for not-yet-shipped tools (robot_framework, slipcover,
bandit, semgrep, vulture, radon, build): return a structured
CIFailure with error_class="parser-pending-{name}" + the raw log
excerpt. Operators see the failure; implementer still has log
context. Phase 1j+ replaces stubs with real parsers without changing
the gate-→-session map.

Components:
- _base.py        — ParserResult dataclass + select_log_excerpt()
                    (tail-N-lines smart selection within 16KB cap)
- _stub.py        — make_stub(name) factory for pending tools
- _registry.py    — resolve(parser_name) + resolve_for_nox_session()
                    + validate_parser_coverage()
- master/ci_summarize.py — summarize_ci_status(head_sha, status,
                    log_fetcher) orchestrator. Handles:
                    - composite multi: gates → CIFailure.composite_findings
                    - log_fetcher returning None → log-fetch-failed
                    - log_fetcher raising → caught + log-fetch-failed
                    - Unknown gate context → NoParserAvailable
                    - Forgejo state=None → unknown summary
                    - Parameterized matrix gates ("unit_tests-3.13")
                      → base session name resolution

Tests (+46 across 2 new files, 0 regressions):
- Per-parser canonical + empty + garbage input
- Registry resolution (real vs stub), coverage validator
- Summarizer V1 contract round-trip
- Composite security_scan composite_findings shape
- Error paths (None status, raising fetcher, unknown gate)
- Parser version aggregation across mixed gates

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-18 14:40:16 -04:00
..