Skip to content

[codex] Fix finalization deadlock and surface stuck-head context - #1666

Open
MuncleUscles wants to merge 10 commits into
v0.121from
codex/studio-alert-health-context-v121
Open

[codex] Fix finalization deadlock and surface stuck-head context#1666
MuncleUscles wants to merge 10 commits into
v0.121from
codex/studio-alert-health-context-v121

Conversation

@MuncleUscles

@MuncleUscles MuncleUscles commented Jun 8, 2026

Copy link
Copy Markdown
Member

Summary

  • Fix a per-contract scheduling deadlock where an older PENDING/ACTIVATED head could defer to a younger eligible finalization that claim_next_finalization could not legally claim yet.
  • Align /health/consensus orphaned-transaction reporting with the main /health stuck-head detector.
  • Add bounded stuck-head transaction details to the cached consensus health payload.
  • Add bounded stuck-finalization transaction details to the cached consensus health payload.
  • Forward health event details as instanceHealthEvents so alerts can include affected transaction and contract context.
  • Add regression coverage for the claim deadlock, detailed health endpoint, usage metrics event payload, and stuck-finalization detail payload.

Root Cause

claim_next_transaction deferred any PENDING/ACTIVATED candidate when an eligible finalization existed on the same contract. claim_next_finalization, correctly, refuses to claim a finalization while an older non-terminal tx exists for that contract. If the finalization was younger than the candidate, both claim paths could reject work: transaction claiming deferred to finalization, and finalization was blocked by the older candidate. The fix makes transaction claiming defer only to older eligible finalizations.

The latest stuck_finalizations alert exposed a separate observability gap: health only returned stuck_finalization_count, so Slack could not name the rows. This PR now includes a bounded stuck_finalization_transactions sample with tx hash, contract, status, age, blocked_at, and worker_id.

Validation

  • ./.venv/bin/python -m py_compile backend/consensus/worker.py backend/protocol_rpc/health.py backend/services/usage_metrics_service.py tests/db-sqlalchemy/test_finalization_starvation.py tests/db-sqlalchemy/test_health_orphan_detection.py tests/unit/test_usage_metrics_service.py
  • ./.venv/bin/python -m pytest tests/unit/test_usage_metrics_service.py -q - 2 passed
  • ./.venv/bin/python -m pytest tests/db-sqlalchemy/test_finalization_starvation.py -q - 11 passed
  • ./.venv/bin/python -m pytest tests/db-sqlalchemy/test_health_orphan_detection.py -q - 23 passed
  • /Users/edgars/Dev/genlayer-studio/.venv/bin/python -m py_compile backend/protocol_rpc/health.py tests/db-sqlalchemy/test_health_orphan_detection.py
  • /Users/edgars/Dev/genlayer-studio/.venv/bin/python -m black --check backend/protocol_rpc/health.py tests/db-sqlalchemy/test_health_orphan_detection.py
  • /Users/edgars/Dev/genlayer-studio/.venv/bin/python -m pytest tests/db-sqlalchemy/test_health_orphan_detection.py -k stuck_finalization - blocked locally because POSTGRES_URL is not set in this environment

Summary by CodeRabbit

  • New Features

    • Health endpoints now include detailed stuck-head transaction info (hash, status, timestamps) for better observability.
  • Bug Fixes

    • Improved stuck-head detection to respect worker claims and avoid false positives.
    • Consensus health status logic refined to more accurately signal degraded vs healthy.
  • Behavioral

    • Metrics now report orphaned/stuck-head events in system health exports.
  • Tests

    • Added comprehensive tests for consensus health, stuck-head/finalization detection, and metrics reporting.
  • Chores

    • CI/CD workflows updated to require/explicitly forward release/build secrets; coverage upload no longer fails CI on upload errors.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 0bfd6209-a132-4f2c-be0e-168f4668e059

📥 Commits

Reviewing files that changed from the base of the PR and between b4468d5 and 4349f24.

📒 Files selected for processing (1)
  • tests/db-sqlalchemy/test_health_orphan_detection.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • tests/db-sqlalchemy/test_health_orphan_detection.py

