Commit Graph
2 Commits
Author SHA1 Message Date
kimandClaude Opus 5 159669ec04 v4.3.27: coder_patch_file 매칭에 조건부 줄 앵커 적용 — 엉뚱한 줄 편집 차단
이전에는 순수 부분 문자열 매칭이라, 파일보다 얕게 들여쓴 SEARCH가 더 깊은 줄
안에서 매칭됐음("    deep()"가 "        deep()"에 적중). 한 줄을 노린 편집이
다른 줄에 적용될 수 있는 경로였고, 조용히 잘못된 바이트를 쓰는 fail-open이었음.

"무조건 줄 단위 일치"로 바꾸면 줄 안의 조각을 고치는 정당한 사용
("return 1" → "return 42")이 전부 깨지므로, SEARCH가 스스로 무엇을 주장하는지에
따라 앵커를 조건부로 적용:

- 선행 공백이 있거나 여러 줄  → 줄 시작 정렬 필수
  (들여쓰기/구조를 주장하고 있으므로 정렬돼야 함)
- 선행 공백 없는 한 줄        → 기존대로 부분 매칭
  (줄 안의 조각일 뿐 들여쓰기를 주장한 적 없음)

거부는 fail-closed — 찾지 못함으로 보고돼 모델이 더 정확한 컨텍스트로 재시도함.
앵커에 걸린 등장은 건너뛰고 뒤쪽의 정렬된 등장을 계속 찾으므로, 같은 텍스트가
줄 중간과 줄 시작에 모두 있으면 후자를 고침.

부수 수정 — 오프셋 치환:
빠른 경로와 폴백 경로 모두 String.replace()를 쓰고 있었는데, replace()는 위치 0
부터 다시 스캔하므로 방금 내린 앵커 판정을 무효화하고 앞쪽의 정렬 안 된 등장을
고칠 수 있었음. 이미 알고 있는 오프셋으로 splice하도록 양쪽 다 변경.

테스트 121개 통과(앵커 규칙 4개 신규). 실디스크 검증: 8칸 들여쓰기 안의
value = 1 → 99 수정 정상, 들여쓰기 불일치 케이스는 파일 무변경으로 거부.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 16:35:53 +09:00
kimandClaude Opus 5 abac4f7940 v4.3.26: coder_patch_file의 SEARCH/REPLACE 적용부 분리 + 테스트 15개
execute-tool.ts에서 파일 편집 알고리즘을 순수 모듈로 추출. 1,529 → 1,498줄.

이 함수는 툴 레이어에서 가장 위험한 순수 로직임 — 사용자의 실제 소스 파일을
다시 쓰는데, 실패해도 예외를 던지지 않고 잘못된 바이트를 쓰거나 "3건 적용"이라
보고하고 2건만 적용한다. executeTool()의 1,349줄 본문 안에서 fs.writeFileSync
바로 옆에 인라인으로 있어서 디스크를 건드리지 않고는 검증할 방법이 없었음.

테스트가 고정한 성질(피해 큰 순):
1. 적용하지 않은 편집을 성공으로 세지 않는다
2. 엉뚱한 구간을 치환하지 않는다
3. 매칭 구간 밖의 바이트(들여쓰기·후행공백)를 보존한다
4. 실패를 보고해 모델이 재시도할 수 있게 한다
+ /g 정규식 lastIndex 오염으로 두 번째 호출이 편집을 건너뛰는 회귀 방지

추출 중 확인 — 계획 정정:
당초 "early return 평탄화"를 하려 했으나 실측해보니 이 파일의 깊은 중첩은
방어적 가드 피라미드가 아니라 알고리즘 자체의 깊이였음(공백 정규화 텍스트 검색,
Promise 래핑+파싱 루프 등). 평탄화해도 나아지지 않고 테스트 없는 I/O 코드를
기계적으로 건드리는 위험만 남으므로, 오늘 효과가 확인된 방식(파묻힌 순수 로직
추출)으로 방향을 바꿈.

알려진 날카로운 모서리를 문서화(수정하지 않음):
매칭이 줄 단위 앵커가 아니라 부분 문자열이라, 파일보다 얕게 들여쓴 SEARCH가
더 깊은 줄 안에서 매칭된다("    deep()"가 "        deep()"에 적중). 대개 무해
하지만 한 줄을 노린 편집이 다른 줄에 갈 수 있는 경로임. 줄 앵커로 바꾸면 모든
호출자의 파일 편집 의미가 달라지므로 조용히 "고치지" 않고 테스트로 고정만 함.

전체 117개 테스트 통과. 실디스크 검증: coder_patch_file로 return 1 → return 42
수정이 들여쓰기·구조 보존한 채 정확히 반영됨.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 16:30:24 +09:00