"""Governance check catalog for the Mais Humana platform.

The catalog is intentionally declarative.  Each check is a small operational
contract that can be evaluated against a repository scan, a human report, and a
round dossier.  The checks are not meant to replace project-specific tests.
They create a common language for deciding whether a platform is merely
technical, actually explainable to people, ready for the panel/GPT same-source
model, or blocked by an external/credential/decision dependency.
"""

from __future__ import annotations

from typing import Iterable

from .governance_models import (
    CheckTemplate,
    GovernanceAxis,
    GovernanceDomain,
    GovernanceSeverity,
)
from .models import OrderType


def check(
    check_id: str,
    axis: GovernanceAxis,
    domain: GovernanceDomain,
    title: str,
    purpose: str,
    positive_terms: Iterable[str],
    negative_terms: Iterable[str],
    required_terms: Iterable[str],
    evidence_hints: Iterable[str],
    applies_to: Iterable[str],
    not_applicable_reason: str,
    pass_summary: str,
    attention_summary: str,
    fail_summary: str,
    suggested_action: str,
    validation_steps: Iterable[str],
    severity: GovernanceSeverity = GovernanceSeverity.MEDIUM,
    required_for_human_ready: bool = False,
    creates_order_type: OrderType = OrderType.MANAGERIAL,
    order_title: str = "",
    order_priority: str = "media",
) -> CheckTemplate:
    return CheckTemplate(
        check_id=check_id,
        axis=axis,
        domain=domain,
        title=title,
        purpose=purpose,
        positive_terms=tuple(positive_terms),
        negative_terms=tuple(negative_terms),
        required_terms=tuple(required_terms),
        evidence_hints=tuple(evidence_hints),
        applies_to=tuple(applies_to),
        not_applicable_reason=not_applicable_reason,
        pass_summary=pass_summary,
        attention_summary=attention_summary,
        fail_summary=fail_summary,
        suggested_action=suggested_action,
        validation_steps=tuple(validation_steps),
        severity=severity,
        required_for_human_ready=required_for_human_ready,
        creates_order_type=creates_order_type,
        order_title=order_title,
        order_priority=order_priority,
    )


ALL_PLATFORMS = (
    "business",
    "compliance",
    "customer_ops",
    "docs",
    "finance",
    "gettys",
    "identity",
    "integracoes",
    "intelligence",
    "mcps",
    "platform_base",
    "public",
    "stj",
    "ui",
)


CORE_PLATFORMS = ("business", "identity", "integracoes", "docs", "mcps", "ui")
SELLABLE_PLATFORMS = ("business", "integracoes", "stj", "public", "finance")
SUPPORT_PLATFORMS = ("customer_ops", "integracoes", "business", "identity", "compliance")
DOCS_RELATED = ("docs", "mcps", "ui", "platform_base", "compliance", "public")
CLOUD_RELATED = ("integracoes", "mcps", "ui", "public", "gettys", "stj")


