콘텐츠로 이동
getnextpdf.com

Pro 에디션안정성: 실험적

C2PA 프리뷰 능력 상태

프리뷰 능력 상태. 결코 GA가 아님. 이 페이지는 C2PA 표면이 프리뷰로서 오늘 무엇을 하는지를 진술합니다. 이는 적합성 주장도, 인증도, NextPDF가 C2PA로 서명된 파일을 생성한다는 진술도 아닙니다. 이 표면은 프리뷰이며 결코 일반 공급되는 것으로 설명되지 않습니다.

NextPDF Pro는 C2paCapabilityStatus를 통해 Content Credentials(C2PA) 프리뷰 표면을 노출합니다. 이 페이지는 그 표면의 정직한 경계입니다. 무엇이 항상 사용 가능한지, 무엇이 옵트인 초안 플래그 뒤에 머무는지, 그리고 왜 종단 상태 주장이 이루어지지 않는지를 다룹니다.

두 계층: 안정적 이음매 대 플래그된 합성

섹션 제목: “두 계층: 안정적 이음매 대 플래그된 합성”

표면에는 명확히 분리된 두 계층이 있으며, 그 구분이 경계의 핵심 전부입니다.

  • 항상 사용 가능 — 안정적 이음매. ManifestStoreC2paManifestEmbedder 인터페이스는 동결되고 벤더 중립적인 이음매입니다. 이들은 Manifest Store를 양 방향으로 운반할 수 있습니다. embed()는 호출자가 공급한 Store의 바이트를 PDF에 쓰고, extract()는 Store를 다시 파싱해 냅니다(존재하지 않으면 null을 반환). 이 이음매는 어떤 클레임 합성도 하지 않습니다 — 어셔션이나 클레임을 스스로 조립하지 않으며, 호출자가 이미 보유한 불투명 ManifestStore를 옮길 뿐입니다.
  • 옵트인 플래그 뒤 — 클레임 합성. Manifest Store를 실제로 구축하는 일 (클레임과 ingredient-hash 어셔션을 조립하는 것)은 오직 ExperimentalC2paEmbedder에만 있으며, 기본 꺼짐 env 플래그 뒤에 게이트되어 있습니다. 이것이 초안 형태이며 예고 없이 깨질 수 있는 부분입니다.

따라서 정확한 진술은 이렇습니다. 추출과 바이트 운반은 항상 도달 가능하고, 매니페스트 내용의 합성은 프리뷰 플래그가 명시적으로 활성화되었을 때만 도달 가능합니다.

핵심을 지탱하는 결정은, 한 임베더가 모든 것을 하는 것이 아니라 안정적 전송 이음매를 불안정한 합성 경로로부터 분리한 것입니다. C2PA-PDF 프로파일은 여전히 외부 워킹 그룹이 소유하고 있으며 동결되어 있지 않습니다. 그 Claim Signature 박스 (c2cs, COSE_Sign1 구조체)가 가장 드리프트하기 쉬운 부분입니다. 그래서 합성은 그 박스를 생략하고 기본 꺼짐 플래그 뒤에 두며, 추출-및-운반은 동결되지 않은 어떤 필드에도 의존하지 않고 모두에게 도달 가능한 상태로 남습니다. 상태 객체는 성숙도를 데이터로 노출하되 generallyAvailableconformanceClaimed를 false로 하드코딩하므로, 호출자는 생산자의 의도를 검증된 결과로 오해할 수 없습니다. 그 분리 덕분에 팀은 지금 내구성 있는 이음매를 채택하고 나중에 서명 어댑터를 추가할 수 있으며, NextPDF가 아직 지킬 수 없는 와이어 형식 약속을 하지 않아도 됩니다.

설계 배경: 감사인에게 건넬 수 있는 컴플라이언스.

C2paCapabilityStatus는 표면의 상태를 산문이 아니라 데이터로서 명시적으로 보고합니다. 그것의 generallyAvailableconformanceClaimed 속성은 하드코딩된 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, 빈 문자열, 또는 부재 포함)은 OFF로 취급됩니다. 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');

플래그가 꺼져 있을 때 fail-closed

섹션 제목: “플래그가 꺼져 있을 때 fail-closed”

조용한 폴백은 없습니다. NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT가 정확히 "1"이 아닌데 ExperimentalC2paEmbedder가 생성되면, 생성자는 플래그, env 변수, 고정된 초안 SHA/날짜를 이름 짓는 메시지를 담은 LogicException을 던집니다. 호출자는 단지 Pro 라이선스를 보유한다는 이유만으로 초안 형태의 바이트를 프로덕션 PDF에 실수로 직렬화할 수 없습니다.

