feat: govern shared campaign artifact storage

This commit is contained in:
2026-08-01 17:48:24 +02:00
parent 82ddc0c34c
commit cec3d17bff
15 changed files with 518 additions and 159 deletions
+45
View File
@@ -28,6 +28,7 @@ from govoplan_core.core.modules import (
RoleTemplate,
)
from govoplan_core.core.operations import OperationalCheckProviderRegistration
from govoplan_core.core.provider_governance import declared_module_architecture
from govoplan_core.core.views import ViewSurface
from govoplan_core.db.base import Base
from govoplan_core.core.postbox import (
@@ -718,6 +719,37 @@ manifest = ModuleManifest(
],
},
),
DocumentationTopic(
id="campaigns.reference.shared-build-artifacts",
title="Operate Campaign build artifacts across workers",
summary="Generated messages use shared object storage and are verified before delivery.",
body="Campaign stores generated EML under opaque shared object keys and records expected size, SHA-256 digest, and Message-ID in each job. A worker may run on another node and verifies that evidence before delivery. Failed builds compensate newly written objects; retention retains metadata when deletion fails. Never copy or edit runtime object keys as business data.",
layer="evidence",
documentation_types=("admin",),
audience=("campaign_operator", "platform_operator", "release_reviewer"),
order=53,
conditions=(
DocumentationCondition(
required_modules=("campaigns",),
any_scopes=("campaigns:diagnostic:read", "system:settings:read"),
),
),
links=(
DocumentationLink(label="Campaign operator queue", href="/campaigns/queue", kind="runtime"),
DocumentationLink(label="Campaign delivery runbook", href="govoplan-campaign/docs/CAMPAIGN_DELIVERY_RUNBOOK.md", kind="repository"),
),
related_modules=("files", "ops", "mail"),
metadata={
"kind": "reference",
"route": "/campaigns/queue",
"screen": "Campaign operator queue",
"verification": "Build on one replica, deliver from another, verify object digest/size evidence, and exercise storage failure during build and retention.",
"limitations": [
"A hard process loss between object creation and database commit can leave an orphan object until an inventory reconciler removes it.",
"Database, object storage, and encryption keys require a coordinated deployment backup and restore procedure.",
],
},
),
),
documentation_providers=(documentation_topics,),
ownership_providers=(
@@ -762,6 +794,19 @@ manifest = ModuleManifest(
cache_seconds=60,
),
),
architecture=declared_module_architecture(
layer="communication_participation",
kind="domain",
maturity="vertical_slice",
documentation_ref="docs/CAMPAIGN_HANDBOOK.md",
test_ref="tests/test_execution_snapshot_integrity.py",
known_limits=("Target-environment recovery and accessibility evidence is incomplete for reference-ready maturity.",),
owned_concepts=("campaign", "campaign version", "recipient snapshot", "delivery job", "delivery report"),
non_owned_concepts=("mail transport", "postbox", "durable address directory", "file storage"),
recovery_docs=("docs/CAMPAIGN_DELIVERY_RUNBOOK.md",),
security_docs=("docs/ACCESS_EXPLANATION_COVERAGE.md",),
operations_docs=("docs/CAMPAIGN_DELIVERY_RUNBOOK.md",),
),
)