📝 Walkthrough

Walkthrough

Adds explicit DockerHub/release secret declarations and action pinning in workflows; implements CTE-based stuck-head detection with per-transaction details in consensus health, surfaces those rows in cached health payloads, integrates orphaned/stuck events into usage metrics, adjusts health degradation logic, and expands DB/unit tests including finalization-starvation coverage.

Changes

CI/Workflow Security Hardening

Layer / File(s) Summary
Docker/release workflow secret declarations and wiring
.github/workflows/docker-build-and-push-all.yml, .github/workflows/manual-docker-release.yml, .github/workflows/release-from-tag.yml
DOCKERHUB_TOKEN and RELEASE_LANE_APP_KEY are explicitly declared/passed in reusable workflow interfaces; manual release no longer uses secrets: inherit and forwards only the two secrets.
Codecov error handling and buildx action pinning
.github/workflows/frontend-unit-tests.yml, .github/workflows/release-from-tag.yml
Codecov upload errors no longer fail CI (fail_ci_if_error: false), and docker/setup-buildx-action is pinned to a specific commit SHA instead of the floating v3 tag.

Consensus Health: Stuck-Head Detection and Metrics Integration

Layer / File(s) Summary
Finalization starvation prevention documentation and test
backend/consensus/worker.py, tests/db-sqlalchemy/test_finalization_starvation.py
Inline comments clarify claim_next_transaction deferral semantics; a regression test ensures older ACTIVATED heads are not blocked by younger ACCEPTED finalizations.
Stuck-head detection SQL and background health monitoring
backend/protocol_rpc/health.py
Adds consensus-active/inflight status sets and STUCK_HEAD_EVENT_LIMIT; replaces count-only stuck-head detection with a CTE that returns limited per-transaction stuck-head rows; stuck-finalization query rewritten to return per-tx event rows; cached background services["consensus"] includes stuck_head_transactions.
Detailed health endpoint refactor and metrics integration
backend/protocol_rpc/health.py, backend/services/usage_metrics_service.py
Rewrites /health/consensus SQL to use contract_stats + stuck_heads CTEs and populate stuck_head_transaction objects with elapsed timing; overall health gating now uses total_processing < 100 and total_orphaned < DEGRADED_AT_STUCK_HEADS; UsageMetricsService.send_system_health_metrics accumulates and forwards orphaned_transactions events from stuck_head_transactions.
Health monitoring test coverage: DB and unit tests
tests/db-sqlalchemy/test_health_orphan_detection.py, tests/unit/test_rpc_health_genvm_tracking.py, tests/unit/test_usage_metrics_service.py, tests/db-sqlalchemy/test_finalization_starvation.py
Adds/extends DB tests for claim-window semantics, status exclusion, per-contract stuck-head details, and stuck-finalization payloads; unit tests add a fake consensus DB helper, cooldown/error scenario coverage, and assert metrics event mapping for stuck-heads.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

run-tests

Suggested reviewers

  • cristiam86
  • kstroobants

Poem

🐰 I hopped through workflows, secrets in paw,
Pinned the builder, kept the tokens in law.
I sniffed stuck heads, recorded each hash,
Metrics now chatter when queues take a crash.
Hooray — tests pass, the rabbit did the dash!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the two main changes: fixing a finalization deadlock and surfacing stuck-head context in health reporting.
Description check ✅ Passed The description covers all required sections: What (changes made), Why (rationale), Testing done (validation steps), and key decisions. All important context is provided.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/studio-alert-health-context-v121

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@MuncleUscles MuncleUscles changed the title [codex] Surface stuck-head alert context [codex] Fix finalization deadlock and surface stuck-head context Jun 8, 2026
@MuncleUscles
MuncleUscles marked this pull request as ready for review June 8, 2026 21:25

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
backend/protocol_rpc/health.py (1)

371-374: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Top-level /health orphaned gate is still hard-coded to 3.

_check_consensus_health now uses HEALTH_DEGRADED_AT_STUCK_HEADS, but _run_health_checks still applies >= 3. Custom thresholds will produce inconsistent service status/issue tags.

