Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Audits and restructures control flow using Code Complete's nesting, cyclomatic complexity, loop design, guard-clause, and boolean simplification rules. Covers deep nesting, loop exit design, index naming, and callback chains. For statement-level flow inside a routine; not for routine/class structure (use cc-routine-and-class-design) or staging a broader refactor (use cc-refactoring-guidance).
.claude/skills/ryanthedev-cc-control-flow-quality/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 58% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 137% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-14 | ✓→✗ | ▼ Worse | 143% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 42% | 0% |
| Threshold | Value | Source | |---|---|---| | Max nesting depth | 3 levels | Yourdon 1986a | | McCabe complexity | >10 decision points → redesign | McCabe 1976 | | Else-clause consideration | 50–80% of ifs need an else | Elshoff 1976 | | Loop-with-exit comprehension | 25% better than top/bottom test | Soloway 1983 | | Mental entity limit | 5–9 items | Miller 1956 |
Shared numeric thresholds and the cohesion/coupling vocabulary: Read(${CLAUDE_PLUGIN_ROOT}/references/cc-foundations.md).
The full audit checklists (conditionals, structure, loops, tables): Read(${CLAUDE_SKILL_DIR}/checklists/conditionals-and-structure.md) and Read(${CLAUDE_SKILL_DIR}/checklists/loops-and-advanced.md).
Principles:
true/false, not 0/1, for booleans.for/foreach when the iteration count is known; while when not.if, the error case in else — except guard clauses, which invert this intentionally.Guard clauses are an exception pattern: error/invalid cases exit early at the top so the nominal path flows without nesting. Use them at function entry; use "nominal in if" for conditionals within the body.
cpp// BEFORE: arrow-shaped (4 levels), nominal case buried if (file.validName()) { if (file.open()) { if (encryptionKey.valid()) { if (file.decrypt(encryptionKey)) { /* lots of code */ } } } } // AFTER: guard clauses flatten it if (!file.validName()) return; if (!file.open()) return; if (!encryptionKey.valid()) return; if (!file.decrypt(encryptionKey)) return; // lots of code (nominal case at top level)
cppbool printerCanPrint = printerReady && !printerBusy && paperAvailable && paperLevel > MIN_PAPER; bool documentCanBePrinted = documentValid && !documentEmpty && documentSize < MAX_SIZE; if (inputStatus == SUCCESS && printerCanPrint && documentCanBePrinted) { print(); }
java// BEFORE: transaction[j][i][k] — is this right? who knows // AFTER: self-documenting and verifiable for (int payCodeIdx = 0; payCodeIdx < numPayCodes; payCodeIdx++) for (int month = 0; month < 12; month++) for (int divisionIdx = 0; divisionIdx < numDivisions; divisionIdx++) sum += transaction[month][payCodeIdx][divisionIdx];
Putting a test into a well-named function improves readability, and that alone justifies it — even for a single use p.433].
cppbool isProcessableLetter(char c) { bool isLetter = (('a' <= c) && (c <= 'z')) || (('A' <= c) && (c <= 'Z')); bool isExcluded = (c == 'X') || (c == 'x'); return isLetter && !isExcluded; } if (isProcessableLetter(inputChar)) { processLetter(inputChar); }
cppif (MIN_VALUE <= count && count <= MAX_VALUE) // in-range: variable between bounds if (count < MIN_VALUE || MAX_VALUE < count) // out-of-range: variable on the outside while (!done) // boolean: compare implicitly while (balance != 0) // numeric: compare explicitly while (*charPtr != '\0') // character: compare to the terminator while (bufferPtr != NULL) // pointer: compare to NULL
cpp// AFTER: while(true) + break eliminates the duplicated read at top and bottom while (true) { GetNextRating(&ratingIncrement); rating += ratingIncrement; if (!((score < targetScore) && (ratingIncrement != 0))) break; GetNextScore(&scoreIncrement); score += scoreIncrement; }
for/foreach, else while.do-while)/MIDDLE, else test at BEGINNING.foreach (eliminates housekeeping arithmetic errors).while(true) + break).#5 and #6 are context-dependent, not ranked: tables can be simpler than polymorphism. "The fact that a design uses inheritance and polymorphism doesn't make it a good design" p.423].
Consider a table instead of branching logic when: writing the 4th+ branch in an if-else chain for the same classification; creating a subclass just to change a data value; rules change often without wanting code changes; or the same lookup is duplicated in several places.
Access method: direct (data keys straight into the table, e.g. month 1–12) → indexed (large/sparse keyspace, few entries) → stair-step (entries valid for ranges, e.g. grade thresholds).
Count: start at 1, add 1 per if/while/for/and/or and per case branch.
| Count | Verdict | |---|---| | 0–5 | Probably fine | | 6–10 | Start simplifying | | 10–20 | Strong justification needed; review for extraction | | 20+ | Mandatory refactor |
A routine in the 10–20 range is acceptable only when all of: it's a flat dispatch (switch/case, no nesting within cases); each case is ≤3 lines (ideally a single call); cases are exhaustive and unlikely to grow unboundedly; and cognitive complexity is low. Inherent-complexity or "just a big if-else chain" do not qualify — extract instead.
The same flatten-the-structure principle applies beyond Code Complete's era: async/await replaces callback nesting, and exhaustiveness-checked pattern matching is the valid high-McCabe flat dispatch.
| After | Next | |---|---| | Control flow verified | Skill(code-foundations:code-clarity-and-docs) |
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 17,151 | 15,300 | -11% | 1 | 1 | 0% | 2,744 | 4,343 | +58% | 0 | 0 | — |
case-02 | pass→pass | 13,588 | 9,422 | -31% | 1 | 1 | 0% | 2,337 | 3,329 | +42% | 0 | 0 | — |
case-03 | fail→fail | 14,377 | 8,615 | -40% | 1 | 1 | 0% | 2,519 | 3,006 | +19% | 0 | 0 | — |
case-04 | pass→pass | 13,439 | 5,526 | -59% | 1 | 1 | 0% | 2,353 | 2,591 | +10% | 0 | 0 | — |
case-05 | fail→pass | 6,235 | 6,189 | -1% | 1 | 1 | 0% | 1,052 | 2,498 | +137% | 0 | 0 | — |
case-06 | pass→pass | 11,719 | 6,163 | -47% | 1 | 1 | 0% | 2,177 | 2,715 | +25% | 0 | 0 | — |
case-11 | pass→pass | 11,104 | 5,328 | -52% | 1 | 1 | 0% | 1,627 | 2,576 | +58% | 0 | 0 | — |
case-07 | pass→pass | 9,584 | 3,763 | -61% | 1 | 1 | 0% | 1,630 | 2,344 | +44% | 0 | 0 | — |
case-08 | pass→pass | 7,498 | 7,097 | -5% | 1 | 1 | 0% | 1,306 | 2,842 | +118% | 0 | 0 | — |
case-09 | pass→pass | 10,056 | 10,712 | +7% | 1 | 1 | 0% | 1,825 | 3,614 | +98% | 0 | 0 | — |
case-10 | pass→pass | 12,817 | 14,945 | +17% | 1 | 1 | 0% | 2,224 | 4,405 | +98% | 0 | 0 | — |
case-12 | pass→pass | 11,443 | 8,687 | -24% | 1 | 1 | 0% | 1,999 | 3,148 | +57% | 0 | 0 | — |
case-13 | pass→pass | 5,832 | 3,374 | -42% | 1 | 1 | 0% | 1,083 | 2,293 | +112% | 0 | 0 | — |
case-14 | pass→fail | 6,076 | 4,412 | -27% | 1 | 1 | 0% | 983 | 2,385 | +143% | 0 | 0 | — |
case-15 | pass→pass | 24,651 | 8,590 | -65% | 1 | 1 | 0% | 4,303 | 3,296 | -23% | 0 | 0 | — |
case-16 | pass→pass | 5,902 | 4,418 | -25% | 1 | 1 | 0% | 919 | 2,414 | +163% | 0 | 0 | — |
case-17 | pass→pass | 8,695 | 3,560 | -59% | 1 | 1 | 0% | 1,458 | 2,216 | +52% | 0 | 0 | — |
case-18 | fail→pass | 13,519 | 4,244 | -69% | 1 | 1 | 0% | 2,065 | 2,332 | +13% | 0 | 0 | — |
case-19 | pass→pass | 26,911 | 5,154 | -81% | 1 | 1 | 0% | 2,375 | 2,429 | +2% | 0 | 0 | — |
case-20 | pass→pass | 8,764 | 7,620 | -13% | 1 | 1 | 0% | 1,604 | 2,932 | +83% | 0 | 0 | — |
case-21 | pass→pass | 4,602 | 3,716 | -19% | 1 | 1 | 0% | 783 | 2,298 | +193% | 0 | 0 | — |
case-22 | pass→pass | 8,815 | 5,889 | -33% | 1 | 1 | 0% | 1,426 | 2,736 | +92% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +9 percentage points is the difference between those two pass rates over the 22 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.