#!/usr/bin/env python3 """Add isolated-candidate evidence while preserving production failure history.""" from datetime import datetime, timezone import hashlib import json from pathlib import Path import xml.etree.ElementTree as ET ROOT = Path(__file__).resolve().parents[2] RESULTS = ROOT / 'tests/results/pdfium-intent-build' def sha(path): with path.open('rb') as stream: return hashlib.file_digest(stream, 'sha256').hexdigest() def read(relative): return json.loads((RESULTS / relative).read_text()) def main(): previous = RESULTS / 'prior-validation-record.json' assert sha(previous) == 'e171862993beb61a9786ffee1f6a4a869ba30e3c3bd03223918a20d8e41f297b' prior = json.loads(previous.read_text()) for name, digest in prior['evidenceSha256'].items(): assert sha(ROOT / name) == digest, name for name, digest in prior['sourceSha256'].items(): assert sha(ROOT / name) == digest, name for name, digest in prior['validationToolsSha256'].items(): assert sha(ROOT / name) == digest, name for name, digest in prior['builds']['arch']['binaries'].items(): assert sha(ROOT / 'build' / name) == digest, name package = prior['ubuntuPackage'] assert sha(ROOT / 'build-ubuntu-vm/packages' / package['archive']) == package['archiveSha256'] assert sha(ROOT / '.deps/pdfium/lib/libpdfium.so') == '08f6ea53a64f6fbb9f5ba8d9c02e0051987c6a9175f3fb5ba25f219174731aaa' candidate = read('candidate-final/report.json') assert candidate['upstreamTestsPass'] and candidate['candidatePdfiumProbesPass'] assert candidate['allBinaryInputsUnchanged'] and not candidate['productionDependencyReplaced'] assert not candidate['success'] and not candidate['intentPopplerSuccess'] assert [(r['tests'], r['failures']) for r in candidate['upstreamTests']] == [(1104, 0), (872, 0)] for name, digest in candidate['evidenceSha256'].items(): assert sha(RESULTS / 'candidate-final' / name) == digest, name for name, digest in candidate['inputs'].items(): assert sha(Path(name)) == digest, name intents = read('candidate-final/intents/report.json') probes = [p for scale in intents['scales'] for p in scale['probes']] assert len(probes) == 600 and all(p['matches']['pdfium'] for p in probes) comparison_failures = [p for p in probes if not p['matches']['poppler']] assert len(comparison_failures) == 18 assert {p['case'] for p in comparison_failures} == {'shading-pattern-RI-override'} baseline = read('intents-baseline/report.json') assert sum(not p['matches']['pdfium'] for s in baseline['scales'] for p in s['probes']) == 150 ctest = read('docview-ctest/report.json') assert ctest['exitCode'] == 0 and ctest['libraryUnchanged'] assert ctest['librarySha256'] == intents['pdfiumLibrary']['sha256'] suite = ET.parse(RESULTS / 'docview-ctest/tests.xml').getroot() assert suite.tag == 'testsuite' and suite.attrib['tests'] == '22' and suite.attrib['failures'] == '0' patch = read('candidate-patch.json') assert patch['success'] and patch['appliesWithoutFuzz'] and patch['appliedSourcesByteIdentical'] assert sha(ROOT / patch['patch']) == patch['patchSha256'] assert sha(ROOT / patch['patchSnapshot']) == patch['patchSha256'] for row in patch['files']: assert sha(ROOT / 'build-pdfium-intent/source' / row['path']) == row['afterSha256'] reproduced = read('fixture-reproduction.json') assert reproduced['success'] and len(reproduced['filesByteIdentical']) == 4 for name, digest in reproduced['filesByteIdentical'].items(): assert sha(RESULTS / 'reproduced-fixture' / name) == digest assert sha(ROOT / 'tests/fixtures/pdf/rendering-intents' / name) == digest tools = ['tests/cmyk_lut/' + name + '.py' for name in ('prepare_pdfium_source', 'fetch_pdfium_build_tools', 'prepare_pdfium_tools', 'export_pdfium_patch', 'validate_pdfium_candidate', 'record_candidate', 'intents')] tools.append('tests/fixtures/pdf/generate_rendering_intents.py') candidate_summary = { 'productionDependencyReplaced': False, 'candidatePdfiumProbesPass': True, 'humanRenderingAcceptance': False, 'crossRendererComparisonAccepted': False, 'sourceRevision': patch['baseRevision'], 'patch': patch['patch'], 'patchSha256': patch['patchSha256'], 'changedCoreFiles': len(patch['files']), 'patchSnapshot': patch['patchSnapshot'], 'library': intents['pdfiumLibrary']['path'], 'librarySha256': intents['pdfiumLibrary']['sha256'], 'upstreamTests': candidate['upstreamTests'], 'docviewCtestGroups': 22, 'cmykAnalyticProbesPassed': 48, 'intentProbesPassed': 600, 'popplerFailedProbes': 18, 'popplerFailureCase': 'shading-pattern-RI-override', 'report': 'tests/results/pdfium-intent-build/candidate-final/report.json', 'reportSha256': sha(RESULTS / 'candidate-final/report.json'), 'scope': 'Arch isolated candidate with existing application/worker binaries; no adoption into the Ubuntu package, Windows execution, calibrated-output or human golden acceptance.'} evidence = {str(path.relative_to(ROOT)): sha(path) for folder in (RESULTS, ROOT / 'tests/fixtures/pdf/rendering-intents') for path in sorted(folder.rglob('*')) if path.is_file() and '__pycache__' not in path.parts and path != RESULTS / 'record.json'} record = {**prior, 'schemaVersion': 5, 'recordedAtUtc': datetime.now(timezone.utc).isoformat(), 'scope': 'Unchanged validation3 product plus an isolated source-built PDFium rendering-intent candidate. Candidate numeric/upstream/application tests pass; comparator differences and final adoption/acceptance remain.', 'goalComplete': False, 'pdfiumRenderingIntentCandidate': candidate_summary, 'previousValidation': {'record': str(previous.relative_to(ROOT)), 'sha256': sha(previous), 'scope': 'Unchanged product and original failing ICC evidence; retained without rewriting its verdict.'}, 'sourceSha256': {**prior['sourceSha256'], patch['patch']: patch['patchSha256']}, 'validationToolsSha256': {**prior['validationToolsSha256'], **{name: sha(ROOT / name) for name in tools}}, 'evidenceSha256': {**prior['evidenceSha256'], **evidence}, 'remainingAcceptance': [*prior['remainingAcceptance'], 'Review and adopt the source-built rendering-intent patch; validate Ubuntu packaging and remaining rendering boundaries (including dedicated soft-mask/tiling probes). Independent Poppler shading-pattern intent differences remain recorded.']} encoded = json.dumps(record, ensure_ascii=False, indent=2) + '\n' (RESULTS / 'record.json').write_text(encoded) (ROOT / 'docs/validation-record.json').write_text(encoded) print(json.dumps({'goalComplete': False, 'candidateProbesPassed': 648, 'upstreamTestsPassed': 1976, 'docviewGroupsPassed': 22, 'evidenceFiles': len(record['evidenceSha256'])})) if __name__ == '__main__': main()