Skip to content

feat(claude): repo 하위 dir에서 git branch 도출 — FP-free walk-up (W-A v2) + walk-up 블로커 해소#25

Merged
ictechgy merged 4 commits into
mainfrom
feature/walkup-cwd-only-blocker-resolved
Jun 13, 2026
Merged

feat(claude): repo 하위 dir에서 git branch 도출 — FP-free walk-up (W-A v2) + walk-up 블로커 해소#25
ictechgy merged 4 commits into
mainfrom
feature/walkup-cwd-only-blocker-resolved

Conversation

@ictechgy

@ictechgy ictechgy commented Jun 13, 2026

Copy link
Copy Markdown
Owner

요약

walk-up 선결 블로커를 lterm 레포 조사로 해소하고(→ W-B 기각), 원래 명시된 문제 P1(codex가 repo 하위 dir에서 시작 시 git branch 미탐)을 **understatus 단독 FP-free 디렉터리 체인 walk-up(W-A v2)**으로 해결한다. lterm 무변경, additive.

커밋 2개

  1. 97c9375 docs: W-B(lterm payload git_worktree 추가) 미채택 주석 가드. lterm 조사 결과 Session.cwd는 세션 시작 dir 고정·cd 미추적·git 미인지 → W-B는 FP를 lterm으로 displace할 뿐이라 기각. 후속 기여자가 RawLtermInputgit_worktree를 추가하는 회귀 차단.
  2. 786271b feat: FP-free walk-up. derive_git_branch_from_cwd를 cwd-only → canonical cwd 조상의 첫 .git까지 walk-up.

FP-free 3대 불변식 (설계 합의 + 적대검증 통과)

다중 에이전트 설계 합의(3 설계안 → Architect+Critic) + 구현 리뷰(correctness/security/test-adequacy). Critic의 FP 공격(symlink cwd / linked-worktree gitfile 경계 / depth / TOCTOU) 전부 차단, 임의 파일 read 0.

  1. canonicalize 정확히 1회(루프 前) → 심볼릭 cwd/부모를 실경로로 치환, 타 repo 미순회. (루프 내 재canonicalize 금지.)
  2. probe-then-read 무분기: symlink_metadata로 첫 .git 정지 → read_branch_from_git_dir 무조건 위임. linked worktree gitfile 경계에서 멈춰 main repo branch 미표시(Task3 gitfile FN 보존). lstat.is_dir() 분기 금지(심볼릭 .git 디렉터리 회귀 footgun, Critic 적발).
  3. depth cap 64 + ancestors 루트 종료(유한 종료).

의미 변화 (문서화·always-on)

추적 안 되는 부모 repo 하위 dir에서도 부모 branch 표시 — 그 cwd의 git branch와 정확히 일치(git-consistent 정탐, FP 아님). derive_git_branch(Claude workspace 경로)는 무변경.

테스트

신규 8 유닛 + 1 e2e: P1 정탐 / 첫.git정지 / gitfile경계(이중 mutation 저항) / 빈.git정지 / symlink cross-repo no-FP(canonicalize 제거 시 Some("leaked")로 깨짐을 mutation으로 실증) / ATTACK P 정탐확대 / root 회귀0 / depth cap. 기존 회귀 11종 무수정 통과.

검증

4게이트 그린: fmt --check / clippy -D warnings / test(336 lib + 15 oneline = 351, 0 failed) / build --release. 버전 0.6.0 불변(내부 hardening). M-2(절대경로 가드)는 PR #23으로 이미 해결.

🤖 Generated with Claude Code

