PDF/UA-1-Report-Shadow: Slice-D-Nachweis
- Datum: 28. August 2026
- Issue: #333 bleibt offen
- Entscheidung: ADR-0062
- Branch:
codex/pdf-ua-report-shadow-slice-d - Implementierungscommit:
c81e37565b5863380f11b99e7524992f83823fcb - Pull Request: #539
- Release-Nachtrag: #540
- Finaler PR-Commit:
088ed8dab1749da623e354ffaa5bab48acc3cd17 - Merge-Commit:
056eafb0eddd0ec6369f71db65862f37b788b152
Aussagegrenze
Slice D erweitert den synthetischen Vier-Tier-Shadow auf 31 geordnete
Sektionen aus dem deployten Report-Typ und drei aus diesen Daten erzeugte
Figure-Alternativtexte. Der Pfad liest weiterhin weder Datenbank, gespeicherte
Reports, Session, Provider, Adresse noch Koordinate und führt keinen
Netzwerkzugriff aus.
Dieser Nachweis behauptet nicht die PDF/UA-Konformität des öffentlichen React-PDF-Outputs und keine Abnahme realer Produktreports. Der öffentliche Renderer bleibt unverändert. Anbindung gespeicherter Reports, Viewerregressionen, kontrollierter Rollout, Produkt-Live-Readback und manuelle Screenreader-Abnahme bleiben offen.
Implementierter Vertrag
- Produktfixture
PDF-UA-REPORT-SLICE-D-1und ViewPDF-UA-SLICE-D-1fürfree,standard,premiumundplaner; - exakt 31 geordnete Sektionen aus Lage, Umwelt, Restriktionen und Governance;
- fehlende Sektionen, abweichende Reihenfolge und relevante unerwartete Kardinalitäten schließen vor dem Renderer fail-closed;
- exakt acht A4-Seiten, drei informative Figures, zwei Links und 16 Pagination-Artefakte;
- Figure 1 beschreibt die synthetische Parzelle aus Fixture-ID und Fläche, Figure 2 die Risikozonen aus vier gemappten Reportbereichen und Figure 3 die Kosten aus allen sechs Szenarien;
- Standard/Premium enthalten die vorhandenen Szenario-Narrative, Premium/Planer den vorhandenen synthetischen Google-Solar-Block;
- Preview-only-Route ohne Body, Query, App-Sitzung, Auth.js-Cookies oder neuen
Shadow-Token; Erfolgsheader
slice-d-1.
Lokale Verifikation
Code- und Vertragsgates
| Gate | Ergebnis |
|---|---|
| gezielte Fixture-, Mapper-, Runtime-, Finalizer- und Routentests | 43/43 bestanden |
| gezielte Slice-C-/Slice-D-Dokumentationstests | 11/11 bestanden |
| vollständiger Vitest-Lauf | 271 Dateien / 3.480 Tests bestanden; 6 Dateien / 39 Tests bewusst übersprungen |
npm run typecheck | bestanden |
npm run lint -- --quiet | bestanden |
npm run build | 124 Routen/Seiten erfolgreich; nur erwartete lokale Auth.js-Warnungen mit synthetischem, unerreichbarem DB-Platzhalter |
| unveränderter öffentlicher React-PDF-/Poppler-Vertrag | Free 3 / Premium 4 Seiten; pdftoppm und pdftocairo bestanden |
| visueller Readback des Premium-Outputs | 8/8 Seiten geprüft; keine Überlagerung, Leerseite oder abgeschnittene Grafik |
| Netzwerkzugriff im Vier-Tier-Harness | verboten; kein Zugriff erfolgt |
Vier-Tier-PDF/UA-/Poppler-Lauf
npm run qa:pdf:ua-shadow bestand lokal mit veraPDF 1.30.2. Jeder Tier-Output
enthielt exakt acht A4-Seiten, drei unterschiedliche Figure-Alternativtexte,
zwei Links, 16 Pagination-Artefakte, physische Textschicht, vollständige
Struktur-Tabreihenfolge sowie je acht Rasterseiten in pdftoppm und
pdftocairo.
| Tier | Bytes | veraPDF | Fixture-SHA-256 | PDF-SHA-256 |
|---|---|---|---|---|
free | 123.278 | 106 Regeln / 23.114 Checks | 6ac36b39379d11815481f4a2e94d655a5b1a040d6e0d14f16328bcb1e1685d2e | 772e678be0cd8af948d58a822dba07494ba8dd49b9bd46b8719b8966c77edc5b |
standard | 124.891 | 106 Regeln / 23.969 Checks | bd803c11161e4ac0e385257901662754da54b9ccd88d631ad9626b8cede8565c | d376b7ae1b348ed86f71fd64b253dc40fd063e273a0fc68c5ea66c18ff8df872 |
premium | 129.646 | 106 Regeln / 24.678 Checks | 08e4ceb82ee4a9c9ea381bbb5846a04c47856c5c854b60848a2d8f598b61f795 | ca574a772c5fe3baec11504c204314ab64dff34f721677d125d18543083da8bc |
planer | 128.072 | 106 Regeln / 24.023 Checks | a1f83edc9c0f5212a829836e408133f47dfc5f804f666f97cb64f241186bb998 | 95dbd51b6272b1fc93c329c2317ea2dd323579c2493e0f644e6fe736994f6900 |
Die PDF-Hashes und Bytewerte bezeichnen diesen lokalen Lauf; Metadatenobjekte können zwischen Erzeugungen variieren. Die Fixture-Hashes und der strukturelle Vertrag sind die dauerhaften Regressionsgrenzen.
Geschützter Preview-Readback und CI
Der unveränderliche Vercel-Preview
dpl_Ew4nDGJZYUX9fRyiNSuqSz8FFutU war READY und laut Vercel-API exakt an
den finalen PR-Commit 088ed8dab1749da623e354ffaa5bab48acc3cd17 sowie PR
#539 gebunden. Der Zugriff erfolgte über den angemeldeten Vercel-CLI-Bypass der
Deployment Protection; ein anonymer öffentlicher Produktpfad wurde nicht
geöffnet.
| Tier | HTTP / Bytes | Server-Timing | Request-ID | Auth.js-Cookies | heruntergeladener PDF-Vertrag |
|---|---|---|---|---|---|
free | 200 / 123.228 | 1.238,3 + 245,6 = 1.486,1 ms | fra1::iad1::dmlf8-1787908766413-78cc4ad889e5 | 0 | 8 Seiten; 106 / 23.114 Checks; 3 Figures; 2 Links |
standard | 200 / 124.838 | 930,8 + 221,8 = 1.153,3 ms | fra1::iad1::rldfq-1787908771196-913388ae86c1 | 0 | 8 Seiten; 106 / 23.969 Checks; 3 Figures; 2 Links |
premium | 200 / 129.595 | 767,1 + 118,3 = 885,9 ms | fra1::iad1::b2g7n-1787908775348-8cbe5b5f7c4a | 0 | 8 Seiten; 106 / 24.678 Checks; 3 Figures; 2 Links |
planer | 200 / 128.020 | 783,3 + 149,9 = 933,4 ms | fra1::iad1::tfsf5-1787908779129-1ff094fd5cdd | 0 | 8 Seiten; 106 / 24.023 Checks; 3 Figures; 2 Links |
Alle vier Antworten trugen Content-Type: application/pdf,
Cache-Control: private, no-store,
X-Robots-Tag: noindex, nofollow, noarchive und
X-LandNutzen-PDF-UA-Shadow: slice-d-1. Die Downloads besaßen je acht
strukturierte A4-Seiten, drei unterschiedliche datenbasierte
Figure-Alternativtexte, zwei Linkannotationen, 16 Pagination-Artefakte und
acht Seiten mit Struktur-Tabreihenfolge. veraPDF 1.30.2 bestand jeweils 106
Regeln und die oben genannten Checks.
| Gegenprobe | Ergebnis | Request-ID |
|---|---|---|
GET /free | leerer 404, 0 Cookies | fra1::iad1::smr6j-1787908843897-8e89a38818ea |
POST /free?source=real | leerer 404, 0 Cookies | fra1::iad1::hlfhf-1787908846544-438adfae9258 |
POST /free mit {}-Body | leerer 404, 0 Cookies | fra1::iad1::dgcqk-1787908849208-da555fa98b97 |
POST /unbekannt | leerer 404, 0 Cookies | fra1::iad1::c2gt8-1787908851804-14ab13454e4f |
Ein nicht angemeldeter POST auf dieselbe Deployment-URL erreichte den
Handler nicht: Vercel Deployment Protection antwortete mit 302, 15 Bytes
und ausschließlich ihrem Schutz-Cookie; Request-ID
fra1::snzdz-1787908858137-ec8f35f28c83.
Der finale Pull-Request-CI-Lauf
33158802838
prüfte den exakten PR-Commit vollständig grün: verify / Job 98807959142
in 11:48 Minuten, PDF-UA-Feasibility / Job 98807958871 in 1:43 Minuten
und PDF-Poppler-Regression / Job 98807959187 in 0:55 Minuten. Der im
ersten Lauf sichtbar gewordene, auf den 26. August fixierte Altlasten-
Recovery-Snapshot wurde dabei nicht durch Lockerung des Produktionsguards,
sondern durch Bindung der Testfixture an die PostgreSQL-Referenzuhr
uhrstabil gemacht. Der Ablauf-Gegentest und das reale Freshness-Gate blieben
unverändert und bestanden lokal sowie in CI.
Der Main-CI-Lauf
33159659390
prüfte den exakten Merge-Commit ebenfalls vollständig grün: verify / Job
98810770129 in 11:55 Minuten, PDF-UA-Feasibility / Job 98810770434 in
1:41 Minuten und PDF-Poppler-Regression / Job 98810770449 in 0:55
Minuten.
Merge und Produktionstrennung
PR #539 wurde als 056eafb0eddd0ec6369f71db65862f37b788b152
gemergt. Das Vercel-Produktionsdeployment
dpl_2bsKrqhys1CuRFQV6QUV6HiSJghg war READY, hatte target=production,
war laut Vercel-API exakt an diesen Merge-Commit gebunden und trug die Aliase
www.landnutzen.at, landnutzen.at und landnutzen.vercel.app.
| Produktionsgegenprobe | Ergebnis | Request-ID |
|---|---|---|
POST /free | leerer 404, 0 Cookies | fra1::iad1::nvzqx-1787909528360-7b9db31c8539 |
POST /standard | leerer 404, 0 Cookies | fra1::iad1::7n8sf-1787909531165-b81bb202595c |
POST /premium | leerer 404, 0 Cookies | fra1::iad1::tvz26-1787909533932-6eece646285b |
POST /planer | leerer 404, 0 Cookies | fra1::iad1::thzxz-1787909536750-1172948d40aa |
GET /free | leerer 404, 0 Cookies | fra1::iad1::6d2dc-1787909539947-b7d0517c2397 |
Alle fünf Antworten des unveränderlichen Produktionsdeployments trugen
Cache-Control: private, no-store und
X-Robots-Tag: noindex, nofollow, noarchive. Damit ist die
Produktionstrennung belegt; es wurde kein
PDF/UA-Produktpfad geöffnet. Ein schreibfreier POST /api/v1/report mit
leerem Objekt bestätigte zusätzlich über X-Deploy-Commit exakt den
Merge-SHA und endete erwartungsgemäß mit 400 address_missing; Request-ID
fra1::iad1::7fxf2-1787909552341-99b38251851c.
Offene Produktabnahme
| Bereich | Stand |
|---|---|
31 repräsentative Sektionen des echten Report-Typs | lokal und im geschützten Preview belegt |
| drei datenbasierte Figure-Alternativtexte | lokal und im geschützten Preview belegt |
| geschützter Preview-Readback und Produktionstrennung | commitgebunden belegt |
| echte gespeicherte Reports und Karten-/Viewerregression | offen |
| kontrollierter Produktrollout und PDF/UA-Live-Readback | offen |
| manuelle Screenreader-Abnahme | offen |
Issue #333 bleibt bis zum Abschluss der Produktgates offen.