/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로 그 라운드를 통째로 되돌립니다.
안에서 무슨 일이 벌어지나요#
선택한 방식에 따라 점검과 수정을 차례로 진행합니다.
- 전체 점검(full) — 모든 검사를 한 번에 돌리고, 결과를 파일·심각도별로 묶어 보여줍니다. 그다음 자동수정을 하고, 다시 점검해서 "자동으로 해결된 것"과 "사람이 직접 손봐야 하는 것"을 구분해 알려줍니다.
- 빠른 점검(analyze/unused/metrics) — 필요한 검사 하나만 골라 돌리고 결과를 보고합니다.
- 자동수정(fix) — 먼저 되돌림 지점(checkpoint 커밋)을 확보한 뒤 고칠 수 있는 문제와 안 쓰는 코드를 정리합니다. 라운드마다 컴파일 확인·테스트 통과·위험 패턴 검사 3중 점검을 통과해야 다음으로 넘어가고, 남은 문제 수가 줄지 않으면 그 라운드를 되돌리고 멈춥니다. 최대 2라운드이며 그래도 남은 것은 "사람이 직접 손봐야 하는 항목"으로 보고합니다(자동수정이 화면상 멀쩡한 코드를 출시 버전에서만 터지게 만든 실제 장애 사례가 있어서 그렇습니다).
-
기준선 잡기(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#
| Parameter | Required | Description | Example |
|---|---|---|---|
target | No | Analysis target (default: lib) | lib, lib/src/feature, . |
--mode | No | Execution mode | full, analyze, fix, unused, metrics, duplication |
--reporter | No | Output format | console (default), json |
--unsafe | No | Include unsafe fixes — refused unless a checkpoint commit exists (see Fix Safety Contract) | |
--baseline | No | Run baseline workflow |
Actions#
| Action | Description | Command |
|---|---|---|
| Full check | Run all checks at once | dcm run . --all |
| Lint analysis | Check for lint rule violations | dcm analyze . |
| Auto-fix | Fix auto-fixable issues | dcm fix . |
| Unused code | Detect unused code declarations | dcm check-unused-code . |
| Unused files | Detect unused Dart files | dcm check-unused-files . |
| Dependency check | Check for dependency issues | dcm check-dependencies . |
| Code duplication | Detect duplicate code | dcm check-code-duplication . |
| Metrics | Calculate code metrics | dcm calculate-metrics . |
| Widget analysis | Analyze Flutter widgets | dcm analyze-widgets . |
| Asset analysis | Analyze image assets | dcm analyze-assets . |
| Structure analysis | Analyze project structure | dcm 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 --porcelainmust be empty; otherwise create a checkpoint commit (git commit -am "checkpoint: before dcm fix") and recordCHECKPOINT=$(git rev-parse HEAD)as the rollback anchor for every round.- No checkpoint → do not run
dcm fix. Report the dirty worktree and stop. --unsafeis gated on$CHECKPOINTexisting: without it--unsafeis 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 requiredThe 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 3–5 · Pattern 3 steps 1–4)
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 reportRollback — 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- Establish the checkpoint — Fix Safety Contract precondition. No checkpoint → stop before step 3
- Run
dcm run . --all - Group and report results by file and severity
- Auto-fix with
dcm fix .(round ≤ 2) - Run the per-round verification gate (
flutter analyze0 errors +melos run testgreen + 0 forbidden-removal grep hits), then re-rundcm analyze .; residual must strictly decrease, elsegit restorethat round and stop —L-dcm.fix-reanalyze/L-dcm.autofix-pitfall-verify - 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=metricsRun the appropriate single command and report results
Pattern 3: Fix Workflow#
/cc-dcm:quality --mode=fix
/cc-dcm:quality --mode=fix --unsafe- Fix Safety Contract precondition — clean worktree or a checkpoint commit;
--unsafeis refused without$CHECKPOINT - Run
dcm fix . - Run
dcm fix . --type=unused-code - Run the per-round verification gate before re-running checks:
flutter analyze0 errors ANDmelos run testgreen AND 0 hits from the forbidden-removal grep overgit diff "$CHECKPOINT"— the grep is not optional, because the typed-listBlocSignalProviderfailure passes analyze and only breaks in a release build (dcm-auto-fix-pitfalls) - Re-run checks to verify fixes; residual (
dcm analyze .issue count) must strictly decrease, elsegit 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 - 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- Present the baseline workflow plan to the user
- Execute step by step after confirmation
- Guide
dcm_baseline.jsoncreation and commit