Ga naar inhoud

De ontwerpfilosofie van NextPDF

Spec: ISO/IEC 25010 Spec: ISO 32000-2 Evidence: Design principle

Deze pagina benoemt de principes waaraan elke API-beslissing in NextPDF wordt getoetst. Het zijn er bewust weinig, want een principe dat je niet uit het hoofd kunt opzeggen, kun je onder druk niet toepassen.

Dit is de pagina die je als eerste leest. De andere Insider-pagina’s laten zien hoe deze principes op specifieke plaatsen werken. Deze pagina benoemt ze, zodat de rest begrijpelijk wordt.

PDF is oud genoeg om overtuigingen te hebben en streng genoeg om gissingen af te straffen. Een handtekening dekt precies de bytes die zij dekt. Een lettertype is ofwel ingesloten ofwel niet. Een archiveringsprofiel houdt maanden later stand in een audit of zakt ervoor, tegenover iemand die bewijs nodig heeft.

Bij dubbelzinnige invoer heeft een bibliotheek een keuze. Ze kan gissen en zwijgen, of stoppen en dat melden. Het eerste voelt vriendelijker aan in een demo. Het kan je ook een productie-incident kosten zonder enig spoor van wat er misging. NextPDF kiest voor het tweede. Het accepteert een minder geruststellende eerste indruk in ruil voor een verdedigbare uitkomst. Normen voor softwarekwaliteit benoemen deze afweging rechtstreeks. Fail-safe-gedrag is het vermogen van een product om bij een storing terug te keren naar een veilige toestand in plaats van door te gaan in een ongedefinieerde toestand ( Spec: ISO/IEC 25010, §3 ).

NextPDF is gebouwd op vijf principes, in volgorde van prioriteit:

  1. Expliciet wint van impliciet. Als de bedoeling ertoe doet, benoemt u die. De engine leidt geen handtekeningniveau, uitvoermodus of conformiteitsdoel af uit de context.
  2. Faal snel, faal luid, faal vroeg. Een ongeldige invoer wordt afgewezen voordat er een byte wordt weggeschreven, met een bericht dat de oorzaak benoemt.
  3. Fouten zijn een API-oppervlak. Storingen zijn specifiek en getypeerd, en bevatten gestructureerde context — ontworpen, niet toevallig.
  4. Grenzen worden benoemd, niet ontdekt. Elke bewering vermeldt waar zij ophoudt. “Noodzakelijk, niet voldoende” is een formulering die NextPDF bewust gebruikt.
  5. Niets verslechtert stilzwijgend. De engine retourneert geen halfcorrect artefact dat er voltooid uitziet.

Al het overige — de fluent builder, het wegwerpdocument, strikte typering — vloeit voort uit deze principes.

De principes zijn geen slogans. Ze krijgen concrete vorm in de broncode en versterken elkaar.

De onderstaande tabel koppelt elk principe aan de plaats waar je het in de engine kunt zien en aan wat het kost als het ontbreekt.

PrincipeHoe het terugkomt in NextPDFDe prijs van het tegenovergestelde
Expliciet wint van implicietsetSignature(certInfo:, level:) neemt het PAdES-niveau als een verplicht, benoemd argument — er is geen “auto”-niveauEen document dat is ondertekend met een profiel dat de verplichting niet vereiste, en dat pas tijdens de validatie wordt ontdekt
Faal snel, faal luidsave() wijst een stream-wrapper-pad of null-byte-pad af voordat er wordt gerenderd; setSignature() gevolgd door save() werpt een uitzondering in plaats van een niet-ondertekend bestand weg te schrijvenEen schrijfactie via path traversal, of een “niet-ondertekend maar verondersteld ondertekend” PDF-bestand in een archief
Fouten zijn een API-oppervlakEén abstracte basisuitzondering en specifieke, getypeerde subklassen, die elk een gestructureerde getContext() blootstellen voor logboeken en APMEen generieke stacktrace en een lange middag gissen
Grenzen worden benoemdIn-process conformiteitscontroles retourneren bevindingen en zeggen expliciet dat het oordeel bij een onafhankelijke validator ligtEen conclusie van “geen uitzondering, dus het moet conform zijn” die een auditor weerlegt
Niets verslechtert stilzwijgendHet pad voor archiveringstijdstempels weigert een halfgeschreven profiel te retourneren in plaats van er een weg te schrijven waarin het vereiste woordenboek ontbreektEen langetermijnvalidatieprofiel dat stilzwijgend geen langetermijnvalidatieprofiel blijkt te zijn

Lees de principes samen en er ontstaat één standpunt: de engine geeft je liever een eerlijk “nee” dan een zelfverzekerd “misschien”. Dat is geen pessimisme. Het erkent dat een PDF vaak een juridisch artefact is. Een juridisch artefact dat onjuist is, is erger dan een artefact dat nooit is geproduceerd.

Deze pagina is een Evidence: Design principle -verklaring: de principes zijn bewuste beslissingen, beargumenteerd in plaats van gemeten. Waar een principe een naam heeft in een externe discipline, sluit deze pagina daarop aan, zodat de redenering niet louter een interne opinie is.

  • Het standpunt “weiger in plaats van door te gaan in een ongedefinieerde toestand” is de fail-safe-kwaliteitseigenschap in Spec: ISO/IEC 25010 §3 — een product dat zichzelf bij een storing in een veilige toestand brengt. Fault tolerance, binnen dezelfde familie, is de mate waarin een systeem zich ondanks fouten blijft gedragen zoals bedoeld. NextPDF richt die inspanning op detecteren en stoppen, niet op het verhullen van de fout.
  • Het standpunt “benoem de grens vóór de aanschaf” is appropriateness recognizability ( Spec: ISO/IEC 25010, §3.26 ): het vermogen om de geschiktheid te beoordelen op basis van documentatie en eerste indrukken.
  • De PDF-specifieke reden waarom dit alles ertoe doet, is Spec: ISO 32000-2, §12.8 : het byte-bereik van een handtekening beschermt precies de bytes die het dekt en niets meer, zodat een engine die een ondertekend document “behulpzaam” herschrijft of er omheen gist, in feite niet heeft geholpen.

