Communitygithub.com

click-path-audit

모든 사용자 대상 버튼/터치포인트를 전체 상태 변경 시퀀스로 추적하여, 개별 함수는 정상 작동하지만 서로를 취소하거나 잘못된 최종 상태를 만들거나 UI를 일관성 없는 상태로 남기는 버그를 찾습니다. 사용 시점: 체계적 디버깅으로 버그를 찾지 못했지만 사용자가 버튼 오작동을 보고할 때, 또는 공유 상태 저장소를 건드리는 주요 리팩터링 이후.

click-path-audit란 무엇인가요?

이 스킬은 정적 코드 리딩으로는 발견하기 어려운 버그, 즉 상태 상호작용 부작용, 순차 호출 간 경합 조건, 그리고 핸들러가 서로를 조용히 취소하는 경우를 찾아냅니다. 전통적인 디버깅은 함수 존재 여부, 런타임 오류, 데이터 타입 검사에 초점을 맞추지만, 최종 UI 상태가 버튼 라벨과 일치하는지, 함수 B가 함수 A의 변경을 조용히 되돌리는지, 공유 상태(Zustand/Redux/Context)에 의도된 동작을 무효화하는 부작용이 있는지는 확인하지 않습니다. 이 스킬은 모든 인터랙티브 터치포인트의 핸들러를 추적하고, 각 함수 호출이 읽고 쓰는 상태와 공유 상태에 미치는 부작용을 분석하여, 나중 호출이 이전 호출의 상태 변경을 취소하는지, 최종 상태가 사용자 기대와 일치하는지, 그리고 비동기 호출 순서에 따른 경합 조건이 있는지를 검사합니다. 54가지 버그 유형을 찾는 체계적 디버깅 후에도 놓칠 수 있는 이 버그 유형을 잡아내며, 수정 전에 실행됩니다. 주요 플랫폼은 Zustand 기반 React 앱을 가정하지만, 모든 상태 관리 라이브러리(Redux, Context)에 적용 가능합니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/click-path-audit

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

/click-path-audit — 동작 흐름 감사

정적 코드 읽기가 놓치는 버그를 찾습니다: 상태 상호작용 부작용, 순차 호출 간 경합 조건, 그리고 서로를 조용히 취소하는 핸들러.

이 스킬이 해결하는 문제

전통적인 디버깅은 확인합니다:

  • 함수가 존재하는가? (와이어링 누락)
  • 충돌하는가? (런타임 오류)
  • 올바른 타입을 반환하는가? (데이터 흐름)

하지만 확인하지 않습니다:

  • 최종 UI 상태가 버튼 라벨이 약속하는 것과 일치하는가?
  • 함수 B가 함수 A가 방금 한 일을 조용히 취소하는가?
  • 공유 상태(Zustand/Redux/컨텍스트)에 의도된 동작을 취소하는 부작용이 있는가?

실제 예시: "새 이메일" 버튼이 setComposeMode(true)를 호출한 다음 selectThread(null)을 호출했습니다. 둘 다 개별적으로는 잘 작동했습니다. 하지만 selectThread에 composeMode: false를 리셋하는 부작용이 있었습니다. 버튼은 아무 일도 하지 않았습니다. 체계적 디버깅으로 54개의 버그를 찾았지만, 이 하나는 놓쳤습니다.


작동 방식

대상 영역의 모든 인터랙티브 터치포인트에 대해:

1. 핸들러(onClick, onSubmit, onChange 등)를 식별합니다.
2. 핸들러의 모든 함수 호출을 **순서대로** 추적합니다.
3. 각 함수 호출에 대해:
   a. 어떤 상태를 **읽나요**?
   b. 어떤 상태를 **쓰나요**?
   c. 공유 상태에 **부작용**이 있나요?
   d. 부작용으로 상태를 리셋/클리어하나요?
4. 확인: 나중 호출이 이전 호출의 상태 변경을 **취소하나요**?
5. 확인: **최종 상태**가 버튼 라벨에서 사용자가 기대하는 것인가요?
6. 확인: 경합 조건(잘못된 순서로 해결되는 비동기 호출)이 있나요?