안정적 추출 경로 역시 fail-closed이지만, 방식이 다릅니다. extract()는 Manifest Store가 존재하지 않으면 null을 반환하고(흔한 경우이며, 저렴하고 예외 없이 유지), Store가 존재하지만 파서의 적대적 강화 불변 조건(깊이, 순환, 크기, 개수)을 위반할 때 C2paException 하위 클래스 — JumbfBombException, JumbfCycleDetectedException, JumbfDepthExceededException, 또는 MalformedJumbfException — 를 던집니다. 이것들은 결코 조용히 삼켜지지 않습니다.

다음 언어는 정책상 이 표면에 대해 사용되지 않으며, 그것에서 파생된 어떤 문서, UI, 또는 마케팅에도 나타나서는 안 됩니다.

  • “C2PA conformant” 또는 “C2PA compliant”.
  • “C2PA certified”.
  • 완성되고 단언된 능력으로서의 “C2PA signed”.
  • “GA” / “generally available”.

표면이 정직하게 무엇인가 하면, C2PA Manifest Store를 파싱(추출)하고 운반(임베드)할 수 있는 안정적 이음매와, 초안 형태의 매니페스트 내용을 합성하는 기본 꺼짐 실험적 임베더, 그리고 자신의 프리뷰 상태를 보고하는 상태 객체입니다. 그것이 무엇이 아닌가 하면, 입증되고 검증 가능한 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()는 초안 매니페스트를 조립합니다. env 플래그가 정확히 "1"이 아니면 생성자가 LogicException을 던집니다.
Feature::PREVIEW_C2PA_DRAFT범위가 한정된 옵트인 플래그. ENV_PREVIEW_C2PA_DRAFT = NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT. isEnabled()는 엄격한 === '1'입니다.
  • 기본 꺼짐, 엄격한 옵트인. 합성은 NEXTPDF_FEATURE_PREVIEW_C2PA_DRAFT 뒤에 있으며, === '1'로 엄격하게 읽힙니다. 그 밖의 모든 것은 OFF입니다. Pro 라이선스 하나만으로는 그것이 활성화되지 않습니다.
  • 생성 시점 fail-closed. new ExperimentalC2paEmbedder()는 플래그가 꺼져 있을 때 LogicException을 던집니다 — 결코 조용한 no-op이 아닙니다.
  • 출력은 서명되지 않고 일시적입니다. 플래그가 켜져 있어도 Claim Signature 박스는 생략됩니다. 바이트를 초안 형태로 취급하고, 안정적 어댑터가 출하되면 다시 임베드하세요.
  • 고정 노후화 검사. 고정된 초안 스냅샷이 노후화될 때를 감지하려면 CI에서 composer c2pa:draft-status(exit 0 신선 / 1 소프트 경고 / 2 하드 실패)를 실행하세요.
  • 적합성 판정 없음. 상태 객체는 적합성 결과가 아니라 프리뷰 상태를 보고합니다. 외부 검증기와 동결된 워킹 그룹 프로파일이 어떤 적합성 논의의 전제 조건이 될 것이며, 둘 다 가정되지 않습니다.
  • 언어 규율. 출력을 “C2PA signed”, “conformant”, “compliant”, “certified”, 또는 “GA”로 설명하지 마세요. “프리뷰 능력 상태”를 사용하세요.

프리뷰 표면은 보안 통제가 아닙니다. 초안 Manifest Store를 운반하거나 합성하는 것은 입증을 생산하거나 검증하는 것과 같지 않습니다 — 그리고 실험적 임베더는 Claim Signature 박스를 전적으로 생략하므로, 그 출력은 구조상 서명되지 않습니다. 프로덕션 출처 보증을 위해 이 프리뷰에 의존하지 마세요. 그것은 자격 증명이 유효하다거나 파일이 서명되었다고 단언하지 않습니다.

이 표면은 어떤 적합성 주장도 하지 않습니다. C2PA 프로파일은 외부 워킹 그룹이 관리하며 동결되어 있지 않습니다. 따라서 NextPDF는 적합성이나 인증이 아니라 프리뷰 능력 상태와 초안/워킹 그룹 경계를 진술합니다. 표준 텍스트는 재현되지 않습니다.

이 페이지는 외부에서 관찰 가능한 동작과 지원되는 공개 API 표면만을 문서화합니다. 내부 네임스페이스 경로, 헬퍼 클래스, 메커니즘 표, 런북 파일명, 티켓 접두사는 범위 밖입니다.