Add governed institutional capability contracts

This commit is contained in:
2026-08-01 20:57:25 +02:00
parent 7192d32e65
commit 2b4eb0151f
16 changed files with 2203 additions and 249 deletions
+96
View File
@@ -0,0 +1,96 @@
from __future__ import annotations
from datetime import UTC, datetime
import unittest
from govoplan_core.core.encryption import (
CAPABILITY_ENCRYPTION_KEY_MATERIAL_PROVIDER_PREFIX,
ContentProtectionEnvelope,
KeyMaterialDescriptor,
KeyVaultCreateRequest,
key_material_provider,
)
NOW = datetime(2026, 8, 1, 12, 0, tzinfo=UTC)
class Provider:
def provision_key(self, _session, _principal, *, request):
return KeyMaterialDescriptor(
provider_id="test",
provider_key_ref=f"test:{request.vault_id}:{request.key_version}",
algorithm_suite=request.algorithm_suite,
state="active",
created_at=NOW,
)
def revoke_key(self, _session, _principal, **_kwargs):
raise NotImplementedError
def schedule_key_destruction(self, _session, _principal, **_kwargs):
raise NotImplementedError
def key_status(self, _session, **_kwargs):
return None
class Registry:
def __init__(self, values):
self.values = values
def has_capability(self, name: str) -> bool:
return name in self.values
def capability(self, name: str):
return self.values[name]
class EncryptionContractTests(unittest.TestCase):
def test_provider_resolution_is_optional_and_structural(self) -> None:
name = f"{CAPABILITY_ENCRYPTION_KEY_MATERIAL_PROVIDER_PREFIX}test"
provider = Provider()
self.assertIs(
provider, key_material_provider(Registry({name: provider}), "test")
)
self.assertIsNone(key_material_provider(Registry({}), "test"))
def test_secret_bearing_policy_and_envelope_metadata_are_rejected(self) -> None:
with self.assertRaisesRegex(ValueError, "secret material"):
KeyVaultCreateRequest(
tenant_id="tenant-1",
vault_id="vault-1",
name="Vault",
provider_id="test",
purpose="content",
algorithm_suite="AES-256-GCM",
scope_type="tenant",
scope_id="tenant-1",
policy_ref="policy:1",
idempotency_key="create-1",
provider_policy={"password": "forbidden"},
)
with self.assertRaisesRegex(ValueError, "secret material"):
ContentProtectionEnvelope(
envelope_id="envelope-1",
tenant_id="tenant-1",
owner_module="files",
resource_type="file",
resource_id="file-1",
profile_kind="server_envelope",
profile_id="profile-1",
provider_id="test",
vault_id="vault-1",
key_version=1,
algorithm_suite="AES-256-GCM",
ciphertext_ref="object://ciphertext/1",
ciphertext_digest="sha256:ciphertext",
authenticated_context_digest="sha256:context",
state="active",
created_at=NOW,
metadata={"private_key": "forbidden"},
)
if __name__ == "__main__":
unittest.main()
+2 -2
View File
@@ -232,7 +232,7 @@ class ModuleSystemTests(unittest.TestCase):
self.assertTrue(manifests["campaigns"].required_capabilities)
self.assertEqual(
manifests["campaigns"].optional_dependencies,
("files", "mail", "notifications", "addresses", "postbox"),
("files", "mail", "notifications", "addresses", "postbox", "approvals"),
)
self.assertEqual(manifests["dashboard"].dependencies, ())
self.assertTrue(manifests["dashboard"].required_capabilities)
@@ -3433,7 +3433,7 @@ finally:
"version_max_exclusive": "0.3.0",
}, modules["campaigns"]["requires_interfaces"])
self.assertEqual(
["files", "mail", "notifications", "addresses", "postbox"],
["files", "mail", "notifications", "addresses", "postbox", "approvals"],
modules["campaigns"]["optional_dependencies"],
)
self.assertEqual("requires_review", modules["files"]["migration_safety"])
+7 -9
View File
@@ -42,6 +42,10 @@ class PlatformEventWorkerTests(unittest.TestCase):
"govoplan_core.celery_app._dataflow_trigger_dispatcher",
return_value=dataflow,
),
patch(
"govoplan_core.celery_app._workflow_trigger_dispatcher",
return_value=None,
),
patch(
"govoplan_core.db.session.get_database",
return_value=database,
@@ -109,21 +113,15 @@ class PlatformEventWorkerTests(unittest.TestCase):
def test_worker_routes_and_periodic_tasks_are_registered(self) -> None:
self.assertEqual(
{"queue": "events"},
celery.conf.task_routes[
"govoplan.events.dispatch_outbox"
],
celery.conf.task_routes["govoplan.events.dispatch_outbox"],
)
self.assertEqual(
{"queue": "events"},
celery.conf.task_routes[
"govoplan.events.purge_outbox"
],
celery.conf.task_routes["govoplan.events.purge_outbox"],
)
self.assertEqual(
"govoplan.events.purge_outbox",
celery.conf.beat_schedule[
"platform-event-retention-daily"
]["task"],
celery.conf.beat_schedule["platform-event-retention-daily"]["task"],
)
+36 -6
View File
@@ -12,12 +12,15 @@ from govoplan_core.core.registry import PlatformRegistry
from govoplan_core.core.workflows import (
CAPABILITY_WORKFLOW_DEFINITION_CONTRIBUTIONS,
CAPABILITY_WORKFLOW_RUNTIME_WORKER,
CAPABILITY_WORKFLOW_TRIGGER_DISPATCHER,
WorkflowDefinitionContribution,
WorkflowDefinitionContributionProvider,
WorkflowRuntimeWorker,
WorkflowTriggerDispatcher,
workflow_definition_contribution_hash,
workflow_definition_contribution_provider,
workflow_runtime_worker,
workflow_trigger_dispatcher,
)
@@ -31,6 +34,14 @@ class _ContributionProvider:
return {"created": 0, "tenant_ids": tuple(tenant_ids)}
class _TriggerDispatcher:
def dispatch_due(self, session, *, now=None, limit=50):
return {"selected": 0}
def ingest_event(self, session, *, event):
return {"queued": 0}
class WorkflowRuntimeWorkerTests(unittest.TestCase):
def test_contribution_contract_hash_and_provider_are_stable(self) -> None:
contribution = WorkflowDefinitionContribution(
@@ -77,9 +88,7 @@ class WorkflowRuntimeWorkerTests(unittest.TestCase):
name="Workflow runtime test",
version="test",
capability_factories={
CAPABILITY_WORKFLOW_RUNTIME_WORKER: (
lambda _context: worker
),
CAPABILITY_WORKFLOW_RUNTIME_WORKER: (lambda _context: worker),
},
)
)
@@ -90,6 +99,29 @@ class WorkflowRuntimeWorkerTests(unittest.TestCase):
self.assertIs(worker, workflow_runtime_worker(registry))
self.assertIsNone(workflow_runtime_worker(PlatformRegistry()))
def test_trigger_dispatch_contract_is_runtime_checkable_and_resolved(self) -> None:
dispatcher = _TriggerDispatcher()
self.assertIsInstance(dispatcher, WorkflowTriggerDispatcher)
registry = PlatformRegistry()
registry.register(
ModuleManifest(
id="workflow_trigger_test",
name="Workflow trigger test",
version="test",
capability_factories={
CAPABILITY_WORKFLOW_TRIGGER_DISPATCHER: (
lambda _context: dispatcher
),
},
)
)
registry.configure_capability_context(
ModuleContext(registry=registry, settings=object())
)
self.assertIs(dispatcher, workflow_trigger_dispatcher(registry))
self.assertIsNone(workflow_trigger_dispatcher(PlatformRegistry()))
def test_celery_task_commits_reconciliation(self) -> None:
session = MagicMock()
database = MagicMock()
@@ -121,9 +153,7 @@ class WorkflowRuntimeWorkerTests(unittest.TestCase):
{"queue": "workflow"},
celery.conf.task_routes["govoplan.workflow.reconcile"],
)
schedule = celery.conf.beat_schedule[
"workflow-reconcile-every-five-seconds"
]
schedule = celery.conf.beat_schedule["workflow-reconcile-every-five-seconds"]
self.assertEqual("govoplan.workflow.reconcile", schedule["task"])
self.assertEqual(5.0, schedule["schedule"])