Перейти к содержимому
getnextpdf.com

Pro редакциястабильность: Экспериментальная

Статус превью-возможности C2PA

Статус превью-возможности. Никогда не GA. Эта страница описывает, что поверхность C2PA делает сегодня как превью. Это не заявление о соответствии, не сертификация и не утверждение, что NextPDF производит файлы, подписанные C2PA. Поверхность — это превью, и она никогда не описывается как общедоступная.

NextPDF Pro предоставляет превью-поверхность Content Credentials (C2PA) через C2paCapabilityStatus. Эта страница — честная граница для этой поверхности: что всегда доступно, что остаётся за подключаемым черновым флагом и почему не делается заявление о конечном состоянии.

Два слоя: стабильный шов против синтеза за флагом

Заголовок раздела «Два слоя: стабильный шов против синтеза за флагом»

У поверхности есть два чётко разделённых слоя, и это различие — весь смысл границы:

  • Всегда доступно — стабильный шов. ManifestStore и интерфейс C2paManifestEmbedder — это замороженный, нейтральный к поставщику шов. Они могут переносить Manifest Store в обе стороны: embed() записывает байты предоставленного вызывающим Store в PDF, а extract() разбирает Store обратно (возвращая null, когда его нет). Этот шов не делает синтеза заявлений — он никогда сам не собирает утверждения или заявления; он перемещает непрозрачный ManifestStore, который вызывающий уже держит.
  • За подключаемым флагом — синтез заявлений. Собственно построение Manifest Store (сборка заявления и утверждения о хеше ингредиента) живёт только в ExperimentalC2paEmbedder, за выключенным по умолчанию env-флагом. Это черновая часть, которая ломается без предупреждения.

Поэтому точная формулировка такова: извлечение и перенос байтов всегда достижимы; синтез содержимого манифеста достижим только тогда, когда превью-флаг явно включён.

Несущее решение разделяет стабильный транспортный шов и изменчивый путь синтеза, а не сводит всё к одному встраивателю, делающему всё. Профиль C2PA-PDF всё ещё принадлежит внешней рабочей группе и не заморожен. Его блок Claim Signature (c2cs, структура COSE_Sign1) — та часть, которая с наибольшей вероятностью будет дрейфовать. Поэтому синтез опускает этот блок и живёт за выключенным по умолчанию флагом, тогда как извлечение-и-перенос не зависит ни от какого незамороженного поля и остаётся доступным всем. Объект статуса выставляет зрелость как данные, с жёстко закодированными false для generallyAvailable и conformanceClaimed, так что вызывающие не могут спутать намерение производителя с проверенным результатом. Это разделение позволяет командам принять надёжный шов сейчас и добавить подписанный адаптер позже, без обещания формата передачи, которое NextPDF пока не может сдержать.

Проектный фон: Соответствие, которое можно передать аудитору.

C2paCapabilityStatus сообщает статус поверхности явно как данные, а не как прозу. Его свойства generallyAvailable и conformanceClaimed жёстко закодированы как false и остаются false независимо от флага; включение превью переключает только previewEnabled. Токен maturity — это незаявляющая метка preview-draft, а specPin записывает закреплённый черновой коммит. Вызывающий читает «preview», а не «подписано и проверено».

use NextPDF\Pro\Compliance\C2pa\C2paCapabilityStatus;
// Reads the env flag live; performs no I/O.
$status = C2paCapabilityStatus::current();
$status->previewEnabled; // bool — true only if the opt-in env flag is set
$status->generallyAvailable; // false (always)
$status->conformanceClaimed; // false (always)
$status->maturity; // 'preview-draft'
$status->specPin; // '4e2afed8' (pinned draft commit, short)
$status->envGate; // 'NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT'
echo $status->summary();
// "C2PA preview-draft surface is present but switched off;
// the C2PA-PDF profile is not yet final."

Спецификация C2PA сопровождается внешней рабочей группой, и профиль, на который NextPDF нацеливался бы, не заморожен. Поскольку профиль не заморожен, превью намеренно не делает заявления о конечном состоянии. Когда профиль рабочей группы стабилизируется, изменится статус поверхности — а не её маркетинг.

Подключение — это единственная переменная окружения процесса, NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT. Она читается вживую и сравнивается строго со строкой "1" — любое другое значение (включая 0, true, yes, пустую строку или отсутствие) трактуется как ВЫКЛ. Одна лишь лицензия Pro не включает её; оператор должен осознанно подключить её.

// Opt in for the current process BEFORE constructing the embedder.
putenv('NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT=1');
use NextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedder;
$embedder = new ExperimentalC2paEmbedder();
// Synthesise a draft-shaped Manifest Store binding the host PDF by SHA-256.
$pdfBytes = file_get_contents('input.pdf');
$store = $embedder->buildManifestStore($pdfBytes, 'my-app/1.0.0');
// The result is an opaque ManifestStore; $store->toBytes() is its serialisation.

В реальном развёртывании устанавливайте флаг при загрузке (не через putenv() во время выполнения), привязывайте его к явному человеческому подключению и проверяйте статус возможности, прежде чем касаться экспериментального встраивателя, чтобы черновой путь достигался только намеренно.

