Conversation
작업지시자 발언 (2026-04-29, v0.7.8 PATCH 결정 후): "우리의 프로젝트는 운영의 기술이 절실하게 필요한 때 입니다. 자칫 너무 많은 걸 묶어 완성도를 높이려는 행위가 위험요소를 높인다는 판단입니다." 본 결정의 정황 + 운영 철학을 메모리로 보존: - 활발한 컨트리뷰션 사이클 (외부 기여자 9명) 에서 큰 묶음의 위험 - v0.x 단계 SemVer 유연 적용 (opt-in / 하위 호환 신규 API 도 PATCH 가능) - 컨트리뷰터 동기 유지가 핵심 자산 - "완성도 100% 후 릴리즈" 함정 회피 - 소프트웨어 엔지니어링 고전 원칙 (small batch / continuous delivery / risk decomposition) 과 일치 활성 메모리 + 백업 (mydocs/manual/memory/) 동기화 완료.
- mydocs/pr/pr_437_review.md (브라우저 확장 URL 해석/검증, dry-run cherry-pick + 검증 게이트 통과 + ESM 정황 발견) - mydocs/orders/20260429.md (PR #437 작성자 보강 대기 + v0.7.8 릴리즈 + Discussion #438 행 추가) 핵심: 코드 본질 정상 + 12 단위 테스트 통과 (.mjs 실행 시) + Rust core 영향 0 정황: PR 본문 명시 자동 테스트 명령이 rhwp-shared/package.json 부재로 실행 불가 요청: rhwp-shared/package.json 추가 ("type": "module") 권장 (선택지 1) PR #437 OPEN 유지, 작성자 재제출 대기
- mydocs/pr/pr_437_report.md (작성자 후속 정정 commit 1건 추가 흡수, 자동 테스트 38건 통과) - mydocs/orders/20260429.md (PR #437 완료 행으로 갱신) 작성자 신속 응답: - 1차 검토 후 17분 만에 권장안 정확 채택 (rhwp-shared/package.json 신규) - 보너스 효과: ESM 선언으로 download-interceptor-common.test.js (26 tests) 도 정상화 검증: 1066 passed + svg_snapshot 6/6 + issue_418 1/1 + clippy 0 + document-url-resolver 12 + download-interceptor-common 26 + Rust core byte 동일
exam_kor.hwp 24페이지 → 20페이지 정합 작업 1단계. - 페이지별 단별 used/hwp_used/diff CSV (output/debug/task435/) - 회귀 대상 5문서 페이지 수 (exam_kor 24, exam_eng 8, k-water-rfp 28, hwpspec 177, synam-001 35) - RHWP_TYPESET_DRIFT 출력 캡처 (pi=0.30, pi=1.25 split 진단) - compute_body_wide_top_reserve_for_para 산정 경로 추적 핵심 진단: col 1 reserve 306.1px (HWP 실제 94.5px 대비 +211.6px 과대). 원인: Paper-rel 좌표를 body-rel 변환 없이 그대로 reserve 에 누적. Stage 2 에서 typeset.rs:2127-2172 의 VertRelTo::Paper 분기 정정. 수행계획서/구현계획서/Stage 1 보고서 포함.
compute_body_wide_top_reserve_for_para 의 VertRelTo::Paper 분기에서 body-rel 변환 누락 정정. body 와 일부만 겹치는 (header→body 침범) 케이스에서 Paper-rel 좌표를 그대로 reserve 에 누적하던 버그 수정. 수정 전 reserve = shape_y_offset(paper) + h + outer_bottom = 306.1 px 수정 후 reserve = max(0, shape_top_abs - body_top) ... = 94.4 px 결과: - exam_kor.hwp: 24 → 22 페이지 (page 2, 15 orphan 해소) - pi=0.30, pi=1.25 split → FullParagraph - 회귀: exam_eng 8, k-water-rfp 28, hwpspec 177, synam-001 35 유지 - cargo test: 1062 passed Stage 3 에서 일반 페이지 누적 -100~-300px 정정 (22 → 20).
원래 가설 ("표/도형 후 컬럼 잔여 공간 산정 부족") 재검토.
RHWP_TYPESET_DRIFT 분석 결과 diff 메트릭은 typeset cur_h 누적
(height_for_fit, trail_ls 제외) vs hwp_used (last line vpos+lh)
의 좌표계 차이를 측정하는 것일 뿐, "rhwp 가 채울 수 있는데 못 채운
잔여 공간" 이 아님을 확인.
실제 22→20 페이지 단축 장애물:
1. 섹션 1 페이지 14: Square wrap 표 + col 0 over-fill (1225>1211)
→ col 1 under-use (64px)
2. 섹션 1 페이지 15: 단일 컬럼 출력 (단정의는 2단인데 단 1 누락)
3. 섹션 2 페이지 18: pi=11 split + pi=13 [단나누기] orphan-like
3가지 전부 해결 시 22→19 가능 (목표 20 도달).
옵션 A/B/C 결정 필요 (현 상태 종료 / Stage 4 확장 / Stage 4 부분).
옵션 A 종료: 24→22 페이지 (Stage 2 col 1 reserve 정정). 잔여 22→20 미달성, 3가지 별도 메커니즘 (Square wrap over-fill, 단일 컬럼 출력 버그, col 0 cur_h over-advance) 별도 task 분리 권고.
- mydocs/pr/pr_442_review.md (Task #435 cherry-pick 검토) - mydocs/pr/pr_442_report.md (cherry-pick 머지 결정 + Canvas 시각 판정 통과) - mydocs/orders/20260429.md (PR #442 완료 행 추가) 검증: 1066 passed + svg_snapshot 6/6 + issue_418 1/1 + clippy 0 + WASM 4,174,855 bytes 광범위 byte 비교: 285/309 동일, 24 차이 (exam_kor 한정 — 의도된 정정) 시각 판정: 작업지시자 Canvas (rhwp-studio) 통과 본질: typeset.rs Paper-rel→body-rel 변환 정정 (32 lines) exam_kor 24→22 페이지 (page 2/15 orphan 제거), col 1 reserve 306.1→94.5px (HWP ±0.2) 잔여 22→20 정합: #439/#440/#441 별도 이슈 (작은 단위 회전 정책 부합)
수행계획서(task_m100_439.md) + 단계1 진단 보고서. 핵심 발견: - 이슈 가설의 engine.rs:702-711 는 fallback 경로 (RHWP_USE_PAGINATOR=1). 기본 활성 엔진은 typeset.rs::TypesetEngine. - 실제 버그 위치: typeset.rs::place_table_with_text (1400-1467). engine.rs 의 !is_wrap_around_table 가드 (engine.rs:1349, 1422) 누락. - 페이지 14 col 0 used=1225.8 (본문 1211.3 초과 +14.5) 정확히 재현. 코드 변경 없음 — 임시 디버그 코드는 모두 revert.
place_table_with_text 의 정확한 cur_h 누적 추적 (디버그 후 revert): - Square wrap 4 표가 pre_height + table_total 합산 → +244.88 px 과다 - HWP 의도: max(호스트 텍스트, 표 + v_offset) 만 누적 수정안: typeset.rs::place_table_with_text 에서 current_height += max(pre_height, v_off + table_total) (Square wrap 시) 코드 변경 없음 — 임시 디버그 println 모두 revert.
typeset.rs::place_table_with_text 에서 Square wrap (어울림) 표일 때 current_height 누적을 pre_height + table_total → max(pre_height, v_off + table_total) 로 변경. 호스트 문단 텍스트와 어울림 표는 같은 수직 영역을 공유하므로 더 큰 쪽만 한 번 누적해야 HWP layout 의도와 일치. PageItem 자체는 PartialParagraph + Table 모두 push (layout 렌더링 보존). 검증: - 페이지 14 col 0 used 1225.8 → 1036.1 px (≤ 1211.3 충족) - exam_kor.hwp 22 → 20 페이지 (목표 ≤ 21 충족) - 회귀 샘플 6 종 (exam_eng/math, 21언어, aift, 2010-01-06, biz_plan) 페이지 수 동일 - cargo test 1066 개 모두 통과 - SVG 렌더링 정상 closes #439
Stage 4 회귀 검증 결과: - 149 개 sample HWP 전수 페이지 수 비교: exam_kor 만 22→20 변경, 148개 동일 - cargo test 1066 passed - DoD 전부 충족 본 task 완료. closes #439.
- mydocs/pr/pr_443_review.md (Task #439 cherry-pick 검토) - mydocs/pr/pr_443_report.md (cherry-pick 머지 결정 + SVG/Canvas 시각 판정 통과) - mydocs/orders/20260429.md (PR #443 완료 행 추가) 검증: 1066 passed + svg_snapshot 6/6 + issue_418 1/1 + clippy 0 + WASM 4,178,523 bytes 광범위 byte 비교: 298/307 동일, 9 차이 (exam_kor 한정 — 의도된 정정) 시각 판정: 작업지시자 SVG + Canvas 양 경로 통과 본질: typeset.rs Square wrap 표 누적 정책 max 적용 (32 lines) exam_kor 22→20 (페이지 14+15 통합), col 0 1225.8→1036.1px, col 1 64.3→1016.9px @planet6897 본 사이클 9번째 PR (가장 활발), PR #442 머지 직후 잔여 작업 즉시 처리
README.md와 CONTRIBUTING.md에 산재한 테스트 수량(755/783/891/1014)을 실제 값(1,100+)으로, mydocs 파일 수(724)를 실제 값(2,200+)으로 일괄 갱신합니다. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
PR #444 (@oksure) 가 한글 README + CONTRIBUTING.md 의 수치 갱신 시 README_EN.md 가 누락된 정황. 한글/영문 일관성 위해 메인테이너 후속 정정. 영문 README 갱신 5곳: - L72 (Roadmap): 935+ tests → 1,100+ tests - L262 (Quick Start): Run tests (935+ tests) → (1,100+ tests) - L357 (Project Structure): English translations (724 files) → (2,200+ files) - L378 (AI 비교 Quality gate): 935 tests → 1,100+ tests - L381 (AI 비교 Documentation): 724 files → 2,200+ files - L400 (mydocs 설명): (724 files, ...) → (2,200+ files, ...) PR #444 의 수치 갱신 흐름과 정합 (한글 README 의 891+/755+/783/724 → 1,100+/2,200+).
Stage 1 의 trailing line_spacing 일괄 적용으로 각주 사이 gap 이 line_spacing 만큼 늘어나는 회귀 발견 (각주 2)→3), 3)→4), 4)→5) gap +9.6px). 다음 각주와의 간격은 note_spacing 이 책임하므로 각주 마지막 paragraph 의 마지막 line 에서는 trailing line_spacing 을 누적하지 않도록 정정. 수정: - layout_footnote_paragraph_with_number 에 is_last_para_of_fn 인자 추가 - 각주 마지막 paragraph 의 마지막 line 에서 y += line_height (trailing ls 미적용) - 그 외 line/paragraph 는 y += line_height + line_spacing_px (Stage 1 의도 유지) - layout_footnote_area 에서 layout_composed_paragraph 호출 결과도 마지막 paragraph 면 trailing ls 만큼 빼서 보정 검증 (samples/2010-01-06.hwp 페이지 1 각주 영역): 각주 1) p[0]→p[1]: 16.0 → 20.8 ✓ (Task #483 핵심 정정 유지) 각주 1) p[1]→p[2]: 20.8 → 20.8 ✓ 각주 2)→3), 3)→4), 4)→5): 23.6 (baseline 동일, 회귀 해결) cargo test --release 1078 + 모든 통합 통과, 골든 SVG 6 통과.
…, cherry-pick @planet6897)
… 셀 alignment + Task #483 각주 line_spacing, cherry-pick @planet6897)
exam_science.hwp p1 pi=21 (5번 문제) 어울림 그림이 본문 첫 줄을 가리는 결함 정정. 근본 원인: layout_composed_paragraph 가 col_area.width 로 available_width 를 계산하여 LINE_SEG.segment_width 를 무시. 표 Square wrap (#362/#439/#463) 은 caller 가 col_area 자체를 wrap_area 로 좁혀 우회하지만, Picture/Shape 는 호스트 paragraph 와 같은 paragraph 에 anchor 되어 별도 우회 경로 부재. 수정: 비-TAC Picture/Shape with wrap=Square 보유 시 LINE_SEG.cs/sw 를 effective_col_x/effective_col_w 로 적용. 200 HU 가드로 페이지 네이션 노이즈 제거. 표 Square wrap 케이스는 caller 가 col_area 자체를 좁혀 호출 → segment_width ≈ col_area_w_hu → 조건 미발동 (회귀 차단). 검증: exam_science p1 pi=21 정정 + p2 pi=37 동일 패턴 자동 정정. 단위 테스트 1 추가, cargo test 1093 + svg_snapshot 6 + issue_418 1 통과. 9 종 샘플 263 페이지 byte 비교 = 261 동일 / 2 정정 (회귀 0). 보조: main.rs dump 명령에 horz_align/vert_align 표시 (디버깅 효율). closes #489
… 텍스트 LINE_SEG, cherry-pick @planet6897)
…LINE_SEG, cherry-pick @planet6897)
table_layout.rs:1573 의 셀 paragraph 인라인 Shape (treat_as_char) 분기가 composed.lines.first() 만 보고 text_before 추출 → multi-line paragraph 에서 사각형이 ls[1]+ 에 있을 때 첫 줄 전체 텍스트가 paragraph_layout 결과와 중복 발행되어 시각적 겹침 발생. 가드: tac_pos 가 paragraph 첫 줄 char 범위 안일 때만 text_before 발행. - 단일 줄 paragraph: 기존 동작 (synam-001 p31 "년 월 일" 발행 보존) - multi-line + 사각형 ls[0] 안: 기존 동작 - multi-line + 사각형 ls[1]+: 차단 (결함 케이스 핀포인트) 검증: - exam_science p2 박스 안 baseline 19→9, 중복 10건 제거 - 64 SVG 회귀 검증: 변경 1건 (의도된 결함 수정), 회귀 0건 - cargo test 전체 통과 단계 3 v1 (TextRun 제거) 시도가 synam-001 p31 회귀 발생 → 옵션 B 가드로 전환. 사각형 자체 위치 결함, #496 (12번 줄간격 압축) 은 별도 task 분리. closes #495
…기 가드, cherry-pick @planet6897)
… cherry-pick @planet6897)
작성자 devel 분기 누적 9 Task (97 commits) 중 페이지 레이아웃 무관 5 Task 만 분리 cherry-pick. 본 사이클 정정 영역 (#501) 과 충돌 위험 큰 4 Task (#476, #479, #480, #492) 제외. 흡수 (8 commits): - #488 (3): 수식 토크나이저 prefix 분리 + 렌더러 italic - #490 (1): 빈 텍스트 + TAC 수식 셀 alignment - #483 (2): 각주 multi-paragraph line_spacing - #489 (1): Picture+Square wrap 호스트 텍스트 LINE_SEG - #495 (1): 셀 paragraph 인라인 Shape 분기 가드 (부분 정정) 검증: cargo test --lib 1102 passed, svg_snapshot 6/6, issue_418 1/1, issue_501 PASS, clippy 0건, WASM 4,211,238 bytes. 작업지시자 시각 판정: 1차/2차 통과 + 3차 (#495) 부분 정정 → 옵션 B (개선 흡수 + 잔존 결함 별도). 이슈 #502 (문단 내 글상자 TextRun 처리) 분리 등록. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
페이지 14 [A] 박스(wrap=Square 표)가 단 1 본문이 아닌 단 0과 단 1 사이의 갭 영역에 그려지던 문제 해결. 근본 원인: layout.rs:2256-2270 Square wrap 분기가 col_area.x 만 사용 하고 paragraph effective_margin(=margin_left + indent)을 미반영. TAC 표 분기는 동일 패턴에서 effective_margin 을 적용했으나 Square wrap 분기는 누락. 수정: area_x = col_area.x + effective_margin / area_w = col_area.width - effective_margin - margin_right 로 paragraph 영역 기준 정렬. halign=Right/Center 도 동일 기준 적용 (Task #295 호환). 검증: - 페이지 14 [A] 박스: x 580.9 → 605.5 (paragraph 영역 안) - cargo test --release: 1078 + 모든 통합 통과 - 골든 SVG 6건 통과 - Task #295 (halign=Right) 동작 호환 closes #480
…aragraph margin 반영, cherry-pick @planet6897)
…h margin 반영, cherry-pick @planet6897)
paragraph가 페이지에 걸쳐 분할(PartialParagraph)될 때 인라인 treat_as_char Shape의 PageItem::Shape가 무조건 마지막 페이지에 등록되어 박스가 잘못된 페이지의 fallback 위치(예: y=742.45)에 출현하던 문제 해결. 근본 원인: TypesetEngine/Paginator의 process_controls가 Shape 분기에서 무조건 st.current_items.push 함. paginate_text_lines가 paragraph를 이미 다음 페이지로 진행시킨 상태이므로 박스가 line 0의 페이지가 아닌 마지막 페이지에 라우팅됨. 그 결과 박스의 페이지 tree에 inline_pos가 없어 shape_layout의 compute_object_position fallback이 잘못된 위치에 박스를 그림. 수정: - pagination.rs에 find_inline_control_target_page 공용 함수 추가: 박스의 char 위치 → line index → 그 line이 라우팅된 (page_idx, col_idx) 반환 - TypesetEngine(메인) / Paginator(fallback) 양쪽의 Shape 분기에서 호출하여 treat_as_char Shape를 박스가 속한 페이지/단의 column_contents.items에 push - shape_layout.rs:218에 회귀 안전장치(D): treat_as_char + inline_pos=None 시 박스 렌더 스킵. RHWP_DEBUG_LAYOUT=1 시 stderr 로깅 - paragraph_layout.rs:2087 빈 paragraph 분기에 Shape의 inline_pos 등록 추가 (Picture만 처리하던 누락분 보강 — D 차단 false positive 방지) 검증: - cargo test --release: 1078 + 모든 통합 테스트 통과 - golden SVG 6건 모두 통과 - samples/21_언어_기출_편집가능본.hwp 페이지 11/12 시각 비교 정상 closes #476
…Shape 페이지 라우팅, cherry-pick @planet6897)
…이지 라우팅, cherry-pick @planet6897)
PR #478 close 후 추가 cherry-pick 진행: - 4차 #480: wrap=Square 표 paragraph margin (82fd66e) - 5차 #476: PartialParagraph 인라인 Shape 페이지 라우팅 (5955b10) 총 7 Task / 10 commits 흡수. 미흡수 #479 (paragraph trailing line_spacing) 는 한컴 2020 정답지 시각 판정 필수로 이슈 #503 분리. 작업지시자 통찰: "#479 는 회귀쪽에서 실패가 납니다. 이건 따로 분리해서 한컴 2020 버전으로 시각판정을 해야 합니다." 검증: cargo test --lib 1102 passed, WASM 4,202,430 bytes, 4차/5차 시각 판정 모두 통과. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…w + 보안 hardening, cherry-pick @seo-rii 7 commits)
…7 commits) 본 PR 은 PR #456 (PageLayerTree replay 전환 P2) 후속 P3 검증 레이어: - rhwp-studio E2E (canvas-render-diff.test.mjs) - GitHub Actions Render Diff workflow - legacy Canvas vs PageLayerTree replay Canvas 픽셀 diff 자동 검증 7 commits 분리 cherry-pick (test + diagnostics + docs + CI runner + 보안 hardening 3건). 변경 영역: JS E2E + CI workflow + Vite 설정 + 문서 (Rust 변경 0). 검증: cargo test --lib 1102 passed, svg_snapshot 6/6, issue_418 1/1, issue_501 PASS, clippy 0건. 작업지시자 정책: ios/devel 처럼 skia 쪽 렌더러도 별도 브랜치로 운영하여 위험도 낮추는 방법 고려 중. 본 검증 인프라가 향후 별도 backend 실험 시 backend 별 회귀 검출 도구로 활용 가능. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
본 사이클 본질: - Task #501 (cell.padding 한컴 방어 로직 모방 정정, closes #501) - PR #428 (oksure — 그룹 내 그림 직렬화) - PR #494 (DanMeon — Paragraph::utf16_pos_to_char_idx 외부 노출, #484) - PR #478 (planet6897 — 7 Task / 10 commits cherry-pick: #488/#490/#483/#489/#495/#480/#476) - PR #498 (seo-rii — Canvas visual diff 파이프라인, relates #364) 미흡수 + 분리: - 이슈 #502 (#495 잔존 — 문단 내 글상자 TextRun 처리) - 이슈 #503 (#479 미흡수 — 한컴 2020 시각 판정 필수) 버전 갱신: Cargo.toml + npm/editor + rhwp-studio + rhwp-vscode 모두 0.7.8 → 0.7.9. CHANGELOG (한/영) 갱신, rhwp-vscode/CHANGELOG.md 갱신. README 기여자 감사 누적 갱신 (cskwork/DanMeon/oksure/planet6897/seanshin/seo-rii 추가). 검증: cargo build OK, cargo test --lib 1102 passed, cargo clippy 0건, WASM 빌드 정합. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
edwardkim
pushed a commit
that referenced
this pull request
May 4, 2026
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.
v0.7.8 후속 사이클 릴리즈 PR.
본질
미흡수 + 분리
검증
외부 기여자 감사
본 사이클: @DanMeon, @oksure, @planet6897, @seo-rii
상세는 CHANGELOG.md / CHANGELOG_EN.md 참고.
🤖 Generated with Claude Code