Skip to content

chore(security): scope CodeQL to product code and clear false-positive alerts#426

Merged
OBenner merged 1 commit into
developfrom
chore/codeql-noise
Jul 17, 2026
Merged

chore(security): scope CodeQL to product code and clear false-positive alerts#426
OBenner merged 1 commit into
developfrom
chore/codeql-noise

Conversation

@OBenner

@OBenner OBenner commented Jul 17, 2026

Copy link
Copy Markdown
Owner

First of three PRs from a triage of the code scanning and Dependabot dashboards. This one is the noise-reduction slice: no behaviour changes.

The problem

330 open code-scanning alerts (17 high, 20 error, 45 medium, 230 note). Triaging the serious-looking ones by hand, almost every high/error is a false positive:

Alert Verdict
20× py/undefined-export (agents/__init__.py) ❌ FP — names resolve via __getattr__/_LAZY_EXPORTS; CodeQL can't follow lazy imports
js/insufficient-password-hash (credential-utils.ts) ❌ FP — SHA256(configDir)[:8] namespaces keychain entries; it isn't a password hash
py/clear-text-logging (security_scanner.py) ❌ FP — logs pattern_type/file/line only, never secret values

The rest is overwhelmingly hygiene (87 unused-local-variable, 64 unused-import, 23 cyclic-import, …) concentrated in test suites, build scripts, and site/. Real findings are invisible in that pile.

What this changes

1. Scope CodeQL to product code. New .github/codeql/codeql-config.yml with paths-ignore for test suites, build/release tooling, the static marketing site, and vendored/generated trees; wired into the CodeQL init step. Query suites are unchanged — apps/, libs/ and the rest of the shipped code are still scanned by +security-extended,security-and-quality.

2. Clear the 20 false py/undefined-export errors properly. agents/__init__.py gains a TYPE_CHECKING block re-declaring each lazy export, so static analysers can resolve __all__. It never executes, so __getattr__ still does the work at runtime. Verified: all 22 names in __all__ resolve and still load from their original modules.

