Skip to content

perf(commands): 상태 조회를 스크립트 한 번으로 묶어 왕복 축소 - #44

Merged
starz-woo merged 7 commits into
mainfrom
perf/script-lookups
Sep 8, 2026
Merged

starz-woo merged 7 commits into
mainfrom
perf/script-lookups

Conversation

@HyeonsangKim

Copy link
Copy Markdown
Contributor

Summary

모델이 개별 명령을 하나씩 실행하던 조회 구간을 스크립트 한 번 호출로 바꿉니다. 판단(브랜치 분기·PR 재사용·리뷰 내용)은 그대로 모델이 합니다.

세 커맨드에서 비용 가중 −8.3% ~ −25.2%, 잰 품질 지표에서 저하 없음.

왕복 한 번은 그때까지의 컨텍스트를 전부 다시 실어 나릅니다. 그래서 커맨드 파일 크기를 줄이는 것보다(별도 실험에서 −0.3%, p=0.92) 왕복 횟수를 줄이는 쪽이 효과가 큽니다.

Changes

신규 스크립트 3종 — 각 커맨드가 필요한 정보만 모아 JSON 하나로 반환

스크립트 대체하는 개별 호출
scripts/repo-context.sh ls · find · cat package.json · git log · node -v · PRD 읽기 → 런당 14회
scripts/repo-state.sh git fetch/status/diff×2/remote · gh pr list×2 · ls PLAN_* → 8회
scripts/pr-context.sh gh pr view×2 · gh pr diff → 3회

커맨드 3종 수정 — 명령 나열을 스크립트 한 줄로 교체하고, 반환 JSON 필드를 문서화

  • commands/implement.md Step 3~4
  • commands/auto-commit.md Step 1
  • commands/review-pr.md Step 1

원문이 아니라 답을 담는 게 핵심입니다. package.json 전문 대신 verify_commands(테스트는 이 명령으로), PR 목록 대신 stale_branch(이 브랜치는 죽었다) 같은 식입니다. /implement에서 모델이 테스트 실행법을 찾느라 왕복 5번을 쓰던 게 여기서 사라집니다.

각 커맨드에 "개별 git/gh 명령을 따로 실행하지 말 것" 한 줄을 같이 넣었습니다. 이 문구가 없으면 스크립트를 돌리고도 확인차 git status를 다시 부릅니다.

문서 — scripts/가 이미 있는데(knowledge_wiki/) 레이아웃 블록에 빠져 있었습니다.

  • CLAUDE.md 구조 블록 2곳에 scripts/ 추가
  • CONTRIBUTING.md Repo layout 추가 + 번들 스크립트 규약 신설

측정

Claude Code 헤드리스(claude -p) · Opus 5 · 원본 무수정, 복제본을 --plugin-dir로 교체.

커맨드 세션 총 입력 비용 가중 턴 품질 런
/implement −33.9% −25.2% [−32.6, −16.9] −30.6% 기능 커버 동일 10
/review-pr −9.9% −19.2% [−33.5, −5.0] −34.4% 결함 탐지 동일 10
/auto-commit −10.5% −8.3% [−12.4, −3.9] −12.9% 2.93 → 2.96 92
  • 비용 가중 = 입력×1 + 캐시쓰기×1.25 + 캐시읽기×0.1 + 출력×5 (상대값, 달러 아님)
  • 대괄호는 부트스트랩 95% 신뢰구간 · /auto-commit은 순열검정 p=0.0003
  • 완주율 전 조건 100%

토큰 개수가 아니라 단가로 가중해 봤습니다. /auto-commit에서 커맨드 파일을 깎은 별도 조건은 세션 총 입력이 **+1.8%**인데 비용 가중은 **−0.3%**로 갈렸습니다 — 개수만 셌으면 반대로 읽었을 값입니다.