Suggested fix
-            if consensus_health.get("total_orphaned_transactions", 0) >= 3:
+            if consensus_status == "degraded" or consensus_health.get(
+                "total_orphaned_transactions", 0
+            ) >= int(os.environ.get("HEALTH_DEGRADED_AT_STUCK_HEADS", "3")):

Also applies to: 631-632

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/protocol_rpc/health.py` around lines 371 - 374, The top-level /health
check in _run_health_checks is using a hard-coded threshold (>= 3) for
consensus_health["total_orphaned_transactions"]; replace that literal with the
centralized constant HEALTH_DEGRADED_AT_STUCK_HEADS (the same constant used by
_check_consensus_health) so custom thresholds are honored; update both
occurrences (the block referencing
consensus_health.get("total_orphaned_transactions", 0) at the shown location and
the similar check around lines 631-632) and ensure the constant is
imported/available in this module and used for the comparison and any related
status/issue tagging.
🧹 Nitpick comments (1)
.github/workflows/frontend-unit-tests.yml (1)

35-35: 💤 Low value

Consider adding a comment explaining the non-blocking rationale.

Setting fail_ci_if_error: false improves operational resilience by preventing Codecov service outages from blocking CI. An inline comment would help future maintainers understand this trade-off.

📝 Suggested documentation
-          fail_ci_if_error: false
+          fail_ci_if_error: false  # Don't block CI on Codecov service issues
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/frontend-unit-tests.yml at line 35, Add an inline comment
next to the YAML key fail_ci_if_error: false explaining the non-blocking
rationale (e.g., to avoid blocking CI during Codecov outages and prefer passing
CI while still reporting coverage issues), so future maintainers understand the
trade-off and where to change behavior if desired; reference the
fail_ci_if_error setting and keep the comment concise and concrete about why
it's set to false.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/protocol_rpc/health.py`:
- Line 661: STUCK_HEAD_EVENT_LIMIT is currently read from env and can be set to
0 which disables the SQL LIMIT and causes stuck_head_contracts to be 0 even when
issues exist; change the logic that derives/uses event_limit so it never becomes
0 when you intend to count events—either coerce STUCK_HEAD_EVENT_LIMIT to at
least 1 (e.g., event_limit = max(1, STUCK_HEAD_EVENT_LIMIT)) or treat 0 as
meaning "no-limit" and adjust the query-building so it omits a LIMIT clause
rather than injecting LIMIT 0; update all places that use event_limit (the env
constant STUCK_HEAD_EVENT_LIMIT and the code paths that build the stuck-head
query and compute stuck_head_contracts) to follow the chosen behavior.

In `@tests/db-sqlalchemy/test_finalization_starvation.py`:
- Line 21: Update the ambiguous multiplication character in the docstring: find
the string containing "N×finality_window" (in
tests/db-sqlalchemy/test_finalization_starvation.py) and replace the Unicode
multiplication sign "×" with a plain ASCII "x" so it reads "N x finality_window"
to satisfy the linter (RUF002).

In `@tests/unit/test_rpc_health_genvm_tracking.py`:
- Around line 188-200: The helper _install_fake_consensus_db lacks type
annotations; update its signature to add types for all parameters (e.g.,
monkeypatch: pytest.MonkeyPatch or MonkeyPatch, recovery_storm_count: int = 0,
max_recovery_count: int = 0, exhausted_rows: Optional[int] = None,
backlog_count: int = 0, oldest_created_at: Optional[datetime] = None,
oldest_backlog_age_seconds: Optional[int] = None, progress_epoch: int = 1,
progress_error: bool = False) and add the return annotation -> None; also add
any needed imports (from typing import Optional and from datetime import
datetime or appropriate types) at the top of the test file so the new
annotations resolve.

In `@tests/unit/test_usage_metrics_service.py`:
- Line 56: Add the missing return type hint to the async test function by
changing the signature of async def
test_system_health_metrics_include_stuck_head_events() to include -> None (i.e.,
async def test_system_health_metrics_include_stuck_head_events() -> None:) so it
conforms to the repository typing rule for Python functions.

---

