low-complexity
Low Complexity Code
Every function/method written or modified MUST target:
- Cognitive Complexity <= 5 (SonarSource metric). Acceptable up to 10 for inherently complex logic. Never exceed 15.
- Cyclomatic Complexity <= 5. Acceptable up to 10. Never exceed 15.
For full scoring rules, see cognitive-complexity-spec.md.
Cognitive Complexity Quick Reference
+1 for each: if, ternary (? :), switch (whole), for, while, do while, catch, else if, else, goto LABEL, break/continue LABEL, each method in a recursion cycle, each sequence of like boolean operators (&& / ||).
+1 nesting penalty on top of structural increment for: if, ternary, switch, for, while, catch — when nested inside another flow-break structure.
Free (no increment): method calls, try, finally, case labels, null-coalescing (?., ??), early return, simple break/continue, lambdas (but lambdas increase nesting level).
Cyclomatic Complexity Quick Reference
+1 for the method entry, +1 for each: if, else if, for, while, do while, case, catch, &&, ||, ternary ?. Core definition; some analyzers may vary by language.
Mandatory Reduction Techniques
Apply these in order of preference:
- Extract method/function — Move a coherent block into a named function. Resets nesting to 0. First choice when the extracted block forms a coherent unit.
- Early return / guard clause — Invert condition, return early, reduce nesting by 1 level.
- Replace nested conditions with flat logic —
if A { if B {becomesif A && B {(saves nesting penalty). - Replace if/else chains with polymorphism, strategy pattern, or lookup table — Eliminates branching entirely.
- Replace loop + condition with declarative pipeline —
filter/map/reduceor LINQ or streams instead offor+if. - Decompose boolean expressions — Extract complex conditions into named boolean variables or predicate functions.
- Replace flag variables with early exit — Eliminate boolean flags that control flow later.
- Use language idioms — Null-coalescing, optional chaining, pattern matching, destructuring. These are often lower-cost than equivalent if/else chains (destructuring is free; pattern matching is +1 for the whole match vs +1 per branch in if/else).
How to Apply
When writing any function/method:
- Write the logic
- Mentally count: each
if/else if/else/for/while/switch/catch/ternary= +1, each nesting level on structural ones = +1 more, each boolean operator sequence = +1 - If score > 5, refactor using the techniques above before finalizing
- Prefer multiple small functions over one large function
- Nesting depth > 2 is a smell — extract immediately
Bad vs Good Examples
Bad: Nested conditionals (CogC = 9)
def process(user, order):
if user.is_active: # +1
if order.is_valid: # +2 (nesting=1)
if order.total > 100: # +3 (nesting=2)
apply_discount(order)
else: # +1
charge_full(order)
else: # +1
raise InvalidOrder()
else: # +1
raise InactiveUser() # Total: 1+2+3+1+1+1 = 9
Good: Guard clauses + extraction (process CogC=2, charge CogC=2)
def process(user, order): # CogC = 2
if not user.is_active: # +1
raise InactiveUser()
if not order.is_valid: # +1
raise InvalidOrder()
charge(order)
def charge(order): # CogC = 2
if order.total > 100: # +1
apply_discount(order)
else: # +1
charge_full(order)
Bad: Loop with nested conditions (CogC = 10)
function findFirst(items, criteria) {
for (const item of items) { // +1
if (item.active) { // +2 (nesting=1)
if (item.type === criteria.type) { // +3 (nesting=2)
if (item.score > criteria.min) { // +4 (nesting=3)
return item;
}
}
}
} // Total: 1+2+3+4 = 10
return null;
}
Good: Flat filter + early continue (findFirst CogC=5, matches CogC=1)
function findFirst(items, criteria) { // CogC = 5
for (const item of items) { // +1
if (!item.active) continue; // +2 (nesting=1)
if (matches(item, criteria)) return item; // +2 (nesting=1)
}
return null;
}
function matches(item, criteria) { // CogC = 1
return item.type === criteria.type // +1 (&& sequence)
&& item.score > criteria.min;
}
More from mryll/skills
vertical-slice-architecture
Enforce Vertical Slice Architecture (VSA) when building applications in any language (Go, .NET/C#, Java, Kotlin, TypeScript, Python, etc.) and any type (web API, mobile backend, CLI, event-driven). Organize code by feature/use-case instead of technical layers. Each feature is a self-contained vertical slice with a single entry point that receives the router/framework handle and its dependencies. Use when the user says "vertical slice architecture", "VSA", "organizar por feature", "feature-based architecture", "slice architecture", or when building a new app or feature and the project already follows VSA conventions. Also use when reviewing or refactoring code to align with VSA principles.
154agentmd
Generate minimal, research-backed CLAUDE.md / AGENTS.md / COPILOT.md context files for coding agent CLIs. Based on "Evaluating AGENTS.md" (ETH Zurich, Feb 2026) which found that auto-generated context files DECREASE performance by ~3% and increase costs by 20-23%, while minimal human-written files improve performance by ~4%. Use when the user says "generate CLAUDE.md", "create AGENTS.md", "generate context file", "agentmd", "create recommended CLAUDE.md", "generate agent instructions", "init context file", or any request to create/improve a coding agent context file for a repository. Replaces the default /init command which generates bloated, counterproductive context files.
36codex-review
Iterative code review and planning discussion between the local agent and Codex CLI (model and reasoning effort taken from the user's local Codex configuration at ~/.codex/config.toml, overridable per invocation). Orchestrates an automatic back-and-forth debate where both agents discuss findings, architecture decisions, or implementation plans until reaching consensus. Codex CLI operates in READ-ONLY mode — it never modifies files. Supports plan mode: when the local agent has a plan ready, invoke this skill to have Codex evaluate and iterate on the plan before implementation, producing an updated consensus plan. Use when the user asks to review with codex, analyze with codex, discuss with codex, iterate with codex, consult codex, ask codex, review the plan with codex, validate plan with codex, or any request involving Codex CLI for code review, architecture review, planning discussion, or collaborative analysis of code, design, or implementation strategy.
23test-namer
Guide for writing expressive, behavior-focused tests following Vladimir Khorikov's testing principles. Apply when writing, reviewing, or renaming any test (unit, integration, e2e) in any programming language. Triggers: writing tests, creating test files, adding test cases, reviewing test names, 'test naming', 'rename tests', 'Khorikov', or any test creation task. Covers: naming conventions (plain English over rigid policies), what to test (behavior not implementation), testing styles (output > state > communication), and pragmatic test investment.
17dual-testing
Go dual testing strategy: integration tests (testcontainers) verify full-chain wiring for happy paths, unit tests (testify/mock) verify error handling logic. Apply when designing test strategy for a Go project, creating a new handler or feature that needs tests, or deciding what type of test to write for a scenario. Triggers: 'dual testing', 'error path coverage', 'testcontainers vs mocks', 'what type of test', 'where should this test go', 'integration vs unit', creating Go handlers/features/workers that need tests. Does NOT trigger on: writing individual test assertions, renaming tests, test naming conventions (use test-namer for those).
3