Enterprise édition
Piste d’audit AST — Référence détaillée
En un coup d’œil
Section intitulée « En un coup d’œil »Le module AST Enterprise enregistre les mutations de document et prépare les documents pour les pipelines de récupération.
AstAuditTrailInterfacedéfinit une piste d’audit par document, en ajout seul, au-dessus duMutationLogde l’AST Pro.AstAuditEntryest un enregistrement immuable d’une mutation : identité du nœud, type de mutation, page, instantanés avant/après, horodatage UTC.InMemoryAstAuditTrailest l’implémentation de référence par processus du contrat de piste.AstAwareChunkerparcourt l’AST en profondeur d’abord et émet des valeursAstChunkancrées sur des citations, destinées à l’ingestion RAG.
Disponibilité et licence
Section intitulée « Disponibilité et licence »Cette capacité est livrée dans NextPDF Enterprise (nextpdf/enterprise) et s’active avec une enveloppe de licence de niveau Enterprise. Un déploiement dépourvu de ce droit ne charge pas les classes de la capacité. Compare les éditions et obtiens une licence.
La surface de piste d’audit AST est licenciée par la capacité enterprise.compliance.evidence. Un droit refusé refuse la fonctionnalité.
| Niveau | Fournit |
|---|---|
| Core | Modèle de document AST (AstDocument, AstNode, NodeId) |
| Pro | Flux de mutation AST et MutationLog |
| Enterprise | Piste d’audit par document en ajout seul ; chunker ancré sur des citations |
La surface Enterprise consomme le journal de mutations Pro. Elle ne remplace pas le modèle AST.
composer require nextpdf/enterprise:^3Surface d’API publique
Section intitulée « Surface d’API publique »| Symbole | Paramètres | Comportement par défaut | Retourne | Lève ou échoue avec | Notes |
|---|---|---|---|---|---|
AstAuditTrailInterface::record() | string $documentSourceHash, MutationLog $log | Convertit chaque entrée de mutation du journal en AstAuditEntry et l’ajoute | void | Rien dans l’implémentation de référence | Des appels répétés avec le même hash accumulent les entrées |
AstAuditTrailInterface::findByDocument() | string $documentSourceHash | Retourne les entrées enregistrées pour un document, dans l’ordre d’insertion | list<AstAuditEntry> | Rien dans l’implémentation de référence | Liste vide quand aucune entrée ne correspond au hash |
AstAuditTrailInterface::count() | aucun | Compte les entrées d’audit | int<0, max> | Rien dans l’implémentation de référence | Total sur tous les documents, pas par document |
InMemoryAstAuditTrail | aucun | Piste adossée à un tableau, cantonnée au processus courant | implémente AstAuditTrailInterface | Rien | Non durable ; adaptée aux cycles de vie mono-requête |
AstAuditEntry | le constructeur promeut tous les champs | Enregistrement d’audit immuable | objet valeur | Rien | final readonly ; voir la clôture de signature ci-dessous |
AstAwareChunker::__construct() | int $maxChunkChars = 1500, int $overlapChars = 150 | Valide les bornes de découpage à la construction | instance | InvalidArgumentException sur une configuration hors plage | Bornes : 16 <= maxChunkChars <= 1048576 ; 0 <= overlapChars < maxChunkChars |
AstAwareChunker::chunk() | AstDocument $document | Parcours en profondeur d’abord ; les titres délimitent les chunks ; le texte des feuilles s’accumule | list<AstChunk> | Rien | Liste vide pour un document sans texte accumulable |
AstChunk | le constructeur promeut tous les champs | Enregistrement de chunk ancré sur une citation | objet valeur | Rien | final readonly ; voir la clôture de signature ci-dessous |
namespace NextPDF\Enterprise\Ast;
use NextPDF\Pro\Ast\Mutation\MutationLog;
interface AstAuditTrailInterface{ public function record(string $documentSourceHash, MutationLog $log): void;
/** @return list<AstAuditEntry> */ public function findByDocument(string $documentSourceHash): array;
/** @return int<0, max> */ public function count(): int;}final readonly class AstAuditEntry{ public function __construct( public readonly string $documentSourceHash, public readonly string $nodeId, public readonly string $mutationType, public readonly int $pageIndex, public readonly array $before, public readonly array $after, public readonly DateTimeImmutable $occurredAt, ) {}}final class AstAwareChunker{ public function __construct( private readonly int $maxChunkChars = 1500, private readonly int $overlapChars = 150, ) {}
/** @return list<AstChunk> */ public function chunk(AstDocument $document): array {}}final readonly class AstChunk{ public function __construct( public readonly string $text, public readonly string $nodeId, public readonly int $pageIndex, public readonly ?array $bbox, public readonly string $nodeType, public readonly string $documentSourceHash, public readonly int $chunkIndex, ) {}}Contrat de comportement
Section intitulée « Contrat de comportement »Piste d’audit
Section intitulée « Piste d’audit »- Ajout seul. Les implémentations doivent être en ajout seul : une entrée enregistrée ne peut être ni modifiée ni supprimée via cette API. Des appels
record()répétés avec le même hash accumulent les entrées. - Conversion.
record()convertit chaque entrée duMutationLogPro (viaMutationLog::all()) enAstAuditEntryet l’ajoute. Toutes les entrées produites par un seul appelrecord()partagent un même horodatage UTCoccurredAt. - Isolation par document.
findByDocument()filtre sur le hash source exact du document et préserve l’ordre d’insertion.count()est le total sur tous les documents. - Instantanés.
beforeetaftersont des cartes d’attributs indexées partext_content. Une mutationupdatedremplit les deux côtés ;insertedlaissebeforevide ;deletedlaisseaftervide.mutationTypeest la valeur chaîne de l’énumérationMutationTypePro :updated,insertedoudeleted. - Dérivation de la page.
pageIndexest extrait de l’identifiant canonique du nœud (ast:{hash}:{page}:{seq}). Un identifiant de nœud mal formé donne unpageIndexde 0 ; l’entrée est tout de même enregistrée.
L’ajout seul est un contrat du store configuré, pas une propriété cryptographique. L’inviolabilité et la non-répudiation proviennent de la façon dont la piste est persistée et horodatée (module Evidence), et non de ce module seul.
- Parcours.
chunk()parcourt l’AST en profondeur d’abord à partir de la racine du document. - Accumulation de texte. Le texte des feuilles de type Paragraph, ListItem, TableCell, Code ou Annotation s’accumule dans le tampon courant. Les types conteneurs (Document, Section, Artifact, FormField, Figure, Table, List, TableRow) sont parcourus sans émettre de texte.
- Délimiteurs. Un nœud Heading vide le tampon courant en chunk et amorce le tampon suivant avec le texte du titre.
- Découpage. Lorsque le texte accumulé dépasserait
maxChunkChars, le chunker remplit l’espace restant, vide le chunk, puis continue avec lesoverlapCharsderniers caractères plus le débordement. La comptabilité de longueur est basée sur les caractères UTF-8. - Ancre de citation. Chaque
AstChunkporte lesnodeId,pageIndex,bboxetnodeTypede son premier nœud contributeur, plus le hash source du document et unchunkIndexséquentiel indexé à partir de 0. - Finalisation. Un tampon final au contenu non blanc est vidé en dernier chunk ; les restes composés uniquement d’espaces sont écartés, et le texte des chunks est détouré.
Cas limites et modes de défaillance
Section intitulée « Cas limites et modes de défaillance »- Enregistrer deux fois le même
MutationLogaccumule des entrées en double ; l’idempotence doit être imposée en amont. - Un
InMemoryAstAuditTrailneuf et non partagé est toujours vide. Le contrat d’intégration exige une seule instanceAstAuditTrailInterfacepartagée, remise à la fois au flux producteur de mutations et au consommateur lecteur d’audit, avecrecord()appelé après chaque écriture réussie. Jusque-là,findByDocument()retourne une liste vide etcount()retourne 0. - La piste en mémoire est par processus et non durable ; les entrées ne survivent pas à la requête qui les a créées. La production fournit une implémentation persistante.
- Un identifiant de nœud qui échoue à l’analyse canonique n’interrompt pas l’enregistrement ; l’entrée concernée retombe sur un
pageIndexde 0. AstAwareChunker::__construct()rejette une configuration dégénérée (overlapChars >= maxChunkChars, oumaxChunkCharshors de[16, 1048576]) avecInvalidArgumentException. Cela empêche une croissance non bornée du tampon pendant le découpage.AstChunk::$bboxvautnulllorsque le premier nœud contributeur ne porte aucune boîte englobante.- Un document sans texte accumulable produit une liste de chunks vide.
- Ce module n’effectue aucune opération cryptographique. Le hachage, la signature et l’horodatage pour l’inviolabilité sont gérés par les modules Evidence, Security et Signature ; la politique de mode FIPS y réside.
Conformité
Section intitulée « Conformité »| Comportement | Référence |
|---|---|
| Contexte de mise à jour incrémentale / intégrité de signature | ISO 32000-2:2020 §12.8 |
La piste d’audit est une aide à la tenue de registres. Elle prend en charge des workflows de preuves de type audit ; ce n’est ni une certification ni une attestation légale, et NextPDF ne détient aucune certification.
Notes de développement
Section intitulée « Notes de développement »- Fournis une implémentation
AstAuditTrailInterfacedurable pour une rétention entre requêtes. Persiste-la dans un store compatible WORM là où la conformité exige l’immuabilité ; la garantie d’ajout seul ne vaut que ce que vaut le store sous-jacent. - Les instantanés de mutation peuvent porter des données personnelles ; la résidence des données suit le store de l’opérateur.
- La piste consomme le journal de mutations Pro tel qu’il est produit ; elle ne redérive pas les mutations à partir de l’état du document.
- Les valeurs par défaut du chunker (
maxChunkChars1500,overlapChars150) conviennent à une ingestion RAG typique ; ajuste-les dans les bornes documentées pour les modèles d’embedding aux budgets de contexte différents. - Le détail des mécanismes internes reste dans la documentation interne du dépôt source et sort du périmètre de ce manuel.
Limite de publication
Section intitulée « Limite de publication »Cette page documente uniquement le comportement observable de l’extérieur et la surface d’API publique prise en charge. Les chemins d’espaces de noms internes, les classes utilitaires, les tables de mécanismes, les noms de fichiers de runbook et les préfixes de tickets sortent du périmètre.