ictechgy and others added 2 commits June 13, 2026 17:04
walk-up 선결 블로커("lterm은 git_worktree를 무엇으로 도출하며 셸 cd를
추적하는가?")를 lterm 레포 조사로 해소.

답: lterm Session.cwd는 비-Mutex 불변 String(server.rs:274)으로 create_session에서
1회 캡처 후 영구 고정 — OSC 7/proc cwd 폴링·cwd 갱신 RPC 모두 전무라 셸 cd를
추적하지 못하고, lterm엔 git 인지 자체가 없다. 따라서 W-B(payload에 git_worktree
추가)는 frozen 시작-dir cwd와 동일 부정확성을 공유해 FP를 외부 repo 틀린 branch로
displace할 뿐 — 기각.

parse_lterm_input에 W-B 미채택 근거를 주석으로 박아 후속 기여자가 RawLtermInput에
git_worktree를 무심코 추가하는 회귀를 차단(기존 W-A 배제 경고 claude.rs:442-453과
동일 패턴). behavior 변경 0(주석만). 4게이트 그린(328 lib + 14 oneline = 342).

참고: 시작-dir-하위 walk-up(W-A, codex가 repo 하위 dir 시작 시 branch 도출)은
별개 문제(P1)로 본 커밋 범위 밖 — cwd가 시작 시점엔 정확하므로 FP-free 디렉터리
체인 canonicalize walk-up 설계로 후속 검토 대상. M-2(절대경로 가드)는 PR #23으로
이미 해결돼 선결 코드 조건은 충족.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…W-A v2)

P1 해결: codex가 repo 하위 dir(예: ~/repo/src)에서 시작하면 <cwd>/.git가 없어
branch가 미탐되던 문제. derive_git_branch_from_cwd를 cwd-only에서 walk-up으로 확장해
canonical cwd 조상의 첫 .git 엔트리까지 올라가 repo 루트 branch를 도출한다.
understatus 단독, lterm 무변경, additive.

FP-free 3대 불변식(설계 합의 + Critic 적대검증 통과 — symlink/worktree/depth/TOCTOU
공격 전부 차단, 임의 파일 read 0):
① canonicalize 정확히 1회(루프 前): 심볼릭 cwd/부모를 실경로로 치환 → 타 repo 미순회.
   루프 내 재canonicalize 금지(부모 심볼릭 재해소로 FP 부활).
② probe-then-read 무분기: symlink_metadata로 첫 .git 엔트리(파일/디렉터리/심볼릭
   무차별) 존재만 보고 정지 → read_branch_from_git_dir 무조건 위임. linked worktree
   gitfile 경계를 넘어 main repo branch를 표시하지 않음(Task3 gitfile FN 보존).
   ★ lstat.is_dir()/is_file() 분기 금지 — 심볼릭 .git 디렉터리가 둘 다 false라
   표준 git 추종이 깨짐(footgun, Critic 적발).
③ depth cap 64 + ancestors 루트 종료: mount loop·병적 깊이 차단, 유한 종료.

신규: find_git_root_dir / find_git_root_dir_capped(테스트 cap 주입) + const
MAX_WALK_UP_DEPTH=64. read_branch_from_git_dir/is_safe_base_path/is_absolute 가드는
무수정 재사용. derive_git_branch(workspace 경로)는 무변경(stdin 임의-read 공격면
확대 방지). 주석 5곳 개정("부모 상승 금지" → "3 불변식 유지").

의미 변화(문서화): 추적 안 되는 부모 repo 하위 dir에서도 부모 branch 표시 —
그 cwd의 `git branch`와 정확히 일치(git-consistent 정탐, FP 아님). always-on.

