"""Tenant governance only narrows the platform tenant envelope (canon C14, G7).""" from __future__ import annotations import pytest from fixture_loading import ENVELOPES, FIXTURES, deep_merge, load_yaml from emergent_security.tenant import PlatformTenantEnvelope, effective_ceilings, validate_tenant_governance SPEC = load_yaml(FIXTURES / "tenants" / "governance-validation.yaml") @pytest.fixture(scope="module") def platform() -> PlatformTenantEnvelope: return PlatformTenantEnvelope.from_dict(load_yaml(ENVELOPES / SPEC["platform_envelope"])) @pytest.fixture(scope="module") def base_governance() -> dict: return load_yaml(ENVELOPES / SPEC["base"]) @pytest.mark.parametrize("case", SPEC["cases"], ids=[c["name"] for c in SPEC["cases"]]) def test_governance_validation(case, platform, base_governance, scales): errors = validate_tenant_governance(deep_merge(base_governance, case["patch"]), platform, scales) if case["error"] is None: assert errors == [] else: assert any(case["error"] in error for error in errors), errors def test_platform_example_is_valid(platform, scales): assert platform.validate(scales) == [] def test_platform_delegations_must_be_capabilities(scales): broken = PlatformTenantEnvelope.from_dict( {"id": "envelope://x", "tenant": "tenant://x", "capabilities": ["code.edit"], "delegated": {"iam.change": {"mode": "autonomous"}}, "ceilings": {}, "prohibitions": []} ) assert any("delegated class outside capabilities: iam.change" in e for e in broken.validate(scales)) def test_platform_cannot_both_delegate_and_prohibit(scales): broken = PlatformTenantEnvelope.from_dict( {"id": "envelope://x", "tenant": "tenant://x", "capabilities": ["code.edit"], "delegated": {"code.edit": {"mode": "autonomous"}}, "ceilings": {}, "prohibitions": ["code.edit"]} ) assert any("both delegated and prohibited: code.edit" in e for e in broken.validate(scales)) def test_effective_ceiling_is_the_narrower_value(platform, base_governance, scales): from emergent_security.tenant import TenantGovernance effective = effective_ceilings(platform, TenantGovernance.from_dict(base_governance), scales) assert effective["blast_radius"] == "repository" # tenant narrowed assert effective["data_sensitivity"] == "personal" # platform value kept def test_platform_widening_does_not_erase_tenant_restrictions(platform, base_governance, scales): from dataclasses import replace from emergent_security.tenant import TenantGovernance wider = replace(platform, ceilings={**platform.ceilings, "blast_radius": "platform"}) effective = effective_ceilings(wider, TenantGovernance.from_dict(base_governance), scales) assert effective["blast_radius"] == "repository" def test_platform_narrowing_propagates_immediately(platform, base_governance, scales): from dataclasses import replace from emergent_security.tenant import TenantGovernance narrower = replace(platform, ceilings={**platform.ceilings, "blast_radius": "task"}) effective = effective_ceilings(narrower, TenantGovernance.from_dict(base_governance), scales) assert effective["blast_radius"] == "task"