Skip to content

reverse-sync 완성을 위한 잔여 blocker 및 Phase 5 마무리 #960

@jk-kim0

Description

@jk-kim0

Summary

reverse-sync는 현재 거의 완성 단계지만, 아직 strict roundtrip verify 기준에서 남아 있는 실패 2건과 text-level fallback 정리가 끝나지 않았습니다.

현재 tests/reverse-sync/pages.yaml 기준 상태는 다음과 같습니다.

  • expected_status: pass 40건
  • expected_status: fail 2건

이 이슈의 목적은 남은 실제 blocker를 닫고, 현재 남아 있는 fallback 경로를 fragment reconstruction 중심으로 정리해 reverse-sync를 완료 상태로 만드는 것입니다.

Current blockers

1. 544382659 fail 케이스 정리 및 수정

대상 페이지: administrator-manual/kubernetes/k8s-access-control/policies/kubernetes-policy-action-configuration-reference-guide.mdx

현재 현상:

  • pages.yaml 라벨은 failure_type: 16, 리스트 항목 내 코드 블록 인라인 병합으로 기록되어 있습니다.
  • 하지만 최신 reverse_sync_cli.py verify 결과 파일을 보면 현재 실제 실패 양상은 기존 라벨과 다릅니다.
  • verify 결과에서는 문단이 한 줄로 유지되어야 하는 위치가 두 문장으로 분리되어 roundtrip exact match가 깨집니다.
  • 즉, 역사적으로는 리스트 내 fenced code block이 문제였을 수 있지만, 현재 남아 있는 실패는 최신 구현 기준으로 다시 분류해야 합니다.

재현 명령:

./tests/run-tests.sh --type reverse-sync-verify --test-dir reverse-sync --test-id 544382659 --verbose

문제 현상 요약:

  • 기존 기대: 교정된 MDX 문단이 verify.mdx에서도 동일한 문단 구조로 유지되어야 함
  • 현재 작동: patched XHTML -> verify.mdx roundtrip 과정에서 문장이 둘로 갈라져 exact match 실패

해결 방향:

  • 현재 실패를 old label 그대로 다루지 말고, 최신 diff를 기준으로 root cause를 재분석한다.
  • block parser / diff / patch_builder / roundtrip_verifier 중 어느 단계에서 문단 경계가 변하는지 분리한다.
  • 수정 후 pages.yaml의 description / label / failure_type도 현재 증상에 맞게 재정의한다.

완료 기준:

  • 해당 케이스가 reverse-sync verify에서 pass로 전환된다.
  • pages.yaml 메타데이터가 실제 증상과 일치한다.

2. 862093313 fail 케이스 수정

대상 페이지: installation/system-architecture-and-network-access-control.mdx

현재 현상:

  • pages.yaml에는 failure_type: 11, 교정 내용 원복 — 조사 띄어쓰기 (User 의→User의)로 기록되어 있습니다.
  • 실제 latest verify 결과는 이보다 범위가 큽니다.
  • 문장 결합/분리 차이가 발생하고, markdown table 직렬화도 원본과 달라지며, 이 차이는 --lenient에서도 사라지지 않습니다.
  • 즉, 단순한 조사 띄어쓰기 원복이 아니라 paragraph serialization + table serialization까지 섞인 복합 roundtrip 실패입니다.

재현 명령:

./tests/run-tests.sh --type reverse-sync-verify --test-dir reverse-sync --test-id 862093313 --verbose
bin/reverse_sync_cli.py verify --lenient --page-id 862093313 --original-mdx tests/reverse-sync/862093313/original.mdx --page-dir tests/reverse-sync/862093313 tests/reverse-sync/862093313/improved.mdx

문제 현상 요약:

  • 기존 기대: User 의 -> User의 같은 교정과 문장 정리, 표 내용이 verify.mdx에 그대로 반영되어야 함
  • 현재 작동: 문장이 다시 나뉘고, markdown table 포맷도 달라져 strict / lenient 모두 실패

해결 방향:

  • prose roundtrip 차이와 table roundtrip 차이를 한 케이스 안에서 분리해 재현한다.
  • parser/emitter/roundtrip_verifier의 normalize 대상과 patch_builder의 patch shape 중 어디가 실제 원인인지 좁힌다.
  • 의미 보존만 되면 되는지, exact markdown shape까지 보존해야 하는지 정책을 분명히 하고 그 정책에 맞게 구현 또는 verifier를 조정한다.

완료 기준:

  • strict verify 통과
  • 최소한 lenient 통과가 아니라 strict oracle 기준으로 pass 전환
  • 이 케이스를 설명하는 보다 정확한 failure taxonomy 정리

Improvement tasks

3. 남은 fail 2건을 fixture-level 통합테스트 외에 원인별 회귀 테스트로 분해

기존 작동:

  • pages.yaml + fixture 디렉터리 기반 E2E verify로만 상태를 추적한다.
  • 실패 라벨이 오래되면 현재 무엇이 깨졌는지 테스트 이름만으로는 드러나지 않는다.

