Aller au contenu

Conformité : routage de ConformanceMode et frontière de validation

NextPDF\Conformance porte le discriminant unique qui indique au writer le contrat ISO visé par un document. La bibliothèque émet les structures définies par le contrat. Elle ne certifie pas, et ne peut pas certifier, la conformité du fichier obtenu. Seul un validateur externe peut certifier cette conformité.

Fenêtre de terminal
composer require nextpdf/core:^3

Le module Conformance expose deux types publics. ConformanceMode est une énumération typée (backed enum) qui nomme le contrat visé (Plain, PdfUa1, PdfUa2, PdfA2, PdfA3, PdfA3b, PdfA3u, PdfA4, PdfA4e, PdfA4f). ConformancePolicy est un objet valeur immuable qui combine un mode et des bascules de rigueur orthogonales.

Le mode est la source de vérité unique pour les barrières en aval côté writer. Avant l’existence de cette énumération, le moteur déduisait « ce document est-il balisé selon la spécification ? » à partir de drapeaux dispersés. ConformanceMode::isTagged(), isAccessibility(), isArchival(), pdfaPart(), pdfaConformanceLetter() et requiresPdf17() renvoient toutes une réponse typée que le writer lit directement. Le catalogue, /MarkInfo, la lignée de l’en-tête du fichier et les marqueurs XMP pdfaid restent cohérents avec l’intention déclarée.

Garde bien en tête la frontière du support. NextPDF Core émet les structures définies par ces normes. ISO 19005-4:2020 §6.7.3 spécifie le schéma d’identification qui enregistre la variante de PDF/A revendiquée par un fichier. ISO 19005-4:2020 indique que la détermination effective de la conformité s’effectue comme spécifié dans sa Clause 5 — c’est-à-dire au regard des exigences normatives, par un outil de vérification, et non par la bibliothèque productrice. ISO 14289-2:2024 §6 présente la conformité comme une propriété qu’un fichier satisfait. Le fait que NextPDF fixe un mode est une donnée d’entrée nécessaire pour obtenir un fichier conforme. À lui seul, cela ne constitue pas un résultat de conformité.

C’est la même discipline « Vérifié contre Revendiqué » qu’applique la matrice de support CSS. Une capacité n’est Vérifiée que lorsqu’il existe une exécution de test ou d’oracle réussie et une clause citée. Tout le reste est une implémentation que la bibliothèque émet — utile, mais pas une garantie de conformité. La conformité est une propriété du fichier final accompagné d’un validateur, pas une promesse de la bibliothèque. Valide la sortie avec veraPDF (voir « Conformité » plus bas).

Une deuxième frontière compte pour l’archivage. La production de PDF/A-4 — le dictionnaire OutputIntent, le profil ICC intégré et le schéma d’extension XMP — est livrée dans l’extension nextpdf/pro, pas dans Core. Dans une installation Core seule, Document::enablePdfA() lève InvalidConfigException parce que la capacité security.pdfa n’est pas enregistrée. Core garde la maîtrise du discriminant ConformanceMode (afin que l’introspection et le chemin balisé PDF/UA-2 fonctionnent), mais il ne produit pas à lui seul un fichier PDF/A-4.

TypeCatégorieMembres clés
NextPDF\Conformance\ConformanceModeenum: stringPlain, PdfUa1, PdfUa2, PdfA2, PdfA3, PdfA3b, PdfA3u, PdfA4, PdfA4e, PdfA4f ; isTagged(), isAccessibility(), isArchival(), requiresPdfUa2PageTabs(), pdfaPart(): ?int, pdfaConformanceLetter(): string, requiresPdf17(): bool
NextPDF\Conformance\ConformancePolicyfinal readonly class__construct(ConformanceMode $mode = PdfUa2, bool $strictUa2 = false, bool $rejectUnvalidatedLang = false, …) ; lax(), strictUa2(), withUax9IsolateSupport(), withoutAstShadowMode(), withBlackPointCompensation(), withStrictOcspProducedAtTolerance(), withAllowStaleOcsp()

ConformancePolicy impose un invariant dans son constructeur : les bascules strictes PDF/UA-2 ne s’appliquent que lorsque le mode est PdfUa2, et strictUa2 = true force rejectUnvalidatedLang = true. Les combinaisons incohérentes lèvent InvalidConfigException plutôt que de se dégrader silencieusement.

<?php
declare(strict_types=1);
use NextPDF\Conformance\ConformanceMode;
$mode = ConformanceMode::PdfA4f;
// Introspect the declared contract — these drive writer-side gates.
$mode->pdfaPart(); // 4
$mode->pdfaConformanceLetter(); // 'F'
$mode->requiresPdf17(); // false (PDF/A-4 is PDF 2.0 lineage)
$mode->isArchival(); // true

