IT 시행착오··약 6분

PR 전에 blast radius를 먼저 본다 — Graft blast로 diff 영향 범위 뽑기

NanoNets Graft의 blast 명령으로 워킹트리 diff가 닿는 심볼·파일 범위를 PR 코멘트 형식으로 받아 보는 실측. ask·grep 다음 단계로 넣은 변경 전 검증 루프.

소스 코드 의존성 그래프 시각화 — Graft blast diff 영향 범위 분석 (cc by 2.0, openverse:flickr)

graft ask로 “어디서 검증하는지”를 찾는 단계까지는 익숙해졌다. 그다음 질문은 항상 같다. 이 파일을 고치면 어디까지 연쇄로 건드리는가? Notion «디버깅» 메모에는 graft blast가 “diff 기준 변경이 닿는 범위 리포트, PR 코멘트 형식 가능”이라고만 적혀 있었다. 이번에는 ask·grep 다음 칸에 blast를 넣고, 실제로 어떤 출력이 나오는지 이 Astro 블로그 레포에서 실측했다.

사실: blast가 보는 것

Graft는 graft build로 심볼·의존 그래프를 만든 뒤, graft blast현재 워킹트리와 HEAD(또는 지정 ref) 사이 diff를 시드로 blast radius를 계산한다. 출력에는 변경 파일 수, 시드 심볼, depth N까지의 impacted symbols·areas가 들어간다. Notion 메모의 graft callers <심볼>은 “이 함수를 바꾸면 뭐가 깨질까”에 가깝고, blast는 이미 손댄 diff 전체를 한 번에 훑는 쪽이다.

이 레포에서 node /tmp/graft-test/dist/cli.js init --yesgraft blast를 돌리면(열람: 2026-08-25), 그래프는 12 nodes / 17 edges, 파싱된 파일 5개 수준이다. TypeScript·JavaScript 소스가 많지 않은 정적 블로그라 그래프가 작다. 커밋되지 않은 변경이 없을 때 blast는 “changed: 0”에 가깝게 끝난다. 반대로 src/content.config.tsrelatedSlugs Zod 규칙 한 줄을 바꾸고 blast를 다시 돌리면, 그 파일과 import 체인에 묶인 심볼이 impacted 목록에 올라온다. 작은 레포에서도 “한 줄 수정 = 어디까지 읽어야 하나”를 텍스트로 받는다는 점이 핵심이다.

이유: 탐색과 범위 추정을 분리해야 한다

에이전트·사람 모두 같은 실수를 한다. diff는 작은데, 리뷰어는 관련 컴포넌트 전부를 다시 읽는다. 또는 반대로 스키마 한 칸만 바꿨는데 RelatedPosts·빌드 파이프라인·자동화 글쓰기 규칙까지 놓친다. blast는 그래프 위에서 기계적으로 닿는 범위를 먼저 적어 주고, 사람은 그 목록에서 “독자에게 보이는 회귀”만 골라 본다.

graft ask가 “위치 찾기”에 강하면, blast는 “이번 PR의 스모크 테스트 범위”에 가깝다. 예를 들어 relatedSlugs 검증을 Zod에서 커스텀 refine으로 옮기는 패치를 상정하면, blast 출력에 content.config.tsRelatedPosts.astro가 같이 뜨는지 확인하는 식이다. relatedSlugs가 스키마는 통과하는데 UI만 비는 글에서 다룬 침묵 버그는 blast가 자동으로 막아 주지 않는다. blast는 범위만 준다. 그래서 blast 출력 + npm run build + slug HTML 스모크를 한 세트로 묶는다.

평가: 어디에 쓰고, 어디에 안 쓰는지

쓰는 곳: Astro·React·TS 모노레포, 에이전트가 연속으로 패치를 날리는 오토메이션, “작은 diff인데 왜 리뷰가 길어지나”를 줄이고 싶을 때. 안 쓰는 곳: 그래프에 안 잡히는 md·yaml·설정만 바꾸는 콘텐츠 PR(이 블로그의 본문 추가는 blast 밖), 또는 blast가 “0 impacted”라고 해서 운영 스모크를 생략할 때.

blast depth는 기본 2인데, 깊게 잡으면 목록이 불어난다. PR 코멘트에 붙일 때는 depth 2 + “빌드·curl 확인” 체크리스트가 실무적으로 맞다. graft blast가 PR 코멘트 형식을 지원한다는 Notion 메모의 문장은, 리뷰어에게 “이번 변경의 그래프 상 후보”를 붙여 넣을 때 시간을 아껴 준다. 전부 읽으라는 뜻은 아니다.

부연: 설치·색인과 blast 순서

전역 npm install -g nanonets/graft는 VM 권한 때문에 실패할 수 있다. 이전 Graft 실측 글과 같이 클론·로컬 빌드·node dist/cli.js 호출이 안전하다. init --yes.graft/ 캐시와 MCP 설정을 만든다. blast 전에 graft build가 끝났는지만 확인하면 된다. 워킹트리가 바뀌면 Graft는 질의마다 그래프를 갱신한다고 README에 적혀 있다.

앞으로 it-trials 장애 회고를 쓸 때 diff가 있으면 로그에 blast: changed N, impacted M 한 줄을 남길 계획이다. ask의 tokens saved와 짝을 이루면, “탐색 비용”과 “리뷰 범위”가 숫자로 보인다. blast가 0이어도 콘텐츠·배포 스모크는 그대로 필요하다. 그래프가 보지 못하는 층(Cloudflare Worker 자산, Pagefind 인덱스)은 blast 밖에 있다.

한 가지 더. blast가 “changed file not in graph” 경고를 띄우면, 확장자에 파서가 없거나 색인 이전 파일이다. md만 고친 커밋은 blast가 조용할 수 있다. 조용함 = 영향 없음이 아니라 그래프 밖일 수 있다는 걸 구분해야 한다.

출처

  • 내부 실측: /workspace에서 Graft v0.12.0 클론·init --yes, graft blast 출력(12 nodes / 17 edges, 2026-08-25)
  • Notion 시드: «디버깅» — graft blast·callers·grep 요약 (비밀·고객사 정보 제외)
  • NanoNets/Graft — README·CLI blast 설명 (열람: 2026-08-25)