Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions mydocs/orders/20260512.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@
| **PR #818 (closes #790)** | perf — release 빌드 LTO + codegen-units=1 + strip 활성화 | **완료 (옵션 A — 2 commits cherry-pick + Cargo.toml 충돌 수동 해결 + 정량 측정 + no-ff merge `f5abcf8d`, 시각 판정 면제 + sweep byte-identical 입증)** | 컨트리뷰터 @oksure (Hyunwoo Park) — **20+ 사이클** 핵심 컨트리뷰터 (5/11 사이클 15번째 시도, PR #815/#817 close 후 다른 본질, 5/12 사이클 본질적으로 첫 머지). 본질: Issue #790 (외부 제안, ripgrep profile 패턴 정합) 영역 Cargo.toml [profile.release] 영역 LTO + codegen-units=1 + strip 활성화 — 바이너리 크기 축소 + 런타임 성능 개선. 정정 (`Cargo.toml` +5/-0, 1 file): `[profile.release]` 영역 영역 `lto = true` (Fat LTO 크로스 크레이트 인라이닝) + `codegen-units = 1` (전역 최적화 극대화) + `strip = "debuginfo"` (디버그 정보 제거, panic backtrace symbol table 보존). **리뷰 반영 commit** (`9ccb0c38`): 초기 `strip = true` → `strip = "debuginfo"` 정정 영역 panic backtrace 보존 정합. **본 환경 충돌 수동 해결** (Cargo.toml): devel 측 PR #599 example pr599_png_gateway (native-skia required) + PR 측 [profile.release] 양측 모두 보존 정합. **본 환경 정량 측정 ★ 핵심 결과**: (1) rhwp CLI 크기 **14 MB → 10 MB (-4 MB, -28%)** (2) WASM 크기 **4.6 MB → 4.3 MB (-0.3 MB, -6.5%)** (3) cargo build --release (clean) ~58s → 2m 53s (+1m 55s, ~3배) (4) WASM 빌드 (Docker) ~1m 30s → 2m 23s (+53s, +59%) (5) cargo test --release ALL GREEN + cargo clippy --release --lib -D warnings 통과 (6) **광범위 sweep 7 fixture / 170 페이지 / 170 same / 0 diff (byte-identical)** ✅ — SVG 출력 무영향 입증. 본 환경 cherry-pick 2 commits 영역 영역 1 충돌 수동 해결. **효과 분석**: 이득 — rhwp CLI -28% + WASM -6.5% 크기 감소 (사용자 다운로드 시간 + 메모리 사용량 개선) / 비용 — release 빌드 시간 ~3배 증가 (개발 빌드 영향 부재) / 회귀 부재 — sweep byte-identical + cargo test/clippy 통과. CI 결과 부재 (DIRTY 영역, 본 환경 자기 검증 + 정량 측정 + sweep 영역 보완). 검토 보고서: `mydocs/pr/archives/pr_818_review.md`. 처리 보고서: `mydocs/pr/archives/pr_818_report.md`. **`feedback_contributor_cycle_check` 정합** — @oksure 20+ 사이클 (5/11 15번째 시도, 5/12 본질적으로 첫 머지). **`feedback_image_renderer_paths_separate` 정합** — Cargo.toml 빌드 설정 영역 영역 렌더링 경로 무관. **`feedback_process_must_follow` 권위 사례 강화** — 본 환경 영역 영역 WASM 빌드 측정 필수 — 컨트리뷰터 PR 영역 영역 native 측정만, 본 환경 영역 영역 WASM 4.3 MB 추가 측정 (4.6 → 4.3, -6.5%) + sweep 결정적 검증 표준 영역 영역 회귀 부재 입증. **`feedback_small_batch_release_strategy` 권위 사례 강화** — 작은 변경 (+5/-0) + opt-in (release 한정, 개발 빌드 영향 부재) + 명확 효과 (-28%/-6.5%) — PATCH cycle 머지 정합. **`feedback_hancom_compat_specific_over_general` 정합** — strip = "debuginfo" (panic backtrace 보존) 영역 회귀 부재 가드 + sweep byte-identical. **`feedback_visual_judgment_authority` 정합** — 빌드 설정 영역 영역 시각 판정 면제, sweep 결정적 검증 통과. **`feedback_pr_supersede_chain` 정합** — Issue #790 (외부 제안, OPEN) → **PR #818** (LTO + CU1 + strip 적용) 본질 정합. |
| **PR #817 (close, Refs #726)** | fix — 1×1 래퍼 표 shortcut 다수 중첩 표 누락 수정 | **close 완료 (옵션 C — Task #688 이미 해결 + byte-identical SVG + 컨트리뷰터 분리 PR 가이드)** | 컨트리뷰터 @oksure (Hyunwoo Park) — **20+ 사이클** 핵심 컨트리뷰터 (5/11 사이클 14번째 시도, PR #815 close 후 다른 본질). PR 본문 본질: table-vpos-01.hwpx 5쪽 nested 11×3 그리드 SVG 완전 누락 정정 — `find_map` 영역 영역 첫 nested table 만 반환 결함 영역 영역 `nested_table_count == 1` 가드 영역 영역 다수 table 시 일반 경로 (`src/renderer/layout/table_layout.rs` +6/-1). **⚠️ devel HEAD 영역 영역 이미 해결됨 (Task #688, PR #694, commit `40ecbe26`)**: `cell.paragraphs.len() == 1` 가드 — paragraphs 수 가드 + 외곽 박스 border 렌더링 추가 정합 (exam_social.hwp pi=15 자료 박스 등 padding + border_fill 영역 외곽 4 라인 추가). table-vpos-01.hwpx p.5 영역 영역 셀[0] paras=2 → Task #688 가드 false → shortcut 우회 → 일반 경로 영역 모든 nested table 렌더링. **PR base 분석**: PR #817 base = `30351cdf` (5/9, Task #688 머지 전) — 본 PR 작성 후 Task #688 영역 영역 같은 본질 영역 다른 방식 영역 먼저 머지 → 본 PR 영역 중복 정정 + 외곽 박스 border 회귀 위험. **작업지시자 시각 비교 요청** — 본 환경 cherry-pick + 5쪽 SVG 내보내기 (output/svg/pr817/before vs after): text=343/polygon=0/image=0/path=2/lines=474 양측 동일 + **diff exit code 0 byte-identical** 입증 → PR 영역 영역 본 환경 효과 부재. **Issue #726 영역 영역 진짜 본질**: 4대 그룹 사이 구분 도형 (화살표) 2개 SVG 미출력 — 본 PR 본문 (nested 11×3 그리드 누락) 영역 영역 다른 본질. devel HEAD = PR 적용 후 동일 — `<polygon>` 0개 + `<image>` 0개 + IR 영역 영역 1개 다각형 (셀[18] tac=true wrap=TopAndBottom) 존재 → 셀 안 다각형/도형 SVG 렌더링 경로 누락 영역 영역 본 PR 무관. 두 결함 후보 (Issue #726 본문): (a) SVG renderer 다각형 미출력 (`src/renderer/` 도형 분기 svg.rs/web_canvas.rs/paint/json.rs 4 backend) / (b) HWPX 파서 다각형 1개 누락 (`src/parser/hwpx/` table cell GenShape 파싱, 셀[6]/셀[13] ctrls=0). **본 환경 reset**: cherry-pick + 시각 비교 → byte-identical 확인 → `git reset --hard origin/devel` 영역 영역 devel 무영향. **컨트리뷰터 안내 [#817#issuecomment-4425741327](https://github.com/edwardkim/rhwp/pull/817#issuecomment-4425741327)** (정중 톤): byte-identical SVG 결과 명시 + Task #688 이미 해결됨 + 외곽 박스 border 정교한 정합 안내 + Issue #726 진짜 본질 (화살표 도형) 분리 PR 가이드 + 두 결함 후보 (a/b) 진단 권장. Issue #726 OPEN 유지. 검토 보고서: `mydocs/pr/archives/pr_817_review.md`. 처리 보고서: `mydocs/pr/archives/pr_817_report.md`. **`feedback_contributor_cycle_check` 정합** — @oksure 20+ 사이클. **`feedback_image_renderer_paths_separate` 권위 사례 강화 후보** — Issue #726 진짜 본질 영역 영역 셀 안 다각형 SVG/Canvas/paint json 4 backend 동기 정정 후속. **`feedback_process_must_follow` 정합** — PR base 5/9 영역 작성 → Task #688 먼저 머지 → 중복 정정 영역 영역 base 갱신 점검 필요 사례. **`feedback_hancom_compat_specific_over_general` 정합** — Task #688 영역 영역 외곽 박스 border 영역 영역 추가 정합 (exam_social.hwp pi=15 정정 포함) — 본 PR 영역 영역 단순 가드만, 정교한 정합 부재. **`feedback_diagnosis_layer_attribution` 권위 사례 강화** — 본 PR 본질 (nested 11×3 그리드 누락, Task #688 이미 해결) vs Issue #726 진짜 본질 (셀 안 화살표 도형 미출력) 두 본질 분리 진단 + PR 영역 영역 잘못 연결 (`closes #726`) 명확화. **`feedback_visual_judgment_authority` 권위 사례 강화** — 작업지시자 영역 영역 5쪽 SVG 시각 비교 요청 → byte-identical 결과 입증 — 결정적 검증 영역 영역 PR 효과 없음 명확화 패턴. **`feedback_pr_supersede_chain` 정합** — PR #694 (Task #688) → Issue #726 (잔존 본질) → **PR #817** (close, 중복 정정) → 분리 PR (Issue #726 진짜 본질) (a) 패턴. |

