LogoSkills

/cc-dcm:quality — 코드 건강검진·자동수리

DCM 코드 품질 분석 실행 — 린팅, 미사용 코드, 메트릭, 자동 수정

/cc-dcm:quality — 코드 건강검진·자동수리#

항목내용
실행 명령/cc-dcm:quality
분류코드 품질
난이도●●○ 보통

한마디로#

코드를 건강검진하고 간단한 문제는 자동으로 고쳐주는 도구입니다. 자동차 정비소처럼, 어디가 문제인지 점검하고(분석) 손볼 수 있는 건 그 자리에서 수리(자동수정)해 줍니다.

누가·언제 쓰나요#

  • 코드 품질을 한번 점검하고 싶을 때
  • 안 쓰는 코드나 파일이 쌓여 있는지 확인하고 정리하고 싶을 때
  • 코드 규칙(린트) 위반이나 복잡도 같은 지표를 살펴보고 싶을 때
  • 고칠 수 있는 문제를 자동으로 정리하고 싶을 때

무엇을 해주나요#

  • 코드 전체를 점검해 문제를 파일별·심각도별로 정리한 리포트를 보여줍니다.
  • 자동으로 고칠 수 있는 문제는 그 자리에서 수정합니다.
  • 안 쓰는 코드·안 쓰는 파일·중복 코드·복잡도 지표를 찾아냅니다.
  • 한 번에 기준선을 잡는 작업(baseline)을 하면 dcm_baseline.json 파일이 만들어집니다 — 지금까지의 문제는 "이미 알고 있는 것"으로 묶어두고, 앞으로 새로 생기는 문제만 골라서 관리할 수 있습니다.

어떻게 쓰나요#

# 기본 점검 (대상 생략 시 lib 폴더)
/cc-dcm:quality

# 특정 폴더만 점검
/cc-dcm:quality lib/src/feature

# 전체 점검 후 자동수정까지 한 번에
/cc-dcm:quality --mode=full

# 빠른 단일 점검 — 린트 / 안 쓰는 코드 / 지표
/cc-dcm:quality --mode=analyze
/cc-dcm:quality --mode=unused
/cc-dcm:quality --mode=metrics

# 자동수정 (위험한 수정까지 포함하려면 --unsafe)
/cc-dcm:quality --mode=fix
/cc-dcm:quality --mode=fix --unsafe

# 기준선(baseline) 잡기
/cc-dcm:quality --baseline
  • --mode는 점검 방식입니다: full(전체), analyze(린트만), fix(자동수정), unused(안 쓰는 코드), metrics(지표), duplication(중복).
  • --reporter로 결과 형식을 바꿀 수 있습니다: console(기본, 화면 출력), json(파일·도구 연동용).
  • --unsafe는 자동수정 시 다소 위험할 수 있는 수정까지 포함합니다. 되돌릴 수 있어야 하므로 작업 트리가 깨끗하거나 직전에 되돌림 지점(checkpoint 커밋)이 있을 때만 실행되고, 문제가 생기면 git restore로 그 라운드를 통째로 되돌립니다.

안에서 무슨 일이 벌어지나요#

선택한 방식에 따라 점검과 수정을 차례로 진행합니다.

  1. 전체 점검(full) — 모든 검사를 한 번에 돌리고, 결과를 파일·심각도별로 묶어 보여줍니다. 그다음 자동수정을 하고, 다시 점검해서 "자동으로 해결된 것"과 "사람이 직접 손봐야 하는 것"을 구분해 알려줍니다.
  2. 빠른 점검(analyze/unused/metrics) — 필요한 검사 하나만 골라 돌리고 결과를 보고합니다.
  3. 자동수정(fix) — 먼저 되돌림 지점(checkpoint 커밋)을 확보한 뒤 고칠 수 있는 문제와 안 쓰는 코드를 정리합니다. 라운드마다 컴파일 확인·테스트 통과·위험 패턴 검사 3중 점검을 통과해야 다음으로 넘어가고, 남은 문제 수가 줄지 않으면 그 라운드를 되돌리고 멈춥니다. 최대 2라운드이며 그래도 남은 것은 "사람이 직접 손봐야 하는 항목"으로 보고합니다(자동수정이 화면상 멀쩡한 코드를 출시 버전에서만 터지게 만든 실제 장애 사례가 있어서 그렇습니다).
  4. 기준선 잡기(baseline) — 먼저 진행 계획을 보여주고, 확인을 받은 뒤 단계별로 실행해 dcm_baseline.json을 만들고 커밋까지 안내합니다.

⚙️ 상세 옵션·실행 명세 (개발자 / AI 에이전트용)

Triggers#

  • When code quality analysis is requested
  • When DCM lint checks are requested
  • When unused code/file detection is requested
  • When code metrics review is requested
  • When auto-fix is requested

Context Trigger Pattern#

/cc-dcm:quality {target} [--options]

Parameters#

ParameterRequiredDescriptionExample
targetNoAnalysis target (default: lib)lib, lib/src/feature, .
--modeNoExecution modefull, analyze, fix, unused, metrics, duplication
--reporterNoOutput formatconsole (default), json
--unsafeNoInclude unsafe fixes — refused unless a checkpoint commit exists (see Fix Safety Contract)
--baselineNoRun baseline workflow

Actions#

ActionDescriptionCommand
Full checkRun all checks at oncedcm run . --all
Lint analysisCheck for lint rule violationsdcm analyze .
Auto-fixFix auto-fixable issuesdcm fix .
Unused codeDetect unused code declarationsdcm check-unused-code .
Unused filesDetect unused Dart filesdcm check-unused-files .
Dependency checkCheck for dependency issuesdcm check-dependencies .
Code duplicationDetect duplicate codedcm check-code-duplication .
MetricsCalculate code metricsdcm calculate-metrics .
Widget analysisAnalyze Flutter widgetsdcm analyze-widgets .
Asset analysisAnalyze image assetsdcm analyze-assets .
Structure analysisAnalyze project structuredcm analyze-structure .

Workflow Patterns#

Fix Safety Contract (shared by Pattern 1 and Pattern 3)#

dcm fix is the only destructive action in this command, and its worst failure mode is invisible to flutter analyze: a BlocSignalProvider<T> inside a typed list loses T, still compiles, passes flutter analyze, and throws ProviderNotFoundException only in a release build — a real production outage (commit e72306ef5). The full pattern list is in dcm-auto-fix-pitfalls.

Notation, the loop-contract fields (inv: prog: term: budget: exhaust: resume: log:) and the tri-state gate rule come from ../../cc-dev/rules/orchestration-graph.md (§2 Loop Contract, §3 Gate Contract, §4 Substrate Selection). The values below are this command's own. Substrate: inline / sequential — fix → verify → fix stays strictly sequential and is never fanned out.

Precondition — before the first dcm fix of any round

  • git status --porcelain must be empty; otherwise create a checkpoint commit (git commit -am "checkpoint: before dcm fix") and record CHECKPOINT=$(git rev-parse HEAD) as the rollback anchor for every round.
  • No checkpoint → do not run dcm fix. Report the dirty worktree and stop.
  • --unsafe is gated on $CHECKPOINT existing: without it --unsafe is refused, not silently downgraded to a safe fix.

Per-round verification gate — verdict is tri-state and undetermined defaults to fail (orchestration-graph §3); all three must pass before the next round:

flutter analyze                                   # 0 errors required
melos run test                                    # green required
git diff  " $CHECKPOINT "   --  ' *.dart '   \
  | grep -nE  ' ^-.*(Tween < |closeOverlay < |closeDrawer < |BlocSignalProvider(\.value)? < |context\.(read|watch) < |getIt < ) ' 
                                                   # 0 hits required

The grep exists because analyze is documented-blind to the typed-list case: a removed line carrying any type argument from the pitfalls skill's "절대 타입을 제거하면 안 되는 패턴" table is a fail even when analyze and tests are green. Missing tooling (flutter/melos not installed) is the only undet:warn case here — orchestration-graph §3.1, "안전이 아니라 도구 부재" — and it must be recorded durably in the fix report; under --unsafe missing tooling is a hard stop instead.

Loop contracts — values live here, at the loop's own site:

L-dcm.fix-reanalyze   (Pattern 1 steps 35 · Pattern 3 steps 14)
inv:      $CHECKPOINT exists at round entry and exit, and the diff against it contains
          only `dcm fix` output. Reaching 0 issues by inserting `// ignore:` by hand or
          by regenerating `dcm_baseline.json` is forbidden.