Le chemin livré dans Core qui exerce un contrat de conformité de bout en bout est la route balisée PDF/UA-2. Il correspond à l’exemple exécutable (examples/31-pdfua2-tagged.php) et sert aussi de cible d’oracle pour le profil strict PDF/UA-2.

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
$doc = Document::createStandalone();
// Set the tagged-PDF contract BEFORE writing content so the HTML pipeline
// wires the TaggedContentEmitter at parser-construction time.
$doc->enableTaggedPdf(lang: 'en');
$doc->setTitle('Accessible report');
// … write content …
$doc->save(__DIR__ . '/out/report-ua2.pdf');
// The library has now emitted PDF/UA-2 structures. It has NOT asserted
// conformance. Verify the file with the pinned veraPDF oracle:
//
// php oracle/run.php pdfua.strict
//
// (Requires the veraPDF Docker image — opt-in; see "Conformance" below.)
  • La production de PDF/A-4 est réservée à Premium. Document::enablePdfA() lève InvalidConfigException dans une installation Core seule (security.pdfa indisponible). Core garde la maîtrise du discriminant, pas l’émission OutputIntent/ICC/XMP. Voir /specifications/pdfa4/.
  • Cas générique (umbrella) et variantes. PdfA4 est le cas générique (umbrella) et renvoie une lettre pdfaConformanceLetter() vide. ISO 19005-4:2020 §6.7.3 prévoit qu’un fichier qui n’est conforme ni à PDF/A-4e ni à PDF/A-4f ne fournit aucun pdfa:conformance. Utilise PdfA4e / PdfA4f uniquement pour les variantes Annexe B / Annexe A.
  • Le mode strict PDF/UA-2 est optionnel (opt-in). ConformancePolicy::lax() est la valeur par défaut, sûre pour la compatibilité ascendante. strictUa2() force /MarkInfo /Marked true et le rejet de BCP-47. L’activer sur un mode autre que PdfUa2 lève une exception.
  • isTagged() tient compte de la variante. Plain, PdfA2, PdfA3b et PdfA4e se déclarent non balisés. Le writer ne doit pas partir du principe qu’un mode d’archivage implique un arbre de structure.
  • Un mode qui passe ne fait pas un fichier qui passe. Fixer PdfA4 ne rend pas la sortie un fichier PDF/A-4 valide. Lance un validateur.

ConformanceMode et ConformancePolicy sont des types valeur purs : la résolution d’un cas d’énumération et la répartition par match sont en O(1), sans allocation au-delà de l’objet de politique immuable. Ils n’ajoutent aucun coût mesurable au chemin d’écriture. Le writer domine le budget du module (wall_ms: 1500), pas le discriminant. L’oracle veraPDF est une étape de CI hors bande et ne fait pas partie de la génération du document.

Les bascules strictes de ConformancePolicy verrouillent un comportement de sécurité fermé par défaut (fail-closed) : securityPkiRfc5280Strict (validation de chemin RFC 5280 §6), strictOcspProducedAtTolerance (fenêtre de tolérance RFC 6960 §4.2.2.1) et allowStaleOcsp (false par défaut — rejette les réponses OCSP dépourvues de nextUpdate). Ces valeurs par défaut sont conservatrices et basculeront en mode strict dans une future version majeure, conformément à la stratégie de compatibilité ascendante documentée. Voir le module de sécurité et le modèle de menace du projet pour le détail du chemin de signature.

NextPDF ne certifie pas la conformité. Il émet les structures définies par les normes ci-dessous et un validateur distinct décide si un fichier est conforme.

NormeClauseCe que NextPDF Core faitStatut
ISO 14289-2:2024 (PDF/UA-2)§6Émet l’arbre de structure, /MarkInfo /Marked true (strict), /Lang, le XMP pdfuaid via le chemin balisé de CoreProfil vérifié : pdfua.strict validé par l’oracle veraPDF (php oracle/run.php pdfua.strict) lorsque le binaire veraPDF est présent (barrière optionnelle, opt-in)
ISO 19005-4:2020 (PDF/A-4)§6.7.3Émet le discriminant pdfaid:part / pdfa:conformance via ConformanceModeRevendiqué (émission du discriminant, couverte par des tests unitaires) ; la production d’un fichier PDF/A-4 est réservée à Premium
ISO 32000-2:2020 (PDF 2.0)§7.5.2Structure de base catalog/documentRevendiqué (comportement du moteur de base)

Le support n’est pas la conformité. NextPDF Core émet les structures d’identification PDF/UA-2 et PDF/A-4 (implémentation, attestée par les tests dans tests/Unit/Conformance/). Qu’un fichier soit conforme à PDF/A-4 ou à PDF/UA-2 ne peut être affirmé que par un validateur exécutant le profil correspondant. D’après la Clause 5 d’ISO 19005-4:2020, la détermination de la conformité est l’affaire du validateur, pas de la bibliothèque productrice.

Le contrôle par veraPDF annonce clairement son prérequis. L’oracle (oracle/run.php, oracle/lib/OracleRunner.php) délègue à une image Docker veraPDF épinglée. Quand Docker ou l’image est absent, le lanceur se termine avec le code 2 (échec d’infrastructure) et ne vérifie rien. Le profil pdfua.strict est donc une barrière de conformité optionnelle (opt-in) : il ne prouve la conformité que sur les machines où le binaire veraPDF est présent. NextPDF ne livre aucun validateur intégré et ne formule aucune revendication de conformité en son absence.

Les citations sont paraphrasées depuis le corpus de conformité de NextPDF. Les identifiants reference_id complets de 64 caractères sont consignés dans l’en-tête (front-matter) de la page et dans _normative-evidence-conf.md.