aboutsummaryrefslogtreecommitdiffstats
path: root/docs/research/031-relocatable-document-preview.md
blob: 602f75e5d771b6ed0198bab38a4d54aed084ac5d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 031 — 독립된 문서 앱 묶음과 저장 비용 경계

2026-09-24. Linux AArch64 첫 공개 체크포인트의 중간 결과다. 기존
[`editor.pure`](../../prototypes/connections/examples/editor.pure) 문서 앱을 새 디렉터리에서
빌드하고, 실행물·정의 파일을 하나의 선택형 묶음으로 만들었다.

## 실제로 옮겨 실행한 묶음

[`package_native.py`](../../prototypes/connections/package_native.py)는 기본 CLI·HTTP,
선택형 인증 문서 피어, 요청한 경우 GTK 창을 분리된 실행물로 담는다. 기본·피어의
코드 섹션과 직접 동적 의존성 예산을 검사한 다음, 파일 SHA-256·크기·직접 공유
라이브러리를 `manifest.json`에 기록한다. GTK·OpenSSL 라이브러리를 자체 코드의
크기에 합쳐 숨기지 않고, **시스템 라이브러리를 묶음에 포함하지 않았음**을 명시한다.

새 `build/checkpoint-clean` 디렉터리에서 `make all document-peer window`와 기본·피어
검사를 통과한 후, [Linux AArch64 시험 묶음](../../prototypes/connections/results/2026-09-24-document-peer/pure-document-linux-aarch64.tar.gz)을
생성했다. 압축 크기는 **316,927 B**다. 동일한 입력으로 두 번 생성한 파일과 결과
디렉터리에 복사한 파일의 [SHA-256](../../prototypes/connections/results/2026-09-24-document-peer/package-hashes.txt)은
모두 `dc3f7339bf5aa22b11eb5ac4c8b4a547168e0e06e65c8003a545f70a31500081`이다.
이는 같은 입력의 아카이브 재현성을 확인한 것이며, 다른 도구 버전에서 실행물까지
같아진다는 뜻은 아니다.

[`check_package.py`](../../prototypes/connections/check_package.py)는 압축을 별도 임시
디렉터리에 풀어 [검증 결과](../../prototypes/connections/results/2026-09-24-document-peer/package-check.json)를
남겼다. 파일 목록·해시를 확인하고 묶음 속 CLI로 문서를 생성·복원했다. 복사한 `.pure`
정의의 `reply(saved, edit.insert)`를 `reply(saved)`로 바꾸자 실제 결과 본문 길이가
10 B에서 0 B로 바뀌었다. 묶음 속 인증 피어와 일반 Python TLS 클라이언트가
1 MiB 문서를 교환했고, 묶음 속 GTK 창·CLI·HTTP가 같은 문서의 변경·충돌·저장을
다시 통과했다. 처음 Xvfb 검사에서 창이 표시되기 전 포커스 시도가 실패해, 창 포커스를
제한된 횟수로 다시 시도하도록 검사기를 수정한 뒤 통과했다.

이는 **Linux AArch64 호스트에서 선택한 실용 앱이 이동해 실행된다**는 증거다.
정적 실행물, macOS 묶음, 시스템 공유 라이브러리의 재배포, 소스 설치형 패키지,
서명·릴리스 라이선스까지 해결됐다는 주장은 아니다. GTK 창의 44 MiB RSS도 압축
파일 크기로 사라지지 않는다.

## 작은 편집의 저장 비용은 그대로 남는다

현재 [`store.c`](../../prototypes/connections/store.c)의 `mutate`는 크기가 변하지 않는
교체에도 새로운 파일에 24 B 헤더, 유지할 앞부분, 삽입 바이트, 유지할 뒷부분을 순서대로
기록하고 `fsync`한 뒤 이름을 교체한다. 따라서 1 MiB 문서의 마지막 한 바이트를 바꿀 때
이 경로의 **사용자 공간 파일 쓰기 요청 길이 합계는 1,048,600 B**다
(1,048,576 B 문서 + 24 B 헤더). 이는 실제 저장 장치의 물리적 쓰기량과 같다는
주장이 아니다. 결과 수명은 기존 파일의 읽기 전용 매핑과 새 파일 교체로 분리한다.

이 비용을 `copy_file_range` 같은 복사 호출로 바꾸는 것만으로 새 파일의 전체 본문
기록이 사라지지는 않는다. 또 현재 읽기 계약은 단일 연속 `PureSpan`이다. 델타나
불변 조각으로 작은 변경만 기록하려면 읽을 때 다시 연속 버퍼를 조립하거나, 소비자가
범위·조각을 직접 받도록 결과 표현을 바꾸어야 한다는 것이 **현재 코드에서의 추론**이다.
다음 저장 실험은 버전별 읽기 안정성, 공개 전후 실패, 충돌과 전체 앱 메모리를 그대로
유지하면서 작은 편집의 실제 쓰기량을 줄여야 한다. 지금 구현을 이미 저쓰기량 저장소로
소개하지 않는다.