From fd0367806c21c1ddb8b4e128405a7d44301686b2 Mon Sep 17 00:00:00 2001 From: codex-server Date: Mon, 4 May 2026 14:23:42 -0300 Subject: [PATCH] auto-sync: tudo-para-ia-mais-humana 2026-05-04 14:23:42 --- src/mais_humana/institutional_decisions.py | 59 ++++++++++++++++++++++ tests/test_institutional_decisions.py | 25 +++++++++ 2 files changed, 84 insertions(+) diff --git a/src/mais_humana/institutional_decisions.py b/src/mais_humana/institutional_decisions.py index 1efe8ed..c9c516e 100644 --- a/src/mais_humana/institutional_decisions.py +++ b/src/mais_humana/institutional_decisions.py @@ -67,6 +67,18 @@ class HumanPolicyPanel: summary: dict[str, int] +@dataclass(frozen=True) +class HumanEvidenceGap: + decision_id: str + status: str + expected_evidence: tuple[str, ...] + present_evidence: tuple[str, ...] + missing_evidence: tuple[str, ...] + visible_to_profile: str + human_impact: str + next_question: str + + def _impact(profile_id: str, expectation: str, signal: str, risk: str, question: str) -> HumanImpact: return HumanImpact( profile_id=profile_id, @@ -435,3 +447,50 @@ def export_human_policy_readiness_panel( "summary": panel.summary, "signals": [asdict(signal) for signal in panel.signals], } + + +def build_human_institutional_evidence_gap_analysis( + available_evidence: dict[str, tuple[str, ...]] | None = None, +) -> dict[str, object]: + evidence_by_decision = available_evidence or { + decision.decision_id: decision.expected_mcp_evidence + for decision in INSTITUTIONAL_DECISIONS + } + gaps: list[HumanEvidenceGap] = [] + for decision in INSTITUTIONAL_DECISIONS: + expected = tuple(decision.expected_mcp_evidence) + present = tuple(evidence_by_decision.get(decision.decision_id, ())) + present_set = set(present) + missing = tuple(field for field in expected if field not in present_set) + status = "ready" if not missing else "partial" if present else "blocked" + profile = decision.affected_profiles[0] + gaps.append( + HumanEvidenceGap( + decision_id=decision.decision_id, + status=status, + expected_evidence=expected, + present_evidence=present, + missing_evidence=missing, + visible_to_profile=profile.profile_id, + human_impact=profile.risk_if_missing if missing else profile.visible_signal, + next_question=profile.next_human_question, + ) + ) + summary = { + "ready": sum(1 for gap in gaps if gap.status == "ready"), + "partial": sum(1 for gap in gaps if gap.status == "partial"), + "blocked": sum(1 for gap in gaps if gap.status == "blocked"), + "missing_evidence": sum(len(gap.missing_evidence) for gap in gaps), + "total": len(gaps), + } + return { + "ok": summary["partial"] == 0 and summary["blocked"] == 0, + "policy_version": POLICY_VERSION, + "generated_at": "2026-05-04T00:00:00.000Z", + "gaps": [asdict(gap) for gap in gaps], + "summary": summary, + "human_boundary": ( + "Mais Humana avalia confianca e pergunta humana; MCP/Docs continuam donos da prova " + "e a UI continua responsavel por renderizar a mesma fonte." + ), + } diff --git a/tests/test_institutional_decisions.py b/tests/test_institutional_decisions.py index 0dd7cec..8abecce 100644 --- a/tests/test_institutional_decisions.py +++ b/tests/test_institutional_decisions.py @@ -5,6 +5,7 @@ import unittest from mais_humana.institutional_decisions import ( PLATFORM_ALIASES, build_human_decision_matrix, + build_human_institutional_evidence_gap_analysis, build_human_policy_readiness_panel, classify_development_action_for_humans, export_human_policy_readiness_panel, @@ -86,6 +87,30 @@ class InstitutionalDecisionHumanTests(unittest.TestCase): self.assertEqual(exported["summary"]["ready"], 6) self.assertEqual(len(exported["signals"]), 6) + def test_human_evidence_gap_analysis_explains_missing_confidence_fields(self) -> None: + analysis = build_human_institutional_evidence_gap_analysis( + { + "docs_full_operational_platform": ( + "documentId", + "sourceHash", + "authority", + "truthState", + "missingTopics", + ), + "mcp_required_cross_platform_acceptance": ("originPlatformId", "contractHash"), + } + ) + self.assertFalse(analysis["ok"]) + self.assertEqual(analysis["summary"]["ready"], 1) + self.assertGreaterEqual(analysis["summary"]["partial"], 1) + mcp_gap = [ + gap for gap in analysis["gaps"] + if gap["decision_id"] == "mcp_required_cross_platform_acceptance" + ][0] + self.assertEqual(mcp_gap["status"], "partial") + self.assertIn("destinationPlatformId", mcp_gap["missing_evidence"]) + self.assertIn("MCP/Docs continuam donos", analysis["human_boundary"]) + if __name__ == "__main__": unittest.main()