Code Quality — Working Collection

The standing code-quality surface for Spec Kitty: what the SonarCloud analysis of main actually says, how the metrics have moved, where the debt clusters, and how that debt lines up with work the roadmap has already scoped. This is a distil-then-retire working collection (see Plans) — the durable "why" lives in the degod/unshim roadmap and the 3.2.x milestone roadmap; this collection holds the measurement and the targeted cleanup scoping.

Analysis source: SonarCloud project Priivacy-ai_spec-kitty, branch main, snapshot of the 2026-08-12 CI Quality run on f6b90d34e. Sonar runs only on workflow_dispatch/schedule (nightly); PRs and normal main pushes skip it, so the gate reflects the accumulated project-wide backlog rather than any single change.

Snapshot (main, 2026-08-12)

Domain Metric Value Rating
Coverage line coverage 84.1% A
Duplication duplicated lines 0.5% (48 blocks) A
Complexity cyclomatic / cognitive 34,535 / 36,285
Reliability bugs 0 A
Maintainability code smells / SQALE debt 1,807 / 12,959 min A
Security vulnerabilities 21 E
Security review hotspots to review 2 E

Size: 205,734 ncloc across 1,158 files.

Quality-metric evolution

Per-analysis history on main. The July trough and August recovery are the story: the large next/ + execution-lanes merge landed under-tested, then the test-sanitation work pulled coverage back to a project high.

date          ncloc   cov%   dup%   cognitive  smells  vulns  bugs
2026-05-03   118105   53.7   1.3     21938      664      0     0
2026-06-07   164071   64.6   1.2     30599      846      0     0
2026-07-07   192086   47.3   0.7     32798      879     17     1   <- vulns appear (lanes/next merge)
2026-07-19   201184   48.2   0.6     33446     1116     20    29   <- bug spike
2026-07-26   212904   48.2   0.6     34824     1225     23    32
2026-08-02   204754   69.9   0.5     36247     1865     21    33
2026-08-06   204161   73.8   0.5     36508     1903     21    34
2026-08-11   204992   83.7   0.5     36470     1935     21     0   <- bugs cleared
2026-08-12   205734   84.1   0.5     36285     1807     21     0   <- current

Reading the trends:

  • Coverage — strongly positive. Recovered from a July trough of ~47% to a project-high 84.1%. The +10pt step on 08-11 → 08-12 is the recent test-backfill work landing.
  • Duplication — excellent and improving. 1.3% → 0.5%, monotonic, well under the 3% ceiling.
  • Complexity — grows with size, density flat. Cognitive complexity nearly doubled while ncloc nearly doubled; per-kloc density actually ticked down (0.186 → 0.176). Growth is proportional, not degrading.
  • Bugs — a clean win. A mid-July reliability spike (0 → 34) was fully burned down to 0 by 08-11. Reliability is A.
  • Code smells — the one watch item. 664 → 1,807 (~3x) while code grew ~1.75x, so smell density rose. Still A-rated, but debt is accreting slightly faster than the codebase. See the taxonomy below — roughly half is test-idiom nits.
  • Vulnerabilities — flat, unresolved backlog. Appeared as a block of 17 on 2026-07-07 (the subprocess-heavy lanes/next merge), peaked at 23, sits at 21. This is the sole thing keeping security at E and failing the dispatch gate.

The quality gate

The workflow_dispatch CI Quality run fails on exactly one condition:

Condition Actual Required
new_security_rating C (3) A (1) FAIL
new_coverage 90.4% >=80% pass
new_reliability_rating A A pass
new_maintainability_rating A A pass
new_duplicated_lines_density 0.1% <=3% pass
new_security_hotspots_reviewed 100% 100% pass

Per ADR 2026-07-17-1, this is an honest standing red, not a release regression: all 21 vulnerabilities predate any current release candidate (created 2026-06-24 → 2026-07-30), and the 2026-08-12 head commit contributed none of them.

Cluster taxonomy

The headline "1,807 smells" splits cleanly into low-value test-idiom nits and real source debt. About half the backlog is pytest-style rules in test files.

Cluster A — test-idiom modernization (~940 smells, ~52%, test files)

Mechanical, low real-risk, bulk-fixable; ideal for a single sweep. Not release-relevant.

Rule Count Meaning
S9073 342 Composite assertions should be split
S9083 252 Pytest fixture/mark decorator parentheses style
S5778 245 Only one call expected inside pytest.raises
S8714 61 Use dedicated exception assertions vs try/except + fail()
S8997 42 Use the monkeypatch fixture

Cluster B — cognitive complexity (S3776, 339, all in src)

The real maintainability cluster and the target of the complexity-ceiling-15 policy. Concentrated in the CLI command layer and doctrine:

11  cli/commands/sync.py
10  cli/commands/agent/mission_finalize.py
 7  cli/commands/glossary.py
 6  doctrine/pack_validator.py
 5  cli/commands/migrate_cmd.py · agent/config.py · doctrine/pack_assembler.py
 5  migration/backfill_runtime_state.py · status/reducer.py

Cluster C — duplicated string literals (S1192, 117, all in src)

The "hoist to a constant at >=3x" cluster. One clear standout:

14  calibration/walker.py
 5  cli/commands/decision.py · doctrine/drg/migration/hand_authored_overlay.py
 4  cli/commands/migrate_cmd.py

Location hotspot

cli/commands/ is the worst neighborhood in src — 128 smells in the directory plus 53 in agent/ (~181). The worst single file across all rules is cli/commands/sync.py (26). After that the tail is thin.

How the debt maps onto the roadmap

The reds are not surprise debt — they map almost 1:1 onto named, sequenced-but-not-yet -executed degod/unshim waves and the subsystems the 3.x execution model built out. The vulnerabilities all appeared on 2026-07-07, exactly when the lanes/next execution-model merge landed.

Sonar cluster Files Cleanup owner Wave status
S6350 subprocess vulns (17, -> security E) lanes/_git, lanes/recovery, worktree_allocator, coordination/surface_resolver, core/git_ops, merge/push_preflight, git/ref_advance Wave 2 (coord-authority) + Wave 4 (sync adapters) QUEUED
S3776 complexity (339) cli/commands/sync.py, agent/mission_finalize, glossary, migrate_cmd sync.py -> Wave 4; coord trio -> Wave 2 QUEUED
S2083 path-traversal (3, BLOCKER) merge/bookkeeping_projection x2, skills/verifier targeted fix (not on a wave) open
S1192 dup literals (117) calibration/walker (14), decision, migrate_cmd campsite ongoing
  1. calibration/walker.py dup-literal cleanup — fully safe, ~2h, immediate campsite PR. Clears 14 smells and improves URN-constant consistency. See targeted cleanup scoping.
  2. cli/commands/sync.py cheap wins — the 15 mechanical findings (~1h, behavior-preserving), dropping the file 26 -> 11 smells.
  3. The 3 S2083 BLOCKERs — targeted ~90-min fix; not on a degod wave, so schedule before the final 3.2.6 tag.
  4. sync.py complexity monsters (status() CC 90, doctor() CC 73) and the S6350 subprocess-hardening — ride the Wave 2 / Wave 4 degod slices with golden-CLI-characterization tests first, per the degod invariant. Not a cosmetic Sonar pass.

Full per-finding detail and effort estimates: Targeted Cleanup Scoping.