Skip to content

Commit f331908

Browse files
committed
정책: 웹 머신 자산 provenance와 SBOM 고정
1 parent 553fab0 commit f331908

11 files changed

Lines changed: 702 additions & 45 deletions

File tree

mainPlan/web-machine-platform/02-phasing-and-wiring.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@
6868
- [통과] Python OS와 Linux가 같은 host API의 `boot/pause/snapshot/restore/resume/shutdown`을 사용한다.
6969
- [통과] 두 guest가 파일 쓰기와 console round trip을 완료하고 destroy 뒤 같은 값으로 복원된다.
7070
- [통과] x86 engine은 외부 주입되며 pyproc 기본 dependency는 0이다.
71-
- [부분] engine과 image 출처, version, SHA-256, 미번들 정책을 기록했다. 제품 배포 전 BIOS/image license와 SBOM 검토가 남았다.
71+
- [통과] engine/image catalog와 SPDX SBOM을 고정하고 code package의 third-party binary를 0개로 제한했다. opaque guest image의 공식 배포는 별도 compliance gate로 차단했다.
7272
- [통과] pyproc `/home/web`과 Linux가 mount한 v86 9P file을 별도 block volume으로 연결하고 guest snapshot에서 file payload를 제거했다.
7373
- [통과] request/packet mode와 permission을 engine boot 전에 구분하고 Linux eth0의 ARP/ICMP frame을 bounded packet switch에 연결했다.
7474
- [통과] browser process cold restore 뒤 snapshot MAC을 보존하고 새 packet port로 ping을 다시 왕복했다.

mainPlan/web-machine-platform/03-progress-ledger.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,3 +528,41 @@ NEXT:
528528
1. v86, BIOS, Buildroot, KolibriOS 구성물의 license provenance와 재배포 조건을 파일 단위로 확정한다.
529529
2. Web Machine package가 배포할 engine/image SBOM과 외부 asset pin 계약을 만든다.
530530
3. 배포 게이트 통과 뒤 독립 `core`, `browser`, `guest-pyproc`, `guest-v86` package로 attempts를 승격한다.
531+
532+
## 2026-07-15 - third-party binary 0개와 fixture SPDX SBOM
533+
534+
감사:
535+
536+
1. npm `v86@0.5.424`는 BSD-2-Clause를 선언하고 registry SHA-512 integrity를 제공하지만 package metadata에
537+
source `gitHead`가 없다. JS module은 declared license를 기록하고 composite WASM file은 최종 license
538+
inventory를 `NOASSERTION`으로 유지했다.
539+
2. v86 revision `2f1346b`의 BIOS script는 SeaBIOS `rel-1.16.2`를 checkout하고 고정 config로 `bios.bin`
540+
`vgabios.bin`을 만든다. 같은 directory의 `COPYING.LESSER`와 SeaBIOS 공식 문서가 LGPL-3.0을 확인한다.
541+
3. `buildroot-bzimage68.bin`은 v86 test URL과 hash만 있고 exact Buildroot revision, `.config`, package manifest,
542+
`legal-info`가 없다. Linux kernel이라는 이름만으로 root filesystem 전체 license를 확정하지 않았다.
543+
4. `kolibri.img`도 v86 test URL과 hash만 있다. KolibriOS project의 GPLv2 선언은 확인했지만 exact image revision과
544+
포함 application inventory가 없어 binary 결론은 `NOASSERTION`으로 유지했다.
545+
546+
구현:
547+
548+
1. `assetCatalog.json`을 fixture URL/hash/size, component provenance, license 결론, bundle blocker의 SSOT로 만들었다.
549+
2. `assetProvenance.mjs`가 catalog를 strict validation하고 SPDX 2.3 `fixtureSbom.json`을 결정적으로 생성·검증한다.
550+
3. `prepareAssets.mjs`의 URL/hash 중복을 제거했다. catalog와 SBOM이 다르면 download 전에 실패하고, cache와
551+
download 모두 SHA-256뿐 아니라 byte length도 검증한다.
552+
4. Node 구조 게이트가 SBOM 동기화, 모든 fixture의 `local-test-only`, opaque guest image의 `NOASSERTION`,
553+
bundle blocker 존재, git에 third-party fixture binary 0개를 강제한다.
554+
5. 자산 배포 정책을 별도 정본으로 만들었다. code package와 공식 machine image의 배포 조건을 분리했다.
555+
556+
판정:
557+
558+
1. code package는 engine constructor와 manifest만 외부 주입받고 third-party binary를 싣지 않으므로 승격 가능하다.
559+
2. test fixture hash 검증을 재배포 승인으로 오해하지 않는다. 기존 두 guest image는 local probe 외 사용을 차단한다.
560+
3. `.webmachine` signature는 publisher identity이지 license 증명이 아니다. 공식 image catalog는 SBOM digest를
561+
signed manifest에 포함하는 다음 schema와 compliance material 전까지 만들지 않는다.
562+
4. Web Machine attempts의 기술·아키텍처·code package 배포 졸업 조건은 모두 통과했다.
563+
564+
NEXT:
565+
566+
1. attempts 모듈을 독립 `core`, `browser`, `guest-pyproc`, `guest-v86` package 경계로 승격한다.
567+
2. package public index와 type contract를 만들고 deep import·third-party binary 0개를 release gate로 고정한다.
568+
3. 별도 product-image 트랙에서 재현 가능한 Buildroot recipe와 signed SBOM attachment schema를 연구한다.

