207 lines
13 KiB
Python
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)
|