From 5e449b09832dc0476252faec25f461294f49bf2b Mon Sep 17 00:00:00 2001 From: Albrecht Degering Date: Mon, 3 Aug 2026 07:02:34 +0200 Subject: [PATCH] Record Core lifecycle recovery adoption --- docs/RECOVERY_LEDGER_ADOPTION.md | 10 ++++++++++ docs/recovery-operation-inventory.json | 15 ++++++++++++--- tests/test_recovery_operation_inventory.py | 10 ++++++++-- 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/docs/RECOVERY_LEDGER_ADOPTION.md b/docs/RECOVERY_LEDGER_ADOPTION.md index 8779638..9b2b0f7 100644 --- a/docs/RECOVERY_LEDGER_ADOPTION.md +++ b/docs/RECOVERY_LEDGER_ADOPTION.md @@ -67,6 +67,16 @@ cannot be retried until evidence confirms either that the effect occurred or is absent. Linked Dataflow uncertainty blocks the Workflow without duplicating Dataflow's recovery authority. +Core module lifecycle is adopted at four boundaries. Installer recovery is +prepared before snapshots so a full database restore preserves the attempted +operation. Pre-migration package changes use compensation, migrated changes use +forward recovery, destructive retirement requires a hashed and restore-checked +snapshot, and live graph changes restore the prior registry when no migration +ran. A deployment-wide database fence serializes these effects; any unresolved +predecessor blocks a differently keyed retry until explicit reconciliation. +Supervised installs become successful only after restart and health evidence is +recorded. + ## Operator Contract Ops lists non-terminal and manual-intervention operations. Operators must verify diff --git a/docs/recovery-operation-inventory.json b/docs/recovery-operation-inventory.json index 999217e..2d040fb 100644 --- a/docs/recovery-operation-inventory.json +++ b/docs/recovery-operation-inventory.json @@ -161,7 +161,7 @@ "resources": ["postgresql", "package-environment", "webui-bundle", "filesystem"], "mode": "compensation", "fenced": true, - "adoption": "planned", + "adoption": "adopted", "issue": "https://git.add-ideas.de/GovOPlaN/govoplan-core/issues/281" }, { @@ -170,7 +170,7 @@ "resources": ["postgresql", "package-environment", "webui-bundle", "runtime-nodes"], "mode": "forward_recovery", "fenced": true, - "adoption": "planned", + "adoption": "adopted", "issue": "https://git.add-ideas.de/GovOPlaN/govoplan-core/issues/281" }, { @@ -179,7 +179,16 @@ "resources": ["postgresql", "object-storage", "package-environment"], "mode": "snapshot_restore", "fenced": true, - "adoption": "planned", + "adoption": "adopted", + "issue": "https://git.add-ideas.de/GovOPlaN/govoplan-core/issues/281" + }, + { + "id": "core.module-runtime.apply-graph", + "repository": "govoplan-core", + "resources": ["postgresql", "runtime-nodes", "module-registry"], + "mode": "compensation", + "fenced": true, + "adoption": "adopted", "issue": "https://git.add-ideas.de/GovOPlaN/govoplan-core/issues/281" } ] diff --git a/tests/test_recovery_operation_inventory.py b/tests/test_recovery_operation_inventory.py index 5451a67..d262b13 100644 --- a/tests/test_recovery_operation_inventory.py +++ b/tests/test_recovery_operation_inventory.py @@ -23,6 +23,11 @@ REQUIRED_PREFIXES = { "dataflow.", "workflow-engine.", "core.module-lifecycle.", + "core.module-runtime.", +} +ATOMIC_EXTERNAL_READS = { + "connectors.sync.read-snapshot", + "mail.mailbox.sync-cursor", } @@ -50,6 +55,7 @@ def test_non_atomic_operations_do_not_claim_plain_database_rollback() -> None: operations = json.loads(INVENTORY.read_text(encoding="utf-8"))["operations"] for item in operations: if item["mode"] == "atomic": - assert item["resources"] == ["postgresql"] or item["id"] == ( - "connectors.sync.read-snapshot" + assert ( + item["resources"] == ["postgresql"] + or item["id"] in ATOMIC_EXTERNAL_READS )