diff options
| -rw-r--r-- | .github/workflows/native-linux-4k-page-store.yml | 17 | ||||
| -rw-r--r-- | .github/workflows/native-macos-arm64.yml | 7 | ||||
| -rw-r--r-- | CHECKPOINT.md | 5 | ||||
| -rw-r--r-- | README.md | 8 | ||||
| -rw-r--r-- | docs/research/071-logical-page-portability.md | 36 | ||||
| -rw-r--r-- | prototypes/connections/Makefile | 8 | ||||
| -rw-r--r-- | prototypes/connections/README.md | 4 | ||||
| -rw-r--r-- | prototypes/connections/SOURCE_PREVIEW.md | 2 | ||||
| -rw-r--r-- | prototypes/connections/results/2026-09-24-logical-page/hybrid-package-check.json | 15 | ||||
| -rw-r--r-- | prototypes/connections/results/2026-09-24-logical-page/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz | bin | 0 -> 58203 bytes | |||
| -rw-r--r-- | prototypes/connections/results/2026-09-24-logical-page/pure-source-preview.tar.gz | bin | 0 -> 338384 bytes | |||
| -rw-r--r-- | prototypes/connections/results/2026-09-24-logical-page/source-package-check.json | 15 | ||||
| -rw-r--r-- | prototypes/connections/store-paged.c | 8 |
13 files changed, 117 insertions, 8 deletions
diff --git a/.github/workflows/native-linux-4k-page-store.yml b/.github/workflows/native-linux-4k-page-store.yml new file mode 100644 index 0000000..c559e46 --- /dev/null +++ b/.github/workflows/native-linux-4k-page-store.yml @@ -0,0 +1,17 @@ +name: Native Linux 4 KiB page store + +"on": + push: + pull_request: + workflow_dispatch: + +jobs: + page-store: + runs-on: ubuntu-24.04 + timeout-minutes: 20 + steps: + - uses: actions/checkout@v4 + - name: Require a real 4 KiB OS page + run: test "$(getconf PAGESIZE)" = 4096 + - name: Exercise the selected 16 KiB logical-page store + run: make -C prototypes/connections check-paged-portable diff --git a/.github/workflows/native-macos-arm64.yml b/.github/workflows/native-macos-arm64.yml index 7d46d6a..c3614be 100644 --- a/.github/workflows/native-macos-arm64.yml +++ b/.github/workflows/native-macos-arm64.yml @@ -20,7 +20,8 @@ jobs: run: | make -C prototypes/connections BUILD=build/mac-default all test -f prototypes/connections/build/mac-default/libpure-execution.a - test -x prototypes/connections/build/mac-default/pure-edit + test -x prototypes/connections/build/mac-default/pure-edit-fixed + test ! -e prototypes/connections/build/mac-default/pure-edit test ! -e prototypes/connections/build/mac-default/pure-connections test ! -e prototypes/connections/build/mac-default/pure-document-peer test ! -e prototypes/connections/build/mac-default/pure-edit-window @@ -37,6 +38,10 @@ jobs: run: | make -C prototypes/connections BUILD=build/mac-native check-policy \ POLICY_EVIDENCE="$RUNNER_TEMP/policy.json" + - name: Exercise selected logical-page storage + run: | + getconf PAGESIZE + make -C prototypes/connections check-paged-portable - name: Show whole-process results if: always() run: | diff --git a/CHECKPOINT.md b/CHECKPOINT.md index 1968c89..a5692c9 100644 --- a/CHECKPOINT.md +++ b/CHECKPOINT.md @@ -226,6 +226,11 @@ TUI의 Ctrl+S부터 저장 완료 표시까지 확인했다. 1 MiB 마지막 1 B 파서 없는 고정 정의 CLI로 제한하고 깨끗한 소스 추출에서 선택 기능이 기본 출력에 섞이지 않는지 확인했다. 링크 코드가 줄었지만 RSS 개선은 입증하지 않았다. + [071](docs/research/071-logical-page-portability.md)에서는 선택형 페이지 + 저장의 16 KiB 논리 페이지와 OS 페이지를 구분해, OS 페이지가 16 KiB를 + 나누면 초기화를 허용하도록 좁게 바꿨다. 현재 16 KiB Linux의 실제 문서· + TUI·형식 내보내기는 통과했다. 4 KiB Linux와 macOS의 CI는 작성만 했고 + 실행 결과는 아직 없다. 3. **실제 네이티브 앱과 통신.** 작성·편집·저장·복원·충돌 처리를 연결하고 자체 통신 형식과 검증된 보안 전송을 붙인다. 외부 호환 입력·출력도 유지한다. 4. **규모·실패·사용성 확인과 공개 자료.** 큰 작업물·느린 소비자·혼합 작업에서 구조가 @@ -59,8 +59,12 @@ in 93.17 ms with the default store and 22.04 ms with the selected page store (24 saves per profile). The 256 B case was 8.54 versus 9.23 ms. The selected source TUI adds 4,958 B linked `text`; its [CLI+TUI archive](prototypes/connections/results/2026-09-24-native-save/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz) is 57,788 B compressed and passed a relocated app check. Large documents use -an incompatible on-disk page format, so this remains an opt-in Linux/16 KiB-page -research profile; the default core and storage path are unchanged. +an incompatible on-disk page format, so this remains an opt-in Linux storage +research profile. Its 16 KiB logical pages now admit OS page sizes that divide +16 KiB, but only the 16 KiB host has passed the real storage suite so far; +the default core and storage path are unchanged. The +[alignment and verification boundary](docs/research/071-logical-page-portability.md) +records the 32 B selected-code cost and the unrun 4 KiB/macOS checks. The current execution profile has separate `core`, `fixed-editor`, `editor`, and `server` build targets. `make all` produces the core and the parser-free CLI diff --git a/docs/research/071-logical-page-portability.md b/docs/research/071-logical-page-portability.md new file mode 100644 index 0000000..a664432 --- /dev/null +++ b/docs/research/071-logical-page-portability.md @@ -0,0 +1,36 @@ +# 071 — 논리 페이지와 OS 페이지의 경계 + +2026-09-24. 선택형 페이지 저장소는 16 KiB **논리** 페이지로 파일 참조를 +기록하지만, 초기화에서는 OS 페이지 크기도 정확히 16 KiB인지 요구했다. +메모리 매핑의 파일 오프셋과 `MAP_FIXED` 주소는 모두 논리 페이지의 배수다. +[Linux `mmap(2)`](https://man7.org/linux/man-pages/man2/mmap.2.html)과 +[Apple `mmap(2)`](https://developer.apple.com/library/archive/documentation/System/Conceptual/ManPages_iPhoneOS/man2/mmap.2.html)의 +페이지 정렬 계약에 따르면, OS 페이지가 16 KiB를 나누면 이 오프셋과 주소는 +OS 페이지에도 정렬된다. 이것은 문서에서 코드의 정렬 조건으로 도출한 +**추론**이며, 4 KiB 호스트에서의 실제 실행 결과를 대신하지 않는다. + +`pure_store_init`은 이제 양의 OS 페이지 크기가 16 KiB를 나누는지 확인한다. +4/8/16 KiB는 받아들이고 64 KiB나 조회 실패는 거절한다. 디스크 형식과 +16 KiB 논리 페이지, 기본 저장소, 실행 코어는 바뀌지 않았다. 같은 GCC 14.2, +Linux AArch64에서 선택형 고정 CLI/HTTP의 링크 `text`는 각각 +24,582→24,614 B, 31,864→31,896 B로 **32 B씩 증가**했다. 기본 코어는 +4,632 B 그대로다. 작은 문서·1 MiB 문서·충돌·복구·재구성·형식 내보내기 +검사와 실제 TUI 조작을 현재 16 KiB OS 페이지에서 통과했다. 지연이나 RSS의 +개선을 주장하지 않는다. + +[최신 소스 묶음](../../prototypes/connections/results/2026-09-24-logical-page/pure-source-preview.tar.gz)을 +다른 디렉터리에서 빌드한 [검사 결과](../../prototypes/connections/results/2026-09-24-logical-page/source-package-check.json)는 +기본 릴리스와 선택형 페이지 TUI를 포함한다. 선택형 소스 CLI+TUI의 +[이동 묶음](../../prototypes/connections/results/2026-09-24-logical-page/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz)은 +압축 58,203 B이며 [다른 위치의 실제 문서 검사](../../prototypes/connections/results/2026-09-24-logical-page/hybrid-package-check.json)를 +통과했다. 이 묶음에는 작성 소스를 읽는 파서와 선택형 TUI도 포함되므로 +기본 코어의 크기가 아니다. + +새 `check-paged-portable`은 선택형 저장소의 C·TUI·고장 경로를 Linux 전용 +크기 검사 없이 실행한다. 기존 macOS arm64 CI의 잘못된 기본 실행물 이름도 +수정하고 이 저장소 검사를 추가했다. 별도 Linux x86_64 CI는 실제 OS 페이지가 +4 KiB임을 확인한 뒤 같은 검사를 실행하도록 작성했다. 현재 Git 원격은 +로컬 저장소이므로 **두 CI 모두 미실행**이다. 4 KiB Linux와 macOS에서 +빌드·매핑·실제 문서 수정이 통과하기 전에는 이 변경을 검증된 플랫폼 지원으로 +표기하지 않는다. 현재 저장소는 선택형이고, 큰 문서의 온디스크 형식은 +기본 저장소와 호환되지 않아 [오프라인 내보내기](062-paged-store-rollback.md)가 필요하다. diff --git a/prototypes/connections/Makefile b/prototypes/connections/Makefile index 502d359..4d4e5a2 100644 --- a/prototypes/connections/Makefile +++ b/prototypes/connections/Makefile @@ -3,7 +3,7 @@ CFLAGS ?= -O2 -g CFLAGS += -std=c17 -Wall -Wextra -Wpedantic -Werror BUILD ?= build -.PHONY: all core async-core editor fixed-editor fixed-server fixed-tui source-tui compiler mirror window server async-server document-peer document-server check check-policy check-policy-peer check-portable check-portable-tui check-portable-peer check-native-checkpoint check-mirror check-core check-async check-async-server check-async-service-scale check-profile check-fixed-profile check-fixed-server check-service-scale check-tui-profile check-source-tui-profile check-tui check-source-tui check-release check-micro-memory check-hybrid check-flat-export check-copy-range check-peer-profile check-document-server-profile check-window-profile check-document-peer check-document-server FORCE +.PHONY: all core async-core editor fixed-editor fixed-server fixed-tui source-tui compiler mirror window server async-server document-peer document-server check check-policy check-policy-peer check-portable check-portable-tui check-paged-portable check-portable-peer check-native-checkpoint check-mirror check-core check-async check-async-server check-async-service-scale check-profile check-fixed-profile check-fixed-server check-service-scale check-tui-profile check-source-tui-profile check-tui check-source-tui check-release check-micro-memory check-hybrid check-flat-export check-copy-range check-peer-profile check-document-server-profile check-window-profile check-document-peer check-document-server FORCE CORE = runtime.c STORE ?= store.c FIXED_PROGRAM ?= examples/editor.pure @@ -243,6 +243,12 @@ check-portable-tui: fixed-editor fixed-tui editor source-tui python3 check_tui.py --build $(BUILD) --portable $(if $(PORTABLE_FIXED_TUI_EVIDENCE),--output "$(PORTABLE_FIXED_TUI_EVIDENCE)") python3 check_tui.py --build $(BUILD) --source --portable $(if $(PORTABLE_SOURCE_TUI_EVIDENCE),--output "$(PORTABLE_SOURCE_TUI_EVIDENCE)") +# Exercise the selected logical-page store without Linux-only size/RSS gates. +# The CI runner separately asserts its real OS page size before this target. +check-paged-portable: + $(MAKE) BUILD=build/paged-portable STORE=store-paged.c check-portable check-portable-tui check build/paged-portable/test-paged-store + build/paged-portable/test-paged-store + # Host-native behavior plus the same real document workload on both CLI variants. # RSS is recorded on macOS and Linux; only check-micro-memory enforces the # reviewed Linux AArch64 ceiling. diff --git a/prototypes/connections/README.md b/prototypes/connections/README.md index 31b9c27..67cccd5 100644 --- a/prototypes/connections/README.md +++ b/prototypes/connections/README.md @@ -145,7 +145,9 @@ python3 prototypes/connections/export_flat_store.py \ [기본 형식으로 내보내는 검증](../../docs/research/062-paged-store-rollback.md). 같은 `.pure` 문서 편집기를 선택형 페이지 저장소와 함께 터미널에서 사용하려면 -Linux의 16 KiB OS 페이지 환경에서 새 저장 디렉터리를 지정한다. CLI와 TUI를 +새 저장 디렉터리를 지정한다. 논리 페이지는 16 KiB이며 OS 페이지가 이를 +나눌 때만 초기화한다. 현재 실제 검사는 Linux 16 KiB 환경에서만 통과했고, +4 KiB Linux와 macOS는 CI 실행 결과가 아직 없다. CLI와 TUI를 함께 담은 [선택형 묶음](results/2026-09-24-native-save/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz)은 다음 빌드로 만들며, 기본 `make all`과 기본 저장 형식은 유지된다. diff --git a/prototypes/connections/SOURCE_PREVIEW.md b/prototypes/connections/SOURCE_PREVIEW.md index 9e0d78d..a4bbfc3 100644 --- a/prototypes/connections/SOURCE_PREVIEW.md +++ b/prototypes/connections/SOURCE_PREVIEW.md @@ -72,7 +72,7 @@ Writers may receive `busy` until it finishes; schedule this as maintenance. The destination must not exist. `make -C prototypes/connections check-flat-export` exercises the conversion with real mixed-size and repeatedly edited documents. -On a Linux host with 16 KiB OS pages, the selected hybrid store can also run +On a Linux host whose OS page size divides the 16 KiB logical page, the selected hybrid store can also run the source-loaded native terminal editor without adding it to the default app: ```sh diff --git a/prototypes/connections/results/2026-09-24-logical-page/hybrid-package-check.json b/prototypes/connections/results/2026-09-24-logical-page/hybrid-package-check.json new file mode 100644 index 0000000..0162011 --- /dev/null +++ b/prototypes/connections/results/2026-09-24-logical-page/hybrid-package-check.json @@ -0,0 +1,15 @@ +{ + "archive_sha256": "649b2d5f0432f58cb9b7c36b5607a3b81d7034d678c836c9307d3a323e2340dc", + "archive_bytes": 58203, + "selected_hosts": [ + "pure-edit", + "pure-edit-tui" + ], + "checks": [ + "relocated archive has only declared files and every file hash matches", + "extracted native CLI creates and restores the real document", + "selected storage keeps small values inline and maps large values", + "editing the packaged .pure source changes the executed reply", + "relocated source-loaded TUI and CLI share UTF-8, large and many-document paths" + ] +} diff --git a/prototypes/connections/results/2026-09-24-logical-page/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz b/prototypes/connections/results/2026-09-24-logical-page/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz Binary files differnew file mode 100644 index 0000000..1f692f9 --- /dev/null +++ b/prototypes/connections/results/2026-09-24-logical-page/pure-document-hybrid-cli-tui-linux-aarch64.tar.gz diff --git a/prototypes/connections/results/2026-09-24-logical-page/pure-source-preview.tar.gz b/prototypes/connections/results/2026-09-24-logical-page/pure-source-preview.tar.gz Binary files differnew file mode 100644 index 0000000..de6dbbc --- /dev/null +++ b/prototypes/connections/results/2026-09-24-logical-page/pure-source-preview.tar.gz diff --git a/prototypes/connections/results/2026-09-24-logical-page/source-package-check.json b/prototypes/connections/results/2026-09-24-logical-page/source-package-check.json new file mode 100644 index 0000000..0b960fd --- /dev/null +++ b/prototypes/connections/results/2026-09-24-logical-page/source-package-check.json @@ -0,0 +1,15 @@ +{ + "archive_sha256": "5b01f1a4a6c4db6e405bd6eedc9f550060b67fdd4550bab35dd83f6465a326b8", + "archive_bytes": 338384, + "source_files": 173, + "checks": [ + "every extracted source file matches the manifest", + "clean default build contains only the core, parser-free CLI and its build-time compiler", + "clean C17, both real terminal PTY scenarios and fixed/source CLI document RSS checks pass", + "source-loaded CLI and parser-free CLI share the real stored document", + "editing .pure changes the native source-loaded reply", + "clean selected page store runs the source-loaded TUI and relocatable CLI+TUI package", + "clean Linux release behavior, code, dependency and RSS gates pass", + "clean source-loaded terminal editor PTY scenarios pass" + ] +} diff --git a/prototypes/connections/store-paged.c b/prototypes/connections/store-paged.c index 89c0148..137301a 100644 --- a/prototypes/connections/store-paged.c +++ b/prototypes/connections/store-paged.c @@ -11,7 +11,7 @@ #include <sys/stat.h> #include <unistd.h> -/* Selected Linux/16 KiB-page storage experiment. Small values retain the +/* Selected Linux storage experiment with 16 KiB logical pages. Small values retain the * existing PUREB001 inline file. Large roots name an append-only page * generation. Both forms expose one immutable, contiguous mapped read. */ enum { PAGE = 16384, INLINE_BYTES = 24, ROOT_BYTES = 48, @@ -167,7 +167,11 @@ static PureResult open_locked(const char *path, bool writer, int *directory, int } PureResult pure_store_init(const char *path) { - if (!path || !*path || sysconf(_SC_PAGESIZE) != PAGE) return PURE_STORE_ERROR; + long host_page = sysconf(_SC_PAGESIZE); + /* Every file offset and MAP_FIXED address uses a PAGE-sized step, so a + * smaller OS page works when its size divides the logical page. */ + if (!path || !*path || host_page <= 0 || PAGE % host_page) + return PURE_STORE_ERROR; bool created = mkdir(path, 0700) == 0; if (!created && errno != EEXIST) return PURE_STORE_ERROR; int directory = open(path, O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC); |