한계

  • /implement·/review-pr은 조건당 5런이라 표본이 작습니다. 신뢰구간이 0을 걸치지는 않았습니다
  • /review-pr은 실제 PR 대신 같은 인터페이스의 gh 스텁으로 돌렸습니다. 왕복 횟수와 컨텍스트는 그대로지만 PR 데이터는 고정값입니다
  • repo-state.sh의 changed_files가 git diff --cached로만 만들어져 스테이징 전 변경이 누락되던 버그를 함께 고쳤습니다. 정확성 수정이고 절감폭 영향은 확인되지 않았습니다(n=5, p=0.50). 위 −8.3%는 수정 전 측정치입니다
  • auto-commit.md의 「브랜치 재사용 감지 방법」 참조 섹션은 여전히 개별 gh pr list를 안내합니다. /auto-commit의 절감폭이 유독 작은 이유일 수 있으나 이번 범위 밖입니다

Type

  • feat — new agent / command / skill / capability
  • fix — bug fix
  • docs — documentation only
  • refactor / chore

Checklist

  • 새 agent/command/skill을 plugin.json에 등록했다 (해당 시) — 해당 없음, 스크립트는 등록 대상이 아니며 ${CLAUDE_PLUGIN_ROOT}로 접근합니다
  • 카운트를 모두 동기화했다 — agents/commands/skills 개수 변동 없음
  • python3 .github/scripts/validate_plugin.py 통과
  • 버전 변경 시 marketplace.json ↔ plugin.json ↔ README/CLAUDE.md 일치 — 버전 변경 없음
  • 사용자 노출 콘텐츠는 한국어, 코드/커밋은 영어

모델이 개별 명령을 하나씩 실행하던 조회 구간을 스크립트 한 번 호출로
바꾼다. 판단(브랜치 분기·PR 재사용·리뷰 내용)은 그대로 모델이 한다.

  /implement    ls·find·cat package.json·git log·node -v·PRD  → repo-context.sh
                런당 14회 조회 → 1회
  /review-pr    gh pr view×2·gh pr diff                        → pr-context.sh
  /auto-commit  git fetch/status/diff×2/remote·gh pr list×2·ls → repo-state.sh

측정 (Claude Code 헤드리스, Opus 5, 복제본을 --plugin-dir 로 교체):

  /implement    비용 가중 −25.2% [−32.6, −16.9]  턴 −30.6%  10런
  /review-pr    비용 가중 −19.2% [−33.5,  −5.0]  턴 −34.4%  10런
  /auto-commit  비용 가중  −8.3% [−12.4,  −3.9]  턴 −12.9%  92런

품질 지표(결함 탐지·기능 커버) 저하 없음, 완주율 전 조건 100%.
비용 가중 = 입력×1 + 캐시쓰기×1.25 + 캐시읽기×0.1 + 출력×5.

커맨드 본문에 "개별 git/gh 명령을 따로 실행하지 말 것"을 함께 넣었다.
이 문구가 없으면 스크립트를 돌리고도 확인차 git status 를 다시 부른다.

repo-state.sh 의 changed_files 가 git diff --cached 로만 만들어져
스테이징 전 변경이 누락됐다. staged/unstaged/untracked 를 모두 담도록
고쳤다. 정확성 수정이고 절감폭 영향은 확인되지 않았다 (n=5, p=0.50).
위 −8.3% 는 수정 전 측정치다.

CLAUDE.md·CONTRIBUTING.md 의 레이아웃 블록에 scripts/ 를 추가하고,
번들 스크립트 규약을 CONTRIBUTING 에 적었다.

버전 0.1.16 → 0.1.17 (patch).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN
@wigtn-contact

wigtn-contact commented Sep 8, 2026 •

Copy link
Copy Markdown

변경된 파일:

  • .claude-plugin/marketplace.json
  • .claude-plugin/plugin.json
  • .github/scripts/test_context_scripts.sh
  • .github/workflows/validate.yml
  • CLAUDE.md
  • CONTRIBUTING.md
  • README.cn.md
  • README.ko.md
  • README.md
  • plugins/wigtn-plugins/.claude-plugin/plugin.json
  • plugins/wigtn-plugins/commands/auto-commit.md
  • plugins/wigtn-plugins/commands/implement.md
  • plugins/wigtn-plugins/commands/review-pr.md
  • plugins/wigtn-plugins/scripts/pr-context.sh
  • plugins/wigtn-plugins/scripts/repo-context.sh
  • plugins/wigtn-plugins/scripts/repo-state.sh

판정: 승인

