3-12. 코어를 한꺼번에 공개하고, 표 생성을 시험하다
지난 편은 화면이 원본 서식과 페이지 배치를 그리지 않고, 표·그림 같은 개체의 구조 편집도 남아 있다는 말로 끝났다. 그 뒤 8일 동안 공개 main은 조용했다. 10월 10일 저녁 커밋이 다시 올라왔고, 그 중심은 그사이 로컬에 쌓인 코어와 화면 코드를 두 커밋으로 한꺼번에 공개한 것이었다. 10월 11일에는 HWP5 계산식 정의 편집, 편집 메뉴, HWPX 새 표 생성 실험이 들어갔고, 10월 12일은 거의 검증 기록으로 채워졌다.
먼저 경계부터 적어 둔다. 새 표는 원래 글자 위치에 조판되지 않고 블록 형태의 시험 배치로만 그려진다. 10월 11일 오전 이후의 수식 결과 직접 수정, 차트 값 편집, 끝 마커 없는 필드 처리는 저장소 문서에 후보 산출물의 검증 기록으로 남았을 뿐, 그 런타임 코드는 이 기간 main에 없다. 아래에서 이 구분을 계속 지킨다.
이 편은 3-11의 기준 커밋 7bf1d632 다음, 10월 10일 19:47 KST의 c02ea30d부터 10월 12일 23:58 KST의 7708ee06까지 289커밋을 다룬다. 이번에도 PR 없이 main에 직접 커밋했다.
날짜와 개수는 3-11과 같이 main 커미터 시각을 한국 시간으로 집계했다.
8일 만의 공개: 두 개의 통합 커밋
10월 10일 23:24의 통합 코어 커밋은 파일 988개, 추가 67,843줄이다. 3분 뒤의 Canvas UI 커밋은 파일 371개, 추가 15,915줄이다. 289커밋에서 추가된 줄의 약 84%가 이 두 커밋에 있다.
작업 트리를 통째로 올린 것은 아니다. 게시 후보 기록에 따르면 WASM·root·회귀 진입점이 실제로 import하는 2,390개 파일을 따라가 바뀐 소스 889개와 JS API 98개만 별도 Git index로 골랐고, 그 사본을 따로 꺼내 ReleaseSafe 빌드를 확인했다. UI 쪽도 app과 Worker가 실제로 연결하는 ESM 464모듈을 골라 연결을 확인했고, Canvas 편집·이력·저장·Worker 회귀 215개가 통과했다. 이 숫자들은 집중 검사이며, 같은 기록은 전체 native·공개 테스트를 별도 실행으로 구분한다. 이 후보는 그날 밤 기본 데모 WASM으로 반영됐다.
이 묶음에는 명시적 비밀번호로 HWP5(DES/AES)와 HWPX를 복호화해 여는 경로도 들어 있다. 저장은 사용자가 동의한 평문 출력이고, 다시 암호화해 저장하는 기능은 아니다. 관련 계약 문서는 아직 게시 대상에 남아 있다고 기록돼 있다.
같은 날 HWP5 쪽 작은 수정도 있었다. 본문 제어 문자 중 하이픈(코드 24)·묶음 빈칸(30)·고정폭 빈칸(31)을 원문 그대로 두고 주변 입력만 허용했다. 한 실파일의 모든 문단에 접두어 입력을 시도하면 418회 중 417회만 성공했는데, 하이픈이 보존 목록에서 빠진 것이 원인이었다. 수정 후보에서는 418회 모두 저장·재열기·이력을 통과했다. 화면에서는 하이픈을 소프트 하이픈(U+00AD) 한 글자로 표시하고, 줄 끝 하이픈 조판은 하지 않는다. 도형 공통 속성 뒤에 남는, 의미를 모르는 바이트는 해석하지 않고 16진 문자열로 꺼내 보는 코어와 decoder가 들어갔다. 이런 바이트가 있는 도형은 페이지 배치에서 계속 미지원으로 거부한다.
미리보기 화면 머리에는 여전히 "원본 페이지 조판은 아직 재현하지 않습니다"라는 문구가 있다. 다만 UI 커밋에 HWP5 페이지 배치 경로가 들어와, 10월 10일 기본 WASM으로 Git이 추적하는 문서 101개 중 실제 CFB 55개를 모두 감사했다. 43개가 배치되고 12개는 미지원으로 거부됐으며, 읽기 실패는 없었다. 미지원 12개 중 10개는 의미를 확인하지 못한 표 속성 비트 때문이다. 글자 폭을 8px로 고정해 잰 배치라 한글 조판과 같다는 증거는 아니라고 페이지 감사 기록이 밝힌다.
10월 11일 새벽: 계산식 정의를 바꾸다
자정부터 두 시간 반 동안은 HWP5 계산식이었다. HWPX 쪽에 먼저 있던 수식 정의 변경을 HWP5에도 붙였다. setFormulaDefinition이 이력과 함께 들어갔고, 예를 들어 chart.hwp의 SUM(B?:E?)를 AVG(B?:E?)로 바꾸면 문서의 13개 수식을 다시 계산해 바뀐 식의 결과가 16.875가 된다. 식은 4,096바이트까지 받고, 인식하지 못한 식이나 숫자가 아닌 참조는 실행하지 않고 거부한다. 계산 결과 텍스트를 손으로 고치는 것은 여전히 막혀 있다.
Worker와 속성 패널을 연결한 뒤 실제 Chromium에서 13수식 목록, AVG 적용 후 16.875, undo 후 SUM, redo 후 16.875를 확인했다. 드롭다운과 폼을 쓰는 경로이고, Canvas에서 수식을 직접 고르거나 다운로드 파일을 다시 올리는 검증은 아니다. 이 시점까지의 게시 커밋을 깨끗하게 꺼내 돌린 정규 감사는 HWP5 290/290, HWPX 34/34였다.
이어 MIN·MAX가 추가됐다. HWP5에 MIN·MAX 문법을 넣은 후보에서, HWPX는 같은 문법을 받아들이면서도 별도 계산기가 합계로 계산하는 오류가 독립 Python 산술로 드러났다. HWP5 커밋 3분 뒤 두 포맷이 같은 집계 모듈을 쓰도록 고쳤다. AVERAGE는 저장된 식을 AVG로 바꾸지 않는 별칭으로 연결했고, 수식 문법과 셀 선택 코드를 HWP5 파서 밖 src/model로 옮겼다.
메뉴를 기존 명령에 잇다
새벽 2시 40분부터는 메뉴가 붙었다. 찾기·바꾸기는 기존 검색 입력에 포커스를 넘긴다. 복사·잘라내기에서 잘라내기는 클립보드 쓰기가 끝난 뒤 선택이 그대로일 때만 원문을 지운다. 붙여넣기 메뉴는 실제 브라우저에서 클립보드 읽기 권한이 거부되는 경로만 확인했고, 허용된 상태의 성공은 아직 별도 검증으로 남겼다. 선택 삭제와 문단 정렬 메뉴도 기존 Canvas 명령과 서식 폼에 위임한다. 메뉴가 따로 편집 상태를 갖지 않는 구조다. 메뉴 구성은 RHWP의 편집기 소스를 참고했지만, 코드를 옮기거나 같은 기능이라고 주장하지 않는다고 문서에 적었다. 개체·서식 클립보드와 문서 전체 선택은 아직 없다.
조회도 몇 군데 묶었다. HWPX 취소선 상태를 조회마다 한 번만 색인하고, 사각형과 도형 텍스트는 구역 단위로 한 번에 조회하도록 바꿨다. 결과가 개별 조회와 같은지는 대조했지만, 문서는 일회성 측정을 전체 처리 속도 개선으로 넓히지 않는다.
같은 시각 native 테스트를 묶음 단위로 실행하는 감사 도구도 공개됐다. 게시 소스로 컴파일한 바이너리에는 3,859개 테스트가 있었고, 이 기간 기록은 실행을 시작했다는 데까지다.
HWPX에 새 표 넣기
새벽 4시 45분부터 오전 10시 35분까지는 HWPX 표 생성이었다. 순서가 분명했다. 먼저 포맷과 무관한 치수 계획으로 행·열·폭에서 셀 좌표를 계산하고, 새 표와 셀 텍스트를 소유하는 모델을 만들었다. 그다음 새 문단 ID 할당, XML 조각 작성, 세션과 체크포인트, 독립 XML·ZIP 검사를 거친 저장, 문서 전체 ID와 서식 참조 검증을 차례로 붙였다. 공개 API는 insertTable이다.
지정한 문단의 UTF-16 위치에 빈 표를 만들고, 새 표의 식별자를 돌려준다. 서식은 문서에서 실제로 쓸 수 있는 문단·글자·스타일·테두리 ID 목록에서 고르고, 목록에 없는 ID는 native가 거부한다. 셀은 최대 100,000개이고, 병합 셀이나 셀 안의 여러 문단은 만들 수 없다.
그 뒤 Worker 표시, 셀 배치, Canvas 표시, 셀 선택과 직접 입력, 삽입 폼이 이어졌다. 실제 Chromium에서 charshape.hwpx를 열고 2×2 표를 만든 뒤 첫 셀에 새 표😀<&를 입력하고, 다운로드, undo·redo, 다시 다운로드, 재열기까지 했다. 두 다운로드 파일은 바이트 단위로 같았고, 독립 Python 검사에서 ZIP 항목 순서·CRC·비대상 파일 보존, 새 표 1개·4셀과 서로 겹치지 않는 새 문단 ID를 확인했다. 이 검사는 section XML 전체의 의미나 조판을 대조하지 않는다고 브라우저 검증 기록이 밝힌다. 이후 Tab·Shift+Tab 셀 이동이 붙었다.
처음에는 새 표가 있는 구역에서 기존 본문을 편집할 수 없게 막았다. 오전 중에 그 보호를 하나씩 풀었다. 본문 텍스트가 바뀌면 새 표의 위치를 함께 옮기고, 개체가 붙은 문단과 필드 바깥 입력, 원본 필드 라벨 편집을 새 표와 같이 쓸 수 있게 했다. 검증 중에는 chart.hwpx의 수식이 참조하는 숫자 셀 안에 표를 넣어 저장하면, 다시 열 때 수식 조회가 실패하는 문제가 실측으로 나왔다. 숫자 읽기를 느슨하게 하지 않고, 저장본을 다시 열어 모든 수식 구역이 조회되는지 저장 전에 확인해 실패하면 원자적으로 거부하게 했다. 암호화되지 않은 추적 HWPX 44개에서 문서마다 적격한 위치 하나에 표 생성·입력·저장·이력·재열기를 해 44/44가 통과했다.
이 표 생성은 이날 기본 데모 WASM에도 반영됐다. 다만 한계가 분명하다. 표를 원래 글자 위치에 조판하지 않고, 위치 0이면 문단 글자 앞에, 그 밖이면 문단 뒤에 블록으로 놓는다. 쪽 나눔은 성공으로 표시하지 않고 UnsupportedCreatedTablePagination으로 보고한다. 표를 넣은 문단의 원본 줄 배치는 지우며, 한글 프로그램에서 다시 조판한 결과는 확인하지 않았다. 새 셀의 서식·구조 편집, HWP5 표 생성, 실제 한글 입력기 검증은 남아 있다.
기록이 코드보다 앞선 하루 반
10월 11일 10:25의 필드 라벨 커밋이 이 기간 src/를 건드린 마지막 커밋이다. 그 뒤 121커밋은 docs 90개, test 17개, fix 8개, feat 6개이고, 바뀐 코드는 web/preview의 UI 모듈과 테스트·검사 도구뿐이다. 그사이 진행된 런타임 작업에 대해서는 관련 문서에 "runtime은 미커밋"이라는 문장이 여러 번 나온다.
그 하루 반에 기록된 것은 크게 넷이다.
- 수식 결과 직접 수정과 셀 분류. HWPX에서 SUM은 문자열과 빈 셀을 집계에서 빼고, 계산 결과 문자열을 사용자가 직접 정하는 저장 경로를 후보에서 검증했다.
main에 들어간 것은 그 기능이 있을 때만 켜지는 결과 입력 UI와 독립 검사기다. - 차트 값 편집. HWPX 차트 값은 차트 XML과 OLE 안의
OOXMLChartContents두 곳에 있어 양쪽을 함께 바꿔야 한다. 후보 산출물로 참조 문서 92개, 연결 93개의 값 2,296개를 모두 편집·독립 대조·이력·재열기했다. 관측된 차트 OLE의 CFB 편차를 명시적으로 정규화하는 옵션을 켠 결과이고, 기본 strict 경로·시리즈 구조·차트 렌더링은 범위 밖이다.main에는 계열·범주 라벨과 64개씩 나눈 값 목록 같은 순수 UI 모듈만 올라왔고, 앱 화면 연결과 native 코드는 아직 로컬이다. - 끝 마커 없는 필드. 두 규제분석 원본에는 표 셀 안에서 시작만 있고 끝이 없는 누름틀이 있다. 지금은 그 시작 이후 구역 전체를 보호하는데, 후보에서는 보호 범위를 그 셀 목록까지로 줄이고, 쪽 번호만 든 run 앞에 입력 위치를 만드는 수정을 검증했다(검증 기록). 문서 마커를 자동으로 고치지는 않는다.
- 계산식 재병합 회귀. 10월 12일 공개 테스트 전체 실행이 2,064개 중 1개 실패했다. 숫자 셀을 바꾼 뒤 계산식 문단을 나눴다 다시 합치면 거부됐고, 그 거부만 없앤 중간 후보에서는 분할 때 지운 원본 줄 배치가 되살아났다. 문단별 소유권으로 범위를 좁힌 후보에서 2,064/2,064가 통과했다. 같은 후보의 native 전체 실행은 3,951/3,956(실패 1, 강제 종료 3, 누수 보고 1)이었고, 테스트 쪽 문제를 고쳐 두 번 더 돌린 실행도 모두 3,953/3,956에 강제 종료 2건이 남았다. 전체 native gate는 아직 통과하지 않았다.
같은 기간 입력 경로 조사도 넓어졌다. 10월 11일 게시 커밋으로 만든 기본 WASM에서 추적 HWPX 46개(암호 1개 제외)의 1,444문단은 일반 입력 1,231, 전용 입력 152, 숫자 입력 48, 계산 결과 13으로 나뉘어 각 경로가 확인됐다. 계산 결과 13개는 직접 입력을 막는 쪽이 확인 대상이다. HWP5는 2,090회 접두어 입력 중 2,042회가 저장·재열기·이력을 통과했고 48회는 숫자 셀의 InvalidFormulaNumber 거부다. 참조 프로젝트 RHWP의 샘플 975개 경로에서는 HWP3 26개를 범위 밖으로 빼고 HWP5 509개, HWPX 435개가 텍스트를 읽었다(690,523문단). 암호 2개와 구역 수가 맞지 않는 3개는 거부된다. 10월 12일에는 후보 산출물로 HWPX 435개 문서의 214,461문단을 대상으로 어느 입력 경로가 선택되는지만 읽기 전용으로 조사하는 도구를 돌려 9,743문단의 거부를 그대로 기록했다. 이 조사는 실제로 입력하지 않으므로 편집 성공으로 세지 않는다.
남은 거리
사흘 사이 hwpjs는 로컬에 쌓아 둔 코어를 공개 main으로 옮겼고, HWP5 계산식 정의 편집과 HWPX 새 표 생성을 공개 API와 화면에 붙였다. 3-11처럼 수치마다 어느 산출물의 결과인지, 독립 검사기가 무엇을 대조하지 않는지 함께 적은 것도 그대로다.
남은 것도 많다. 화면은 여전히 원본 페이지 조판을 재현하지 않고, 새 표는 블록 시험 배치이며, HWP5에서는 표를 만들 수 없다. 10월 11일 오전 이후 문서에 기록된 수식 결과·차트·필드 작업은 런타임이 main에 없고, 전체 native gate도 통과하지 않았다. 저장본을 한글 프로그램에서 열어 대조한 기록, 실제 한글 입력기와 Chromium 밖 브라우저 검증도 아직 없다. Rust 판의 HTML 뷰어를 신규 Zig 기능으로 세지 않는다는 이전 원칙도 그대로다.