Skip to content

[AAASM-3347] ♻️ (python-sdk): Reduce SonarCloud code smells under 20#144

Merged
Chisanan232 merged 9 commits into
masterfrom
v0.0.1/AAASM-3347/reduce_sonar_smells
Jun 18, 2026
Merged

[AAASM-3347] ♻️ (python-sdk): Reduce SonarCloud code smells under 20#144
Chisanan232 merged 9 commits into
masterfrom
v0.0.1/AAASM-3347/reduce_sonar_smells

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

Description

Reduces SonarCloud code smells for the AI-agent-assembly_python-sdk project from 22 to a projected 3 (target was < 20). All fixes are behaviour-preserving; the full test suite (572 passed) and mypy agent_assembly remain green.

Per-rule fixes:

  • S5799 (implicitly concatenated strings, x5): merged adjacent f-string literals in cli/adapter_validator.py (3) and adapters/mcp/patch.py (2).
  • S112 (generic exception class, x7): narrowed the -> Exception return annotation on the _build_*_error helpers to the concrete MCPToolBlockedError / PolicyViolationError they return — mcp (1), pydantic_ai (4 call sites via 2 builders), google_adk (2 call sites via 2 builders).
  • S1172 (unused parameter, x2): removed the unused node_name parameter from _wrap_tool_node_subgraphs and _make_subgraph_spawn_wrapper in adapters/langgraph/patch.py and updated all call sites + tests.
  • S108 (empty block, x1): removed the dead if TYPE_CHECKING: pass block (and unused import) in cli/adapter_validator.py.
  • S7504 (unnecessary list(), x1 of 2): dropped the redundant list() around tools_by_name.items() (the loop mutates tool.func, not the dict).
  • S3776 (cognitive complexity 18 > 15, x2): collapsed the per-status if chains in both _normalize_decision functions (crewai, langchain) into a single status-set lookup helper.

Not fixed (flagged for operator review):

  • S7503 x3 (client/gateway.py lines 99/133/196): register_agent, check_policy_compliance, dispatch_tool are async but use no await. Removing async is a breaking public-API change (every caller and test does await client.<method>()). Left as-is — recommend Won't Fix or a separate, deliberate API change.
  • S7504 x1 (langgraph/patch.py line 390): list(items_method()) is a false positive — the loop mutates node_map[node_name] during iteration, so the defensive copy is required. Recommend Won't Fix.

Two preparatory commits unblock the pre-commit mypy hook, which was red on master for reasons unrelated to this change (CI does not run mypy as a merge gate): enabling the pydantic mypy plugin (fixes spurious model call-arg errors) and making test_runtime.py monkeypatch targets mypy-clean. No --no-verify / no hook bypass was used.

Type of Change

  • ♻️ Refactoring

Breaking Changes

  • No

Related Issues

  • Related JIRA ticket: AAASM-3347 (Epic AAASM-3345)

Testing

  • Unit tests added/updated (langgraph signature change; runtime monkeypatch targets)
  • Integration tests added/updated
  • Manual testing performed (pytest test/ → 572 passed, 13 env-skipped; mypy → clean; pre-commit hooks green)
  • No tests required (explain why)

Checklist

  • Code follows project style guidelines
  • Self-review completed
  • Comments added for complex logic
  • Documentation updated if needed
  • All tests passing

🤖 Generated with Claude Code

The pre-commit mypy hook was red on master: pydantic models with
Field(default=...) defaults reported spurious 'Missing named argument'
call-arg errors because the pydantic mypy plugin was not enabled. Enable
it so defaulted fields are correctly treated as optional at construction.

refs AAASM-3347
The pre-commit mypy hook flagged runtime.socket / runtime.subprocess as
non-exported attributes and a Popen-vs-str comparison-overlap. Patch via
string targets (mypy does not check string monkeypatch paths) and widen
the handle annotation to object. No behaviour change; tests still pass.

refs AAASM-3347
SonarCloud S5799 flagged two adjacent f-string literals in the blocked
message; merge each into one. S112 flagged the generic Exception return
of _build_blocked_error; narrow it to MCPToolBlockedError. No behaviour
change.

refs AAASM-3347
SonarCloud S5799 flagged three adjacent f-string literals in adapter
validation messages; merge each into one. S108 flagged the empty
`if TYPE_CHECKING: pass` block (no longer guarding any import); remove it
and the now-unused TYPE_CHECKING import. No behaviour change.