mainPlan/web-machine-platform/04-clean-architecture-and-code-rules.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,10 @@ tests/attempts/webMachine/
175175
│ ├─ network/
176176
│ │ └─ ipv4EchoPeer.js
177177
│ └─ v86/
178+
│ ├─ assetCatalog.json
179+
│ ├─ assetProvenance.mjs
178180
│ ├─ config.js
181+
│ ├─ fixtureSbom.json
179182
│ ├─ prepareAssets.mjs
180183
│ └─ assets/ # hash 검증 로컬 자산, git 미추적
181184
└─ probes/ # 유일한 composition root
@@ -310,6 +313,6 @@ ownership loss, torn commit, cold restore를 검증한다.
310313
3. [통과] request/packet network 분리, permission 선거부, Linux NIC frame 왕복과 process cold reattach.
311314
4. [통과] 브라우저 프로세스 종료 뒤 IndexedDB HEAD/PREV cold reopen.
312315
5. [통과] architecture gate와 adapter contract suite.
313-
6. [대기] engine/image license와 SBOM 배포 검토.
316+
6. [통과] engine/image provenance와 SPDX SBOM 검토. code package는 third-party binary 0개, opaque guest image는 local-test-only.
314317

315318
이전에는 attempts 코드가 아무리 안정적이어도 pyproc `src/`나 public export로 복사하지 않는다.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# 05. 자산 provenance와 배포 정책
2+
3+
## 결정
4+
5+
Web Machine code package와 실행 자산을 같은 배포물로 취급하지 않는다.
6+
7+
1. `core`, `browser`, `guest-pyproc`, `guest-v86` code package에는 third-party binary를 0개만 허용한다.
8+
2. engine constructor, firmware, guest image는 composition root가 명시적으로 주입한다.
9+
3. provenance가 불완전한 binary는 hash가 맞아도 `local-test-only`다.
10+
4. 공식 `.webmachine` image 배포는 image가 포함한 OS·filesystem의 SBOM과 compliance material을 별도로 갖추기 전까지 금지한다.
11+
12+
hash는 무결성을 증명하지만 재배포 권리를 증명하지 않는다. 프로젝트 이름의 license만 알아도 exact binary에
13+
포함된 component, source revision, build config를 모르면 배포 판정은 `NOASSERTION`이다.
14+
15+
## 현재 자산 판정
16+
17+
SSOT는 [assetCatalog.json](../../tests/attempts/webMachine/fixtures/v86/assetCatalog.json), 파생 표준 산출물은
18+
[fixtureSbom.json](../../tests/attempts/webMachine/fixtures/v86/fixtureSbom.json)이다. `assetProvenance.mjs --check`
19+
두 파일의 일치를 검사하고 `npm test`가 package 미번들과 opaque guest image의 `NOASSERTION`을 강제한다.
20+
21+
| 자산 | 확인된 provenance | license 정보 | 현재 배포 판정 |
22+
|---|---|---|---|
23+
| `libv86.mjs` | npm `v86@0.5.424`, registry integrity, source repository | package declared `BSD-2-Clause` | local test만, code package는 constructor 외부 주입 |
24+
| `v86.wasm` | npm `v86@0.5.424`, registry integrity, source repository | composite binary의 최종 inventory 미검증 | local test만, package 미번들 |
25+
| `seabios.bin` | v86 `2f1346b` build script가 SeaBIOS `rel-1.16.2`와 고정 config 사용 | `LGPL-3.0-only` | 재현 build·license/source 전달물 전 local test만 |
26+
| `vgabios.bin` | 위 SeaBIOS build의 `out/vgabios.bin` | `LGPL-3.0-only` | 재현 build·license/source 전달물 전 local test만 |
27+
| `buildroot-bzimage68.bin` | v86 test URL과 SHA-256만 확인, exact revision/config 없음 | kernel·rootfs component inventory 없음 | 번들·공식 image 배포 금지 |
28+
| `kolibri.img` | v86 test URL과 SHA-256만 확인, exact image revision 없음 | KolibriOS project는 GPLv2지만 image 내용 mapping 없음 | 번들·공식 image 배포 금지 |
29+
30+
근거:
31+
32+
- v86은 [공식 저장소](https://github.com/copy/v86#license)에서 BSD-2-Clause와 별도 third-party license를 명시한다.
33+
- BIOS build recipe는 [SeaBIOS rel-1.16.2를 checkout](https://github.com/copy/v86/blob/2f1346b/bios/fetch-and-build-seabios.sh)하고
34+
같은 경로의 [LGPL-3.0 text](https://github.com/copy/v86/blob/2f1346b/bios/COPYING.LESSER)를 둔다.
35+
- v86은 guest disk를 저장소에 포함하지 않고 [별도 test URL에서 받는다](https://github.com/copy/v86#testing).
36+
- Buildroot는 제품 산출물마다 package manifest, source, license text, config를 모으는
37+
[`make legal-info`](https://buildroot.org/downloads/manual/manual.html#legal-info)를 요구한다. 현재 binary에는 이 전달물이 없다.
38+
- KolibriOS 공식 다운로드는 GPLv2를 명시하지만, 현재 고정한 `i.copy.sh` image와 exact source revision의 연결은 없다.
39+
40+
## package 경계
41+
42+
```text
43+
@web-machine/core pure code
44+
@web-machine/browser browser implementation code
45+
@web-machine/guest-pyproc adapter code, pyproc engine externally pinned
46+
@web-machine/guest-v86 adapter code, V86 constructor externally injected
47+
48+
application composition root
49+
-> engine/firmware/guest asset manifest
50+
-> provenance approval
51+
-> runtime registration
52+
```
53+
54+
`.webmachine` schema v1은 engine과 boot image를 파일에 복사하지 않는다. 다만 guest RAM snapshot과 block state는
55+
원래 OS의 executable·filesystem material을 포함할 수 있다. 사용자가 자기 환경에서 export한 file은 package가
56+
아니며, 그것을 제3자에게 배포하는 순간 별도 software distribution이 된다. trusted signature는 출처 identity를
57+
증명할 뿐 license compliance를 대신하지 않는다.
58+
59+
## 공식 machine image 배포 게이트
60+
61+
공식 Linux 또는 graphical `.webmachine` image를 배포하려면 모두 필요하다.
62+
63+
1. guest source repository와 exact revision.
64+
2. 재현 가능한 build config, patch series, compiler/toolchain pin.
65+
3. Buildroot 계열은 `make legal-info` 전체 결과와 경고 0 판정.
66+
4. firmware와 filesystem을 포함한 SPDX SBOM.
67+
5. license text, notice, corresponding source 또는 source offer 전달 경로.
68+
6. 최종 boot asset과 `.webmachine` blob의 SHA-256.
69+
7. signed image manifest가 SBOM digest와 provenance policy version을 포함하는 다음 schema.
70+
71+
이 일곱 항목 전에는 public image catalog, bundled lab, CDN mirror를 만들지 않는다. code package 승격과 이
72+
게이트를 묶지 않되, 실행 가능한 공식 image가 없는 상태를 완성된 배포 제품이라고 부르지도 않는다.

mainPlan/web-machine-platform/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ Linux eth0를 bounded packet switch에 연결해 실제 ARP/ICMP와 process cold
1717
연결했다. 새 process의 CMOS 값과 RDRAND bytes를 guest 하드웨어 끝단에서 직접 검증했다. 이동 가능한
1818
`.webmachine`은 canonical manifest와 연속 blob으로 두 OS snapshot, block, permissions, capability requirements를
1919
서명해 운반한다. 원본 storage가 없는 새 browser profile에서 trust와 전체 integrity를 확인한 뒤 두 OS를 boot
20-
없이 복원했다. 기술 완료 조건은 통과했고 독립 package 승격 전 license와 SBOM 배포 검토가 남아 있다.
20+
없이 복원했다. 기술 완료 조건과 code package의 third-party binary 0개 배포 검토는 통과했다. provenance가
21+
불완전한 guest image는 local-test-only로 봉인했으며 공식 machine image 배포는 별도 compliance gate로 남긴다.
2122

2223
## 한 문장
2324

@@ -38,6 +39,7 @@ pyproc은 실행, 프로세스, 파일, 네트워크 가상화, 권한, 머신
3839
3. [02-phasing-and-wiring.md](02-phasing-and-wiring.md) - 실험 순서, Dual-Boot 게이트, 졸업과 중단 조건.
3940
4. [03-progress-ledger.md](03-progress-ledger.md) - 결정 원장과 최신 NEXT.
4041
5. [04-clean-architecture-and-code-rules.md](04-clean-architecture-and-code-rules.md) - 최종 package 구조, 의존성 방향, 코드와 기계 게이트.
42+
6. [05-asset-distribution-policy.md](05-asset-distribution-policy.md) - engine·firmware·guest image provenance, SBOM, 미번들 정책.
4143

4244
## 완료 조건
4345

tests/attempts/webMachine/README.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,19 +72,23 @@ snapshot 보장은 숨기지 않는다.
7272
- `host/`: engine과 browser 구현을 모르는 state machine, adapter contract, snapshot envelope, machine manifest, 구조화 오류.
7373
- `browser/`: device, content-addressed generation, IndexedDB persistence, Web Lock owner coordination, signed image file과 import 조정 구현.
7474
- `adapters/`: 파일 하나당 guest adapter 하나. 같은 guest의 wire format/engine bridge만 이름 있는 하위 폴더에 두며 guest끼리는 import하지 않는다.
75-
- `fixtures/v86/`: hash 고정 자산 recipe와 manifest. binary는 미추적이다.
75+
- `fixtures/v86/`: hash·provenance·배포 blocker catalog, SPDX SBOM, 준비 recipe. binary는 미추적이다.
7676
- `probes/`: adapter와 device를 조립할 수 있는 유일한 composition root다.
7777

7878
상세 package 경계와 강행 규칙은 [클린 아키텍처 정본](../../../mainPlan/web-machine-platform/04-clean-architecture-and-code-rules.md)을 따른다.
7979

80-
v86 probe 자산은 레포에 넣지 않는다. 아래 명령이 [v86 0.5.424](https://www.npmjs.com/package/v86)
81-
module/wasm, v86 revision `2f1346b`의 BIOS, [공식 예제](https://github.com/copy/v86/blob/2f1346b/examples/serial.html)
82-
Buildroot bzImage와 [KolibriOS](https://wiki.kolibrios.org/index.php?title=Main_Page) floppy image를 내려받고
83-
SHA-256을 검증해 ignored `assets/`에 둔다. v86 package는 BSD-2-Clause, KolibriOS는 GPL 계열이지만 BIOS와
84-
guest image는 별도 구성물이므로 제품 번들 전 정확한 license와 SBOM 검토를 다시 통과해야 한다.
80+
v86 probe 자산은 레포와 package에 넣지 않는다. [assetCatalog.json](fixtures/v86/assetCatalog.json)이 URL,
81+
SHA-256, byte length, component, license 결론, bundle blocker의 SSOT다. [fixtureSbom.json](fixtures/v86/fixtureSbom.json)
82+
그 catalog에서 생성한 SPDX 2.3 문서이고 `assetProvenance.mjs --check`가 둘의 일치를 검사한다.
83+
84+
v86 npm module은 BSD-2-Clause, SeaBIOS/vgabios build는 LGPL-3.0으로 추적됐다. 기존 Buildroot와 Kolibri image는
85+
exact source revision·build config·component inventory가 없어 `NOASSERTION`, `local-test-only`다. code package는
86+
engine constructor와 asset manifest만 외부 주입받고 third-party binary를 0개로 유지한다. 상세 판정과 공식
87+
machine image 배포 조건은 [자산 배포 정책](../../../mainPlan/web-machine-platform/05-asset-distribution-policy.md)이 정본이다.
8588

8689
```bash
8790
node tests/attempts/webMachine/fixtures/v86/prepareAssets.mjs
91+
node tests/attempts/webMachine/fixtures/v86/assetProvenance.mjs --check
8892
node tests/browser/run.mjs tests/attempts/webMachine/probes/linuxGuestProbe.html
8993
node tests/browser/run.mjs tests/attempts/webMachine/probes/ownerSuccessorProbe.html
9094
node tests/browser/run.mjs tests/attempts/webMachine/probes/framebufferPointerProbe.html
@@ -98,9 +102,9 @@ file은 guest snapshot에 중복되지 않고 별도 block volume이 완료 gene
98102
IndexedDB 단조 epoch도 정상 양도와 강제 context 제거에서 통과했다. RGBA framebuffer와 relative pointer도
99103
별도 capability로 graphical guest와 process cold restore에서 통과했다. wall/monotonic clock과 cryptographic
100104
entropy도 Linux CMOS, timer, RDRAND와 process cold restore에서 통과했다. signed `.webmachine`도 새 browser
101-
profile에서 pyproc과 Linux의 snapshot·block을 boot 없이 복원했다. license와 SBOM 배포 검토가 남았으므로
102-
`src/` 또는 `index.js`로 승격하지 않는다. 승격 위치는 독립 `core`, `browser`, `guest-pyproc`,
103-
`guest-v86` package로 확정했다.
105+
profile에서 pyproc과 Linux의 snapshot·block을 boot 없이 복원했다. code package의 미번들 provenance/SBOM
106+
게이트도 통과했으므로 attempts 졸업 조건은 충족했다. 승격 위치는 독립 `core`, `browser`, `guest-pyproc`,
107+
`guest-v86` package다. 공식 guest image 배포는 별도 compliance gate 전까지 금지한다.
104108

105109
## 덕지덕지 제거 기준
106110

@@ -121,4 +125,5 @@ ICMP를 왕복하고 새 process에서 port를 다시 연결한다. VGA text fra
121125
재연결한다. owner context 제거 뒤에는 정확히 한 successor가 21-23ms에 같은 generation을 복구한다.
122126
1024x768 RGBA frame과 PS/2 pointer도 새 process에서 재연결한다. Linux CMOS와 RDRAND도 새 process의
123127
clock/entropy 공급원에 다시 연결한다. 이동 가능한 envelope도 storage identity 밖 새 profile에서 통과했다.
124-
배포 license 게이트가 남았으므로 공개 API라고 부르지 않는다.
128+
code package 승격 조건은 충족했지만 아직 attempts에 있으므로 공개 API라고 부르지 않는다. opaque guest image의
129+
공식 배포는 provenance와 compliance material이 완성될 때까지 계속 차단한다.

0 commit comments

Comments
 (0)