Skip to content

fix(complexity): calibrate Halstead thresholds to file level, add p90 outlier category - #83

Merged
aspala merged 2 commits into
mainfrom
fix/complexity-thresholds-file-level
Sep 1, 2026
Merged

fix(complexity): calibrate Halstead thresholds to file level, add p90 outlier category#83
aspala merged 2 commits into
mainfrom
fix/complexity-thresholds-file-level

Conversation

@aspala

@aspala aspala commented Sep 1, 2026

Copy link
Copy Markdown
Member

Die Complexity-Schwellen stammen aus der Halstead-Literatur, wo sie für einzelne Funktionen gelten. codeqa berechnet Halstead aber pro Datei, wodurch sie zwei Größenordnungen zu niedrig lagen: eine gewöhnliche 300-LOC-Datei misst effort ~867k gegen einen A-Schwellwert von 5000, sodass jedes reale Repo D- bekam — codeqa-action auf sich selbst eingeschlossen (30/D-, jetzt 85/A-).

Der Mittelwert allein verbarg zudem genau die Ausreißer, die man sehen will, hinter der Masse kleiner Dateien; deshalb kommt p90 als eigene Kategorie dazu, die die Verteilung statt des Durchschnitts bewertet.

… outlier category

Die Complexity-Schwellen stammten aus der Halstead-Literatur, wo sie fuer einzelne Funktionen gelten — angewandt auf ganze Dateien lagen sie zwei Groessenordnungen zu niedrig, sodass jedes reale Repo D- bekam, codeqa-action selbst eingeschlossen. Der Mittelwert allein verbarg zudem Ausreisser hinter der Masse kleiner Dateien, weshalb p90 als eigene Kategorie dazukommt.
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Score: B → B- | Δ -2 pts | 0 blocks flagged across 5 files | 5 modified, 0 added

🟡 Code Health: B- (71/100)

196 files · codeqa-action · 2026-09-01

Combined metric scores use cosine similarity: +1 = metric profile perfectly matches healthy pattern for this behavior, 0 = no signal, −1 = anti-pattern detected. Mapped to 0–100 using breakpoints (approx: ≥0.5→A, ≥0.2→B, ≥0.0→C, ≥−0.3→D, <−0.3→F); actual letter grades use the full 15-step scale.

Metric Changes

Category Base Head Δ
Readability 88.64 97.89 +9.25
Complexity 30.63 41.57 +10.94
Duplication 0.57 0.59 +0.02
Structure 6.23 9.20 +2.97
%%{init: {'theme': 'neutral'}}%%
xychart-beta
    title "Code Health Scores"
    x-axis ["Readability", "Complexity", "Complexity Outliers", "Structure", "Duplication", "Naming", "Magic Numbers", "Combined Metrics"]
    y-axis "Score" 0 --> 100
    bar [94, 85, 75, 87, 49, 96, 100, 65]
Loading
Readability          ███████████████████░   94  🟢 A
Complexity           █████████████████░░░   85  🟢 A-
Complexity Outliers  ███████████████░░░░░   75  🟡 B
Structure            █████████████████░░░   87  🟢 A-
Duplication          ██████████░░░░░░░░░░   49  🟠 C-
Naming               ███████████████████░   96  🟢 A
Magic Numbers        ████████████████████  100  🟢 A
Combined Metrics     █████████████░░░░░░░   65  🔴 D

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor
🔍 Top Likely Issues (cosine similarity)

Most negative cosine = file's metric profile best matches this anti-pattern.

Behavior Cosine Score
dependencies.low_coupling -0.56 -12.98
file_structure.single_responsibility -0.52 -12.68
file_structure.line_count_under_300 -0.45 -9.59
code_smells.no_dead_code_after_return -0.41 -23.23
scope_and_assignment.shadowed_by_inner_scope -0.31 -5.13
file_structure.line_length_under_120 -0.30 -8.41
variable_naming.name_contains_type_suffix -0.23 -2.28
variable_naming.loop_var_is_single_letter -0.23 3.48
variable_naming.name_contains_and -0.21 -36.63
consistency.same_concept_same_name -0.21 -2.34
🟢 Readability — A (94/100)

Codebase averages: flesch_adapted=97.89, fog_adapted=4.82, avg_tokens_per_line=9.57, avg_line_length=35.81

Metric Value Score
readability.flesch_adapted 97.89 100
readability.fog_adapted 4.82 100
readability.avg_tokens_per_line 9.57 72
readability.avg_line_length 35.81 100
🟢 Complexity — A- (85/100)

Codebase averages: difficulty=41.57, effort=243432.62, volume=4137.53, estimated_bugs=1.38

Metric Value Score
halstead.difficulty 41.57 81
halstead.effort 243432.62 83
halstead.volume 4137.53 89
halstead.estimated_bugs 1.38 90
🟡 Complexity Outliers — B (75/100)

