feat: add governance operations dashboard

This commit is contained in:
2026-07-31 04:21:34 +02:00
parent 1ec47647ab
commit b84cab1aa4
6 changed files with 266 additions and 1 deletions
+7
View File
@@ -13,6 +13,9 @@ This repository owns:
- backend module manifest `ops` - backend module manifest `ops`
- operator-facing status APIs - operator-facing status APIs
- governance inventory for module-declared permissions, roles, capabilities,
policies, documentation, access-control hooks, search providers, and
migration ownership
- deployment profile and sizing assumption summaries - deployment profile and sizing assumption summaries
- WebUI route contribution `@govoplan/ops-webui` - WebUI route contribution `@govoplan/ops-webui`
- future operational runbooks that describe the configured platform rather than - future operational runbooks that describe the configured platform rather than
@@ -21,6 +24,10 @@ This repository owns:
Core owns lifecycle management, module discovery, maintenance mode, package Core owns lifecycle management, module discovery, maintenance mode, package
installation safety, and shared WebUI shell behavior. installation safety, and shared WebUI shell behavior.
Core exposes the registry contract but does not own an operations dashboard.
Ops projects the provider-neutral registry metadata and runtime checks into the
operator-facing governance surface.
## Runbooks ## Runbooks
- `docs/SCALABILITY_PROFILES.md` explains how to use the Ops page with the - `docs/SCALABILITY_PROFILES.md` explains how to use the Ops page with the
+45
View File
@@ -58,6 +58,7 @@ def _ops_status_payload(request: Request) -> dict[str, Any]:
_deployment_security_check(current_profile), _deployment_security_check(current_profile),
] ]
readiness = _readiness(checks, maintenance_mode) readiness = _readiness(checks, maintenance_mode)
governance = _governance_inventory(registry)
return { return {
"summary": { "summary": {
"app_env": core_settings.app_env, "app_env": core_settings.app_env,
@@ -72,6 +73,7 @@ def _ops_status_payload(request: Request) -> dict[str, Any]:
}, },
"readiness": readiness, "readiness": readiness,
"checks": checks, "checks": checks,
"governance": governance,
"deployment_profiles": _deployment_profiles(current_profile), "deployment_profiles": _deployment_profiles(current_profile),
"sizing": _sizing_assumptions(), "sizing": _sizing_assumptions(),
} }
@@ -84,6 +86,49 @@ def _registry(request: Request) -> PlatformRegistry:
return registry return registry
def _governance_inventory(registry: PlatformRegistry) -> dict[str, Any]:
modules: list[dict[str, Any]] = []
for manifest in registry.manifests():
capability_names = tuple(sorted(manifest.capability_factories))
access_control_count = (
len(manifest.resource_acl_providers)
+ len(manifest.ownership_providers)
+ sum(len(providers) for providers in manifest.delete_veto_providers.values())
+ len(manifest.uninstall_guard_providers)
)
modules.append({
"module_id": manifest.id,
"name": manifest.name,
"version": manifest.version,
"permission_count": len(manifest.permissions),
"role_template_count": len(manifest.role_templates),
"capability_count": len(capability_names),
"policy_count": sum(name.startswith("policy.") for name in capability_names),
"documentation_count": len(manifest.documentation),
"documentation_provider_count": len(manifest.documentation_providers),
"access_control_count": access_control_count,
"search_provider_count": len(manifest.search_providers) + len(manifest.search_sources),
"migration_managed": manifest.migration_spec is not None,
})
return {
"summary": {
"module_count": len(modules),
"permission_count": sum(item["permission_count"] for item in modules),
"role_template_count": sum(item["role_template_count"] for item in modules),
"capability_count": sum(item["capability_count"] for item in modules),
"policy_count": sum(item["policy_count"] for item in modules),
"documented_module_count": sum(
bool(item["documentation_count"] or item["documentation_provider_count"])
for item in modules
),
"access_control_count": sum(item["access_control_count"] for item in modules),
"search_provider_count": sum(item["search_provider_count"] for item in modules),
"migration_module_count": sum(bool(item["migration_managed"]) for item in modules),
},
"modules": modules,
}
def _database_status() -> dict[str, Any]: def _database_status() -> dict[str, Any]:
try: try:
with get_database().session() as session: with get_database().session() as session:
+83
View File
@@ -0,0 +1,83 @@
from __future__ import annotations
import unittest
from govoplan_core.core.modules import (
CapabilityDocumentation,
DocumentationTopic,
MigrationSpec,
ModuleManifest,
PermissionDefinition,
RoleTemplate,
)
from govoplan_core.core.registry import PlatformRegistry
from govoplan_ops.backend.api.v1.routes import _governance_inventory
class GovernanceInventoryTests(unittest.TestCase):
def test_inventory_projects_manifest_governance_without_provider_internals(self) -> None:
registry = PlatformRegistry()
registry.register(ModuleManifest(
id="example",
name="Example",
version="1.2.3",
permissions=(
PermissionDefinition(
scope="example:item:read",
label="Read examples",
description="Read example records.",
category="Examples",
level="tenant",
module_id="example",
resource="item",
action="read",
),
),
role_templates=(
RoleTemplate(
slug="example_reader",
name="Example reader",
description="Reads examples.",
permissions=("example:item:read",),
),
),
capability_factories={
"example.lookup": lambda _context: object(),
"policy.example": lambda _context: object(),
},
capability_documentation={
"example.lookup": CapabilityDocumentation(
label="Example lookup",
summary="Resolves examples.",
),
},
documentation=(
DocumentationTopic(
id="example.reference",
title="Example reference",
summary="Documents the example module.",
),
),
migration_spec=MigrationSpec(module_id="example"),
))
payload = _governance_inventory(registry)
self.assertEqual(payload["summary"]["module_count"], 1)
self.assertEqual(payload["summary"]["permission_count"], 1)
self.assertEqual(payload["summary"]["role_template_count"], 1)
self.assertEqual(payload["summary"]["capability_count"], 2)
self.assertEqual(payload["summary"]["policy_count"], 1)
self.assertEqual(payload["summary"]["documented_module_count"], 1)
self.assertEqual(payload["summary"]["migration_module_count"], 1)
self.assertEqual(payload["modules"][0]["module_id"], "example")
self.assertNotIn("capability_factories", payload["modules"][0])
self.assertFalse(any(
callable(value)
for value in payload["modules"][0].values()
))
if __name__ == "__main__":
unittest.main()
+29
View File
@@ -23,6 +23,21 @@ export type OpsSizingAssumption = {
operator_note: string; operator_note: string;
}; };
export type OpsGovernanceModule = {
module_id: string;
name: string;
version: string;
permission_count: number;
role_template_count: number;
capability_count: number;
policy_count: number;
documentation_count: number;
documentation_provider_count: number;
access_control_count: number;
search_provider_count: number;
migration_managed: boolean;
};
export type OpsStatus = { export type OpsStatus = {
summary: { summary: {
app_env: string; app_env: string;
@@ -49,6 +64,20 @@ export type OpsStatus = {
}>; }>;
}; };
checks: OpsCheck[]; checks: OpsCheck[];
governance: {
summary: {
module_count: number;
permission_count: number;
role_template_count: number;
capability_count: number;
policy_count: number;
documented_module_count: number;
access_control_count: number;
search_provider_count: number;
migration_module_count: number;
};
modules: OpsGovernanceModule[];
};
deployment_profiles: OpsDeploymentProfile[]; deployment_profiles: OpsDeploymentProfile[];
sizing: OpsSizingAssumption[]; sizing: OpsSizingAssumption[];
}; };
+80 -1
View File
@@ -14,7 +14,14 @@ import {
type ApiSettings, type ApiSettings,
type DataGridColumn } from type DataGridColumn } from
"@govoplan/core-webui"; "@govoplan/core-webui";
import { fetchOpsStatus, type OpsCheck, type OpsDeploymentProfile, type OpsSizingAssumption, type OpsStatus } from "../../api/ops"; import {
fetchOpsStatus,
type OpsCheck,
type OpsDeploymentProfile,
type OpsGovernanceModule,
type OpsSizingAssumption,
type OpsStatus
} from "../../api/ops";
export default function OpsPage({ settings }: {settings: ApiSettings;}) { export default function OpsPage({ settings }: {settings: ApiSettings;}) {
const [status, setStatus] = useState<OpsStatus | null>(null); const [status, setStatus] = useState<OpsStatus | null>(null);
@@ -60,6 +67,8 @@ export default function OpsPage({ settings }: {settings: ApiSettings;}) {
<MetricCard label="i18n:govoplan-ops.profile.ff4fc027" value={status?.summary.active_profile ?? "-"} tone="info" detail={status?.summary.database_url ?? "i18n:govoplan-ops.no_database_url.51a2db0c"} /> <MetricCard label="i18n:govoplan-ops.profile.ff4fc027" value={status?.summary.active_profile ?? "-"} tone="info" detail={status?.summary.database_url ?? "i18n:govoplan-ops.no_database_url.51a2db0c"} />
<MetricCard label="i18n:govoplan-ops.readiness.1db9d6fb" value={ready ? "ready" : "not ready"} tone={ready ? "good" : "danger"} detail={status?.readiness.blockers.length ? `${status.readiness.blockers.length} blocker(s)` : "i18n:govoplan-ops.no_readiness_blockers.0df259bd"} /> <MetricCard label="i18n:govoplan-ops.readiness.1db9d6fb" value={ready ? "ready" : "not ready"} tone={ready ? "good" : "danger"} detail={status?.readiness.blockers.length ? `${status.readiness.blockers.length} blocker(s)` : "i18n:govoplan-ops.no_readiness_blockers.0df259bd"} />
<MetricCard label="i18n:govoplan-ops.modules.04e9462c" value={status?.summary.module_count ?? 0} tone="neutral" detail="i18n:govoplan-ops.enabled_in_the_runtime_registry.d2c6142d" /> <MetricCard label="i18n:govoplan-ops.modules.04e9462c" value={status?.summary.module_count ?? 0} tone="neutral" detail="i18n:govoplan-ops.enabled_in_the_runtime_registry.d2c6142d" />
<MetricCard label="i18n:govoplan-ops.permissions.842c35eb" value={status?.governance.summary.permission_count ?? 0} tone="neutral" detail="i18n:govoplan-ops.declared_governance_permissions.d08d3bf1" />
<MetricCard label="i18n:govoplan-ops.policies.e7800f56" value={status?.governance.summary.policy_count ?? 0} tone="neutral" detail="i18n:govoplan-ops.registered_policy_capabilities.112a2b64" />
<MetricCard label="i18n:govoplan-ops.workers.b6ef3acd" value={status?.summary.celery_enabled ? "split" : "off"} tone={status?.summary.celery_enabled ? "good" : "warning"} detail={status?.summary.celery_queues?.length ? status.summary.celery_queues.join(", ") : "i18n:govoplan-ops.celery_worker_setting.323d7737"} /> <MetricCard label="i18n:govoplan-ops.workers.b6ef3acd" value={status?.summary.celery_enabled ? "split" : "off"} tone={status?.summary.celery_enabled ? "good" : "warning"} detail={status?.summary.celery_queues?.length ? status.summary.celery_queues.join(", ") : "i18n:govoplan-ops.celery_worker_setting.323d7737"} />
<MetricCard label="i18n:govoplan-ops.redis.5eaa1f2f" value={status?.summary.redis_url ? "configured" : "-"} tone={status?.summary.celery_enabled ? "info" : "neutral"} detail={status?.summary.redis_url ?? "-"} /> <MetricCard label="i18n:govoplan-ops.redis.5eaa1f2f" value={status?.summary.redis_url ? "configured" : "-"} tone={status?.summary.celery_enabled ? "info" : "neutral"} detail={status?.summary.redis_url ?? "-"} />
<MetricCard label="i18n:govoplan-ops.warnings.1430f976" value={warningCount + errorCount} tone={errorCount ? "danger" : warningCount ? "warning" : "good"} detail="i18n:govoplan-ops.current_health_checks.7830bccf" /> <MetricCard label="i18n:govoplan-ops.warnings.1430f976" value={warningCount + errorCount} tone={errorCount ? "danger" : warningCount ? "warning" : "good"} detail="i18n:govoplan-ops.current_health_checks.7830bccf" />
@@ -70,6 +79,10 @@ export default function OpsPage({ settings }: {settings: ApiSettings;}) {
<CheckList checks={checks} /> <CheckList checks={checks} />
</Card> </Card>
<Card title="i18n:govoplan-ops.governance_inventory.835d8e57">
<GovernanceTable modules={status?.governance.modules ?? []} />
</Card>
<Card title="i18n:govoplan-ops.deployment_profiles.b0caa179"> <Card title="i18n:govoplan-ops.deployment_profiles.b0caa179">
<ProfileList profiles={status?.deployment_profiles ?? []} /> <ProfileList profiles={status?.deployment_profiles ?? []} />
</Card> </Card>
@@ -84,6 +97,72 @@ export default function OpsPage({ settings }: {settings: ApiSettings;}) {
} }
function GovernanceTable({ modules }: { modules: OpsGovernanceModule[] }) {
const columns: DataGridColumn<OpsGovernanceModule>[] = [
{
id: "module",
header: "i18n:govoplan-ops.module.b8ff0289",
width: "minmax(200px, 1fr)",
minWidth: 180,
resizable: true,
sortable: true,
filterable: true,
value: (module) => `${module.name} ${module.module_id} ${module.version}`,
render: (module) => <div><strong>{module.name}</strong><span className="muted block">{module.module_id} · {module.version}</span></div>
},
{
id: "authority",
header: "i18n:govoplan-ops.authority.8802e425",
width: "minmax(190px, .8fr)",
minWidth: 170,
resizable: true,
value: (module) => `${module.permission_count} ${module.role_template_count}`,
render: (module) => `${module.permission_count} permissions · ${module.role_template_count} roles`
},
{
id: "contracts",
header: "i18n:govoplan-ops.contracts.57d80902",
width: "minmax(190px, .8fr)",
minWidth: 170,
resizable: true,
value: (module) => `${module.capability_count} ${module.policy_count}`,
render: (module) => `${module.capability_count} capabilities · ${module.policy_count} policies`
},
{
id: "controls",
header: "i18n:govoplan-ops.controls.0cdb80fb",
width: "minmax(190px, .8fr)",
minWidth: 170,
resizable: true,
value: (module) => `${module.access_control_count} ${module.search_provider_count}`,
render: (module) => `${module.access_control_count} access · ${module.search_provider_count} search`
},
{
id: "evidence",
header: "i18n:govoplan-ops.evidence.7ea014de",
width: "minmax(190px, .8fr)",
minWidth: 170,
resizable: true,
value: (module) => `${module.documentation_count} ${module.documentation_provider_count} ${module.migration_managed}`,
render: (module) => (
<div>
{module.documentation_count + module.documentation_provider_count} docs
<span className="muted block">{module.migration_managed ? "migration managed" : "no module migrations"}</span>
</div>
)
}
];
return (
<DataGrid
id="ops-governance-inventory"
rows={modules}
columns={columns}
getRowKey={(module) => module.module_id}
emptyText="i18n:govoplan-ops.no_modules_reported.847f06d9"
/>
);
}
function CheckList({ checks }: {checks: OpsCheck[];}) { function CheckList({ checks }: {checks: OpsCheck[];}) {
if (!checks.length) return <p className="muted">i18n:govoplan-ops.no_health_checks_reported.03c067c4</p>; if (!checks.length) return <p className="muted">i18n:govoplan-ops.no_health_checks_reported.03c067c4</p>;
return ( return (
+22
View File
@@ -4,25 +4,36 @@ export const generatedTranslations: PlatformTranslations = {
"en": { "en": {
"i18n:govoplan-ops.area.2745deba": "Area", "i18n:govoplan-ops.area.2745deba": "Area",
"i18n:govoplan-ops.baseline.e6ab7982": "Baseline", "i18n:govoplan-ops.baseline.e6ab7982": "Baseline",
"i18n:govoplan-ops.authority.8802e425": "Authority",
"i18n:govoplan-ops.celery_worker_setting.323d7737": "Celery worker setting", "i18n:govoplan-ops.celery_worker_setting.323d7737": "Celery worker setting",
"i18n:govoplan-ops.components.9289473e": "Components", "i18n:govoplan-ops.components.9289473e": "Components",
"i18n:govoplan-ops.current_health_checks.7830bccf": "Current health checks", "i18n:govoplan-ops.current_health_checks.7830bccf": "Current health checks",
"i18n:govoplan-ops.contracts.57d80902": "Contracts",
"i18n:govoplan-ops.controls.0cdb80fb": "Controls",
"i18n:govoplan-ops.declared_governance_permissions.d08d3bf1": "Declared governance permissions",
"i18n:govoplan-ops.deployment_profiles.b0caa179": "Deployment Profiles", "i18n:govoplan-ops.deployment_profiles.b0caa179": "Deployment Profiles",
"i18n:govoplan-ops.enabled_in_the_runtime_registry.d2c6142d": "Enabled in the runtime registry", "i18n:govoplan-ops.enabled_in_the_runtime_registry.d2c6142d": "Enabled in the runtime registry",
"i18n:govoplan-ops.evidence.7ea014de": "Evidence",
"i18n:govoplan-ops.fit.dab564d8": "Fit", "i18n:govoplan-ops.fit.dab564d8": "Fit",
"i18n:govoplan-ops.health_checks.201c869f": "Health Checks", "i18n:govoplan-ops.health_checks.201c869f": "Health Checks",
"i18n:govoplan-ops.governance_inventory.835d8e57": "Governance Inventory",
"i18n:govoplan-ops.loading_operations_status.6890fe6e": "Loading operations status...", "i18n:govoplan-ops.loading_operations_status.6890fe6e": "Loading operations status...",
"i18n:govoplan-ops.modules.04e9462c": "Modules", "i18n:govoplan-ops.modules.04e9462c": "Modules",
"i18n:govoplan-ops.module.b8ff0289": "Module",
"i18n:govoplan-ops.no_database_url.51a2db0c": "No database URL", "i18n:govoplan-ops.no_database_url.51a2db0c": "No database URL",
"i18n:govoplan-ops.no_deployment_profiles_reported.7c3af1db": "No deployment profiles reported.", "i18n:govoplan-ops.no_deployment_profiles_reported.7c3af1db": "No deployment profiles reported.",
"i18n:govoplan-ops.no_health_checks_reported.03c067c4": "No health checks reported.", "i18n:govoplan-ops.no_health_checks_reported.03c067c4": "No health checks reported.",
"i18n:govoplan-ops.no_modules_reported.847f06d9": "No modules reported.",
"i18n:govoplan-ops.no_sizing_assumptions_reported.17515959": "No sizing assumptions reported.", "i18n:govoplan-ops.no_sizing_assumptions_reported.17515959": "No sizing assumptions reported.",
"i18n:govoplan-ops.operator_note.1dc58f7b": "Operator note", "i18n:govoplan-ops.operator_note.1dc58f7b": "Operator note",
"i18n:govoplan-ops.ops.907a54c2": "Ops", "i18n:govoplan-ops.ops.907a54c2": "Ops",
"i18n:govoplan-ops.permissions.842c35eb": "Permissions",
"i18n:govoplan-ops.policies.e7800f56": "Policies",
"i18n:govoplan-ops.profile.ff4fc027": "Profile", "i18n:govoplan-ops.profile.ff4fc027": "Profile",
"i18n:govoplan-ops.readiness.1db9d6fb": "Readiness", "i18n:govoplan-ops.readiness.1db9d6fb": "Readiness",
"i18n:govoplan-ops.reload.cce71553": "Reload", "i18n:govoplan-ops.reload.cce71553": "Reload",
"i18n:govoplan-ops.redis.5eaa1f2f": "Redis", "i18n:govoplan-ops.redis.5eaa1f2f": "Redis",
"i18n:govoplan-ops.registered_policy_capabilities.112a2b64": "Registered policy capabilities",
"i18n:govoplan-ops.no_readiness_blockers.0df259bd": "No readiness blockers", "i18n:govoplan-ops.no_readiness_blockers.0df259bd": "No readiness blockers",
"i18n:govoplan-ops.runtime_health_deployment_profile_worker_split_a.55340156": "Runtime health, deployment profile, worker split, and sizing assumptions.", "i18n:govoplan-ops.runtime_health_deployment_profile_worker_split_a.55340156": "Runtime health, deployment profile, worker split, and sizing assumptions.",
"i18n:govoplan-ops.scale_trigger.1c85e10e": "Scale trigger", "i18n:govoplan-ops.scale_trigger.1c85e10e": "Scale trigger",
@@ -34,25 +45,36 @@ export const generatedTranslations: PlatformTranslations = {
"de": { "de": {
"i18n:govoplan-ops.area.2745deba": "Area", "i18n:govoplan-ops.area.2745deba": "Area",
"i18n:govoplan-ops.baseline.e6ab7982": "Baseline", "i18n:govoplan-ops.baseline.e6ab7982": "Baseline",
"i18n:govoplan-ops.authority.8802e425": "Berechtigungen",
"i18n:govoplan-ops.celery_worker_setting.323d7737": "Celery worker setting", "i18n:govoplan-ops.celery_worker_setting.323d7737": "Celery worker setting",
"i18n:govoplan-ops.components.9289473e": "Components", "i18n:govoplan-ops.components.9289473e": "Components",
"i18n:govoplan-ops.current_health_checks.7830bccf": "Current health checks", "i18n:govoplan-ops.current_health_checks.7830bccf": "Current health checks",
"i18n:govoplan-ops.contracts.57d80902": "Verträge",
"i18n:govoplan-ops.controls.0cdb80fb": "Kontrollen",
"i18n:govoplan-ops.declared_governance_permissions.d08d3bf1": "Deklarierte Governance-Berechtigungen",
"i18n:govoplan-ops.deployment_profiles.b0caa179": "Deployment Profiles", "i18n:govoplan-ops.deployment_profiles.b0caa179": "Deployment Profiles",
"i18n:govoplan-ops.enabled_in_the_runtime_registry.d2c6142d": "Enabled in the runtime registry", "i18n:govoplan-ops.enabled_in_the_runtime_registry.d2c6142d": "Enabled in the runtime registry",
"i18n:govoplan-ops.evidence.7ea014de": "Nachweise",
"i18n:govoplan-ops.fit.dab564d8": "Fit", "i18n:govoplan-ops.fit.dab564d8": "Fit",
"i18n:govoplan-ops.health_checks.201c869f": "Health Checks", "i18n:govoplan-ops.health_checks.201c869f": "Health Checks",
"i18n:govoplan-ops.governance_inventory.835d8e57": "Governance-Inventar",
"i18n:govoplan-ops.loading_operations_status.6890fe6e": "Loading operations status...", "i18n:govoplan-ops.loading_operations_status.6890fe6e": "Loading operations status...",
"i18n:govoplan-ops.modules.04e9462c": "Module", "i18n:govoplan-ops.modules.04e9462c": "Module",
"i18n:govoplan-ops.module.b8ff0289": "Modul",
"i18n:govoplan-ops.no_database_url.51a2db0c": "No database URL", "i18n:govoplan-ops.no_database_url.51a2db0c": "No database URL",
"i18n:govoplan-ops.no_deployment_profiles_reported.7c3af1db": "No deployment profiles reported.", "i18n:govoplan-ops.no_deployment_profiles_reported.7c3af1db": "No deployment profiles reported.",
"i18n:govoplan-ops.no_health_checks_reported.03c067c4": "No health checks reported.", "i18n:govoplan-ops.no_health_checks_reported.03c067c4": "No health checks reported.",
"i18n:govoplan-ops.no_modules_reported.847f06d9": "Keine Module gemeldet.",
"i18n:govoplan-ops.no_sizing_assumptions_reported.17515959": "No sizing assumptions reported.", "i18n:govoplan-ops.no_sizing_assumptions_reported.17515959": "No sizing assumptions reported.",
"i18n:govoplan-ops.operator_note.1dc58f7b": "Operator note", "i18n:govoplan-ops.operator_note.1dc58f7b": "Operator note",
"i18n:govoplan-ops.ops.907a54c2": "Betrieb", "i18n:govoplan-ops.ops.907a54c2": "Betrieb",
"i18n:govoplan-ops.permissions.842c35eb": "Berechtigungen",
"i18n:govoplan-ops.policies.e7800f56": "Richtlinien",
"i18n:govoplan-ops.profile.ff4fc027": "Profil", "i18n:govoplan-ops.profile.ff4fc027": "Profil",
"i18n:govoplan-ops.readiness.1db9d6fb": "Bereitschaft", "i18n:govoplan-ops.readiness.1db9d6fb": "Bereitschaft",
"i18n:govoplan-ops.reload.cce71553": "Neu laden", "i18n:govoplan-ops.reload.cce71553": "Neu laden",
"i18n:govoplan-ops.redis.5eaa1f2f": "Redis", "i18n:govoplan-ops.redis.5eaa1f2f": "Redis",
"i18n:govoplan-ops.registered_policy_capabilities.112a2b64": "Registrierte Richtlinien-Fähigkeiten",
"i18n:govoplan-ops.no_readiness_blockers.0df259bd": "Keine Bereitschaftsblocker", "i18n:govoplan-ops.no_readiness_blockers.0df259bd": "Keine Bereitschaftsblocker",
"i18n:govoplan-ops.runtime_health_deployment_profile_worker_split_a.55340156": "Runtime health, deployment profile, worker split, and sizing assumptions.", "i18n:govoplan-ops.runtime_health_deployment_profile_worker_split_a.55340156": "Runtime health, deployment profile, worker split, and sizing assumptions.",
"i18n:govoplan-ops.scale_trigger.1c85e10e": "Scale trigger", "i18n:govoplan-ops.scale_trigger.1c85e10e": "Scale trigger",