테스트: 신규 8 유닛(P1 정탐 / 첫.git정지 / gitfile경계 이중-mutation / 빈.git정지 /
symlink cross-repo no-FP / ATTACK P 정탐확대 / root 회귀0 / depth cap) + e2e 1.
symlink 테스트는 canonicalize 제거 시 Some("leaked")로 깨짐을 mutation으로 실증.
기존 회귀 11종 무수정 통과. 4게이트 그린(336 lib + 15 oneline = 351, 0 failed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ictechgy ictechgy changed the title docs(claude): W-B(lterm git_worktree) 미채택 근거 주석 가드 — blocker 조사 반영 feat(claude): repo 하위 dir에서 git branch 도출 — FP-free walk-up (W-A v2) + walk-up 블로커 해소 Jun 13, 2026
ictechgy and others added 2 commits June 13, 2026 18:38
…스트 강화

quad-review-loop 라운드1(Claude+Codex+Forge 3트랙) 결과 반영. 엄밀 consensus
blocker(HIGH+ AND ≥2트랙)는 0이나, 2-트랙 consensus MEDIUM과 실재 테스트 갭을
반영(레포 관례: 실제 MEDIUM도 수정).

- [correctness, Claude+Codex 2트랙] read_branch_from_git_dir 시그니처를 &str→&Path로
  변경해 derive_git_branch_from_cwd의 to_string_lossy 라운드트립 제거. 비-UTF8 canonical
  경로가 U+FFFD로 다른 경로로 retarget될 (이론적) FP 위험 차단. 양 호출부 갱신
  (derive_git_branch는 Path::new(base_path)로, 동작·외부 시그니처 불변).
- [testability, Forge HIGH] 심볼릭 .git 엔트리 walk-up 테스트 2개 추가: 부모 .git이
  심볼릭(→실 git dir)이면 추종해 inner branch 도출(outer 미누출), dangling .git 심볼릭이면
  정지·None(부모 outer 미상승). is_dir/is_file 분기 mutation을 walk-up 깊이에서도 포착.
- [testability, Forge MEDIUM] prod 경로 depth-cap 테스트 추가(64단계 중첩→derive_git_branch_
  from_cwd가 None, MAX_WALK_UP_DEPTH 실제 강제 증명). cap 의미 주석 명시(start 포함 cap개
  방문, ascent 횟수 아님 — Codex off-by-one 우려 해소).
- [testability, Forge MEDIUM] e2e oneline 테스트를 unique branch명(wt-<hash>)으로 변경 +
  max_width=500 주입으로 폭-의존 flaky 제거(다른 소스 main 누출 false-green 차단). 스트레스
  oneline 0/20·walk_up 0/10 무실패 검증.
- [주석 정밀화, LOW] symlink-cwd 테스트의 "루프 내 재canonicalize 시 깨짐" 부정확 표현 제거
  (canonical 조상 재canonicalize는 no-op), derive_git_branch 대칭 주석 갱신(후속 처리 분기
  명시), MAX_WALK_UP_DEPTH "<20" 근거를 경험적 추정으로 명시.

4게이트 그린(339 lib + 15 oneline = 354, 0 failed). 기존 회귀 전부 통과.

quad-review-loop round 1/5
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ink 외부repo 의도 계약

quad-review-loop 라운드2(Claude+Codex+Forge) 수렴(엄밀 consensus blocker 0).
남은 비-blocker 2건을 test-only로 반영(프로덕션 로직 무변경 — derive_git_branch_from_cwd/
find_git_root_dir/read_branch_from_git_dir/MAX_WALK_UP_DEPTH 본문 변경 0).

- [Forge LOW, mutation 저항] prod 경로 depth-cap in-cap 경계 positive 테스트 추가
  (derive_from_cwd_walk_up_prod_depth_in_cap_some): 63단계 중첩 = root가 ancestors
  index 63 = take(64) 포함 → Some. 기존 64단계 None 테스트와 짝지어 63-in/64-out 경계를
  정확히 고정. cap을 64 미만으로 낮추는 mutation을 포착.
- [Codex MEDIUM single-track, 의도 계약화] symlink .git→외부 repo 추종을 명시 테스트로 계약
  (derive_from_cwd_walk_up_symlink_git_to_external_repo_follows_some): 외부 repo로의 .git
  심볼릭도 따라가 Some(external-branch). 이는 기존 cwd-only 경로의 의도된 git-consistent
  동작(해당 cwd에서 `git branch`와 동일)이라 FP가 아닌 정탐 — 거부하지 않고 계약화. 동작을
  바꾸려면 공유 read_branch_from_git_dir + derive_from_cwd_symlink_git_dir_follows_to_some
  계약을 함께 재검토해야 함을 주석·테스트로 명시. read_branch_from_git_dir 주석 1줄 보강.

4게이트 그린(341 lib + 15 oneline = 356, 0 failed). 신규 2 테스트 개별 스트레스 0/5 실패.

quad-review-loop round 2/5 (수렴)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ictechgy ictechgy merged commit d666aec into main Jun 13, 2026
1 check passed
@ictechgy ictechgy deleted the feature/walkup-cwd-only-blocker-resolved branch June 13, 2026 10:02
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