Codebase averages: p90_volume=9542.41, p90_difficulty=67.33, p90_effort=659285.40

Metric Value Score
halstead.p90_volume 9542.41 88
halstead.p90_difficulty 67.33 55
halstead.p90_effort 659285.40 81
🟢 Structure — A- (87/100)

Codebase averages: branching_density=0.14, mean_depth=3.85, avg_function_lines=8.37, max_depth=9.18, max_function_lines=20.13, variance=6.77, avg_param_count=1.16, max_param_count=2.08

Metric Value Score
branching.branching_density 0.14 76
indentation.mean_depth 3.85 88
function_metrics.avg_function_lines 8.37 89
indentation.max_depth 9.18 87
function_metrics.max_function_lines 20.13 90
indentation.variance 6.77 100
function_metrics.avg_param_count 1.16 100
function_metrics.max_param_count 2.08 100
🟠 Duplication — C- (49/100)

Codebase averages: redundancy=0.59, bigram_repetition_rate=0.54, trigram_repetition_rate=0.37

Metric Value Score
compression.redundancy 0.59 58
ngram.bigram_repetition_rate 0.54 38
ngram.trigram_repetition_rate 0.37 41
🟢 Naming — A (96/100)

Codebase averages: entropy=0.89, mean=6.64, variance=18.73, avg_sub_words_per_id=1.17

Metric Value Score
casing_entropy.entropy 0.89 100
identifier_length_variance.mean 6.64 100
identifier_length_variance.variance 18.73 85
readability.avg_sub_words_per_id 1.17 100
🟢 Magic Numbers — A (100/100)

Codebase averages: density=0.00

Metric Value Score
magic_number_density.density 0.00 100
🔴 Combined Metrics — D (65/100)
Category Score Grade
Code Smells 25 🔴 D-
Consistency 82 🟡 B+
Dependencies 19 🔴 E+
Documentation 85 🟢 A-
Error Handling 91 🟢 A-
File Structure 48 🟠 C-
Function Design 82 🟡 B+
Naming Conventions 90 🟢 A-
Scope And Assignment 29 🔴 D-
Testing 83 🟡 B+
Type And Value 89 🟢 A-
Variable Naming 74 🟡 B
🔴 Code Smells — D- (25/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
no_dead_code_after_return -0.41 25 D-
🟡 Consistency — B+ (82/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
consistent_function_style 0.39 82 B+
🔴 Dependencies — E+ (19/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
low_coupling -0.56 19 E+
🟢 Documentation — A- (85/100)

Cosine similarity scores for 3 behaviors.

Behavior Cosine Score Grade
file_has_module_docstring 0.32 78 B+
docstring_is_nonempty 0.46 88 A-
function_has_docstring 0.47 88 A-
🟢 Error Handling — A- (91/100)

Cosine similarity scores for 3 behaviors.

Behavior Cosine Score Grade
error_message_is_descriptive 0.46 87 A-
does_not_swallow_errors 0.62 92 A-
returns_typed_error 0.66 93 A
🟠 File Structure — C- (48/100)

Cosine similarity scores for 5 behaviors.

Behavior Cosine Score Grade
single_responsibility -0.52 20 E+
line_count_under_300 -0.45 24 E+
line_length_under_120 -0.30 30 D-
has_consistent_indentation 0.28 75 B
no_magic_numbers 0.58 92 A-
🟡 Function Design — B+ (82/100)

Cosine similarity scores for 3 behaviors.

Behavior Cosine Score Grade
is_less_than_20_lines 0.33 79 B+
has_verb_in_name 0.40 83 B+
no_magic_numbers 0.40 83 B+
🟢 Naming Conventions — A- (90/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
function_name_is_not_single_word 0.50 90 A-
🔴 Scope And Assignment — D- (29/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
shadowed_by_inner_scope -0.31 29 D-
🟡 Testing — B+ (83/100)

Cosine similarity scores for 2 behaviors.

Behavior Cosine Score Grade
test_single_concept 0.28 75 B
test_name_describes_behavior 0.54 91 A-
🟢 Type And Value — A- (89/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
hardcoded_url_or_path 0.48 89 A-
🟡 Variable Naming — B (74/100)

Cosine similarity scores for 1 behaviors.

Behavior Cosine Score Grade
name_is_generic 0.26 74 B

@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

kind: refactoring-tasks
path: /home/runner/work/codeqa-action/codeqa-action
timestamp: 2026-09-01T17:53:01.452397Z
overall_grade: B-
overall_score: 71
task_count: 0
critical: 0
high: 0
instructions: >-
Address the tasks below in order of severity (critical first).
After each fix, run the project's test suite and confirm it passes
before moving on.

No critical or high-severity blocks need attention. ✅

@aspala
aspala merged commit f1d80df into main Sep 1, 2026
8 checks passed
@aspala
aspala deleted the fix/complexity-thresholds-file-level branch September 1, 2026 17:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant