coulomb-social/scripts/rehearse-backup-mirror.py
tegwick 11cab7298b
Some checks failed
Use-case regression gate / usecase-regressions (push) Failing after 6m27s
Guard paired capture and mirror scratch capacity inside the writer lock
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
2026-10-30 00:37:37 +01:00

138 lines
5.7 KiB
Python

#!/usr/bin/env python3
"""Rehearse the pinned platform engine using development-only synthetic fixtures.
No provider client is created and no credentials are read. This proves adapter
integration, not IAM, native provider behavior or recurring service operation.
"""
from __future__ import annotations
import argparse
import hashlib
import importlib.util
import json
import os
import sys
import tempfile
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT))
from tests.test_backup_health import health_state # noqa: E402
from tests.test_backup_mirror_worker import MemoryS3 # noqa: E402
def fixture(directory, worker):
state, primary, _ = health_state.__wrapped__(directory, worker.health)
data = b"age-encryption.org/v1\n" + b"SYNTHETIC CIPHERTEXT ONLY\n"
(state / primary["local_archive"]).write_bytes(data)
primary.update(
ciphertext_sha256=hashlib.sha256(data).hexdigest(),
encrypted_sha256=hashlib.sha256(data).hexdigest(),
ciphertext_bytes=len(data),
encrypted_bytes=len(data),
)
(state / "last-success.json").write_text(json.dumps(primary))
(state / "last-mirror.json").unlink()
return state, primary
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--platform-scripts", type=Path, required=True)
parser.add_argument(
"--runtime-manifest", type=Path, default=ROOT / "deploy/backup/mirror-platform-runtime.json"
)
parser.add_argument("--output", type=Path, required=True)
args = parser.parse_args()
if args.output.exists() or args.output.is_symlink():
raise ValueError("Fresh proof output required")
source = ROOT / "scripts/mirror-paired-backup.py"
spec = importlib.util.spec_from_file_location("integration_worker", source)
worker = importlib.util.module_from_spec(spec)
spec.loader.exec_module(worker)
runtime = worker.load_runtime(args.platform_scripts, args.runtime_manifest)
worker.capacity.enforce_file_limit()
scenarios = []
for lost_reply in [False, True]:
with tempfile.TemporaryDirectory(prefix="csoc-mirror-engine-") as directory:
state, primary = fixture(Path(directory), worker)
client = MemoryS3()
client.lose_put_reply = lost_reply
before = (state / "last-success.json").read_bytes()
if lost_reply:
try:
worker.mirror_latest(state, runtime, client)
except TimeoutError:
pass
else:
raise AssertionError("Lost reply was not exercised")
assert not (state / "last-mirror.json").exists()
result = worker.mirror_latest(state, runtime, client)
mirrored = json.loads((state / "last-mirror.json").read_bytes())
worker.health.validate_mirror(primary, mirrored, require_retained_receipt=True)
ref = mirrored["recovery_mirror"]
held = client.objects[ref["receipt_object_key"]]["Body"]
assert hashlib.sha256(held).hexdigest() == ref["receipt_sha256"]
assert (
client.objects[ref["object_key"]]["Body"]
== (state / primary["local_archive"]).read_bytes()
)
assert (state / "last-success.json").read_bytes() == before
assert len(client.objects) == 2
assert sum(op == "complete" for op, _ in client.calls) == 1
assert sum(op == "put" for op, _ in client.calls) == 1
assert all(a["Bucket"] == worker.health.MIRROR_BUCKET for _, a in client.calls)
assert all(
a["Key"].startswith("archives/" + primary["object_key"]) for _, a in client.calls
)
assert result["receipt_readback_verified"]
scenarios.append(
{
"lost_receipt_put_reply": lost_reply,
"ciphertext_multipart_completions": 1,
"metadata_conditional_puts": 1,
"retained_objects": 2,
"primary_unchanged": True,
"exact_version_hash_readbacks": True,
"last_mirror_only_after_full_readback": True,
"only_coulomb_archive_prefix_used": True,
}
)
proof = {
"schema": "coulomb.mirror-worker-rehearsal.v1",
"status": "pinned_engine_synthetic_integration_passed",
"worker_sha256": hashlib.sha256(source.read_bytes()).hexdigest(),
"capacity_sha256": hashlib.sha256(
(ROOT / "scripts/backup_capacity.py").read_bytes()
).hexdigest(),
"checker_sha256": hashlib.sha256(
(ROOT / "scripts/check-paired-backup-health.py").read_bytes()
).hexdigest(),
"driver_sha256": hashlib.sha256(Path(__file__).read_bytes()).hexdigest(),
"fixture_sha256": {
name: hashlib.sha256((ROOT / "tests" / name).read_bytes()).hexdigest()
for name in ["test_backup_health.py", "test_backup_mirror_worker.py"]
},
"runtime_manifest": json.loads(args.runtime_manifest.read_bytes()),
"scenarios": scenarios,
"synthetic_store": True,
"provider_contacted": False,
"credentials_read": False,
"node_files_changed": False,
"timers_activated": False,
}
fd = os.open(args.output, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o600)
with os.fdopen(fd, "w") as stream:
json.dump(proof, stream, indent=2, sort_keys=True)
stream.write("\n")
print(
json.dumps(
{"status": proof["status"], "scenarios": len(scenarios), "provider_contacted": False}
)
)
if __name__ == "__main__":
main()