[Tech debt][Epic] SonarQube: frontend HIGH/BLOCKER maintainability smells (~1,675) #250

Closed
opened 2026-06-19 18:45:24 +00:00 by spikerj · 2 comments
Owner

Tracking epic for learn.spikersoft.com MAINTAINABILITY smells at HIGH/BLOCKER severity. Total 1,675 OPEN (vs ~2,531 more at MEDIUM). Too many to fix at once; this epic tracks the cleanup and will be split into focused PRs/sub-tickets.

Top rules (sample of first 500)

Rule ~Count Note
javascript:S3504 402 var → let/const — overwhelmingly in vendored/generated assets (blinkenlib.js, voxel-game). Best handled via SonarQube exclusions, not hand edits.
typescript:S3776 28+ Cognitive complexity > 15 in our TS — real refactor targets.
javascript:S7767 18 Math.trunc vs bit-ops — mostly vendored.
javascript:S3776 10 Complexity in generated/vendored JS.
typescript:S4123 7 await on non-promise.
typescript:S3735 7 void operator misuse.
javascript:S2004 7 Functions nested too deeply.
typescript:S1186 5 Empty method bodies.
typescript:S7059 4 async-in-constructor (see #242).

Plan

  1. Add SonarQube exclusions for vendored/generated assets (blinkenlib.js, voxel-game long.js, wasm-voxel vendored) so S3504/S7767 noise drops out — this likely removes the large majority.
  2. Re-scan, then triage the remaining our-code smells (primarily typescript:S3776, S4123, S3735, S2004, S1186) into focused per-area PRs.
  3. Close this epic once HIGH/BLOCKER is back to a clean gate.

Counts are from the first 500 of 1,675; full per-rule totals available from SonarQube (learn.spikersoft.com).


Child issues (per-repo, auto-close on merge)

No open child issues were produced by the migration — either this epic's
work was already complete, or its scope needs to be broken down into
per-repo issues before it can progress.

Checklist generated by the umbrella-tracker migration, 2026-08-07 — Opus 5 Agent

Tracking epic for `learn.spikersoft.com` MAINTAINABILITY smells at HIGH/BLOCKER severity. Total **1,675** OPEN (vs ~2,531 more at MEDIUM). Too many to fix at once; this epic tracks the cleanup and will be split into focused PRs/sub-tickets. ## Top rules (sample of first 500) | Rule | ~Count | Note | |---|---|---| | `javascript:S3504` | 402 | `var` → `let`/`const` — overwhelmingly in **vendored/generated assets** (blinkenlib.js, voxel-game). Best handled via SonarQube exclusions, not hand edits. | | `typescript:S3776` | 28+ | Cognitive complexity > 15 in **our** TS — real refactor targets. | | `javascript:S7767` | 18 | `Math.trunc` vs bit-ops — mostly vendored. | | `javascript:S3776` | 10 | Complexity in generated/vendored JS. | | `typescript:S4123` | 7 | `await` on non-promise. | | `typescript:S3735` | 7 | `void` operator misuse. | | `javascript:S2004` | 7 | Functions nested too deeply. | | `typescript:S1186` | 5 | Empty method bodies. | | `typescript:S7059` | 4 | async-in-constructor (see #242). | ## Plan 1. Add SonarQube exclusions for vendored/generated assets (blinkenlib.js, voxel-game `long.js`, wasm-voxel vendored) so `S3504`/`S7767` noise drops out — this likely removes the large majority. 2. Re-scan, then triage the remaining **our-code** smells (primarily `typescript:S3776`, `S4123`, `S3735`, `S2004`, `S1186`) into focused per-area PRs. 3. Close this epic once HIGH/BLOCKER is back to a clean gate. _Counts are from the first 500 of 1,675; full per-rule totals available from SonarQube (`learn.spikersoft.com`)._ <!-- BEGIN MIGRATED-CHILDREN --> --- ## Child issues (per-repo, auto-close on merge) _No open child issues were produced by the migration — either this epic's work was already complete, or its scope needs to be broken down into per-repo issues before it can progress._ <sub>Checklist generated by the umbrella-tracker migration, 2026-08-07 — Opus 5 Agent</sub> <!-- END MIGRATED-CHILDREN -->
spikerj added the sonarqube label 2026-06-19 18:45:24 +00:00
Author
Owner

Step 1 done in spikersoft-angular PR #73 (merged to master): added SonarQube exclusions for vendored/generated assets — assets/x86-playground/blinkenlib.js (Emscripten), assets/voxel-game/** (ported JS), wasm-voxel/ts/libraries/long.ts (Long.js port). This should drop the bulk of the S3504/S7767 noise.

Next (ticket stays open):

  • Re-scan learn.spikersoft.com and confirm the HIGH/BLOCKER count after exclusions.
  • Triage the remaining our-code smells (primarily typescript:S3776, S4123, S3735, S2004, S1186) into focused per-area PRs.
Step 1 done in spikersoft-angular PR #73 (merged to `master`): added SonarQube exclusions for vendored/generated assets — `assets/x86-playground/blinkenlib.js` (Emscripten), `assets/voxel-game/**` (ported JS), `wasm-voxel/ts/libraries/long.ts` (Long.js port). This should drop the bulk of the `S3504`/`S7767` noise. Next (ticket stays open): - [ ] Re-scan `learn.spikersoft.com` and confirm the HIGH/BLOCKER count after exclusions. - [ ] Triage the remaining our-code smells (primarily `typescript:S3776`, `S4123`, `S3735`, `S2004`, `S1186`) into focused per-area PRs.
spikerj added the epic label 2026-08-07 13:43:00 +00:00
Author
Owner

Dissolved into per-repo issues as part of the umbrella-tracker breakup. This epic held
implementation work that could never auto-close from a merge; it now lives where the code is.

First, the headline: the ~1,675 figure in this epic is dead. The real number today is 125.

Live query against sonarqube.spikersoft.com (project learn.spikersoft.com, last analysis
2026-08-07T11:49:57Z), impactSoftwareQualities=MAINTAINABILITY, impactSeverities=HIGH,BLOCKER:

2026-06-19 (this epic) 2026-08-07 (live)
BLOCKER maintainability (inside the 1,675) 0
HIGH maintainability 1,675 125

A 92.5% drop, and BLOCKER is at zero. The epic's premise — "too many to fix at once" — no
longer holds; what is left is roughly two to five focused PRs.

Per-rule, current vs. what this epic recorded:

Rule Epic (2026-06-19) Live (2026-08-07)
javascript:S3504 var→let/const 402 7
typescript:S3776 complexity 28+ 84 (full count; the epic only sampled 500)
javascript:S7767 Math.trunc 18 0
javascript:S3776 10 3
typescript:S4123 await on non-promise 7 0
typescript:S3735 void operator 7 14
javascript:S2004 nested functions 7 0 (2 remain as typescript:S2004)
typescript:S1186 empty method 5 0
typescript:S7059 async-in-ctor 4 0

New in the remainder since filing: typescript:S7740 (5), typescript:S7746 (4),
typescript:S1994 (3), typescript:S888 (1), typescript:S7761 (1).

Already shipped, no issue filed

Step 1 of this epic's plan is done and verified. spikersoft-angular@8e5a4048
sonar-project.properties carries the exclusions from PR spikerj/spikersoft-angular#73
(assets/x86-playground/blinkenlib.js, assets/voxel-game/**, wasm-voxel/ts/libraries/long.ts),
extended since by PRs #541 (pnpm store / deps / binary assets), #542 (spec + e2e classified as test
code) and #543 (scanner 8.1.0). It worked exactly as predicted: S3504 402→7, S7767 18→0.

Step 2 (triage the our-code remainder) is what the five issues below carry. Step 3 (close when the
gate is clean) is moot here — the gate is currently ERROR, but on new_coverage (56.8 vs 80),
new_duplicated_lines_density, new_security_hotspots_reviewed and new_violations, i.e. on the
new-code period, not on these legacy smells. Clearing all 125 would not by itself turn the gate
green; that work is tracked by the coverage waves, separately.

The five issues

Every one of the 125 open findings is assigned to exactly one of these (8+34 / 17 / 22 / 22 / 22 = 125):

  • Angular: spikerj/spikersoft-angular#705 — decision: Sonar exclusion policy for generated +
    ported sources. 42 findings (34% of the remainder) sit in the Emscripten AVIF worker
    (assets/wasm/enc/avif_enc_mt.worker.mjs, 8) and the wasm-voxel TypeScript port of the Minecraft
    Java client (wasm-voxel/ts/**, 34 — including a function scoring 101 and one scoring 92).
    The AVIF worker is the same category as blinkenlib.js, already excluded. The voxel port is a real
    judgment call, because the coverage waves wrote tests against it — so it is filed as a decision
    with four options, not as a refactor. Sibling to the backend rule-noise policy decision
    spikerj/spikersoft-backend#596 (that one is rule-scoped, this one file-scoped — deliberately not
    duplicated).
  • Angular: spikerj/spikersoft-angular#706 — art-studio: 14 S3735 void-operator + 3 S3776.
    All 14 void-operator findings in the entire frontend live in this one library.
  • Angular: spikerj/spikersoft-angular#707 — browser games (space, chess, hex-TD, dungeon-crawler,
    rpg, snake, hexatile): 20 S3776 + 2 S7740.
  • Angular: spikerj/spikersoft-angular#708 — dev-tools + platform runtimes: 18 S3776 + S7746 x2,
    S7761, S7740. Contains the strongest single refactor case left, regex-pattern-tokenizer.ts:162
    at complexity 71.
  • Angular: spikerj/spikersoft-angular#709 — app components, domain libs, wasm-voxel Angular wrapper
    and repo scripts: 17 S3776 + S2004x2, S7746x2, S3735.

Each carries the exact file:line + rule + complexity-score list for its cluster, plus the live
per-rule table and the curl command to reproduce it, so no one has to re-derive the numbers.

The unit is tracked by the shared [Sonar FE] title prefix and by sibling cross-links in each
issue. Closing here — the umbrella tracker is being emptied.

— Opus 5 Agent

Dissolved into per-repo issues as part of the umbrella-tracker breakup. This epic held implementation work that could never auto-close from a merge; it now lives where the code is. ## First, the headline: **the ~1,675 figure in this epic is dead. The real number today is 125.** Live query against `sonarqube.spikersoft.com` (project `learn.spikersoft.com`, last analysis `2026-08-07T11:49:57Z`), `impactSoftwareQualities=MAINTAINABILITY`, `impactSeverities=HIGH,BLOCKER`: | | 2026-06-19 (this epic) | 2026-08-07 (live) | |---|---|---| | BLOCKER maintainability | (inside the 1,675) | **0** | | HIGH maintainability | **1,675** | **125** | A **92.5% drop**, and BLOCKER is at zero. The epic's premise — "too many to fix at once" — no longer holds; what is left is roughly two to five focused PRs. Per-rule, current vs. what this epic recorded: | Rule | Epic (2026-06-19) | Live (2026-08-07) | |---|---|---| | `javascript:S3504` var→let/const | 402 | **7** | | `typescript:S3776` complexity | 28+ | **84** (full count; the epic only sampled 500) | | `javascript:S7767` Math.trunc | 18 | **0** | | `javascript:S3776` | 10 | **3** | | `typescript:S4123` await on non-promise | 7 | **0** | | `typescript:S3735` void operator | 7 | **14** | | `javascript:S2004` nested functions | 7 | **0** (2 remain as `typescript:S2004`) | | `typescript:S1186` empty method | 5 | **0** | | `typescript:S7059` async-in-ctor | 4 | **0** | New in the remainder since filing: `typescript:S7740` (5), `typescript:S7746` (4), `typescript:S1994` (3), `typescript:S888` (1), `typescript:S7761` (1). ## Already shipped, no issue filed **Step 1 of this epic's plan is done and verified.** `spikersoft-angular@8e5a4048` `sonar-project.properties` carries the exclusions from PR spikerj/spikersoft-angular#73 (`assets/x86-playground/blinkenlib.js`, `assets/voxel-game/**`, `wasm-voxel/ts/libraries/long.ts`), extended since by PRs #541 (pnpm store / deps / binary assets), #542 (spec + e2e classified as test code) and #543 (scanner 8.1.0). It worked exactly as predicted: `S3504` 402→7, `S7767` 18→0. Step 2 (triage the our-code remainder) is what the five issues below carry. Step 3 (close when the gate is clean) is moot here — the gate is currently ERROR, but on `new_coverage` (56.8 vs 80), `new_duplicated_lines_density`, `new_security_hotspots_reviewed` and `new_violations`, i.e. on the new-code period, **not** on these legacy smells. Clearing all 125 would not by itself turn the gate green; that work is tracked by the coverage waves, separately. ## The five issues Every one of the 125 open findings is assigned to exactly one of these (8+34 / 17 / 22 / 22 / 22 = 125): - Angular: spikerj/spikersoft-angular#705 — **decision**: Sonar exclusion policy for generated + ported sources. 42 findings (34% of the remainder) sit in the Emscripten AVIF worker (`assets/wasm/enc/avif_enc_mt.worker.mjs`, 8) and the wasm-voxel TypeScript port of the Minecraft Java client (`wasm-voxel/ts/**`, 34 — including a function scoring **101** and one scoring **92**). The AVIF worker is the same category as `blinkenlib.js`, already excluded. The voxel port is a real judgment call, because the coverage waves wrote tests against it — so it is filed as a decision with four options, not as a refactor. Sibling to the backend rule-noise policy decision spikerj/spikersoft-backend#596 (that one is rule-scoped, this one file-scoped — deliberately not duplicated). - Angular: spikerj/spikersoft-angular#706 — art-studio: 14 `S3735` void-operator + 3 `S3776`. All 14 void-operator findings in the entire frontend live in this one library. - Angular: spikerj/spikersoft-angular#707 — browser games (space, chess, hex-TD, dungeon-crawler, rpg, snake, hexatile): 20 `S3776` + 2 `S7740`. - Angular: spikerj/spikersoft-angular#708 — dev-tools + platform runtimes: 18 `S3776` + `S7746` x2, `S7761`, `S7740`. Contains the strongest single refactor case left, `regex-pattern-tokenizer.ts:162` at complexity **71**. - Angular: spikerj/spikersoft-angular#709 — app components, domain libs, wasm-voxel Angular wrapper and repo scripts: 17 `S3776` + `S2004`x2, `S7746`x2, `S3735`. Each carries the exact `file:line` + rule + complexity-score list for its cluster, plus the live per-rule table and the curl command to reproduce it, so no one has to re-derive the numbers. The unit is tracked by the shared `[Sonar FE]` title prefix and by sibling cross-links in each issue. Closing here — the umbrella tracker is being emptied. — Opus 5 Agent
Sign in to join this conversation.