Aller au contenu

Valider la conformité : pré-contrôle en cours de traitement et oracle externe

Ce recipe exécute les validateurs de conformité 100 % PHP de NextPDF, en cours de traitement, comme pré-contrôle structurel rapide, puis confie la décision de conformité qui fait autorité à un validateur indépendant. Les contrôles en cours de traitement sont nécessaires, mais pas suffisants : un résultat sans constatation est un fait structurel, pas un verdict de conformité. Ce recipe s’appuie sur examples/33-validate-conformance.php et sur son harnais tests/Cookbook/Php/ValidateConformanceRecipeTest.php.

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

Les validateurs en cours de traitement ne nécessitent aucune chaîne d’outils externe. L’étape de la porte qui fait autorité nécessite un validateur externe dans le PATH. L’exemple utilise veraPDF. Tu n’as besoin ni d’un package Pro ni d’un package Enterprise.

NextPDF fournit des validateurs en cours de traitement sous \NextPDF\Compliance\Validator. Ils vérifient des invariants normatifs précis sans exécuter de processus externe :

  • PdfRValidator — contrôles du flux d’octets ISO 23504-1 (PDF/R-1) §5/§6 : la liste d’autorisation de l’en-tête de fichier, les objets de génération 0, la liste d’autorisation des opérateurs de contenu de page du §6.5.7 (q/Q/cm/Do uniquement), et la liste d’autorisation des clés du dictionnaire Info du §6.4.3. Il renvoie un PdfRValidationFinding[] plat ; une liste vide signifie que chaque contrôle gardé du §6 a réussi.
  • ArlingtonValidator — exécute la grammaire Arlington lisible par machine de la PDF Association en mode rapport seul : il ne bloque jamais le build, et il enregistre le SHA du commit de grammaire épinglé sur chaque constatation afin que les consommateurs d’audit puissent le corréler avec un instantané amont connu.

Ces contrôles ont une portée délibérément restreinte. Ils détectent la dérive entre un contrat d’émission et une spec, mais ils n’établissent pas la conformité ISO pour un profil tel que PDF/A-4 ou PDF/UA-2. Cette détermination revient à un validateur indépendant dont le verdict est la porte du build (ISO 19005-4 §6.7.3 le rend explicite pour PDF/A). Le recipe garde une frontière nette : il exécute le pré-contrôle en cours de traitement, puis affiche et exécute la commande de l’oracle externe qui décide.

Le diagramme ci-dessous montre la porte à deux étages. Une seule règle la régit : seul le verdict de l’oracle externe peut être rapporté comme conformité.

Findings

Clean

Pass

Fail

Produced PDF bytes

In-process pre-check

PdfRValidator / Arlington

Structural drift?

Fail fast — cheap reject

NOT a conformance verdict

Necessary, not sufficient

never report as conformance

Independent external validator

the authoritative oracle

Oracle verdict

May report file conforming

Not conforming — do not ship

Diagram

La surface de l’API est générée à partir de la PHPDoc. Voici les principaux points d’entrée :

  • \NextPDF\Compliance\Validator\PdfRValidator::validate(string $pdfBytes): list<PdfRValidationFinding>
  • \NextPDF\Compliance\Validator\PdfRValidationFinding (en lecture seule : clause, severity, message)
  • \NextPDF\Compliance\Validator\ArlingtonValidator::validateReportOnly(string $pdfPath): list<ArlingtonFinding>
  • \NextPDF\Core\Document::output(?string $filename, OutputDestination $dest): string (OutputDestination::String pour les octets bruts)
<?php
declare(strict_types=1);
require_once __DIR__ . '/vendor/autoload.php';
use NextPDF\Compliance\Validator\PdfRValidator;
use NextPDF\Contracts\OutputDestination;
use NextPDF\Core\Document;
$doc = Document::createStandalone();
$doc->addPage();
$doc->setFont('helvetica', '', 12);
$doc->cell(0, 10, 'Document under conformance review.', newLine: true);
$bytes = $doc->output(dest: OutputDestination::String);
$findings = (new PdfRValidator())->validate($bytes);
// A finding list is a structural fact, not a conformance verdict.
echo $findings === []
? "No in-process PDF/R-1 findings (necessary, not sufficient).\n"
: count($findings) . " in-process finding(s); not a conformance verdict.\n";

En production, l’appelant traite le validateur en cours de traitement comme une porte peu coûteuse qui échoue vite dès qu’une dérive structurelle évidente apparaît, puis exécute l’oracle externe comme la décision de conformité qui fait autorité. Seul le verdict de l’oracle peut être rapporté comme conformité.

