제7장
WIA-BIO-014 구현이 무엇을 만족하는지 선언하고, 시험 벡터와 서명된 산출물로 그것을 입증하며, 그 선언을 시간이 지나도 참으로 유지하는 방법.
제2장부터 제6장까지는 하나의 시스템을 세웠다. 레코드 모델, 식별자와 스키마를 갖춘 직렬화, 레코드를 생산하고 검증하는 SDK와 CLI, 승인 게이트와 감사 추적을 갖춘 생애주기, 그리고 접근제어와 교환 경로를 갖춘 기관 배치가 그것이다. 이 장이 다루는 것은 그 작업의 끝에 적어서 그 자리에 없었던 사람에게 건네는 한 문장이다. 그 사람은 제휴 기관일 수도, 내부 감사인일 수도, 연구윤리 부서일 수도, 조달 심사자일 수도 있다. 그 한 문장이 적합성 주장이며, 그 가치는 거기에 붙은 증거에서만 나온다.
이 장은 통상 뒤섞여 쓰이는 세 가지를 의도적으로 분리한다. 주장은 어떤 요구사항을 만족하는지에 대한 진술이다. 증거는 남이 내 시스템에 접근하지 않고도 그 주장을 확인할 수 있게 하는 기계 판독 가능한 자료다. 인증은 공표된 제도 아래에서 제3자가 그 주장을 받아들이는 행위다. WIA-BIO-014 v1.0은 앞의 둘을 충분히 지원하지만 세 번째는 현재 전혀 정의하지 않는다. 이 장은 존재하지 않는 제도를 만들어 내는 대신 그 사실을 그대로 적는다.
적합성 주장은 네 부분으로 이루어지며, 그중 하나라도 빠지면 주장은 쓸 수 없게 된다. 주장은 대상(“우리 플랫폼”이 아니라 특정 서비스의 특정 빌드), 기준(판번호가 명시된 문서의 식별된 요구사항), 주장자(법적 주체와 서명자의 이름), 증거(읽는 사람이 어떻게 검증하는지)를 밝힌다. 적합성 평가의 일반 용어를 정한 ISO/IEC 17000은 공급자 스스로 적합을 선언하는 제1자 활동, 고객이나 이용자가 공급자를 평가하는 제2자 활동, 독립 기관이 인증하는 제3자 활동을 구분한다. ISO/IEC 17050-1은 공급자 적합성 선언의 형식을 규정한다. 즉 대상을 특정하고, 기준을 인용하고, 서명하고, 날짜를 적고, 뒷받침 증거를 이용 가능한 상태로 유지하는 것이다.
이 용어 구분이 중요한 이유는, 이 표준의 구현자가 오늘 무엇을 말할 수 있고 무엇을 말할 수 없는지를 그것이 확정하기 때문이다. 공표된 WIA-BIO-014 v1.0에는 인정(accreditation) 제도가 없고, 인증기관이 지정돼 있지 않으며, 평가자 역량 요건도 없고, 채점 규칙도 공표돼 있지 않다. 따라서 지금 이 표준에 대해 이루어지는 모든 적합성 진술은 제1자 선언이다. 제1자 선언이 열등한 것은 아니다. 실무의 소프트웨어 상호운용성은 대부분 제1자 선언 위에서 돌아간다. 그러나 그것은 제1자 선언이라고 표시돼야 한다. 아무도 인증하지 않았는데 제품 소개에 “WIA-BIO-014 인증”이라고 적는 것이 이런 주장의 신뢰를 스스로 깨뜨리는 가장 흔한 방식이다.
네 개의 PHASE 문서는 모두 Annex E에 “후속 감사인이 해당 배치를 Annex A의 올바른 적합성 등급에 대해 채점할 수 있도록” OpenAPI 문서에 운영 범위를 선언하라는 항목을 담고 있다. 그런데 Annex A는 없다. 명세서에도, 어느 PHASE 문서에도, README에도, 공표된 트리의 어디에도 없다. 등급 목록도, 채점 임계값도, 등급이 무엇을 재는 것인지에 대한 정의도 없다.
결과는 분명하다. 적합성 등급을 인용하는 것은 이행 불가능하며, 이 표준과 관련해 쓰이는 등급 명칭은 무엇이든 지어낸 것이다. 이 책의 이전 판에는 시험 통과율 임계값과 시장 혜택을 붙인 3단 인증 등급표가 있었다. 그 등급은 명세서에 근거가 없으므로 철회하며, 여기서 어떤 형태로도 재현하지 않는다. Annex A가 공표되기 전까지 정직한 대체물은 이 장의 나머지가 설명하는 증거 기반 주장이다. 등급도 점수도 없이, 요구사항별 상태와 그 상태를 뒷받침하는 검증 가능한 산출물만 둔다.
Annex I는 각 PHASE 문서가 매니페스트에 열거할 “규범적 요구사항 ID”를 갖고 있다고 전제한다. 공표된 문서에는 그것이 없다. 번호 체계가 없고, PHASE 본문은 템플릿 문장이다. 네 문서 모두 표준 WIA-BIO-013 제목을 달고 있고, 본문은 한 문장을 빼면 동일하며, “Technical Requirements”와 “Quality Control” 표는 프로토콜 레코드와 아무 관계가 없는 진단 분야의 일반 합격 수치다. 그 표들은 주장의 기준이 될 수 없으며, 제1장에서 이미 사용 불가로 표시했다.
그러므로 적합성 프로그램의 첫 산출물은 시험 실행이 아니라 기관이 직접 작성하는 요구사항 등록부다. 구현이 이행하려는 의무 하나하나에 대해 등록부는 기관이 부여한 안정적 식별자, 의무 문장 원문, 정확한 출처(문서·판·절), 소프트웨어로 시험 가능한지 여부, 그 의무를 시험하는 벡터를 기록한다. 지역 식별자는 영구히 고정돼야 한다. 앞으로 발행하는 모든 매니페스트와 행렬의 키가 되기 때문이다. 또한 공식 WIA 요구사항 번호로 오인되지 않도록 기관 고유의 접두사를 붙인다.
| 공표 트리의 출처 | 거기서 얻는 것 | 주장 기준으로 쓸 수 있는가 |
|---|---|---|
| 명세서 §8.1 — 필수 구성요소 | 적합 시스템이 포함해야 하는 다섯 서비스 | 가능 — 존재 여부와 레코드 기록 동작 모두 시험 가능 |
| 명세서 §8.3.1 — 프로토콜 JSON | 정본 문서 형태와 필드명 | 가능 — 스키마 검증, 양성·음성 모두 |
| 명세서 §8.4 — 오류 표 | 오류 코드와 코드별 호출자 조치 | 가능 — 제4장에서 지적한 코드 개수 불일치를 병기할 것 |
SDK types.ts — 열거형과 인터페이스 | 통제 어휘와 레코드 계약 | 가능 — 규범 문언이 아니라 참조 구현 동작으로서 |
| CLI 표면 | 명령 집합, 종료 코드, 기계 판독 출력 | 가능 — 자동화 접합부는 직접 시험 가능 |
| Annex E | 범위 선언, 스키마 진화, 보존, 시각 동기화, 오류예산 보고 | 부분적 — 명시적 비규범이므로 정책 약속으로 주장 |
| Annex G | 벡터·증거 패키지·음성결과 보고 관행 | 가능 — 자발적으로 채택한 절차 의무로서 |
| Annex H | 버전·폐기·정오표 정책 | 가능 — 자사 릴리스에 대한 약속으로서 |
| Annex I | 프로파일 매니페스트 기제 | 가능 — 매니페스트 자체가 검증 가능한 산출물 |
| Annex J | 네 가지 배치 형태와 서명 규칙 | 가능 — 운영 중인 토폴로지 선언으로서 |
| PHASE 본문(Technical Requirements, Quality Control) | 다른 주제에서 옮겨온 일반 템플릿 수치 | 불가 — CRISPR 레코드의 기준이 아니므로 제외 |
| “Annex A”(Annex E가 참조) | 없음. 해당 부속서가 존재하지 않는다 | 불가 — 인용 불가이며 어떤 등급도 주장할 수 없다 |
문서 식별자에 관한 편집 주기. README와 명세서는 이 표준을 WIA-BIO-014로 식별하고, PHASE 문서는 WIA-BIO-013으로 표기하며, 이전 전자책 빌드는 WIA-CRISPR_PRO라는 문자열을 썼다. 라이선스 표기도 참조 구현과 PHASE 각주에서 서로 다르다. 그러므로 이 장의 모든 주장 산출물은 WIA-BIO-014와 판 1.0을 기록하되, 주장하는 의무의 파일 경로와 제목을 함께 적는다. 출처의 식별자가 서로 어긋난 상태에서도 읽는 사람이 의무 문장을 찾아갈 수 있어야 한다.
각 PHASE 문서의 Annex G는 시험 자료의 형태를 정한다. 모든 규범적 요구사항에는 최소 하나의 양성 벡터와 최소 하나의 음성 벡터가 있고, 벡터는 tests/phase-vectors/<phase>/ 아래에 두며, 적합성을 주장하는 구현은 모든 벡터를 CI에서 실행하고 그 결과 통과/실패 행렬을 준수 패키지에 공표한다. 실무에서 가장 큰 일을 하는 규칙도 이 부속서에 있다. 음성 결과를 양성 결과와 동일한 충실도로 보고해야 하며, 사유가 기록되지 않은 채 건너뛴 시험은 감사인에게 실패로 간주된다는 것이다.
시작 전에 솔직히 밝힐 점이 하나 있다. 공표된 트리에는 벡터 디렉터리가 없다. Annex G가 정한 것은 위치와 관행이며 내용이 아니므로, 벡터는 구현자가 직접 써야 한다. 이는 기다리면 해결되는 결함이 아니라 해야 할 일 자체다. 또한 행렬의 의미는 그것이 키로 삼는 등록부의 품질을 넘지 못하므로, §7.1이 먼저 온다.
벡터는 작고 자족적인 파일이다. 식별자, 그것이 시험하는 등록부 키, 극성, 입력 레코드, 그리고 구현이 내야 하는 결과가 들어간다. 음성 벡터의 결과는 단순한 “실패”가 아니다. 오류 코드와, 구현이 필드 경로를 보고한다면 그 경로까지 지정한다. 서비스가 죽어서 통과한 음성 벡터는 아무것도 알려주지 않는다.
입력 레코드에는 두 가지 규율이 적용된다. 첫째, 합성 데이터다. 운영 중인 프로토콜 레코드를 벡터의 씨앗으로 쓰지 않는다. 공표할 파일에 실제 신원과 기관 맥락을 끌고 들어가며, 원본 레코드가 개정되면 벡터가 발밑에서 바뀐다. 둘째, 자리표시 값은 자리표시로 보이게 쓴다. 명세서의 예시 문서는 예시용 유전자·좌표·파라미터 값을 쓰는데, 표시를 고치지 않고 벡터 고정값으로 재사용하면 그것을 권장 설정으로 오해한 구현자가 실제 레코드에 복사해 넣는다. 제3장도 주석 달린 예시 문서에 같은 규칙을 적용한다.
{
"vector_id": "KU-V-0142-neg",
"requirement": "KU-REQ-0142",
"requirement_text": "참조된 승인 레코드가 존재하고 유효기간 내일 때에만 실행 기록을 받아들여야 한다.",
"source": "spec/WIA-BIO-014-v1.0.md#9.2.2 (정책 계층, 제5장 참조)",
"polarity": "negative",
"fixture_provenance": "synthetic; 실데이터 미사용",
"input": {
"protocol_id": "PLACEHOLDER-PROTOCOL-0001",
"version": "2",
"state_transition": { "from": "approved", "to": "in_execution" },
"safety": {
"ethics_approval": false,
"approval_refs": [
{
"approval_id": "PLACEHOLDER-IRB-0001",
"body_type": "IRB",
"issuing_body": "PLACEHOLDER 기관생명윤리위원회",
"expires_at": "2026-01-31T23:59:59Z"
}
]
},
"requested_at": "2026-03-04T09:12:00Z"
},
"expect": {
"accepted": false,
"error_code": "C006",
"error_path": "/safety/approval_refs/0/expires_at",
"audit_event_written": true
}
}
마지막 기대값을 보아야 한다. 거절 자체도 기록할 가치가 있는 사건이며, 벡터는 그 사실을 고정해 두는 가장 값싼 자리다. 호출자가 거절당했고, 그 거절이 추적에 남아 있다. 추적의 구조는 제5장이 다루며, 여기서는 시험의 단언 하나일 뿐이다.
통과/실패 행렬은 심사자가 가장 먼저 여는 산출물이다. 기계 판독 가능한 형태로, 벡터당 한 행으로, 그 행을 재현할 수 있을 만큼의 이력과 함께 공표한다. 즉 등록부 키, 벡터 id, 극성, 결과, 건너뜀 사유, 빌드 신원, 실행 환경, 시각이다. 같은 데이터를 사람이 읽기 쉽게 렌더링하는 것은 환영하지만, 스크린샷이나 PDF 표는 아니다. 분기 간 차이를 비교할 수 없기 때문이다.
{
"matrix_version": "1",
"object": { "service": "protocol-registry", "build": "2026.03.0+b7419", "sdk": "@wia/bio-014@1.0.0" },
"criteria": { "standard": "WIA-BIO-014", "standard_version": "1.0", "register": "KU-REG-2026-03" },
"runner": { "ci": "self-hosted", "os": "linux", "node": "20.x", "started": "2026-03-04T02:11:07Z" },
"totals": { "vectors": 148, "passed": 146, "failed": 1, "skipped": 1 },
"rows": [
{ "requirement": "KU-REQ-0142", "vector": "KU-V-0142-pos", "polarity": "positive", "result": "pass" },
{ "requirement": "KU-REQ-0142", "vector": "KU-V-0142-neg", "polarity": "negative", "result": "pass" },
{ "requirement": "KU-REQ-0207", "vector": "KU-V-0207-neg", "polarity": "negative", "result": "fail",
"note": "등록부가 기대한 C007 대신 C010으로 거절; 결함 KU-2026-31 미해결" },
{ "requirement": "KU-REQ-0311", "vector": "KU-V-0311-pos", "polarity": "positive", "result": "skip",
"justification": "CI 환경에 필드 단위 암호화 미적용; 분기 스테이징 행렬에 실행 기록" }
]
}
위 예시의 합계는 어느 한 번의 예시 실행에서 나온 수치이며 목표치가 아니다. 벡터 개수에 정답은 없고, 개수가 많다는 것만으로는 아무것도 입증되지 않는다. 커버리지는 등록부를 기준으로 측정되며, 그래서 행렬이 등록부 판번호를 인용한다. 실패 행은 의도적으로 남겨 두었다. 분기가 거듭되도록 실패가 하나도 없는 행렬은 실패가 고쳐진 것이 아니라 지워진 것이라는 의심을 부른다. 실패와 함께 미해결 결함 번호를 공표하는 것이 백지 행렬보다 프로그램이 작동한다는 더 강한 증거다.
Annex G가 사유 없는 건너뜀을 실패와 동등하게 취급하므로, 건너뜀 경로에는 선의가 아니라 기계 장치가 필요하다. 시험 실행기는 사유 문자열 없이 건너뜀을 기록할 수 없어야 하고, CI 게이트는 사유 없는 건너뜀이 하나라도 있으면 빌드를 실패시켜야 한다. 사유는 다른 발견 사항과 똑같이 검토한다. 여러 주기에 걸쳐 반복되는 건너뜀은 프로그램이 책임져야 할 환경 격차이며, 시험 로그에 숨는 대신 프로파일 매니페스트에 partial 상태로 올라가야 한다.
Annex G는 패키지를 구체적으로 정의한다. CycloneDX 1.5 또는 SPDX 2.3 형식의 소프트웨어 자재명세서, OpenAPI 문서, 시험 벡터 행렬, 서명된 매니페스트를 담은 tarball이며, 서명은 Sigstore를 쓴다. 즉 DSSE 봉투와 투명성 로그 항목을 사용해, 후속 소비자가 사설 인증기관을 신뢰하지 않고도 출처를 검증할 수 있게 한다. 마지막 조항이 이 설계의 핵심이다. 제휴 기관이 노트북에서, 공개 인프라만으로, 우리가 무언가를 발급해 주지 않아도 패키지를 확인할 수 있다는 뜻이다.
| 산출물 | 형식 | 생성 주체 | 서명자 | 갱신 주기 |
|---|---|---|---|---|
| 소프트웨어 자재명세서(SBOM) | CycloneDX 1.5 또는 SPDX 2.3 | 빌드 파이프라인(배포 산출물에서 생성) | 릴리스 서명 신원 | 매 빌드 |
| OpenAPI 문서 | OpenAPI 3.0 | 서비스(실제 라우트에서 생성) | SBOM과 동일 신원 | 매 빌드 |
| 시험 벡터 행렬 | JSON(§7.2) | CI 벡터 실행 | 동일 신원 | 매 CI 실행, 분기 공표 |
| 요구사항 등록부 | JSON 또는 CSV(판번호 부여) | 준수 책임자 | 동일 신원 | 표준·범위 변경 시 |
| 프로파일 매니페스트 | JSON(§7.4) | 준수 책임자 | SBOM과 동일 키(Annex I) | 범위·토폴로지 변경 시 |
| 증거 매니페스트(루트) | JSON, DSSE 봉투 | 릴리스 파이프라인 | 릴리스 서명 신원, 로그 항목 기록 | 매 패키지 |
| 오류예산 요약 | JSON(Annex E 보고 항목) | 운영 | 운영 책임자 | 월간(Annex E) |
| 선언서 | 서명 문서, ISO/IEC 17050-1 형식 | 지명된 서명자 | 서명자 | 패키지 공표 시마다 |
매니페스트는 구성 파일 각각의 암호학적 다이제스트로 패키지를 묶는다. 파일명으로 묶지 않는다. 파일명은 손쉽게 바꿀 수 있지만 다이제스트는 그렇지 않다. 재생성 후에도 다이제스트가 같아야 하는 JSON 구성원은 해싱 전에 정규화한다. RFC 8785(JSON Canonicalization Scheme)가 키 순서와 수 표기를 고정해, 의미가 같은 문서가 같은 다이제스트를 내게 한다. 다이제스트는 SHA-256을 쓰고, 모든 시각은 RFC 3339의 UTC 순간으로 표기하며, 다이제스트 알고리즘을 명시해 훗날 읽는 사람이 추측하지 않게 한다.
{
"manifest_version": "1",
"claim": {
"type": "first-party declaration",
"standard": "WIA-BIO-014",
"standard_version": "1.0",
"object": { "service": "protocol-registry", "build": "2026.03.0+b7419" },
"claimant": { "organization": "PLACEHOLDER 대학교", "signatory_role": "연구데이터 책임자" },
"topology": "single-tenant edge",
"issued": "2026-03-04T10:00:00Z"
},
"digest_algorithm": "sha256",
"subjects": [
{ "path": "sbom.cdx.json", "sha256": "PLACEHOLDER_DIGEST_01", "media_type": "application/vnd.cyclonedx+json" },
{ "path": "openapi.json", "sha256": "PLACEHOLDER_DIGEST_02", "media_type": "application/json" },
{ "path": "vector-matrix.json", "sha256": "PLACEHOLDER_DIGEST_03", "canonicalization": "RFC8785" },
{ "path": "requirement-register.json", "sha256": "PLACEHOLDER_DIGEST_04", "canonicalization": "RFC8785" },
{ "path": "profile-manifest.json","sha256": "PLACEHOLDER_DIGEST_05", "canonicalization": "RFC8785" },
{ "path": "declaration.pdf", "sha256": "PLACEHOLDER_DIGEST_06", "media_type": "application/pdf" }
],
"signature": {
"envelope": "DSSE",
"payload_type": "application/vnd.wia.bio014.evidence+json",
"transparency_log": { "kind": "rekor", "entry": "PLACEHOLDER_LOG_INDEX" }
}
}
패키지는 검증이 기계적일 때에만 쓸모가 있다. 수령 기관은 우리에게 연락하지 않고 다섯 단계를 수행할 수 있어야 한다. DSSE 서명을 검증하고 투명성 로그 항목을 확인한다. 모든 구성원 다이제스트를 재계산해 비교한다. 프로파일 매니페스트를 읽고, 행렬이 양성·음성 벡터 통과로 뒷받침하지 않는 supported 상태는 거부한다. 등록부를 읽어 주장된 요구사항이 실제로 무엇을 말하는지 확인한다. SBOM을 읽어 그 구성요소가 주장에 명시된 빌드와 일치하는지 본다. 전송 문제는 제6장이 다루는데, 에어갭 사이트에서는 같은 패키지가 대역 외 경로로 이동한다. 검증 절차가 우리 시스템에 대한 네트워크 접근을 전혀 요구하지 않도록 설계된 이유가 바로 그것이다.
Annex I는 부분 적합이 완전 적합으로 위장하지 못하게 하는 기제를 제공한다. 모든 구현은 JSON 프로파일 매니페스트를 공표해, 만족하는 요구사항(status: "supported"), 부분 만족하는 요구사항(status: "partial", 사유 포함), 제외하는 요구사항(status: "excluded", 정당화 포함)을 열거하고, SBOM에 쓴 것과 같은 키로 서명한다. 연합 배치는 구성원 프로파일의 합집합과 교집합을 요약한 집계 매니페스트를 공표하며, 디렉터리 서비스가 이를 소비해 호출자가 상호작용에 필요한 최소공통 프로파일로 경로를 잡게 한다. 프로파일 이름은 Annex H의 시맨틱 버저닝 규칙에 따라 판번호를 갖는데, 부속서 자신의 예시는 WIA-P1-DATA-FORMAT-Edge-only/2다. 끝의 숫자는 프로파일의 주 버전이며 배치 순번이 아니다. 레지스트리 항목은 불변이다. 새로운 배치 형태는 기존 항목을 수정하는 대신 새 이름을 받는다.
Annex I는 무엇이 supported 상태를 얻게 하는지 말하지 않으므로, 기관이 그것을 정하고 파이프라인에서 강제한다. 어떤 요구사항이 supported로 표시될 수 있는 것은, 함께 제출된 행렬이 인용하는 그 실행에서 해당 요구사항의 양성 벡터와 음성 벡터가 각각 최소 하나씩 통과했을 때뿐이다. 그 밖의 경우는 사유를 붙인 partial이거나 정당화를 붙인 excluded다. 행렬 옆에서 손으로 편집하는 대신 행렬로부터 생성한 매니페스트는 증거와 어긋날 수 없다.
{
"profile": { "name": "PLACEHOLDER-UNIV-Registry-Edge", "profile_version": "1",
"standard": "WIA-BIO-014", "standard_version": "1.0",
"register": "KU-REG-2026-03", "matrix": "sha256:PLACEHOLDER_DIGEST_03" },
"topology": "single-tenant edge",
"requirements": [
{ "id": "KU-REQ-0101", "summary": "정본 프로토콜 JSON이 공표 스키마를 통과한다",
"status": "supported", "vectors": ["KU-V-0101-pos", "KU-V-0101-neg"] },
{ "id": "KU-REQ-0142", "summary": "유효한 승인 참조 없이는 실행 기록이 차단된다",
"status": "supported", "vectors": ["KU-V-0142-pos", "KU-V-0142-neg"] },
{ "id": "KU-REQ-0207", "summary": "전달 봉투 형식 오류에 등록된 오류 코드를 반환한다",
"status": "partial", "reason": "등록부가 기대한 C007 대신 C010 반환; 결함 KU-2026-31",
"vectors": ["KU-V-0207-neg"] },
{ "id": "KU-REQ-0311", "summary": "제한 필드에 대한 필드 단위 접근 제한",
"status": "partial", "reason": "운영에서는 강제하나 CI에서 미실행; 행렬의 건너뜀 사유 참조" },
{ "id": "KU-REQ-0420", "summary": "기관 간 교환 엔드포인트",
"status": "excluded", "justification": "교환 상대가 구성되지 않아 엔드포인트 미배포" }
],
"signature": { "envelope": "DSSE", "key_identity": "sbom.cdx.json과 동일한 릴리스 신원",
"transparency_log": { "kind": "rekor", "entry": "PLACEHOLDER_LOG_INDEX" } }
}
연합에서 두 집계는 서로 다른 질문에 답한다. 합집합은 어떤 기능이 망 안 어딘가에 존재한다는 뜻이며, 계획을 세우거나 그 기능을 제공할 수 있는 한 구성원에게 요청을 보낼 때 쓸모가 있다. 교집합은 모든 구성원이 만족하는 것을 뜻하며, 기관 간 업무 흐름이 가정해도 되는 유일한 집계다. 이 둘을 혼동하는 것이 제6장에서 설계한 교환이 가장 역량이 낮은 상대에서 깨지는 방식이다. 보내는 쪽이 합집합 매니페스트를 보증으로 읽은 것이다. 집계 매니페스트는 디렉터리 서비스가 서명하고, 각 구성원은 여전히 자기 매니페스트에 서명한다. 그래서 읽는 사람은 그것이 누구의 진술인지 언제나 구별할 수 있다.
Annex I는 이전 매니페스트도 보존한다. 배치가 더 넓은 프로파일로 이전할 때 이전 매니페스트는 폐기 유예 기간 동안 유효하고 서명된 상태로 남아, 작년의 교환을 검토하는 감사인이 당시 무엇이 주장됐는지 볼 수 있다. 매니페스트는 제3장이 레코드를 다루는 방식대로 다룬다. 즉 추가적이고 판번호를 갖되, 제자리에서 고치지 않는다. Annex J는 방아쇠를 하나 더 더한다. 토폴로지 변경은 새 매니페스트 서명으로 반영해야 한다. 코드가 그대로라도 배치의 격리 성질과 증거 전송 성질이 바뀌었기 때문이다.
주장은 상하는 산출물이다. 부속서들은 두 개의 주기와 하나의 보고 의무로 이를 대비하는데, 첫 번째의 이유는 대부분의 엔지니어링 팀에게 직관에 반하므로 분명히 적을 값이 있다. Annex G는 원본 변경이 없더라도 매 분기 증거 패키지를 다시 공표하도록 요구한다. 소비자가 벤더 변경이력을 뒤지지 않고도 환경 표류, 즉 컴파일러·의존성·운영체제 갱신을 감지할 수 있게 하기 위해서다. 주장의 대상은 소스 트리가 아니라 돌아가고 있는 시스템이며, 돌아가는 시스템은 코드가 그대로여도 발밑이 바뀐다.
Annex E는 운영 쪽 절반을 더한다. 구현은 월간 오류예산 요약, 즉 95백분위 지연시간·오류율·위반 시간을 WIA 보고 프로파일이 정한 형식으로 공표해야 하며, 그래야 테넌트 고유 정보를 노출하지 않고 벤더를 비교할 수 있다. 이 책의 나머지와 같은 태도로 한 가지 단서를 붙인다. 그 보고 프로파일 문서 역시 트리에 공표돼 있지 않다. 명시된 세 항목을 공표하고, 추가 항목은 기관이 정의하되 기관 정의임을 표시해, 읽는 사람이 우리의 확장을 표준의 것으로 오해하지 않게 한다.
| 의무 | 주기 | 출처 | 생성 산출물 |
|---|---|---|---|
| 전체 벡터 실행 | 매 CI 실행 | Annex G | 벡터 행렬 |
| 증거 패키지 재공표 | 분기마다, 변경 유무와 무관 | Annex G | 새 다이제스트를 담은 서명 패키지 |
| 오류예산 요약 | 월간 | Annex E | 운영 보고서 |
| 프로파일 매니페스트 재서명 | 범위·토폴로지 변경 시 | Annex I, Annex J | 새 매니페스트(이전 것 보존) |
| 요구사항 등록부 검토 | 표준 부버전 갱신마다 | Annex H | 새 등록부 판과 대응표 |
| 벤더 간 크로스워크 갱신 | 인접 제도가 개정될 때 | Annex G | 갱신된 크로스워크 표 |
| 판번호–빌드 변경이력 공표 | 매 릴리스 | Annex H | 버전-빌드 변경이력 |
Annex H는 작업반이 Semantic Versioning 2.0.0을 따를 것을 약속한다. 규범적 요구사항의 하위 비호환 변경은 주버전 상승, 기존 구현을 깨지 않는 새 요구사항은 부버전 상승, 편집적 변경만 있을 때는 패치 상승이다. 폐기된 주버전은 12개월 일몰 기간에 들어가 레지스트리에 폐기로 표시되고, 그 항목에는 무엇이 해당 요구사항을 대체했으며 왜 바뀌었는지를 설명하는 이전 안내가 붙는다. 편집적 정오표는 폐기 유예 없이 패치 수준으로 발행되어 공개 정오표 등록부에 추적되며, 각 항목은 작업반 의장이 서명한다. 또한 구현은 지원하는 각 표준 판을 그것을 충족하는 특정 빌드·컨테이너 다이제스트·SDK 판에 대응시키는 변경이력을 공표해야 한다. 감사인이 우리 행렬 전체를 다시 돌리지 않고도 판 적합성을 확인할 수 있게 하는 것이 바로 이 대응표다.
두 부속서 사이에 구현자가 해결해야 하는 충돌이 있다. Annex F는 하위 비호환 변경 시 WIA 공표 참조 구현에서 “이전 주버전과 최소 90일의 중첩”을 요구한다고 적고, Annex H는 이전 주버전을 “최소 180일” 병행 유지한다고 적는다. 둘 다 비규범이다. 안전한 독법은 더 긴 기간을 지키고, 어느 부속서를 따랐으며 왜 그랬는지를 자체 정책에 기록하는 것이다. 이 불일치를 발견한 감사인은 우리가 조용히 편한 숫자를 고른 것이 아니라 그 차이를 인지했다는 사실을 보고 싶어 한다.
크로스워크에는 한 가지 주의가 필요하다. Annex G의 벤더 간 크로스워크는 대응 항목이 존재하는 경우 각 벡터를 인접 산업 제도의 동등한 단언에 대응시켜, 이미 다른 제도에서 인증받은 구현자가 적은 추가 노력으로 적합성을 보일 수 있게 한다. 이는 실질적인 절감이지만 동등성 역시 다른 모든 것과 마찬가지로 하나의 주장이다. 크로스워크 항목을 인용하고, 크로스워크가 정확히 그렇게 말하지 않는 한 다른 제도의 인증서가 WIA 요구사항을 충족한다고 진술하지 않는다.
아래 체크리스트는 각 항목이 산출물을 남기도록 의도적으로 설계했다. 흔적 없이 통과할 수 있는 항목은 통제가 아니라 의견이다. 최초 공표 전에 한 번, 이후 분기 재공표 전마다 다시 수행하고, 완료된 체크리스트를 패키지 안에 넣는다.
| # | 항목 | 통과의 의미 | 남는 증거 |
|---|---|---|---|
| 1 | 스키마 검증 | 정본 문서가 통과하고, JSON↔SDK 필드 대응표가 공표돼 있다(3장) | 양성·음성 스키마 벡터 |
| 2 | 식별자 불변성 | 수정이 새 판을 만들고, 제자리 편집은 거절된다 | 음성 벡터와 감사 이벤트 2건 |
| 3 | 오류 코드 커버리지 | 등록부의 모든 코드가 도달 가능하고 단언되며, 명세서와 SDK의 코드 개수 차이가 문서화돼 있다(4장) | 코드별 음성 벡터 1건 |
| 4 | 감사 추적 완전성 | 변경을 일으키는 모든 호출이 행위자·필드·이전값·새값·권한·시각을 기록하고, 해시 체인이 끝까지 검증된다(5장) | 체인 검증 보고서 |
| 5 | 승인 게이트 강제 | 참조된 승인이 없거나 만료된 경우 실행 단계로의 전이가 거절된다 | 합성 만료 승인을 쓴 음성 벡터 |
| 6 | 접근제어 강제 | 각 역할에 대해 허용되는 것뿐 아니라 허용되지 않는 것도 시험한다(6장) | 음성 사례를 포함한 역할×권한 행렬 |
| 7 | 보존 기간 설정 | 보존 기간이 설정돼 있고, 더 엄격한 지역 규칙 우선 원칙이 문서화돼 있다(5장) | 설정 발췌와 정책 참조 |
| 8 | 매니페스트 서명 | DSSE가 검증되고, 투명성 로그 항목이 조회되며, 모든 구성원 다이제스트가 재계산된다 | 검증 기록 |
| 9 | 프로파일 정직성 | 두 벡터 없이 supported가 없고, 매니페스트가 행렬로부터 생성된다 | 생성된 매니페스트와 생성기 로그 |
| 10 | 레코드 위생 | 가명 식별자 외의 개인 식별 정보가 없고, 원시 시퀀싱 파일이 레코드 저장소에 복제되지 않는다(6장) | 필드 단위 점검 보고서 |
| 11 | SBOM 신선도 | SBOM이 실제 배포된 빌드를 다이제스트로 기술한다 | SBOM 다이제스트와 릴리스 다이제스트 대조 |
| 12 | 시각 규율 | 시각은 서버가 부여하고 시계가 동기화돼 감사 이벤트를 순서화할 수 있다(5장) | 시각 출처 설정 기록 |
| 13 | 건너뜀 사유 게이트 | 사유가 기록되지 않은 건너뜀이 있으면 CI가 실패한다 | CI 정책 파일과 실패 실행 예 |
| 14 | 주장 문구 | 공표 문구가 제1자 선언임을 밝히고, 어디에도 등급·수준 명칭이 없다 | 선언서와 홍보 문구 검토 메모 |
구조만 검사하는 검증기를 인증하는 것. 이 장 전체에서 가장 흔한 실패는 벡터가 전부 스키마 벡터인 프로그램이다. 구조적 유효성은 가장 값싸고 가장 재미없는 계층이다. 문서는 완벽히 형식에 맞으면서도 어떤 위원회도 승인하지 않은 실행을 기술할 수 있다. 정책 요구사항, 즉 승인이 존재하고 유효한지, 상태 전이가 적법한지, 행위자에게 권한이 있는지는 각자의 벡터가 필요하며, 심사자가 가장 먼저 묻는 것이 그쪽이다.
어떤 코드도 수행하지 않는 정책 검사에 supported를 주장하는 매니페스트. 앞 함정의 서류판 쌍둥이이며, 격차가 아니라 허위 진술이므로 더 나쁘다. 행렬로부터 매니페스트를 생성하면 이 가능성이 기계적으로 사라진다.
낡은 자재명세서. 배포 산출물이 아니라 저장소에서 생성한 SBOM은 며칠 만에 어긋나며, 동작을 바꾼 의존성 갱신이야말로 분기 재공표가 드러내려는 대상이다. SBOM을 빌드 다이제스트에 묶고, 사람이 아니라 파이프라인이 생성하게 한다.
구현에서 뽑아낸 벡터. 서비스를 돌려서 기대 출력을 캡처한 벡터는 시험이 아니라 스냅숏이다. 구현이 틀렸을 때를 포함해 언제까지나 구현과 일치한다. 기대값은 요구사항 문장에서 먼저 쓰고, 그다음에 서비스를 돌린다.
음성 벡터를 선택 사항으로 다루는 것. 일정에 쫓기는 팀이 가장 먼저 버리는 것이 음성 쪽 절반이다. 중복처럼 느껴지기 때문이다. 그러나 시스템이 거절해야 할 것을 거절한다는 사실을 입증하는 절반이 그쪽이며, Annex G의 충실도 규칙이 존재하는 이유가 바로 음성 결과가 조용히 사라지기 때문이다.
서명 키 하나, 사람 한 명, 교체 계획 없음. 패키지 전체가 서명 하나에 얹혀 있다. 누가 키를 보관하는지, 교체를 어떻게 알리는지, 교체 후에도 이전 서명이 검증 가능하게 유지되는지, 서명자가 기관을 떠나면 어떻게 하는지를 미리 정한다. 투명성 로그 항목이 여기서 도움이 된다. 서명이 언제 이루어졌는지를 고정해 주므로, 키 교체 이후의 검증을 판정할 수 있게 한다.
읽을 수 없는 형태로 증거를 공표하는 것. 스크린샷으로 낸 행렬, 슬라이드에 담긴 등록부, 메일 본문에 붙여 넣은 매니페스트는 각각 그 형식이 의도한 기계적 검증을 무력화한다. 기계 판독을 먼저, 사람용 렌더링을 나중에 한다.
등급 표현이 슬며시 되살아나는 것. 등급은 상업적으로 매력적이므로, 기술팀이 지운 뒤에도 제품 소개와 과제 신청서에 한참 뒤까지 다시 나타난다. 문구 점검을 체크리스트(항목 14)에 넣고, 재발은 오타가 아니라 발견 사항으로 다룬다.
WIA-BIO-014 v1.0에서 적합성은 산출물로 뒷받침되는 제1자 선언이며, 인증서도 등급도 아니다. 이 장의 순서가 방법 전체다. 실제로 인용 가능한 출처에서 요구사항 등록부를 만든다. 등록부 항목마다 양성·음성 벡터를 쓴다. CI에서 실행하고, 실패와 사유 있는 건너뜀을 그대로 남긴 행렬을 공표한다. Annex G가 정한 패키지, 즉 SBOM·OpenAPI 문서·행렬·등록부·서명 매니페스트를 정규 다이제스트와 투명성 로그 항목을 갖춘 DSSE 서명으로 묶어 조립한다. 프로파일 매니페스트를 행렬로부터 생성해 supported가 증거를 앞지를 수 없게 한다. 그리고 코드가 그대로여도 환경은 움직이므로 분기마다 다시 공표한다.
위의 모든 것을 규정하는 공표 출처의 두 가지 결함은 덮지 말고 위로 보고할 일이다. Annex A가 없으므로 어떤 적합성 등급도 채점하거나 인용할 수 없다. 그리고 PHASE 문서에는 요구사항 식별자가 없고 본문이 다른 주제의 템플릿이므로, 등록부는 기관의 자체 작업이다. 제8장은 이 둘을 누락된 생애주기 상태기계와 교환 프로파일과 함께 표준 로드맵에 올린다.
과학·실험실 안전 관련 내용: 소속 기관의 IBC/IRB 및 공식 생물안전·규제 당국(질병관리청/LMO법 소관 당국, WHO, NIH Guidelines, 해당 국가 규제기관)에 문의할 것.