Enterprise edizione
Audit trail dell'AST — Riferimento approfondito
In sintesi
Sezione intitolata “In sintesi”Il modulo AST di Enterprise registra le mutazioni dei documenti e prepara i documenti per le pipeline di recupero.
AstAuditTrailInterfacedefinisce un audit trail append-only, per documento, sopra ilMutationLogdell’AST di Pro.AstAuditEntryè un record immutabile di una singola mutazione: identità del nodo, tipo di mutazione, pagina, snapshot before/after, timestamp UTC.InMemoryAstAuditTrailè l’implementazione di riferimento per processo del contratto della traccia.AstAwareChunkerpercorre l’AST in profondità (depth-first) ed emette valoriAstChunkancorati alle citazioni per l’ingestione RAG.
Disponibilità e licenza
Sezione intitolata “Disponibilità e licenza”Questa capability è inclusa in NextPDF Enterprise (nextpdf/enterprise) e si attiva con un envelope di licenza di tier Enterprise. Un deployment privo di tale diritto non carica le classi della capability. Confronta le edizioni e ottieni una licenza.
La superficie dell’audit trail dell’AST è gestita in licenza dalla capability enterprise.compliance.evidence. Un diritto negato nega la funzionalità.
| Tier | Fornisce |
|---|---|
| Core | Modello del documento AST (AstDocument, AstNode, NodeId) |
| Pro | Flusso di mutazione dell’AST e MutationLog |
| Enterprise | Audit trail append-only per documento; chunker ancorato alle citazioni |
La superficie Enterprise consuma il log delle mutazioni di Pro. Non sostituisce il modello AST.
composer require nextpdf/enterprise:^3Superficie API pubblica
Sezione intitolata “Superficie API pubblica”| Simbolo | Parametri | Comportamento predefinito | Restituisce | Solleva o fallisce con | Note |
|---|---|---|---|---|---|
AstAuditTrailInterface::record() | string $documentSourceHash, MutationLog $log | Converte ogni voce di mutazione del log in un AstAuditEntry e la aggiunge in append | void | Nulla nell’implementazione di riferimento | Chiamate ripetute con lo stesso hash accumulano voci |
AstAuditTrailInterface::findByDocument() | string $documentSourceHash | Restituisce le voci registrate per un singolo documento, in ordine di inserimento | list<AstAuditEntry> | Nulla nell’implementazione di riferimento | Lista vuota quando nessuna voce corrisponde all’hash |
AstAuditTrailInterface::count() | nessuno | Conta le voci di audit | int<0, max> | Nulla nell’implementazione di riferimento | Totale su tutti i documenti, non per documento |
InMemoryAstAuditTrail | nessuno | Traccia basata su array e limitata al processo corrente | implementa AstAuditTrailInterface | Nulla | Non durevole; adatta a cicli di vita a singola richiesta |
AstAuditEntry | il costruttore promuove tutti i campi | Record di audit immutabile | value object | Nulla | final readonly; vedi il blocco della firma più sotto |
AstAwareChunker::__construct() | int $maxChunkChars = 1500, int $overlapChars = 150 | Valida i limiti di chunking alla costruzione | istanza | InvalidArgumentException su configurazione fuori intervallo | Limiti: 16 <= maxChunkChars <= 1048576; 0 <= overlapChars < maxChunkChars |
AstAwareChunker::chunk() | AstDocument $document | Percorso depth-first; le intestazioni delimitano i chunk; il testo foglia si accumula | list<AstChunk> | Nulla | Lista vuota per un documento senza testo accumulabile |
AstChunk | il costruttore promuove tutti i campi | Record di chunk ancorato alle citazioni | value object | Nulla | final readonly; vedi il blocco della firma più sotto |
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, ) {}}Contratto di comportamento
Sezione intitolata “Contratto di comportamento”Audit trail
Sezione intitolata “Audit trail”- Append-only. Le implementazioni devono essere append-only: una voce registrata non può essere modificata o rimossa tramite questa API. Chiamate
record()ripetute con lo stesso hash accumulano voci. - Conversione.
record()converte ogni voce delMutationLogdi Pro (tramiteMutationLog::all()) in unAstAuditEntrye la aggiunge in append. Tutte le voci prodotte da una singola chiamatarecord()condividono un unico timestamp UTCoccurredAt. - Isolamento per documento.
findByDocument()filtra sull’hash esatto della fonte del documento e preserva l’ordine di inserimento.count()è il totale su tutti i documenti. - Snapshot.
beforeeaftersono mappe di attributi con chiavetext_content. Una mutazioneupdatedriempie entrambi i lati;insertedlasciabeforevuoto;deletedlasciaaftervuoto.mutationTypeè il valore stringa dell’enumMutationTypedi Pro:updated,insertedodeleted. - Derivazione della pagina.
pageIndexè estratto dall’ID canonico del nodo (ast:{hash}:{page}:{seq}). Un ID di nodo malformato producepageIndex0; la voce viene comunque registrata.
L’append-only è un contratto dello store configurato, non una proprietà crittografica. La tamper-evidence e il non ripudio derivano da come la traccia è persistita e marcata temporalmente (modulo Evidence), non da questo modulo da solo.
Chunker
Sezione intitolata “Chunker”- Percorso.
chunk()percorre l’AST in profondità (depth-first) a partire dalla radice del documento. - Accumulo del testo. Il testo foglia di tipo Paragraph, ListItem, TableCell, Code o Annotation si accumula nel buffer corrente. I tipi contenitore (Document, Section, Artifact, FormField, Figure, Table, List, TableRow) vengono percorsi senza emettere testo.
- Delimitatori. Un nodo Heading svuota il buffer corrente come chunk e inizializza il buffer successivo con il testo dell’intestazione.
- Suddivisione. Quando il testo accumulato supererebbe
maxChunkChars, il chunker riempie lo spazio rimanente, svuota il chunk e prosegue con gli ultimioverlapCharscaratteri più l’eccedenza. Il conteggio della lunghezza è basato sui caratteri UTF-8. - Ancora di citazione. Ogni
AstChunkporta ilnodeId, ilpageIndex, ilbboxe ilnodeTypedel suo primo nodo contributore, più l’hash della fonte del documento e unchunkIndexsequenziale in base 0. - Finalizzazione. Un buffer finale con contenuto non costituito da soli spazi bianchi viene svuotato come chunk conclusivo; i residui composti solo da spazi bianchi vengono scartati e il testo del chunk viene ripulito (trim).
Casi limite e modalità di errore
Sezione intitolata “Casi limite e modalità di errore”- Registrare due volte lo stesso
MutationLogaccumula voci duplicate; l’idempotenza deve essere imposta a monte. - Un
InMemoryAstAuditTrailnuovo e non condiviso è sempre vuoto. Il contratto di integrazione richiede una singola istanzaAstAuditTrailInterfacecondivisa, consegnata sia al flusso che produce le mutazioni sia al consumatore che legge l’audit, conrecord()chiamato dopo ogni scrittura andata a buon fine. Fino ad allora,findByDocument()restituisce una lista vuota ecount()restituisce 0. - La traccia in memoria è per processo e non durevole; le voci non sopravvivono alla richiesta che le ha create. La produzione fornisce un’implementazione persistente.
- Un ID di nodo che non supera il parsing canonico non interrompe la registrazione; la voce interessata ricade su
pageIndex0. AstAwareChunker::__construct()rifiuta una configurazione degenere (overlapChars >= maxChunkChars, oppuremaxChunkCharsfuori da[16, 1048576]) conInvalidArgumentException. Questo previene una crescita illimitata del buffer durante il chunking.AstChunk::$bboxènullquando il primo nodo contributore non porta alcun bounding box.- Un documento privo di testo accumulabile produce una lista di chunk vuota.
- Questo modulo non esegue alcuna operazione crittografica. L’hashing, la firma e la marca temporale per la tamper-evidence sono gestiti dai moduli Evidence, Security e Signature; la politica della modalità FIPS risiede lì.
Conformità
Sezione intitolata “Conformità”| Comportamento | Riferimento |
|---|---|
| Contesto di aggiornamento incrementale / integrità della firma | ISO 32000-2:2020 §12.8 |
L’audit trail è un ausilio di tenuta dei record. Supporta i flussi di lavoro di evidenza in stile audit; non è una certificazione né un’attestazione legale, e NextPDF non detiene alcuna certificazione.
Note di sviluppo
Sezione intitolata “Note di sviluppo”- Fornire un’implementazione durevole di
AstAuditTrailInterfaceper la ritenzione tra le richieste. Persisterla in uno store con capacità WORM dove la conformità richiede l’immutabilità; la garanzia append-only è forte solo quanto lo store sottostante. - Gli snapshot delle mutazioni possono contenere dati personali; la residenza dei dati segue lo store dell’operatore.
- La traccia consuma il log delle mutazioni di Pro così come prodotto; non ri-deriva le mutazioni dallo stato del documento.
- I valori predefiniti del chunker (
maxChunkChars1500,overlapChars150) sono adatti all’ingestione RAG tipica; regolarli entro i limiti documentati per modelli di embedding con budget di contesto differenti. - I dettagli del meccanismo interno restano nella documentazione interna del repository sorgente e sono fuori dall’ambito di questo manuale.
Confine di pubblicazione
Sezione intitolata “Confine di pubblicazione”Questa pagina documenta esclusivamente il comportamento osservabile dall’esterno e la superficie API pubblica supportata. I percorsi di namespace interni, le classi helper, le tabelle dei meccanismi, i nomi di file dei runbook e i prefissi di ticket sono fuori ambito.