Pular para o conteúdo
getnextpdf.com

Enterprise edição

Evidence — Referência Profunda

Esta página é a referência aprofundada do módulo NextPDF\Enterprise\Evidence. O módulo sela achados de validação em um EvidencePackage imutável, exporta-o como JSON determinístico com um resumo SHA-256 estável, persiste-o por meio de um contrato de armazenamento plugável e rastreia regressões entre execuções com o ContinuousMonitor. O módulo consome achados produzidos pelas superfícies Validation e Compliance; ele próprio não realiza nenhuma verificação de conformidade. Para orientação de fluxo de trabalho, leia primeiro a página de capacidade Evidence.

Esta capacidade é distribuída no NextPDF Enterprise (nextpdf/enterprise) e é ativada com um envelope de licença de nível Enterprise. Uma implantação sem esse direito de uso não carrega as classes da capacidade. Compare edições e obtenha uma licença.

A superfície é licenciada pela capacidade enterprise.compliance.evidence; um direito de uso negado nega o recurso. O Core e o Pro produzem achados e relatórios; selar achados em um pacote imutável, determinístico e opcionalmente carimbado no tempo, com rastreamento de regressão, não tem equivalente no nível Core nem no nível Pro.

Terminal window
composer require nextpdf/enterprise:^3
SímboloParâmetrosComportamento padrãoRetornaLança ou falha comNotas
EvidencePortal::__constructEvidenceStoreInterface $store, EvidenceExporter $exporterConecta o store e o exporterEvidencePortalNada declaradoAmbos os colaboradores são injetáveis
EvidencePortal::generateEvidencestring $documentHash, list<EvidenceRecord> $records, ?string $tsaTimestamp = nullConta aprovações/reprovações, sela um pacote com um novo id UUID e generatedAt do relógio, e o persisteEvidencePackageNada declaradoPersiste por meio de store(), não de persistImmutable()
EvidencePortal::getEvidencestring $documentHashPacote armazenado mais recente para o hash?EvidencePackageNada declaradonull quando nenhum armazenado
EvidencePortal::getHistorystring $documentHashHistórico completo, do mais recente ao mais antigolist<EvidencePackage>Nada declaradoA ordenação é fornecida pelo store
EvidencePortal::exportAsJsonEvidencePackage $packageDelega ao exporternon-empty-stringJsonExceptionMesmos bytes que EvidenceExporter::toJson
EvidencePackage::__constructoito parâmetros nomeados, veja o blocoObjeto de valor imutávelEvidencePackageNada declaradoAs contagens não são validadas contra $records
EvidencePackage::allPassednenhumfailedCount === 0boolNada declaradotrue para um pacote vazio; use totalFindings como gate
EvidencePackage::passRatenenhumpassedCount / totalFindingsfloatNada declarado0.0 quando totalFindings === 0
EvidenceRecord::__constructstring $policyName, bool $passed, string $details, string $validatorVersion, DateTimeImmutable $timestampResultado imutável de uma única verificação de políticaEvidenceRecordNada declaradoTodas as propriedades são public readonly
EvidenceExporter::toJsonEvidencePackage $packageJSON com ordem de chaves fixa; barras e Unicode sem escapenon-empty-stringJsonExceptionA ordem das chaves é determinante
EvidenceExporter::exportHashEvidencePackage $packageSHA-256 sobre os bytes de toJson()non-empty-string (64 hex)JsonExceptionEstável por pacote
EvidenceStoreInterface::storeEvidencePackage $packageAnexa; o histórico por hash de documento é permitidovoidDefinido pela implementaçãoSemântica somente-anexação exigida
EvidenceStoreInterface::persistImmutableEvidencePackage $packageEscrita WORM onde o backend a suportavoidDefinido pela implementaçãoBackends não-WORM se comportam como store()
EvidenceStoreInterface::findByDocumentHashstring $documentHashPacote mais recente para o hash?EvidencePackageDefinido pela implementação
EvidenceStoreInterface::findAllByDocumentHashstring $documentHashTodos os pacotes para o hash, do mais recente ao mais antigolist<EvidencePackage>Definido pela implementação
EvidenceStoreInterface::countnenhumNúmero total de pacotes armazenadosint<0, max>Definido pela implementação
InMemoryEvidenceStoreclasseStore baseado em array para testes e desenvolvimenton/dn/dNão durável; sem semântica WORM
ContinuousMonitor::__constructEvidenceStoreInterface $storeConecta o storeContinuousMonitorNada declarado
ContinuousMonitor::checkEvidencePackage $currentEvidence, string $documentHashCompara nomes de políticas reprovadas com o pacote armazenado mais recenteMonitorResultNada declaradoA primeira verificação trata toda reprovação atual como nova
ContinuousMonitor::isDuestring $documentHash, MonitorSchedule $scheduleDevido quando não há evidência anterior, o intervalo decorreu, ou a evidência armazenada tem data futuraboolNada declaradoÀ prova de falhas em desvio de relógio
MonitorResult::__constructoito parâmetros nomeados, veja o blocoResultado de diff imutávelMonitorResultNada declaradoInclui ambos os pacotes e checkedAt
MonitorSchedule::__constructMonitorFrequency $frequency, int $retentionDays = 90, bool $alertOnNewIssues = trueObjeto de valor de configuraçãoMonitorScheduleNada declaradoRetenção e alertas são impostos pelo host
MonitorFrequencyenum com backing stringCasos Daily, Weekly, Monthlyn/dn/dValores de backing daily, weekly, monthly
MonitorFrequency::intervalSecondsnenhumIntervalo por caso: 86400, 604800, 2592000positive-intNada declaradoMonthly é um período fixo de 30 dias
final class EvidencePortal
{
public function __construct(
private readonly EvidenceStoreInterface $store,
private readonly EvidenceExporter $exporter,
)
public function generateEvidence(string $documentHash, array $records, ?string $tsaTimestamp = null): EvidencePackage
public function getEvidence(string $documentHash): ?EvidencePackage
public function getHistory(string $documentHash): array
public function exportAsJson(EvidencePackage $package): string
}
final readonly class EvidencePackage
{
public function __construct(
public string $packageId,
public string $documentHash,
public array $records,
public int $totalFindings,
public int $passedCount,
public int $failedCount,
public DateTimeImmutable $generatedAt,
public ?string $tsaTimestamp = null,
)
public function allPassed(): bool
public function passRate(): float
}
final readonly class EvidenceRecord
{
public function __construct(
public string $policyName,
public bool $passed,
public string $details,
public string $validatorVersion,
public DateTimeImmutable $timestamp,
)
}
final readonly class EvidenceExporter
{
public function toJson(EvidencePackage $package): string
public function exportHash(EvidencePackage $package): string
}
interface EvidenceStoreInterface
{
public function store(EvidencePackage $package): void;
public function persistImmutable(EvidencePackage $package): void;
public function findByDocumentHash(string $documentHash): ?EvidencePackage;
public function findAllByDocumentHash(string $documentHash): array;
public function count(): int;
}
final class ContinuousMonitor
{
public function __construct(
private readonly EvidenceStoreInterface $store,
)
public function check(EvidencePackage $currentEvidence, string $documentHash): MonitorResult
public function isDue(string $documentHash, MonitorSchedule $schedule): bool
}
final readonly class MonitorSchedule
{
public function __construct(
public MonitorFrequency $frequency,
public int $retentionDays = 90,
public bool $alertOnNewIssues = true,
)
}
enum MonitorFrequency: string
{
case Daily = 'daily';
case Weekly = 'weekly';
case Monthly = 'monthly';
public function intervalSeconds(): int
}

EvidencePortal::generateEvidence(string $documentHash, list<EvidenceRecord> $records, ?string $tsaTimestamp = null): EvidencePackage é o ponto de entrada de selagem. Regras observáveis externamente:

  1. Montagem. generateEvidence conta os registros aprovados e reprovados e define totalFindings como a soma deles. Atribui um packageId UUID versão 4 novo, estampa generatedAt com o relógio de parede, persiste o pacote por meio de EvidenceStoreInterface::store e o retorna. A lista de registros é embutida na ordem fornecida, sem modificação.
  2. Imutabilidade. EvidencePackage é final readonly e nunca sofre mutação após a construção; é adequado para armazenamento WORM. allPassed() é failedCount === 0. passRate() é passedCount / totalFindings, e 0.0 quando totalFindings === 0.
  3. Exportação determinística. EvidenceExporter::toJson emite o envelope e cada registro com uma ordem de chaves fixa e escrita à mão; a sequência de registros segue o pacote. A codificação é estrita e lança em caso de falha, com barras e Unicode deixados sem escape (JSON_UNESCAPED_SLASHES). Os carimbos de tempo são serializados com DateTimeInterface::RFC3339_EXTENDED, a forma estendida RFC 3339 com frações de segundo. exportHash retorna o resumo SHA-256 em hex de 64 caracteres exatamente sobre esses bytes. O mesmo pacote sempre produz o mesmo resumo, em qualquer host, a qualquer momento. Regenerar a evidência para o mesmo documento produz um novo packageId e generatedAt, portanto um novo resumo: o determinismo é por pacote, não por documento.
  4. O carimbo de tempo é evidência de tempo, não um veredito. Um pacote pode carregar um token RFC 3161 opcional fornecido pelo chamador (codificado em base64). O token vincula o dado do pacote a um valor de tempo. O módulo o incorpora como uma string opaca; ele não busca, não analisa nem verifica tokens, e não responde pela TSA. A verificação do token pertence aos módulos Signature e Security.
  5. Rastreamento de regressão. ContinuousMonitor::check carrega o pacote armazenado mais recente para o hash de documento e compara nomes únicos de políticas reprovadas. Os problemas são categorizados como newIssues (reprovado agora, não antes), resolvedIssues (reprovado antes, não agora) e unchangedIssues (reprovado em ambos). hasChanges é true apenas quando existem problemas novos ou resolvidos; reprovações inalteradas sozinhas reportam false. Em uma primeira verificação, toda reprovação atual é nova.
  6. Agendamento. ContinuousMonitor::isDue retorna true quando não há evidência para o hash, quando o tempo decorrido desde o generatedAt armazenado atinge o intervalo de frequência do agendamento, ou quando a evidência armazenada tem data futura em relação ao host de polling. O caso de data futura é à prova de falhas: no pior caso uma reverificação extra, nunca uma perdida.
  7. Contrato do store. As implementações de EvidenceStoreInterface devem suportar semântica somente-anexação; múltiplos pacotes por hash de documento formam o histórico, do mais recente ao mais antigo. persistImmutable visa backends com capacidade WORM; implementações não-WORM devem se comportar exatamente como store.
  • Um pacote vazio reporta allPassed() true e passRate() 0.0. Use totalFindings > 0 como gate antes de tratar um pacote como uma aprovação.
  • A construção direta de EvidencePackage não valida as contagens contra $records. Use o portal, ou mantenha as contagens consistentes você mesmo.
  • generateEvidence persiste antes de retornar. Execute ContinuousMonitor::check com o novo pacote antes de persistí-lo; uma verificação após a persistência compara o pacote consigo mesmo e reporta nenhuma alteração.
  • exportHash cobre exatamente os bytes de toJson. Um resumo recomputado por qualquer outro serializador, ordem de chaves ou política de escape não corresponderá.
  • MonitorFrequency::Monthly é uma janela fixa de 30 dias, não um mês de calendário.
  • MonitorSchedule::$retentionDays e $alertOnNewIssues são configuração carregada para agendadores do host. O módulo nunca exclui evidências e nunca envia alertas.
  • InMemoryEvidenceStore é para testes e desenvolvimento. Os pacotes são perdidos ao encerrar o processo, e seu persistImmutable não tem semântica WORM.
  • As strings details dos registros são exportadas literalmente; o exporter não redige. Mantenha segredos e dados pessoais regulamentados fora de details. Residência, retenção e controle de acesso seguem a implementação de store do operador.
  • O argumento tsaTimestamp é aceito como uma string opaca. Um token malformado é embutido sem alteração e só se manifesta na verificação a jusante.