examples/33-validate-conformance.php (gate core)
$bytes = $doc->output(dest: OutputDestination::String);
$doc->save($out);
// 1. In-process pre-check — necessary, not sufficient.
$findings = (new PdfRValidator())->validate($bytes);
foreach ($findings as $finding) {
fwrite(STDERR, sprintf("[%s] §%s — %s\n",
$finding->severity, $finding->clause, $finding->message));
}
// 2. The authoritative gate — the external validator decides.
$exitCode = 0;
$report = [];
exec('verapdf --flavour 4 ' . escapeshellarg($out), $report, $exitCode);
if ($exitCode !== 0) {
fwrite(STDERR, "veraPDF FAILED — not reported conforming\n");
fwrite(STDERR, implode("\n", $report) . "\n");
exit(1);
}
echo "veraPDF PASS — the validator reports the file conforming\n";

Exécute l’exemple avec php examples/33-validate-conformance.php. Il construit un PDF ordinaire, puis affiche les constatations issues du contrôle en cours de traitement. Un PDF ordinaire est censé produire des constatations PDF/R-1, et c’est précisément le point pédagogique. L’exemple affiche ensuite la commande de l’oracle externe qui fait autorité.

  • Nécessaire, mais pas suffisant. Une liste de constatations PdfRValidator vide signifie que les contrôles gardés du §6 ont réussi, rien de plus. Ce n’est pas une affirmation de conformité PDF/A-4 ou PDF/UA-2. Ne rapporte jamais une conformité à partir d’un seul résultat en cours de traitement.
  • Un PDF ordinaire échoue à PDF/R-1 par conception. PDF/R-1 est un profil raster image uniquement ; un PDF texte normal produit légitimement des constatations §6.5.7 et §6.4.3. L’exemple le démontre exprès pour montrer que la sortie en cours de traitement est un fait structurel, pas un verdict.
  • Arlington est en rapport seul. ArlingtonValidator::validateReportOnly() ne lève jamais d’exception et ne bloque jamais. En mode grammaire seule, il émet une constatation info attestant que le SHA de grammaire épinglé est chargé ; il renvoie une liste vide quand la grammaire n’est pas matérialisée. Ne construis pas de porte pass/fail dessus — c’est un artefact de contre-vérification.
  • Octets vs. fichier. PdfRValidator::validate() prend la chaîne d’octets bruts (OutputDestination::String) ; l’oracle externe a besoin d’un chemin de fichier. Persiste le document avec save() pour l’étape de l’oracle.
  • Entrée vide. Passer une chaîne vide ou sans en-tête à PdfRValidator::validate() renvoie une constatation d’erreur §6.2.2 plutôt que de lever une exception. Vérifie la liste de constatations ; ne suppose pas une exception.

Les validateurs en cours de traitement effectuent des analyses par regex et par octets en une seule passe sur le PDF. Ils sont rapides et économes en allocations pour les documents typiques, et ils restent dans le budget de 2000 ms / 128 Mo. Quand il est présent, l’oracle externe domine le temps total, mais il s’exécute hors du processus. Le profil de reproductibilité sémantique s’applique. L’intérêt de l’exemple tient à son comportement de validation observable, que le harnais vérifie via une comparaison structurelle AST plus métadonnées.

Les validateurs lisent les octets du document en cours de traitement, et rien ne quitte le processus. L’oracle externe, en revanche, reçoit le fichier. Si tu exécutes un validateur hébergé, le contenu du document quitte ta frontière. Préfère un binaire de validateur local pour le contenu sensible, ou caviarde le document avant de valider.

Les constatations peuvent citer des chemins d’objets et des fragments d’opérateurs. L’exemple écrit les constatations sur STDERR et une ligne de progression fixe sur STDOUT. Garde les journaux de constatations hors des collecteurs partagés pour les documents sensibles. Ne journalise jamais les octets bruts du PDF.

Un résultat propre en cours de traitement n’est pas un signal d’intégrité ni d’authenticité. Un producteur hostile peut fabriquer un fichier qui passe les contrôles en cours de traitement à portée restreinte mais échoue au validateur complet, ou qui est bien formé mais trompeur. Traite la réussite du contrôle en cours de traitement comme un filtre rapide, jamais comme une marque de confiance.

Ce recipe n’effectue aucune opération cryptographique. Le mode FIPS ne change pas son comportement. Aucune signature, aucun chiffrement ni aucun condensat de matériel de confiance n’est produit.

ÉnoncéSpecClausereference_id
Le contenu de page PDF/R-1 n’utilise que la liste d’autorisation des opérateurs q/Q/cm/Do.ISO 23504-1§6.5.7
Les pages PDF/R-1 contiennent uniquement du contenu raster image.ISO 23504-1§6.5.5
PDF/R-1 contraint les clés du dictionnaire d’informations du document.ISO 23504-1§6.4.4
La grammaire Arlington est une contre-vérification lisible par machine du modèle objet.Arlington PDF Modelgrammaire
C’est un validateur, et non le producteur, qui décide de la conformité.ISO 19005-4§6.7.3

Les validateurs en cours de traitement de NextPDF vérifient des invariants normatifs précis. Le support n’est pas la conformité ; la validation n’est pas la certification. Un résultat propre en cours de traitement n’établit pas la conformité ISO ; un validateur indépendant (par exemple veraPDF) fait cette détermination. Fais de son verdict la porte du build.