Repository navigation
feat: 기여 PR 10건 통합과 조판·Studio 회귀 보정 - #8228
Merged
Merged
Conversation
KoPub돋움체·바탕체는 한자·전각 기호를 한글 전진폭(0.872 · 0.94)으로 쟀고, 「」『』·× 등은 KoPub 표 밖이라 공통 폴백으로 갔다. 글꼴(cmap+hmtx)은 한자·기호 900, 낫표 450 이고, 한/글 Print 내장 서브셋과 실제 전진이 같은 값을 증언한다. - 공통 갈래(KoPub·KoPubWorld): 한자 · 옛 자모(ㆍ 포함) · 전각 FF01–FF5E·FFE0–FFE6 · CJK 기호(、。〈〉《》「」『』【】〔〕 450, 〃〓 900) · is_fullwidth_symbol 900 · ◦ 600 · ₩ 894 · £¥ 계열별. - KoPub돋움체·바탕체는 U+0080–U+2FFF 를 글꼴 표(668자, 세 굵기 동일)로 잰다. 상자 그리기는 rhwp 의 PUA 글머리표 표시 대체(━ 등)가 생기는 블록이고 한/글은 그 글리프를 KoPub 으로 그리지 않아(정본 383쪽 중 0건) 표에서 뺐다. (cherry picked from commit 08bd263)
(cherry picked from commit 48bd1e3)
288쪽은 한/글이 KoPub바탕 Light 를 두 크기(한글 13.92·14.40px)로 내고 rhwp 는 한 크기로 묶어, 쪽 한글 중앙값이 두 무리 경계에 걸렸다. devel 의 다른 변경으로 그 중앙값이 0.1px(14.1 → 14.0) 움직이자 「」 전진폭은 그대로(6.7–6.9px, 한/글과 같음)인데 비가 허용치를 넘었다. 같은 줄(run 의 y)·같은 글꼴·같은 크기의 한글 중앙값을 기준으로 바꾼다. 정본 비도 같은 PDF 에서 같은 기준으로 다시 쟀다 — 57쪽 × 만 0.8889 → 0.9638(글꼴 비 900/936 = 0.962, 쪽 기준은 다른 자간의 한글이 섞였다)이고 나머지 여섯 사례는 쪽 기준과 같다. - 새 head: 일곱 사례 모두 허용치 안(288쪽 0.4786 vs 0.4778) - 수정 전(devel def947c, 이 검사 파일만 얹음): 38쪽 바탕 한자 1.0000 vs 0.9667 로 실패 (cherry picked from commit ef97704)
한/글은 쪽·종이 기준 위아래 배치 개체를 가진 문단의 첫 줄도 그 밴드를 피해 밴드 아래에 놓는다(stored_reset_float 입력: 구역 첫 빈 문단 vpos 30915 = 사각형 하단). #7696 은 개체를 방출한 뒤에 밴드를 등록해 앵커 문단은 밴드 위에 남고 뒤 문단만 밀었다. 쪽 vpos 기준도 그 문단 vpos 로 잡혀 본문 전체가 정본보다 줄 하나(21.3px) 위에 그려졌고, 저장 줄과 흐름의 축이 어긋나 P 를 줄 3에서 나눴다(정본 줄 2). - 밴드는 흐름과 무관한 절대 위치이므로 문단 fit 전에 그 문단 소유 밴드를 등록한다. 밴드 아래에서 첫 줄이 단에 들어갈 때만 등록해, 못 들어가는 경우의 쪽 소속(#7696 spill)은 그대로다. - 단 첫 문단이 밴드에 밀리면 그 문단 vpos 로 잡은 쪽 기준을 민 거리만큼 되돌린다. 입력: 한/글 2020 이 열어 HWP 로 저장한 합성 입력 두 개(gen_field_float_reset.py, FILL=20, 구역 첫 빈 문단의 용지 기준 자리차지 사각형)와 Print PDF. 대조군 _plain 은 필드·글 앞 개체가 없다. 회귀 tests/cases/stored_reset_field_float_suffix.rs (devel d9fd85e 에서 둘 다 FAIL, 수정 후 PASS): - section_first_paragraph_starts_below_its_own_paper_band: pi=1 이 A 하단 + pi=0 저장 줄 한 칸 - paragraph_after_section_paper_band_splits_at_stored_line: P 가 정본처럼 줄 2에서 나뉜다 이 입력은 필드·경계 뒤 개체가 저장 경계 수용을 막는 판정(#8124)을 검출하지 않는다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 9c8499c)
한/글은 U+27C0..U+27FF·U+2900..U+2BFF(수학 기호 A·화살표 보충·수학 기호 B· 수학 연산자 보충·기타 기호와 화살표)를 앞뒤 글자와 무관하게 기호 슬롯 글꼴로 재고 그린다. 슬롯마다 다른 설치 글꼴을 준 합성 입력(한/글 2020·2024 Print)에서 ⦁ ⟨ ⤀ ⨀ 는 기호 슬롯 글꼴(함초롬바탕, 0.972em)로 나오고 그 글꼴에 글리프가 없을 때만 대체 글꼴로 간다. rhwp 는 이 블록을 한글 슬롯으로 분류해 한글 글꼴에 없는 글자로 반각(0.5em)을 주었고, 기호 슬롯으로 옮겨도 함초롬바탕 폭 표가 이 구간을 수집하지 않아 같은 반각 폴백에 떨어졌다. - 언어 슬롯 판별에 두 블록을 기호(5)로 추가한다. - 함초롬바탕·함초롬돋움 SFNT 의 이 구간 cmap·hmtx 를 확인한 표로 보충한다 (scripts/extract_verified_math_symbol_metrics.py). 기존 범위는 덮어쓰지 않는다. 1342000-202300055 6쪽 글머리 ⦁ 줄: Native 88.55 → 98.84, WASM 89.27 → 98.85 (4·5·7·8·11쪽도 상승, 하락 쪽 없음). samples A/B·10k 조판 지표·쪽수 대장 변화 없음. (cherry picked from commit dbad604)
이어지는 조각에 넘기는 행 꼬리(`next_start_row_height_override` 의 #5714 경로)는 측정 행 높이에서 이번 상자를 뺐다. 측정 행 높이는 내용으로 자란 행 전체(줄 사이 간격 포함)라 남은 내용에 컷 줄의 줄간격까지 얹은 빈 띠가 되었다. 한/글 2020 Print(1613000 141·142쪽 행 88: 칸 선언 1282HU = 17.1px, 측정 38.4px)는 이어지는 조각을 남은 한 줄 17.1px 로 그린다 — rhwp 는 21.3px 로 142쪽 이후 행이 4.3px 씩 밀렸다(142–181쪽 짝수 쪽 56.8–67.9%). - 글줄만 담은 칸의 행은 행 칸 선언의 최댓값을 행 전체 높이로 쓴다. 남은 내용은 다음 스캔이 잰다. - 그 행에서 끝나는 병합 칸의 선언이 지나는 행들의 칸 선언 합보다 크면(1342000 127·128쪽 행 78–80 19744HU > 5782+4300+2618) 남는 몫이 측정 행 높이에 실리므로 종전대로 공통 계획 높이를 쓴다. 선언이 행 합과 같으면(1613000 행 121–122 칸 2564 = 1282×2) 행 칸 선언으로 잰다. 오버플로 값 (u32 > i32::MAX) 칸 선언은 합에서 뺀다. - 개체를 담은 칸의 행(86712 27·28쪽)은 종전대로 측정 행 높이를 쓴다. - 앞 조각이 이미 그린 행을 잇는 가운데 조각은 앞 상자를 장부로 받지 않았으면 행 전체 높이에서 이번 상자만 빼지 않는다(86712 32–34쪽 행 1: 2262.5 − 929.6 = 1332.8px 를 34쪽에 실어 끝 조각이 본문 아래까지 늘었다; 한/글 아래 괘선 535.1). Native(문서별 글꼴) devel 2e087a5 대비, 다음 커밋과 함께 잰 값: 1613000 142–181쪽 56.8–67.9 → 99.6–99.9, 86712 34쪽 81.4→100.0, 1342000·80168 hwp 변화 없음(0쪽). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit cf34ff9)
한/글은 행 수용을 선언 높이가 아니라 내용으로 정하고, 내용이 든 행의 상자를 닫는 선까지 그린다. 1613000 188쪽 구역 2 표 행 26 «6. 모니터링»(칸 선언 2614HU = 34.85px, 한 줄): 쪽 끝 29.9px 에 내용이 들어 한/글 2020 Print 는 188쪽에 두고 아래 괘선을 1040.6(닫는 선)에 긋는다. rhwp 는 선언이 넘친다고 행을 통째로 189쪽에 넘겨 189·190쪽이 한 행씩 밀렸다(49.7·40.1%). 병합 칸이 닿지 않고(`!rowspan_touched`) 행 처음부터 시작하는 행이 내용 컷을 다 소비하면 남은 공간까지를 이 쪽 상자로 받는다. 남는 선언 몫은 다음 조각이 행 칸 선언으로 다시 재고(앞 커밋), 1280HU 이하이면 쪽 경계에서 버린다(`complete_row_blank_tail_is_absorbed`). 병합 칸이 닿는 행은 기존 밴드 컷(#2236), 재조판 물리 프레임 행과 표 끝 행은 각자의 기존 경로를 그대로 탄다. Native(문서별 글꼴): 1613000 188·189·190쪽 96.9/50.3/40.6 → 99.3/99.8/99.5, 90% 미만 5→2(1·6쪽, devel 과 같음). 1342000·80168 hwp·86712 변화 없음. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 9c37dec)
예산은 첫 조각 host_before 로 바깥 위 여백을 예약하는데, 그리기는 글자 없는 앵커의 첫 표에서 여백을 열지 않았다. 1480000-201900698 11쪽 구역 3 문단 0 표(97×4, 바깥 위 283HU)는 정본 한/글 2020 Print 위 괘선 134px 인데 수정 전 rhwp 는 130.8 에 그렸다(Visual Sweep 46.2 → 100.0). 칸 단위로 나누는(CellBreak) 표는 이 원점에 여백을 넣지 않는다(같은 문서 156쪽 정본). devel 2e087a5 기준: 샘플 1,167 파일 중 2쪽만 바뀜(1480000-201900698 11쪽, coanchored_float_tac_order 2쪽 — 정본과 쪽 수가 달라 4 vs 3 비교 불가). 코퍼스 10k 쪽 수 변화 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 16dfd8d)
걸침 칸이 없어도 내용 컷으로 나뉜 행 자신의 선언 높이가 이 조각 상자보다 크면 그 행이 쪽 끝 띠를 소유한다. 한/글 2020 은 첫 조각의 아래 괘선을 닫는 선에 긋고 다음 조각은 선언에서 그 상자를 뺀 나머지다(task1749 hwpx 4쪽 행 2: 정본 괘선 1024.0, 수정 전 rhwp 는 내용 높이 83.0px 에서 닫고 남는 4.4px 를 5쪽에 실어 5쪽 전체가 내려갔다). 저장 행 프레임이 상자를 정한 행과, 앞 쪽에서 이미 그린 행을 잇는 가운데 조각은 제외한다(편람 214쪽 3쪽짜리 행 — 장부가 앞 상자를 모른다). devel 2e087a5 기준(Native, 문서별 글꼴): task1749 hwpx 4·5쪽 98.0/71.0 → 100.0/100.0. 1342000·80168 hwp 전쪽 변화 0. 샘플 1,167 파일: 바뀐 쪽 중 정본 있는 쪽은 모두 같거나 오름 (page-number-bottom15/footer15 3쪽 51.2 → 100.0, synam-001 13쪽 85.4 → 99.6), 쪽 수 변화 0. 코퍼스 10k 쪽 수 변화 0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 44522be)
종전 검사는 첫 조각이 내용 높이에서 닫혀 첫 줄 위 = 안 여백 + 원본 앞 간격이라고 가정했다. 독립 Print(`pdf/task1749/saved_bounds_cumulative_page_break-hwpx-2020.pdf` 4쪽)는 아래 괘선을 닫는 선 1024.0 에 긋고 가운데 정렬 칸의 남는 몫을 위아래로 나눈다(별 줄 기준선 962.15·993.15·1017.29). 원본 앞 간격 소유는 그대로 검사한다. 관련 쪽: Native(Haansoft Batang·Dotum 실제 공급) task1749 hwpx 1–5쪽 최저 99.83%, hwp 99.16%. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 6f6948c)
한/글 실측(사다리 D, 각주 변형 66/66): 각주가 이미 놓인 쪽에서 쪽을 넘는 표의 닫는 선은 각주 구분선 위 여백까지 포함한 각주 영역의 위다. 표 첫 조각 예산이 따로 빼던 보수 안전 띠(3000HU = 40px)는 없다. 1130000 가맹 보고서 50쪽 표 pi=532 행 0 이 각주 위에 다 들어 51쪽은 행 1 로 시작한다(정본 한/글 2020). 수정 전에는 띠만큼 일찍 잘라 50–54쪽이 한 행씩 밀렸다. 각주가 없는 쪽은 띠도 없어 그대로이고, 표 자신의 각주는 따로 수용을 판정하므로 제외한다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit f18fc6c)
조각 높이(`row_cut_height`)는 이어받는 조각의 끝까지 소비한 무소유 빈 꼬리를 물리 범위에서 뺐지만, 그리기는 그 빈 줄을 칸 상자에 담는다. 그 차이만큼 뒤 문단이 표 상자 안으로 올라왔다(86712 21쪽 1×1 표 끝 조각: 330.2 < 344.3px, «3» 이 표에 겹침). 정본 한/글 2024 는 빈 줄까지 상자에 담는다. 끝 빈 꼬리를 빼는 것은 행이 다음 쪽으로 이어지는 컷(끝 컷이 있는 조각)에만 남긴다 — 한 칸이 먼저 끝나고 다른 칸이 이어지는 행의 재측정 과대 요구(9f4592d)는 그대로다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit 53ecb85)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> (cherry picked from commit d9e144a)
빈 host 에 자리차지 표가 둘(오프셋 0 / 양수)인 문단은 #7687 이후 글 있는 host 와 같은 visible float 배치(place_table_with_text)를 탄다. 그 배치는 표 원점에 바깥 위 여백을, 흐름 끝·배제 띠 끝에 바깥 아래 여백을 스스로 더한다. 그런데 통째 배치 호출부는 이 host 에 흐름용 높이(표 + host 앞 간격)와 RowBreak 흐름 꼬리(아래 여백)를 넘겨, 오프셋 0 표의 흐름 끝과 양수 오프셋 표의 배제 띠 끝이 바깥 여백만큼 더 내려갔다. 한글문서파일형식 20쪽 pi=130: 둘째 표 띠 끝 379.72px — 저장 사다리(pi=132 vpos 28197)와 배치는 375.96px. 뒤 빈 문단이 그 띠로 뛰어 pi=133 「3.2.12. 참고문헌」 host 원점이 3.76px 내려갔고, 통합 뒤 배치가 typeset 확정 원점을 쓰면서 그 host 의 둘째 표(7×2)·제목·뒤 본문이 정본보다 +4.3px 아래에 그려졌다. 첫 표(오프셋 0)는 배치 흐름이 놓아 제자리였다. 글 있는 host 처럼 표 상자 높이(effective_height)만 넘기고 흐름 꼬리를 붙이지 않는다. - 한글문서파일형식 20쪽: 둘째 표 686.0 → 682.3(정본 681.7), 「3.2.12.」 853.9 → 850.2(849.5) - 합성 K1~K4(gen_titled_host_after_band.py, 한/글 2020 Print): K1~K3 T4·뒤 글줄 +3.8px → 정본 ±0.5px, K4(앞 빈 host 없음) 불변 - 회귀: titled_host_after_empty_host_band_keeps_its_float_offsets — 수정 전 FAIL(K1 T4 496.7, 기대 492.9) (cherry picked from commit 160209f)
(cherry picked from commit 495fc8f)
같은 문단의 앞 자리차지 표(오프셋 0)가 흐름을 소비하면 한/글은 host 첫 줄을 그 띠 아래에 저장한다. 통째 배치(entry.rs)는 저장 사다리가 인증한 그 첫 줄 원점 (source_text_origin)을 글줄 원점이자 표 앵커로 함께 넘겨, 뒤 양수 오프셋 표가 앞 표의 띠(바깥 여백 포함)만큼 아래로 내려갔다. 오프셋 0 표는 문단 원점 (placement_para_start_height)에 놓이므로 같은 문단의 두 표가 서로 다른 원점에서 쟀다. 앞에 공동 앵커 자리차지 표가 있으면 from_stored_host / from_stored_head_host 에 문단 원점을 넘긴다. 글줄은 종전대로 저장 원점(stored_host_origin)을 쓴다. 앞 표 띠와 겹치는 경우의 쌓기는 HostPlacementConstraint 가 그대로 맡는다. - 합성 K1~K4 HWP 저장본(한/글 2020 Print): T4 윗변 700.5/700.5/679.1/386.3 → 492.9/612.9/471.6/298.7 (정본 492.4/612.3/471.2/298.4). 글줄·T3 불변 - samples 1,318 · 10k 코퍼스 9,991 문서 SVG A/B: 변화 0 - 회귀: saved_titled_host_measures_offset_float_from_paragraph_origin — 수정 전 FAIL(K2 T4−T3 207.6, 기대 120.0) (cherry picked from commit 630e8e9)
…WASM) (cherry picked from commit c5d4943)
(cherry picked from commit 3fb95ab)
- PluginHost 에 ui(registerSidePanel·toggleSidePanel·isSidePanelOpen)와 getSelectionText 추가. 패널 해지는 플러그인 원장(uiUnsubs)이 회수한다. - 선택 평문은 내부 클립보드를 덮어쓰는 copySelection 대신 읽기 API로 만든다. - #editor-area grid 셋째 열에 #side-panel-host. 기존 네 칸은 명시 배치. - 내장 ai-assistant 플러그인: 도구 메뉴 「AI 도우미」, 최상위 창에서만 자동 로드. - RHWP_WITHOUT_AI=1 빌드 플래그. 확장 빌드는 __RHWP_AI__=false 를 정의한다. - e2e side-panel 추가, 플러그인 개수를 단정하던 e2e 2건은 존재 검사로 보정. (cherry picked from commit 57cc895)
- @anthropic-ai/sdk 0.137.0 고정. SDK 는 처음 쓸 때 불러오는 별도 청크. - KeyStore: 세션(기본) / 기억(IndexedDB) / 기억+암호(PBKDF2 → AES-GCM). 저장소가 막히면 세션 모드로 내려가고 화면에 알린다. - 도구 > AI 설정: 제공자·모델(기본 Claude Opus 5.5)·응답 깊이·키·기억·암호, 연결 테스트는 models.retrieve 로 토큰 없이 확인. - 패널 상태 none/locked/consent/ready, 잠금 해제 대화상자, 전송 동의. - 단위 테스트 14건, e2e ai-settings(API mock) 추가. (cherry picked from commit f61b43f)
- ClaudeProvider: beta messages stream, effort·캐시·strict 도구, Opus/Sonnet 5.5 서버 대체(fallbacks default), 응답 중간 대체 경계 정리. - ChatSession 덧붙이기 전용 이력, runAgent 도구 루프(라운드 상한 8, max_tokens·거절·중단·오류 시 이력 교대 보존). - 읽기 도구 7종. read_page_text 는 렌더 조각으로 표 칸 글까지 읽는다 (getPageText 는 표 안 글이 빠짐). - 문서 내용 nonce 경계·이스케이프, Markdown 안전 렌더(HTML 해석 없음). - 단위 테스트 41건. (cherry picked from commit bdbb02d)
- 대화 기록·스트리밍 표시·도구 진행 표시·보내기/중단·새 대화·토큰 사용량. - 선택 영역 빠른 동작(요약·설명·맞춤법 점검), 한글 조합 중 Enter 는 보내지 않음. - 중단·거절·잘림·오류 문구, 문서 교체 시 새 대화. - 준비되면 입력란으로 포커스, 개발 서버가 SDK 를 미리 묶어 첫 질문 때 페이지가 새로 고쳐지지 않게 함. - e2e ai-panel(SSE mock) 28항목. (cherry picked from commit aad18d2)
- http://IP 처럼 비보안 출처에서는 브라우저가 crypto.subtle 을 주지 않아 암호 저장이 TypeError(「알 수 없는 오류」)로 실패했다. KeyStore 가 CRYPTO_UNAVAILABLE 로 미리 거절하고, 설정 화면은 암호 칸을 막고 이유를 안내한다. - 400·기타 API 오류는 제공자 사유와 request id 를 문구에 붙이고 콘솔에 남긴다. (cherry picked from commit cbcdf30)
실제 API 확인 결과 「요청이 거절되었습니다」의 원인은 계정 크레딧 부족이었다 (최소 요청까지 같은 400). 문구로만 오는 이 경우를 billing 갈래로 옮겨 Plans & Billing 충전 안내를 보인다. (cherry picked from commit df9d83e)
(cherry picked from commit b6d972c)
- replace_text/fill_field: 찾을 글로 자리를 정하고, 적용 직전 다시 찾아 낡은 자리에는 쓰지 않는다. 적용은 트랜잭션 한 번(undo 한 단계). - 변경 카드에서 적용/거절, 설정의 「확인 없이 바로 적용」(기본 끔). - 대화 엔진 도구 실행 비동기화(승인 대기, 중단 시 남은 호출 결과 채움). - 실제 모델·실제 문서로 편집 왕복 확인. (cherry picked from commit dda58a1)
- insert_paragraphs: 문서 앞·끝·지정 문단 뒤에 새 문단(빈 새 문서는 첫 문단부터). - create_document: 메뉴 「새 문서」와 같은 저장 확인을 거친다. PluginHost createBlankDocument 가 Promise<boolean> 과 confirmUnsaved 를 받는다. - AI 가 만든 문서 교체로는 대화를 끊지 않는다. (cherry picked from commit 2c2e740)
- format_text: 굵게·기울임·밑줄·취소선·크기·글자색·배경색·글꼴. - format_paragraph: 정렬·줄 간격. - insert_table: 문서 앞·끝·지정 문단 뒤에 표를 만들고 칸을 채운다. - 변경 카드에 서식 요약, 표 미리보기. - 실제 모델로 새 문서에 서식 있는 보고서와 표 작성 확인. (cherry picked from commit 98cf153)
This was referenced Oct 25, 2026
Collaborator
Author
후속 처리·브랜치·산출물 정리 완료
|
This was referenced Oct 25, 2026
7 tasks
planet6897
added a commit
to planet6897/rhwp
that referenced
this pull request
Oct 26, 2026
devel 238de6d(edwardkim#8228)가 `from_stored_ladder` 를 저장본·재조판 공용 `from_ladder` 로 나눴다. 저장본 경로는 받은 `origin_closes_float_frame` 을 넘기고, 재조판 경로 (`from_reflowed_ladder`)는 앞 항목 상자 끝을 증언하는 호출자가 없으므로 `false` 다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 26, 2026
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
변경 요약
#8130은 작성자가 미병합 종료한 중복 구현이므로 기능 적용 목록에서 제외하고 정상 검사·입력만 유지합니다.
review/planet6897-202610249418ed0c7cf289c5c4ac2b3bb8cdc18a1b637a9a관련 이슈
Refs #8099, #8105, #7687, #8156, #7874, #8169, #8167, #8172, #4599, #7445, #7765, #7881
부분 개선을 전체 해결로 확대하지 않습니다. 실제 완료 범위와 종료 대상은 최종 검증 뒤 확정합니다.
테스트
검증 code head:
673c1d5f7cdcb5573b793ba2d2abaaedd2602134. 제출 asset head:826b57e5d0c22b93ea03f41018e83167d95b57e6. 후자는 review·TSV·PNG·검증 기록만 추가하며 제품/테스트 소스는 동일합니다.CI 보정 head:
9604f6e42e89966b4e3d1968cbc79edf73890596. 사용자 지시로 삭제한 편람 Gym 과제 8건을 원장 기대 건수에도 반영했습니다(949→941). 이 커밋은 Python 검사 기대값만 바꾸며 Rust·Studio·렌더링 소스는 동일합니다. CI와 동일한 Gym 계약 2,125건을 로컬 재실행해 실패 0·skip 1을 확인했습니다. 해당 head의 Gym CI는 통과했습니다. 아래 후속 CI 참조 보정 때문에 최종 CI는 새 head에서 확인합니다.CI 실행 명령 출력 참조 보정 head:
b1e93d8de2d4842f725415aee19bd5b98ecfb8b3. 삭제한 편람issue_1035_alignment대신 유지 중인mcp_password_contract의--print결과를 확인합니다. workflow 정책·게이트는 바꾸지 않았으며 동일 manifest·unit-tier·명령 출력·workflow 계약 6개 명령을 로컬 재실행해 모두 exit0을 확인했습니다. 현재 head의 Full CI는 성공했고, merge3e02fe2749866a8453af3eb3901b9c1a674cccaf로 devel에 반영했습니다. 사용자 지정 옵션 2의 문서 PR #8231도 fast-pass 후 merge238de6de41a208648f4ade6b494fe433a81c1fce로 반영했습니다. 이 PR에는 trailing commit을 추가하지 않았습니다.브랜치
review/planet6897-20261024, 고정 base9418ed0c7cf289c5c4ac2b3bb8cdc18a1b637a9a.Summary [1920.075s] 11481 tests run: 11481 passed (46 slow), 45 skipped, exit0. MCP 실패 1건은 선택한 fixture 기대값 연결로 복구했고 관련4건도 모두 PASS입니다.필수 게이트 14개 exit0: fmt, Native/WASM/workspace all-target/Native Skia Clippy, workspace build, 전체 nextest, Skia lib/placeholder/direct PDF, manifest/unit tier/Node 계약 검사.
renderer focused16 PASS. Studio runtime/unit source 불변 확인 후 기존 unit 2,572 PASS/2 skip, TypeScript 2종·AI 포함/제외 build PASS 근거를 재사용했습니다. AI mock SSE E2E93 assertions/exit0와 현재 fresh WASM actual Native15/Canvas2D15/지원CanvasKit12를 구분합니다.
외부 PR 통합 검토는 현재 지침에 따라 clean 주 작업공간의 review branch에서 수행했고 검토 Cargo target을 명시했습니다. 글꼴 예외·새 npm/editor API·capability 카탈로그 변경은 비해당입니다.
Mac fresh WASM은 locked wrapper
--target web --out-dir pkg --no-opt로컬 대체 빌드이며 Docker 최적화 통과가 아닙니다.전체 검증 기록 · 개별 PR·입력·페이지·그림·바이트 해시 대응.
제출 asset·review·오늘할일 223개를 이 head의 실제 raw URL에서 다운로드했고 HTTP200·바이트·SHA-256 일치를 확인했습니다. 게시한 본문 API가 준비본과 정확히 같고 실제 GitHub 화면에서 review·overlay가 표시되는 것을 확인했습니다.
변경 범위별 필수 검증을 수행하고, 제출 HEAD가 검증한 commit과 같음을 확인
Rust source·test/baseline helper·Rust 검증 입력 변경 시: 별도 worktree 준비 후
cargo fmt --all -- --check, native·WASM32·workspace all-target Clippy 통과Rust 변경 시: 범위에 해당하는 focused·전체 integration·Native Skia 회귀 및 시각 검증 수행
조판 영향 여부를 실제 소비 경로로 판단했고, 영향이 있으면 Native/fresh WASM Visual Sweep·페이지별 TSV·직접 review/overlay 확인 완료 (한 페이지라도 90% 미만 또는 측정 불가이면 본인 branch에서 수정·재실행; 정확히 90%는 통과)
전체 Native/fresh WASM TSV 원문을 본문에 넣고 게시 후 API로 확인했거나, 본문 크기 제한 시 asset 원본의 SHA 고정 raw 링크를 넣고 다운로드 바이트·SHA-256이 생성 원본과 같은지 확인함 (저장소 보존·링크 예시)
렌더링 회귀 추가·변경 시: 같은 원본·독립 한컴 Print PDF의 관련 모든 페이지에서 Native/fresh WASM 최저 90% 이상을 먼저 확인했고, 절대 px 좌표·고정 px 영역 대신 문단·줄·개체의 소유·순서·보존·포함·겹침 관계를 검사함 (기존 회귀 실패 시 원본 출력 보정 → 90% 이상 확인 → 필요한 검사 변경; 글꼴 예외로 이 선행 조건을 면제하지 않음)
90% 통과 후에도 변경 영역·알려진 차이·사용자 지적 영역을 독립 Print PDF와 Native/fresh WASM의 같은 배율로 확대 대조하여 수식 모양·장평·기준선·첨자·장식 및 관계 기호·본문·보기 번호·탭·줄 사이 간격을 확인했고, 점수와 직접 판독 결과를 별도로 기록함 (확대 판독 절차)
90% 미만의 해결 불가능한 글꼴 문제로 제출한다면 글꼴 예외 계약의 공급 시도·배치/쪽수 일치 근거와
font_mismatch_exception기록 첨부 (TSV 원값 유지, 측정 누락·배치 결함은 면제하지 않음)기준 PDF는 원본 저장 버전에 맞는 한컴 Print 인쇄 경로로 출력했고, 제품/빌드·인쇄 설정·출처 확인 (MCP 2020/2024 및 수동 출력 계약)
새 integration test는 원본을
tests/cases/*.rs에만 추가했고tests/generated/,tests/suites/manifest.json, 일반 PR의 Cargo generated test target을 포함하지 않음 (--sync-cargo-targets메인터너 registry PR은 marker 블록만 예외)src/**또는crates/*/src/**의#[cfg(test)]변경 시:node scripts/rust-unit-test-tiers.mjs --check --base-ref <검증한-PR-base-SHA>통과 (무생성 검사)Studio 변경 시: 테스트 전용 unit 또는 fresh dev WASM package 검증 통과, 브라우저 동작 변경 시 관련 E2E·실제 동작 확인 · 명령/결과:
편집 command·Undo/Redo 변경 시: 편집 체크리스트 확인; E2E 미실행 시 사유와 대체 증적 기록
npm/editor 변경 시: 해당 package·embed 계약 검사 수행
문서 변경 시: 최신 base 기준
git diff --check upstream/devel...HEAD및git diff --check, 링크·내용 정합성과 변경한 실행 절차 확인(에이전트 보조 작업 권장) 작업 증빙 첨부 —
rhwp replay --capsule영수증 캡슐 또는 관련--json봉투 원문 (AGENTS.md 작업 증빙 절).claude/agents/,.claude/skills/,.agents/skills/변경 시: capability 카탈로그의 등록·검증 규칙을 반영조판 변경 근거 (해당하는 경우)
Visual Sweep 직접 증적 (해당하는 경우)
같은 입력·독립 한컴 Print PDF·글꼴 공급, canonical
visual_sweep.py, PDFium, Print profile/96 CSSpx,2px 관용입니다. 원본·PDF·실제 renderer의 SHA와 명령은 검증 기록에 연결했습니다.Native/fresh WASM 각각35조건·2,041쪽, 최저91.87422% /91.82753%,90% 미만·누락0쪽입니다. 고정 base 대비 raw 0.1%p 이상 하락0쪽입니다.
쪽수 개선3조건(offset-min3→2, 정책연구65→64, 온새미로 변환본48→46)은 같은 쪽 번호의 raw 대신 본문 소유·순서·문자 보존을 별도로 검증했습니다.
Native SHA-256:
e1389384bfb2fbd9e22f350979123af4a590b6116887d7ea1c4d4c79ba7a5e45.fresh WASM SHA-256:
0a81d25f3e910d91d9b89fa5a06dbcb5cd6f38d126cb2caf3b1abb27bffe118d.root/pkg·Studio public·실제 WASM HTTP200 응답 hash를 확인했습니다. Vite JS 응답은 변환된 응답 hash와 원본 source hash를 구분했습니다.
field-resetfield-plainsymbol-slot-2020symbol-slot-2024titled-hostsaved-hostomitted-afterhwp5-controlonsaemiro-controloffset-minrowspan-headertac-successorpolicy1790387-actualbriefing1487franchiseregulatory86712cbta1613task1749xtask1749hnear-top-resetcurriculum-controlmath1342000-actualroadmap-controlonsaemiro-converted-controlsource8152-d2176source8152-d17253source8152-d80168source8152-d1853source8152-d1880source8152-d5169source8152-hfinesource8152-ha10msource8152-dbandsource8152-hs2source8152-d80168x#8111 ·
onsaemiro-control· Print p36 ↔ rhwp p36samples/[2027] 온새미로 1 본교재.hwp, 기준pdf/[2027] 온새미로 1 본교재-hwp-2020.pdf.#8141 ·
symbol-slot-2024· Print p1 ↔ rhwp p1samples/lang_slot/symbol_slot_bullets.hwpx, 기준pdf/lang_slot/symbol_slot_bullets-2024.pdf.#8152 ·
curriculum-control· Print p178 ↔ rhwp p178mydocs/pr/assets/issue7445/education-curriculum-map/1342000_edu_curriculum_map.hwp, 기준mydocs/pr/assets/issue7445/education-curriculum-map/existing-hwp-hancom2020-print.pdf.#8157 ·
titled-host· Print p1 ↔ rhwp p1samples/issue7687/titled-host.hwpx, 기준pdf/issue7687/titled-host-2020.pdf.#8159 ·
saved-host· Print p1 ↔ rhwp p1samples/issue8156/titled-host-hancom2020-saved.hwp, 기준pdf/issue8156/titled-host-hancom2020-saved-2020.pdf.#8163 ·
omitted-after· Print p2 ↔ rhwp p2samples/issue7874/omitted-spacing-after.hwpx, 기준pdf/issue7874/omitted-spacing-after-2024.pdf.#8185 ·
rowspan-header· Print p3 ↔ rhwp p3samples/issue4599/1790387_rowspan_header_repeat.hwpx, 기준pdf/1790387_rowspan_header_repeat-2020.pdf.개별 PR 검토 기록
CBTA48쪽의 그림 안 작은 글자 농도·본문 자형 차이는 남습니다. 현재 raw는 base보다 높으며 별도 품질 개선을 추가하지 않았습니다. 원 정책연구6쪽 범례의 작은 상자/raster 차이도 잔여로 기록합니다. #7445·#8105·#4599 전체 해결로 확대하지 않습니다.
성능 영향 및 측정 결과 (해당하는 경우)
기존 전체 회귀·실물 검증의 실행 시간은 검증 기록에 남겼습니다. 별도 성능 벤치마크 개선을 주장하지 않습니다.
스크린샷
#8170의 mock SSE browser E2E 화면입니다. Print 일치율·실제 유료 API 성공 증거와 구분합니다.
병합 후 확정 결과
no-verified-pr-duration-measurements로 갱신을 보류했습니다. 문서 PR에서 worker를 실행하지 않은 정상 결과이며 CI를 재실행하지 않았습니다.