Files
pygienium/tasks/10-check-complexity.md

3.4 KiB
Raw Permalink Blame History

10. Excessive complexity check

meta: id: pygienium-10 feature: pygienium priority: P2 depends_on: [pygienium-06] tags: [check]

objective:

  • Implement the excessive-complexity check: detect high cyclomatic complexity with concrete thresholds, plus unnecessarily fancy code, non-conventional patterns, and over-abstraction; refactor toward the simplest implementation that meets requirements.

deliverables:

  • src/checks/complexity.ts: CheckDefinition with scan + fix tasks
  • Cyclomatic complexity thresholds (MUST enforce, not advisory):
    • 50+ → must refactor. No exceptions. The function is too complex; break it up.
    • 3549 → heavy skepticism. Only keep if this is a massively critical point along the main path and the complexity genuinely must be here. Otherwise refactor. The agent must justify, in findings.md, why a 3549 function is kept (critical path + why it can't be simplified).
    • <35 → not flagged on cyclomatic grounds (may still be flagged for other complexity smells like nesting/over-abstraction)
  • Rubric: speculative abstractions, premature config indirection, non-idiomatic patterns, over-engineered generics, unnecessary wrappers; refactor to common conventions and the simplest correct form
  • /pygienium-complexity runs E2E

steps:

  • Author buildScanTask: agent identifies complexity hotspots:
    1. Cyclomatic complexity — compute via a deterministic tool when available (e.g. lizard/radon/gocyclo/language-native), fall back to counting decision points (if/else if/for/while/case/&&/||/catch) per function. Classify each function into the 50+ / 3549 / below-35 bands above. Write per-function scores to pygienium/checks/complexity/findings.md with line refs.
    2. Structural smells — deep nesting (>3 levels), needless indirection, speculative abstractions — same findings.md, separate section.
    • findings.md includes a proposed simpler form for every flagged function.
  • Author buildFixTask: apply safe refactors (flatten nested conditionals, inline trivial wrappers, remove speculative config, split 50+ functions); for 3549 functions, keep ONLY if the agent can justify critical-path necessity, else refactor. Flag risky refactors for review.
  • Register the check

tests:

  • Integration: temp file with a 55-decision-point function (must-refactor) + a 40-decision-point function (heavy-skepticism, must justify or refactor); run --fix; assert the 50+ is split, the 3549 is either refactored or has a documented justification in changes.md
  • Integration: temp file with a needlessly abstracted config layer + deep nesting; run --fix; assert simplified

acceptance_criteria:

  • findings.md lists cyclomatic complexity scores per function banded as 50+/35-49/below-35
  • Every 50+ function is refactored by --fix (no 50+ remains post-fix)
  • Every kept 3549 function has a documented justification (critical path + why-simpler-isn't-possible) in findings.md; unjustified ones are refactored
  • findings.md lists structural complexity hotspots with proposed simplifications
  • --fix applies safe refactors and preserves behavior (agent re-reads after edit)

validation:

  • Inspect pygienium/checks/complexity/{findings.md,changes.md}

notes:

  • Encode the engineering rules directly in the rubric: simplest implementation, no speculative abstractions, grow in layers
  • The lens risk-hotspots (fan-in × complexity) and module_report complexity flags are signals to feed the agent