실행 단계

1단계: 상태 저장소 매핑

터치포인트를 감사하기 전에, 모든 상태 저장소 액션의 부작용 맵을 구축합니다:

각 Zustand 저장소 / React 컨텍스트에 대해:
  각 액션/세터에 대해:
    - 어떤 필드를 설정하나요?
    - 다른 필드를 **리셋**하나요? (부작용)
    - 문서화: actionName → {sets: [...], resets: [...]}

이것이 중요한 참조입니다. "새 이메일" 버그는 selectThread가 composeMode를 리셋한다는 사실을 몰랐으면 보이지 않았을 것입니다.

출력 형식:

STORE: emailStore
  setComposeMode(bool) → sets: {composeMode}
  selectThread(thread|null) → sets: {selectedThread, selectedThreadId, messages, drafts, selectedDraft, summary} RESETS: {composeMode: false, composeData: null, redraftOpen: false}
  setDraftGenerating(bool) → sets: {draftGenerating}
  ...

위험한 리셋 (자신이 소유하지 않은 상태를 지우는 액션):
  selectThread → composeMode 리셋 (setComposeMode 소유)
  reset → 모든 것 리셋

2단계: 각 터치포인트 감사

대상 영역의 각 버튼/토글/폼 제출에 대해:

TOUCHPOINT: [버튼 라벨] in [Component:line]
  HANDLER: onClick → {
    call 1: functionA() → sets {X: true}
    call 2: functionB() → sets {Y: null} RESETS {X: false}  ← 충돌
  }
  EXPECTED: 사용자가 [버튼 라벨이 약속하는 설명]을 봄
  ACTUAL: functionB가 리셋했으므로 X는 false
  VERDICT: BUG — [설명]

다음 각 버그 패턴을 확인합니다:

패턴 1: 순차적 취소

handler() {
  setState_A(true)     // X = true 설정
  setState_B(null)     // 부작용: X = false 리셋
}
// 결과: X는 false. 첫 번째 호출은 무의미했습니다.

패턴 2: 비동기 경합

handler() {
  fetchA().then(() => setState({ loading: false }))
  fetchB().then(() => setState({ loading: true }))
}
// 결과: 최종 loading 상태는 어느 것이 먼저 해결되느냐에 달려 있습니다.

패턴 3: 오래된 클로저

const [count, setCount] = useState(0)
const handler = useCallback(() => {
  setCount(count + 1)  // 오래된 count 캡처
  setCount(count + 1)  // 동일한 오래된 count — 2가 아닌 1만 증가
}, [count])

패턴 4: 상태 전환 누락

// 버튼 라벨이 "저장"이지만 핸들러는 유효성 검사만 할 뿐 실제 저장은 하지 않음
// 버튼 라벨이 "삭제"이지만 핸들러는 플래그만 설정하고 API는 호출하지 않음
// 버튼 라벨이 "보내기"이지만 API 엔드포인트가 제거/손상됨

패턴 5: 조건부 사망 경로

handler() {
  if (someState) {        // someState는 이 시점에서 항상 false
    doTheActualThing()    // 절대 도달하지 않음
  }
}

패턴 6: useEffect 간섭

// 버튼이 stateX = true로 설정
// useEffect가 stateX를 감시하고 false로 리셋
// 사용자는 아무 일도 일어나지 않음을 봄

3단계: 보고

발견된 각 버그에 대해:

CLICK-PATH-NNN: [심각도: CRITICAL/HIGH/MEDIUM/LOW]
  터치포인트: [버튼 라벨] in [file:line]
  패턴: [순차적 취소 / 비동기 경합 / 오래된 클로저 / 전환 누락 / 사망 경로 / useEffect 간섭]
  핸들러: [함수 이름 또는 인라인]
  추적:
    1. [호출] → sets {필드: 값}
    2. [호출] → RESETS {필드: 값}  ← 충돌
  예상 결과: [사용자가 기대하는 것]
  실제 결과: [실제로 일어나는 것]
  수정: [구체적인 수정]

범위 제어

이 감사는 비용이 많이 듭니다. 적절히 범위를 지정하세요:

  • 전체 앱 감사: 출시 시 또는 주요 리팩터링 후에 사용합니다. 페이지별로 병렬 에이전트를 실행합니다.
  • 단일 페이지 감사: 새 페이지를 구축한 후 또는 사용자가 버튼 오작동을 보고한 후에 사용합니다.
  • 저장소 중심 감사: Zustand 저장소를 수정한 후에 사용합니다 — 변경된 액션의 모든 소비자를 감사합니다.

전체 앱에 권장되는 에이전트 분할:

Agent 1: 모든 상태 저장소 매핑 (1단계) — 다른 모든 에이전트의 공유 컨텍스트
Agent 2: 대시보드 (작업, 메모, 일지, 아이디어)
Agent 3: 채팅 (DanteChatColumn, JustChatPage)
Agent 4: 이메일 (ThreadList, DraftArea, EmailsPage)
Agent 5: 프로젝트 (ProjectsPage, ProjectOverviewTab, NewProjectWizard)
Agent 6: CRM (모든 하위 탭)
Agent 7: 프로필, 설정, 금고, 알림
Agent 8: 관리 제품군 (모든 페이지)

Agent 1이 먼저 완료되어야 합니다. 그 출력은 다른 모든 에이전트의 입력입니다.


사용 시점

  • 체계적 디버깅에서 "버그 없음"을 찾았지만 사용자가 UI 오작동을 보고하는 경우
  • Zustand 저장소 액션을 수정한 후 (모든 호출자 확인)
  • 공유 상태를 건드리는 모든 리팩터링 후
  • 출시 전, 중요한 사용자 흐름에 대해
  • 버튼이 "아무 일도 안 할 때" — 이를 위한 도구입니다.

사용하지 말아야 할 시점

  • API 수준 버그(잘못된 응답 형태, 누락된 엔드포인트) — 체계적 디버깅 사용
  • 스타일링/레이아웃 문제 — 시각적 검사
  • 성능 문제 — 프로파일링 도구

다른 스킬과의 통합

  • /superpowers:systematic-debugging 후에 실행 (다른 54가지 버그 유형을 찾음)
  • /superpowers:verification-before-completion 전에 실행 (수정이 작동하는지 확인)
  • /superpowers:test-driven-development에 입력 제공 — 여기서 발견된 모든 버그는 테스트를 받아야 함

예시: 이 스킬의 영감이 된 버그

ThreadList.tsx "새 이메일" 버튼:

onClick={() => {
  useEmailStore.getState().setComposeMode(true)   // ✓ composeMode = true 설정
  useEmailStore.getState().selectThread(null)      // ✗ composeMode = false 리셋
}}

저장소 정의:

selectThread: (thread) => set({
  selectedThread: thread,
  selectedThreadId: thread?.id ?? null,
  messages: [],
  drafts: [],
  selectedDraft: null,
  summary: null,
  composeMode: false,     // ← 이 조용한 리셋이 버튼을 망쳤습니다
  composeData: null,
  redraftOpen: false,
})

체계적 디버깅이 놓친 이유:

  • 버튼에 onClick 핸들러가 있음 (데드 아님)
  • 두 함수 모두 존재함 (와이어링 누락 없음)
  • 함수 중 어느 것도 충돌하지 않음 (런타임 오류 없음)
  • 데이터 타입이 올바름 (타입 불일치 없음)

클릭 경로 감사가 포착하는 이유:

  • 1단계: selectThread가 composeMode를 리셋함을 매핑
  • 2단계: 핸들러 추적 — 첫 번째 호출이 true 설정, 두 번째 호출이 false 리셋
  • 판정: 순차적 취소 — 최종 상태가 버튼 의도와 모순됨

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

관련 스킬