3. Replace a stale root-level script with real tests. test_verify_subtask_2_2.py (left at the repo root by #154) generated 6 alerts and was never collected by pytest — wrong location, and its imports only resolve from apps/backend.

Worth flagging: it had also gone stale. It asserts that string-based error detection works, but is_rate_limit_error/is_authentication_error are now typed-only (the string fallback was deliberately removed, and both are deprecated) — so the script would fail if anyone ran it. Rather than delete it, I turned it into tests/test_error_classification.py, which pins the current typed-only contract and the deprecation warnings. Those helpers previously had no test coverage anywhere, so this is a net gain rather than a removal.

Verification

  • pytest tests/test_error_classification.py11 passed
  • Lazy-import smoke: every name in agents.__all__ resolves; run_autonomous_agentagents.coder, find_subtask_in_planagents.utils
  • Both YAML files parse

The effect on the alert count lands once CodeQL re-runs on develop. The remaining real items (sanitizer regex, log-injection, file-system-race) come in a later PR.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes

    • Error classification now relies on dedicated error types rather than matching exception message text.
    • Prevented generic errors from being incorrectly identified as rate-limit or authentication failures.
    • Deprecated error-classification wrappers now provide appropriate warnings.
  • Quality Improvements

    • Improved automated security analysis coverage and reduced noise from non-product files.
    • Enhanced static analysis visibility for available backend agent functionality.

…e alerts

CodeQL runs +security-extended,security-and-quality across the whole repo,
so the quality queries fire heavily in tests, build scripts, and the static
site. The result is ~330 open alerts in which the real findings are invisible.

- Add .github/codeql/codeql-config.yml with paths-ignore for test suites,
  build/release tooling, the marketing site, and vendored/generated trees,
  and wire it into the CodeQL init step.
- Re-declare the lazy exports of agents/__init__.py in a TYPE_CHECKING block.
  The names in __all__ resolve through __getattr__ at runtime, which CodeQL
  cannot follow, producing 20 false 'py/undefined-export' errors. The block is
  never executed, so lazy loading is unchanged.
- Replace the root-level test_verify_subtask_2_2.py verification script from
  #154 with tests/test_error_classification.py. The script was never collected
  by pytest and had gone stale: it asserted the string-based error detection
  that has since been removed, so it would fail if run. The new tests pin the
  current typed-only contract, which had no coverage at all.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Oleg Miagkov <mrobenner@gmail.com>
@cursor

cursor Bot commented Jul 17, 2026

Copy link
Copy Markdown

Bugbot is not enabled for your account, so this pull request was not reviewed.

Enable Bugbot in the Cursor dashboard to get automatic reviews on future PRs.

@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

CodeQL static analysis

Layer / File(s) Summary
CodeQL configuration and static exports
.github/codeql/codeql-config.yml, .github/workflows/quality-security.yml, apps/backend/agents/__init__.py
CodeQL excludes tests, generated or vendored content, the workflow loads the configuration and triggers on its changes, and lazily exported agent symbols are exposed to static analysis under TYPE_CHECKING.

Error classification verification

Layer / File(s) Summary
Typed error classification tests
test_verify_subtask_2_2.py, tests/test_error_classification.py
The standalone verification script is removed and pytest coverage verifies typed classifications, deprecation warnings, rejected string matching, generic exceptions, and non-overlapping results.

Estimated code review effort: 2 (Simple) | ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the PR’s main goal: scoping CodeQL to product code and reducing false positives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
✨ 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 chore/codeql-noise

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.

@sonarqubecloud

Copy link
Copy Markdown

@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: 1

🤖 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 `@tests/test_error_classification.py`:
- Around line 22-31: Update the pytest.warns calls in _is_rate_limit and
_is_auth to include match patterns for the expected deprecation warning
messages, ensuring each assertion targets the specific deprecated helper warning
rather than unrelated warnings.
🪄 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: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b1b62220-7a26-4134-81f7-53adee9536ac

📥 Commits

Reviewing files that changed from the base of the PR and between 8a11776 and aae9270.

📒 Files selected for processing (5)
  • .github/codeql/codeql-config.yml
  • .github/workflows/quality-security.yml
  • apps/backend/agents/__init__.py
  • test_verify_subtask_2_2.py
  • tests/test_error_classification.py
💤 Files with no reviewable changes (1)
  • test_verify_subtask_2_2.py

Comment on lines +22 to +31
def _is_rate_limit(error: Exception) -> bool:
"""Call the deprecated helper, asserting it still warns."""
with pytest.warns(DeprecationWarning):
return is_rate_limit_error(error)


def _is_auth(error: Exception) -> bool:
"""Call the deprecated helper, asserting it still warns."""
with pytest.warns(DeprecationWarning):
return is_authentication_error(error)

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.

📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Make the deprecation warning assertions stricter.

It is a recommended pytest convention to use the match parameter with pytest.warns to ensure you are catching the specific warning intended, rather than unrelated deprecations that might bubble up from internal dependencies. As per path instructions, ensure tests follow pytest conventions.

♻️ Proposed refactor to add `match` parameters
 def _is_rate_limit(error: Exception) -> bool:
     """Call the deprecated helper, asserting it still warns."""
-    with pytest.warns(DeprecationWarning):
+    with pytest.warns(DeprecationWarning, match=r"is_rate_limit_error\(\) is deprecated"):
         return is_rate_limit_error(error)
 
 
 def _is_auth(error: Exception) -> bool:
     """Call the deprecated helper, asserting it still warns."""
-    with pytest.warns(DeprecationWarning):
+    with pytest.warns(DeprecationWarning, match=r"is_authentication_error\(\) is deprecated"):
         return is_authentication_error(error)
📝 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 _is_rate_limit(error: Exception) -> bool:
"""Call the deprecated helper, asserting it still warns."""
with pytest.warns(DeprecationWarning):
return is_rate_limit_error(error)
def _is_auth(error: Exception) -> bool:
"""Call the deprecated helper, asserting it still warns."""
with pytest.warns(DeprecationWarning):
return is_authentication_error(error)
def _is_rate_limit(error: Exception) -> bool:
"""Call the deprecated helper, asserting it still warns."""
with pytest.warns(DeprecationWarning, match=r"is_rate_limit_error\(\) is deprecated"):
return is_rate_limit_error(error)
def _is_auth(error: Exception) -> bool:
"""Call the deprecated helper, asserting it still warns."""
with pytest.warns(DeprecationWarning, match=r"is_authentication_error\(\) is deprecated"):
return is_authentication_error(error)
🤖 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/test_error_classification.py` around lines 22 - 31, Update the
pytest.warns calls in _is_rate_limit and _is_auth to include match patterns for
the expected deprecation warning messages, ensuring each assertion targets the
specific deprecated helper warning rather than unrelated warnings.

Source: Path instructions

@OBenner
OBenner merged commit e97550a into develop Jul 17, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant