From d7e15d6f3d29df425ed653850592583e3d4ba1d8 Mon Sep 17 00:00:00 2001 From: codex-server Date: Sat, 2 May 2026 04:45:08 -0300 Subject: [PATCH] auto-sync: tudo-para-ia-mais-humana 2026-05-02 04:45:08 --- src/mais_humana/central_materialization.py | 24 ++++--- src/mais_humana/human_rulebook.py | 17 +++-- src/mais_humana/identity_policy.py | 81 ++++++++++++++++++++++ src/mais_humana/mcp_publication_gate.py | 22 +++--- src/mais_humana/repository_mesh.py | 15 ++-- tests/test_central_materialization.py | 2 +- tests/test_mcp_publication_gate.py | 2 +- tests/test_repository_mesh.py | 3 +- 8 files changed, 127 insertions(+), 39 deletions(-) create mode 100644 src/mais_humana/identity_policy.py diff --git a/src/mais_humana/central_materialization.py b/src/mais_humana/central_materialization.py index a5521d7..a869411 100644 --- a/src/mais_humana/central_materialization.py +++ b/src/mais_humana/central_materialization.py @@ -17,14 +17,14 @@ from enum import Enum from pathlib import Path from typing import Any, Mapping, Sequence +from .identity_policy import CANONICAL_COMPATIBILITY_RULE, CANONICAL_PROJECT_ID, CENTRAL_FOLDER_NAME, CURRENT_PROJECT_ID from .models import GeneratedFile, OrderStatus, OrderType, ServiceOrder, as_plain_data, merge_unique, utc_now from .orders import order_markdown from .storage import connect, upsert_files, upsert_orders -PROJECT_ID = "tudo-para-ia-mais-humana" -REAL_REPO = "tudo-para-ia-mais-humana" -CENTRAL_FOLDER_NAME = "15_repo_tudo-para-ia-mais-humana-platform" +PROJECT_ID = CANONICAL_PROJECT_ID +REAL_REPO = CURRENT_PROJECT_ID class MaterializationStatus(str, Enum): @@ -336,14 +336,14 @@ def active_managerial_order_specs() -> tuple[MaterializedOrderSpec, ...]: _mgr( "0052_GERENCIAL__formalizar-nome-canonico-mais-humana-platform-e-aliases", "Formalizar nome canonico Mais Humana platform e aliases", - "Decidir a relacao entre repo real sem sufixo, alias administrativo -platform e alias historico -plataform.", - "O projeto real local e remoto encontrado e tudo-para-ia-mais-humana, enquanto a pasta central usa -platform.", - "Nome canonico, aliases, politica de migracao e janela segura documentados sem duplicar repositorio.", + "Registrar a relacao entre canonico -platform, repo local sem sufixo e alias historico -plataform.", + "A decisao institucional registrada no roteador aprovou tudo-para-ia-mais-humana-platform como nome canonico.", + "Nome canonico aprovado, aliases preservados e migracao futura limitada a janela coordenada sem duplicar repositorio.", ("README.md", "dados/mcp-publication-gate-mais-humana.json"), ("verificar remote", "verificar ownerPlatformId", "verificar referencias centrais"), - ("decisao institucional registrada", "aliases preservados ou migrados", "sem repositorio duplicado"), + ("decisao institucional registrada", "aliases preservados", "sem repositorio duplicado"), role=OrderLifecycleRole.ACTIVE_INPUT, - status=OrderStatus.BLOCKED, + status=OrderStatus.COMPLETED, ), _mgr( "0053_GERENCIAL__pactuar-docs-catalogonly-ou-response-ready-como-excecao-global", @@ -644,7 +644,7 @@ def _active_queue_markdown(report: CentralMaterializationReport) -> str: def _state_markdown(report: CentralMaterializationReport) -> str: lines = [ - "# Estado atual reconciliado - tudo-para-ia-mais-humana", + "# Estado atual reconciliado - tudo-para-ia-mais-humana-platform", "", "## Atualizacao central materialization - 2026-05-02", "", @@ -655,7 +655,9 @@ def _state_markdown(report: CentralMaterializationReport) -> str: f"- project_root: `{report.project_root}`", f"- central_platform_folder: `{report.central_platform_folder}`", "", - "A rodada materializou ordens citadas pela fila, gerou o catalogo de aceitacao das rotas administrativas MCP-only e preservou como pendencias apenas credencial Git, runner/deploy, ACL local, decisao canonica e Docs.", + "A rodada materializou ordens citadas pela fila, gerou o catalogo de aceitacao das rotas administrativas MCP-only, registrou a decisao canonica e preservou como pendencias apenas credencial Git, runner/deploy, ACL local e Docs.", + "", + f"Politica canonica: {CANONICAL_COMPATIBILITY_RULE}", "", "## Saida ativa efetiva", "", @@ -672,7 +674,7 @@ def _state_markdown(report: CentralMaterializationReport) -> str: def _orders_index_markdown(report: CentralMaterializationReport) -> str: lines = [ - "# Indice de ordens - tudo-para-ia-mais-humana", + "# Indice de ordens - tudo-para-ia-mais-humana-platform", "", "## Rodada 015 - materializacao central", "", diff --git a/src/mais_humana/human_rulebook.py b/src/mais_humana/human_rulebook.py index cedea19..5642d60 100644 --- a/src/mais_humana/human_rulebook.py +++ b/src/mais_humana/human_rulebook.py @@ -22,6 +22,14 @@ from enum import Enum from pathlib import Path from typing import Any, Iterable, Mapping, Sequence +from .identity_policy import ( + CANONICAL_PROJECT_ID, + CURRENT_PROJECT_ID, + LEGACY_PROJECT_IDS, + MCP_CONTROL_PLANE_ID, + MCP_EXECUTE_ENDPOINT, + UI_SUPPORT_PLATFORM_ID, +) from .models import PlatformHumanReport, as_plain_data, merge_unique, slugify, utc_now @@ -98,15 +106,6 @@ MCP_TRANSIT_FIELDS: tuple[str, ...] = ( ) -CANONICAL_PROJECT_ID = "tudo-para-ia-mais-humana-platform" -CURRENT_PROJECT_ID = "tudo-para-ia-mais-humana" -LEGACY_PROJECT_IDS: tuple[str, ...] = ( - "tudo-para-ia-mais-humana", - "tudo-para-ia-mais-humana-plataform", -) -MCP_CONTROL_PLANE_ID = "tudo-para-ia-mcps-internos-plataform" -UI_SUPPORT_PLATFORM_ID = "tudo-para-ia-ui-platform" -MCP_EXECUTE_ENDPOINT = "https://mcps-gateway.ami-app.workers.dev/v1/execute" RULEBOOK_SOURCE_TOOL_ID = "mais_humana.rulebook.compact" diff --git a/src/mais_humana/identity_policy.py b/src/mais_humana/identity_policy.py new file mode 100644 index 0000000..2e3edfd --- /dev/null +++ b/src/mais_humana/identity_policy.py @@ -0,0 +1,81 @@ +"""Canonical identity policy for the Mais Humana platform. + +The institutional decision is explicit: the platform's canonical name is +``tudo-para-ia-mais-humana-platform``. The physical repository may still be +materialized as the historical no-suffix folder while synchronization and Gitea +renames are coordinated, so the policy keeps compatibility aliases visible +instead of treating them as competing sources of truth. +""" + +from __future__ import annotations + +from dataclasses import dataclass +from typing import Any + +from .models import as_plain_data, merge_unique + + +CANONICAL_PROJECT_ID = "tudo-para-ia-mais-humana-platform" +CURRENT_PROJECT_ID = "tudo-para-ia-mais-humana" +LEGACY_PLATAFORM_ALIAS = "tudo-para-ia-mais-humana-plataform" +CENTRAL_FOLDER_NAME = "15_repo_tudo-para-ia-mais-humana-platform" +CANONICAL_DECISION_STATUS = "approved" +CANONICAL_DECISION_SOURCE = "015-ROTEADOR-PERMANENTE-DE-ORDEM_DE_SERVICO.MD" +MCP_CONTROL_PLANE_ID = "tudo-para-ia-mcps-internos-plataform" +UI_SUPPORT_PLATFORM_ID = "tudo-para-ia-ui-platform" +MCP_EXECUTE_ENDPOINT = "https://mcps-gateway.ami-app.workers.dev/v1/execute" + +LEGACY_PROJECT_IDS: tuple[str, ...] = ( + CURRENT_PROJECT_ID, + LEGACY_PLATAFORM_ALIAS, +) + +ACCEPTED_PROJECT_IDS: tuple[str, ...] = merge_unique( + (CANONICAL_PROJECT_ID, *LEGACY_PROJECT_IDS) +) + +CANONICAL_COMPATIBILITY_RULE = ( + "Nome canonico institucional aprovado como tudo-para-ia-mais-humana-platform; " + "o repositorio local historico tudo-para-ia-mais-humana e o alias " + "tudo-para-ia-mais-humana-plataform permanecem aliases de compatibilidade " + "ate migracao Git/MCP sincronizada, sem duplicar repositorio nem sobrescrever historico." +) + + +@dataclass(frozen=True, slots=True) +class CanonicalIdentityPolicy: + """Serializable policy consumed by MCP contracts, reports, and gates.""" + + canonical_project_id: str = CANONICAL_PROJECT_ID + current_project_id: str = CURRENT_PROJECT_ID + legacy_project_ids: tuple[str, ...] = LEGACY_PROJECT_IDS + accepted_project_ids: tuple[str, ...] = ACCEPTED_PROJECT_IDS + decision_status: str = CANONICAL_DECISION_STATUS + decision_source: str = CANONICAL_DECISION_SOURCE + central_folder_name: str = CENTRAL_FOLDER_NAME + control_plane_id: str = MCP_CONTROL_PLANE_ID + compatibility_rule: str = CANONICAL_COMPATIBILITY_RULE + + def to_dict(self) -> dict[str, Any]: + return as_plain_data(self) + + +def canonical_identity_policy() -> CanonicalIdentityPolicy: + """Return the immutable identity policy for this round.""" + + return CanonicalIdentityPolicy() + + +def canonicalize_project_id(project_id: str) -> str: + """Map known historical ids to the approved canonical project id.""" + + normalized = str(project_id).strip() + if normalized in ACCEPTED_PROJECT_IDS: + return CANONICAL_PROJECT_ID + return normalized + + +def is_accepted_project_id(project_id: str) -> bool: + """Return whether an id is canonical or an approved compatibility alias.""" + + return canonicalize_project_id(project_id) == CANONICAL_PROJECT_ID diff --git a/src/mais_humana/mcp_publication_gate.py b/src/mais_humana/mcp_publication_gate.py index 1157ed1..4ca1295 100644 --- a/src/mais_humana/mcp_publication_gate.py +++ b/src/mais_humana/mcp_publication_gate.py @@ -34,6 +34,11 @@ from .mcp_contract import ( PROVIDER_TOOL_ID, stable_hash, ) +from .identity_policy import ( + CANONICAL_COMPATIBILITY_RULE, + CANONICAL_DECISION_STATUS, + LEGACY_PROJECT_IDS, +) from .models import GeneratedFile, as_plain_data, merge_unique, slugify, utc_now from .redaction import redact_sensitive_text @@ -504,7 +509,7 @@ def build_alias_policy( *, central_platform_folder: Path | None = None, repo_remote: str = "", - decision_status: str = "pending_institutional_decision", + decision_status: str = CANONICAL_DECISION_STATUS, ) -> AliasPolicyEvidence: """Build the canonical-name policy without renaming files or remotes.""" @@ -519,15 +524,12 @@ def build_alias_policy( current_project_id=CURRENT_PROJECT_ID, canonical_project_id=CANONICAL_PROJECT_ID, owner_platform_id=DEFAULT_OWNER_PLATFORM_ID, - legacy_aliases=(DEFAULT_OWNER_PLATFORM_ID, LEGACY_ALIAS_PLATFORM_ID), + legacy_aliases=tuple(LEGACY_PROJECT_IDS), central_folder=central_folder, repo_remote=repo_remote, decision_status=decision_status, migration_safe_now=migration_safe_now, - compatibility_rule=( - "Preserve current project id and central -platform alias until an explicit " - "institutional decision authorizes a synchronized Git/MCP/documentation rename." - ), + compatibility_rule=CANONICAL_COMPATIBILITY_RULE, blockers=tuple(blockers), ) @@ -596,7 +598,7 @@ def decide_publication_orders( alias.status, "politica de alias foi materializada sem renome destrutivo", ("alias_policy",), - "aguardar decisao institucional antes de renomear remote, pasta central, ownerPlatformId ou referencias historicas", + "executar migracao Git/MCP/documentacao somente por janela coordenada, preservando aliases e hashes", ), _decision( "0043_GERENCIAL__aprovar-janela-publicacao-provider-mais-humana-com-rollback", @@ -629,9 +631,9 @@ def decide_publication_orders( _decision( "0047_GERENCIAL__decidir-nome-canonico-e-politica-alias-mais-humana", alias.status, - "nome atual, nome canonico recomendado e aliases estao documentados", + "decisao institucional aprovada: canonico -platform com aliases historicos preservados", ("alias_policy",), - "registrar decisao formal: preservar alias ou executar migracao coordenada", + "manter politica de compatibilidade e abrir apenas execucao tecnica de migracao coordenada", ), ) @@ -687,7 +689,7 @@ def build_publication_gate_report( f"Wrangler autenticado: {wrangler.authenticated}; deploy dry-run OK: {wrangler.deploy_dry_run_ok}.", f"Tools live prontas: {sum(1 for item in probes if item.live_ready)}/{len(probes)}.", f"Probes live com envelope MCP completo: {sum(1 for item in probes if not item.missing_transit_fields)}/{len(probes)}.", - f"Nome atual: {CURRENT_PROJECT_ID}; canonico recomendado: {CANONICAL_PROJECT_ID}; ownerPlatformId MCP: {DEFAULT_OWNER_PLATFORM_ID}.", + f"Nome atual materializado: {CURRENT_PROJECT_ID}; canonico aprovado: {CANONICAL_PROJECT_ID}; ownerPlatformId MCP: {DEFAULT_OWNER_PLATFORM_ID}.", f"Decisoes de OS avaliadas: {len(decisions)}.", ) return McpPublicationGateReport( diff --git a/src/mais_humana/repository_mesh.py b/src/mais_humana/repository_mesh.py index 37169af..316ced6 100644 --- a/src/mais_humana/repository_mesh.py +++ b/src/mais_humana/repository_mesh.py @@ -31,6 +31,7 @@ from enum import Enum from pathlib import Path from typing import Any, Callable, Iterable, Mapping, MutableMapping, Sequence +from .identity_policy import CANONICAL_PROJECT_ID, CURRENT_PROJECT_ID, LEGACY_PLATAFORM_ALIAS from .models import GeneratedFile, as_plain_data, merge_unique, slugify, utc_now @@ -565,14 +566,16 @@ def default_repository_targets() -> tuple[RepositoryTarget, ...]: central_folder="09_repo_tudo-para-ia-intelligence-platform", ), RepositoryTarget( - declared_name="tudo-para-ia-mais-humana-platform", - expected_local_name="tudo-para-ia-mais-humana", - gitea_repo="admin/tudo-para-ia-mais-humana", + declared_name=CANONICAL_PROJECT_ID, + expected_local_name=CANONICAL_PROJECT_ID, + gitea_repo=f"admin/{CANONICAL_PROJECT_ID}", central_folder="15_repo_tudo-para-ia-mais-humana-platform", - aliases=("tudo-para-ia-mais-humana-plataform",), - canonical_name="tudo-para-ia-mais-humana-platform", + aliases=(CURRENT_PROJECT_ID, LEGACY_PLATAFORM_ALIAS), + canonical_name=CANONICAL_PROJECT_ID, requires_nominal_reconciliation=True, - notes=("nome canonico administrativo declarado como -platform; repo local/remoto materializado segue sem sufixo ate decisao Gitea",), + notes=( + "decisao institucional aprovou -platform como canonico; repo local/remoto historico sem sufixo permanece alias ate migracao coordenada", + ), ), RepositoryTarget( declared_name="tudo-para-ia-mcps-internos-plataform", diff --git a/tests/test_central_materialization.py b/tests/test_central_materialization.py index 446ac89..c55e2b5 100644 --- a/tests/test_central_materialization.py +++ b/tests/test_central_materialization.py @@ -50,7 +50,7 @@ class CentralMaterializationTests(unittest.TestCase): code = main(["central-materialization", "--project-root", str(project), "--central-platform-folder", str(central)]) self.assertEqual(code, 0) payload = json.loads((central / "dados" / "central-materialization-report.json").read_text(encoding="utf-8")) - self.assertEqual(payload["project_id"], "tudo-para-ia-mais-humana") + self.assertEqual(payload["project_id"], "tudo-para-ia-mais-humana-platform") self.assertEqual(len(payload["active_input_orders"]), 10) self.assertEqual(len(payload["next_output_orders"]), 10) diff --git a/tests/test_mcp_publication_gate.py b/tests/test_mcp_publication_gate.py index 2163f61..d7eb932 100644 --- a/tests/test_mcp_publication_gate.py +++ b/tests/test_mcp_publication_gate.py @@ -142,7 +142,7 @@ class McpPublicationGateTests(unittest.TestCase): ) self.assertEqual( by_id["0047_GERENCIAL__decidir-nome-canonico-e-politica-alias-mais-humana"].status, - GateStatus.BLOCKED, + GateStatus.PASSED, ) def test_publication_gate_report_serializes_markdown_and_csv(self) -> None: diff --git a/tests/test_repository_mesh.py b/tests/test_repository_mesh.py index 5611d32..61390c0 100644 --- a/tests/test_repository_mesh.py +++ b/tests/test_repository_mesh.py @@ -111,7 +111,8 @@ class RepositoryMeshTests(unittest.TestCase): targets = default_repository_targets() names = {item.declared_name: item for item in targets} self.assertIn("tudo-para-ia-mais-humana-platform", names) - self.assertEqual(names["tudo-para-ia-mais-humana-platform"].expected_local_name, "tudo-para-ia-mais-humana") + self.assertEqual(names["tudo-para-ia-mais-humana-platform"].expected_local_name, "tudo-para-ia-mais-humana-platform") + self.assertIn("tudo-para-ia-mais-humana", names["tudo-para-ia-mais-humana-platform"].aliases) self.assertIn("tudo-para-ia-mais-humana-plataform", names["tudo-para-ia-mais-humana-platform"].aliases) self.assertTrue(names["tudo-para-ia-mais-humana-platform"].requires_nominal_reconciliation) self.assertIn("tudo-para-ia-integracoes-platform", names)