## M100 — 내부 타스크 (5/12 사이클)

| Issue | 타스크 | 상태 | 비고 |
|------|--------|------|------|
| **#857 (closes #857)** | fix — table-vpos-01.hwp p.5 중첩 11×3 표 c=2 column 셀 클릭 misroute (외곽 placeholder TextRun first-match 선점) | **완료 (3 stage GREEN + WASM 재빌드 + 사용자 E2E 확인 + cargo test 전체 PASS + SVG byte-identical)** | 작업지시자 직접 보고 (table-vpos-01.hwp p.5 셀 클릭 안됨). 본 환경 Phase 1 진단 — pi=30/pi=32 header/title 셀은 정상, **pi=34 외곽 1×1 안 inner 11×3 c=2 column 본문 셀만 misroute** 확인. Root cause: `cursor_rect.rs:648-666` 의 1차 bbox 매칭이 cell-context TextRun first-match (`if hit_cell.is_none()`) — 외곽 셀 빈 placeholder TextRun (bbox 712.5 px paragraph 1 전체) 이 depth-first 순회 순서상 inner 11×3 실제 텍스트 TextRun (cellPath 길이 2, 작은 bbox) 보다 먼저 매칭. **Pre-Task #717 검증** (commit `1c783a89`): c=2 column 4개 케이스 동일 FAIL → v0.5.0 부터 잠재 (Task #717 무관). **Issue #850 과 별개** — #850 은 Task #717 직접 회귀 (L391-403, inner cell_context layout 결함, API 에러 `"컨트롤 인덱스 0 범위 초과"`) / 본 #857 은 v0.5.0 부터 L648-666 first-match (silent misroute, 콘솔 에러 없음). Fix (`src/document_core/queries/cursor_rect.rs` L648-666, +6/-1): cell-context TextRun selection `first-match` → `min area best-match` 변경 — Task #717 의 cell_bboxes selection (L671-675) 과 동일 best-match 패턴. **코드 일관성** — cursor_rect.rs 내 L587/L671/L680 모두 best-match, L648-666 만 유일했던 first-match 정책 차이 해소. **검증 결과**: (1) 본 RED 회귀 테스트 13 cases (`tests/issue_table_vpos_01_page5_cell_hit_test.rs`) Stage 1 5 FAIL / 8 PASS → Stage 2 **13 PASS** (2) 전체 `cargo test` **1232 unit + 35 suites 0 fail** (3) Task #717 회귀 3 PASS / `issue_630` PASS / `issue_nested_table_border` PASS (4) clippy 새 warning 없음 (5) **SVG byte-identical** (`diff /tmp/tvp01-p5/ /tmp/svg-after/` exit 0) — 렌더링 단 무영향 (6) WASM 재빌드 (Docker, 2m 27s, `pkg/rhwp_bg.wasm` 4.35 MB) + 작업지시자 직접 시연 확인. 진단 노트: `mydocs/troubleshootings/table_vpos_01_page5_cell_hit_test.md`. 수행 계획서: `mydocs/plans/task_m100_857.md`. 구현 계획서: `mydocs/plans/task_m100_857_impl.md`. Stage 보고서: `mydocs/working/task_m100_857_stage{1,2,3}.md`. 최종 보고서: `mydocs/report/task_m100_857_report.md`. **`feedback_process_must_follow` 정합** — 수행/구현 계획서 → Stage 1 RED → Stage 2 GREEN → Stage 3 회귀 sweep 단계별 승인. **`feedback_visual_judgment_authority` 정합** — SVG diff byte-identical + 작업지시자 직접 시연 확인. **`feedback_diagnosis_layer_attribution` 권위 사례 강화** — #850 (Task #717 회귀, L391-403, layout 단계, API 에러) vs #857 (v0.5.0 잠재, L648-666, hit-test 정책, silent misroute) 두 본질 분리 진단 + git blame + pre-#717 commit 직접 실행으로 객관 입증. **`feedback_hancom_compat_specific_over_general` 정합** — Task #717 의 cell_bboxes best-match 패턴 미러 영역 영역 정교한 정합. |

