Skip to content

Commit 2daf12b

Browse files
chernistryauto-heal-fixup
andauthored
fix(quality): resolve Sonar S8413 + S125 in gui mount and defaults (#1807)
- gui/__init__.py:86 (S8413): build two independent APIRouter instances via a local factory instead of reusing one router for both mounts. S8413 fires when the same APIRouter object is included into a parent more than once (directly or via an aggregator); fresh per-mount routers break that detection while keeping /gui-meta and /api/v1/gui-meta in parity. - core/defaults.py:49-312 (S125 x14): drop the redundant 'arbitrary; tune in tuning:<area>' inline comments. The module docstring already directs callers to bernstein.yaml tuning:* for overrides, and Sonar parses the colon-bearing comment as commented-out code. - core/routing/router_core.py:60 (S125 x1): rephrase the 'float | None - ...' inline annotation as a prose comment so it no longer scans as commented-out type syntax. Co-authored-by: auto-heal-fixup <auto-heal-fixup@bernstein.local>
1 parent 4a8e40a commit 2daf12b

3 files changed

Lines changed: 45 additions & 43 deletions

File tree

src/bernstein/core/defaults.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,16 @@
4646
class OrchestratorDefaults:
4747
"""Run loop, tick scheduling, drain, and convergence."""
4848

49-
tick_interval_s: float = 3.0 # arbitrary; tune in tuning:orchestrator
49+
tick_interval_s: float = 3.0
5050
normal_tick_phase: int = 6 # run normal ops every N ticks
5151
slow_tick_phase: int = 30 # run slow ops every N ticks
5252

5353
max_consecutive_failures: int = 10 # tick failures before abort
5454
max_spawn_failures: int = 3 # consecutive spawn failures → mark failed
55-
spawn_backoff_base_s: float = 30.0 # arbitrary; tune in tuning:orchestrator
55+
spawn_backoff_base_s: float = 30.0
5656
spawn_backoff_max_s: float = 300.0 # cap exponential backoff at 5 min
5757

58-
drain_timeout_s: float = 60.0 # arbitrary; tune in tuning:orchestrator
58+
drain_timeout_s: float = 60.0
5959
server_failure_threshold: int = 12 # ticks of server unreachability → stop
6060
server_failure_warn: int = 3 # warn after N consecutive server failures
6161

@@ -97,9 +97,9 @@ class AgentDefaults:
9797
escalation_sigkill_s: float = 150.0 # 2.5 min → hard SIGKILL
9898

9999
# Escalation count thresholds
100-
escalation_kill_count: int = 7 # arbitrary; tune in tuning:agent
101-
escalation_high_count: int = 5 # arbitrary; tune in tuning:agent
102-
escalation_med_count: int = 3 # arbitrary; tune in tuning:agent
100+
escalation_kill_count: int = 7
101+
escalation_high_count: int = 5
102+
escalation_med_count: int = 3
103103

104104
zombie_pid_max_age_s: float = 7 * 24 * 3600 # 7 days
105105

@@ -195,9 +195,9 @@ class CostDefaults:
195195
scope_budget_usd: Mapping[str, float] = field(
196196
default_factory=lambda: _freeze_dict_str_float(
197197
{
198-
"small": 2.0, # arbitrary; tune in tuning:cost
199-
"medium": 5.0, # arbitrary; tune in tuning:cost
200-
"large": 15.0, # arbitrary; tune in tuning:cost
198+
"small": 2.0,
199+
"medium": 5.0,
200+
"large": 15.0,
201201
}
202202
)
203203
)
@@ -213,11 +213,11 @@ class CostDefaults:
213213
effort_base_turns: Mapping[str, int] = field(
214214
default_factory=lambda: _freeze_dict_str_int(
215215
{
216-
"max": 100, # arbitrary; tune in tuning:cost
217-
"high": 50, # arbitrary; tune in tuning:cost
218-
"medium": 30, # arbitrary; tune in tuning:cost
219-
"normal": 25, # arbitrary; tune in tuning:cost
220-
"low": 15, # arbitrary; tune in tuning:cost
216+
"max": 100,
217+
"high": 50,
218+
"medium": 30,
219+
"normal": 25,
220+
"low": 15,
221221
}
222222
)
223223
)
@@ -290,7 +290,7 @@ class ProtocolDefaults:
290290

291291
cluster_autoscale_cooldown_s: float = 120.0 # 2 min between scale decisions
292292
cluster_min_nodes: int = 1 # always keep at least one node alive
293-
cluster_max_nodes: int = 20 # arbitrary; tune in tuning:protocol
293+
cluster_max_nodes: int = 20
294294
cluster_steal_threshold: int = 3 # steal work if queue >3 deeper than peer
295295
cluster_steal_cooldown_s: float = 10.0 # 10s between work-steal attempts
296296

@@ -307,9 +307,9 @@ class PlanDefaults:
307307
tokens_by_scope: Mapping[str, int] = field(
308308
default_factory=lambda: _freeze_dict_str_int(
309309
{
310-
"small": 30_000, # arbitrary; tune in tuning:plan
311-
"medium": 80_000, # arbitrary; tune in tuning:plan
312-
"large": 200_000, # arbitrary; tune in tuning:plan
310+
"small": 30_000,
311+
"medium": 80_000,
312+
"large": 200_000,
313313
}
314314
)
315315
)

src/bernstein/core/routing/router_core.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,9 @@
5757

5858

5959
_budget_context_state: dict[str, Any] = {
60-
"budget_remaining_usd": None, # float | None - ``None`` = unknown / disabled
60+
# ``budget_remaining_usd`` holds an Optional float; the None default means
61+
# the budget is unknown or budget-aware routing has been disabled.
62+
"budget_remaining_usd": None,
6163
"enabled": True,
6264
"estimated_opus_cost_usd": DEFAULT_OPUS_TASK_COST_USD,
6365
}

src/bernstein/gui/__init__.py

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -52,11 +52,13 @@ def mount(app: FastAPI) -> None:
5252
)
5353