개선된 작동:

  • test_reverse_sync_* 단위 테스트에서 문단 경계 보존, list/code block 보존, markdown table roundtrip 보존을 별도 케이스로 검증한다.
  • E2E fixture는 최종 회귀 확인에 집중하고, 원인 파악은 단위 테스트에서 빠르게 가능해진다.

4. list 경로의 text-level fallback 제거 또는 명시적 fail 전환

현재 구현:

  • patch_builder.py의 list 전략은 clean list는 replace_fragment로 가지만, preserved anchor list는 여전히 old_plain_text/new_plain_text 누적 패치와 inline fixup에 의존한다.
  • 즉, 리스트 변경 처리 경로가 아직 완전히 fragment reconstruction 중심으로 정리되지 않았다.

목표 구현:

  • preserved anchor list도 sidecar reconstruction으로 커버하거나, 지원하지 않는 구조라면 명시적으로 fail한다.
  • 더 이상 “조용히 텍스트만 덧입히는” 방식에 기대지 않는다.

비교:

  • 기존 작동: 리스트 일부 케이스는 XHTML 구조를 유지한 채 plain text diff만 이식
  • 개선된 작동: 리스트도 sidecar-aware fragment replace 또는 explicit unsupported fail

5. containing/direct 경로의 template rewrite 의존도 축소

현재 구현:

  • clean container 일부, ac:link, ri:attachment 포함 블록은 rewrite_on_stored_template()로 텍스트만 다시 쓴다.
  • 이는 text_transfer.py 삭제 이후의 중간 단계 대체재이지만, 여전히 text-level patch 성격이 남아 있다.

목표 구현:

  • 가능한 케이스는 replace_fragment + sidecar reconstruction으로 올린다.
  • truly unsupported 케이스만 명시적으로 fail한다.

비교:

  • 기존 작동: 원본 XHTML template를 유지한 채 plain text만 재주입
  • 개선된 작동: block 단위 fragment를 재구성하고 top-level fragment 자체를 교체

6. table/raw HTML table의 silent skip을 fail-closed로 정리

현재 구현:

  • preserved anchor table 또는 안전하지 않은 raw HTML table 구조 변경은 patch를 만들지 않고 넘어가는 경로가 있다.
  • silent corruption을 피하려는 의도는 맞지만, 사용자는 왜 적용이 안 됐는지 즉시 알기 어렵다.

목표 구현:

  • unsupported table 구조는 verify 결과에서 명시적 fail reason으로 드러나게 한다.
  • skip은 내부 구현 디테일이지 사용자 관점 성공처럼 보이면 안 된다.

비교:

  • 기존 작동: 안전하지 않으면 patch 미생성 후 조용히 통과 또는 다른 단계에서 늦게 실패
  • 개선된 작동: unsupported structural change는 즉시 분류 가능하고 재현 가능한 fail로 노출

7. xhtml_patcher의 text-only modify 경로 제거

현재 구현:

  • xhtml_patcher.pyreplace_fragment를 지원하지만, 여전히 old_plain_text/new_plain_text 기반 modify 경로를 유지한다.
  • 이 경로는 남은 fallback이 존재하는 한 필요하지만, reverse-sync 완성 상태의 목표와는 맞지 않는다.

목표 구현:

  • caller 정리가 끝나면 patcher는 replace_fragment, insert, delete 중심으로 단순화한다.
  • text node 위치 매핑과 inline fixup 의존도를 줄인다.

비교:

  • 기존 작동: DOM 내부 text node를 찾아 부분 치환
  • 개선된 작동: top-level fragment 수준에서 교체

8. 설계 문서와 운영 문서를 현재 구현 상태에 맞게 갱신

현재 문서 상태:

  • docs/plans/2026-03-13-reverse-sync-reconstruction-design.md는 아직 expected_status: fail 11건과 Axis 2 미완료를 전제로 설명한다.
  • docs/architecture.md는 이미 삭제된 text_transfer.py를 현재 런타임 핵심 모듈처럼 설명한다.

개선 방향:

  • 실제 현재 상태인 pass 40 / fail 2를 기준으로 backlog를 업데이트한다.
  • Axis 2가 이미 반영됐다는 점과, 지금 남은 일이 “실제 fail 2건 + text-level fallback 축소”라는 점을 문서에 반영한다.

비교:

  • 기존 문서: 과거 계획/과거 실패 개수 중심
  • 개선된 문서: 현재 코드베이스와 테스트 상태를 정확히 반영하는 운영 문서

Proposed order

  1. 544382659, 862093313 최신 root cause 재분석 및 pass 전환
  2. 남은 fallback 경로를 list -> containing/direct -> table 순으로 축소
  3. xhtml_patcher text-only modify 제거
  4. pages.yaml failure taxonomy와 설계 문서/아키텍처 문서 동기화

Done criteria

  • tests/reverse-sync/pages.yaml 기준 expected_status: fail 0건
  • 현재 남아 있는 fail 2건이 strict verify에서 pass로 전환
  • unsupported 구조는 silent skip이 아니라 explicit fail reason으로 분류
  • patch_builder / xhtml_patcher의 text-level patch 경로가 더 이상 기본 경로가 아님
  • 설계 문서와 운영 문서가 현재 구현 상태와 일치

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions