Skip to content
impact-analyzer logo

Impact Analyzer Skill v1.0

impact-analyzer

**IMPACT ANALYZER v1.0** - '영향도', '영향 범위', '변경 영향', '리팩토링 영향', '이거 바꾸면', '어디에 영향', '위험도' 요청 시 자동 발동. codebase-graph 기반 변경 전파 분석. 직접/간접 영향, 위험도 점수, 테스트 범위 제안. 코드 수정 전 필수 분석.

SKILL.md

Full skill instructions

Impact Analyzer Skill v1.0

변경 영향도 분석기 - 코드 수정 전 영향 범위를 정확히 파악하여 안전한 변경 보장

핵심 컨셉

Problem:
  Without_Analysis: "함수 수정 → 예상치 못한 곳에서 에러 → 롤백"
  Reality: "한 줄 변경이 100개 파일에 영향을 줄 수 있음"

Solution:
  Impact_Analysis:
    - "변경 대상의 역의존성 트리 추적"
    - "직접/간접 영향 범위 계산"
    - "위험도 점수 산출"
    - "테스트 범위 자동 제안"

Key_Metrics:
  Direct_Impact: "직접 호출하는 함수들"
  Indirect_Impact: "연쇄적으로 영향받는 범위"
  Risk_Score: "변경 위험도 (0-100)"
  Test_Coverage: "영향 범위 대비 테스트 커버리지"

자동 발동 조건

Auto_Trigger_Conditions:
  Before_Edit:
    - "Edit 도구 사용 전 자동 분석 제안"
    - "공유 코드(shared, utils) 수정 시"
    - "핵심 모듈(auth, api) 수정 시"

  Keywords_KO:
    - "영향도 분석, 영향 범위"
    - "이거 바꾸면 어디 영향?"
    - "변경 영향, 수정 영향"
    - "리팩토링 영향, 리팩토링 범위"
    - "위험도, 얼마나 위험"
    - "테스트 범위, 테스트해야 할 곳"

  Keywords_EN:
    - "impact analysis, impact scope"
    - "what will this affect"
    - "change impact, modification impact"
    - "refactoring scope, refactoring impact"
    - "risk assessment, risk score"
    - "test scope, what to test"

  High_Risk_Patterns:
    - "export 변경/삭제"
    - "함수 시그니처 변경"
    - "타입 정의 변경"
    - "API 엔드포인트 변경"
    - "shared 모듈 변경"

영향도 분석 알고리즘

interface ImpactAnalysisRequest {
  target: string;                 // 변경 대상 노드 ID
  changeType: ChangeType;         // 변경 유형
  depth?: number;                 // 분석 깊이 (기본 3)
}

type ChangeType =
  | 'signature'      // 시그니처 변경 (파라미터, 반환타입)
  | 'implementation' // 구현 변경 (로직)
  | 'rename'         // 이름 변경
  | 'delete'         // 삭제
  | 'move'           // 이동
  | 'type'           // 타입 변경
  ;

interface ImpactResult {
  target: GraphNode;              // 변경 대상
  changeType: ChangeType;
  directImpact: ImpactNode[];     // 직접 영향
  indirectImpact: ImpactNode[];   // 간접 영향
  totalAffected: number;          // 총 영향받는 노드 수
  riskScore: number;              // 위험도 (0-100)
  riskLevel: 'low' | 'medium' | 'high' | 'critical';
  testSuggestions: TestSuggestion[];  // 테스트 제안
  warnings: string[];             // 경고 메시지
}

interface ImpactNode {
  node: GraphNode;
  depth: number;                  // 영향 깊이 (1=직접, 2+=간접)
  impactType: 'caller' | 'type-user' | 'importer' | 'extender';
  confidence: number;             // 영향 확실성 (0-1)
  reason: string;                 // 영향 이유
}

영향 범위 계산

class ImpactAnalyzer {
  private graph: CodebaseGraph;

  constructor(graph: CodebaseGraph) {
    this.graph = graph;
  }

  /​**
   * 영향도 분석 실행
   */
  analyze(request: ImpactAnalysisRequest): ImpactResult {
    const target = this.graph.findNode(request.target);
    if (!target) {
      throw new Error(`Node not found: ${request.target}`);
    }

    // 1. 직접 영향 수집
    const directImpact = this.collectDirectImpact(target, request.changeType);

    // 2. 간접 영향 수집 (재귀)
    const indirectImpact = this.collectIndirectImpact(
      directImpact,
      request.depth || 3
    );

    // 3. 위험도 계산
    const riskScore = this.calculateRiskScore(target, directImpact, indirectImpact, request.changeType);

    // 4. 테스트 제안 생성
    const testSuggestions = this.generateTestSuggestions(target, directImpact, indirectImpact);

    // 5. 경고 생성
    const warnings = this.generateWarnings(target, directImpact, request.changeType);

    return {
      target,
      changeType: request.changeType,
      directImpact,
      indirectImpact,
      totalAffected: directImpact.length + indirectImpact.length,
      riskScore,
      riskLevel: this.getRiskLevel(riskScore),
      testSuggestions,
      warnings,
    };
  }

  /​**
   * 직접 영향 수집
   */
  private collectDirectImpact(target: GraphNode, changeType: ChangeType): ImpactNode[] {
    const impacts: ImpactNode[] = [];

    // 1. 이 노드를 호출하는 함수들
    const callers = this.graph.getIncomingEdges(target.id, 'calls');
    for (const edge of callers) {
      const caller = this.graph.findNode(edge.source);
      if (caller) {
        impacts.push({
          node: caller,
          depth: 1,
          impactType: 'caller',
          confidence: changeType === 'signature' ? 1.0 : 0.7,
          reason: `Calls ${target.name}`,
        });
      }
    }

    // 2. 이 타입을 사용하는 곳
    if (target.type === 'type' || target.type === 'class') {
      const typeUsers = this.graph.getIncomingEdges(target.id, 'uses');
      for (const edge of typeUsers) {
        const user = this.graph.findNode(edge.source);
        if (user) {
          impacts.push({
            node: user,
            depth: 1,
            impactType: 'type-user',
            confidence: changeType === 'type' ? 1.0 : 0.5,
            reason: `Uses type ${target.name}`,
          });
        }
      }
    }

    // 3. 이 모듈을 import하는 파일들
    const importers = this.graph.getIncomingEdges(target.id, 'imports');
    for (const edge of importers) {
      const importer = this.graph.findNode(edge.source);
      if (importer && !impacts.some(i => i.node.id === importer.id)) {
        impacts.push({
          node: importer,
          depth: 1,
          impactType: 'importer',
          confidence: changeType === 'rename' || changeType === 'delete' ? 1.0 : 0.3,
          reason: `Imports from ${target.path}`,
        });
      }
    }

    // 4. 이 클래스를 상속하는 클래스들
    if (target.type === 'class') {
      const extenders = this.graph.getIncomingEdges(target.id, 'extends');
      for (const edge of extenders) {
        const extender = this.graph.findNode(edge.source);
        if (extender) {
          impacts.push({
            node: extender,
            depth: 1,
            impactType: 'extender',
            confidence: 1.0,
            reason: `Extends ${target.name}`,
          });
        }
      }
    }

    return impacts;
  }

  /​**
   * 간접 영향 수집 (BFS)
   */
  private collectIndirectImpact(directImpact: ImpactNode[], maxDepth: number): ImpactNode[] {
    const indirect: ImpactNode[] = [];
    const visited = new Set<string>(directImpact.map(i => i.node.id));
    const queue: ImpactNode[] = [...directImpact];

    while (queue.length > 0) {
      const current = queue.shift()!;

      if (current.depth >= maxDepth) continue;

      // 현재 노드의 호출자들 수집
      const callers = this.graph.getIncomingEdges(current.node.id, 'calls');

      for (const edge of callers) {
        if (visited.has(edge.source)) continue;

        const caller = this.graph.findNode(edge.source);
        if (!caller) continue;

        visited.add(caller.id);

        const impactNode: ImpactNode = {
          node: caller,
          depth: current.depth + 1,
          impactType: 'caller',
          confidence: current.confidence * 0.7, // 깊이에 따라 감소
          reason: `Indirect via ${current.node.name}`,
        };

        indirect.push(impactNode);
        queue.push(impactNode);
      }
    }

    return indirect;
  }

  /​**
   * 위험도 점수 계산
   */
  private calculateRiskScore(
    target: GraphNode,
    direct: ImpactNode[],
    indirect: ImpactNode[],
    changeType: ChangeType
  ): number {
    let score = 0;

    // 1. 변경 유형 기본 점수
    const changeTypeScores: Record<ChangeType, number> = {
      implementation: 20,
      signature: 50,
      type: 60,
      rename: 40,
      move: 45,
      delete: 80,
    };
    score += changeTypeScores[changeType];

    // 2. 직접 영향 수 (각 +3점, 최대 30점)
    score += Math.min(direct.length * 3, 30);

    // 3. 간접 영향 수 (각 +1점, 최대 20점)
    score += Math.min(indirect.length, 20);

    // 4. 대상 특성 보정
    if (target.isExported) score += 10;           // export된 것
    if (target.path.includes('shared')) score += 15; // shared 모듈
    if (target.path.includes('api')) score += 10;    // API 관련
    if (target.path.includes('auth')) score += 15;   // 인증 관련
    if (target.type === 'type') score += 10;         // 타입 정의

    // 5. 테스트 커버리지 보정
    const hasTests = this.hasTestCoverage(target);
    if (!hasTests) score += 10; // 테스트 없으면 위험

    return Math.min(score, 100);
  }

  /​**
   * 위험 수준 결정
   */
  private getRiskLevel(score: number): 'low' | 'medium' | 'high' | 'critical' {
    if (score < 30) return 'low';
    if (score < 50) return 'medium';
    if (score < 75) return 'high';
    return 'critical';
  }

  /​**
   * 테스트 제안 생성
   */
  private generateTestSuggestions(
    target: GraphNode,
    direct: ImpactNode[],
    indirect: ImpactNode[]
  ): TestSuggestion[] {
    const suggestions: TestSuggestion[] = [];

    // 1. 대상 테스트
    suggestions.push({
      target: target.id,
      priority: 'critical',
      reason: 'Direct change target',
      testType: 'unit',
    });

    // 2. 직접 영향 테스트
    for (const impact of direct.slice(0, 10)) { // 상위 10개
      suggestions.push({
        target: impact.node.id,
        priority: impact.confidence > 0.8 ? 'high' : 'medium',
        reason: impact.reason,
        testType: impact.impactType === 'caller' ? 'integration' : 'unit',
      });
    }

    // 3. 고확신 간접 영향 테스트
    const highConfidenceIndirect = indirect.filter(i => i.confidence > 0.5);
    for (const impact of highConfidenceIndirect.slice(0, 5)) {
      suggestions.push({
        target: impact.node.id,
        priority: 'low',
        reason: `${impact.reason} (indirect)`,
        testType: 'integration',
      });
    }

    return suggestions;
  }

  /​**
   * 경고 생성
   */
  private generateWarnings(
    target: GraphNode,
    direct: ImpactNode[],
    changeType: ChangeType
  ): string[] {
    const warnings: string[] = [];

    // 1. 높은 영향 범위
    if (direct.length > 20) {
      warnings.push(`HIGH IMPACT: This change affects ${direct.length} direct callers`);
    }

    // 2. export 삭제/변경
    if (target.isExported && (changeType === 'delete' || changeType === 'rename')) {
      warnings.push(`BREAKING: Modifying exported symbol may break external consumers`);
    }

    // 3. 핵심 모듈 변경
    if (target.path.includes('shared') || target.path.includes('core')) {
      warnings.push(`CORE MODULE: Changes to shared/​core modules require extra caution`);
    }

    // 4. 테스트 부족
    if (!this.hasTestCoverage(target)) {
      warnings.push(`NO TESTS: Target has no test coverage - add tests before changing`);
    }

    // 5. 순환 참조 관련
    const cycles = this.graph.detectCircularDependencies();
    if (cycles.some(c => c.includes(target.id))) {
      warnings.push(`CIRCULAR: Target is part of circular dependency - changes may cascade unpredictably`);
    }

    return warnings;
  }

