railiance-platform/scripts/application_recovery_mirror.py
codex b16f8bab8c Add immutable Coulomb recovery mirroring through scoped APIs
Assistant: codex
Assistant-Model: gpt-6.1-sol
Assistant-Session: 01a17f16-d99c-7ea3-95f0-8212897fba6b
2026-10-29 22:25:41 +01:00

141 lines
6.8 KiB
Python

"""Coulomb immutable recovery mirror using the proven primary multipart engine.
The adapter pins every logical request to Coulomb and remaps only to its own
isolated recovery project/bucket/prefix. Independent fetch uses the reader.
"""
from __future__ import annotations
import argparse
import json
import re
import sys
from pathlib import Path
import primary_application_archive as primary
from application_recovery_identities import (
Refused,
checkpoint,
private_directory,
private_json,
)
from application_recovery_resources import s3, status
PROJECT = "06d107bc-9d84-4672-b2a0-95701cc0c07f"
BUCKET = "railiance-coulomb-social-archives"
OPERATIONS = {"head_object", "get_object", "create_multipart_upload", "upload_part",
"complete_multipart_upload", "abort_multipart_upload"}
class Mirror:
def __init__(self, client):
self.client = client
def __getattr__(self, operation):
if operation not in OPERATIONS:
raise Refused("mirror_operation_outside_contract")
def invoke(**arguments):
if arguments.get("Bucket") != primary.BUCKET:
raise Refused("mirror_logical_bucket_refused")
key = arguments.get("Key", "")
primary.validate_key("coulomb-social", key)
return getattr(self.client, operation)(**dict(arguments, Bucket=BUCKET, Key="archives/" + key))
return invoke
def validate_receipt(receipt):
primary.validate_key("coulomb-social", receipt.get("object_key", ""))
primary.require_version(receipt.get("version_id"))
if (receipt.get("application") != "coulomb-social"
or receipt.get("schema") != "platform.application-primary-archive.v1"
or receipt.get("status") != "offsite_fetched_verified"
or receipt.get("remote_retrieval_verified") is not True
or receipt.get("destination") != "s3://" + primary.BUCKET + "/" + receipt["object_key"]
or receipt.get("immutable_create") is not True
or not re.fullmatch(r"[a-f0-9]{64}", receipt.get("ciphertext_sha256", ""))
or type(receipt.get("ciphertext_bytes")) is not int
or not 0 < receipt["ciphertext_bytes"] <= primary.MAX_BYTES):
raise Refused("verified_coulomb_primary_receipt_required")
def mirror(client, source, readback, receipt, journal, save):
validate_receipt(receipt)
binding = {k: receipt[k] for k in ("object_key", "version_id", "ciphertext_sha256", "ciphertext_bytes",
"captured_at", "image", "age_recipient", "database_sha256", "content_sha256")}
if journal:
if journal.get("primary_binding") != binding or journal.get("recovery_project_id") != PROJECT:
raise Refused("mirror_resume_binding_differs")
else:
journal.update(schema="platform.coulomb-recovery-mirror.v1", primary_binding=binding,
recovery_project_id=PROJECT, object_key=receipt["object_key"],
ciphertext_sha256=receipt["ciphertext_sha256"])
primary.regular_file(source)
if primary.digest(source) != receipt["ciphertext_sha256"] or source.stat().st_size != receipt["ciphertext_bytes"]:
raise Refused("mirror_source_differs")
primary.transfer(Mirror(client), "coulomb-social", source, readback, journal, save)
reference = {"project_id": PROJECT, "bucket": BUCKET,
"object_key": "archives/" + receipt["object_key"],
"version_id": journal["version_id"], "ciphertext_sha256": receipt["ciphertext_sha256"],
"ciphertext_bytes": receipt["ciphertext_bytes"], "hash_readback_verified": True}
journal["recovery_mirror"] = reference
save()
return dict(receipt, recovery_mirror=reference)
def retrieve(client, output, receipt):
validate_receipt(receipt)
ref = receipt.get("recovery_mirror", {})
if (ref.get("project_id") != PROJECT or ref.get("bucket") != BUCKET
or ref.get("object_key") != "archives/" + receipt["object_key"]
or ref.get("ciphertext_sha256") != receipt["ciphertext_sha256"]
or ref.get("ciphertext_bytes") != receipt["ciphertext_bytes"]
or ref.get("hash_readback_verified") is not True):
raise Refused("exact_recovery_mirror_reference_required")
primary.require_version(ref.get("version_id"))
primary.download(Mirror(client), receipt["object_key"], ref["version_id"],
receipt["ciphertext_bytes"], receipt["ciphertext_sha256"], output)
return {"status": "independent_mirror_retrieved_verified", "provider_mutations": False,
"recovery_mirror": ref, "application_restore_verified": False}
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("operation", choices=("publish", "retrieve"))
parser.add_argument("--execute", action="store_true")
parser.add_argument("--directory", type=Path, default=Path.home() / ".config/railiance-platform/coulomb-social-recovery")
parser.add_argument("--receipt", type=Path, required=True)
parser.add_argument("--source", type=Path)
parser.add_argument("--output", type=Path, required=True)
parser.add_argument("--journal", type=Path)
parser.add_argument("--result", type=Path)
args = parser.parse_args()
if not args.execute:
print(json.dumps({"status": "preview", "provider_contacted": False, "operation": args.operation}))
return
private_directory(args.directory)
private_directory(args.output.parent)
receipt = private_json(args.receipt)
if args.result:
private_directory(args.result.parent)
if args.result.exists() or args.result.is_symlink():
raise Refused("fresh_result_required")
if args.operation == "retrieve":
result = retrieve(s3(private_json(args.directory / "reader-pair.json"), PROJECT), args.output, receipt)
else:
if not args.journal or not args.source or not args.result:
raise Refused("publish_source_journal_result_required")
private_directory(args.journal.parent)
journal = private_json(args.journal) if args.journal.exists() else {}
result = mirror(s3(private_json(args.directory / "publisher-pair.json"), PROJECT), args.source,
args.output, receipt, journal, lambda: checkpoint(args.journal, journal))
if args.result:
checkpoint(args.result, result)
print(json.dumps({"status": "mirror_publish_verified" if args.operation == "publish" else result["status"],
"application_restore_verified": False, "private_values_printed": False}))
if __name__ == "__main__":
try:
main()
except Exception as error: # noqa: BLE001 -- suppress private provider diagnostics
print(json.dumps({"status": "refused", "failure_type": type(error).__name__, "native_status": status(error)}))
sys.exit(1)