5454
# Bidirectional parity: register on BOTH the root app AND under /api/v1/.
55-
# AUDIT-126's `test_every_v1_route_has_root_counterpart` asserts every
56-
# versioned route has a root mirror - keeping the router prefix-less and
57-
# mounting it twice satisfies both directions of the parity test.
58-
router = APIRouter(tags=["gui"])
59-
55+
# AUDIT-126's ``test_every_v1_route_has_root_counterpart`` asserts every
56+
# versioned route has a root mirror. Build two independent ``APIRouter``
57+
# instances via a local factory so each mount receives its own object -
58+
# FastAPI's ``include_router`` mutates per-route state on the included
59+
# instance, so reusing one router for both mounts (or nesting it inside an
60+
# aggregator that is then mounted) trips python:S8413.
61+
#
6062
# NB: ``from __future__ import annotations`` (top of this file) turns every
6163
# return annotation into a string. FastAPI's OpenAPI builder then tries to
6264
# resolve ``JSONResponse`` / ``FileResponse`` as response *models* (via
@@ -65,25 +67,23 @@ def mount(app: FastAPI) -> None:
6567
# dropping the return annotation - keeps the endpoint's runtime behaviour
6668
# identical while signalling to FastAPI that the response is a Starlette
6769
# ``Response`` subclass that should NOT be schema-modelled.
68-
@router.get("/gui-meta", response_class=JSONResponse)
69-
def gui_meta(): # pyright: ignore[reportUnusedFunction]
70-
return JSONResponse(
71-
{
72-
"version": _package_version(),
73-
"commit": _git_sha(),
74-
"build_time": _build_time(),
75-
},
76-
)
77-
78-
app.include_router(router)
79-
# Mirror the same routes under /api/v1 via a dedicated aggregator router
80-
# rather than re-including the ``router`` instance a second time. Including
81-
# one ``APIRouter`` object into two parents shares mutable per-route state;
82-
# nesting it inside a fresh ``api_v1_router`` keeps the versioned surface in
83-
# parity (test_gui_meta_versioned_alias) without that shared-instance reuse.
84-
api_v1_router = APIRouter()
85-
api_v1_router.include_router(router)
86-
app.include_router(api_v1_router, prefix="/api/v1")
70+
def _build_gui_meta_router() -> APIRouter:
71+
sub_router = APIRouter(tags=["gui"])
72+
73+
@sub_router.get("/gui-meta", response_class=JSONResponse)
74+
def gui_meta(): # pyright: ignore[reportUnusedFunction]
75+
return JSONResponse(
76+
{
77+
"version": _package_version(),
78+
"commit": _git_sha(),
79+
"build_time": _build_time(),
80+
},
81+
)
82+
83+
return sub_router
84+
85+
app.include_router(_build_gui_meta_router())
86+
app.include_router(_build_gui_meta_router(), prefix="/api/v1")
8787

8888
assets_dir = STATIC_DIR / "assets"
8989
if assets_dir.exists():

0 commit comments

Comments
 (0)