Skip to content

feat: E5 outline/read/diff — 에이전트 읽기·검증 표면 3종 + 스킬 축소#110

Merged
pignuante merged 15 commits into
mainfrom
feat/e5-outline-read-diff
Jul 23, 2026
Merged

feat: E5 outline/read/diff — 에이전트 읽기·검증 표면 3종 + 스킬 축소#110
pignuante merged 15 commits into
mainfrom
feat/e5-outline-read-diff

Conversation

@pignuante

Copy link
Copy Markdown
Contributor

요약

E5 에픽: 에이전트 편집 루프의 읽기·검증 반쪽을 채우는 3표면 + 스킬 축소.

  • outline — 문서 항법 지도 1회 호출: 제목(공유 분류 체인)·표(공유 ordinal + 격자 치수 + addressable)·누름틀·책갈피. 이름 앵커가 1차 키, {section, para} 로케이터는 보조(편집 후 stale 명시).
  • read — 문서 통째 왕복 없는 표적 텍스트 읽기: --section N [--paras A..B] / --table N(병합은 앵커 1회 + span) / --field NAME. 비텍스트 내용은 무음 소실 대신 명시 contains 마커.
  • diff — 두 HWPX 비교(semantic + package 2채널): 편집이 의도한 델타만 냈는지 검증. semantic = Core typed walker(필드값/셀 {table,row,col}/문단 텍스트 {section,para}/구조 카운트/raw cap+dropped 명시), package = ZIP 엔트리 바이트. 비교 계층 명시문 포함(엔트리 내부 레이아웃 캐시는 비교 밖 — linesegarray 교훈).
  • 스킬 축소 — SKILL.md "ALWAYS inspect first" 2개소를 outline→read→편집→diff 흐름으로 국소 교체(EDIT 서브트리 보존), 읽기 표면 역할 경계 명시, MCP next 힌트 5곳 갱신.

CLI 3커맨드 + MCP 3툴(hwpforge_outline/hwpforge_read/hwpforge_diff, 3-layer 출력) 전부 추가 전용 feat: — breaking 없음.

구조 변화 (공유 우선)

  • core outline::classify_paragraph — smithy-md styled 인코더에 묻혀 있던 heading/list 판정 4단 체인을 core 로 리프트, smithy-md 는 소비자로 재기저 (text-neutral 게이트: smithy-md 307 테스트 불변). Paragraph.heading_level(titleMark 축) 미사용 원칙을 독스로 고정.
  • core Control::kind_name — 전수 match(신규 variant 시 컴파일 강제) 컨트롤 종류 라벨.
  • diff 는 admission 게이트 무접촉first_diff_path 를 pub(crate) 공유만 하고 stamp/set-cell admission 경로는 그대로 (동작 불변).
  • outline 요약 표 카운트는 공유 inventory 재집계 (blank-HPC 실측에서 ContentCounts(최상위만)와 ordinal 목록의 11 vs 12 불일치 발견·수정).

검증

  • 신규 테스트: core 분류기 20 · smithy read/outline 14 · diff 엔진 8(self-diff 공집합 / fill·set-cell 산출물 = 선언 델타 정확 1건 — 기존 변경 표면의 회귀 게이트 성립 / 구조 추가 / package 엔트리 검출) · CLI 게이트 8 · MCP 표면 테스트 7
  • 실측: blank-HPC(별지 서식) outline = 표 12개(중첩 1 포함) ordinal·격자 치수 전부 정확 · MD 변환 문서 제목 레벨 1/2 분류 실증
  • 영향 크레이트 5개 전체 nextest + workspace clippy -D warnings(pre-commit 훅 매 커밋 통과)

한계 (문서화된 것)

  • diff 문단 정렬 = prefix/suffix trim (교차 삽입은 changed 쌍으로 뭉침 — LCS 는 후속)
  • package 채널은 엔트리 단위 — 엔트리 내부 wire 캐시 sub-diff 는 후속 백로그(<hp:t> 분할 보존과 결합)
  • outline 의 제목/책갈피는 본문 흐름만 (셀 내부 제목은 문서 outline 아님)

설계·토론 이력: .docs/planning/2026-07-23-e5-outline-read-diff.md (내부 문서)