Outside diff comments:
In `@backend/protocol_rpc/health.py`:
- Around line 371-374: The top-level /health check in _run_health_checks is
using a hard-coded threshold (>= 3) for
consensus_health["total_orphaned_transactions"]; replace that literal with the
centralized constant HEALTH_DEGRADED_AT_STUCK_HEADS (the same constant used by
_check_consensus_health) so custom thresholds are honored; update both
occurrences (the block referencing
consensus_health.get("total_orphaned_transactions", 0) at the shown location and
the similar check around lines 631-632) and ensure the constant is
imported/available in this module and used for the comparison and any related
status/issue tagging.

---

Nitpick comments:
In @.github/workflows/frontend-unit-tests.yml:
- Line 35: Add an inline comment next to the YAML key fail_ci_if_error: false
explaining the non-blocking rationale (e.g., to avoid blocking CI during Codecov
outages and prefer passing CI while still reporting coverage issues), so future
maintainers understand the trade-off and where to change behavior if desired;
reference the fail_ci_if_error setting and keep the comment concise and concrete
about why it's set to false.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5ffce8bc-5dec-4982-9bbc-116d39411b6c

📥 Commits

Reviewing files that changed from the base of the PR and between a502935 and 3acf0f3.

📒 Files selected for processing (11)
  • .github/workflows/docker-build-and-push-all.yml
  • .github/workflows/frontend-unit-tests.yml
  • .github/workflows/manual-docker-release.yml
  • .github/workflows/release-from-tag.yml
  • backend/consensus/worker.py
  • backend/protocol_rpc/health.py
  • backend/services/usage_metrics_service.py
  • tests/db-sqlalchemy/test_finalization_starvation.py
  • tests/db-sqlalchemy/test_health_orphan_detection.py
  • tests/unit/test_rpc_health_genvm_tracking.py
  • tests/unit/test_usage_metrics_service.py

PRE_CONSENSUS_BACKLOG_STATUSES_SQL = (
"'PENDING','ACTIVATED','PROPOSING','COMMITTING','REVEALING'"
)
STUCK_HEAD_EVENT_LIMIT = int(os.environ.get("HEALTH_STUCK_HEAD_EVENT_LIMIT", "10"))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Guard HEALTH_STUCK_HEAD_EVENT_LIMIT from disabling stuck-head counting.

With event_limit=0, LIMIT 0 yields no rows, so stuck_head_contracts becomes 0 even when stuck heads exist. That can mask real degradation.

Suggested fix
-    STUCK_HEAD_EVENT_LIMIT = int(os.environ.get("HEALTH_STUCK_HEAD_EVENT_LIMIT", "10"))
+    STUCK_HEAD_EVENT_LIMIT = max(
+        1, int(os.environ.get("HEALTH_STUCK_HEAD_EVENT_LIMIT", "10"))
+    )

Also applies to: 705-755

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/protocol_rpc/health.py` at line 661, STUCK_HEAD_EVENT_LIMIT is
currently read from env and can be set to 0 which disables the SQL LIMIT and
causes stuck_head_contracts to be 0 even when issues exist; change the logic
that derives/uses event_limit so it never becomes 0 when you intend to count
events—either coerce STUCK_HEAD_EVENT_LIMIT to at least 1 (e.g., event_limit =
max(1, STUCK_HEAD_EVENT_LIMIT)) or treat 0 as meaning "no-limit" and adjust the
query-building so it omits a LIMIT clause rather than injecting LIMIT 0; update
all places that use event_limit (the env constant STUCK_HEAD_EVENT_LIMIT and the
code paths that build the stuck-head query and compute stuck_head_contracts) to
follow the chosen behavior.

eligible statuses (ACCEPTED/UNDETERMINED/*_TIMEOUT).
4. Safety-net log fires when an ACCEPTED tx's wait exceeds N×finality_window.
5. Recovered PENDING txs are deprioritized across contracts so other
5. Safety-net log fires when an ACCEPTED tx's wait exceeds N×finality_window.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Replace ambiguous multiplication character in the docstring.

N×finality_window triggers Ruff RUF002; use plain x to avoid lint churn.

Suggested fix
-5. Safety-net log fires when an ACCEPTED tx's wait exceeds N×finality_window.
+5. Safety-net log fires when an ACCEPTED tx's wait exceeds Nxfinality_window.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
5. Safety-net log fires when an ACCEPTED tx's wait exceeds N×finality_window.
5. Safety-net log fires when an ACCEPTED tx's wait exceeds Nxfinality_window.
🧰 Tools
🪛 Ruff (0.15.15)

[warning] 21-21: Docstring contains ambiguous × (MULTIPLICATION SIGN). Did you mean x (LATIN SMALL LETTER X)?

(RUF002)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/db-sqlalchemy/test_finalization_starvation.py` at line 21, Update the
ambiguous multiplication character in the docstring: find the string containing
"N×finality_window" (in tests/db-sqlalchemy/test_finalization_starvation.py) and
replace the Unicode multiplication sign "×" with a plain ASCII "x" so it reads
"N x finality_window" to satisfy the linter (RUF002).

Source: Linters/SAST tools

Comment on lines +188 to +200
def _install_fake_consensus_db(
self,
monkeypatch,
*,
recovery_storm_count=0,
max_recovery_count=0,
exhausted_rows=None,
backlog_count=0,
oldest_created_at=None,
oldest_backlog_age_seconds=None,
progress_epoch=1,
progress_error=False,
):

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/unit/test_rpc_health_genvm_tracking.py"

# Basic info
echo "== File =="
ls -l "$FILE"
echo

# Show the helper signature area (around provided line range)
echo "== Helper signature (lines 160-240) =="
nl -ba "$FILE" | sed -n '160,240p'

# Look for other helper signatures and typing patterns in this file
echo
echo "== Other function defs with/without type hints =="
rg -n "def _install_fake_consensus_db|def " "$FILE"

# Specifically check for type comments/annotations patterns within this file
echo
echo "== Search for '->' return annotations and ':' parameter annotations =="
rg -n "->|:\s*(pytest|int|bool|list|dict|str|float|None|Optional|\| None)" "$FILE" || true

Repository: genlayerlabs/genlayer-studio

Length of output: 280


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/unit/test_rpc_health_genvm_tracking.py"

echo "== File =="
ls -l "$FILE"
echo

echo "== Helper signature area (lines 160-240) =="
cat -n "$FILE" | sed -n '160,240p'

echo
echo "== Function defs in this file =="
rg -n "^\s*def\s" "$FILE"

echo
echo "== Return/param annotation presence =="
rg -n "->|:\s*(int|bool|str|float|dict|list|tuple|set|Optional|pytest\.MonkeyPatch|None|object|\| None)" "$FILE" || true

echo
echo "== Specific helper signature block =="
rg -n "def _install_fake_consensus_db\(" -n "$FILE" && \
  sed -n '160,240p' "$FILE"

Repository: genlayerlabs/genlayer-studio

Length of output: 8563


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/unit/test_rpc_health_genvm_tracking.py"

echo "== Search for any return annotations (->) =="
rg -n -- "->" "$FILE" || true

echo
echo "== Search for any parameter type annotations (e.g., ': int', ': bool', ': str') =="
rg -n -- ":\s*(int|bool|str|float|dict|list|tuple|set|Optional|Any|object)\b" "$FILE" || true

echo
echo "== Search for pytest.MonkeyPatch annotations usage =="
rg -n -- "pytest\.MonkeyPatch" "$FILE" || true

echo
echo "== Check for from __future__ import annotations =="
rg -n -- "from __future__ import annotations" "$FILE" || true

Repository: genlayerlabs/genlayer-studio

Length of output: 308


🏁 Script executed:

#!/bin/bash
set -euo pipefail

FILE="tests/unit/test_rpc_health_genvm_tracking.py"
echo "== File header (first 80 lines) =="
sed -n '1,80p' "$FILE"

Repository: genlayerlabs/genlayer-studio

Length of output: 3335


🏁 Script executed:

#!/bin/bash
set -euo pipefail
FILE="tests/unit/test_rpc_health_genvm_tracking.py"

