Enterprise редакция
Журнал аудита AST — глубокий справочник
Модуль Enterprise AST записывает мутации документа и подготавливает документы для конвейеров извлечения.
AstAuditTrailInterfaceопределяет журнал аудита по документам, работающий только на добавление, поверхMutationLogиз Pro AST.AstAuditEntry— это неизменяемая запись одной мутации: идентичность узла, вид мутации, страница, снимки до/после, метка времени UTC.InMemoryAstAuditTrail— это эталонная реализация контракта журнала в пределах процесса.AstAwareChunkerобходит AST в глубину и выдаёт значенияAstChunkс привязкой к цитированию для приёма в RAG.
Доступность и лицензирование
Заголовок раздела «Доступность и лицензирование»Эта возможность поставляется в NextPDF Enterprise (nextpdf/enterprise) и активируется лицензионным конвертом уровня Enterprise. Развёртывание без этого права не загружает классы возможности. Сравните редакции и получите лицензию.
Поверхность журнала аудита AST лицензируется возможностью enterprise.compliance.evidence. Отказ в праве отказывает в функции.
| Уровень | Предоставляет |
|---|---|
| Core | Модель документа AST (AstDocument, AstNode, NodeId) |
| Pro | Поток мутаций AST и MutationLog |
| Enterprise | Журнал аудита по документам только на добавление; разбиватель с привязкой к цитированию |
Поверхность Enterprise потребляет журнал мутаций Pro. Она не заменяет модель AST.
composer require nextpdf/enterprise:^3Публичная поверхность API
Заголовок раздела «Публичная поверхность API»| Символ | Параметры | Поведение по умолчанию | Возвращает | Бросает или завершается ошибкой | Примечания |
|---|---|---|---|---|---|
AstAuditTrailInterface::record() | string $documentSourceHash, MutationLog $log | Преобразует каждую запись мутации в журнале в AstAuditEntry и добавляет её | void | Ничего в эталонной реализации | Повторные вызовы с тем же хешем накапливают записи |
AstAuditTrailInterface::findByDocument() | string $documentSourceHash | Возвращает записи, сохранённые для одного документа, в порядке вставки | list<AstAuditEntry> | Ничего в эталонной реализации | Пустой список, когда ни одна запись не соответствует хешу |
AstAuditTrailInterface::count() | нет | Считает записи аудита | int<0, max> | Ничего в эталонной реализации | Общее число по всем документам, не по документу |
InMemoryAstAuditTrail | нет | Журнал на массивах, ограниченный текущим процессом | реализует AstAuditTrailInterface | Ничего | Не долговечен; подходит для жизненного цикла одного запроса |
AstAuditEntry | конструктор продвигает все поля | Неизменяемая запись аудита | объект-значение | Ничего | final readonly; см. блок сигнатуры ниже |
AstAwareChunker::__construct() | int $maxChunkChars = 1500, int $overlapChars = 150 | Проверяет границы разбиения при конструировании | экземпляр | InvalidArgumentException при конфигурации вне диапазона | Границы: 16 <= maxChunkChars <= 1048576; 0 <= overlapChars < maxChunkChars |
AstAwareChunker::chunk() | AstDocument $document | Обход в глубину; заголовки разделяют части; листовой текст накапливается | list<AstChunk> | Ничего | Пустой список для документа без накапливаемого текста |
AstChunk | конструктор продвигает все поля | Запись части с привязкой к цитированию | объект-значение | Ничего | final readonly; см. блок сигнатуры ниже |
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, ) {}}Контракт поведения
Заголовок раздела «Контракт поведения»Журнал аудита
Заголовок раздела «Журнал аудита»- Только на добавление. Реализации должны работать только на добавление: записанную запись нельзя изменить или удалить через этот API. Повторные вызовы
record()с тем же хешем накапливают записи. - Преобразование.
record()преобразует каждую запись журнала мутаций ProMutationLog(черезMutationLog::all()) вAstAuditEntryи добавляет её. Все записи, произведённые одним вызовомrecord(), разделяют одну метку времени UTCoccurredAt. - Изоляция по документам.
findByDocument()фильтрует по точному хешу источника документа и сохраняет порядок вставки.count()— это общее число по всем документам. - Снимки.
beforeиafter— это карты атрибутов с ключомtext_content. Мутацияupdatedзаполняет обе стороны;insertedоставляетbeforeпустым;deletedоставляетafterпустым.mutationType— это строковое значение перечисления ProMutationType:updated,insertedилиdeleted. - Вывод страницы.
pageIndexизвлекается из канонического идентификатора узла (ast:{hash}:{page}:{seq}). Некорректный идентификатор узла даётpageIndex0; запись всё равно сохраняется.
Только на добавление — это контракт настроенного хранилища, а не криптографическое свойство. Защита от подделки и неотказуемость происходят от того, как журнал сохраняется и проставляется метками времени (модуль Evidence), а не только от этого модуля.
Разбиватель
Заголовок раздела «Разбиватель»- Обход.
chunk()обходит AST в глубину от корня документа. - Накопление текста. Листовой текст типа Paragraph, ListItem, TableCell, Code или Annotation накапливается в текущий буфер. Контейнерные типы (Document, Section, Artifact, FormField, Figure, Table, List, TableRow) обходятся без выдачи текста.
- Разделители. Узел Heading сбрасывает текущий буфер как часть и засевает следующий буфер текстом заголовка.
- Разбиение. Когда накопленный текст превысил бы
maxChunkChars, разбиватель заполняет оставшееся пространство, сбрасывает часть и продолжает с последнихoverlapCharsсимволов плюс переполнение. Учёт длины ведётся по символам UTF-8. - Якорь цитирования. Каждый
AstChunkнесётnodeId,pageIndex,bboxиnodeTypeсвоего первого вносящего вклад узла, а также хеш источника документа и последовательныйchunkIndex, отсчитываемый от 0. - Финализация. Завершающий буфер с непробельным содержимым сбрасывается как последняя часть; остатки только из пробелов отбрасываются, а текст части обрезается.
Граничные случаи и режимы отказа
Заголовок раздела «Граничные случаи и режимы отказа»- Запись одного и того же
MutationLogдважды накапливает дублирующиеся записи; идемпотентность должна обеспечиваться на предыдущем шаге. - Свежий, не разделяемый
InMemoryAstAuditTrailвсегда пуст. Контракт интеграции требует одного общего экземпляраAstAuditTrailInterface, переданного как в поток, производящий мутации, так и в потребителя, читающего аудит, с вызовомrecord()после каждой успешной записи. До этогоfindByDocument()возвращает пустой список, аcount()возвращает 0. - Внутрипамятный журнал существует в пределах процесса и не долговечен; записи не переживают запрос, который их создал. Продакшен предоставляет устойчивую реализацию.
- Идентификатор узла, не прошедший канонический разбор, не прерывает запись; затронутая запись откатывается к
pageIndex0. AstAwareChunker::__construct()отклоняет вырожденную конфигурацию (overlapChars >= maxChunkCharsилиmaxChunkCharsвне[16, 1048576]) сInvalidArgumentException. Это предотвращает неограниченный рост буфера во время разбиения.AstChunk::$bboxравенnull, когда первый вносящий вклад узел не несёт ограничивающего прямоугольника.- Документ без накапливаемого текста даёт пустой список частей.
- Этот модуль не выполняет криптографических операций. Хеширование, подписание и проставление меток времени для защиты от подделки обрабатываются модулями Evidence, Security и Signature; политика режима FIPS живёт там.
Соответствие
Заголовок раздела «Соответствие»| Поведение | Ссылка |
|---|---|
| Контекст инкрементного обновления / целостности подписи | ISO 32000-2:2020 §12.8 |
Журнал аудита — это вспомогательное средство ведения записей. Он поддерживает рабочие процессы доказательств аудиторского типа; он не является сертификацией и не является юридической аттестацией, и NextPDF не имеет сертификации.
Замечания по разработке
Заголовок раздела «Замечания по разработке»- Предоставьте долговечную реализацию
AstAuditTrailInterfaceдля сохранения между запросами. Сохраняйте её в хранилище с поддержкой WORM, где соответствие требует неизменяемости; гарантия только на добавление сильна ровно настолько, насколько сильно резервное хранилище. - Снимки мутаций могут нести персональные данные; размещение данных следует хранилищу оператора.
- Журнал потребляет журнал мутаций Pro в том виде, в каком он произведён; он не выводит мутации заново из состояния документа.
- Значения по умолчанию разбивателя (
maxChunkChars1500,overlapChars150) подходят для типичного приёма в RAG; настраивайте в пределах задокументированных границ для моделей встраивания с другими бюджетами контекста. - Детали внутреннего механизма остаются во внутренней документации репозитория исходного кода и находятся вне области охвата этого руководства.
Граница публикации
Заголовок раздела «Граница публикации»Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы заявок находятся вне области охвата.