"""Generate operational playbooks oriented to human roles.""" from __future__ import annotations from dataclasses import dataclass from typing import Sequence from .catalog import HUMAN_PROFILES, PROFILE_BY_ID from .models import PlatformHumanReport, Recommendation, as_plain_data @dataclass(slots=True) class PlaybookStep: step_id: str title: str action: str evidence_needed: str done_when: str def to_dict(self) -> dict[str, object]: return as_plain_data(self) @dataclass(slots=True) class HumanPlaybook: playbook_id: str profile_id: str title: str purpose: str steps: tuple[PlaybookStep, ...] def to_dict(self) -> dict[str, object]: return as_plain_data(self) def step_from_recommendation(profile_id: str, recommendation: Recommendation, index: int) -> PlaybookStep: return PlaybookStep( step_id=f"{profile_id}-{recommendation.platform_id}-{index}", title=recommendation.title, action=recommendation.reason, evidence_needed=", ".join(recommendation.validation_steps or ("validacao operacional",)), done_when=recommendation.expected_impact, ) def build_playbook_for_profile(profile_id: str, reports: Sequence[PlatformHumanReport]) -> HumanPlaybook: profile = PROFILE_BY_ID[profile_id] candidate_recommendations: list[Recommendation] = [] for report in reports: profile_cells = [cell for cell in report.cells if cell.profile_id == profile_id] weak = profile_cells and profile_cells[0].score < 70 if profile_id in report.platform.expected_profiles or weak: candidate_recommendations.extend(report.recommendations[:3]) if not candidate_recommendations: for report in reports[:3]: candidate_recommendations.extend(report.recommendations[:1]) candidate_recommendations.sort(key=lambda item: (-item.priority, item.platform_id)) steps = tuple( step_from_recommendation(profile_id, recommendation, index) for index, recommendation in enumerate(candidate_recommendations[:8], start=1) ) return HumanPlaybook( playbook_id=f"playbook-{profile_id}", profile_id=profile_id, title=f"Playbook humano - {profile.name}", purpose=( f"Orientar {profile.name} a interpretar estado, evidencias e proximas acoes " "sem depender de leitura direta do codigo." ), steps=steps, ) def build_playbooks(reports: Sequence[PlatformHumanReport]) -> tuple[HumanPlaybook, ...]: return tuple(build_playbook_for_profile(profile.profile_id, reports) for profile in HUMAN_PROFILES) def playbooks_markdown(playbooks: Sequence[HumanPlaybook]) -> str: lines = ["# Playbooks humanos", ""] for playbook in playbooks: lines.append(f"## {playbook.title}") lines.append("") lines.append(playbook.purpose) lines.append("") for step in playbook.steps: lines.append(f"### {step.title}") lines.append("") lines.append(f"- acao: {step.action}") lines.append(f"- evidencia necessaria: {step.evidence_needed}") lines.append(f"- pronto quando: {step.done_when}") lines.append("") return "\n".join(lines).strip() + "\n" def playbook_summary(playbooks: Sequence[HumanPlaybook]) -> dict[str, int]: return {playbook.profile_id: len(playbook.steps) for playbook in playbooks}