prog:     residual = `dcm analyze .` issue count (error+warning+info), strictly
          decreasing per round
          no-prog: never re-run the same fix on the same residual —
          `git restore --source=$CHECKPOINT --worktree -- .` that round and stop
term:     residual == 0
budget:   2 fix rounds (same value as the sibling dart/DCM lint gate in
          `../../cc-dev/commands/run.md` Step 8.5); `--unsafe` gets the same 2, not more
exhaust:  report the remaining issues as manual items; when this command is invoked
          inside a gate (e.g. run.md Step 8.5) block instead of passing.
          There is no third round.
resume:   $CHECKPOINT SHA + a fresh `dcm analyze .` measurement decide the round
          position (a conversation counter is not a budget)
log:      one line per round —  " #1: dcm=41→12 analyze=0 test=green "   — plus the rounds
          restored and every item handed to manual work, in the fix report
          (`--reporter=json` output, or the PR body when run inside run.md)

L-dcm.autofix-pitfall-verify   (manual type-restore pass inside one fix round)
inv:      at iteration exit: `flutter analyze` 0 errors AND `melos run test` green AND
          0 grep hits on the forbidden-removal patterns above
prog:     violations = grepHits + analyzeErrors + failingTests, strictly decreasing
          no-prog: same hits twice → restore the whole round, do not keep patching
term:     violations == 0
budget:   1 restore iteration per fix round (2 in total)
exhaust:  `git restore` the round and promote the rule to a manual item — exclude it in
          `analysis_options.yaml` rather than re-running the fix
resume:   recompute `git diff  " $CHECKPOINT " `; the only side effect is restoring type
          parameters, which is idempotent
log:      restored symbols + remaining hits, in the same fix report

Rollback — always available, mandatory for --unsafe: undo one round with git restore --source="$CHECKPOINT" --worktree -- ., then confirm with git diff "$CHECKPOINT" --stat returning empty.

Pattern 1: Full Code Review#

/cc-dcm:quality --mode=full
  1. Establish the checkpoint — Fix Safety Contract precondition. No checkpoint → stop before step 3
  2. Run dcm run . --all
  3. Group and report results by file and severity
  4. Auto-fix with dcm fix . (round ≤ 2)
  5. Run the per-round verification gate (flutter analyze 0 errors + melos run test green + 0 forbidden-removal grep hits), then re-run dcm analyze .; residual must strictly decrease, else git restore that round and stop — L-dcm.fix-reanalyze / L-dcm.autofix-pitfall-verify
  6. Report fix results and items requiring manual action; after 2 rounds the remainder is manual and, in a gate context, blocking — see dcm-auto-fix-pitfalls

Pattern 2: Quick Analysis#

/cc-dcm:quality --mode=analyze
/cc-dcm:quality --mode=unused
/cc-dcm:quality --mode=metrics

Run the appropriate single command and report results

Pattern 3: Fix Workflow#

/cc-dcm:quality --mode=fix
/cc-dcm:quality --mode=fix --unsafe
  1. Fix Safety Contract precondition — clean worktree or a checkpoint commit; --unsafe is refused without $CHECKPOINT
  2. Run dcm fix .
  3. Run dcm fix . --type=unused-code
  4. Run the per-round verification gate before re-running checks: flutter analyze 0 errors AND melos run test green AND 0 hits from the forbidden-removal grep over git diff "$CHECKPOINT" — the grep is not optional, because the typed-list BlocSignalProvider failure passes analyze and only breaks in a release build (dcm-auto-fix-pitfalls)
  5. Re-run checks to verify fixes; residual (dcm analyze . issue count) must strictly decrease, else git restore --source="$CHECKPOINT" --worktree -- . that round and stop. Budget 2 rounds (L-dcm.fix-reanalyze) — on exhaustion report the rest as manual items, and block when invoked inside a gate. Never a third round
  6. With --unsafe, state the rollback command in the report so the round can be undone: git restore --source="$CHECKPOINT" --worktree -- .

Pattern 4: Baseline Adoption#

/cc-dcm:quality --baseline
  1. Present the baseline workflow plan to the user
  2. Execute step by step after confirmation
  3. Guide dcm_baseline.json creation and commit