From 23ffe2cf4b214666754a2420558943438e54251a Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 31 Oct 2026 04:21:17 +0100 Subject: [PATCH] Reconcile backup snapshot pin and seal operating sources Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a18e2d-f513-7742-b8e7-12af0b744ff3 --- .../backup-operating-delivery-2026-10-31.json | 271 ++++++++++++++++++ .../backup-operating-delivery-2026-10-31.md | 66 +++++ .../backup-operating-preflight-2026-10-30.md | 12 +- scripts/snapshot-content-and-db.py | 2 +- ...0012-durable-recovery-service-readiness.md | 14 + 5 files changed, 363 insertions(+), 2 deletions(-) create mode 100644 docs/release/backup-operating-delivery-2026-10-31.json create mode 100644 docs/release/backup-operating-delivery-2026-10-31.md diff --git a/docs/release/backup-operating-delivery-2026-10-31.json b/docs/release/backup-operating-delivery-2026-10-31.json new file mode 100644 index 0000000..24caf34 --- /dev/null +++ b/docs/release/backup-operating-delivery-2026-10-31.json @@ -0,0 +1,271 @@ +{ + "schema": "coulomb.backup-operating-delivery-preparation.v1", + "status": "sources_sealed_not_installed", + "manifest_sha256": "dd00360997f29d82e133211316514c5f853d5f28f92a7b4ea4e279a3e517dab9", + "archive_sha256": "76af8159d0e4e7f71c115fcc44e1c6b59150dfc9b5a83e37258c9039f02178fe", + "archive_bytes": 143360, + "private_archive": "/home/worsch/.config/railiance-platform/coulomb-social-recovery/operating-delivery-20261031/sources.tar", + "manifest": { + "schema": "coulomb.backup-operating-source-bundle.v1", + "created_at": "2026-10-31T03:19:49.147938+00:00", + "status": "prepared_not_admitted", + "files": [ + { + "source": "scripts/paired-backup.py", + "member": "consumer/paired-backup.py", + "target": "/opt/coulomb-social-backup/paired-backup.py", + "mode": "0600", + "sha256": "d161c742d1a6a182460a57d0a1719591ab58fc94006f55169ad3d74442a93630", + "bytes": 14911 + }, + { + "source": "scripts/snapshot-content-and-db.py", + "member": "consumer/snapshot-content-and-db.py", + "target": "/opt/coulomb-social-backup/snapshot-content-and-db.py", + "mode": "0600", + "sha256": "4ff81b791daf6c8b976a4f89ef152e52f385fc1656986e2ea28bf555b9bd0d8a", + "bytes": 7702 + }, + { + "source": "scripts/mirror-paired-backup.py", + "member": "consumer/mirror-paired-backup.py", + "target": "/opt/coulomb-social-backup/mirror-paired-backup.py", + "mode": "0600", + "sha256": "9ceb26d9083af016c4b787907e4dce7bdf437c782fb2d15eb28d9e334e6e431c", + "bytes": 10546 + }, + { + "source": "scripts/check-paired-backup-health.py", + "member": "consumer/check-paired-backup-health.py", + "target": "/opt/coulomb-social-backup/check-paired-backup-health.py", + "mode": "0600", + "sha256": "c003871fe91c5c31788fd9bfc50aef3b2a275c06c5a42c2c3165b92d5ea80db9", + "bytes": 10217 + }, + { + "source": "scripts/backup_capacity.py", + "member": "consumer/backup_capacity.py", + "target": "/opt/coulomb-social-backup/backup_capacity.py", + "mode": "0600", + "sha256": "cb699a79e67b129239b5aa5d6f3b0d4ffaa9773a8b073227ad17fdecb5b9d893", + "bytes": 5312 + }, + { + "source": "deploy/backup/mirror-platform-runtime.json", + "member": "consumer/mirror-platform-runtime.json", + "target": "/opt/coulomb-social-backup/mirror-platform-runtime.json", + "mode": "0600", + "sha256": "9253c5f6e956b67f499d3e12d2851be7fabd3bc56b00496b8810bbd0be8209f1", + "bytes": 597 + }, + { + "source": "/home/worsch/railiance-platform/scripts/application_recovery_identities.py", + "member": "platform/application_recovery_identities.py", + "target": "/opt/railiance-platform/scripts/application_recovery_identities.py", + "mode": "0600", + "sha256": "20f56255ed6eeec4aafe33f142bc3ee03f623d4957a7b0cabb741d340f15f79d", + "bytes": 19065 + }, + { + "source": "/home/worsch/railiance-platform/scripts/application_recovery_mirror.py", + "member": "platform/application_recovery_mirror.py", + "target": "/opt/railiance-platform/scripts/application_recovery_mirror.py", + "mode": "0600", + "sha256": "d48ab95e89b9eeae36269d853ebe4c44c22e1f57d4e14224f03d0b9aeeb34178", + "bytes": 6927 + }, + { + "source": "/home/worsch/railiance-platform/scripts/application_recovery_resources.py", + "member": "platform/application_recovery_resources.py", + "target": "/opt/railiance-platform/scripts/application_recovery_resources.py", + "mode": "0600", + "sha256": "ab70ec341e738272730eb0daf76840d0bca807caeb3c4e4c2357f162fbed4498", + "bytes": 23619 + }, + { + "source": "/home/worsch/railiance-platform/scripts/primary_application_archive.py", + "member": "platform/primary_application_archive.py", + "target": "/opt/railiance-platform/scripts/primary_application_archive.py", + "mode": "0600", + "sha256": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d", + "bytes": 13612 + }, + { + "source": "deploy/backup/coulomb-social-backup-freshness.service", + "member": "units/coulomb-social-backup-freshness.service", + "target": "/etc/systemd/system/coulomb-social-backup-freshness.service", + "mode": "0644", + "sha256": "aaed68bc4bce752eb55a22c1b14bf74df306f1b0c017bd5bdfaff0f0943878d8", + "bytes": 528 + }, + { + "source": "deploy/backup/coulomb-social-paired-backup.service", + "member": "units/coulomb-social-paired-backup.service", + "target": "/etc/systemd/system/coulomb-social-paired-backup.service", + "mode": "0644", + "sha256": "fe637fb31ef077be4edbbc94540fcce4ab1badde6a6a0e232bed4f0de5bf4324", + "bytes": 1271 + }, + { + "source": "deploy/backup/coulomb-social-backup-freshness.timer", + "member": "units/coulomb-social-backup-freshness.timer", + "target": "/etc/systemd/system/coulomb-social-backup-freshness.timer", + "mode": "0644", + "sha256": "75d1d0721c07fdd0703910c06bb8a678396440e7d95411a37ee7de4938f3ac31", + "bytes": 198 + }, + { + "source": "deploy/backup/coulomb-social-paired-backup.timer", + "member": "units/coulomb-social-paired-backup.timer", + "target": "/etc/systemd/system/coulomb-social-paired-backup.timer", + "mode": "0644", + "sha256": "5e87235e66f89a64a972562d6f163f62420628fc44fb7fd8d603a96c347dfbb9", + "bytes": 234 + }, + { + "source": "/home/worsch/railiance-platform/requirements/backup-primary.lock", + "member": "evidence/backup-primary.lock", + "target": null, + "mode": null, + "sha256": "7142d3690855a6fcfdd2dac02113e7a76b6731988d52b4b013a50d97570f2aaa", + "bytes": 1711 + } + ], + "observed_preconditions": { + "observed_at": "2026-10-31T03:19:21.996368+00:00", + "files": { + "/opt/coulomb-social-backup/paired-backup.py": { + "exists": true, + "sha256": "43e119acb6a4933b4e144c349a091e074e1a91ab61dbe15a65c8264c1d47661a", + "uid": 0, + "gid": 0, + "mode": "0o600" + }, + "/opt/coulomb-social-backup/snapshot-content-and-db.py": { + "exists": true, + "sha256": "4ff81b791daf6c8b976a4f89ef152e52f385fc1656986e2ea28bf555b9bd0d8a", + "uid": 0, + "gid": 0, + "mode": "0o600" + }, + "/opt/coulomb-social-backup/mirror-paired-backup.py": { + "exists": false + }, + "/opt/coulomb-social-backup/check-paired-backup-health.py": { + "exists": false + }, + "/opt/coulomb-social-backup/backup_capacity.py": { + "exists": false + }, + "/opt/coulomb-social-backup/mirror-platform-runtime.json": { + "exists": false + }, + "/opt/railiance-platform/scripts/primary_application_archive.py": { + "exists": true, + "sha256": "a3f0a61e869a6012edb4b5288be14e3b0c4a9a1273b090320ab146d12e5aa94d", + "uid": 0, + "gid": 0, + "mode": "0o644" + }, + "/opt/railiance-platform/scripts/application_recovery_mirror.py": { + "exists": false + }, + "/opt/railiance-platform/scripts/application_recovery_resources.py": { + "exists": false + }, + "/opt/railiance-platform/scripts/application_recovery_identities.py": { + "exists": false + }, + "/etc/systemd/system/coulomb-social-paired-backup.service": { + "exists": false + }, + "/etc/systemd/system/coulomb-social-paired-backup.timer": { + "exists": false + }, + "/etc/systemd/system/coulomb-social-backup-freshness.service": { + "exists": false + }, + "/etc/systemd/system/coulomb-social-backup-freshness.timer": { + "exists": false + } + }, + "units": { + "coulomb-social-paired-backup.service": { + "command_returncode": 0, + "properties": { + "LoadState": "not-found", + "ActiveState": "inactive", + "SubState": "dead", + "UnitFileState": "" + } + }, + "coulomb-social-paired-backup.timer": { + "command_returncode": 0, + "properties": { + "LoadState": "not-found", + "ActiveState": "inactive", + "SubState": "dead", + "UnitFileState": "" + } + }, + "coulomb-social-backup-freshness.service": { + "command_returncode": 0, + "properties": { + "LoadState": "not-found", + "ActiveState": "inactive", + "SubState": "dead", + "UnitFileState": "" + } + }, + "coulomb-social-backup-freshness.timer": { + "command_returncode": 0, + "properties": { + "LoadState": "not-found", + "ActiveState": "inactive", + "SubState": "dead", + "UnitFileState": "" + } + } + } + }, + "snapshot_server_dry_run": { + "status": "reviewed", + "server_dry_run": true, + "image_pinned": true, + "pvc_read_only": true, + "db_scope": "coulomb_social_db", + "replicas_restored_to": 1 + }, + "limits_proposed": { + "file_bytes": 1073741824, + "state_bytes": 8589934592, + "free_bytes": 8589934592, + "inodes": 1024 + }, + "existing_approvals": { + "node_executor_and_publisher": "9557e2b8-2b37-5b94-a5e6-e5fe08d0351e", + "independent_recovery_custody": "27bbc1ac-e275-42be-ba34-6cf16eae4e78", + "schedule": "daily 03:15 UTC; jitter <=5min; RPO24h; stale26h; attended RTO60min" + }, + "unresolved": [ + "capacity admission", + "compatible rolling retention and expiry authority/native execution", + "historical private-copy disposition", + "named monitored alert receiver and received failed/pending/stale proof", + "exact installation execution plan and native service-run review" + ], + "installer_included": false, + "credentials_included": false, + "production_mutations": false, + "timers_activated": false + }, + "archive_members_verified": 16, + "application_tests": { + "command": "make check", + "tests": 441, + "failures": 0, + "errors": 0, + "skipped": 0, + "junit_sha256": "1e5b3c63d85a23f176420f2004831b59406d294c1528b3be80d49669edbb116f" + } +} diff --git a/docs/release/backup-operating-delivery-2026-10-31.md b/docs/release/backup-operating-delivery-2026-10-31.md new file mode 100644 index 0000000..9e4aedb --- /dev/null +++ b/docs/release/backup-operating-delivery-2026-10-31.md @@ -0,0 +1,66 @@ +# Backup operating source delivery review + +The repository snapshot helper now matches the exact helper installed by the +verified storage release: SHA-256 +`4ff81b791daf6c8b976a4f89ef152e52f385fc1656986e2ea28bf555b9bd0d8a`. +Its image pin is the live `51281946…` digest. The previous repository copy still +targeted `9a646d8e…`; copying it during an operating installation would have +reintroduced that stale pin and caused capture to refuse the deployed release. +Only the source pin changed. The node helper was already correct. + +The installed helper's default server dry-run passes against the cluster, pinned +image and read-only content PVC. No capture, application pause or provider call +was requested. Full `make check` passes all 441 tests, including the required +browser journeys, with zero skips. + +## Exact source bundle + +A private 143,360-byte tar contains the five consumer Python files, runtime +manifest, four hash-pinned platform Python files, four candidate units and the +SDK dependency lock as review evidence, plus the bundle manifest. All 16 members +were read back and compared. No credential or application data is included. + +Location: +`~/.config/railiance-platform/coulomb-social-recovery/operating-delivery-20261031/sources.tar` + +Archive SHA-256: +`76af8159d0e4e7f71c115fcc44e1c6b59150dfc9b5a83e37258c9039f02178fe` + +Manifest SHA-256: +`dd00360997f29d82e133211316514c5f853d5f28f92a7b4ea4e279a3e517dab9` + +The JSON companion records every member's hash, byte count, intended target and +mode. It also records current installed file hashes and systemd metadata. The +SDK lock has no installation target: it documents the required dependency set, +and does not authorize changing the existing environment. The four platform +sources exactly match the existing reviewed runtime manifest. + +The node currently has the paired worker, refreshed snapshot helper and primary +transport helper. The other proposed helper/manifest files and all four units +are absent at their intended paths; the units report not-found/inactive/dead. +These observations are installation preconditions to recheck, not permission +to overwrite future changes. Historical release/date receipts remain unchanged. + +## Operating acceptance still required + +The bundle is source delivery material, not an installer or an activation +receipt. It does not supply a notification receiver or enforcement of provider +retention. Before installation/execution is ready for final review: + +1. Admit the proposed capacity profile from + `backup-capacity-review-2026-10-30.md` and complete the compatible rolling + retention/expiry return. The separately prepared expiry executor has not run. +2. Record the disposition of retained historical private copies. +3. Identify the monitored alert destination and responding owner, prepare that + integration, and prove received failed/pending/stale signals under the + applicable send authorization. A queued event or local journal is insufficient. +4. Complete the exact installation/rollback procedure, preserving the current + correct snapshot helper and source/runtime pins. Install units disabled, + verify the admitted native service run and independent receipt, and only then + activate and verify the already approved timers. + +Existing node/publisher, recovery custody and daily 03:15 UTC schedule approvals +remain valid. No repeated approval of those scopes is required. The open capacity, +retention, monitoring and execution requirements are the existing WP-0012 and +RPF-WP-0053 obligations; this preparation does not replace them with a smaller +completion criterion. diff --git a/docs/release/backup-operating-preflight-2026-10-30.md b/docs/release/backup-operating-preflight-2026-10-30.md index 9657fc8..605a69b 100644 --- a/docs/release/backup-operating-preflight-2026-10-30.md +++ b/docs/release/backup-operating-preflight-2026-10-30.md @@ -49,7 +49,8 @@ scheduled checker and the proposed new one have not been installed by this work. while the previous point lacks its required mirror/receipt. The source worker, pinned dependency manifest and pre/post service hooks are now prepared in mirror-worker-operating-review-2026-10-30.md. Its synthetic - integration is verified; native publication/retrieval is still outstanding. + integration and October 31 native publication/independent retrieval are + verified; the scheduled node service run remains outstanding. 2. Complete the rolling-retention/headroom contract, provider prefix expiry compatibility and pre-capture budget/reserve guard. Preserve protected kit and restored point outside rolling expiry. Historical private copies still await @@ -72,3 +73,12 @@ Follow-up: the updated checker additionally requires retained public-receipt metadata. Its exact source hash and read-only native observation, plus exact candidate-unit verification on the target node, are appended to the JSON proof; the initial observation and source hash above remain historical evidence. + +October 31 delivery follow-through: the source snapshot image pin now matches +the already installed and verified storage-release helper byte for byte. Native +default server dry-run passes. All operating sources and candidate units are +sealed for review in backup-operating-delivery-2026-10-31.{md,json}; current +node metadata confirms all four units remain absent/inactive. Capacity admission, +retention/disposition, monitored receiver/reception and the exact installation +and native service-run review still gate activation. No helper or unit was +installed, and no timer was enabled. diff --git a/scripts/snapshot-content-and-db.py b/scripts/snapshot-content-and-db.py index e8c3a91..7fb21dc 100644 --- a/scripts/snapshot-content-and-db.py +++ b/scripts/snapshot-content-and-db.py @@ -21,7 +21,7 @@ from pathlib import Path NS = 'coulomb-social' IMAGE = ('forgejo.coulomb.social/coulomb/coulomb-social@sha256:' - '9a646d8e01a61ba5316d3c2eb0273064e17f2d0300ad07af766ccedda65ecb18') + '512819463a1902b43a615beee14be7bf97e6a05e016385082b9380692ad1a8cd') CLUSTER_UID = 'a553c742-0115-43d4-99a4-a5ca56fe0786' LOCK_PATH = Path('/var/lib/coulomb-social-backup/snapshot.lock') diff --git a/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md b/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md index 7792d08..bc4fc86 100644 --- a/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md +++ b/workplans/CSOC-WP-0012-durable-recovery-service-readiness.md @@ -384,6 +384,20 @@ docs/release/service-owner-boundary-2026-10-31.{json,sources.txt}; interpretatio and concrete owner dependencies in service-provenance-reconciliation-2026-10-30.md. No credential, catalog write, live configuration or task acceptance changed. +2026-10-31 operating-source reconciliation: the repository snapshot helper still +pinned the pre-release image. Updated that source constant to the accepted live +digest; its complete hash now equals the already installed helper 4ff81b79. Native +default server dry-run passes without capture/pause/provider calls. Sealed the +15 operating source/unit/dependency-evidence files plus manifest into a private +review bundle; all 16 member bytes verified and current installed hashes/unit +states retained. All four node units remain absent/inactive. Full make check: +441 passed, zero skips. Review: docs/release/backup-operating-delivery-2026-10-31.{md,json}. +Capacity admission, rolling retention/expiry, historical-copy disposition, named +alert receiver and received signals, exact installation/rollback and native +service execution remain open. Requested the missing receiver/response-owner +information; no notification was sent. Existing schedule/custody approvals remain +valid. No installed helper, unit, timer, data or task acceptance changed. + ## Completion Finish when every task above has its stated evidence and acceptance, or hand off any newly discovered residual to a live work record first. Cross-owner dependencies remain their existing canonical records.