mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
* [W7] Add possibilities_matrix_enabled feature flag (default off) * [W7] Add _work_appears_done predicate (status+commits+PR+ACs+no-open-findings) * [W7] Add CI-green quality proxy for the fast path (local fallback on no-CI) * [W7] Add work-already-done fast path in i_am_done (slimmed gates, no rich plan) * [W7] Add WORK_ALREADY_DONE prompt state * [W7] Make fast path mypy-clean (cast to helpers for _resolve_ci_status; typed mock locals) * [W7] Extract _all_criteria_addressed to bring _work_appears_done under xenon B --------- Co-authored-by: Renn F <rennf93@users.noreply.github.com>
159 lines
4.6 KiB
Python
159 lines
4.6 KiB
Python
"""Typed stub mixins inherit from for static analysis.
|
|
|
|
The role mixins (`board.py`, `doc.py`, `qa.py`, …) call methods like
|
|
``self.task.get(...)`` and ``self._emit_rejection(...)`` that live on
|
|
the legacy ``Choreographer`` class in ``_impl.py``. Without a typed
|
|
reference, mypy resolves those as ``Any`` (via ``# type: ignore[attr-defined]``)
|
|
which then bubbles up as ``no-any-return`` errors at every Envelope-returning
|
|
verb.
|
|
|
|
This module gives mypy a typed view of those helpers. ``ChoreographerHelpers``
|
|
is **not** a Protocol — Protocol with abstract members causes the
|
|
composed ``Choreographer`` class to be flagged as instantiating an
|
|
abstract class. Instead it's a plain class with stub signatures used
|
|
ONLY under ``TYPE_CHECKING``; at runtime mixins inherit from ``object``
|
|
so there's no abstract-method baggage. The real implementations live
|
|
on ``_LegacyChoreographer`` and are picked up by Python's MRO when the
|
|
composed ``Choreographer`` runs.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from typing import TYPE_CHECKING, Any
|
|
|
|
if TYPE_CHECKING:
|
|
from uuid import UUID
|
|
|
|
from roboco.services.gateway.choreographer._verb_runner import VerbRunner
|
|
from roboco.services.gateway.envelope import Envelope
|
|
|
|
|
|
class ChoreographerHelpers:
|
|
"""Typed stub of attributes + helpers role mixins call on ``self``.
|
|
|
|
Stub bodies (``...``) are never executed; the real methods live on
|
|
``_LegacyChoreographer`` and resolve via MRO at runtime.
|
|
"""
|
|
|
|
task: Any
|
|
work_session: Any
|
|
git: Any
|
|
a2a: Any
|
|
journal: Any
|
|
audit: Any
|
|
evidence_repo: Any
|
|
|
|
async def _emit_rejection(
|
|
self,
|
|
env: Envelope,
|
|
*,
|
|
agent_id: UUID,
|
|
task_id: UUID | None,
|
|
verb: str,
|
|
) -> Envelope:
|
|
raise NotImplementedError
|
|
|
|
async def _teardown_sandbox_best_effort(self, agent_id: UUID) -> None:
|
|
raise NotImplementedError
|
|
|
|
async def _toolchain_broken_guard(
|
|
self, agent_id: UUID, task: Any, *, reviewer: bool = False
|
|
) -> Envelope | None:
|
|
raise NotImplementedError
|
|
|
|
async def _conventions_guard(
|
|
self,
|
|
agent_id: UUID,
|
|
task: Any,
|
|
briefing: dict[str, Any],
|
|
preferred_parent: str | None = None,
|
|
) -> Envelope | None:
|
|
raise NotImplementedError
|
|
|
|
@classmethod
|
|
def _free_text_soup(
|
|
cls, checks: tuple[tuple[str, Any, int], ...]
|
|
) -> Envelope | None:
|
|
raise NotImplementedError
|
|
|
|
@staticmethod
|
|
def _soup_or_decision_env(
|
|
soup: Envelope | None, decision: Any, briefing: dict[str, Any]
|
|
) -> Envelope | None:
|
|
raise NotImplementedError
|
|
|
|
async def _guard_free_text(
|
|
self,
|
|
*,
|
|
checks: tuple[tuple[str, Any, int], ...],
|
|
task: Any,
|
|
agent_id: UUID,
|
|
role_str: str,
|
|
verb: str,
|
|
) -> Envelope | None:
|
|
raise NotImplementedError
|
|
|
|
async def _briefing_for(
|
|
self,
|
|
agent_id: UUID,
|
|
task_id: UUID | None,
|
|
*,
|
|
task: Any | None = None,
|
|
include_ac_coverage: bool = False,
|
|
full: bool = False,
|
|
include_company_goals: bool = False,
|
|
) -> dict[str, Any]:
|
|
raise NotImplementedError
|
|
|
|
async def _project_slug_for(self, t: Any) -> str | None:
|
|
raise NotImplementedError
|
|
|
|
@staticmethod
|
|
def _with_briefing(
|
|
env: Envelope,
|
|
briefing: dict[str, Any],
|
|
) -> Envelope:
|
|
raise NotImplementedError
|
|
|
|
async def _run_claim_guards(
|
|
self,
|
|
*,
|
|
agent_id: UUID,
|
|
task: Any,
|
|
role_str: str | None = None,
|
|
skip_dev_guards: bool = False,
|
|
) -> Envelope | None:
|
|
raise NotImplementedError
|
|
|
|
async def _touch(self, task_id: UUID | None) -> None:
|
|
raise NotImplementedError
|
|
|
|
def _verb_runner(self) -> VerbRunner:
|
|
raise NotImplementedError
|
|
|
|
async def _build_tracing_gap(
|
|
self,
|
|
agent_id: UUID,
|
|
task_id: UUID,
|
|
missing: list[str],
|
|
*,
|
|
task: Any | None = None,
|
|
) -> Envelope:
|
|
raise NotImplementedError
|
|
|
|
async def _resolve_ci_status(self, task_id: UUID, t: Any) -> dict[str, Any] | None:
|
|
raise NotImplementedError
|
|
|
|
|
|
def actor_context_fields(agent: Any) -> tuple[str | None, str | None]:
|
|
"""``(actor_slug, agent_team)`` for a spec ``Context``, None-agent safe.
|
|
|
|
Every verb builds its policy Context with the same two conditional
|
|
kwargs; inlining them pushed nine verbs over the xenon B threshold when
|
|
the team-match sweep added ``agent_team`` to all 27 sites.
|
|
"""
|
|
if agent is None:
|
|
return None, None
|
|
team = getattr(agent, "team", None)
|
|
return getattr(agent, "slug", None), str(team) if team else None
|