앞의 일곱 장은 WIA 적합 대기 CO2 직접 포집(DAC) 시스템이 무엇을 기록하는지, 그 기록을 어떻게 노출하는지, 어떤 운영·MRV 이벤트를 발생시키는지, 그리고 저장소·전력망·등록부·기업 시스템과 어떻게 연결되는지를 설명했다. 마지막 장은 다른 질문을 던진다. 구현체는 이 모든 것을 한다는 사실을 어떻게 보여 주는가, 그리고 공급사를 신뢰하지 않는 사람은 그 주장을 어떻게 확인하는가?
표준은 모든 PHASE 문서에 공통으로 들어 있는 작은 적합성 도구 묶음으로 답한다. 세 가지 적합성 등급, 서명 매니페스트, 요구사항별로 지원 여부를 밝히는 프로파일 매니페스트, 그리고 테스트 벡터와 소프트웨어 자재명세서(SBOM)를 중심으로 한 증거 패키지다. 이 도구들은 여섯 개 명세 파일에 Annex E~I라는 이름으로 거의 글자 그대로 반복되어 있다. 이 장은 이를 한 번만 인용하고, 각 도구가 무엇을 증명하며 무엇을 증명하지 못하는지 설명하며, 배포된 도구가 어디에서 멈추고 구현자가 어떤 빈틈을 메워야 하는지 보여 준다.
이 장 전체를 관통하는 구분이 하나 있다. 데이터 표준에 대한 적합성은 소프트웨어와 기록에 관한 진술이다. 즉 시스템이 형식에 맞고 추적 가능하며 서명된 데이터를 만든다는 뜻이다. 어느 시설이 몇 톤을 제거했다는 진술이 아니다. 그 두 번째 주장은 MRV 절차와 등록부의 몫이다(제6장). 잘 설계된 적합성 제도는 둘을 분리하며, 잘 만든 제품은 적합성 배지를 검증 성명서 대신 내세우지 않는다.
PHASE-1-DATA-FORMAT §3과 README는 세 등급을 정의한다. 표는 짧지만 각 행은 세 가지 질문에 답한다. 누가 주장하는가, 어떤 증거가 뒷받침하는가, 그 증거는 얼마나 자주 갱신되는가.
| 등급 | 명세 문구 | 증명 주체 | 증거 | 갱신 주기 | 사용자가 신뢰할 수 있는 것 |
|---|---|---|---|---|---|
| Surface | "data formats accepted; self-attested"(데이터 형식 수용, 자체 증명) | 구현자 | 서명 매니페스트, 가능하면 공개된 테스트 벡터 결과표 | 릴리스마다 | 시스템이 WIA 레코드를 받고 만든다. 독립된 제3자는 확인하지 않았다. |
| Verified | "annual third-party audit"(연간 제3자 감사) | 독립 감사인 | 감사 보고서와 감사 시점의 증거 패키지 | 매년 | 외부 당사자가 특정 시점에 네 PHASE 문서 기준으로 구현체를 점검했다. |
| Anchored | "continuous evidence package per Annex G"(Annex G에 따른 지속적 증거 패키지) | 구현자, 단 누구나 재검증할 수 있는 증거와 함께 | 서명된 SBOM, OpenAPI 문서, 테스트 결과표, 매니페스트를 투명성 로그에 앵커링 | 릴리스마다, 최소 분기마다 | 증거가 최신이고 변조를 감지할 수 있다. 공급사에 묻지 않고 사용자가 직접 확인할 수 있다. |
세 등급은 품질의 엄격한 사다리가 아니다. Verified는 1년에 한 번 독립된 사람의 판단을 더한다. Anchored는 연속성과 기계로 확인 가능한 출처 증명을 더하지만, 문구상 감사인을 요구하지는 않는다. 독립성과 최신성이 모두 필요한 등록부라면 "더 높아 보이는" 등급이 다른 등급을 포함한다고 가정하지 말고 Verified 와 Anchored 증거를 함께 요구해야 한다. 이 책은 제품 페이지에 등급과 함께 가장 최근 증거의 날짜를 적을 것을 권고한다. 예를 들어 "Anchored, 2026-07-01자 증거 패키지"처럼 쓰면 독자가 주장이 최신인지 한눈에 알 수 있다.
구현체는 OpenAPI 문서의 벤더 확장 필드 x-wia-conformance-tier로 등급을 선언한다. OpenAPI 3.1은 info 객체에 x- 확장을 허용하며, API 전체에 관한 주장은 이 위치에 두는 것이 자연스럽다. /.well-known/wia/direct-air-capture의 발견 문서(제4장)도 같은 값을 반복하고 매니페스트를 가리켜야 한다. 그래야 클라이언트가 등급에서 증거로 곧바로 찾아갈 수 있다.
openapi: 3.1.0
info:
title: Example DAC Operations API
version: 1.4.2
x-wia-conformance-tier: Anchored
x-wia-standard: direct-air-capture
x-wia-manifest: https://dac.example.com/.well-known/wia/manifest.dsse.json
servers:
- url: https://dac.example.com/api/v1
위 발췌의 x-wia-standard와 x-wia-manifest 키는 이 책의 제안이며, 명세가 정의하는 것은 x-wia-conformance-tier뿐이다. 값은 명세에 적힌 세 등급 이름 중 하나를 철자 그대로 써야 한다. 클라이언트는 그 밖의 값이나 값이 없는 경우를 "주장 없음"으로 처리해야 한다.
등급은 특정 빌드의 특정 버전에 대한 주장이다. 여기서 두 가지 실무 규칙이 나온다. 둘 다 표준 본문이 아니라 이 책의 권고다.
여러 부속서(예: 각 PHASE 파일의 Annex E)는 독자를 "Annex A의 적합성 등급"으로 안내한다. 그러나 배포된 명세에는 Annex A가 없다. 등급 정의는 PHASE-1-DATA-FORMAT §3에 있고 PHASE-2-API-INTERFACE와 README에 같은 내용이 실려 있으니 그쪽을 인용해야 한다.
적합성 주장은 두 개의 JSON 문서에 담긴다. 매니페스트는 어떤 구현체, 어떤 빌드, 표준의 어떤 버전인지를 밝힌다. 프로파일 매니페스트는 요구사항별로 그 빌드가 무엇을 지원하는지를 밝힌다. 명세는 둘을 한 문서로 두든 두 문서로 두든 허용하며, 같은 키로 서명하라는 것만 요구한다.
PHASE-1-DATA-FORMAT §2는 내용을 이렇게 나열한다. standardSlug, version, implementation 블록, profile, 요구사항별 지원 상태, 그리고 Sigstore DSSE 서명이다. CLI의 manifest-template 명령(§8.4)이 출력하는 골격은 이 목록의 일부만 담고 있다.
| 필드 | 의미 | 근거 | CLI 템플릿에 있는가 |
|---|---|---|---|
standardSlug | 항상 상수 "direct-air-capture"이며 WIA-ENE-050이 아니다 | DATA-FORMAT §2 | 있음 |
version | 구현한 표준의 버전(SemVer 2.0.0) | DATA-FORMAT §2 | 있음(CLI 자신의 버전 1.0.0으로 채워짐) |
implementation.name | 제품 또는 서비스 이름 | DATA-FORMAT §2 | 있음(자리표시자) |
implementation.build | Git 커밋 또는 컨테이너 이미지 다이제스트 | DATA-FORMAT §2 | 있음(자리표시자) |
implementation.sbom | CycloneDX 또는 SPDX SBOM의 URL | DATA-FORMAT §2 | 있음(example.com) |
profile.named, profile.version | 이름 붙은 상호운용 프로파일과 그 메이저 버전 | DATA-FORMAT §2, Annex I | 있음 |
| 요구사항별 상태 | 요구사항 ID마다 supported / partial / excluded | DATA-FORMAT §2, Annex I | 없음 |
| 서명 | DSSE 봉투와 투명성 로그 항목 | DATA-FORMAT §2, Annex G | 없음(문서 바깥에서 적용) |
documentId, issuedAt | 매니페스트 식별자와 발급 시각 | CLI 템플릿에만 있음 | 있음(issuedAt은 고정된 자리표시 날짜) |
실무에서는 두 가지 세부가 중요하다. 첫째, 매니페스트의 version은 표준의 버전이고 implementation.build는 제품을 식별한다. 둘을 혼동해 제품 버전을 version에 적는 실수는 흔하며, 그러면 매니페스트가 존재하지 않는 표준 버전에 적합하다고 주장하게 된다. 둘째, 템플릿의 issuedAt은 하드코딩된 날짜다. 실제 서명 시각을 UTC로 넣어야 한다. 제4장에서 짚었듯이 이 값은 매니페스트의 속성이며 포집·저장 레코드의 타임스탬프와는 관계가 없다.
Annex I는 세 가지 상태를 정의한다. 요구사항은 supported이거나, partial(reason 포함)이거나, excluded(justification 포함)이다. 목적도 분명히 적혀 있다. 규모가 다른 배포가 "부분 적합을 완전 적합으로 잘못 표시하지 않으면서, 자신이 충족하는 규범 요구사항의 부분집합을 알릴 수 있도록" 하는 것이다.
명세는 요구사항 ID 목록을 공개하지 않는다. 운영 프로토콜에는 목록이 필요 없다. 제5장에서 보았듯이 각 단계에는 이미 DAC-CAPTURE-REG-001이나 DAC-MRV-001 같은 식별자가 있다. 데이터와 API 계층에 대해 이 책은 DAC-<PHASE>-<영역>-<NNN> 패턴을 제안한다. 예컨대 시설 스키마는 DAC-DATA-FAC-001이 된다. 워킹그룹이 공식 목록을 내기 전까지는 어떤 ID 체계를 쓰는지 매니페스트에 밝혀 두어야 감사인이 ID를 본문과 대응시킬 수 있다.
CLI의 profiles 명령은 네 가지 배포 형태를 나열한다. single-tenant(조직당 런타임 하나), multi-tenant(헤더 기반 격리를 둔 공유 런타임), federated(런타임들의 P2P 메시), air-gapped(실시간 연결 없는 배치 증거 패키지)이다. DAC에서 air-gapped 프로파일은 특이한 경우가 아니다. 플랜트 제어망은 흔히 인터넷과 분리되어 있고, 현장은 실시간 API를 열지 않고 서명된 일일 묶음을 내보낼 수 있다. 프로파일 이름에는 메이저 버전이 붙는다. Annex I의 예 WIA-P1-DATA-FORMAT-Edge-only/2는 해당 이름 붙은 프로파일의 버전 2라는 뜻이지, 두 번째 배포라는 뜻이 아니다.
다음 예는 가상의 MRV 플랫폼에 대한 매니페스트와 프로파일 매니페스트를 합친 것이다. 이름, 다이제스트, URL은 모두 예시다.
{
"documentId": "wia-direct-air-capture-0007",
"standardSlug": "direct-air-capture",
"version": "1.0.0",
"implementation": {
"name": "Example MRV Platform",
"build": "sha256:4f1c...e09a",
"sbom": "https://mrv.example.com/evidence/1.4.2/sbom.cdx.json"
},
"profile": { "named": "air-gapped", "version": 1 },
"requirementIdScheme": "book-recommended DAC-PHASE-AREA-NNN",
"requirements": [
{ "id": "DAC-DATA-FAC-001", "status": "supported" },
{ "id": "DAC-DATA-CAP-001", "status": "supported" },
{ "id": "DAC-DATA-CRD-001", "status": "partial",
"reason": "blockchain block accepted but not populated" },
{ "id": "DAC-API-WS-001", "status": "excluded",
"justification": "air-gapped profile: no live WebSocket feed; daily signed bundles instead" },
{ "id": "DAC-MRV-001", "status": "supported" }
],
"issuedAt": "2026-07-01T09:30:00Z"
}
excluded 항목의 표현에 주목하라. "구현하지 않음"이라고 쓰지 않고, 왜 그 요구사항이 이 배포 형태에 해당하지 않는지를 설명한다. 정직한 부분 주장과 단순한 결함은 여기서 갈린다. 감사인은 partial과 excluded 줄을 먼저 읽는다. 구현자 자신의 판단이 개입된 곳이 바로 그 줄이기 때문이다.
연합형 배포에는 문서가 하나 더 붙는다. 구성원 프로파일의 합집합과 교집합을 밝히는 집계 매니페스트다(Annex I). 여러 DAC 현장이 하나의 MRV 플랫폼에 보고하는 네트워크라면 쓸모 있는 것은 교집합이다. 교집합은 모든 현장에 대해 성립하는 요구사항, 즉 등록부가 네트워크 전체에 대해 할 수 있는 주장의 범위를 알려 준다.
표준은 서명에 Sigstore를 쓴다. 매니페스트 바이트는 DSSE(Dead Simple Signing Envelope) 구조로 감싸지며, 이 구조에는 payloadType, base64로 인코딩한 페이로드, 하나 이상의 서명이 들어간다. 서명 이벤트는 Rekor 투명성 로그에 기록된다. 로그 항목이 있으면 누구든 그 서명이 특정 시점에 존재했고 몰래 바뀌지 않았음을 확인할 수 있다. 발견 문서도 같은 키로 서명하므로(DATA-FORMAT §4) 실제 API 엔드포인트와 증거가 서로 묶인다.
{
"payloadType": "application/vnd.wia.manifest+json",
"payload": "eyJkb2N1bWVudElkIjoid2lhLWRpcmVjdC1haXItY2FwdHVyZS0wMDA3Ii...",
"signatures": [
{ "keyid": "mrv-signing-2026", "sig": "MEUCIQ..." }
]
}
위의 payloadType 값은 예시이며 명세는 이를 정하지 않는다. Sigstore의 cosign 도구를 쓰는 전형적인 흐름에서는 매니페스트 파일에 서명하고, 그 결과로 나온 번들(서명, 인증서, 로그 포함 증명)을 파일 옆에 저장한 뒤, 사용자가 번들과 기대하는 서명자 신원으로 검증하게 한다. 세부 옵션은 cosign 릴리스마다 달라지므로 CI에서 도구 버전을 고정하고 그 버전을 증거 패키지에 기록해야 한다.
부속서에서 두 가지 운영 규칙이 나온다. 갱신은 새 매니페스트로 발급하고, 이전 매니페스트는 대체 표시와 함께 보존한다. 서명 키는 배포 정책에 따라 교체하되, 옛 공개키는 공개된 키 이력에 남겨 감사인이 3년 전 매니페스트도 오프라인으로 검증할 수 있게 한다. DAC에서는 이것이 형식적 절차가 아니다. 탄소제거 크레딧은 발행 후 몇 년이 지나 검토될 수 있고, 그때에도 당시 MRV 소프트웨어가 적합했다는 증거가 검증되어야 한다.
유효한 서명은 누가 매니페스트를 발급했는지, 그리고 그것이 변경되지 않았음을 증명한다. 그 안의 진술이 참인지, SBOM이 완전한지, 시설이 기록대로 포집했는지는 증명하지 않는다. 이 질문들에는 각각 테스트 벡터 결과표(소프트웨어 동작), 감사(Verified 등급), MRV 검증 보고서(톤수)가 답한다.
Annex G는 적합성 패키지를 네 가지 산출물을 담은 tarball로 설명한다. SBOM(CycloneDX 1.5 또는 SPDX 2.3), OpenAPI 문서, 테스트 벡터 결과표, 서명 매니페스트다. Anchored 구현체가 공개하고 Verified 감사인이 검토하는 단위가 바로 이 패키지다.
| 산출물 | 형식 | 답하는 질문 | DAC 구현자를 위한 메모 |
|---|---|---|---|
| SBOM | CycloneDX 1.5 또는 SPDX 2.3 | 이 빌드에 어떤 소프트웨어가 들어갔는가? | JSON Schema 검증기와 단위 변환 라이브러리를 포함할 것. 둘 다 레코드의 정확성에 영향을 준다. |
| OpenAPI 문서 | OpenAPI 3.1 | API가 실제로 무엇을 노출하는가? | 배포된 7줄짜리 골격이 아니라 스키마에서 도출한 실제 문서여야 한다(제4장 §4.6). |
| 테스트 벡터 결과표 | JSON(명세가 형태를 정하지 않음) | 이 빌드에서 어떤 요구사항이 통과·실패하는가? | 요구사항마다 양성·음성 결과 하나씩. 건너뜀은 실패로 친다. |
| 서명 매니페스트 | DSSE 봉투에 담긴 JSON | 누가, 어떤 빌드에 대해, 무엇을 주장하는가? | 프로파일 매니페스트를 포함하거나 참조한다. |
| 변경이력 매핑(권장) | 텍스트 또는 JSON | 각 표준 버전은 어떤 빌드에 대응하는가? | Annex H의 권장 사항. 감사인이 모든 테스트를 다시 돌리지 않아도 된다. |
산출물의 위치를 예측 가능하게 두는 배치는 다음과 같다(이 책의 제안).
evidence-1.4.2.tar.gz
|-- manifest.json
|-- manifest.dsse.json (DSSE envelope + Rekor bundle)
|-- profile-manifest.json (if kept separate)
|-- sbom.cdx.json
|-- openapi.yaml
|-- test-matrix.json
|-- changelog-mapping.json
`-- README.txt (tool versions, how to re-verify)
Annex G는 "모든 규범 요구사항에 최소 하나의 양성 벡터와 하나의 음성 벡터"를 tests/phase-vectors/ 아래에 두고, 적합을 주장하는 구현체는 CI에서 모든 벡터를 실행하라고 요구한다. 그러나 이 디렉터리는 참조만 되어 있고 배포되지 않았으므로, 현재는 구현자마다 벡터를 직접 작성해야 한다. 제2장과 제3장의 레코드에서 쓸모 있는 쌍을 많이 끌어낼 수 있다. 일부는 JSON Schema만으로 확인되고, 일부는 스키마로 표현할 수 없는 일관성 검사가 필요하다.
| 요구사항(예시 ID) | 양성 벡터 | 음성 벡터 | 검사 수단 |
|---|---|---|---|
| 시설 ID 패턴(DAC-DATA-FAC-001) | dac-example-reykjanes-01 | DAC_Example_01(대문자, 밑줄) | JSON Schema pattern |
| 비율은 비율로(DAC-DATA-CAP-002) | efficiency: 0.82 | efficiency: 82 | JSON Schema 범위 0–1 |
| 크레딧 빈티지(DAC-DATA-CRD-002) | vintage: 2025 | vintage: 2019 | JSON Schema minimum: 2020 |
| 주입 일관성(DAC-DATA-STO-003) | 속도 × 시간이 허용오차 안에서 주입량과 같음 | 속도 × 시간이 주입량의 두 배 | 자체 검증기(제3장 §3.1) |
| 이중 발행 금지(DAC-DATA-CRD-004) | 새 저장 이벤트에 새 일련번호 | 같은 저장 톤을 인용하는 두 번째 크레딧 | 증거 사슬 전체를 보는 자체 검증기 |
| 오류 봉투(DAC-API-ERR-001) | 없는 시설 조회 시 합의된 오류 객체 반환 | 없는 시설 조회 시 HTTP 200과 빈 데이터 반환 | API 통합 테스트 |
결과표의 각 항목에는 요구사항, 벡터 파일, 방향별 결과, 그리고 건너뛴 것이 있다면 그 사유를 기록해야 한다. 예를 들면 다음과 같다.
{
"build": "sha256:4f1c...e09a",
"standardVersion": "1.0.0",
"generatedAt": "2026-07-01T08:55:12Z",
"results": [
{ "requirement": "DAC-DATA-CRD-002",
"positive": { "vector": "crd-002-pos.json", "result": "pass" },
"negative": { "vector": "crd-002-neg.json", "result": "pass" } },
{ "requirement": "DAC-API-WS-001",
"positive": { "result": "skipped", "justification": "excluded by air-gapped profile" },
"negative": { "result": "skipped", "justification": "excluded by air-gapped profile" } }
]
}
여기서 음성 벡터의 "pass"는 구현체가 잘못된 입력을 올바르게 거부했다는 뜻이다. 이 규약을 결과표 안에 적어 두면 형식에 익숙하지 않은 독자에게 도움이 된다.
Annex G는 공급사가 음성 결과를 양성 결과와 같은 충실도로 보고해야 하며, "기록된 사유 없이 건너뛴 테스트는 감사인이 실패로 취급한다"고 적고 있다. 이 규칙은 익숙한 허점을 막는다. 까다로운 테스트를 조용히 건너뛰는 스위트는 100 % 통과를 보고할 수 있기 때문이다. 사유는 감사인이 확인할 수 있는 대상, 대개 프로파일 매니페스트의 excluded 줄을 가리켜야 한다. 프로파일 제외를 인용하지 않는 건너뜀은 실패다.
구현체는 자기 소스가 바뀌지 않았더라도 분기마다 증거 패키지를 다시 공개한다(Annex G). 이유는 환경 드리프트다. 컴파일러, 의존성, 운영체제 이미지가 빌드 아래에서 바뀐다. DAC MRV 소프트웨어에서는 날짜 라이브러리나 숫자 형식 라이브러리가 조용히 갱신되어 레코드 타임스탬프나 반올림이 달라지고, 그 결과 톤수 합계가 바뀔 수 있다. 분기마다 다시 빌드하고 벡터 전체를 돌리는 것은 검증기관보다 먼저 이를 잡아내는 값싼 방법이다. 새 실패의 원인을 설명하는 가장 빠른 길은 두 분기 패키지의 SBOM 차이를 비교하는 것인 경우가 많다.
Annex G가 언급하는 공급사 간 대응표(crosswalk)는 현재 이 표준과 함께 공개되어 있지 않다. 향후 작업으로 보아야 한다.
표준이 배포하는 도구는 cli/direct-air-capture.sh(버전 1.0.0) 하나로, 네 개 명령을 가진 Bash 스크립트다. 출발점으로 유용하며, 템플릿과 적합성 제도 사이에 얼마나 많은 일이 남아 있는지를 분명히 보여 준다.
| 명령 | 하는 일 | 한계 |
|---|---|---|
manifest-template | standardSlug, version, implementation, profile, issuedAt를 담은 매니페스트 골격 출력 | 요구사항 목록 없음, 서명 없음, issuedAt 고정 |
validate <file> | standardSlug가 direct-air-capture인지 확인(jq 사용, 없으면 Python 대체 경로) | 그 밖에는 아무것도 확인하지 않음 |
profiles | 네 프로파일 이름 나열 | 고정 텍스트, 프로파일 버전 없음 |
info | 버전과 등급 이름 출력 | 고정 텍스트 |
$ ./direct-air-capture.sh manifest-template > manifest.json
$ ./direct-air-capture.sh validate manifest.json
OK: manifest.json declares standardSlug=direct-air-capture
$ echo '{"standardSlug":"WIA-ENE-050"}' > wrong.json
$ ./direct-air-capture.sh validate wrong.json
standardSlug mismatch: got 'WIA-ENE-050', expected 'direct-air-capture'
두 번째 실행은 쓸모 있는 성질을 보여 준다. 이 도구는 명세 본문의 식별자 WIA-ENE-050을 슬러그 필드에 넣으면 거부하므로, 제1장의 명명 규칙을 강제한다. 그러나 implementation이 비어 있거나, 요구사항 목록이 없거나, version에 제품 버전을 넣은 매니페스트도 여전히 "OK"를 출력한다. 또한 Python 대체 경로는 파일 이름을 Python 소스 안에 끼워 넣어 명령을 만들기 때문에, 따옴표가 들어간 파일 이름에서는 동작이 깨진다. 신뢰할 수 있는 경로로만 호출하거나 자체 래퍼에서 경로를 안전하게 다뤄야 한다.
저장소의 세 가지 참조는 배포되지 않은 대상을 가리킨다. tests/phase-vectors/의 적합성 벡터, api/typescript/의 TypeScript SDK(따라서 README의 @wia/direct-air-capture 예제는 예시일 뿐이다), 그리고 기계가 읽을 수 있는 스키마 파일이다. 스키마는 PHASE-2-DATA 안의 JSON으로만 존재하므로, 실제 도구를 만드는 첫 단계는 이를 파일로 추출해 버전 관리하는 것이다.
validate 확장하기가장 간단한 개선은 매니페스트를 JSON Schema 2020-12 문서로 검증하는 것이다. 명세가 그런 스키마를 공개하지 않으므로 아래 스키마는 이 책의 제안이다. 표 8-2와 Annex I의 규칙을 담고 있다.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://example.com/schemas/wia-dac-manifest.json",
"type": "object",
"required": ["standardSlug", "version", "implementation", "profile", "requirements", "issuedAt"],
"properties": {
"standardSlug": { "const": "direct-air-capture" },
"version": { "type": "string",
"pattern": "^(0|[1-9]\\d*)\\.(0|[1-9]\\d*)\\.(0|[1-9]\\d*)(-[0-9A-Za-z.-]+)?$" },
"implementation": {
"type": "object",
"required": ["name", "build", "sbom"],
"properties": {
"name": { "type": "string", "minLength": 1, "not": { "const": "REPLACE_ME" } },
"build": { "type": "string", "minLength": 7 },
"sbom": { "type": "string", "format": "uri" }
}
},
"profile": {
"type": "object",
"required": ["named", "version"],
"properties": {
"named": { "enum": ["single-tenant", "multi-tenant", "federated", "air-gapped"] },
"version": { "type": "integer", "minimum": 1 }
}
},
"requirements": {
"type": "array", "minItems": 1,
"items": {
"type": "object",
"required": ["id", "status"],
"properties": {
"id": { "type": "string" },
"status": { "enum": ["supported", "partial", "excluded"] }
},
"allOf": [
{ "if": { "properties": { "status": { "const": "partial" } } },
"then": { "required": ["reason"] } },
{ "if": { "properties": { "status": { "const": "excluded" } } },
"then": { "required": ["justification"] } }
]
}
},
"issuedAt": { "type": "string", "format": "date-time" }
}
}
짧은 Node.js 스크립트로 이 스키마를 Ajv에 돌릴 수 있다. Ajv는 ajv/dist/2020 진입점으로 2020-12 초안을 지원하며, ajv-formats 패키지가 uri와 date-time 검사를 더한다.
// validate-manifest.mjs (illustrative)
import Ajv2020 from "ajv/dist/2020.js";
import addFormats from "ajv-formats";
import { readFileSync } from "node:fs";
const schema = JSON.parse(readFileSync("wia-dac-manifest.schema.json", "utf8"));
const doc = JSON.parse(readFileSync(process.argv[2], "utf8"));
const ajv = new Ajv2020({ allErrors: true, strict: true });
addFormats(ajv);
const validate = ajv.compile(schema);
if (!validate(doc)) {
for (const e of validate.errors) console.error(`${e.instancePath || "/"} ${e.message}`);
process.exit(1);
}
if (doc.issuedAt === "2026-04-26T00:00:00Z") {
console.error("issuedAt still holds the template placeholder");
process.exit(1);
}
console.log("manifest OK");
같은 방식을 데이터 레코드 자체로 넓힐 수 있다. PHASE-2-DATA에서 시설·포집·흡착제·저장·검증·크레딧 스키마를 추출하고, 제2장과 제3장의 일관성 검사를 별도 함수로 추가한 뒤, 모든 양성·음성 벡터가 같은 진입점을 호출하게 하면 된다. 얇은 Bash 래퍼를 두어 원래 CLI 인터페이스를 유지하고 기존 슬러그 검사를 먼저, 스키마 검사를 그다음에 실행하면 기존 스크립트도 그대로 동작한다.
FOUNDATION §8.2는 두 종류의 인증을 구분한다. 문서상으로는 비슷해 보이지만 답하는 질문도, 관여하는 기관도 다르다.
| 항목 | 시설 인증 | 소프트웨어 인증 |
|---|---|---|
| 명세에 나열된 단계 | 자체 평가 설문, 문서 검토, 제3자 감사, 연간 재인증 | API 적합성 시험, 데이터 형식 검증, 보안 감사, 상호운용성 시험 |
| 주장의 대상 | 플랜트와 그 데이터 관행: 계량, 교정, 보존, 프로토콜 | WIA 레코드를 생산하거나 소비하는 제품·서비스 |
| 주요 증거 | 교정 기록, 프로토콜 로그(제5장), 샘플 레코드, MRV 패키지(제6장) | 증거 패키지(§8.3), 보안 시험 보고서 |
| 등급과의 관계 | 소프트웨어 등급이 아님. 현장 데이터 파이프라인에 대해서는 Verified에 가장 가까움 | Surface, Verified, Anchored |
| 관련 외부 체계 | 등록부 방법론, 온실가스 진술의 검증과 검증기관에 관한 ISO 14064-3 및 ISO 14065 | 인증기관에 관한 ISO/IEC 17065, 보안 경영시스템에 관한 ISO/IEC 27001 |
어느 트랙도 톤수를 인증하지 않는다. 인증받은 시설도 검증량이 기록된 포집량보다 낮은 분기를 겪을 수 있고, Anchored MRV 플랫폼이라고 해서 계량이 부실한 현장의 레코드를 더 낫게 만들지는 못한다.
표준은 제품·공정·서비스를 인증하는 기관에 대한 요구사항인 ISO/IEC 17065:2012를 인용한다. 실무적으로 이는 Verified 감사가 자체 절차가 ISO/IEC 17065를 충족하는 기관, 가급적 국가 인정기구의 인정을 받은 기관에서 나와야 하며, 구현체를 직접 만든 컨설팅사에서 나와서는 안 된다는 뜻이다. Annex E는 7년의 증거 보존이 "대부분의 관할에서 ISO/IEC 17065:2012 감사 기대치를 충족하기에 충분하다"고 적는다. 이는 워킹그룹의 평가이지 ISO/IEC 17065 자체의 요구사항이 아니다. 규제기관이나 등록부가 더 긴 보존을 요구할 수 있으며, 그 경우 배포 정책이 보존 기간을 늘려야 한다. DAC에서는 소프트웨어 증거의 보존을 제2장의 레코드 보존(원자료 7년, 집계 30년, 검증 기록 영구)에 맞추는 것이 합리적이다. 오래된 크레딧을 살펴보는 감사인에게는 둘 다 필요하기 때문이다.
톤수 자체의 검증은 등록부 방법론을 따르며 등록부가 인정하는 검증기관이 수행한다. 이 절차는 제6장에서 다뤘다. 이 장의 적합성 증거는 검증기관의 일을 쉽게 해 주지만 대신하지는 않는다.
FOUNDATION §8.3은 분쟁을 유형별로 나눈다. 기술 분쟁은 기술위원회 검토로, 인증 분쟁은 독립 중재로, 데이터 분쟁은 제3자 검증으로 보내며, 이의 제기 절차는 "명확히 정의"한다고 적는다. 그러나 명세는 아직 그 절차를 정의하지 않았다. 구현자가 대비할 수 있는 구체적 방법은 하나다. 분쟁에 필요할 모든 산출물을 미리 서명하고 날짜를 붙여 두는 것이다. 예컨대 저장 이벤트를 둘러싼 데이터 분쟁은 인수인계 계량값, 저장 이벤트 레코드, 검증 보고서, 그리고 이를 처리한 소프트웨어의 매니페스트로 해결된다. 넷 모두가 존재하고 서명·앵커링되어 있다면 분쟁은 증거를 재구성하는 일이 아니라 증거를 읽는 일이 된다.
표준은 전체적으로 Semantic Versioning 2.0.0을 따른다. 메이저 버전은 규범 요구사항의 하위 호환되지 않는 변경을, 마이너 버전은 기존 구현을 깨지 않는 요구사항 추가를, 패치는 편집상 수정만을 뜻한다(Annex H). PHASE-2-DATA §10은 같은 규칙을 스키마에 적용하고 필드 단위 표시인 "deprecated": true를 더한다. 정오표는 패치 릴리스로 발행되며, 공개 정오표 대장에 기록되고 워킹그룹 의장이 서명한다.
거버넌스는 두 곳에서 설명된다. FOUNDATION §8.1은 WIA-ENE-050 워킹그룹이 운영하는 연 1회 검토 주기와, RFC → 커뮤니티 검토 → 투표 → 갱신으로 이어지는 개정 절차를 제시한다. PHASE-1-DATA-FORMAT §8은 WIA 표준 워킹그룹이 매 마이너 릴리스 주기 시작 시점에 direct-air-capture 레이블이 붙은 GitHub 이슈를 검토하고, 결정 로그를 릴리스 노트와 함께 공개한다고 적는다. 연간 검토를 최소 주기로, 릴리스별 검토를 일상 주기로 읽으면 두 설명은 양립한다.
명세의 여러 규칙이 서로 충돌한다. 구현자가 우연히 물려받는 대신 의식적으로 선택할 수 있도록 여기에 정리한다.
| 주제 | 명세의 진술 | 실무 처리(이 책의 권고) |
|---|---|---|
| 메이저 버전 병행 기간 | 최소 90일(PHASE-1-DATA-FORMAT §6, Annex F), 최소 180일(Annex H) | 180일을 기준으로 계획하고 선택한 기간을 배포 정책에 명시한다. |
| 필드 폐기 후 제거까지 | 6개월(PHASE-2-DATA §10.2) | 스키마 수준의 최소 기간으로 본다. 180일과 대략 일치하지만 별개의 규칙이다. |
| 폐기된 메이저 버전의 일몰 | 마이그레이션 노트를 동반한 12개월 일몰 기간(§6, Annex H) | 폐기 후 12개월 동안 옛 버전 레코드를 계속 받아들인다. |
| 필드 이름 변경·삭제(오류 페이로드 포함) | 마이너 버전 올림 필요(Annex E), 호환되지 않는 변경은 메이저 올림 필요(Annex H, SemVer) | 클라이언트를 깨는 이름 변경은 메이저 변경이다. 새 이름을 추가하고 옛 이름을 폐기 표시한 뒤 다음 메이저에서 제거한다. |
| 문서 상태 | FOUNDATION: v1.0 "Draft", DATA-FORMAT·API-INTERFACE: v1.0 "Stable" | 적합성 주장에는 정확한 파일과 상태를 인용한다. |
| 라이선스 | FOUNDATION: CC BY 4.0, README: MIT | 스키마를 재배포하기 전에 어느 파일에 어떤 라이선스가 적용되는지 워킹그룹에 확인한다. |
이 충돌들은 구현자가 해결할 수 없다. 올바른 대응은 direct-air-capture 레이블로 이슈를 열어 충돌하는 절을 인용하고, 그동안 가장 보수적인 해석을 채택하는 것이다. 폐기 기간에서 "가장 보수적"이란 가장 긴 기간을 뜻한다. DAC 크레딧은 바탕이 된 레코드가 만들어지고 한참 뒤에 검증되거나 폐기될 수 있고, 그때에도 그 레코드는 검증을 통과해야 하기 때문이다.
탄소 제거에서는 레코드가 작성되고 수십 년 뒤에 읽힐 수 있다. 주입 후 저장 모니터링이 이어질 때나 구매자가 이미 폐기된 크레딧을 다시 검토할 때가 그렇다. 따라서 스키마 변경에는 과거 레코드를 위한 이행 경로가 필요하다. 두 가지 관행이 도움이 된다. 모든 레코드에 작성 당시의 스키마 버전을 담아 검증기가 맞는 스키마를 고를 수 있게 하는 것, 그리고 이행 시 서명된 원본을 고쳐 쓰지 말고 파생 필드를 추가하는 것이다. 서명된 레코드를 다시 쓰면 증거 사슬이 끊어진다.
FOUNDATION §9는 네 PHASE 문서 다음에 다섯 번째 단계인 생태계(Ecosystem)를 제시한다. 공개 대시보드, 탄소시장 통합, 연구 데이터 플랫폼, 정책 통합이다. 배포된 명세에는 아직 Phase 5 본문이 없다. 아래 절들은 그 작업이 답해야 할 질문을 설명한다. 일부러 정성적으로 서술했으며, 이 책은 시장 규모나 보급에 관한 어떤 전망도 하지 않는다.
제7장은 공개 데이터 집계와 단계별 접근 모델을 설명했다. 공개 대시보드의 의미는 그것이 집계하는 데이터가 얼마나 비교 가능한지에 달려 있다. 대시보드를 만들기 전에 Phase 5는 공개할 양(총포집량, 저장량, 검증된 순제거량), 보고 기간, 불확도 처리에 대한 합의된 정의가 필요하다. 그렇지 않으면 같은 "톤"을 보고하는 두 시설이 서로 다른 것을 뜻할 수 있다. 이 장의 적합성 도구는 데이터 출처의 품질을 표시하는 자연스러운 수단이다. 대시보드는 각 시설 옆에 그 데이터를 만든 소프트웨어의 적합성 등급과 날짜를 함께 보여 줄 수 있다.
표준은 이미 저장 방법과 영구성 등급을 열거값으로 기록한다(제1장, 제3장). 탄소 제거 분야의 흐름은 내구성을 주장 자체에 명시해, 지질 구조에 저장된 1톤과 제품에 저장된 1톤을 서로 바꿔 쓸 수 있는 것처럼 팔지 않게 하는 쪽으로 가고 있다. 데이터 표준으로서는 영구성 등급이 폐기를 포함한 모든 시스템을 거치며 크레딧과 함께 이동해야 하고, 등록부와 구매자가 이를 기준으로 걸러 낼 수 있어야 한다는 뜻이다. 제5장에서 짚었듯이 현재의 활용 경로 분류에는 의문스러운 부분이 있다. 향후 버전은 어떤 내구성 등급이든 이름표가 아니라 검증기관이 확인할 수 있는 증거에 근거해야 한다.
크레딧 스키마는 등록부로 Puro.earth, Verra, Gold Standard, ACR, "Other"를 나열한다. 현재 각 등록부는 고유한 식별자와 데이터 모델을 갖는다. 상호운용의 중요성을 키우는 흐름은 두 가지다. 첫째는 같은 톤이 둘 이상의 등록부에 나타날 위험으로, 제3장의 증거 사슬은 바로 이를 드러내도록 설계되었다. 둘째는 파리협정 제6조에 따른 국제 이전으로, 크레딧의 특정 용도에는 유치국 국가 회계에 대한 "상응 조정"이 요구된다. 데이터 표준은 저장 이벤트와 크레딧에 안정적이고 전 세계적으로 고유한 식별자를 부여하고, 각 이전의 승인·조정 상태를 자유 서술이 아닌 명시적 필드로 기록함으로써 두 가지를 모두 지원할 수 있다.
시설 스키마에는 electrochemical-dac가 들어 있지만, 운영 레코드와 흡착제 레코드는 분명히 열 스윙 공정을 기준으로 설계되었다. 재생 온도, 열 투입, 흡착제 적재량, 사이클당 열화가 그렇다. 전기화학 공정은 열이 아니라 전압으로 구동된다. 이를 잘 담으려면 사이클당 전기에너지, 셀 조건(전압, 전류, CO2 단위량당 통과 전하량), 흡착제 적재량 대신 전극·분리막 등 활성 소재의 노화를 기록하는 필드가 필요할 가능성이 크다. 전기가 주 투입물이므로 사용 전력의 시간 해상도 배출계수는 지금보다도 더 순제거량의 중심이 된다(제7장 §7.3). 이 중 어느 것도 새 아키텍처를 요구하지 않는다. 이 장의 확장 메커니즘과 프로파일 매니페스트를 쓰면 공급사는 지금 이런 필드를 추가해 확장으로 선언하고, 나중에 정상적인 RFC 절차를 거쳐 표준화를 제안할 수 있다.
저장 모니터링과 크레딧 주장은 어떤 소프트웨어 제품, 서명 키, 클라우드 사업자보다 오래 지속된다. 향후 버전에는 투명성 로그나 서명 알고리즘이 퇴역할 때를 위한 계획이 필요하다. 예컨대 옛 로그가 닫히기 전에 과거 증거를 새 로그에 다시 앵커링하는 방식이다. 이는 WIA만이 아니라 분야 전체의 미해결 과제이며, 워킹그룹에서 일찍 제기할 가치가 있다.
standardSlug만 확인하며, 테스트 벡터·TypeScript SDK·스키마 파일은 배포되지 않았다. JSON Schema 2020-12와 자체 일관성 검사로 검증을 확장하는 것이 첫 번째 실무 단계다.| # | 항목 | 완료 기준 |
|---|---|---|
| 1 | 등급 선언 | OpenAPI info 객체에 x-wia-conformance-tier가 있고 발견 문서에도 같은 값이 있다 |
| 2 | 매니페스트 완비 | 슬러그, 표준 버전, 빌드 다이제스트, SBOM URL, 프로파일, 요구사항 목록이 있고 issuedAt이 실제 서명 시각이다 |
| 3 | 정직한 프로파일 | 모든 partial에 사유가, 모든 excluded에 감사인이 확인할 수 있는 정당화가 있다 |
| 4 | 벡터 실행 | 요구사항마다 양성·음성 벡터를 CI에서 실행하고 결과표를 공개하며 사유 없는 건너뜀이 없다 |
| 5 | 증거 서명·앵커링 | DSSE 서명, 투명성 로그 항목, 공개된 키 이력이 있고 분기별 재점검 일정이 잡혀 있다 |
이 장으로 책을 마친다. 대기 CO2 직접 포집 플랜트는 공기를 CO2 흐름으로 바꾸며, 그만큼 중요하게 레코드의 흐름도 만들어 낸다. 이 책에서 설명한 표준은 그 레코드에 공통의 형태, 공통의 인터페이스, 무결성을 증명하는 공통의 방법을 준다. 1톤의 제거가 실재하는지는 언제나 측정과 검증이 판정한다. 데이터 표준의 가치는 플랜트가 다음 사이클로 넘어간 지 오래된 뒤에도 누구든 그 판정을 확인할 수 있게 해 준다는 데 있다.