# 작은 OS로 설계하는 마이크로 런타임과 실행 영역 작성일: 2026-09-23. 상태: 설계 방향. [022](../research/022-execution-core.md)에서 저장 프로필의 영역별 작업 접수·완료·대여·회수를 구현했다. 작은 OS의 통합 코어·범용 실행·샌드박스는 아직 미완료다. ## 마이크로 런타임의 크기 제약 **작은 OS라는 책임 범위와 마이크로 런타임이라는 크기 제약을 함께 지킨다.** 아래 기능 목록을 항상 포함되는 커널·서비스 목록으로 해석하지 않는다. - 공통 코어는 실제 작업에 필요한 실행 진행, 소유권·자원 한도, 접근 권한과 완료·회수 규칙에 한정한다. 사용하지 않는 기능을 위한 범용 객체·관리 계층을 미리 만들지 않는다. - 네트워크 프로토콜·저장 구현·UI·미디어·호환 기능은 앱에 필요한 구성을 선택해 결합한다. 초기 방식은 빌드 시 선택이며 동적 로더·플러그인 레지스트리를 기본 의존성으로 추가하지 않는다. 기능 지원을 그 코드·상태·백그라운드 작업의 상시 포함으로 구현하지 않는다. - 영역마다 전용 스레드·스택·소켓·큰 큐를 예약하지 않는다. 공유 가능한 준비 코드·연결은 공유하고 상태·대기 공간은 실제 수요와 명시적인 한도에 맞춘다. 유휴 풀의 보유 공간도 비용이다. - 파서·컴파일러·작성 도구를 실행 전용 구성의 필수 의존성으로 만들지 않는다. 준비된 실행에 필요 없는 소스·AST·필드 이름표를 계속 보관하지 않는다. 특수화에 따른 코드 증가도 비용에 넣는다. 코어의 코드·정적 데이터, 선택한 의존성을 포함한 배포 구성, 유휴 메모리, 영역·진행 작업별 추가 비용을 구분한다. 실제 앱의 전체 피크와 외부 버퍼도 확인한다. 작은 코어 옆의 라이브러리나 호스트로 비용을 옮긴 것으로 축소를 주장하지 않는다. 모듈을 분리했다는 사실만으로 미사용 코드·상태가 빠졌다고 보지 않고 선택한 빌드와 실행에서 확인한다. 새 코어 기능에는 현재 작업이 요구하는 이유와 더 작은 구현 가능성을 제시한다. 다음 구현의 전후 크기·메모리 차이를 확인하고 설명되지 않는 증가가 있으면 범위를 줄인다. 수치 상한은 실행 전용 코어·선택 구성·대상 기기별로 근거를 갖고 정하며 임의의 KiB 숫자를 달성치로 쓰지 않는다. 필수 권한·정확성·보안 계약을 제거해 작게 만들지 않는다. 현재 저장 프로필은 `make core`로 파서·저장·HTTP 없는 아카이브만 빌드한다. release의 `make check-core`가 코드 섹션·구조체 상한, 아카이브 구성과 외부 의존성을 검사한다. 상한 변경은 필요한 기능·더 작은 배치·전체 비용의 검토를 함께 기록한다. 현재 수치와 선택 실행물의 비용 범위는 [023](../research/023-document-edits.md)에 있다. 이 제한된 코어의 크기를 전체 앱·모든 플랫폼의 메모리 크기로 인용하지 않는다. ## Pure가 소유하는 운영 모델 **Pure 런타임 자체를 하나의 작은 OS로 설계한다.** 실행·메모리·보호·자원 수명·저장·통신의 의미와 정책을 Pure가 소유하고, 앱은 그 모델 위에서 동작한다. UI는 이 기반의 한 하위 체계다. OS 프로세스는 현재 호스트에서 구동할 때 받는 실행·보호·자원 제약이며 Pure의 기본 개념이 아니다. 앞선 설명처럼 프로세스 배치 관리에서 설계를 시작하지 않는다. 현재 호스트는 CPU 실행 기회, 메모리, 시계, 저장·통신·장치 접근을 제공한다. Pure는 제공받은 범위 안에서 어떤 작업을 실행하고, 누구에게 자원을 할당하며, 어떤 연결과 효과를 허용하고, 언제 회수할지 결정한다. 호스트의 PID·스레드·파일 디스크립터·소켓을 앱의 정체성이나 공통 실행 계약으로 노출하지 않는다. 기존 네이티브 도구의 FFI는 별도 경계다. | Pure가 정의할 정책·의미 | 플랫폼 연결부가 제공할 수단·제약 | |---|---| | 실행 가능한 작업과 스케줄링, 기한·중단 계약 | 실행 기회, 깨우기·대기·시계, 사용 가능한 중단 수단 | | 메모리 배치·소유권·대여·할당·회수와 예산 | 메모리 확보·반환·매핑·보호의 가용 기능과 실패 | | 앱·자원 식별, 접근 권한과 실행 보호 | 해당 환경이 집행할 수 있는 보호 기능과 한계 | | 내부 연결, 원격 호출과 완료·실패 의미 | 바이트·패킷 전달 수단과 실제 입출력 완료 | | 저장 배치·공개·내구성·복구 계약 | 파일·블록 등 저장 수단, 동기화 결과와 장애 | | UI 입력·배치·표시의 일관된 의미 | 창·입력·접근성·그래픽 등 환경 기능 | 이 표는 새 중간 객체를 매번 만드는 API를 요구하지 않는다. 준비된 연결에서 계약을 보존하며 불필요한 경계를 제거한다. 플랫폼이 어떤 계약을 집행하지 못하면 지원 범위로 명시한다. 호스트 밖의 메모리·CPU를 통제하거나 호스트 종료를 막는다고 주장하지 않는다. 개발은 기존 OS에서 구동하는 형태로 시작한다. 직접 하드웨어를 구동하는 경로에서도 Pure의 앱·실행 모델을 유지할 수 있도록 경계를 정하되, 드라이버·부팅 구현을 지금 완료한 것으로 취급하지 않는다. 작은 OS라는 목표를 단순한 이름 변경이나 향후 부가 기능으로 미루지 않는다. ## 외부 통신은 핵심 기능이다 Pure 외부와의 연결도 운영 모델의 일부다. Pure를 사용하지 않는 서비스·런타임·프로그램과 요청을 보내고 받을 수 있어야 한다. 작은 OS라는 설계 방향을 폐쇄된 통신 환경으로 해석하지 않는다. - Pure 내부 연결은 준비된 연산·데이터 관계를 사용한다. - Pure 간 원격 연결은 자체 형식과 보안 전송을 사용할 수 있다. - 외부 서비스와의 연결은 상대가 사용하는 프로토콜·형식·인증·완료 의미를 지원한다. HTTP(S), 기존 RPC, TCP/UDP 기반 프로토콜과 로컬 IPC 등 필요한 접점을 양방향으로 제공한다. 이는 지원 목표이며 위 프로토콜들을 모두 구현했다는 목록이 아니다. 자체 형식도 상대가 그 계약을 구현하면 Pure 외부에서 사용할 수 있어야 한다. 외부 프로그램의 내부 구조까지 Pure 실행 영역으로 옮기거나 모든 상대에게 Pure 전용 프로토콜을 강제하지 않는다. 외부 형식은 필요에 따라 검증·변환하되, 내부 데이터를 항상 외부 형식으로 보관하지 않는다. 그대로 소비할 수 있는 데이터에 불필요한 변환을 추가하지 않는다. 변환·암호화·대기·복사 비용은 전체 경로에 포함하고, 해당 프로토콜의 주소·메서드·오류 등 앱에 필요한 의미는 접점에서 제공한다. 호환성을 이유로 그 개념을 모든 Pure 내부 연결의 필수 모델로 올리지는 않는다. ## 기본 단위 **실행 영역**은 Pure 내부에서 상태·권한·수명을 귀속시키는 단위다. 기존 [메모리 계약](002-memory-lifetime.md)의 영역을 작은 OS의 운영 모델 안에서 구체화한다. 영역을 OS 프로세스의 대체 이름이나 컨테이너의 포장으로 정의하지 않는다. VM 명령 집합의 채택 여부는 이 관리 단위를 정의하는 결정과 별개다. 영역은 앱이 독립적으로 관리해야 하는 상태·권한·수명의 경계에 만든다. 함수·그래프 노드·요청마다 영역이나 메일박스를 하나씩 만들지 않는다. 첫 후보는 영역의 관리 상태를 한 제어 흐름이 변경하고, 독립 작업의 완료를 그 흐름에서 회수하는 방식이다. 영역마다 전용 OS 스레드·스택·소켓·이벤트 루프를 예약할 필요는 없다. 변경하지 않는 준비 프로그램은 공유하고, 인스턴스 상태와 사용 중인 작업만 개별 보유한다. | 영역이 관리할 것 | 의미 | |---|---| | 실행 식별자와 세대 | 재시작한 인스턴스에 이전 요청·완료가 섞이지 않음 | | 프로그램과 상태 | 준비된 연산·연결, 영역이 소유한 변경 가능한 상태 | | 자원 예산 | 보유 메모리, 진행·대기·완료 요청과 외부 자원의 귀속·한도 | | 허용된 연결과 효과 | 호출 가능한 입력, 저장·파일·네트워크 등 접근 범위 | | 실행·종료 상태 | 새 작업 접수, 진행 작업 배출, 취소 요청, 실제 접근 종료와 회수 | pod·VM은 사용자가 설명한 관리 경험의 비유이며 Pure의 내부 구조를 고정하는 명칭이 아니다. 묶음 수명과 보호 강도는 Pure의 요구에서 정한다. 영역마다 별도의 OS 이미지나 가상 장치를 필수로 넣지 않는다. ## 연결은 자원의 접근·공유 조건에서 준비한다 앱은 허용된 입력과 출력의 관계를 작성한다. 연결을 준비할 때 대상의 형식·권한·수명과 배치를 확인하고 실행 경로를 정한다. 모든 호출을 범용 객체·직렬화·소켓으로 보내지 않는다. 경로를 선택해도 격리 정책과 관찰 가능한 실행 순서를 우회하지 않는다. | 가용 자원과 보호 조건 | 가능한 경로 | 남는 책임 | |---|---|---| | 데이터를 함께 접근할 수 있고 실행 순서를 바로 연결 가능 | 준비된 직접 호출·읽기 대여·소유권 이전 | 권한, 원본 수명, 접수 예산, 재진입·효과 순서 | | 데이터를 공유할 수 있으나 실행 흐름이 독립적 | 제한된 작업 큐와 데이터 참조 전달 | 동기화·공개 순서, 대여 유지, 완료 회수 | | 보호 경계가 직접 접근을 제한 | 허용된 공유 매핑 또는 바이트 전달 | 공유 영역의 권한·수명·동기화·검증, 종료 후 회수 | | 메모리를 공유할 수 없는 원격 상대 | 자체 경계 형식과 보안 전송 | 인코딩, 흐름 제어, 기한, 응답 유실과 결과 불명 | 현재 호스트 연결부에서는 위 조건을 스레드·메모리 매핑·IPC·소켓 등으로 구현할 수 있다. 이 구현 분류를 Pure 코어의 필수 프로세스·소켓 계층으로 올리지 않는다. 같은 프로세스라도 격리된 샌드박스 사이에서는 임의 포인터 대여를 허용하지 않는다. 같은 기기라도 공유 메모리를 항상 사용하는 것으로 확정하지 않는다. 공유·매핑의 관리 비용과 격리 요구에 따라 복사나 IPC가 더 적절할 수 있다. 서로 다른 프로세스에는 포인터를 전송하지 않는다. 버퍼 핸들은 기존 계약처럼 발급 영역 안에서 유효하다. 영역 간 대여는 수신 영역에서 검사할 수 있는 접근 권한과 대여 기록으로 연결하며, 발급 영역의 핸들 숫자만 복사하지 않는다. 물리 버퍼는 한 번만 계상하되, 각 소비자가 얼마나 오래 회수를 막는지도 기록한다. ## 같은 호출 계약과 다른 실패 조건 접수, 결과, 완료, 취소, 기한의 의미는 [연산 계약](001-operation-semantics.md)과 [모듈 계약](003-module-contract.md)을 따른다. 로컬 호출이 즉시 끝나더라도 제출 도중 앱에 예상치 못한 재진입을 만들지 않는다. 관찰 가능한 순서·권한·예산을 보존할 수 있을 때 내부 호출이나 완료 처리를 합칠 수 있으며 모든 경계마다 큐를 강제하지 않는다. 원격 호출을 로컬 함수와 똑같이 성공·실패한다고 보이게 만들지는 않는다. 요청이 접수되기 전 거절과, 효과 실행 후 응답을 받지 못한 결과 불명은 구분한다. 취소는 이미 발생한 저장 효과를 되돌리지 않는다. 재연결 시 자동 재실행도 기본으로 가정하지 않는다. 같은 입력을 로컬·원격에 배치하려면 앱이 요구하는 순서·내구성·오류·공유 조건을 양쪽에서 충족해야 한다. 충족하지 못하는 배치는 거절하거나 명시적으로 다른 계약을 선택한다. 준비된 연결은 대상의 실행 세대와 결부한다. 대상이 재시작하면 이전 연결을 무효화하고 형식·권한을 다시 확인한다. 늦은 완료로 새 인스턴스의 상태·버퍼를 변경하지 않는다. 이전 작업이 이미 실행됐을 가능성이 있으면 새 인스턴스에 조용히 재전달하지 않는다. 네트워크의 인증된 상대 식별과 영역 내부의 슬롯·세대는 별개이며 세대 번호 자체는 인증 수단이 아니다. ## 자원 관리와 강제 격리 첫 단계의 신뢰하는 네이티브 코드 사이에서 가능한 것은 관리 계약에 따른 상태·자원 분리다. 현재 C 코드에 영역 구조체를 추가하는 것으로 임의 메모리 접근이나 프로세스 크래시를 격리했다고 주장할 수 없다. 프로세스를 공유하면 OS 수준의 종료·주소 공간 장애도 공유한다. 불신 코드에 필요한 격리 강도는 배치의 입력 조건으로 둔다. 후보는 제한된 실행 형식의 검증·메모리 접근 제어, Wasm 같은 샌드박스, 별도 OS 프로세스 또는 VM 경계다. 메모리 안전한 실행 형식도 네이티브 확장·호스트 호출의 권한과 안전성을 자동 보장하지 않는다. 예를 들어 Wasmtime은 인스턴스 메모리 격리를 제공하고 호스트 API의 안전성도 별도로 다룬다. 이 문서는 Wasmtime 도입 결정이 아니다. [Wasmtime 보안 모델](https://docs.wasmtime.dev/security.html) 메모리 예산에는 진행 작업뿐 아니라 완료 슬롯, 큐, 암호·재전송·외부 라이브러리의 보유 공간도 포함하거나 미계측으로 명시한다. 같은 물리 공간의 중복 합산과 외부로 비용을 숨기는 일을 피한다. 공유 코드·스케줄러·유휴 풀은 런타임 공통 비용으로 따로 보고한다. CPU 시간의 강제 제한에는 중단 가능한 실행이나 OS의 집행 수단이 필요하다. 협력적 스케줄러의 실행 예산만으로 멈추지 않는 네이티브 함수나 동기 파일 호출을 제어할 수는 없다. 현재 서버의 동기 저장 호출은 이벤트 루프를 막을 수 있다. 영역을 나누는 것만으로 해결됐다고 세지 않는다. 종료 요청은 새 접수를 막고 진행 작업·대여를 배출하는 단계다. 시간 초과만으로 참조 중인 메모리를 재사용하지 않는다. 영역을 관리 목록에서 제외하더라도 남은 자원은 접근이 끝날 때까지 명시적인 회수 책임과 예산 아래 둔다. 강제 종료·무중단 이동·복제는 별도 구현과 복구 계약이 필요하다. ## BSD socket·Kitex 수준의 목표를 평가하는 방법 BSD socket은 통신 API이므로 단일 성능 수치를 뜻하지 않는다. 요구를 **같은 일을 하는 직접 소켓 구현에 비해 런타임의 추가 비용을 작게 유지하고, 실제 RPC에서는 Kitex와 경쟁하는 것**으로 둔다. 그 수준에 도달했다는 결과는 아직 없다. Kitex는 Netpoll을 기본 전송 구현으로 사용하지만 다른 전송 구현도 연결할 수 있다. 연결 풀·프로토콜·실행 경로를 포함해 비교해야 한다. [Kitex 전송 확장](https://www.cloudwego.io/docs/kitex/tutorials/framework-exten/transport/) 현재 공식 문서는 긴 연결 풀을 기본으로 설명한다. `netpollmux`에 의존하는 `WithMuxConnection` / `WithMuxTransport`는 유지보수 중단으로 deprecated 상태다. 이는 QUIC이나 gRPC를 포함한 모든 다중화가 불필요하다는 뜻이 아니다. 과거 벤치마크 숫자나 설정을 그대로 합격선으로 삼지 않는다. [Kitex 연결 유형](https://www.cloudwego.io/docs/kitex/tutorials/basic-feature/connection_type/) 비교는 실제 선택에 필요할 때만 수행한다. - 같은 주소 공간의 연결: 같은 작업·권한·수명·완료 조건을 가진 직접 구현에 비해 추가된 할당·큐·복사·스케줄링을 확인한다. 소켓을 생략한 결과를 네트워크 전송 성능으로 발표하지 않는다. - 프로세스·기기 간 RPC: 성공 결과·형식·인증/암호화·연결 재사용·동시성·배치·내구성과 타임아웃·재시도 조건을 맞춘 직접 소켓 구현 및 유지보수되는 Kitex 구성과 비교한다. - 기존 변경·저장 작업에서 지연 분포와 성공 처리량, 클라이언트·서버 CPU·전체 메모리, 연결별 보유량을 확인한다. 큰 전달·느린 수신자·과부하가 작은 작업에 주는 영향도 포함한다. 영역·핸들·바이너리 형식을 만들었다는 사실은 신규성이나 성능의 증명이 아니다. 연구 가설은 작성된 연결의 의미를 보존하면서 **배치에 불필요한 전송·복사·중간 보관을 준비 단계에서 제거하고, 필요한 격리와 자원 관리는 유지할 수 있는가**다. ## 다음 구현의 구체적 범위 [006](006-native-protocol.md)의 진입점 분리를 **Pure가 운영 정책을 소유하는 코어와 호스트 수단의 분리**로 진행한다. 기존 선택·조건부 저장·응답 작업을 재사용해 실제 효과까지 연결한다. 기존 구현에서 필요한 책임만 분리하며, 사용처 없는 서비스 관리자·범용 모듈 체계를 먼저 만들지 않는다. 이번 경로에 필요한 코어 크기와 실행 비용을 기준으로 유지하고, 추가 기능의 비용은 선택 구성에 귀속시킨다. 1. Pure가 요청 접수·진행 작업·완료·자원 회수를 소유하고, 호스트 연결부는 저장·전송·시계 등 실제 수단과 결과를 제공하도록 책임을 분리한다. PID·파일 디스크립터를 앱의 식별자로 삼지 않는다. 2. 영역별 프로그램·상태·예산·접근 권한을 이 코어에 귀속시킨다. 두 영역의 기존 작업을 내부 연결로 실행하고 외부 요청도 같은 앱 의미로 접수한다. 사용자에게 수명 관리를 떠넘기지 않는다. 3. 한 영역의 포화·정상 종료·재생성과 이전 완료 처리에서 다른 영역의 관리 상태를 보존하고, 호스트의 자원 부족·입출력 실패가 Pure 결과로 정확히 전달되는지 확인한다. 4. 호스트에서 집행할 수 있는 격리와 보안 원격 경로를 확장한다. 각 기능의 검증 범위와 호스트 제약을 기록하며 관리 상태 분리를 네이티브 크래시 격리로 해석하지 않는다. 첫 구현에 클러스터 스케줄러, 게스트 OS, 범용 바이트코드 VM, 자동 복제·라이브 이동을 추가하지 않는다. 고정 바이트 예산과 처리량 목표는 대상 작업·기기·보장을 확정한 뒤 결정한다.