Este módulo computa resumos SHA-256 e incorpora um token RFC 3161 fornecido pelo chamador. Ele não realiza nenhuma assinatura nem custódia de chaves. O comportamento em modo FIPS é regido pelos módulos Security e Signature.

AfirmaçãoPadrãoCláusula
Um token de carimbo de tempo indica que um dado existia em um determinado ponto no tempo.IETF RFC 3161§2
Os carimbos de tempo exportados usam o perfil de data/hora da Internet do ISO 8601, com frações de segundo.IETF RFC 3339§5.6
O material de validação embutido dentro de um PDF pertence ao Document Security Store; essa superfície é do módulo Signature, não deste.ISO 32000-2:2020§12.8.4

Todas as cláusulas são parafraseadas; o NextPDF não reproduz texto normativo. O NextPDF não faz nenhuma alegação de certificação. A captura de evidências dá suporte a fluxos de trabalho de auditoria; não é um atestado legal nem uma certificação de auditoria. Um token de carimbo de tempo é evidência apenas de tempo, e este módulo não afirma que qualquer conteúdo está em conformidade. Validade e conformidade permanecem propriedades do arquivo final mais um validador. Esta referência não é um parecer jurídico; consulte seus próprios assessores de conformidade e jurídicos.

  • O código-fonte do módulo carrega @since 2.2.0; esta referência documenta a superfície conforme distribuída em nextpdf/enterprise 3.1.0.
  • Tudo é executado em processo no seu host. O módulo não realiza nenhuma E/S de rede e nunca contata uma TSA por conta própria.
  • A ordem de chaves do literal de array do exporter é determinante por design. Reordená-la mudaria exportHash e invalidaria resumos previamente armazenados; o código-fonte a proíbe.
  • packageId é um UUID versão 4 montado a partir da saída de \random_bytes(16); os identificadores são únicos, mas não reproduzíveis.
  • A persistência durável é fornecida pelo host. A imposição WORM e o controle de acesso são de responsabilidade do operador; o store em memória é a única implementação incluída.
  • MonitorResult é um objeto de valor final readonly; suas oito propriedades são public, incluindo checkedAt, o horário de relógio de parede da verificação.

Esta página documenta apenas o comportamento observável externamente e a superfície da API pública suportada. Caminhos de namespace internos, classes auxiliares, tabelas de mecanismos, nomes de arquivo de runbook e prefixos de tíquete estão fora do escopo.