echo "== Show _install_fake_consensus_db body where monkeypatch is used (lines 188-420) =="
cat -n "$FILE" | sed -n '188,420p'

echo
echo "== Count occurrences of 'monkeypatch' in this file =="
rg -n "monkeypatch" "$FILE"

Repository: genlayerlabs/genlayer-studio

Length of output: 11052


Add type hints to _install_fake_consensus_db helper signature

tests/unit/test_rpc_health_genvm_tracking.py (lines 188-200): _install_fake_consensus_db defines parameters and no return annotation; add type hints (including -> None) to match the repository typing rule.

Suggested fix
-    def _install_fake_consensus_db(
-        self,
-        monkeypatch,
+    def _install_fake_consensus_db(
+        self,
+        monkeypatch: pytest.MonkeyPatch,
         *,
-        recovery_storm_count=0,
-        max_recovery_count=0,
-        exhausted_rows=None,
-        backlog_count=0,
-        oldest_created_at=None,
-        oldest_backlog_age_seconds=None,
-        progress_epoch=1,
-        progress_error=False,
-    ):
+        recovery_storm_count: int = 0,
+        max_recovery_count: int = 0,
+        exhausted_rows: list[SimpleNamespace] | None = None,
+        backlog_count: int = 0,
+        oldest_created_at: object | None = None,
+        oldest_backlog_age_seconds: int | None = None,
+        progress_epoch: int = 1,
+        progress_error: bool = False,
+    ) -> None:
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
def _install_fake_consensus_db(
self,
monkeypatch,
*,
recovery_storm_count=0,
max_recovery_count=0,
exhausted_rows=None,
backlog_count=0,
oldest_created_at=None,
oldest_backlog_age_seconds=None,
progress_epoch=1,
progress_error=False,
):
def _install_fake_consensus_db(
self,
monkeypatch: pytest.MonkeyPatch,
*,
recovery_storm_count: int = 0,
max_recovery_count: int = 0,
exhausted_rows: list[SimpleNamespace] | None = None,
backlog_count: int = 0,
oldest_created_at: object | None = None,
oldest_backlog_age_seconds: int | None = None,
progress_epoch: int = 1,
progress_error: bool = False,
) -> None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_rpc_health_genvm_tracking.py` around lines 188 - 200, The
helper _install_fake_consensus_db lacks type annotations; update its signature
to add types for all parameters (e.g., monkeypatch: pytest.MonkeyPatch or
MonkeyPatch, recovery_storm_count: int = 0, max_recovery_count: int = 0,
exhausted_rows: Optional[int] = None, backlog_count: int = 0, oldest_created_at:
Optional[datetime] = None, oldest_backlog_age_seconds: Optional[int] = None,
progress_epoch: int = 1, progress_error: bool = False) and add the return
annotation -> None; also add any needed imports (from typing import Optional and
from datetime import datetime or appropriate types) at the top of the test file
so the new annotations resolve.

Source: Coding guidelines



@pytest.mark.asyncio
async def test_system_health_metrics_include_stuck_head_events():

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Add a return type hint to the new async test function (Line 56).

Please annotate the test as -> None to satisfy the repository typing rule for Python functions.

Suggested patch
 `@pytest.mark.asyncio`
-async def test_system_health_metrics_include_stuck_head_events():
+async def test_system_health_metrics_include_stuck_head_events() -> None:

As per coding guidelines: "**/*.py: Include type hints in all Python code".

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
async def test_system_health_metrics_include_stuck_head_events():
`@pytest.mark.asyncio`
async def test_system_health_metrics_include_stuck_head_events() -> None:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/unit/test_usage_metrics_service.py` at line 56, Add the missing return
type hint to the async test function by changing the signature of async def
test_system_health_metrics_include_stuck_head_events() to include -> None (i.e.,
async def test_system_health_metrics_include_stuck_head_events() -> None:) so it
conforms to the repository typing rule for Python functions.

Source: Coding guidelines

@sonarqubecloud

sonarqubecloud Bot commented Jun 9, 2026

Copy link
Copy Markdown

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