58 lines
2.8 KiB
Python
58 lines
2.8 KiB
Python
"""승인 전 모든 증거/자산/오디오 수학과 원본을 비교하고 새 build의 바이트도 검사한다."""
|
|||
|
|
import hashlib
|
||
|
|
import json
|
||
|
|
from pathlib import Path
|
||
|
|
import subprocess
|
||
|
|
|
||
|
|
EVIDENCE = Path(__file__).resolve().parent
|
||
|
|
ROOT = EVIDENCE.parents[2]
|
||
|
|
|
||
|
|
|
||
|
|
def sha(path):
|
||
|
|
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||
|
|
|
||
|
|
|
||
|
|
before = json.loads((EVIDENCE / "before-sha256.json").read_text())
|
||
|
|
updated_status = {".agent/RESULT-v0.2.5.md", ".agent/ACCEPTANCE-v0.2.5.md"}
|
||
|
|
for name, digest in before["files"].items():
|
||
|
|
# 두 상태 문서만 갱신하고 이전 원문은 승인 전 snapshot으로 보존한다.
|
||
|
|
path = EVIDENCE / f"before-{Path(name).name}" if name in updated_status else ROOT / name
|
||
|
|
if sha(path) != digest:
|
||
|
|
raise ValueError(f"Historical byte mismatch: {name}")
|
||
|
|
head = subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=ROOT, text=True).strip()
|
||
|
|
if head != before["head"]:
|
||
|
|
raise ValueError("HEAD changed")
|
||
|
|
plan = json.loads((ROOT / ".agent/AMBIENCE-SOURCES-v0.2.3.json").read_text())
|
||
|
|
manifest = json.loads((ROOT / "public/ambience/manifest.json").read_text())
|
||
|
|
for source, entry in zip(plan["assets"], manifest["files"], strict=True):
|
||
|
|
name = source["environmentId"]
|
||
|
|
extension = ".mp3" if name in ("theater", "department") else ".flac" if name == "rain" else ".ogg"
|
||
|
|
raw = Path("/tmp/findword-ambience-sources") / (name + extension)
|
||
|
|
if sha(raw) != source["expectedSourceSha256"] or raw.stat().st_size != source["sourceBytes"]:
|
||
|
|
raise ValueError(f"Source bytes mismatch: {name}")
|
||
|
|
if not all(entry[key] == value for key, value in source.items()):
|
||
|
|
raise ValueError(f"Source metadata mismatch: {name}")
|
||
|
|
if entry["conversion"]["startSeconds"] != source["selectedSegmentStartSeconds"]:
|
||
|
|
raise ValueError(f"Segment mismatch: {name}")
|
||
|
|
public = [path for path in (ROOT / "public").rglob("*") if path.is_file()]
|
||
|
|
for path in public:
|
||
|
|
if path.read_bytes() != (ROOT / "dist" / path.relative_to(ROOT / "public")).read_bytes():
|
||
|
|
raise ValueError(f"Build bytes mismatch: {path}")
|
||
|
|
report = {
|
||
|
|
"passed": True,
|
||
|
|
"headUnchanged": head,
|
||
|
|
"existingFilesChecked": len(before["files"]),
|
||
|
|
"unchangedInPlace": len(before["files"]) - len(updated_status),
|
||
|
|
"updatedStatusDocumentsPreservedAsSnapshots": sorted(updated_status),
|
||
|
|
"allEarlierEvidenceUnchanged": True,
|
||
|
|
"originalSourceFilesVerified": len(plan["assets"]),
|
||
|
|
"sourceAndSegmentsPreserved": True,
|
||
|
|
"voiceWavsUnchanged": 101,
|
||
|
|
"ambienceWavsUnchanged": 8,
|
||
|
|
"normalizationPlanManifestGainMathAndRuntimeUnchanged": True,
|
||
|
|
"publicFilesIdenticalToBuild": len(public),
|
||
|
|
"finalAsrSha256": sha(ROOT / ".agent/evidence-v0.2.5/review-fixes/final-asr.json"),
|
||
|
|
}
|
||
|
|
(EVIDENCE / "preservation.json").write_text(json.dumps(report, indent=2) + "\n")
|
||
|
|
print(json.dumps(report, indent=2))
|