Init. commit
This commit is contained in:
104
osint-mirror-trace/solve/check_release.py
Normal file
104
osint-mirror-trace/solve/check_release.py
Normal file
@@ -0,0 +1,104 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import csv
|
||||
import json
|
||||
import subprocess
|
||||
import sys
|
||||
import zipfile
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
CONFIG = json.loads((ROOT / "src" / "task_config.json").read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def require(path: Path) -> None:
|
||||
if not path.exists():
|
||||
raise SystemExit(f"missing required file: {path}")
|
||||
|
||||
|
||||
def assert_contains(path: Path, needle: str, error: str) -> None:
|
||||
if needle not in path.read_text(encoding="utf-8"):
|
||||
raise SystemExit(error)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
archive_path = ROOT / "public" / CONFIG["archive_name"]
|
||||
bundle_dir = ROOT / "public" / "mirrortrace_casebundle"
|
||||
retained_copy = bundle_dir / "20_artifacts" / CONFIG["retained_copy_name"]
|
||||
|
||||
require(ROOT / "public" / "case_brief.txt")
|
||||
require(ROOT / "public" / "negotiation_excerpt.txt")
|
||||
require(archive_path)
|
||||
require(bundle_dir / "10_datasets" / "graph_nodes.csv")
|
||||
require(bundle_dir / "10_datasets" / "graph_edges.csv")
|
||||
require(bundle_dir / "20_artifacts" / "doc_01.pdf")
|
||||
require(bundle_dir / "20_artifacts" / "doc_03.pdf")
|
||||
require(bundle_dir / "20_artifacts" / "capture_05.html")
|
||||
require(bundle_dir / "20_artifacts" / "capture_11.html")
|
||||
require(retained_copy)
|
||||
|
||||
assert_contains(
|
||||
ROOT / "public" / "case_brief.txt",
|
||||
CONFIG["retained_copy_name"],
|
||||
"case_brief.txt is missing retained copy reference",
|
||||
)
|
||||
|
||||
doc_01_bytes = (bundle_dir / "20_artifacts" / "doc_01.pdf").read_bytes()
|
||||
if f"/Author ({CONFIG['correct']['pdf_author']})".encode("ascii") not in doc_01_bytes:
|
||||
raise SystemExit("doc_01.pdf is missing expected metadata author")
|
||||
if b"Retained legal copy marker: ED-C0" not in doc_01_bytes:
|
||||
raise SystemExit("doc_01.pdf is missing expected retained copy marker")
|
||||
|
||||
doc_03_bytes = (bundle_dir / "20_artifacts" / "doc_03.pdf").read_bytes()
|
||||
if f"/Author ({CONFIG['same_cluster_decoy']['pdf_author']})".encode("ascii") not in doc_03_bytes:
|
||||
raise SystemExit("doc_03.pdf is missing expected same-cluster decoy author")
|
||||
|
||||
capture_05 = (bundle_dir / "20_artifacts" / "capture_05.html").read_text(encoding="utf-8")
|
||||
if CONFIG["correct"]["full_name"] not in capture_05:
|
||||
raise SystemExit("capture_05.html is missing expected identity")
|
||||
|
||||
capture_11 = (bundle_dir / "20_artifacts" / "capture_11.html").read_text(encoding="utf-8")
|
||||
if CONFIG["same_cluster_decoy"]["personal_domain"] not in capture_11:
|
||||
raise SystemExit("capture_11.html is missing expected same-cluster decoy pivot")
|
||||
|
||||
with (bundle_dir / "10_datasets" / "graph_edges.csv").open(encoding="utf-8", newline="") as fh:
|
||||
rows = list(csv.DictReader(fh))
|
||||
expected_edges = {
|
||||
("panel", "cert_ms441"),
|
||||
("helpdesk_mercury", "doc_03"),
|
||||
("git_mercury", "personal_vk"),
|
||||
("helpdesk_mercury", "personal_as"),
|
||||
}
|
||||
actual_edges = {(row["source"], row["target"]) for row in rows}
|
||||
if not expected_edges.issubset(actual_edges):
|
||||
raise SystemExit("graph_edges.csv is missing expected hard-mode relations")
|
||||
|
||||
subprocess.run(
|
||||
["unzip", "-P", CONFIG["passphrase"], "-t", str(retained_copy)],
|
||||
check=True,
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
)
|
||||
|
||||
with zipfile.ZipFile(archive_path) as zf:
|
||||
expected = {
|
||||
"mirrortrace_casebundle/00_brief/case_brief.txt",
|
||||
"mirrortrace_casebundle/10_datasets/graph_nodes.csv",
|
||||
"mirrortrace_casebundle/10_datasets/graph_edges.csv",
|
||||
"mirrortrace_casebundle/20_artifacts/doc_01.pdf",
|
||||
"mirrortrace_casebundle/20_artifacts/doc_03.pdf",
|
||||
"mirrortrace_casebundle/20_artifacts/capture_05.html",
|
||||
"mirrortrace_casebundle/20_artifacts/capture_11.html",
|
||||
f"mirrortrace_casebundle/20_artifacts/{CONFIG['retained_copy_name']}",
|
||||
}
|
||||
names = set(zf.namelist())
|
||||
if not expected.issubset(names):
|
||||
raise SystemExit("participant archive is missing expected hard-mode files")
|
||||
|
||||
print("MirrorTrace offline release check passed.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user