CHECK_TEMPLATES: tuple[CheckTemplate, ...] = (
    check(
        "repository.exists",
        GovernanceAxis.LOCAL_TRACEABILITY,
        GovernanceDomain.REPOSITORY,
        "Repositorio local existe",
        "Confirma que ha espelho local para leitura material antes de gerar avaliacao humana.",
        ("repositorio real encontrado", "repo.exists", "git local", "readme"),
        ("repositorio real nao encontrado", "caminho nao encontrado", "not_found"),
        ("repo_path",),
        ("repo_path", "README.md", ".git"),
        ALL_PLATFORMS,
        "A plataforma nao faz parte do catalogo operacional desta rodada.",
        "Repositorio local foi encontrado e pode ser analisado.",
        "Repositorio existe, mas ainda precisa de evidencias complementares.",
        "Repositorio local nao foi encontrado; nao ha base material suficiente.",
        "criar ou clonar o repositorio real sem numero da pasta gerencial",
        ("verificar caminho local", "confirmar .git", "registrar hash final"),
        GovernanceSeverity.CRITICAL,
        True,
        OrderType.EXECUTIVE,
        "Criar ou recuperar espelho local do repositorio real",
        "alta",
    ),
    check(
        "repository.git-traceability",
        GovernanceAxis.LOCAL_TRACEABILITY,
        GovernanceDomain.REPOSITORY,
        "Git local e remoto rastreaveis",
        "Garante que a rodada possa informar status, commit, push e hash final.",
        ("git local detectado", "remote_origin", "branch", "head"),
        ("sem .git", "git local nao detectado", "dubious ownership", "index.lock"),
        ("branch", "head"),
        (".git", "git status", "remote"),
        ALL_PLATFORMS,
        "A plataforma nao possui repositorio operacional nesta leitura.",
        "Git local foi detectado e possui metadados uteis.",
        "Git existe parcialmente ou requer validacao de remote/branch.",
        "Git local esta ausente ou inacessivel para fechamento da OS.",
        "corrigir permissao, safe.directory ou inicializar Git com origin correto",
        ("git status --short --branch", "git remote -v", "git rev-parse HEAD"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Restaurar rastreabilidade Git e sincronizacao",
        "alta",
    ),
    check(
        "documentation.human-readme",
        GovernanceAxis.HUMAN_DOCUMENTATION,
        GovernanceDomain.DOCUMENTATION,
        "README tecnico-humano minimo",
        "Verifica se a plataforma explica missao, comandos e criterio humano sem exigir leitura do codigo.",
        ("readme tecnico", "missao", "execucao", "validacao", "papel no ecossistema"),
        ("readme tecnico nao encontrado", "sem documentacao inicial"),
        ("readme",),
        ("README.md", "docs/README.md"),
        ALL_PLATFORMS,
        "A plataforma nao precisa expor README separado neste contexto.",
        "README ou documentacao principal foi encontrada.",
        "README existe, mas precisa explicitar comandos, pessoas e evidencias.",
        "README tecnico-humano nao foi encontrado.",
        "criar README com missao, comandos, validacoes, relacao MCP e criterio de pronto",
        ("abrir README", "conferir comandos", "comparar com reports gerados"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Criar README tecnico-humano reconciliado",
    ),
    check(
        "documentation.runbook",
        GovernanceAxis.HUMAN_DOCUMENTATION,
        GovernanceDomain.DOCUMENTATION,
        "Runbook operacional para humanos",
        "Confirma que suporte, tecnico e gestor possuem proxima acao operacional clara.",
        ("runbook", "playbook", "proxima acao", "diagnostico", "comandos humanos"),
        ("sem runbook", "sem proxima acao", "erro bruto"),
        (),
        ("runbook", "COMANDOS-HUMANOS-EQUIVALENTES", "playbooks"),
        ALL_PLATFORMS,
        "Nao ha runbook esperado para esta plataforma.",
        "Runbook ou playbook operacional foi detectado.",
        "Ha sinais de operacao, mas sem runbook humano completo.",
        "A plataforma nao oferece caminho operacional claro para humanos.",
        "criar playbook por perfil com diagnostico, acao, evidencia e limite seguro",
        ("validar playbook", "executar comando de smoke", "registrar evidencia"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Consolidar runbooks e comandos humanos equivalentes",
    ),
    check(
        "contract.openapi-or-equivalent",
        GovernanceAxis.CONTRACT_VERSIONING,
        GovernanceDomain.CONTRACT,
        "Contrato OpenAPI ou equivalente",
        "Evita que painel, GPT e suporte dependam de implementacao implícita sem contrato audivel.",
        ("openapi", "swagger", "schema", "contract", "contrato", "surfaceVersion"),
        ("openapi nao encontrado", "sem contrato", "contract missing"),
        (),
        ("openapi.json", "schema", "contract"),
        ALL_PLATFORMS,
        "Esta plataforma nao expoe API ou surface operacional nesta etapa.",
        "Contrato ou schema auditavel foi detectado.",
        "Contrato existe parcialmente ou precisa de versionamento.",
        "Contrato OpenAPI/equivalente nao foi encontrado.",
        "publicar contrato minimo versionado ou declarar contrato alternativo na central",
        ("validar JSON/schema", "comparar rotas", "registrar contractVersion"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Publicar contrato operacional versionado",
    ),
    check(
        "contract.version-policy",
        GovernanceAxis.CONTRACT_VERSIONING,
        GovernanceDomain.CONTRACT,
        "Politica de versao e compatibilidade",
        "Garante que alteracoes futuras tenham schemaVersion, deprecacao e migracao controlada.",
        ("schemaVersion", "contractVersion", "compatibilityVersion", "deprecated", "migration"),
        ("breaking change sem registro", "sem versionamento", "versao ausente"),
        ("version",),
        ("contractVersion", "schemaVersion", "migrationNotes"),
        ALL_PLATFORMS,
        "Nao ha contrato vivo nesta plataforma ainda.",
        "Versionamento de contrato aparece na evidencia.",
        "Ha contrato, mas a politica de compatibilidade ainda precisa ser formalizada.",
        "Sem versionamento, a plataforma acumula risco de regressao silenciosa.",
        "criar politica de versionamento, deprecacao, substituicao e notas de migracao",
        ("exportar contrato", "validar versao", "registrar breakingChanges"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Formalizar politica de versao e compatibilidade",
    ),
    check(
        "tests.detected",
        GovernanceAxis.TESTABLE_BEHAVIOR,
        GovernanceDomain.TESTS,
        "Testes ou smoke detectaveis",
        "Confirma que a plataforma possui validacao automatizada ou smoke local rastreavel.",
        ("test", "spec", "smoke", "unittest", "vitest", "pytest", "node --test"),
        ("testes nao encontrados", "sem teste", "no tests"),
        (),
        ("tests", "test.spec", "package.json", "pyproject.toml"),
        ALL_PLATFORMS,
        "Esta plataforma ainda esta somente planejada.",
        "Teste ou smoke detectavel foi encontrado.",
        "Ha sinais de teste, mas falta suite canonica do contrato humano.",
        "Nenhum teste/smoke detectavel foi encontrado.",
        "criar smoke canonico para health, readiness, contrato e relatorio humano",
        ("executar suite", "registrar saida", "incluir comando em README"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Criar testes canonicos de prontidao humana",
    ),
    check(
        "tests.regression",
        GovernanceAxis.TESTABLE_BEHAVIOR,
        GovernanceDomain.TESTS,
        "Regressao de contrato e painel",
        "Detecta se uma plataforma que era panelReady ou sameSource perdeu prontidao.",
        ("regression", "snapshot", "delta", "sameSource", "panelReady", "sourceHash"),
        ("regressao sem alerta", "perdeu panelReady", "mismatch"),
        (),
        ("snapshot", "DELTA-MATURIDADE", "quality-gates"),
        CORE_PLATFORMS,
        "Regressao de painel nao se aplica a plataforma fora do nucleo de surfaces.",
        "Sinais de regressao e snapshot foram encontrados.",
        "Snapshots existem, mas precisam virar falha automatica quando houver divergencia.",
        "Nao ha mecanismo claro de regressao para contrato/painel.",
        "criar teste de regressao para listagem, detalhe, validacao, diagnostico e contrato",
        ("gerar snapshot", "comparar delta", "falhar se sourceHash divergir"),
        GovernanceSeverity.HIGH,
        False,
        OrderType.EXECUTIVE,
        "Implementar regressao de panelReady e sameSource",
        "alta",
    ),
    check(
        "panel.backend-mcp",
        GovernanceAxis.PANEL_BACKEND,
        GovernanceDomain.MCP,
        "MCP como backend do painel humano",
        "Garante que painel nao crie backend paralelo para dados que o GPT tambem explica.",
        ("admin_ui", "screenData", "screenAction", "viewInstance", "panelReady"),
        ("backend paralelo", "fonte paralela", "dados divergentes"),
        ("panelReady",),
        ("admin_ui", "screen", "viewInstance"),
        CORE_PLATFORMS,
        "A plataforma nao entrega surface de painel nesta etapa.",
        "Ha evidencia de backend MCP ou contrato admin_ui.",
        "Ha sinais de painel, mas o backend MCP precisa ser explicitado.",
        "A surface humana nao esta ligada ao MCP como fonte operacional.",
        "formalizar admin_ui, screenData, screenAction, diagnostics e evidence no MCP",
        ("listar telas", "detalhar tela", "validar panelReady"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.MANAGERIAL,
        "Consolidar MCP como backend oficial do painel humano",
        "alta",
    ),
    check(
        "panel.same-source",
        GovernanceAxis.GPT_PANEL_EQUIVALENCE,
        GovernanceDomain.MCP,
        "Mesma fonte para GPT e painel",
        "A UI humana e a explicacao GPT devem usar o mesmo contrato, hashes e evidencia.",
        ("sameSource", "same source", "sourcePayloadHash", "sourceRecordsHash", "dataTruth"),
        ("sameSource false", "source mismatch", "divergente", "truthIssues"),
        ("source", "hash"),
        ("sourcePayloadHash", "sourceRecordsHash", "sameSource"),
        CORE_PLATFORMS,
        "A plataforma nao possui surface compartilhada GPT/painel.",
        "Mesma fonte ou hashes de fonte foram detectados.",
        "Ha painel, mas faltam hashes ou prova da mesma fonte.",
        "Painel e GPT podem explicar estados diferentes.",
        "reconciliar sourceEndpoint, sourceToolId, payload hash e records hash",
        ("comparar payload", "validar sourceHash", "gerar evidencia HTTP"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Reconciliar mesma fonte entre GPT e painel",
        "alta",
    ),
    check(
        "panel.compact-response",
        GovernanceAxis.PANEL_BACKEND,
        GovernanceDomain.MCP,
        "Resposta compacta para auditoria humana",
        "Evita estouro de contexto e torna o painel/gpt auditavel em escala.",
        ("summaryOnly", "failuresOnly", "limit", "cursor", "mode=compact", "compact"),
        ("resposta grande demais", "sem paginacao", "timeout por payload"),
        (),
        ("limit", "cursor", "summaryOnly", "failuresOnly"),
        CORE_PLATFORMS,
        "Nao ha ferramenta de auditoria em escala nesta plataforma.",
        "Ha suporte a resposta compacta, filtros ou paginacao.",
        "Ha dados de painel, mas faltam filtros operacionais.",
        "Resposta grande demais reduz auditabilidade humana.",
        "implementar summaryOnly, failuresOnly, limit, cursor e includeRaw=false",
        ("chamar modo compact", "comparar com modo full", "validar limites"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Adicionar resposta compacta e paginada para auditoria",
    ),
    check(
        "identity.actor-scope",
        GovernanceAxis.IDENTITY_SCOPE,
        GovernanceDomain.IDENTITY,
        "Ator, organizacao e escopo claros",
        "A acao humana precisa saber quem chamou, em nome de quem e com qual permissao.",
        ("actorId", "organizationId", "tenant", "scope", "role", "identity"),
        ("usuario desconhecido", "test_user_not_found", "scope ausente"),
        ("actor", "organization"),
        ("identity", "rbac", "organizationId", "tenant"),
        ("identity", "business", "integracoes", "customer_ops", "compliance"),
        "A plataforma nao executa acao por usuario ou organizacao nesta etapa.",
        "Ator, organizacao ou escopo aparecem no contrato.",
        "Ha identidade parcial, mas falta cadeia completa de ator/tenant/role.",
        "Sem ator e escopo, a acao humana fica insegura.",
        "amarrar user, organization, role, scope, tenant e impersonation controlado",
        ("criar usuario teste", "vincular organizacao", "validar negacao RBAC"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Consolidar ator, organizacao e escopo Identity",
        "alta",
    ),
    check(
        "identity.rbac-deny",
        GovernanceAxis.IDENTITY_SCOPE,
        GovernanceDomain.IDENTITY,
        "Matriz RBAC com negacao provada",
        "Maturidade real exige provar permissoes negadas, nao apenas caminhos felizes.",
        ("rbac", "deny", "forbidden", "403", "permission", "matriz de negacao"),
        ("sem negacao", "permissao aberta", "allow all"),
        (),
        ("rbac", "403", "permission"),
        ("identity", "business", "integracoes", "ui", "mcps"),
        "A plataforma nao possui acao sensivel nesta etapa.",
        "Sinais de RBAC e negacao foram detectados.",
        "RBAC aparece, mas faltam cenarios de negacao.",
        "Sem negacao provada, o controle de acesso nao e auditavel.",
        "criar matriz de permissao com allowed/denied e testes por perfil",
        ("executar deny case", "registrar payload sanitizado", "validar auditId"),
        GovernanceSeverity.HIGH,
        False,
        OrderType.EXECUTIVE,
        "Adicionar matriz RBAC de negacao e evidencia",
        "alta",
    ),
    check(
        "business.entitlement",
        GovernanceAxis.BUSINESS_GATE,
        GovernanceDomain.BUSINESS,
        "Entitlement e plano como fonte comercial",
        "Produto vendavel precisa consultar Business para plano, limite, franquia e bloqueio.",
        ("entitlement", "plano", "quota", "franquia", "bloqueio", "checkout", "billing"),
        ("sem entitlement", "regra comercial propria", "plano divergente"),
        ("entitlement",),
        ("Business", "entitlement", "billing", "quota"),
        SELLABLE_PLATFORMS,
        "A plataforma nao tem oferta vendavel direta nesta leitura.",
        "Sinais de entitlement/plano foram detectados.",
        "Ha readiness comercial parcial, mas falta fonte unica Business.",
        "Sem entitlement, produto pode ser vendido ou liberado incorretamente.",
        "conectar plano, produto, usage, quota, bloqueio e liberacao via Business",
        ("consultar entitlement", "simular bloqueio", "validar consumo"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.MANAGERIAL,
        "Consolidar Business como fonte comercial unica",
        "alta",
    ),
    check(
        "business.blocker-isolation",
        GovernanceAxis.BUSINESS_GATE,
        GovernanceDomain.BUSINESS,
        "Blocker isolado por produto",
        "Um token pendente de Stripe ou provider nao deve contaminar telas e produtos independentes.",
        ("productId", "providerId", "blockerId", "isolado", "stage", "readiness por produto"),
        ("blocker global indevido", "contamina", "global blocker sem produto"),
        (),
        ("productId", "blockerId", "providerId"),
        SELLABLE_PLATFORMS,
        "Nao ha produto vendavel com blocker comercial nesta plataforma.",
        "Ha sinais de isolamento por produto/provider.",
        "Blocker existe, mas falta separar impacto por produto.",
        "Blocker global indevido reduz maturidade e confianca humana.",
        "classificar blockers por productId/providerId/stage e impacto comercial",
        ("listar blockers", "validar produto independente", "gerar matriz de impacto"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Isolar blockers comerciais por produto e provider",
    ),
    check(
        "docs.canonical-read",
        GovernanceAxis.DOCS_CANONICALITY,
        GovernanceDomain.DOCS,
        "Leitura Docs canonica ou excecao formal",
        "Docs nao pode ficar como blocker ambiguo entre catalogOnly e fonte operacional.",
        ("responseReady", "canonical", "leitura canonica", "excecao formal", "catalogOnly deliberado"),
        ("catalogOnly precisa decisao", "catalogOnly blocker", "docs catalogOnly"),
        ("docs",),
        ("Docs", "catalogOnly", "responseReady"),
        DOCS_RELATED,
        "Docs nao e dependencia primaria desta plataforma.",
        "Docs tem leitura canonica ou excecao formal detectada.",
        "Docs aparece, mas a decisao catalogOnly/responseReady precisa ser formalizada.",
        "Docs permanece como blocker documental ambiguo.",
        "promover leitura Docs responseReady minima ou registrar excecao catalogOnly deliberada",
        ("consultar Docs", "registrar decisao", "atualizar readiness global"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Resolver Docs catalogOnly por leitura minima ou excecao formal",
        "alta",
    ),
    check(
        "docs.contract-reconciliation",
        GovernanceAxis.DOCS_CANONICALITY,
        GovernanceDomain.DOCS,
        "Contrato documentado reconciliado com operacao",
        "Docs deve explicar contratos vivos, evidencias e guias sem virar copia solta.",
        ("contrato", "schema", "guia", "evidencia", "hash", "documento canonico"),
        ("documentacao divergente", "sem hash", "docs desatualizado"),
        (),
        ("contrato", "hash", "guia", "evidencia"),
        DOCS_RELATED,
        "Nao ha dependencia documental explicita.",
        "Contrato/documentacao aparece reconciliado.",
        "Documentacao existe, mas falta hash ou reconciliacao com operacao.",
        "Sem reconciliacao, Docs deixa de ser fonte confiavel.",
        "registrar contrato, hash, guia e evidencia por plataforma em Docs",
        ("comparar contrato", "gerar hash", "atualizar guia"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Reconciliar Docs com contratos e evidencias operacionais",
    ),
    check(
        "integrations.byok-chain",
        GovernanceAxis.BYOK_CREDENTIALS,
        GovernanceDomain.INTEGRATIONS,
        "Jornada BYOK ponta a ponta",
        "Integrações precisam de usuario, organizacao, entitlement, credentialRef, smoke e consumo.",
        ("BYOK", "credentialRef", "organization", "entitlement", "smoke", "usage", "consumo"),
        ("test_user_not_found", "needs_token", "credential missing", "sem credentialRef"),
        ("credentialRef", "smoke"),
        ("BYOK", "credentialRef", "smoke", "usage"),
        ("integracoes", "business", "identity", "mcps"),
        "A plataforma nao opera provider externo por tenant nesta etapa.",
        "Cadeia BYOK possui sinais fortes.",
        "BYOK aparece, mas faltam uma ou mais etapas da cadeia.",
        "BYOK incompleto impede autosservico real.",
        "executar fluxo organizacao, usuario, entitlement, credentialRef, smoke, consumo e auditoria",
        ("criar organizacao", "criar usuario", "gerar credentialRef", "executar smoke readonly"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Provar jornada BYOK ponta a ponta sem vazamento",
        "alta",
    ),
    check(
        "integrations.credential-redaction",
        GovernanceAxis.SECRET_REDACTION,
        GovernanceDomain.SECURITY,
        "Segredo nunca exposto em relatorios",
        "A plataforma deve usar refs e redaction para impedir vazamento em trace, audit e Markdown.",
        ("credentialRef", "redaction", "masked", "sanitized", "sem segredo", "secretRef"),
        ("secret=", "api_key", "token bruto", "password", "vazamento"),
        ("redaction",),
        ("REDACTION-CHECK", "credentialRef", "masked"),
        ("integracoes", "identity", "mcps", "compliance", "business"),
        "Nao ha segredo operacional nesta plataforma.",
        "Sinais de redaction/credentialRef foram detectados.",
        "Ha refs seguras, mas falta prova automatica de nao vazamento.",
        "Possivel segredo bruto ou ausencia de redaction.",
        "executar varredura de segredo, mascaramento e politica de campos proibidos",
        ("rodar redaction check", "validar JSON", "inspecionar relatorios"),
        GovernanceSeverity.CRITICAL,
        True,
        OrderType.EXECUTIVE,
        "Blindar redaction e referencias de credencial",
        "alta",
    ),
    check(
        "integrations.provider-stage",
        GovernanceAxis.BYOK_CREDENTIALS,
        GovernanceDomain.INTEGRATIONS,
        "Stage operacional por provider",
        "Cada provider precisa ficar em catalogOnly, sandbox, pilot, sellable ou blocked com criterio claro.",
        ("providerId", "stage", "catalogOnly", "sandbox", "pilot", "sellable", "blocked"),
        ("simulated_ready sem stage", "provider sem status", "maturidade indefinida"),
        ("provider", "stage"),
        ("providerId", "readiness", "stage"),
        ("integracoes", "business", "mcps"),
        "Nao ha provider externo ligado a esta plataforma.",
        "Stage por provider foi detectado.",
        "Providers existem, mas falta uma regua de maturidade comercial/tecnica.",
        "Provider sem stage claro pode ser vendido antes da hora.",
        "classificar cada provider em lifecycle comercial e tecnico unico",
        ("listar providers", "atribuir stage", "validar blockers por provider"),
        GovernanceSeverity.HIGH,
        False,
        OrderType.MANAGERIAL,
        "Normalizar maturidade comercial por provider",
        "alta",
    ),
    check(
        "support.diagnostic-next-action",
        GovernanceAxis.SUPPORT_DIAGNOSTICS,
        GovernanceDomain.SUPPORT,
        "Diagnostico de suporte com proxima acao",
        "Quando falha, suporte precisa saber origem, impacto e proximo passo sem expor segredo.",
        ("diagnostic", "diagnostico", "nextAction", "ticket", "incident", "support", "handoff"),
        ("erro bruto", "stack trace para cliente", "sem proxima acao"),
        ("diagnostic",),
        ("diagnostic", "ticket", "nextAction"),
        SUPPORT_PLATFORMS,
        "Esta plataforma nao possui fluxo de suporte direto nesta etapa.",
        "Diagnostico ou nextAction foi detectado.",
        "Ha suporte parcial, mas falta proxima acao padronizada.",
        "Sem diagnostico, suporte humano fica bloqueado.",
        "criar diagnostico sanitizado com causa, impacto, proxima acao e evidencia",
        ("simular falha", "validar nextAction", "abrir ticket de exemplo"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Adicionar diagnostico sanitizado para suporte",
    ),
    check(
        "support.incident-lifecycle",
        GovernanceAxis.INCIDENT_LIFECYCLE,
        GovernanceDomain.CUSTOMER_OPS,
        "Ciclo de incidente rastreavel",
        "Incidentes devem abrir, atualizar, resolver, auditar e virar aprendizagem operacional.",
        ("incident", "incidente", "status", "resolved", "handoff", "sla", "timeline"),
        ("incidente sem fechamento", "sem historico", "sem status"),
        (),
        ("incident", "timeline", "SLA"),
        ("customer_ops", "identity", "integracoes", "business", "mcps"),
        "Nao ha fluxo de incidente esperado nesta plataforma.",
        "Ciclo de incidente foi detectado.",
        "Ha incidentes, mas falta timeline ou fechamento.",
        "Incidente sem ciclo completo prejudica atendimento e auditoria.",
        "implementar ciclo aberto/em andamento/resolvido com evidenceId e owner",
        ("abrir incidente", "atualizar status", "fechar com evidencia"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Consolidar lifecycle de incidentes e handoffs",
    ),
    check(
        "observability.audit-trace",
        GovernanceAxis.AUDIT_EVIDENCE,
        GovernanceDomain.OBSERVABILITY,
        "Trace, audit e evidenceId",
        "Toda acao relevante precisa de trace, audit e evidencia sem conteudo sensivel.",
        ("traceId", "auditId", "evidenceId", "audit", "trace", "evidencia"),
        ("sem audit", "sem trace", "trace bruto", "audit ausente"),
        ("audit", "trace"),
        ("traceId", "auditId", "evidenceId"),
        ALL_PLATFORMS,
        "A plataforma nao executa acao auditavel nesta leitura.",
        "Trace/audit/evidencia aparecem nos sinais.",
        "Observabilidade existe, mas falta padrao auditId/evidenceId.",
        "Sem trace e audit a entrega nao fica verificavel.",
        "padronizar traceId, auditId, evidenceId, latency e status por chamada",
        ("executar smoke", "capturar auditId", "validar redaction"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Padronizar trace, audit e evidenceId",
        "alta",
    ),
    check(
        "observability.health-readiness",
        GovernanceAxis.READINESS_HEALTH,
        GovernanceDomain.OBSERVABILITY,
        "Health e readiness vivos",
        "A pessoa precisa saber se a plataforma esta pronta, parcial ou bloqueada agora.",
        ("health", "readiness", "ready", "status", "ok", "blocked"),
        ("health missing", "readiness ausente", "status desconhecido"),
        ("health", "readiness"),
        ("health", "readiness", "status"),
        ALL_PLATFORMS,
        "Nao ha runtime vivo esperado nesta plataforma.",
        "Health/readiness foram detectados.",
        "Ha health ou readiness parcial, mas falta classificacao de blocker.",
        "Sem health/readiness a leitura humana vira inferencia.",
        "publicar health/readiness com blockers classificados e timestamp",
        ("chamar health", "chamar readiness", "registrar status"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Publicar health/readiness com blockers classificados",
    ),
    check(
        "observability.error-classification",
        GovernanceAxis.AUDIT_EVIDENCE,
        GovernanceDomain.OBSERVABILITY,
        "Erro classificado e sanitizado",
        "Falhas devem ser classificadas por dominio e expostas sem segredo bruto.",
        ("errorCode", "classification", "classified", "sanitized", "safeError", "nextAction"),
        ("erro bruto", "unhandled", "stack trace", "sem classificacao"),
        (),
        ("errorCode", "safeError", "classification"),
        ALL_PLATFORMS,
        "Nao ha chamada operacional com erro esperado.",
        "Classificacao de erro aparece na evidencia.",
        "Erro e diagnosticado parcialmente, mas falta taxonomia.",
        "Erro sem classificacao reduz suporte e auditoria.",
        "criar taxonomia de erro por dominio com mensagem humana e payload redigido",
        ("forcar erro", "validar safeError", "checar ausencia de token"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Classificar erros e mensagens humanas seguras",
    ),
    check(
        "cloud.wrangler-reference",
        GovernanceAxis.CLOUD_OPERATION,
        GovernanceDomain.CLOUD,
        "Wrangler como referencia operacional Cloudflare",
        "Deploy, rotas, secrets, bindings, logs e health checks devem usar wrangler, nao o plugin.",
        ("wrangler", "workers", "routes", "bindings", "secrets", "deploy"),
        ("plugin Cloudflare como bloqueio", "usar plugin para deploy", "plugin substitui wrangler"),
        (),
        ("wrangler.toml", "wrangler deploy", "wrangler secret"),
        CLOUD_RELATED,
        "A plataforma nao possui Worker/Cloudflare nesta leitura.",
        "Wrangler ou Worker aparecem como referencia operacional.",
        "Cloudflare aparece, mas wrangler precisa ser declarado como via operacional.",
        "Sem wrangler, diagnostico Cloudflare fica fraco ou dependente do plugin.",
        "documentar e validar rotas, deploy, secrets, bindings, logs e health por wrangler",
        ("wrangler whoami quando aplicavel", "wrangler deploy dry run", "wrangler tail/route check"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Formalizar wrangler como via operacional Cloudflare",
    ),
    check(
        "cloud.plugin-exception",
        GovernanceAxis.CLOUD_OPERATION,
        GovernanceDomain.CLOUD,
        "Falha do plugin Cloudflare tratada como excecao esperada",
        "A negativa do plugin nao pode virar bloqueio nem desculpa para parar OS.",
        ("plugin Cloudflare", "user rejected MCP tool call", "negado", "esperada", "nao e blocker"),
        ("plugin cloudflare bloqueou", "parar por plugin", "diagnostico relevante do plugin"),
        (),
        ("AUDITORIA", "PENDENCIAS", "EXECUTADO"),
        CLOUD_RELATED,
        "A plataforma nao usa Cloudflare nesta leitura.",
        "A excecao do plugin foi tratada corretamente.",
        "Plugin foi mencionado, mas precisa ficar claro que nao bloqueia.",
        "Plugin Cloudflare foi tratado como blocker indevido.",
        "registrar tentativa do plugin apenas como premissa e seguir trabalho por wrangler quando houver acao real",
        ("registrar tentativa", "validar que pendencias nao citam plugin como blocker", "usar wrangler para trabalho real"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Auditar tratamento correto da falha esperada do plugin Cloudflare",
    ),
    check(
        "data.truth-state",
        GovernanceAxis.DATA_TRUTH,
        GovernanceDomain.GOVERNANCE,
        "truthState e fonte da verdade explicitos",
        "O painel humano e o GPT precisam saber se dado e real, simulado, fixture, stale ou parcial.",
        ("truthState", "dataTruth", "realData", "simulated", "stale", "partial", "sourceOfTruth"),
        ("truthIssues", "fonte da verdade ausente", "sampleData indefinido"),
        ("truth",),
        ("truthState", "sourceOfTruth", "dataTruth"),
        ALL_PLATFORMS,
        "Nao ha dado operacional exposto nesta plataforma.",
        "Fonte da verdade ou truthState foi detectado.",
        "Ha dados, mas falta classificar real/simulado/stale/partial.",
        "Sem truthState, pessoas podem confundir dado simulado com real.",
        "classificar cada resposta como real, simulatedInstitutional, fixture, stale, partial ou blocked",
        ("validar payload", "comparar estado", "registrar truthState"),
        GovernanceSeverity.HIGH,
        True,
        OrderType.EXECUTIVE,
        "Classificar truthState e fonte da verdade dos dados",
        "alta",
    ),
    check(
        "data.stale-safe",
        GovernanceAxis.DATA_TRUTH,
        GovernanceDomain.OBSERVABILITY,
        "Snapshot stale-safe para leitura humana",
        "Painel e GPT devem poder ler ultimo estado valido se uma dependencia estiver sobrecarregada.",
        ("snapshot", "stale", "expiresAt", "staleAfter", "lastSuccessful", "cache"),
        ("d1 overload sem fallback", "sem snapshot", "sem stale"),
        (),
        ("snapshot", "staleAfter", "expiresAt"),
        ("mcps", "ui", "business", "integracoes", "identity"),
        "Nao ha dependencia pesada ou tela de leitura nesta plataforma.",
        "Snapshot/stale-safe foi detectado.",
        "Ha snapshot, mas falta TTL ou marcacao stale.",
        "Sem stale-safe, painel pode cair por dependencia lenta.",
        "materializar ultimo snapshot valido com TTL, stale=true e evidenceId",
        ("simular dependencia lenta", "verificar stale=true", "comparar hash"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.EXECUTIVE,
        "Adicionar snapshot stale-safe para telas humanas",
    ),
    check(
        "release.gates",
        GovernanceAxis.RELEASE_GOVERNANCE,
        GovernanceDomain.GOVERNANCE,
        "Gates de release e rollback",
        "Projetos duradouros precisam de gate, rollback e criterio de promocao.",
        ("release", "rollback", "gate", "promotion", "migration", "breakingChanges"),
        ("sem rollback", "sem gate", "deploy sem criterio"),
        (),
        ("release", "rollback", "gate"),
        ALL_PLATFORMS,
        "Nao ha release operacional nesta plataforma.",
        "Gates de release/rollback foram detectados.",
        "Ha release parcial, mas falta rollback ou criterio formal.",
        "Sem gate de release, mudancas podem quebrar contrato humano.",
        "criar gate de release com smoke, contrato, rollback, compatibilidade e evidencia",
        ("validar smoke", "validar contrato", "registrar rollback"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Formalizar gates de release e rollback",
    ),
    check(
        "commercial.sellable-stage",
        GovernanceAxis.COMMERCIAL_MATURITY,
        GovernanceDomain.BUSINESS,
        "Stage vendavel controlado",
        "Produto humano precisa separar catalogado, sandbox, piloto controlado e venda geral.",
        ("sellable", "pilot", "controlled", "catalog-ready", "commercialReady", "produto vendavel"),
        ("vendavel sem smoke", "sellable simulated", "stage comercial indefinido"),
        ("stage",),
        ("commercialReady", "sellable", "pilot"),
        SELLABLE_PLATFORMS,
        "Nao ha produto vendavel direto nesta plataforma.",
        "Stage comercial aparece classificado.",
        "Produto tem valor comercial, mas falta stage operacional claro.",
        "Produto pode ser vendido sem prontidao real.",
        "criar regua catalog-ready, credential-ready, smoke-ready, pilot-controlled e sellable",
        ("classificar produto", "validar smoke", "registrar limite comercial"),
        GovernanceSeverity.HIGH,
        False,
        OrderType.MANAGERIAL,
        "Separar maturidade comercial e tecnica por produto",
        "alta",
    ),
    check(
        "human.profile-value",
        GovernanceAxis.HUMAN_VALUE,
        GovernanceDomain.HUMAN_EXPERIENCE,
        "Valor humano por perfil explicitado",
        "Cada plataforma deve dizer quem atende, como atende, o que falta e qual proxima acao.",
        ("perfil humano", "quem atende", "matriz", "playbook", "perguntas humanas", "metas humanas"),
        ("tecnico demais", "sem perfil", "sem matriz"),
        ("perfil", "matriz"),
        ("matriz-plataforma-perfil", "playbooks-humanos", "perguntas-humanas"),
        ALL_PLATFORMS,
        "Nao ha relatorio humano esperado para esta plataforma.",
        "Valor por perfil foi detectado.",
        "Ha leitura humana, mas falta conectar a perfil/pergunta/acao.",
        "Sem valor por perfil, a plataforma parece apenas tecnica.",
        "gerar matriz plataforma x perfil com perguntas, lacunas, evidencias e OS",
        ("regenerar matriz", "comparar perfis fracos", "criar OS vinculada"),
        GovernanceSeverity.MEDIUM,
        False,
        OrderType.MANAGERIAL,
        "Elevar valor humano por perfil e pergunta",
    ),
)


CHECK_BY_ID = {template.check_id: template for template in CHECK_TEMPLATES}


DOMAIN_TO_PRIMARY_PLATFORM: dict[GovernanceDomain, str] = {
    GovernanceDomain.MCP: "mcps",
    GovernanceDomain.IDENTITY: "identity",
    GovernanceDomain.BUSINESS: "business",
    GovernanceDomain.DOCS: "docs",
    GovernanceDomain.INTEGRATIONS: "integracoes",
    GovernanceDomain.COMPLIANCE: "compliance",
    GovernanceDomain.FINANCE: "finance",
    GovernanceDomain.CUSTOMER_OPS: "customer_ops",
    GovernanceDomain.UI: "ui",
    GovernanceDomain.CLOUD: "integracoes",
    GovernanceDomain.SECURITY: "identity",
    GovernanceDomain.OBSERVABILITY: "mcps",
    GovernanceDomain.SUPPORT: "customer_ops",
    GovernanceDomain.GOVERNANCE: "mcps",
    GovernanceDomain.HUMAN_EXPERIENCE: "ui",
    GovernanceDomain.REPOSITORY: "platform_base",
    GovernanceDomain.DOCUMENTATION: "docs",
    GovernanceDomain.CONTRACT: "platform_base",
    GovernanceDomain.TESTS: "platform_base",
    GovernanceDomain.RUNTIME: "platform_base",
}


def templates_for_platform(platform_id: str) -> tuple[CheckTemplate, ...]:
    return tuple(template for template in CHECK_TEMPLATES if template.applies_to_platform(platform_id))


def templates_for_domain(domain: GovernanceDomain) -> tuple[CheckTemplate, ...]:
    return tuple(template for template in CHECK_TEMPLATES if template.domain == domain)


def core_template_ids() -> tuple[str, ...]:
    return tuple(template.check_id for template in CHECK_TEMPLATES if template.required_for_human_ready)