pignuante added 15 commits July 23, 2026 01:32
styled MD 인코더에 묻혀 있던 heading/list 판정 우선순위 체인
(para_heading_level → para_list_type → style_heading_level → 스타일명
휴리스틱)을 core::outline::classify_paragraph 로 리프트. E5 outline/read
표면과 MD 인코더가 같은 진실 소스를 공유한다. Paragraph.heading_level
(titleMark 축)은 의도적으로 미사용.
encode_paragraph_styled 의 heading/list 판정 체인을
core::outline::classify_paragraph 소비로 교체 (text-neutral —
smithy-md 307 테스트 불변). empty-text 가드는 렌더 시점 유지.
중복 진실이 된 format_as_list 제거, format_list_item 은
ListItemKind 를 소비 (lossy 경로 동반 갱신).
문서 파악 1회 호출 표면: 제목(공유 분류기, 본문 흐름만)·표(공유
ordinal + strict 격자 치수 + addressable)·누름틀(list_fields 재사용,
단일 진실)·책갈피(이름 중복 제거). 이름 앵커가 1차 키, {section,para}
로케이터는 보조(편집 후 stale 명시). 빈 텍스트 제목은 항법 앵커
불가로 제외.
제목/표(ordinal·격자 치수·addressable)/누름틀/책갈피를 한 호출로.
--json = {status, outline}. 게이트 2종(2x2 격자 치수·named field 축).
3-layer 출력(next 힌트: fields/fill·set_cell·to_json 연결) +
to_json 과 동일한 1MB 인라인 상한(초과 시 CLI 안내). MD 변환
문서의 제목 2단계·표 격자 실측 테스트 포함.
ContentCounts 는 최상위 run 만 세어 중첩 표가 있으면 요약(11)과
ordinal 목록(12)이 어긋남 (blank-HPC 실측) — 요약을 공유 inventory
재집계로 교체, images/charts 는 최상위 의미로 문서화.
read/diff projection 이 임베디드 컨트롤을 payload 노출 없이 라벨링하는
데 쓴다. 의도적 전수 match — 신규 variant 는 컴파일 시점에 이름을
강제받는다.
HwpxReader::{read_paragraphs,read_table,read_field}: 문서 통째 왕복
없는 표적 텍스트 읽기. 문단은 공유 분류 kind + 비텍스트 내용의
명시 contains 마커(무음 소실 금지, 미래 variant 는 other), 표는
병합 앵커 1회 + span, 필드는 이름 매치(부재 시 가용 이름 열거).
범위/서수/섹션 오류는 ReadError 로 단계별 보고.
--section N [--paras A..B] | --table N | --field NAME (정확히 1개).
비텍스트 내용은 contains 마커로 표기, 병합 셀은 앵커+span 1회.
게이트 3종(격자 행렬·범위+필드·타깃 충돌 거부).
section(+paras)/table/field 단일 타깃 검증, ReadError 를 안정
에러코드+outline/fields 연결 힌트로 매핑. next 힌트로 편집 표면
(fill/set_cell/patch) 연결. 표면 테스트 3종.
semantic = Core typed walker: 필드 축(list_fields 키드, 문단 비교는
필드 본문 스트립 후 — 이중 보고 방지), 셀 축(표를 셀 문단 블랭크로
완전성 가드 후 앵커별 텍스트 델타), 문단 텍스트(prefix/suffix trim
정렬), 구조 카운트, raw(첫-차이 경로, cap 100 + dropped 명시).
package = ZIP 엔트리 바이트 비교(added/removed/changed). 비교 계층
명시문 포함(엔트리 내부 레이아웃 캐시는 비교 밖). 게이트: self-diff
공집합 · fill/set-cell 산출물 = 선언 델타 정확 1건 · 구조 추가 ·
package 엔트리 검출.
hwpforge diff base.hwpx revised.hwpx [-o report.json]. 텍스트 출력은
채널·분류별 요약 + 비교 계층 명시문, --json 은 전체 리포트 인라인.
게이트 2종(self-diff identical · fill 델타 end-to-end 검증+리포트
파일).
base/revised 비교, 인라인 1MB 상한(초과 시 output_path 필수·요약만),
output_path 로 전체 리포트 기록. next 힌트로 재적용/read 연결.
표면 테스트 2종.
SKILL.md: 'ALWAYS inspect first' 2개소를 outline/read/diff 흐름으로
교체, 읽기 표면 역할 경계(inspect=카운트/outline=항법/read=표적
텍스트/to-md=손실 평탄화/to-json=기계 편집 전용) 명시, EDIT 서브트리
는 보존. editing-workflow.md 에 표면별 기대 델타 표 + 검증 루프.
MCP next 힌트 5곳을 diff 검증·outline 연결로 갱신.
독립 리뷰 H1: strip_field_bodies 가 named ClickHere 만 보고하는
field 축보다 넓게 지워 unnamed/비-ClickHere 필드 본문 변경이
semantic 채널에서 완전 무음 — strip 을 ClickHere+named 로 한정,
나머지는 raw 폴백 (잠금 테스트 포함). L1: 추가/삭제 섹션의 문단을
Added/Removed 로 항목화. C2: stamp→diff 편집사슬 게이트 추가.

커버리지 90% 게이트 상환: CLI 텍스트 렌더(제목/리스트/문단·구조)
·에러 경로 게이트, MCP summary/DECODE_ERROR/FILE_WRITE_FAILED
분기, smithy metadata/추가섹션 경로 — 라인 90.02% 실측.
@pignuante
pignuante added this pull request to the merge queue Jul 23, 2026
Merged via the queue into main with commit 4a9bc78 Jul 23, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant