Machbarkeitsnachweis: PDF/UA-1-Vertragsprüfgate

  • Datum: 26. August 2026
  • Status: lokaler und Linux-CI-Vertragslauf bestanden; Slice A commit- und CI-gebunden abgeschlossen
  • Issue: #333 bleibt offen
  • Entscheidung: ADR-0059
  • Produktionsrenderer: unverändert @react-pdf/renderer

Aussagegrenze

Dieser Nachweis belegt den lokalen und Linux-CI-gebundenen Arbeitsstand von Slice A. Der synthetische Kandidat und die negative Gegenprobe wurden auf dem Harness-Commit dbd46f3c3a94ac6a5ee632cd72ee1a3cad085e96 lokal und im GitHub-Actions-Lauf 32951907614 ausgehend von PR-Head e04b7fee94086c599791d2b0d24ea83abd9b84c0 tatsächlich ausgeführt. GitHub Actions checkte dafür den synthetischen Merge-Commit 30f49405b42e63318f83f7ae6afc787509894969 aus. Der Abschluss von Slice A behauptet weiterhin keine PDF/UA-Konformität des produktiven Standort-Reports.

Slice A darf nach seiner Ausführung ausschließlich folgende Aussage tragen: Eine synthetische, nicht personenbezogene HTML-Fixture kann über einen Chromium-basierten Kandidatenpfad ein PDF/UA-1-Dokument erzeugen, das den gepinnten Validator besteht, während eine semantisch entsprechende Fixture aus dem heutigen React-PDF-Pfad fail-closed scheitert. Das ist ein Machbarkeitsnachweis, keine Produktfreigabe.

Feste synthetische Fixture

Die netzwerkfreie Fixture enthält nur erfundene Daten und muss folgende Strukturen in logischer Lesereihenfolge abdecken:

SemantikPositive Erwartung
DokumentTitel, Sprache de-AT, PDF/UA-1-XMP-Kennzeichen und MarkInfo/Marked
TextÜberschriftsebenen, Absätze und vollständig extrahierbare Textschicht
ListeListe mit einzeln strukturierten Listeneinträgen
TabelleTabellenstruktur mit expliziten Kopf- und Datenzellen
Linkechter, beschrifteter URI-Link im Strukturbaum
informative Abbildungaussagekräftiger Alternativtext
Dekoration und Seiten-Chromenicht Teil der inhaltlichen Lesereihenfolge, als Artefakt behandelt

Die Fixture lädt keine Fonts, Bilder, Skripte oder Inhalte aus dem Netz. Der Runner verbietet ausführbare HTML-Inhalte, deaktiviert JavaScript und blockiert HTTP-, Datei- und WebSocket-Verbindungen. Ihre rohen Datei-Bytes werden über einen im Runner fest hinterlegten SHA-256 an den Lauf gebunden. Die erzeugten PDF-Bytes müssen nicht als dauerhaft identischer Golden-Hash behandelt werden; der protokollierte Hash identifiziert das jeweils geprüfte Artefakt.

Verbindliche Gegenprobe

Der Runner erzeugt zusätzlich ein PDF aus dem bestehenden @react-pdf/renderer-Pfad. Es enthält Sprache, Metadaten, Text und Links, aber keinen belegten vollständigen PDF/UA-Strukturvertrag. Diese Datei muss vom gleichen Prüfgate gezielt abgewiesen werden. Ein Lauf, in dem sowohl Kandidat als auch Bestandsoutput bestehen, ist wegen fehlender Trennschärfe rot.

Die Gegenprobe ist keine Abwertung des produktiven Viewervertrags: React-PDF bleibt für mehrseitige Darstellung, Text, Links, Metadaten und weiße Hintergründe abgenommen. Sie zeigt ausschließlich, dass diese Eigenschaften keinen PDF/UA-Nachweis ersetzen.

Nur diese erwartete Noncompliance-Gegenprobe darf den dokumentierten veraPDF-Exitcode 1 liefern, und auch dann ausschließlich zusammen mit einem vollständig geparsten Bericht isCompliant=false. Der positive Kandidat muss mit Exitcode 0 enden. Timeout, Signal, Buffergrenze, anderer Exitcode, fehlender Bericht oder ein konformer Bericht bei Exitcode 1 sind in beiden Pfaden harte Fehler.

Laufmatrix

NachweisPflichtStand am 26. August 2026
lokaler positiver Chromium-/veraPDF-LaufValidator endet ohne fehlgeschlagene PDF/UA-1-Regelbestanden: 106/106 Regeln und 4.679/4.679 Checks
lokale React-PDF-Gegenprobescheitert am semantischen PDF/UA-Vertragbestanden: 9 Regeln und 189 Checks erwartungsgemäß fehlgeschlagen
StrukturinspektionTag-Baum in definierter DOM-/Fixture-Reihenfolge, physische Textschicht in seitenweiser Markerreihenfolge, Sprache, MarkInfo, XMP, Dokumenttitel und -metadaten, Outline, Linkziel, genau eine informative Figure mit Alternativtext und Artefaktgrenze sichtbarbestanden: 2 Seiten, 6 Outline-Einträge und alle Pflichtinvarianten
temporäre Artefakteauch bei Fehlern entfernt; keine Veröffentlichung als Build-Artefaktbestanden: finally-Cleanup und leerer Temp-Verzeichnis-Gegencheck
eigener CI-Jobderselbe Runner mit bytegepinntem Browser, Java und veraPDF; keine veröffentlichte PDF-Dateibestanden: Run 32951907614, Job 98125074601, 1 min 18 s, 0 Build-Artefakte

Lokaler Lauf

  • Geprüfter Slice-A-Commit: dbd46f3c3a94ac6a5ee632cd72ee1a3cad085e96, ausgehend von 749b5e43988f2c08083cbbf062abf10a7fa79d15. Der identische Harness wurde nach dem Commit bei sauberem Arbeitsbaum erneut mit Exit-Code 0 ausgeführt.
  • System: macOS 26.5.1 (arm64), Node 24.16.0, Playwright 1.60.0, Chromium 148.0.7778.96 (Revision 1223), Temurin 21.0.12.1+1 und veraPDF 1.30.2.
  • CI-Werkzeugbytes: Das Linux-x64-Archiv von Chromium 148.0.7778.96 ist an SHA-256 e58a0612f6156ad287ff392c681f6e1154d0c938feccf631d0c5d7abf3bbf81a, Temurin 21.0.12.1+1 an ce79869e1307ed8ee1e2baa86a412b1eb5b75d10a01006d788a6f968bcfaee94 und der veraPDF-1.30.2-Installer an 6cc6341cb1af644044054b81f00a6590a7918abb18f762243de115258bcad838 gebunden. CI entpackt Chromium erst nach erfolgreicher Byteprüfung in den festgelegten Playwright-Cachepfad.
  • Befehl: derselbe TypeScript-Runner wie npm run qa:pdf:ua-feasibility, explizit unter Node 24.16.0 und mit VERAPDF_BIN auf die lokal gepinnte CLI; Exit-Code 0.
  • Positive Probe: 106 Regeln und 4.679 Checks bestanden; 0 Regeln und 0 Checks fehlgeschlagen. Sprache de-AT, Dokumenttitel und -metadaten, MarkInfo/Marked, PDF/UA-1-XMP, 6 Outline-Einträge, exakte Rollen-Lesereihenfolge, genau eine Figure mit einem an alle vier dargestellten Kriterien und Werte gebundenen Alternativtext, Link-Contents, exaktes Linkziel, /Tabs /S sowie Header und Footer als /Artifact /Pagination wurden zusätzlich strukturell geprüft. Poppler band die physische Textschicht getrennt auf beiden Seiten an feste Textmarker und deren Reihenfolge; damit wird keine MCID-Zuordnung einzelner Texte behauptet.
  • Negative Probe: Der echte aktuelle React-PDF-Free-Fixture-Output wurde mit 9 fehlgeschlagenen Regeln und 189 fehlgeschlagenen Checks abgewiesen. Belegt sind unter anderem fehlender XMP-Metadatenstrom, fehlendes MarkInfo/Marked, fehlender StructTreeRoot, ungetaggter Inhalt, nicht getaggte Links, fehlende Link-Contents und fehlendes /Tabs /S.
  • SHA-256 des letzten lokalen Wiederholungslaufs: Fixture 538dfd32a04eb64039665b9ec928fd1a5a89affc0feaa9d747bcbf20d6256140, Kandidat 87e5836668e07291794664903676941cf06980ac932a01c0f8adbd3e9d7bf89f, React-PDF-Gegenprobe d3d0a7858971ac883ed2a1495b2c037e40a926c8146b520d365c95d5895e5b4c. Die PDF-Hashes identifizieren genau diesen Lauf und sind keine Golden-Bytes.
  • Regression: 28 fokussierte Harness- und Dokumentationstests bestanden; nach dem Lauf blieb kein landnutzen-pdf-ua-*-Tempverzeichnis zurück. Die vollständige Regression bestand zusätzlich mit 264 Testdateien und 3.424 Tests (6 Dateien/39 Tests bewusst übersprungen), ESLint, TypeScript, Content-/SEO-Audit, Poppler-Viewergate und Next.js-Produktionsbuild.

Linux-CI-Lauf

  • Run und Job: GitHub Actions 32951907614, Job 98125074601, ausgehend von PR-Head e04b7fee94086c599791d2b0d24ea83abd9b84c0; tatsächlich ausgecheckter synthetischer Merge-Commit 30f49405b42e63318f83f7ae6afc787509894969; Laufzeit 1 Minute 18 Sekunden.
  • Gesamtgate: Der vollständige PR-Lauf endete erfolgreich. Neben dem PDF/UA-Job bestanden verify in 11 Minuten 48 Sekunden, die separate Poppler-Regression in 58 Sekunden und das Vercel-Preview-Deployment.
  • System: GitHub-hosted Ubuntu 24.04.4 x64, Node 24.16.0, Chromium 148.0.7778.96, Poppler 24.02.0, Temurin 21.0.12.1+1 und veraPDF 1.30.2.
  • Positive Probe: 106/106 Regeln und 4.645/4.645 Checks bestanden; 0 Regeln und 0 Checks fehlgeschlagen.
  • Negative Probe: Der React-PDF-Free-Output wurde mit 9 fehlgeschlagenen Regeln und 189 fehlgeschlagenen Checks erwartungsgemäß abgewiesen.
  • SHA-256: Fixture 538dfd32a04eb64039665b9ec928fd1a5a89affc0feaa9d747bcbf20d6256140, Kandidat fa10d9d1b1329266325d1880ac0580b40c376c91ba40f58c5eee3877247e980a, React-PDF-Gegenprobe d42a8b7365578706378e2b9e96f073e0550e5f7c231058492a213a13618c7d21. Die plattformabhängigen PDF-Hashes unterscheiden sich erwartbar vom macOS-Lauf; Fixture-Hash, Strukturvertrag und Validatorprofil sind identisch.
  • Artefaktgrenze: Die GitHub-Actions-Artefaktliste für Run 32951907614 enthielt nach Abschluss des gesamten Runs total_count=0. Das Harness entfernte sein Arbeitsverzeichnis; keine Kandidaten- oder Gegenproben-PDF wurde publiziert.

Merge, Main-CI und Produktions-Readback

  • Implementierungs-PR: #532 wurde als Merge-Commit e39272c56134bfbe4c9f3b7789e872baa88706e8 in main übernommen. Die PR-Beschreibung verwendet Progresses #333; Issue #333 blieb offen.
  • Main-CI: GitHub Actions 32954309960 bestand auf exakt diesem Merge-Commit einschließlich verify, PDF-Poppler-Regression und PDF-UA-Feasibility. Die drei Jobs liefen 12 Minuten 6 Sekunden, 49 Sekunden und 1 Minute 45 Sekunden; die vollständige Run-Artefaktliste blieb mit total_count=0 leer.
  • Vercel-Produktion: Deployment dpl_27B3QDZtKAyT7kEi3xe1rFWk1qWB meldete READY, target=production und denselben Merge-Commit. Es wurde an www.landnutzen.at, landnutzen.at, landnutzen.vercel.app und den Main-Alias gebunden.

Der anschließende öffentliche Readback prüfte ausschließlich Dokumentation und führte keine Report-, Konto- oder personenbezogenen Schreibvorgänge aus:

ProduktionsrouteHTTPInhaltlicher Marker
/docs/pdf-ua-machbarkeitsnachweis-2026-08-26200Run 32951907614, 4.645/4.645, Aussagegrenze und offene Produktintegration
/docs/pdf-ua-feasibility-v1200ADR-0059 und PDF/UA-1-Machbarkeitsvertrag
/docs/report-output200Slice-A-CI-Bindung und unveränderter React-PDF-Produktionsrenderer
/docs/feature-pdf-permalink200externer Status, 4.645/4.645 und weiterhin offene Reportintegration

Alle vier Antworten trugen X-Robots-Tag: noindex, nofollow, noarchive, Cache-Control: private, no-cache, no-store, max-age=0, must-revalidate und einen Vercel-Requestbeleg. Vor dem Merge antworteten die beiden neu registrierten ADR-/Evidenzrouten in Produktion noch mit 404; nach dem commitgebundenen Deployment lieferten sie den dokumentierten Stand. Damit ist die Dokumentation live verifiziert, nicht der unverändert ungetaggte Produktionsrenderer.

Nicht durch Slice A belegt

Auch nach einem grünen Machbarkeitslauf bleiben folgende Punkte ausdrücklich offen:

  • Der produktive Standort-Report wird weiterhin mit React-PDF erzeugt und ist noch kein PDF/UA-Dokument.
  • Free-, Standard-, Premium- und Planer-Reports sind nicht auf vollständige semantische Tags und reale Lesereihenfolge migriert.
  • Karten und andere informative Grafiken besitzen noch keine fachlich abgenommenen Alternativtexte; wiederkehrender Kopf-/Fuß-Chrome ist im produktiven Output nicht als Artefakt belegt.
  • Es gibt noch keinen Serverless-Benchmark für Kaltstart, Speicher, PDF-Größe, Parallelität und Vercel-Limits des Kandidatenrenderers.
  • Poppler-, PDFium-, Apple-Vorschau- und Mehrseitenregression müssen nach einer echten Rendererumstellung erneut vollständig bestanden werden.
  • Eine manuelle Prüfung mit VoiceOver oder einem anderen Screenreader ist noch nicht durchgeführt.

Issue #333 darf durch Slice A deshalb nicht geschlossen werden. Ein späterer Produktionswechsel benötigt eine eigene Entscheidung, ein kontrolliertes Rollout, Live-Readback und dokumentierte Screenreader-Abnahme.