From f448682369bbf3f2cbad5e329cbcad3f152d3782 Mon Sep 17 00:00:00 2001 From: manavgup Date: Sat, 23 May 2026 18:27:49 -0400 Subject: [PATCH 1/5] fix(security): resolve P0 code scanning alerts (#803) - Wrap implicit string concatenation in parentheses (qa_agent.py) - Add comment to empty except for WebSocket disconnect (ws.py) - Add debug logging to empty except for storage read (concept_compiler.py) - Add nosec B405 suppression for xml.etree.ElementTree imports (rss.py) - Add nosec B311 suppression for random.sample usage (contradictions.py) [skip-doc-check] Co-Authored-By: Claude Opus 4.6 (1M context) --- src/wikimind/api/routes/ws.py | 2 +- src/wikimind/engine/concept_compiler.py | 2 +- src/wikimind/engine/linter/contradictions.py | 4 ++-- src/wikimind/engine/qa_agent.py | 8 +++++--- src/wikimind/ingest/adapters/rss.py | 4 ++-- 5 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/wikimind/api/routes/ws.py b/src/wikimind/api/routes/ws.py index 2854e9bc..0e8296db 100644 --- a/src/wikimind/api/routes/ws.py +++ b/src/wikimind/api/routes/ws.py @@ -269,7 +269,7 @@ async def websocket_endpoint(websocket: WebSocket) -> None: break except WebSocketDisconnect: - pass + pass # Expected during normal client disconnect; cleanup in finally finally: manager.disconnect(websocket) diff --git a/src/wikimind/engine/concept_compiler.py b/src/wikimind/engine/concept_compiler.py index ba311aa9..804e3293 100644 --- a/src/wikimind/engine/concept_compiler.py +++ b/src/wikimind/engine/concept_compiler.py @@ -71,7 +71,7 @@ async def _build_source_material(articles: list[Article], user_id: str) -> str: fc = fc[:max_chars] + "\n[...truncated...]" section += f"\nContent:\n{fc}\n" except (OSError, ValueError): - pass + log.debug("skipped article content", article_id=article.id, reason="storage read failed") parts.append(section) return "\n---\n".join(parts) diff --git a/src/wikimind/engine/linter/contradictions.py b/src/wikimind/engine/linter/contradictions.py index 2a6493e4..1d25a652 100644 --- a/src/wikimind/engine/linter/contradictions.py +++ b/src/wikimind/engine/linter/contradictions.py @@ -425,7 +425,7 @@ async def _collect_work( articles = list(article_result.scalars().all()) pairs = list(itertools.combinations(articles, 2)) if len(pairs) > cfg.max_contradiction_pairs_per_concept: - pairs = random.sample(pairs, cfg.max_contradiction_pairs_per_concept) + pairs = random.sample(pairs, cfg.max_contradiction_pairs_per_concept) # nosec B311 -- sampling for performance, not security all_work.append((None, "all-articles", pairs)) else: for concept_obj in concepts: @@ -435,7 +435,7 @@ async def _collect_work( continue pairs = list(itertools.combinations(articles, 2)) if len(pairs) > cfg.max_contradiction_pairs_per_concept: - pairs = random.sample(pairs, cfg.max_contradiction_pairs_per_concept) + pairs = random.sample(pairs, cfg.max_contradiction_pairs_per_concept) # nosec B311 -- sampling for performance, not security all_work.append((cid, cname, pairs)) return all_work diff --git a/src/wikimind/engine/qa_agent.py b/src/wikimind/engine/qa_agent.py index fe8df510..f86e437c 100644 --- a/src/wikimind/engine/qa_agent.py +++ b/src/wikimind/engine/qa_agent.py @@ -171,9 +171,11 @@ def _format_external_tools_block(tools: list[ExternalToolInfo]) -> str: lines = [ "", - "You also have access to external tools. If the wiki context is insufficient, " - "you MAY suggest calling one of these tools by including a 'tool_calls' array " - "in your response:", + ( + "You also have access to external tools. If the wiki context is insufficient, " + "you MAY suggest calling one of these tools by including a 'tool_calls' array " + "in your response:" + ), "", ] for info in tools: diff --git a/src/wikimind/ingest/adapters/rss.py b/src/wikimind/ingest/adapters/rss.py index b5891bdb..1122c801 100644 --- a/src/wikimind/ingest/adapters/rss.py +++ b/src/wikimind/ingest/adapters/rss.py @@ -8,7 +8,7 @@ import hashlib from typing import TYPE_CHECKING -from xml.etree.ElementTree import ParseError +from xml.etree.ElementTree import ParseError # nosec B405 -- exception class only, parsing uses defusedxml import defusedxml.ElementTree as DefusedET import httpx @@ -26,7 +26,7 @@ ) if TYPE_CHECKING: - from xml.etree.ElementTree import Element + from xml.etree.ElementTree import Element # nosec B405 -- exception class only, parsing uses defusedxml from sqlmodel.ext.asyncio.session import AsyncSession From 845ad9f5be0e039ac7f59e4e751fcda79be5226d Mon Sep 17 00:00:00 2001 From: manavgup Date: Sat, 23 May 2026 19:04:31 -0400 Subject: [PATCH 2/5] ci: retrigger checks From b6755759c1f2aba1cd0a9dbbaa19bf0f7a951863 Mon Sep 17 00:00:00 2001 From: manavgup Date: Sat, 23 May 2026 19:04:45 -0400 Subject: [PATCH 3/5] ci: retrigger checks From 68d7bc2efa6f35136744b75fe5334d8b525e8e35 Mon Sep 17 00:00:00 2001 From: manavgup Date: Sat, 23 May 2026 19:26:32 -0400 Subject: [PATCH 4/5] ci: retrigger checks From 1793850e0600024486d4b32de9acf9b629248d73 Mon Sep 17 00:00:00 2001 From: manavgup Date: Mon, 25 May 2026 11:13:40 -0400 Subject: [PATCH 5/5] ci: trigger checks