# 021 — 필드와 입력 값으로 정하는 저장·응답 2026-09-23. **바이트 위치를 연산마다 직접 쓰지 않고, 필드 이름과 실제 입력 값으로 저장할 내용을 정할 수 있게 했다.** 문서·선택 시작·길이를 받아 선택한 내용만 저장하고 응답하는 네이티브 경로를 구현했다. 한글·이모지가 있는 UTF-8 파일을 예제 클라이언트에서 선택하고 다시 조회해 같은 바이트가 남는 것을 확인했다. 이 단계는 작성 표현과 실제 계산·저장·소비를 연결한 기능 결과다. 범용 타입 시스템이나 새 직렬화 표준을 확정한 것이 아니며 성능 우위도 주장하지 않는다. ## 사용자가 작성하는 관계 [selection.pure](../../prototypes/connections/examples/selection.pure)는 경계의 필드를 선언한다. ```text layout Selection { start: u32le; count: u32le; document: bytes; } on put { let input = view(Selection, request.body); let selected = range(input.document, input.start, input.count); let saved = store.write(request.key, request.revision, selected); reply(saved, selected); } ``` `layout`은 이 입력 경계의 배치다. 선언 순서와 타입 폭으로 접근 위치를 정하며, RAM 전체나 저장소를 같은 레코드로 강제하지 않는다. 이 예제의 저장 본문은 선택한 원본 문서 바이트이고 입력의 start·count 필드는 저장되지 않는다. 기존 전체 바이트 저장 경로에는 layout도 필요 없다. 이름·타입·별칭은 서버 시작 때 해소한다. 요청에서는 두 u32 값을 정렬되지 않은 위치에서도 little-endian으로 읽고, 범위를 검사한 뒤 원본의 해당 구간을 참조한다. 레코드 객체·필드 사전· 선택 본문 사본을 추가하지 않는다. 저장과 응답은 같은 계산 결과를 쓰며 응답 완료까지 원본을 유지한다. 실제 사용은 [Python 예제 클라이언트](../../prototypes/connections/examples/select-text.py)가 UTF-8 텍스트 파일과 문자 위치를 받아 요청한다. 클라이언트는 Unicode 코드 포인트 위치를 바이트 위치로 바꾼다. 서버의 bytes 연산 자체는 UTF-8이나 사용자에게 보이는 글자 덩어리를 검증하지 않는다. [실행 방법](../../prototypes/connections/README.md). ## 준비할 수 있는 것과 실행해야 하는 것 상수 구간은 기존처럼 합친다. 필드의 실제 값에 의존하는 구간만 준비된 범위 연산 목록에 남긴다. 예제는 한 단계이며 그 결과에 별칭을 더 붙여도 단계 수는 늘지 않는다. 동적 구간의 하위 구간도 표현할 수 있다. 사용하지 않는 동적 구간의 실패도 관찰 가능한 동작으로 유지하고, 모든 입력 검사가 성공한 뒤에만 쓰기를 호출한다. GET에서는 이름 기반 고정 필드와 가변 꼬리 구간을 선택한다. 꼬리의 길이는 같은 파일 버전의 전체 크기에서 구하므로 본문 전체를 별도 배열로 읽지 않는다. GET의 숫자 필드 값에 의존하는 범위는 현재 거절한다. 필요한 숫자와 선택 본문을 같은 버전에서 읽는 계획을 구현하지 않고 전체 매핑으로 대체하지 않았다. 지원 타입은 u32le·고정 bytes[N]·마지막 가변 bytes다. 선언은 최대 4개, 필드는 선언당 16개, 입력 값에 의존하는 범위는 8단계다. 버전 식별·마이그레이션·일반 산술·중첩 배치·여러 가변 필드를 지원하는 최종 애플리케이션 데이터 모델은 아직 아니다. 송수신자가 배치에 합의해야 한다. ## 비용과 검증 Linux AArch64에서 일반 빌드와 ASan·UBSan 빌드가 통과했다. - 기존 22개 통합 시나리오에 실제 문서 선택, 잘린 입력·동적 범위, 필드 순서·정렬 변경, 사용되지 않은 계산의 오류, 저장된 가변 꼬리 조회, 부분 전송 수명을 추가해 28개를 확인했다. - 선언 순서를 바꾸면 실제 숫자 접근 위치도 달라진다. 고정된 헤더 위치를 서버에 숨겨 넣은 것이 아니다. - 정렬되지 않은 u32, 여러 바이트에 걸친 수, 최대 u32, 빈 구간·끝 위치·범위 초과를 검사했다. - 오류가 나면 기존 내용·revision을 유지한다. 느린 응답에서는 선택 본문 길이만 계상하는 대신 보유 중인 원본 수신 할당 전체를 계상하고, 완료 뒤 반납한다. 이 기능에는 비용이 추가됐다. 준비 구조체는 프로그램당 **112 B에서 648 B로 증가**했다. 최대 8개의 동적 범위 계획도 고정 예약하는 현재 구현의 크기이며 전체 RSS·컴파일러 크기가 아니다. 요청 계산에는 고정된 임시 span 배열을 쓰고 이 기능 때문에 힙 객체를 만들지는 않는다. 기존 수신 할당·파일 쓰기·페이지 매핑·커널 복사·클라이언트 인코딩 비용은 남는다. 따라서 이번 결과를 전체 메모리 절감이나 처리량 개선으로 해석하지 않는다. [원자료·소스 사본](../../prototypes/connections/results/2026-09-23-field-connections/README.md), [필드와 범위 준비·계산](../../prototypes/connections/program.c), [계약](../design/005-field-connections.md). macOS 실행, 전원 장애, 대규모 서비스, 네이티브 UI, 현재 숫자/화면 DSL과의 언어 통합은 검증 범위 밖이다. 저장 효과는 여전히 요청당 하나이고 파일 작업은 동기식이다. ## 다음 결정 현재 입력 값과 소비자를 연결했지만, 저장된 값의 조회·변경·다시 저장은 한 요청에서 작성할 수 없다. 다음은 **실제 앱의 읽기·변경·저장 경로에서 연산과 버전 관계를 연결하는 것**이다. 읽은 버전과 조건부 쓰기의 관계, 서로 다른 생산자가 제공하는 값의 수명을 먼저 정한다. 숫자 타입·문법을 늘리기보다 기존 실행 코어에서 재사용할 연산과 필요한 외부 효과 경계를 구체적인 작업에서 결정한다. 이번 문서 선택 데모의 크기를 키운 반복 측정은 하지 않는다.