확인한 내용:

  • repo-context.sh는 tracked·untracked 파일을 함께 수집하고, 파일 목록 상한과 사전 전체 개수(file_count)를 분리해 반환합니다.
  • repo-state.sh는 서브디렉터리에서 실행해도 저장소 루트 기준으로 staged·unstaged·untracked 변경을 수집합니다.
  • pr-context.sh는 입력 검증, 메타데이터 조회 실패, diff 조회 실패를 모두 fail-closed로 처리하며, PR URL 사용 시 대상 저장소를 보존합니다.
  • Bun·pnpm 및 Python·Go·Rust·Make 검증 명령 감지와 회귀 테스트가 추가되어 의도한 동작을 검증합니다.
  • 버전 0.1.17 변경이 매니페스트와 문서에 일관되게 반영되어 있습니다.

검증

  • 방법: CI
  • 명령/체크: Validate plugin manifests & counts
  • 결과: 통과
  • 근거: GitHub Actions job 102016374388 성공. 추가된 컨텍스트 스크립트 회귀 테스트도 워크트리에서 통과 33 · 실패 0으로 실행됐습니다.

검토한 head SHA: 00307f41de26a7329026c6f17f42410f2c41c965

이 리뷰가 도움이 됐다면 👍, 지적이 틀렸다면 👎 를 눌러주세요. 오탐 집계에 씁니다.

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요약 코멘트에 차단 이슈가 있습니다.


반환 JSON에 파일 목록·디렉터리 구조·`package.json` 스크립트·**검증 명령(`verify_commands`)**·PRD/PLAN 경로·런타임 버전·git 상태가 들어 있다.

**검증은 `verify_commands`에 적힌 명령만 쓴다.** `npm test`가 실패한다고 `node --test` 변형을 시도하지 말 것 — 명령이 틀린 게 아니라 코드가 틀린 것이다.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 문장의 node --test가 계약 검사기에 의해 implement 커맨드의 미정의 --test 파라미터 사용으로 해석됩니다. 실제 CI가 본문이 '--test' 를 쓰는데 ## Parameters 에 정의가 없음으로 실패했습니다. --test를 제거하거나 백틱 밖의 일반 텍스트로 바꿔 계약 검사를 통과시키세요.

check_contracts.py 는 인라인 코드(`...`) 안의 --flag 를 그 커맨드의
파라미터 사용으로 해석한다. `node --test` 예시가 ## Parameters 에
정의되지 않은 --test 사용으로 잡혀 CI 가 실패했다.

의미는 그대로 두고 백틱 밖 일반 텍스트로 바꿨다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요약 코멘트에 재현된 차단 이슈가 있습니다.

try: return json.loads(o) if o else {}
except Exception: return {}

meta = j(f'gh pr view {pr} --json title,body,author,baseRefName,headRefName,files,'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 번호가 f-string으로 셸 명령에 직접 들어가고 shell=True로 실행됩니다. 44; printf INJECTED; #를 인자로 주면 임의 명령이 실행되는 것을 재현했습니다. PR 번호를 정수로 검증하고 subprocess.run([...]) 인자 배열을 사용해 셸 해석을 제거해 주세요.

pr-context.sh 가 인자를 f-string 으로 gh 명령에 끼워 넣고 shell=True 로
실행했다. PR 번호에 셸 구문을 넣으면 임의 명령이 실행된다.
`44; touch /tmp/PWNED; #` 로 파일 생성이 재현됐다.

- subprocess 를 인자 배열(shell=False)로 바꿔 조립 자체를 없앴다
- PR 참조는 숫자 또는 GitHub PR URL 만 받는다. 그 외는 JSON 오류로 종료
  (44 / #44 / https://.../pull/44 는 그대로 동작)

repo-state.sh 도 브랜치명을 gh pr list 에 보간하고 있었다. git 이 ref 이름에
따옴표를 허용하지 않아 실제로는 뚫리지 않았지만, ref 규칙에 기대지 않도록
같은 방식(인자 배열)으로 바꿨다.

세 스크립트 모두 f-string 명령 조립이 0건이다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요약 코멘트에 재현 가능한 차단 이슈가 있습니다.


# 실제로 도는 검증 명령만 고른다 — 모델이 시행착오로 찾지 않도록
verify = {}
for key in ('test', 'typecheck', 'lint', 'build'):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Major: 이 루프는 package.json scripts만 검사합니다. implement.md:146은 모델이 verify_commands에 적힌 명령만 실행하라고 강제하므로, pyproject.toml/go.mod/Cargo.toml/Makefile 기반 레포에서는 검증 명령이 빈 객체가 되어 기존 테스트·린트가 실행되지 않습니다. 지원 대상의 검증 명령을 함께 감지하거나 이 제한적인 목록을 강제하지 않도록 수정해 주세요.

staged=[x for x in run('git diff --cached --name-only').split('\n') if x]
unstaged=[x for x in run('git diff --name-only').split('\n') if x]
untracked=[x for x in run('git ls-files --others --exclude-standard').split('\n') if x]
files=sorted(set(staged+unstaged+untracked))[:50]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: 변경 파일을 50개로 자른 뒤 그 길이를 file_count로 반환합니다. auto-commit.md는 이 값을 전체 변경 파일 수로 설명하므로 51개 이상 변경 시 수가 조용히 틀립니다. 자르기 전 개수와 truncation 여부를 분리해 반환해 주세요.

verify_commands 가 package.json 스크립트만 보고 만들어졌다. implement.md 는
"이 목록의 명령만 쓴다"고 지시하므로, package.json 이 없는 Python/Go/Rust
레포에서는 목록이 비고 구현 에이전트가 검증을 아예 건너뛴다.

- pyproject.toml(pytest·ruff·mypy), tox.ini/pytest.ini, go.mod(go test·go vet),
  Cargo.toml(cargo test·clippy), Makefile 의 실제 타깃을 감지한다
- JS 는 락파일로 패키지 매니저를 맞춘다 (npm/pnpm/yarn/bun)
- verify_detected 를 함께 반환한다. implement.md 계약을 고쳐 false 일 때는
  검증을 건너뛰지 말고 직접 찾도록 했다. 감지 범위도 커맨드에 적었다

repo-state.sh 는 변경 파일을 50개로 자른 뒤 그 길이를 file_count 로 냈다.
auto-commit.md 는 이를 전체 변경 규모로 설명하므로 대형 변경에서 조용히
틀린다. file_count 를 자르기 전 개수로 계산하고 files_truncated 를 추가했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요약 코멘트에 재현 가능한 차단 이슈가 있습니다.

os.chdir(root)

# 소스 트리 (노이즈 제외, 상한 200)
files = [f for f in run(

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

git ls-files는 추적 중인 파일만 반환하므로 아직 커밋하지 않은 소스 파일을 모두 누락합니다. /implement가 이 JSON을 프로젝트 상태 분석의 입력으로 사용하므로 새 파일이 있는 작업 트리에서 기존 구현을 빈 트리로 오인할 수 있습니다. untracked 작업 트리 파일도 포함하도록 수집해 주세요.

repo-context.sh 가 git ls-files 만 썼다. tracked 파일만 나오는데 명령이
성공하므로 뒤의 find 폴백도 타지 않는다. 새 프로젝트나 작업 중 레포에서는
file_count: 0, files: [] 이 나와 /implement 가 빈 트리로 분석하게 된다.
임시 저장소에 커밋하지 않은 package.json·src/app.ts 를 두고 재현했다.

- git ls-files 와 git ls-files --others --exclude-standard 를 합친다
  (.gitignore 는 계속 존중, node_modules 는 그대로 제외)
- git 저장소가 아니면 find 로 떨어진다
- file_count 를 자르기 전 전체 수로 내고 files_truncated 를 추가했다.
  dirs 도 잘리기 전 목록에서 뽑는다
- implement.md 에 위 표기를 적었다

점검한 경우: 커밋 없는 새 레포 / 커밋+untracked 혼재 / git 아닌 디렉터리 /
gitignore 존중 / 200개 초과 자르기. repo-state.sh·pr-context.sh 도 같은
부류로 다시 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요약 코멘트를 참고해 주세요.

@starz-woo starz-woo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

총평

방향은 타당합니다. 왕복 횟수를 줄이는 게 프롬프트 크기를 깎는 것보다 효과적이라는 가설, 비용 가중 지표, 신뢰구간·한계 명시까지 근거가 잘 갖춰져 있고 커밋 히스토리(5개 중 3개가 자체 발견 버그 수정)도 성실합니다.

다만 세 스크립트가 모든 커맨드 실행의 첫 단계에 놓이는 만큼, 실패 모드에서 조용히 틀리는 지점 두 개는 머지 전에 잡는 게 좋겠습니다.


Major 1 — repo-state.sh: 서브디렉터리에서 실행하면 untracked 파일이 누락되고 경로가 어긋남

repo-context.sh는 os.chdir(root)를 하는데 repo-state.sh는 하지 않습니다. git diff --name-only는 cwd와 무관하게 repo 전체·root 기준 경로를 주지만, git ls-files --others는 cwd 하위만, cwd 기준 상대경로로 냅니다.

임시 레포(root_untracked.txt, sub/sub_untracked.txt, staged sub2/x.txt)를 만들고 sub/에서 실행해 재현했습니다:

changed_files  ['sub2/x.txt', 'sub_untracked.txt']   ← root_untracked.txt 통째로 누락
untracked      ['sub_untracked.txt']                 ← 실제 경로는 sub/sub_untracked.txt

/auto-commit이 서브디렉터리 cwd에서 돌면 (1) 다른 디렉터리의 새 파일을 못 보고 (2) changed_files에 root 기준과 cwd 기준 경로가 섞여 나옵니다. CLAUDE.md가 hook·auto-commit을 굳이 --show-toplevel 기준으로 맞춰둔 것도 같은 시나리오를 전제한 거라 실제로 밟히는 경로입니다.

root=run('git rev-parse --show-toplevel','.')
os.chdir(root)          # ← 추가
br=run('git branch --show-current')

Major 2 — pr-context.sh: gh 실패가 "빈 PR"로 성공 처리됨

run()이 non-zero에서 기본값을 반환하므로, PR이 없거나 gh 인증이 안 됐거나 다른 레포에서 돌리면 exit 0 + 전 필드 null + diff: "" 가 나옵니다.

$ bash pr-context.sh 99999
{"pr":"99999","state":null,...,"diff":""}   exit=0

review-pr.md는 state를 MERGED/CLOSED만 분기하므로 null은 그냥 통과하고, 모델은 빈 diff를 받은 채 리뷰를 계속합니다. 리뷰 커맨드에서 가장 위험한 실패 모드(없는 코드에 대한 리뷰 생성)입니다. PR 번호 검증은 fail-closed로 잘 만들었는데 정작 조회 실패만 fail-open이라 일관성도 어긋납니다.

if not meta:
    print(json.dumps({'pr': pr, 'error': 'gh pr view 실패 — PR 번호·인증·레포를 확인'},
                     ensure_ascii=False))
    sys.exit(1)

여기에 review-pr.md에 "error 필드가 있으면 중단하고 사용자에게 알린다" 한 줄을 같이 넣으면 됩니다.


Minor

1. bun test는 package.json 스크립트를 실행하지 않습니다 (repo-context.sh, 패키지 매니저 분기). Bun 내장 테스트 러너가 돌아서 프로젝트 테스트와 다른 결과가 납니다. bun run test여야 합니다. 같은 줄의 락파일 감지도 bun.lockb만 봐서 Bun 1.2+ 기본인 bun.lock을 놓칩니다.

2. PR URL 정규식이 호스트·레포를 버립니다 (pr-context.sh). 다른 레포의 PR URL을 넣으면 번호만 뽑아 현재 레포의 같은 번호 PR을 조용히 리뷰합니다. 숫자만 받거나, URL이면 --repo까지 넘기는 쪽이 맞습니다.

3. 신규 스크립트 3종에 테스트가 없습니다. 이 레포는 동급 컴포넌트마다 CI 테스트가 있습니다(test_gate.sh, test_danger_hook.sh, test_knowledge_wiki.py). 그리고 이 PR의 자체 수정 커밋 2개(file_count 잘림, ls-files tracked-only)와 위 Major 1이 전부 테스트 한 줄이면 잡혔을 종류입니다. test_context_scripts.sh 하나 추가할 자리로 보입니다.

4. python3가 세 커맨드의 하드 의존성이 됐습니다. 없으면 exit 127로 커맨드 자체가 죽는데, CONTRIBUTING에 새로 쓴 "never let a missing tool abort the script" 규약과 어긋납니다. 셸 앞단에서 command -v python3 확인 후 안내 JSON 정도면 충분합니다.


판정

Major 2건 수정 후 머지 권장. 둘 다 수정 자체는 각각 2~3줄이고, Minor는 후속으로 빼도 무방합니다.

🤖 Generated with Claude Code

리뷰에서 잡힌 실패 모드 두 가지. 둘 다 실패했는데 성공처럼 보이는 종류다.

repo-state.sh 가 repo 루트로 이동하지 않았다. git ls-files --others 는 cwd
하위만 cwd 기준 경로로 내므로, 서브디렉터리에서 /auto-commit 을 돌리면 다른
디렉터리의 새 파일이 통째로 빠지고 changed_files 에 root 기준과 cwd 기준
경로가 섞인다. os.chdir(root) 로 수집 기준을 맞췄다.

pr-context.sh 는 gh 조회가 실패해도 전 필드 null 에 diff 빈 문자열로 exit 0
했다. review-pr.md 가 state 를 MERGED/CLOSED 만 분기하므로 null 은 통과하고
모델이 빈 diff 로 리뷰를 만든다. 입력 검증과 같은 fail-closed 로 맞추고,
review-pr.md 에 error 필드가 있으면 중단하도록 적었다.

그 외:
- PR URL 은 owner/repo 를 살려 --repo 로 넘긴다. 번호만 뽑으면 현재 레포의
  동일 번호 PR 을 조용히 리뷰한다
- bun·pnpm 의 test 서브커맨드는 package.json 스크립트를 돌리지 않으므로
  항상 run 을 거친다. bun.lock(Bun 1.2+ 기본)도 감지한다
- 세 스크립트에 python3 존재 확인을 넣어 exit 127 대신 안내 JSON 을 낸다

test_context_scripts.sh 를 추가하고 CI 에 등록했다(28개). 임시 저장소를 만들어
실제 실행하고 JSON 필드만 본다. 모델 호출 없음. 이 PR 에서 나온 결함
- tracked-only 수집, 잘린 개수를 전체로 보고, 서브디렉터리 경로 어긋남,
gh 실패의 빈 PR - 을 각각 되돌려 테스트가 실패하는 것까지 확인했다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Diff 조회 실패를 오류로 전파해야 합니다.

'error': 'gh pr view 실패 — PR 번호·인증·레포를 확인'},
ensure_ascii=False))
sys.exit(1)
diff = run(['gh', 'pr', 'diff', pr] + repo_args)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

run()은 gh pr diff 실패 시 빈 문자열을 반환하지만 이 경로에서는 error를 만들지 않습니다. 그 결과 스크립트가 exit 0으로 빈 diff를 반환하고 review-pr.md의 오류 중단 조건도 우회합니다. diff 조회 실패를 명시적인 오류로 반환하고 비정상 종료하도록 처리해 주세요.

앞 커밋에서 gh pr view 실패만 fail-closed 로 바꾸고 diff 조회는 빠뜨렸다.
메타데이터는 성공하고 diff 만 실패하면(인증·네트워크·권한) 빈 diff 로
exit 0 이 나가고, review-pr.md 의 error 중단 조건도 우회한다. 코드가 없는
PR 을 리뷰하게 되는 경로가 그대로 남아 있었다.

- run_ok() 로 성공 여부를 함께 받아 실패를 빈 문자열로 뭉개지 않는다
- diff 조회 실패 시 error + detail 을 내고 비정상 종료한다

test_context_scripts.sh 에 가짜 gh 를 PATH 앞에 두는 회귀 테스트를 넣었다
(메타 실패 / 메타 성공+diff 실패 / 둘 다 성공). 인증 상태와 무관하게 돌고,
이 커밋의 수정을 되돌리면 해당 2건이 실패하는 것을 확인했다. 33개.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NWDghVZqdr4ZRFhm1aVDSN

@wigtn-contact wigtn-contact left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

요약 코멘트를 참고해 주세요.

@starz-woo
starz-woo merged commit 3859395 into main Sep 8, 2026
1 check passed
@starz-woo
starz-woo deleted the perf/script-lookups branch September 8, 2026 10:14
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.

3 participants