  private hasTestCoverage(node: GraphNode): boolean {
    // 테스트 파일 존재 확인
    const testPatterns = [
      node.path.replace('.ts', '.test.ts'),
      node.path.replace('.ts', '.spec.ts'),
      node.path.replace('/​src/', '/​test/'),
    ];

    return testPatterns.some(pattern =>
      this.graph.findNode(pattern) !== null
    );
  }
}

위험도 점수 기준

Risk_Scoring:
  Base_Scores_by_Change_Type:
    implementation: 20    # 로직만 변경
    signature: 50         # 시그니처 변경
    type: 60              # 타입 정의 변경
    rename: 40            # 이름 변경
    move: 45              # 위치 이동
    delete: 80            # 삭제

  Modifiers:
    direct_impact: "+3 per caller (max 30)"
    indirect_impact: "+1 per node (max 20)"
    is_exported: "+10"
    in_shared: "+15"
    in_api: "+10"
    in_auth: "+15"
    is_type: "+10"
    no_tests: "+10"

  Risk_Levels:
    low: "0-29 (안전한 변경)"
    medium: "30-49 (주의 필요)"
    high: "50-74 (신중한 검토 필요)"
    critical: "75-100 (위험, 충분한 테스트 필수)"

출력 템플릿

## Impact Analysis Report

### Target: {{targetName}}
- **Path**: {{targetPath}}:{{targetLine}}
- **Type**: {{targetType}}
- **Change Type**: {{changeType}}

---

### Risk Assessment
| Metric | Value |
|--------|-------|
| Risk Score | {{riskScore}}/​100 |
| Risk Level | {{riskLevel}} |
| Direct Impact | {{directCount}} nodes |
| Indirect Impact | {{indirectCount}} nodes |
| Total Affected | {{totalAffected}} nodes |

---

