Files
tudo-para-ia-mais-humana-pl…/src/mais_humana/governance_exports.py
2026-04-30 06:42:00 -03:00

207 lines
13 KiB
Python

"""Artifact writers for the Mais Humana governance layer."""
from __future__ import annotations
import json
from dataclasses import dataclass
from pathlib import Path
from typing import Callable, Iterable, Sequence
from .evidence_graph import EvidenceGraph, graph_dot, graph_markdown, graph_rows
from .exit_order_compiler import CompiledOrderSet, compiled_orders_markdown, order_coverage_rows, source_candidate_rows
from .governance_engine import (
EcosystemGovernancePortfolio,
compact_governance_payload,
governance_candidates_markdown,
governance_cards_csv,
governance_checks_csv,
governance_portfolio_markdown,
governance_to_plain_data,
rows_to_csv,
)
from .governance_scenarios import ScenarioPortfolio, scenario_rows, scenarios_markdown
from .human_readiness_registry import ReadinessRegistry, registry_markdown, registry_rows
from .models import GeneratedFile, as_plain_data
from .portfolio_queries import PortfolioQuestion, compact_question_payload, questions_markdown, questions_rows
from .round_assurance import AssuranceSuite, assurance_markdown, assurance_rows
from .runtime_budget import RoundLineBudget, budget_markdown, budget_rows
from .service_order_lifecycle import RoundExecutionPackage, lifecycle_audit_markdown, lifecycle_execution_markdown, lifecycle_pending_markdown, lifecycle_queue_markdown
from .workflow_registry import WorkflowPortfolio, workflow_markdown, workflow_rows
@dataclass(slots=True)
class GovernanceExport:
path: Path
description: str
function: str
file_type: str
writer: Callable[[Path], None]
@dataclass(slots=True)
class GovernanceExportBundle:
files: tuple[Path, ...]
generated_records: tuple[GeneratedFile, ...]
errors: tuple[str, ...]
def to_dict(self) -> dict[str, object]:
return {
"files": [str(path) for path in self.files],
"generated_records": [item.to_dict() for item in self.generated_records],
"errors": self.errors,
}
def write_json(path: Path, payload: object) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(json.dumps(as_plain_data(payload), ensure_ascii=False, indent=2, sort_keys=True), encoding="utf-8")
def write_text(path: Path, text: str) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text(text, encoding="utf-8")
def record_for(path: Path, project_root: Path, description: str, function: str, file_type: str, relation_to_order: str) -> GeneratedFile:
try:
rel = path.relative_to(project_root)
except ValueError:
rel = path
return GeneratedFile(
path=str(rel).replace("\\", "/"),
description=description,
function=function,
file_type=file_type,
changed_by="mais_humana.governance_exports",
change_summary=description,
relation_to_order=relation_to_order,
)
def export(
relative_path: str,
description: str,
function: str,
file_type: str,
writer: Callable[[Path], None],
root: Path,
) -> GovernanceExport:
return GovernanceExport(
path=root / relative_path,
description=description,
function=function,
file_type=file_type,
writer=writer,
)
def governance_exports(
project_root: Path,
portfolio: EcosystemGovernancePortfolio,
registry: ReadinessRegistry,
workflows: WorkflowPortfolio,
scenarios: ScenarioPortfolio,
graph: EvidenceGraph,
questions: Sequence[PortfolioQuestion],
budget: RoundLineBudget | None = None,
compiled_orders: CompiledOrderSet | None = None,
lifecycle: RoundExecutionPackage | None = None,
assurance: AssuranceSuite | None = None,
) -> tuple[GovernanceExport, ...]:
exports: list[GovernanceExport] = [
export("dados/governanca-operacional.json", "Portfolio completo de governanca operacional.", "governanca", "json", lambda path: write_json(path, governance_to_plain_data(portfolio)), project_root),
export("dados/governanca-operacional-compacta.json", "Portfolio compacto de governanca operacional.", "governanca compacta", "json", lambda path: write_json(path, compact_governance_payload(portfolio)), project_root),
export("ecossistema/GOVERNANCA-OPERACIONAL-MAIS-HUMANA.md", "Relatorio de governanca operacional.", "governanca", "markdown", lambda path: write_text(path, governance_portfolio_markdown(portfolio)), project_root),
export("ecossistema/CANDIDATAS-OS-GOVERNANCA.md", "Candidatas de OS por governanca.", "ordens candidatas", "markdown", lambda path: write_text(path, governance_candidates_markdown(portfolio)), project_root),
export("matrizes/governanca-cards.csv", "Cards de governanca em CSV.", "matriz governanca", "csv", lambda path: write_text(path, governance_cards_csv(portfolio)), project_root),
export("matrizes/governanca-checks.csv", "Checks de governanca em CSV.", "matriz governanca", "csv", lambda path: write_text(path, governance_checks_csv(portfolio)), project_root),
export("dados/registro-prontidao-humana.json", "Registro plataforma x perfil x governanca.", "registro prontidao", "json", lambda path: write_json(path, registry), project_root),
export("ecossistema/REGISTRO-PRONTIDAO-HUMANA.md", "Registro humano de prontidao por perfil.", "registro prontidao", "markdown", lambda path: write_text(path, registry_markdown(registry)), project_root),
export("matrizes/registro-prontidao-humana.csv", "Registro humano em CSV.", "registro prontidao", "csv", lambda path: write_text(path, rows_to_csv(registry_rows(registry))), project_root),
export("dados/workflows-humanos.json", "Workflows humanos em JSON.", "workflows", "json", lambda path: write_json(path, workflows), project_root),
export("ecossistema/WORKFLOWS-HUMANOS-OPERACIONAIS.md", "Workflows humanos operacionais.", "workflows", "markdown", lambda path: write_text(path, workflow_markdown(workflows)), project_root),
export("matrizes/workflows-humanos.csv", "Workflows humanos em CSV.", "workflows", "csv", lambda path: write_text(path, rows_to_csv(workflow_rows(workflows))), project_root),
export("dados/cenarios-governanca.json", "Cenarios de aceite de governanca.", "cenarios", "json", lambda path: write_json(path, scenarios), project_root),
export("ecossistema/CENARIOS-ACEITE-GOVERNANCA.md", "Cenarios de aceite de governanca.", "cenarios", "markdown", lambda path: write_text(path, scenarios_markdown(scenarios)), project_root),
export("matrizes/cenarios-governanca.csv", "Cenarios de governanca em CSV.", "cenarios", "csv", lambda path: write_text(path, rows_to_csv(scenario_rows(scenarios))), project_root),
export("dados/grafo-evidencias.json", "Grafo de evidencias em JSON.", "grafo evidencias", "json", lambda path: write_json(path, graph), project_root),
export("ecossistema/GRAFO-EVIDENCIAS-MAIS-HUMANA.md", "Grafo de evidencias em Markdown.", "grafo evidencias", "markdown", lambda path: write_text(path, graph_markdown(graph)), project_root),
export("graficos/grafo-evidencias.dot", "Grafo de evidencias em DOT.", "grafo evidencias", "dot", lambda path: write_text(path, graph_dot(graph)), project_root),
export("matrizes/grafo-evidencias.csv", "Grafo de evidencias em CSV.", "grafo evidencias", "csv", lambda path: write_text(path, rows_to_csv(graph_rows(graph))), project_root),
export("dados/perguntas-governanca.json", "Perguntas operacionais sobre governanca.", "perguntas governanca", "json", lambda path: write_json(path, compact_question_payload(questions)), project_root),
export("ecossistema/PERGUNTAS-OPERACIONAIS-GOVERNANCA.md", "Perguntas operacionais sobre governanca.", "perguntas governanca", "markdown", lambda path: write_text(path, questions_markdown(questions)), project_root),
export("matrizes/perguntas-governanca.csv", "Perguntas de governanca em CSV.", "perguntas governanca", "csv", lambda path: write_text(path, rows_to_csv(questions_rows(questions))), project_root),
]
if budget is not None:
exports.extend(
[
export("dados/budget-linhas-rodada.json", "Budget de linhas da rodada.", "budget linhas", "json", lambda path: write_json(path, budget), project_root),
export("ecossistema/BUDGET-LINHAS-RODADA.md", "Budget de linhas da rodada.", "budget linhas", "markdown", lambda path: write_text(path, budget_markdown(budget)), project_root),
export("matrizes/budget-linhas-rodada.csv", "Budget de linhas em CSV.", "budget linhas", "csv", lambda path: write_text(path, rows_to_csv(budget_rows(budget))), project_root),
]
)
if compiled_orders is not None:
exports.extend(
[
export("dados/ordens-governanca-compiladas.json", "Ordens compiladas por governanca.", "ordens compiladas", "json", lambda path: write_json(path, compiled_orders), project_root),
export("ecossistema/ORDENS-GOVERNANCA-COMPILADAS.md", "Ordens compiladas por governanca.", "ordens compiladas", "markdown", lambda path: write_text(path, compiled_orders_markdown(compiled_orders)), project_root),
export("matrizes/ordens-governanca-compiladas.csv", "Ordens compiladas em CSV.", "ordens compiladas", "csv", lambda path: write_text(path, rows_to_csv(order_coverage_rows(compiled_orders))), project_root),
export("matrizes/candidatas-governanca-usadas.csv", "Candidatas usadas em ordens compiladas.", "ordens compiladas", "csv", lambda path: write_text(path, rows_to_csv(source_candidate_rows(compiled_orders))), project_root),
]
)
if lifecycle is not None:
exports.extend(
[
export("dados/lifecycle-ordens-ativas.json", "Lifecycle de ordens ativas.", "lifecycle ordens", "json", lambda path: write_json(path, lifecycle), project_root),
export("ecossistema/LIFECYCLE-ORDENS-ATIVAS.md", "Lifecycle de ordens ativas.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_execution_markdown(lifecycle)), project_root),
export("ecossistema/PENDENCIAS-LIFECYCLE-ORDENS.md", "Pendencias do lifecycle de ordens.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_pending_markdown(lifecycle)), project_root),
export("ecossistema/AUDITORIA-LIFECYCLE-ORDENS.md", "Auditoria do lifecycle de ordens.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_audit_markdown(lifecycle)), project_root),
export("ecossistema/FILA-ATIVA-LIFECYCLE.md", "Fila ativa do lifecycle.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_queue_markdown(lifecycle)), project_root),
]
)
if assurance is not None:
exports.extend(
[
export("dados/assurance-rodada.json", "Assurance da rodada em JSON.", "assurance", "json", lambda path: write_json(path, assurance), project_root),
export("ecossistema/ASSURANCE-RODADA-MAIS-HUMANA.md", "Assurance da rodada.", "assurance", "markdown", lambda path: write_text(path, assurance_markdown(assurance)), project_root),
export("matrizes/assurance-rodada.csv", "Assurance da rodada em CSV.", "assurance", "csv", lambda path: write_text(path, rows_to_csv(assurance_rows(assurance))), project_root),
]
)
return tuple(exports)
def write_governance_exports(
project_root: Path,
exports: Sequence[GovernanceExport],
relation_to_order: str,
) -> GovernanceExportBundle:
written: list[Path] = []
records: list[GeneratedFile] = []
errors: list[str] = []
for item in exports:
try:
item.writer(item.path)
written.append(item.path)
records.append(record_for(item.path, project_root, item.description, item.function, item.file_type, relation_to_order))
except OSError as exc:
errors.append(f"{item.path}: {exc}")
return GovernanceExportBundle(files=tuple(written), generated_records=tuple(records), errors=tuple(errors))
def central_lifecycle_exports(platform_folder: Path, lifecycle: RoundExecutionPackage) -> tuple[GovernanceExport, ...]:
return (
export("reports/EXECUTADO__fechamento-ordens-ativas.md", "Fechamento das ordens ativas.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_execution_markdown(lifecycle)), platform_folder),
export("reports/PENDENCIAS-CODEX__fechamento-ordens-ativas.md", "Pendencias do fechamento das ordens.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_pending_markdown(lifecycle)), platform_folder),
export("audit/AUDITORIA-GPT__fechamento-ordens-ativas.md", "Auditoria do fechamento das ordens.", "lifecycle ordens", "markdown", lambda path: write_text(path, lifecycle_audit_markdown(lifecycle)), platform_folder),
export("current/active-order-queue.md", "Fila ativa apos rodada.", "fila ativa", "markdown", lambda path: write_text(path, lifecycle_queue_markdown(lifecycle)), platform_folder),
export("indexes/orders-lifecycle-index.md", "Indice lifecycle das ordens.", "indice ordens", "markdown", lambda path: write_text(path, lifecycle_execution_markdown(lifecycle)), platform_folder),
)
def write_central_lifecycle_exports(platform_folder: Path, lifecycle: RoundExecutionPackage) -> tuple[Path, ...]:
written: list[Path] = []
for item in central_lifecycle_exports(platform_folder, lifecycle):
item.writer(item.path)
written.append(item.path)
return tuple(written)