De afzonderlijke principes worden op hun eigen pagina’s gedemonstreerd aan de hand van echte engine-broncode — Een API die weigert te gissen en Fouten als functie leveren het Evidence: Code-backed bewijs. Deze pagina is het waarom; die pagina’s zijn het wat.

De principes zijn zichtbaar in een paar regels normaal gebruik. De handtekeningaanroep benoemt de bedoeling expliciet. De engine weigert vroeg in plaats van iets misleidends weg te schrijven.

<?php
declare(strict_types=1);
use NextPDF\Core\Document;
use NextPDF\Exception\NotImplementedException;
use NextPDF\Security\Signature\CertificateInfo;
use NextPDF\Security\Signature\SignatureLevel;
$document = Document::createStandalone();
$document->setTitle('Service Agreement 2026-0042');
$document->addPage();
$document->setFont('helvetica', '', 12);
$document->cell(0, 10, 'This agreement is configured for a PAdES signature.', newLine: true);
// Explicit beats implicit: the PAdES level is a required, named argument.
// There is no inferred or "auto" level.
$document->setSignature(
certInfo: new CertificateInfo(
certificate: $certificatePem,
privateKey: $privateKeyPem,
),
level: SignatureLevel::PAdES_B_B,
);
try {
// Fail fast, no silent degradation: rather than emit an UNSIGNED file
// that the caller believes setSignature() signed, the high-level path
// refuses and names the supported route.
$document->save('/srv/output/agreement.pdf');
} catch (NotImplementedException $e) {
// The message identifies the feature and the follow-up, not a stack
// trace: "... is not implemented in this release. <actionable follow-up>"
error_log($e->getMessage());
}

Het gaat niet om de mechaniek van de handtekening. Drie principes zijn zichtbaar in één snippet: de bedoeling wordt benoemd (level:), de fout wordt vroeg en expliciet gemeld, en de engine weigert een document te produceren dat zou liegen over zijn eigen toestand.

De meest voorkomende misvatting is dat deze principes NextPDF “moeilijker te gebruiken” maken. Ze maken het moeilijker om het verkeerd te gebruiken. Een verplicht argument is één stilzwijgende standaardwaarde minder die je kan verrassen. Een vroege uitzondering is één corrupt artefact minder in een archief. De wrijving wordt bewust geplaatst waar een fout goedkoop is — bij de aanroep, tijdens de ontwikkeling — in plaats van waar zij duur is: in productie, in een audit, in de rechtszaal.

Een tweede misvatting is dat “uitgesproken” “onbuigzaam” betekent. Dat is niet zo. De engine heeft overtuigingen over correctheid en bedoeling, niet over je document. Je hebt nog steeds volledige controle over lay-out, inhoud, lettertypen en structuur. Die overtuigingen betekenen dat de engine niet namens je gist waar een gissing onveilig zou zijn.

Deze pagina benoemt de ontwerpbedoeling. Zij is zelf geen gedragsspecificatie. De principes beschrijven hoe beslissingen worden genomen, niet wat een afzonderlijke methode garandeert. Het exacte contract van elke methode staat in de referentie en op de eigen Insider-pagina met het bewijsniveau van die pagina.

De principes zijn ook geen absolute natuurwetten. Het zijn prioriteiten, toegepast met oordeelsvermogen. Waar twee principes botsen (een striktere weigering tegenover een vergevingsgezindere standaardwaarde), is de bovenstaande prioriteitsvolgorde doorslaggevend. Een specifieke module kan nog steeds een beredeneerde uitzondering documenteren. Wanneer dat gebeurt, wordt die uitzondering opgeschreven, niet verondersteld.

Tot slot is “ontwerpprincipe” hier bewust de bewijsbasis. Deze pagina argumenteert. Zij benchmarkt niet. Beweringen die een getal, een test of een clausule nodig hebben als onderbouwing, worden gedaan op de pagina’s die over dat bewijs beschikken, niet hier.

  • Ontwerpprincipe (bewijsniveau) — een pagina waarvan de beweringen bewuste ontwerpbeslissingen zijn, beargumenteerd vanuit de bedoeling en ondersteunende standaarden in plaats van gemeten met een benchmark of een enkele test.
  • Fail-safe — een softwarekwaliteitseigenschap: bij een storing keert het product terug naar een veilige toestand in plaats van door te gaan in een ongedefinieerde toestand. Dit is de reden waarom NextPDF weigert in plaats van gist.
  • Fail fast — een ongeldige invoer zo vroeg mogelijk afwijzen, met een duidelijke oorzaak, in plaats van door te gaan en later op een obscure manier te falen.
  • PAdES — PDF Advanced Electronic Signatures, de ETSI-profielfamilie voor het ondertekenen van PDF-documenten (B-B, B-T, B-LT, B-LTA). Hier bij eerste gebruik voluit geschreven; uitgebreid behandeld op de ondertekeningspagina’s.
  • Noodzakelijk, niet voldoende — een bewuste formulering die wordt gebruikt wanneer een in-process controle een echt signaal is maar geen conformiteitsoordeel; de gezaghebbende beslissing ligt bij een onafhankelijke validator.