feat(cv): qualify templates and reliable local import processing

This commit is contained in:
cesnimda
2026-10-28 14:36:12 +01:00
parent 73ea888375
commit 3f4db8ca81
69 changed files with 2597 additions and 180 deletions
+68
View File
@@ -0,0 +1,68 @@
"""Independent byte-bound completeness/bounds report; no presentation-quality goldens.
Run after the producer and unchanged scripts/verify-cv-fidelity.py. All reported
whitespace/name-wrap observations remain measurements for human review.
"""
import argparse
import hashlib
import json
import re
from collections import Counter
from pathlib import Path
import pdfplumber
def inspect(root, fixture):
filename = root / fixture["fixture"] / "export.pdf"
failures, pages, markers = [], [], []
with pdfplumber.open(filename) as document:
for index, page in enumerate(document.pages):
words = page.extract_words()
text = page.extract_text() or ""
markers.extend(re.findall(r"\b[SEBPR]\d{2}\b", text))
outside = [word for word in words if word["x0"] < -1.42 or word["top"] < -1.42
or word["x1"] > page.width + 1.42 or word["bottom"] > page.height + 1.42]
if outside:
failures.append(f"page {index + 1}: {len(outside)} words outside physical page by more than 0.5mm")
if not words:
failures.append(f"page {index + 1}: blank output")
top = min((word["top"] for word in words), default=0)
bottom = max((word["bottom"] for word in words), default=0)
pages.append({"page": index + 1, "wordCount": len(words), "widthPt": page.width,
"heightPt": page.height, "textTopPt": top, "textBottomPt": bottom,
"occupiedVerticalFraction": (bottom - top) / page.height,
"trailingWhitespaceFraction": (page.height - bottom) / page.height,
"outsideWords": outside, "text": text,
"embeddedImages": len(page.images)})
if Counter(markers) != Counter(fixture["expectedMarkers"]):
failures.append("PDF marker multiset differs from independent source fixture")
if len(pages) != fixture["previewPages"]:
failures.append("PDF/preview page count differs")
return {"fixture": fixture["fixture"], "pass": not failures, "failures": failures,
"pdfSha256": hashlib.sha256(filename.read_bytes()).hexdigest(), "expectedMarkerCount": len(fixture["expectedMarkers"]),
"actualMarkerCount": len(markers), "nameLineCount": fixture["measured"]["nameLineCount"],
"splitNameWords": fixture["measured"]["splitNameWords"], "pages": pages}
def main():
parser = argparse.ArgumentParser()
parser.add_argument("directory", type=Path)
args = parser.parse_args()
measurements = json.loads((args.directory / "measurements.json").read_text(encoding="utf-8"))
fixtures = [inspect(args.directory, item) for item in measurements["fixtures"]]
result = {"measurementSha256": hashlib.sha256((args.directory / "measurements.json").read_bytes()).hexdigest(),
"designVersion": measurements["designVersion"], "total": len(fixtures),
"passed": sum(item["pass"] for item in fixtures), "pages": sum(len(item["pages"]) for item in fixtures),
"qualification": "Finite synthetic completeness and physical bounds only; whitespace and name wrapping require visual review.",
"fixtures": fixtures}
(args.directory / "pdf-proof.json").write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"Source-bound PDF completeness/bounds: {result['passed']}/{result['total']} documents, {result['pages']} pages")
for item in fixtures:
if not item["pass"]:
print(item["fixture"], item["failures"])
raise SystemExit(0 if result["passed"] == result["total"] else 1)
if __name__ == "__main__":
main()