Targeted Cleanup Scoping — sync.py and walker.py
Line-level scoping of the two highest-signal cleanup targets surfaced by the 2026-08-12 SonarCloud snapshot (see Code Quality index for the full picture). Effort figures are SonarCloud's own remediation estimates; the risk and sequencing judgement is ours.
The two files tell opposite stories: walker.py is a fully safe mechanical sweep that
can land today; sync.py mixes cheap safe wins with two genuine refactors that must
ride a degod wave.
src/specify_cli/calibration/walker.py — safe, immediate (~2h)
533 LOC, 14 smells, all S1192 (duplicated string literals), ~1h50m Sonar effort.
Zero structural risk: the findings are all inside the module-level _REQUIRED_SCOPE
lookup table — a static dict[tuple[str, str], frozenset[str]] mapping
(mission_type, action_urn) to the doctrine URNs the step directly requires.
What the findings are
The table hand-lists doctrine URNs, and many are raw duplicated strings:
- action-URN prefixes —
"action:software-dev/..."(L113, L134, L164) - directive URNs —
"directive:DIRECTIVE_024"/025/028/029/030/034(L129, L136-140) - tactic URNs —
"tactic:acceptance-test-first","tactic:quality-gate-verification","tactic:stopping-conditions"(L141, L144, L145) - agent-profile URNs —
"agent_profile:r...","agent_profile:c..."(L300, L308)
Why it is safe
The module already has a partial named-constant set (DIRECTIVE_003,
DIRECTIVE_010, TACTIC_ADR_DRAFTING_WORKFLOW, TACTIC_REQUIREMENTS_VALIDATION_WORKFLOW,
TACTIC_PREMORTEM_RISK_IDENTIFICATION, ...). The fix simply completes that set: the
inconsistency — some URNs named, most inlined — is itself the smell.
Scope of work
- Define the missing URN constants next to the existing ones (directives 024/025/028/ 029/030/034/037, the tactic URNs, the agent-profile URNs).
- Replace the raw duplicated string occurrences in
_REQUIRED_SCOPEwith the constants. - No logic change — the frozensets resolve to identical values; existing calibration tests are the regression guard.
Risk: minimal. Behavior-preserving, single-file, covered by the existing calibration suite. Good first pickup / campsite PR. Clears all 14 smells.
src/specify_cli/cli/commands/sync.py — split the safe wins from the refactor
6,261 LOC — a god-module of spec-kitty sync subcommands. 26 smells, ~4h
Sonar effort. This file is the worst single source file in the project and sits in the
Wave 4 sync-adapter cluster of the degod roadmap.
Do not treat it as one cosmetic pass — separate the mechanical wins from the two
complexity monsters.
Tier 1 — mechanical wins, safe now (~1h, 15 findings)
Behavior-preserving; drops the file 26 -> 11 smells.
| Rule | Count | Lines | Fix |
|---|---|---|---|
| S7632 | 6 | 1019, 1806, 2002, 2058, 3657, 3869 | Fix malformed issue-suppression comment syntax |
| S3358 | 5 | 189, 2158, 2165, 4693, 5960 | Extract nested ternary into a statement |
| S1192 | 3 | 108, 561, 2146 | Hoist "bold yellow", ":memory:", "[dim]Unavailable" to constants |
| S5713 | 1 | 2590 | Remove redundant Exception subclass |
Note the 6 S7632 findings are malformed suppression comments — worth fixing on sight,
and a reminder that the file already leans on suppressions (see Tier 2).
Tier 2 — cognitive complexity, ride Wave 4 (~3h, 10x S3776)
The real debt. Two functions dominate and already carry # noqa: C901 — explicit
complexity suppressions that the campsite/charter policy says to retire, not add to:
| Function | Line | Cognitive complexity | Sonar effort | Notes |
|---|---|---|---|---|
status() |
5299 | 90 | 1h20m | # noqa: C901; build-and-emit table + --check coherence gate |
doctor() |
5925 | 73 | 1h3m | # noqa: C901; diagnostic build-and-emit + gate |
routes() |
2126 | 27 | 17m | |
purge() |
4424 | 26 | 16m | |
_enforce_sync_now_exit_from_dispatch() |
304 | 22 | 12m | |
status()-adjacent |
3737 | 19 | 9m | |
| (subcommand) | 5109 | 19 | 9m | |
share() |
2232 | 18 | 8m | |
| (subcommand) | 5840 | 17 | 7m | |
| (subcommand) | 4348 | 16 | 6m |
status() and doctor() are the classic decomposition shape: a long sequence of
conditional table.add_row(...) blocks (build), a --check/coherence gate (validate),
and rendering (emit). The natural split is _build_*_rows() / _run_coherence_gate() /
_render(...) pure helpers, each independently testable — which also satisfies the
Sonar rule "prefer testable extractions."
Why this is not a cosmetic pass. sync.py is a 6.3k-line CLI surface. Extracting
helpers under it without a golden CLI-characterization test first risks silent
behavior drift, which the degod roadmap calls out as a non-negotiable invariant
("golden-CLI-characterization test first on every command degod"). This work belongs in
the Wave 4 sync-adapter degod slice, where that harness is built, and where the
# noqa: C901 suppressions come off as the functions drop under complexity 15.
Effort summary
| Target | Findings | Safe now | Deferred to a wave |
|---|---|---|---|
walker.py |
14 | ~2h (all) | — |
sync.py Tier 1 |
15 | ~1h | — |
sync.py Tier 2 |
10 | — | ~3h (Wave 4, with characterization tests) |
Immediate safe cleanup: ~3h clears 29 findings (walker.py + sync.py Tier 1).
The 10 sync.py complexity findings ride Wave 4. (A prior 11th target,
sync_workspace(), was resolved by deletion — issue #424 / PR #500, "Delete dead
GitVCS/VCSProtocol.sync_workspace" — and dropped from this inventory so future
cleanup planning does not chase a non-existent function.) The 3 S2083 BLOCKER
vulnerabilities in merge/bookkeeping_projection.py and skills/verifier.py are a
separate ~90-min targeted fix (not on a wave) and should land before the final 3.2.6 tag.