use NextPDF\Pro\Compliance\C2pa\C2paCapabilityStatus;
use NextPDF\Pro\Compliance\C2pa\Experimental\ExperimentalC2paEmbedder;
// Set NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT=1 in the environment at process boot.
$status = C2paCapabilityStatus::current();
if (!$status->previewEnabled) {
// Flag off: do NOT instantiate the experimental embedder — its
// constructor would throw. Fall back to your non-preview path.
return;
}
// Surface the draft pin to the operator. The bytes are transient:
// re-embed once a stable adapter ships. Run `composer c2pa:draft-status`
// in CI to fail the build if the pinned snapshot goes stale.
$pinnedDraft = ExperimentalC2paEmbedder::SPEC_PIN_SHA; // 4e2afed8…
$pinnedDate = ExperimentalC2paEmbedder::SPEC_PIN_DATE; // 2026-04-26
$embedder = new ExperimentalC2paEmbedder();
$store = $embedder->buildManifestStore($pdfBytes, 'my-app/1.0.0');

Молчаливого запасного варианта нет. Если ExperimentalC2paEmbedder конструируется, когда NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT не равен в точности "1", конструктор выбрасывает LogicException, чьё сообщение называет флаг, переменную окружения и закреплённый SHA/дату черновика. Вызывающий не может случайно сериализовать черновые байты в продакшен-PDF, просто держа лицензию Pro.

Стабильный путь извлечения тоже отказывает закрытием, но иначе: extract() возвращает null, когда Manifest Store отсутствует (обычный случай, оставленный дешёвым и без исключений), и выбрасывает подкласс C2paExceptionJumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException или MalformedJumbfException — когда Store присутствует, но нарушает инварианты противодействия атакам парсера (глубина, цикл, размер, количество). Они никогда не проглатываются молча.

Следующие формулировки не используются для этой поверхности, по политике, и не должны появляться ни в какой документации, интерфейсе или маркетинге, производных от неё:

  • «C2PA conformant» или «C2PA compliant».
  • «C2PA certified».
  • «C2PA signed» как завершённая, утверждённая возможность.
  • «GA» / «generally available».

Чем поверхность честно является: стабильный шов, способный разбирать (extract) и переносить (embed) Manifest Store C2PA, плюс выключенный по умолчанию экспериментальный встраиватель, который синтезирует черновое содержимое манифеста, и объект статуса, сообщающий своё собственное превью-состояние. Чем она не является: производителем заверенных, проверяемых учётных данных C2PA. Примечательно, что экспериментальный встраиватель намеренно опускает блок Claim Signature (c2cs) — часть COSE_Sign1 спецификации, наиболее склонную к дрейфу, — поэтому даже с включённым флагом вывод — это неподписанные черновые байты. Профиль рабочей группы не заморожен; граница в этом и есть суть.

Формат, который выдаёт экспериментальный встраиватель, закреплён к черновому коммиту c2pa-org/specifications (SPEC_PIN_SHA = 4e2afed8…, датирован 2026-04-26), выставленному как публичная константа, чтобы вызывающие могли закрепить ожидаемый SHA.

СимволРоль
C2paCapabilityStatusЧестный, машиночитаемый объект-значение статуса. current() читает env-флаг вживую; generallyAvailable / conformanceClaimed всегда false; summary() не несёт заявления о GA/соответствии.
ManifestStoreНеизменяемый объект-значение Manifest Store. Тип стабильного шва; переносит байты в обе стороны. Без аксессоров уровня заявлений. Всегда доступен.
C2paManifestEmbedderЗамороженный, нейтральный к поставщику SPI: embed() / extract(). Без синтеза заявлений. extract() возвращает null при промахе. Всегда доступен.
ExperimentalC2paEmbedderВыключенный по умолчанию синтез. buildManifestStore() собирает черновой манифест; конструктор выбрасывает LogicException, если env-флаг не равен в точности "1".
Feature::PREVIEW_C2PA_DRAFTОграниченный по области подключаемый флаг. ENV_PREVIEW_C2PA_DRAFT = NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT; isEnabled() строго === '1'.
  • Выключено по умолчанию, строгое подключение. Синтез за NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT, читаемым строго как === '1'. Всё прочее — ВЫКЛ; одна лишь лицензия Pro его не включает.
  • Отказ закрытием на этапе конструирования. new ExperimentalC2paEmbedder() выбрасывает LogicException, когда флаг выключен, — никогда молчаливый no-op.
  • Вывод неподписан и временен. Даже с включённым флагом блок Claim Signature опущен; считайте байты черновыми и встраивайте заново, когда выйдет стабильный адаптер.
  • Проверка устаревания закрепления. Выполняйте composer c2pa:draft-status (код выхода 0 свежо / 1 мягкое предупреждение / 2 жёсткий отказ) в CI, чтобы обнаружить, когда закреплённый черновой снимок устаревает.
  • Нет вердикта о соответствии. Объект статуса сообщает превью-состояние, а не результат соответствия. Внешний валидатор и замороженный профиль рабочей группы были бы предпосылками для любого разговора о соответствии, и ни одна не предполагается.
  • Дисциплина формулировок. Не описывайте вывод как «C2PA signed», «conformant», «compliant», «certified» или «GA». Используйте «статус превью-возможности».

Превью-поверхность — это не средство контроля безопасности. Перенос или синтез чернового Manifest Store — это не то же самое, что производство или проверка аттестации, и экспериментальный встраиватель полностью опускает блок Claim Signature, поэтому его вывод неподписан по построению. Не полагайтесь на это превью для гарантии происхождения в продакшене; оно не утверждает, что учётные данные действительны или что файл подписан.

Эта поверхность не делает заявления о соответствии. Профиль C2PA сопровождается внешней рабочей группой и не заморожен; поэтому NextPDF заявляет статус превью-возможности и черновую границу/границу рабочей группы, а не соответствие или сертификацию. Текст стандартов не воспроизводится.

Эта страница документирует только внешне наблюдаемое поведение и поддерживаемую публичную поверхность API. Внутренние пути пространств имён, вспомогательные классы, таблицы механизмов, имена файлов runbook и префиксы тикетов — вне области.