532 lines
22 KiB
Python
532 lines
22 KiB
Python
"""Generate the MCP control contract registry for Mais Humana.
|
|
|
|
The generated module is source code on purpose. It is the compact,
|
|
importable registry that proves which platform/profile/surface/report contracts
|
|
Mais Humana can expose through the MCP control plane without reading Markdown
|
|
at runtime.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
from typing import Iterable
|
|
|
|
|
|
ROOT = Path(__file__).resolve().parents[1]
|
|
SRC = ROOT / "src"
|
|
OUTPUT = SRC / "mais_humana" / "generated_mcp_control_contracts.py"
|
|
|
|
|
|
def ensure_import_path() -> None:
|
|
import sys
|
|
|
|
src = str(SRC)
|
|
if src not in sys.path:
|
|
sys.path.insert(0, src)
|
|
|
|
|
|
def q(value: object) -> str:
|
|
return repr(str(value))
|
|
|
|
|
|
def tuple_literal(values: Iterable[object], *, indent: int = 8) -> str:
|
|
cleaned = [str(value) for value in values if str(value).strip()]
|
|
if not cleaned:
|
|
return "()"
|
|
if len(cleaned) <= 30:
|
|
return "(" + ", ".join(q(value) for value in cleaned) + ("," if len(cleaned) == 1 else "") + ")"
|
|
pad = " " * indent
|
|
lines = ["("]
|
|
for value in cleaned:
|
|
lines.append(f"{pad}{q(value)},")
|
|
lines.append(" " * (indent - 4) + ")")
|
|
return "\n".join(lines)
|
|
|
|
|
|
def normalize(value: str) -> str:
|
|
return value.replace("_", "-").replace(" ", "-").replace("/", "-").lower()
|
|
|
|
|
|
def category_values(categories: Iterable[object]) -> tuple[str, ...]:
|
|
return tuple(getattr(category, "value", str(category)) for category in categories)
|
|
|
|
|
|
def audience_for_profile(profile_id: str, categories: tuple[str, ...]) -> str:
|
|
if profile_id in {"administrador_empresa"}:
|
|
return "ADMINISTRATOR"
|
|
if profile_id in {"ceo", "gestor_comercial"}:
|
|
return "EXECUTIVE"
|
|
if profile_id in {"gestor_operacional", "secretaria"}:
|
|
return "OPERATOR"
|
|
if profile_id in {"suporte", "atendimento_cliente"}:
|
|
return "SUPPORT"
|
|
if profile_id in {"cliente_externo"}:
|
|
return "CUSTOMER"
|
|
if profile_id in {"tecnico"}:
|
|
return "TECHNICAL"
|
|
if profile_id in {"juridico"} or "legal" in categories:
|
|
return "LEGAL"
|
|
if profile_id in {"financeiro", "contador"} or "finance" in categories:
|
|
return "FINANCE"
|
|
return "USER"
|
|
|
|
|
|
def truth_for_platform(platform_id: str) -> str:
|
|
if platform_id == "docs":
|
|
return "FORMAL_EXCEPTION"
|
|
if platform_id == "intelligence":
|
|
return "BLOCKED"
|
|
if platform_id in {"integracoes", "mcps", "identity", "business", "ui"}:
|
|
return "SAME_SOURCE_READY"
|
|
if platform_id in {"finance", "compliance", "public", "gettys", "customer_ops", "stj"}:
|
|
return "RESPONSE_READY"
|
|
return "DERIVED"
|
|
|
|
|
|
def panel_ready_for_platform(platform_id: str) -> bool:
|
|
return platform_id not in {"intelligence"}
|
|
|
|
|
|
def maturity_for_platform(platform_id: str) -> int:
|
|
if platform_id in {"mcps", "business", "identity", "ui"}:
|
|
return 9
|
|
if platform_id == "docs":
|
|
return 7
|
|
if platform_id == "intelligence":
|
|
return 3
|
|
if platform_id in {"integracoes", "finance", "compliance", "public"}:
|
|
return 8
|
|
return 6
|
|
|
|
|
|
def payload_fields(platform_id: str, profile_id: str, surface: str, category: str) -> tuple[str, ...]:
|
|
return (
|
|
"origin",
|
|
"destination",
|
|
"tool",
|
|
"payload",
|
|
"actor",
|
|
"permission",
|
|
"result",
|
|
"traceId",
|
|
"auditId",
|
|
"timestamp",
|
|
"projectId",
|
|
"platformId",
|
|
"profileId",
|
|
"surfaceId",
|
|
"category",
|
|
"sourceEndpoint",
|
|
"sourceToolId",
|
|
"sourcePayloadHash",
|
|
"sourceRecordsHash",
|
|
"truthState",
|
|
"panelReady",
|
|
"gptExplainable",
|
|
"humanNextAction",
|
|
f"{platform_id}Status",
|
|
f"{profile_id}Need",
|
|
f"{normalize(surface)}State",
|
|
f"{category}Gate",
|
|
)
|
|
|
|
|
|
def redaction_requirements(platform_id: str) -> tuple[str, ...]:
|
|
return (
|
|
"bloquear valores cfat_ brutos em qualquer artefato humano",
|
|
"permitir apenas credentialRef, tokenRef ou secretRef opacos",
|
|
"mascarar Authorization Bearer antes de persistir evidencia",
|
|
"registrar sourcePayloadHash e sourceRecordsHash sem payload sensivel bruto",
|
|
f"vincular redaction ao provider {platform_id} via MCP",
|
|
)
|
|
|
|
|
|
def validation_steps(platform_id: str, profile_id: str, surface: str, kind: str) -> tuple[str, ...]:
|
|
return (
|
|
f"chamar {platform_id} somente via tudo-para-ia-mcps-internos-plataform",
|
|
f"validar envelope MCP completo para {profile_id}",
|
|
f"comparar payload GPT e UI para {normalize(surface)}",
|
|
"confirmar sourcePayloadHash e sourceRecordsHash",
|
|
"confirmar que o resultado nao contem segredo bruto",
|
|
f"registrar evidencia do contrato {kind}",
|
|
)
|
|
|
|
|
|
def contract_block(
|
|
name: str,
|
|
*,
|
|
contract_id: str,
|
|
kind: str,
|
|
platform_id: str,
|
|
profile_id: str,
|
|
tool_id: str,
|
|
title: str,
|
|
purpose: str,
|
|
source_tool_id: str,
|
|
payload: tuple[str, ...],
|
|
truth: str,
|
|
panel_ready: bool,
|
|
gpt_explainable: bool,
|
|
report_model_id: str,
|
|
audience: str,
|
|
redaction: tuple[str, ...],
|
|
validations: tuple[str, ...],
|
|
pending: str,
|
|
order_ids: tuple[str, ...],
|
|
policy_tags: tuple[str, ...],
|
|
maturity: int,
|
|
generated_from: str,
|
|
) -> str:
|
|
return "\n".join(
|
|
[
|
|
f"{name} = McpControlContract(",
|
|
f" contract_id={q(contract_id)},",
|
|
f" kind=McpContractKind.{kind},",
|
|
f" platform_id={q(platform_id)},",
|
|
f" profile_id={q(profile_id)},",
|
|
f" tool_id={q(tool_id)},",
|
|
f" title={q(title)},",
|
|
f" purpose={q(purpose)},",
|
|
" source_endpoint=MCP_EXECUTE_ENDPOINT,",
|
|
f" source_tool_id={q(source_tool_id)},",
|
|
" required_transit_fields=MCP_TRANSIT_FIELDS,",
|
|
f" required_payload_fields={tuple_literal(payload)},",
|
|
f" truth_state=TruthState.{truth},",
|
|
f" panel_ready={panel_ready},",
|
|
f" gpt_explainable={gpt_explainable},",
|
|
f" report_model_id={q(report_model_id)},",
|
|
f" audience=AudienceClass.{audience},",
|
|
f" redaction_requirements={tuple_literal(redaction)},",
|
|
f" validation_steps={tuple_literal(validations)},",
|
|
f" pending_if_missing={q(pending)},",
|
|
f" order_ids={tuple_literal(order_ids)},",
|
|
f" policy_tags={tuple_literal(policy_tags)},",
|
|
f" maturity_level={int(maturity)},",
|
|
f" generated_from={q(generated_from)},",
|
|
")",
|
|
]
|
|
)
|
|
|
|
|
|
def build_contracts() -> tuple[list[str], list[str]]:
|
|
ensure_import_path()
|
|
from mais_humana.catalog import HUMAN_PROFILES, PLATFORMS
|
|
|
|
blocks: list[str] = []
|
|
names: list[str] = []
|
|
index = 1
|
|
|
|
for platform in PLATFORMS:
|
|
platform_categories = category_values(platform.primary_categories)
|
|
surfaces = tuple(platform.expected_surfaces or ("readiness", "evidence", "admin_ui"))
|
|
first_surface = surfaces[0]
|
|
first_category = platform_categories[0] if platform_categories else "governance"
|
|
truth = truth_for_platform(platform.platform_id)
|
|
panel_ready = panel_ready_for_platform(platform.platform_id)
|
|
maturity = maturity_for_platform(platform.platform_id)
|
|
for profile in HUMAN_PROFILES:
|
|
profile_categories = category_values(profile.priority_needs)
|
|
common = tuple(value for value in platform_categories if value in profile_categories)
|
|
category = common[0] if common else first_category
|
|
audience = audience_for_profile(profile.profile_id, profile_categories)
|
|
name = f"CONTRACT_{index:04d}"
|
|
names.append(name)
|
|
blocks.append(
|
|
contract_block(
|
|
name,
|
|
contract_id=f"{platform.platform_id}.{profile.profile_id}.provider-tool",
|
|
kind="PROVIDER_TOOL",
|
|
platform_id=platform.platform_id,
|
|
profile_id=profile.profile_id,
|
|
tool_id=f"mais_humana.{platform.platform_id}.{profile.profile_id}.explain",
|
|
title=f"{platform.title} explicado para {profile.name}",
|
|
purpose=(
|
|
f"Permitir que {profile.name} receba leitura humana de {platform.title} "
|
|
"por provider MCP minimo da Mais Humana."
|
|
),
|
|
source_tool_id="mais_humana.rulebook.compact",
|
|
payload=payload_fields(platform.platform_id, profile.profile_id, first_surface, category),
|
|
truth=truth,
|
|
panel_ready=panel_ready,
|
|
gpt_explainable=True,
|
|
report_model_id=f"report.{platform.platform_id}.{profile.profile_id}.operacional",
|
|
audience=audience,
|
|
redaction=redaction_requirements(platform.platform_id),
|
|
validations=validation_steps(platform.platform_id, profile.profile_id, first_surface, "provider_tool"),
|
|
pending=f"publicar e validar tool MCP para {platform.platform_id}/{profile.profile_id}",
|
|
order_ids=("0016_EXECUTIVA__publicar-rulebook-mcp-provider-mais-humana", "0029_GERENCIAL__pactuar-mcp-como-caminho-unico-administrativo"),
|
|
policy_tags=("mcp_provider", "same_source", "human_explanation", category),
|
|
maturity=maturity,
|
|
generated_from="platform_profile_provider_contract",
|
|
)
|
|
)
|
|
index += 1
|
|
|
|
for profile in HUMAN_PROFILES:
|
|
profile_categories = category_values(profile.priority_needs)
|
|
category = platform_categories[0] if platform_categories else "governance"
|
|
audience = audience_for_profile(profile.profile_id, profile_categories)
|
|
name = f"CONTRACT_{index:04d}"
|
|
names.append(name)
|
|
blocks.append(
|
|
contract_block(
|
|
name,
|
|
contract_id=f"{platform.platform_id}.{profile.profile_id}.report-model",
|
|
kind="REPORT_MODEL",
|
|
platform_id=platform.platform_id,
|
|
profile_id=profile.profile_id,
|
|
tool_id="mais_humana.relatorios.modelos_oficiais",
|
|
title=f"Modelo oficial de relatorio {platform.title} para {profile.name}",
|
|
purpose=(
|
|
f"Definir modelo oficial que separa artefato de apoio de relatorio oficial para {profile.name}."
|
|
),
|
|
source_tool_id="mais_humana.relatorios.modelos_oficiais",
|
|
payload=payload_fields(platform.platform_id, profile.profile_id, "relatorio-oficial", category),
|
|
truth=truth,
|
|
panel_ready=panel_ready,
|
|
gpt_explainable=True,
|
|
report_model_id=f"report.{platform.platform_id}.{profile.profile_id}.oficial",
|
|
audience=audience,
|
|
redaction=redaction_requirements(platform.platform_id),
|
|
validations=validation_steps(platform.platform_id, profile.profile_id, "relatorio-oficial", "report_model"),
|
|
pending=f"homologar modelo oficial de relatorio para {platform.platform_id}/{profile.profile_id}",
|
|
order_ids=("0030_GERENCIAL__definir-modelo-oficial-de-relatorio-humano",),
|
|
policy_tags=("report_model", "official_report", "audience", audience.lower()),
|
|
maturity=maturity,
|
|
generated_from="platform_profile_report_model_contract",
|
|
)
|
|
)
|
|
index += 1
|
|
|
|
for surface in surfaces:
|
|
surface_id = normalize(surface)
|
|
name = f"CONTRACT_{index:04d}"
|
|
names.append(name)
|
|
blocks.append(
|
|
contract_block(
|
|
name,
|
|
contract_id=f"{platform.platform_id}.{surface_id}.ui-screen",
|
|
kind="UI_SCREEN",
|
|
platform_id=platform.platform_id,
|
|
profile_id="todos",
|
|
tool_id="mais_humana.admin_ui.same_source",
|
|
title=f"Tela {surface} de {platform.title} renderizada pela UI",
|
|
purpose=(
|
|
f"Impedir fonte paralela na tela {surface}; GPT e painel devem usar o mesmo contrato MCP."
|
|
),
|
|
source_tool_id="mais_humana.admin_ui.same_source",
|
|
payload=payload_fields(platform.platform_id, "todos", surface, first_category),
|
|
truth=truth,
|
|
panel_ready=panel_ready,
|
|
gpt_explainable=True,
|
|
report_model_id=f"screen.{platform.platform_id}.{surface_id}.same-source",
|
|
audience="ADMINISTRATOR",
|
|
redaction=redaction_requirements(platform.platform_id),
|
|
validations=validation_steps(platform.platform_id, "todos", surface, "ui_screen"),
|
|
pending=f"validar same-source da tela {surface} em {platform.platform_id}",
|
|
order_ids=("0020_EXECUTIVA__validar-mcp-admin-ui-same-source-rulebook", "0031_GERENCIAL__governar-ui-como-renderizador-sem-fonte-paralela"),
|
|
policy_tags=("ui_renderer", "screen", "same_source", surface_id),
|
|
maturity=maturity,
|
|
generated_from="platform_surface_ui_contract",
|
|
)
|
|
)
|
|
index += 1
|
|
|
|
for operation in ("consulta", "diagnostico", "acao", "auditoria", "explicacao"):
|
|
name = f"CONTRACT_{index:04d}"
|
|
names.append(name)
|
|
blocks.append(
|
|
contract_block(
|
|
name,
|
|
contract_id=f"{platform.platform_id}.{operation}.transit-policy",
|
|
kind="TRANSIT_POLICY",
|
|
platform_id=platform.platform_id,
|
|
profile_id="todos",
|
|
tool_id=f"mais_humana.transito.{operation}",
|
|
title=f"Politica de transito {operation} para {platform.title}",
|
|
purpose=(
|
|
f"Garantir que {operation} de {platform.title} registre origem, destino, tool, ator, permissao, resultado, trace, audit e timestamp."
|
|
),
|
|
source_tool_id=f"mais_humana.transito.{operation}",
|
|
payload=payload_fields(platform.platform_id, "todos", operation, first_category),
|
|
truth=truth,
|
|
panel_ready=panel_ready,
|
|
gpt_explainable=True,
|
|
report_model_id=f"policy.{platform.platform_id}.{operation}.mcp-transit",
|
|
audience="ADMINISTRATOR",
|
|
redaction=redaction_requirements(platform.platform_id),
|
|
validations=validation_steps(platform.platform_id, "todos", operation, "transit_policy"),
|
|
pending=f"validar politica MCP de {operation} para {platform.platform_id}",
|
|
order_ids=("0029_GERENCIAL__pactuar-mcp-como-caminho-unico-administrativo",),
|
|
policy_tags=("mcp_transit", operation, "audit", "trace"),
|
|
maturity=maturity,
|
|
generated_from="platform_transit_policy_contract",
|
|
)
|
|
)
|
|
index += 1
|
|
|
|
for ref_kind in ("credentialRef", "tokenRef", "secretRef", "cfat"):
|
|
name = f"CONTRACT_{index:04d}"
|
|
names.append(name)
|
|
blocks.append(
|
|
contract_block(
|
|
name,
|
|
contract_id=f"{platform.platform_id}.{normalize(ref_kind)}.redaction-policy",
|
|
kind="REDACTION_POLICY",
|
|
platform_id=platform.platform_id,
|
|
profile_id="todos",
|
|
tool_id="mais_humana.redaction.guard",
|
|
title=f"Redaction {ref_kind} para {platform.title}",
|
|
purpose=(
|
|
f"Provar que artefatos humanos de {platform.title} nao propagam valor sensivel bruto de {ref_kind}."
|
|
),
|
|
source_tool_id="mais_humana.redaction.guard",
|
|
payload=payload_fields(platform.platform_id, "todos", ref_kind, "security"),
|
|
truth=truth,
|
|
panel_ready=True,
|
|
gpt_explainable=True,
|
|
report_model_id=f"redaction.{platform.platform_id}.{normalize(ref_kind)}",
|
|
audience="TECHNICAL",
|
|
redaction=redaction_requirements(platform.platform_id) + (f"validar {ref_kind} como referencia opaca",),
|
|
validations=validation_steps(platform.platform_id, "todos", ref_kind, "redaction_policy"),
|
|
pending=f"executar varredura redaction para {platform.platform_id}/{ref_kind}",
|
|
order_ids=("0019_EXECUTIVA__blindar-redaction-credentialref-e-cfat-em-artefatos",),
|
|
policy_tags=("redaction", "secret_policy", normalize(ref_kind)),
|
|
maturity=max(6, maturity),
|
|
generated_from="platform_redaction_policy_contract",
|
|
)
|
|
)
|
|
index += 1
|
|
|
|
special_contracts = [
|
|
(
|
|
"docs.formal-exception.docs-catalogonly",
|
|
"DOCS_EXCEPTION",
|
|
"docs",
|
|
"todos",
|
|
"mais_humana.docs.formal_exception",
|
|
"Excecao formal Docs catalogOnly",
|
|
"Formalizar que Docs pode permanecer catalogOnly quando a decisao institucional assim declarar.",
|
|
"mais_humana.docs.formal_exception",
|
|
"docs-catalogonly",
|
|
"documentation",
|
|
"FORMAL_EXCEPTION",
|
|
True,
|
|
True,
|
|
"policy.docs.catalogonly.formal-exception",
|
|
"LEGAL",
|
|
("0017_EXECUTIVA__resolver-docs-catalogonly-com-response-ready-minimo",),
|
|
("docs_exception", "catalogonly", "governance"),
|
|
7,
|
|
),
|
|
(
|
|
"mais-humana.canonical-rename.plataform",
|
|
"CANONICAL_RENAME",
|
|
"mais_humana",
|
|
"todos",
|
|
"mais_humana.canonical.rename",
|
|
"Renome canonico para tudo-para-ia-mais-humana-plataform",
|
|
"Registrar o plano de renome sem executar migracao local/remota sem autorizacao institucional.",
|
|
"mais_humana.canonical.rename",
|
|
"canonical-rename",
|
|
"governance",
|
|
"DOCUMENTED",
|
|
True,
|
|
True,
|
|
"policy.mais_humana.rename.plataform",
|
|
"ADMINISTRATOR",
|
|
("0027_GERENCIAL__nome-canonico-mcps-conect", "0028_GERENCIAL__autorizar-renome-canonico-mais-humana-plataform"),
|
|
("canonical_identity", "rename", "external_decision"),
|
|
6,
|
|
),
|
|
]
|
|
for special in special_contracts:
|
|
(
|
|
contract_id,
|
|
kind,
|
|
platform_id,
|
|
profile_id,
|
|
tool_id,
|
|
title,
|
|
purpose,
|
|
source_tool_id,
|
|
surface,
|
|
category,
|
|
truth,
|
|
panel_ready,
|
|
gpt_explainable,
|
|
report_model_id,
|
|
audience,
|
|
order_ids,
|
|
tags,
|
|
maturity,
|
|
) = special
|
|
name = f"CONTRACT_{index:04d}"
|
|
names.append(name)
|
|
blocks.append(
|
|
contract_block(
|
|
name,
|
|
contract_id=contract_id,
|
|
kind=kind,
|
|
platform_id=platform_id,
|
|
profile_id=profile_id,
|
|
tool_id=tool_id,
|
|
title=title,
|
|
purpose=purpose,
|
|
source_tool_id=source_tool_id,
|
|
payload=payload_fields(platform_id, profile_id, surface, category),
|
|
truth=truth,
|
|
panel_ready=panel_ready,
|
|
gpt_explainable=gpt_explainable,
|
|
report_model_id=report_model_id,
|
|
audience=audience,
|
|
redaction=redaction_requirements(platform_id),
|
|
validations=validation_steps(platform_id, profile_id, surface, kind.lower()),
|
|
pending=f"registrar decisao institucional para {contract_id}",
|
|
order_ids=order_ids,
|
|
policy_tags=tags,
|
|
maturity=maturity,
|
|
generated_from="special_governance_contract",
|
|
)
|
|
)
|
|
index += 1
|
|
|
|
return blocks, names
|
|
|
|
|
|
def render_module(blocks: list[str], names: list[str]) -> str:
|
|
header = '''"""Generated MCP control contracts for Mais Humana.
|
|
|
|
Do not edit this file by hand. Regenerate it with:
|
|
|
|
python tools/generate_mcp_control_contracts.py
|
|
|
|
The contracts are Python source so they can be imported, tested, packaged,
|
|
hashed, and exposed as a provider payload without parsing external YAML.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from .human_rulebook import MCP_TRANSIT_FIELDS, TruthState
|
|
from .mcp_contract import AudienceClass, MCP_EXECUTE_ENDPOINT, McpContractKind, McpControlContract
|
|
|
|
'''
|
|
assignments = "\n\n".join(blocks)
|
|
contract_lines = ["CONTRACTS = ("]
|
|
for name in names:
|
|
contract_lines.append(f" {name},")
|
|
contract_lines.append(")")
|
|
all_lines = ["__all__ = [", " 'CONTRACTS',", "]"]
|
|
return header + assignments + "\n\n" + "\n".join(contract_lines) + "\n\n" + "\n".join(all_lines) + "\n"
|
|
|
|
|
|
def main() -> int:
|
|
blocks, names = build_contracts()
|
|
OUTPUT.write_text(render_module(blocks, names), encoding="utf-8")
|
|
print(f"generated {len(names)} MCP contracts at {OUTPUT}")
|
|
return 0
|
|
|
|
|
|
if __name__ == "__main__":
|
|
raise SystemExit(main())
|