## 작업 메모

### 5/11 → 5/12 사이클 전환
Expand Down
100 changes: 100 additions & 0 deletions mydocs/plans/task_m100_857.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Task m100 #857 수행 계획서

> Issue: [#857 — table-vpos-01.hwp p.5 중첩 11×3 표 c=2 column 셀 클릭 misroute](https://github.com/edwardkim/rhwp/issues/857)
> 브랜치: `local/task857`
> 작성일: 2026-05-12

## 1. Context

`samples/table-vpos-01.hwp` 의 5쪽에 있는 중첩 11×3 표의 **c=2 column 본문 셀들**(예: "포용과 균형의 기본사회 구현", ④⑤⑥⑦⑧⑨ 본문 항목) 클릭 시 커서가 해당 셀에 진입하지 못함. 글자 입력 시 외곽 1×1 wrapper 의 paragraph 1 텍스트 영역(시각적으로 "4 공공 AX" 행 부근)에 silent 삽입됨. 사용자에게는 "셀이 안 눌린다" 로 인식.

같은 inner 11×3 의 c=0 column 라벨 셀("1 참여소통", "2 기본사회" 등) 은 정상 동작 — c=2 column 본문 셀만 영향. 콘솔 에러 없음.

## 2. Phase 1 진단 결과 (완료)

### 2.1 재현 확인
- `tests/issue_table_vpos_01_page5_cell_hit_test.rs` (13 케이스, 5 FAIL / 8 PASS) — RED 테스트로 capture
- FAIL: c=2 column row 0/1/3/6 (4 hit-test) + c=2 row 0 insert_text (1)
- PASS: 단순 표 cells, inner 1×1 title, **c=0 column 라벨 셀 4개 모두**

### 2.2 Root cause 확정 (디버그 출력으로 검증)
[src/document_core/queries/cursor_rect.rs:648-666](../../src/document_core/queries/cursor_rect.rs#L648-L666) 의 1차 bbox 매칭이 **첫 매칭 cell-TextRun** 을 골라 early-return.

디버그 캡처:
```
all_cell_hits=[13, 17] hit_cell=Some((13, 0))
cell_hit[13] tid=Some(32) si=0 pi=1 cs=0 cc=0 bbox=(396.9, 298.0, 625.2×712.5) ctx=[(0, 0, 1)] ← 외곽 placeholder
cell_hit[17] tid=Some(51) si=0 pi=0 cs=0 cc=19 bbox=(184.4, 310.5, 330.0×20.0) ctx=[(0, 0, 1), (0, 2, 0)] ← inner 11×3 r=0,c=2
```

depth-first 트리 순회 순서상 외곽 placeholder TextRun (char_count=0, bbox 712.5 px 영역) 이 inner 실제 TextRun 보다 먼저 매칭 → 선점. inner run 의 cell_context 가 정상(길이 2) 임에도 무시됨.

**c=0 column 이 정상인 이유**: click x 좌표(≈128) 가 외곽 placeholder x_range `[396.9, 1022.1]` **밖** 이라 매칭 자체 안 됨.

### 2.3 Task #717 무관 — 장기간 잠재 결함
- L648-666 first-match 로직은 v0.5.0 초기 커밋 (`f0f7f1a4`) 이후 **변경 없음** (`git log -L` 으로 확인)
- pre-Task #717 commit `1c783a89` 에서 동일 RED 테스트 실행 → c=2 column 4개 케이스 **동일하게 FAIL**
- 즉 **v0.5.0 부터 잠재** 했으며 Task #717 (commit ef67efa1) 도입 무관

### 2.4 Issue #850 과의 관계 — 별개
- #850: Task #717 직접 회귀 (L391-403 변경). 메커니즘: inner cell_context layout 결함. 증상: 클릭 됨 + 입력 시 API 에러
- 본 이슈: L648-666 first-match (v0.5.0 이후 불변). 메커니즘: hit-test 매칭 정책. 증상: silent misroute
- 동시 발견됐을 뿐 별개 fix 필요

## 3. 수정 방향

[cursor_rect.rs:648-666](../../src/document_core/queries/cursor_rect.rs#L648-L666) 의 첫 매칭 선택을 **path depth 최대 + tie-break 작은 bbox** 로 변경:

```rust
let hit_cell = runs.iter().enumerate()
.filter(|(_, r)| /* bbox contains click + cell_context.is_some */)
.max_by_key(|(_, r)| {
let depth = r.cell_context.as_ref().unwrap().path.len();
let neg_area = -((r.bbox_w * r.bbox_h * 1000.0) as i64);
(depth, neg_area)
});
```

본 사례에서 runs[17] (depth 2, bbox 6600) 가 runs[13] (depth 1, bbox 445400) 을 이김 → 정상 inner cell 매칭.

`hit_body` 분기는 변경 안 함 (셀 vs 본문 우선순위 유지).

## 4. 회귀 위험 점검 대상

본문/셀 우선순위 변경이 아니므로 회귀 위험 제한적이지만 다음 회귀 테스트 PASS 필수:
- `tests/issue_717_table_cell_hit_test.rs` (Task #717 회귀 — nested cellPath length 2 정상 유지)
- `tests/issue_595_*` (수식 hit-test 회귀)
- `tests/issue_628.rs`, `tests/issue_630.rs`, `tests/issue_nested_table_border.rs`
- `cargo test` 전체

본 RED 테스트:
- 5 FAIL → 모두 PASS
- 기존 8 PASS → 유지

## 5. 구현 단계 분할 (예정 — 구현 계획서에서 확정)

- Stage 1 (RED): 본 RED 테스트가 이미 작성됨. 그대로 사용
- Stage 2 (GREEN): cursor_rect.rs:648-666 first-match → max_by_key 변경
- Stage 3 (회귀 sweep): 전체 cargo test + 시각 회귀 (export-svg 비교) + rhwp-studio E2E 수동

상세는 구현 계획서 `mydocs/plans/task_m100_857_impl.md` 에서 확정.

## 6. 산출물 인계

본 진단 결과는 이미 다음 파일에 남아 있음:
- 진단 노트: `mydocs/troubleshootings/table_vpos_01_page5_cell_hit_test.md`
- RED 테스트: `tests/issue_table_vpos_01_page5_cell_hit_test.rs`
- Plan mode 초안: `/Users/junpyooh/.claude/plans/samples-table-vpos-01-hwp-5-sorted-comet.md` (참고용)

브랜치 `local/task857` 에서 작업 시작.

## 7. 진행 순서

1. **본 수행 계획서 승인 요청** ← 현재 단계
2. 구현 계획서 (`task_m100_857_impl.md`) 작성 → 승인 요청
3. Stage 1 (RED 유지 검증) → `_stage1.md` 보고서
4. Stage 2 (GREEN 수정) → `_stage2.md` 보고서
5. Stage 3 (회귀 sweep) → `_stage3.md` 보고서
6. 최종 보고서 (`mydocs/report/task_m100_857_report.md`) → 승인
7. `local/task857` → `local/devel` merge
8. `mydocs/orders/20260512.md` 에 task #857 완료 표시
Loading
Loading