feat: implement institutional governance and recovery architecture
Dependency Audit / dependency-audit (push) Failing after 10s
Deployment Installer / deployment-installer (push) Successful in 6s
Security Audit / security-audit (push) Failing after 9s

This commit is contained in:
2026-08-01 17:46:53 +02:00
parent 3c658fa32d
commit d78b13f9d3
45 changed files with 4388 additions and 262 deletions
+56 -4
View File
@@ -28,6 +28,12 @@ LOCK_FILENAME = ".deployment.lock"
RUNTIME_ENV_KEYS = (
"APP_ENV",
"GOVOPLAN_INSTALL_PROFILE",
"GOVOPLAN_INSTALLATION_ID",
"GOVOPLAN_STATE_PROFILE",
"GOVOPLAN_RUNTIME_HEARTBEAT_SECONDS",
"GOVOPLAN_RUNTIME_STALE_AFTER_SECONDS",
"GOVOPLAN_EXPECTED_API_REPLICAS",
"GOVOPLAN_EXPECTED_WORKER_REPLICAS",
"MASTER_KEY_B64",
"DATABASE_URL",
"GOVOPLAN_DATABASE_URL_PGTOOLS",
@@ -55,6 +61,7 @@ RUNTIME_ENV_KEYS = (
"FILE_STORAGE_S3_SECRET_ACCESS_KEY",
"FILE_STORAGE_S3_BUCKET",
"FILE_STORAGE_S3_DEPLOYMENT_MANAGED",
"FILE_STORAGE_S3_ENDPOINT_TRUSTED",
)
@@ -169,6 +176,18 @@ def reconcile_runtime_environment(
{
"APP_ENV": "production" if spec.profile == "self-hosted" else "staging",
"GOVOPLAN_INSTALL_PROFILE": spec.profile,
"GOVOPLAN_INSTALLATION_ID": spec.installation_id,
# Generated Compose replicas share one Docker host. A deliberately
# Redis-free, single-API evaluation remains process-local; the
# Kubernetes exporter overrides this to ``shared`` for independent
# hosts.
"GOVOPLAN_STATE_PROFILE": (
"local" if redis.mode == "disabled" else "host-shared"
),
"GOVOPLAN_RUNTIME_HEARTBEAT_SECONDS": "15",
"GOVOPLAN_RUNTIME_STALE_AFTER_SECONDS": "60",
"GOVOPLAN_EXPECTED_API_REPLICAS": str(spec.replicas.api),
"GOVOPLAN_EXPECTED_WORKER_REPLICAS": str(spec.replicas.worker),
"ENABLED_MODULES": ",".join(spec.enabled_modules),
"CELERY_ENABLED": "true" if redis.mode != "disabled" else "false",
"CELERY_QUEUES": (
@@ -198,6 +217,7 @@ def reconcile_runtime_environment(
if storage.mode == "local":
values["FILE_STORAGE_BACKEND"] = "local"
values["FILE_STORAGE_S3_DEPLOYMENT_MANAGED"] = "false"
values["FILE_STORAGE_S3_ENDPOINT_TRUSTED"] = "false"
values["FILE_STORAGE_LOCAL_ROOT"] = "/var/lib/govoplan/files"
elif storage.mode == "garage":
access_key = values.setdefault(
@@ -221,11 +241,13 @@ def reconcile_runtime_environment(
"FILE_STORAGE_S3_SECRET_ACCESS_KEY": secret_key,
"FILE_STORAGE_S3_BUCKET": bucket,
"FILE_STORAGE_S3_DEPLOYMENT_MANAGED": "true",
"FILE_STORAGE_S3_ENDPOINT_TRUSTED": "false",
}
)
else:
values["FILE_STORAGE_BACKEND"] = "s3"
values["FILE_STORAGE_S3_DEPLOYMENT_MANAGED"] = "false"
values["FILE_STORAGE_S3_ENDPOINT_TRUSTED"] = "true"
required = (
"FILE_STORAGE_S3_ENDPOINT_URL",
"FILE_STORAGE_S3_REGION",
@@ -243,12 +265,13 @@ def reconcile_runtime_environment(
schemes={"http", "https"},
label="S3 endpoint URL",
)
if spec.profile == "self-hosted" and endpoint.scheme != "https":
raise ValueError("self-hosted S3 endpoint URL must use HTTPS")
if endpoint.scheme != "https":
raise ValueError("external S3 endpoint URL must use HTTPS")
return dict(sorted(values.items()))
def render_compose(spec: InstallationSpec) -> dict[str, object]:
health_host = urlsplit(spec.public_url).hostname or "localhost"
runtime_env = {
"environment": _environment_references(RUNTIME_ENV_KEYS),
}
@@ -378,6 +401,10 @@ def render_compose(spec: InstallationSpec) -> dict[str, object]:
services["migrate"] = {
**runtime_env,
"environment": {
**runtime_env["environment"],
"GOVOPLAN_RUNTIME_ROLE": "migration",
},
"image": spec.release.api_image,
"command": ["python", "-m", "govoplan_core.commands.init_db"],
"restart": "no",
@@ -387,6 +414,10 @@ def render_compose(spec: InstallationSpec) -> dict[str, object]:
}
services["api"] = {
**common_runtime,
"environment": {
**runtime_env["environment"],
"GOVOPLAN_RUNTIME_ROLE": "api",
},
"image": spec.release.api_image,
"scale": spec.replicas.api,
"command": [
@@ -407,7 +438,10 @@ def render_compose(spec: InstallationSpec) -> dict[str, object]:
"-c",
(
"import urllib.request;"
"urllib.request.urlopen('http://127.0.0.1:8000/health',timeout=3)"
"request=urllib.request.Request("
"'http://127.0.0.1:8000/health/ready',"
f"headers={{'Host': {health_host!r}}});"
"urllib.request.urlopen(request,timeout=3)"
),
],
"interval": "10s",
@@ -454,6 +488,10 @@ def render_compose(spec: InstallationSpec) -> dict[str, object]:
if spec.components.redis.mode != "disabled":
services["worker"] = {
**common_runtime,
"environment": {
**runtime_env["environment"],
"GOVOPLAN_RUNTIME_ROLE": "worker",
},
"image": spec.release.api_image,
"scale": spec.replicas.worker,
"command": [
@@ -474,8 +512,20 @@ def render_compose(spec: InstallationSpec) -> dict[str, object]:
}
services["scheduler"] = {
**common_runtime,
"environment": {
**runtime_env["environment"],
"GOVOPLAN_RUNTIME_ROLE": "scheduler",
},
"image": spec.release.api_image,
"command": [
"python",
"-m",
"govoplan_core.commands.fenced_run",
"--resource",
"scheduler:celery-beat",
"--wait-seconds",
"120",
"--",
"python",
"-m",
"celery",
@@ -531,6 +581,7 @@ api_bind_addr = "[::]:3903"
def render_load_balancer_config(spec: InstallationSpec) -> str:
health_host = urlsplit(spec.public_url).hostname or "localhost"
return f"""global
log stdout format raw local0
maxconn 4096
@@ -572,7 +623,8 @@ frontend internal_api
backend api_replicas
balance leastconn
option httpchk GET /health
option httpchk GET /health/ready
http-check send hdr Host {health_host}
http-check expect status 200
server-template api- {spec.replicas.api} api:8000 check resolvers docker init-addr libc,none
"""