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/
nextmerge), 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 |
Recommended sequence
calibration/walker.pydup-literal cleanup — fully safe, ~2h, immediate campsite PR. Clears 14 smells and improves URN-constant consistency. See targeted cleanup scoping.cli/commands/sync.pycheap wins — the 15 mechanical findings (~1h, behavior-preserving), dropping the file 26 -> 11 smells.- The 3 S2083 BLOCKERs — targeted ~90-min fix; not on a degod wave, so schedule before the final 3.2.6 tag.
sync.pycomplexity 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.