refs AAASM-3347
SonarCloud S112 flagged four `raise` sites whose builders returned the
generic Exception type. Narrow _build_denied_error /
_build_pending_rejected_error return annotations to PolicyViolationError
(added under TYPE_CHECKING). No behaviour change.

refs AAASM-3347
SonarCloud S112 flagged two `raise` sites whose builders returned the
generic Exception type. Narrow _build_denied_error /
_build_pending_rejected_error return annotations to PolicyViolationError
(added under TYPE_CHECKING). No behaviour change.

refs AAASM-3347
…2/S7504)

SonarCloud S1172 flagged the unused node_name parameter on
_wrap_tool_node_subgraphs and _make_subgraph_spawn_wrapper; remove it and
update all call sites (incl. tests). S7504 flagged the unnecessary list()
around tools_by_name.items() — the loop mutates tool.func, not the dict,
so iterate directly. No behaviour change.

refs AAASM-3347
SonarCloud S3776 flagged _normalize_decision at complexity 18 (limit 15).
Collapse the three per-status if-chains in both the str and Mapping
branches into a single _coerce_known_status lookup against a status set.
Behaviour is identical; unknown verdicts still fail closed under enforce.

refs AAASM-3347
SonarCloud S3776 flagged _normalize_decision at complexity 18 (limit 15).
Collapse the three per-status if-chains in both the str and Mapping
branches into a single _coerce_known_status lookup against a status set.
Behaviour is identical; unknown verdicts still fail closed under enforce.

refs AAASM-3347
@codecov

codecov Bot commented Jun 18, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
5.9% Duplication on New Code (required ≤ 3%)

See analysis details on SonarQube Cloud

@Chisanan232

Copy link
Copy Markdown
Contributor Author

🤖 Claude Code — PR Review

Disclosure: Authored by a sub-agent I orchestrated under the AAASM-3347 fan-out (Epic AAASM-3345). Reviewing critically.

1. CI verdict

14 green / 6 skipped / 1 failure — SonarCloud Code Analysis, which is acceptance-class and ignorable here: the only failing gate condition is new_duplicated_lines_density (5.9% > 3%). Everything else is OK — new security rating 1, 0 new vulns, reliability 1, maintainability 1, new coverage 100%, hotspots 100%. The duplication is an artifact of the smell-fix refactors (extracted helpers / constants creating near-duplicate blocks). Per policy (SonarQube quality-gate parts are ignorable), this does not block. mergeStateStatus=BLOCKED is the review gate.

2. Scope vs AAASM-3347 — met

Metric Before → After
Code smells 22 → 3 (target <20)

19 fixed across 6 rules (S5799 string-concat, S112 exception-narrowing, S1172 unused-params, S108 empty-block, S7504 redundant-list, S3776 complexity) — behaviour-preserving.

3. Quality observations

  • The 3 residuals are correctly flagged for operator Won't-Fix, not auto-marked: S7503 ×3 (gateway.py register_agent/check_policy_compliance/dispatch_tool are async with no await — removing async is a breaking public-API change; every caller awaits) and S7504 ×1 (langgraph/patch.py:390 — genuine FP, the list() copy is required because the loop mutates the dict during iteration). Sound judgment.
  • One scope note I scrutinized — the 2 "prep" commits: the repo's pre-commit gate runs mypy, and master's baseline was already mypy-red (8 pre-existing errors in test/), so the agent could not land through the required gate without either skipping hooks (forbidden) or fixing the baseline. It chose the latter: enable the pydantic mypy plugin (mypy.ini) + make test_runtime.py monkeypatch targets mypy-clean — both zero-behaviour-change, clearly scoped, and they unblock the gate honestly. Acceptable, and the right call vs --no-verify.
  • Validation: pytest 572 passed, mypy clean (135 files), ruff no new findings.

4. Verdict

🟢 APPROVED. Smells 22→3 (target met), residuals are legitimate FP/breaking-to-fix, the prep commits are a justified gate-unblock (not --no-verify). The SonarCloud red is acceptance-class (new-code duplication only). Safe to merge; I'll action the 3 Won't-Fix marks on your go-ahead.


Generated by Claude Code (Opus 4.8, 1M ctx) · scope: CI triage (gate=duplication, acceptance) + AAASM-3347 verification + prep-commit scrutiny + FP-justification review

@Chisanan232 Chisanan232 merged commit 1cd44f6 into master Jun 18, 2026
20 of 21 checks passed
@Chisanan232 Chisanan232 deleted the v0.0.1/AAASM-3347/reduce_sonar_smells branch June 18, 2026 07:09
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