### Direct Impact ({{directCount}} nodes)
| Node | Type | Reason | Confidence |
|------|------|--------|------------|
{{#each directImpact}}
| {{node.name}} | {{impactType}} | {{reason}} | {{confidence}}% |
{{/​each}}

---

### Indirect Impact (Top 10 of {{indirectCount}})
| Node | Depth | Reason | Confidence |
|------|-------|--------|------------|
{{#each indirectImpact}}
| {{node.name}} | {{depth}} | {{reason}} | {{confidence}}% |
{{/​each}}

---

### Warnings
{{#each warnings}}
- {{this}}
{{/​each}}

---

### Recommended Tests
| Target | Priority | Type | Reason |
|--------|----------|------|--------|
{{#each testSuggestions}}
| {{target}} | {{priority}} | {{testType}} | {{reason}} |
{{/​each}}

---

### Verdict
{{#if riskLevel === 'critical'}}
**CRITICAL**: Do NOT proceed without comprehensive test coverage and review.
{{else if riskLevel === 'high'}}
**HIGH RISK**: Proceed with caution. Ensure all suggested tests pass.
{{else if riskLevel === 'medium'}}
**MEDIUM RISK**: Safe to proceed with standard review process.
{{else}}
**LOW RISK**: Safe to proceed. Minor change with limited impact.
{{/​if}}

Quick Commands

CommandAction
impact <target>기본 영향도 분석
impact signature <target>시그니처 변경 영향도
impact delete <target>삭제 영향도
impact rename <target>이름 변경 영향도
impact depth <n> <target>깊이 지정 분석
impact test <target>테스트 제안만
impact warnings <target>경고만

다른 스킬과의 통합

Integration:
  codebase-graph:
    type: "데이터 소스"
    usage: "그래프 쿼리, 역의존성 추적"

  smart-context:
    type: "협력"
    usage: "영향 범위 컨텍스트 생성"

  code-reviewer:
    type: "소비자"
    usage: "리뷰 시 영향도 표시"

  tdd-guardian:
    type: "소비자"
    usage: "테스트 범위 제안 수신"

  vibe-coding-orchestrator:
    type: "제공자"
    usage: "대규모 리팩토링 전 자동 분석"

문서 구조

impact-analyzer/
├── SKILL.md                      # 이 파일 (메인)
├── core/
│   ├── impact-calculation.md     # 영향도 계산 상세
│   ├── risk-scoring.md           # 위험도 점수 체계
│   └── test-suggestion.md        # 테스트 제안 알고리즘
├── algorithms/
│   ├── reverse-dependency.md     # 역의존성 추적
│   ├── propagation.md            # 영향 전파 알고리즘
│   └── confidence.md             # 확신도 계산
├── templates/
│   ├── report-template.md        # 리포트 템플릿
│   └── warning-templates.md      # 경고 메시지 템플릿
└── quick-reference/
    ├── commands.md               # 명령어 가이드
    └── risk-guide.md             # 위험도 해석 가이드

Version: 1.0.0 Quality Target: 95% Required Skill: codebase-graph Related Skills: smart-context, code-reviewer, tdd-guardian

More skills from majiayu000

xiaohongshu logo
majiayu000/claude-arsenal

xiaohongshu

xiaohongshu

286 148
View
agent-task-conductor logo
majiayu000/claude-skill-registry

agent-task-conductor

Conduct multi-agent task orchestration and workflow coordination.

663 1
View
conductor-setup logo
majiayu000/claude-skill-registry

conductor-setup

Initialize project with Conductor artifacts (product definition,

663 1
View
animation-designer logo
majiayu000/claude-skill-registry

animation-designer

Expert in web animations, transitions, and motion design using Framer Motion and CSS

663 1
View
diagramming logo
majiayu000/claude-skill-registry

diagramming

Creates Mermaid and ASCII diagrams for flowcharts, architecture, ERDs, state machines, mindmaps, and more. Use when user mentions diagram, flowchart, mermaid, ASCII diagram, text diagram, terminal diagram, visualize, C4, mindmap, architecture diagram, sequence diagram, ERD, or needs visual docume...

663 1
View
h3-pg logo
majiayu000/claude-skill-registry-data

h3-pg

PostgreSQL bindings for H3 hexagonal grid system. Use when working with H3 cells in Postgres, including spatial indexing, geometry/geography integration, and raster analysis.

23 1
View
conductor-development logo
majiayu000/claude-skill-registry

conductor-development

Context-Driven Development skill for projects using Conductor. Use this skill when you detect a `conductor/` directory in the project, when working on tasks defined in a `plan.md` file, or when the user asks about tracks, specs, or plans. Automatically applies TDD workflow, tracks task completion...

663 1
View
conductor-status logo
majiayu000/claude-skill-registry

conductor-status

Display project status, active tracks, and next actions

663 1
View
dockerization logo
majiayu000/claude-skill-registry

dockerization

Official Stakpak application containerization standard operating procedure, a step-by-step guidline to properly dockerize applications. This is a rule book curated by the Stakpak Team.

663 1
View

Popular AI tools

Kaiber logo
Video

Kaiber

Generate, edit, and beat-sync AI video with leading models in one workspace.

Paid
View
Vimcal logo
Productivity

Vimcal

The world's fastest calendar for remote work

Free
View

Transform Your Design with AI Designer by ImgCreator.ai

Freemium
View
Akool AI logo
Content & writing

Akool AI

Revolutionizing Video Production with AI-Powered Creativity

Paid
View

Extend an image past the frame and let AI fill the new aspect ratio.

Freemium
View
StarByFace logo
Security

StarByFace

Discover your celebrity doppelgänger with StarByFace!

Free
View
C

ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.

Freemium
View
Opus Clip logo
Coding & apps

Opus Clip

Opus.ai: Revolutionize Your Web Experience

Free
View