Skip to content

fix(ci): migrate sonarcloud to org workflow and pin @main to SHA#27

Merged
williaby merged 23 commits into
mainfrom
claude/fix-sonarcloud-ci-issues-9hioH
May 20, 2026
Merged

fix(ci): migrate sonarcloud to org workflow and pin @main to SHA#27
williaby merged 23 commits into
mainfrom
claude/fix-sonarcloud-ci-issues-9hioH

Conversation

@williaby
Copy link
Copy Markdown
Contributor

@williaby williaby commented May 15, 2026

Summary

Addresses two CI issues in one PR:

Closes #7 — Migrate SonarCloud to org reusable workflow + fix organization

  • Replaced inline sonarcloud.yml (which used sonarqube-scan-action at an old SHA / v4.2.2) with a thin caller to the org reusable workflow python-sonarcloud.yml@6bad2f898be1d387b8424e9deddefa519674cb19 (uses sonarqube-scan-action v7.2.0 and resolves the /analysis/analyses 404 bug on new projects).
  • Caller passes skip-if-no-token: true, fail-on-quality-gate: false, and sonar-organization: 'williaby' (the actual SonarCloud account name).
  • In ci.yml, added enable-sonarcloud: false and sonarcloud-organization: 'williaby' so the CI reusable workflow delegates SonarCloud responsibility to sonarcloud.yml.

Closes #8 — Pin all @main org reusable workflow references to SHA

Replaced every @main suffix on ByronWilliamsCPA/.github reusable workflow references with @e067cdb7294f6221dbde74ef1f4c3ca735eed570 # main. Floating on @main is a supply chain risk; any commit pushed to the org .github repo would be immediately live in this repository's CI without review.

Files updated (15 callers + sonarcloud rewrite):

  • ci.yml, codecov.yml, container-security.yml, coverage.yml, docs.yml
  • mutation-testing.yml, performance-regression.yml, publish-pypi.yml
  • python-compatibility.yml, qlty.yml, release.yml, sbom.yml
  • scorecard.yml, security-analysis.yml, slsa-provenance.yml
  • sonarcloud.yml (rewritten as caller to python-sonarcloud.yml)

Verified no @main references remain in any YAML workflow file.

Test plan

  • CI workflow runs on this PR using the new pinned SHA
  • SonarCloud workflow runs against the org reusable workflow and either reports analysis or skips cleanly if SONAR_TOKEN is unset
  • ci job no longer attempts inline SonarCloud (delegated to sonarcloud.yml)
  • All other pinned-SHA workflows still trigger and execute their reusable callees

Closes #7
Closes #8


Generated by Claude Code

Summary by CodeRabbit

  • Chores

    • Pinned reusable CI workflows to specific commit SHAs for greater stability and consistency.
    • Switched SonarCloud to a reusable workflow invocation and adjusted SonarCloud-related inputs and secrets handling.
  • Bug Fixes

    • Standardized UTC/timezone handling across the codebase for Python 3.12 compatibility.
    • Scoped atheris to Python 3.11+ to avoid incompatible installs.
  • Dependencies

    • Bumped pymdown-extensions to 10.21.3.
  • Documentation

    • Added template feedback entries describing CI/CD and tooling issues.

Review Change Stack

Copilot AI review requested due to automatic review settings May 15, 2026 21:03
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Warning

Rate limit exceeded

@williaby has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 37 seconds before requesting another review.

You’ve run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 174cffe4-4327-41c5-a4c2-036aa51a4691

📥 Commits

Reviewing files that changed from the base of the PR and between 8d4e30f and 8f9af6c.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (31)
  • .coderabbit.yaml
  • .github/workflows/ci.yml
  • .github/workflows/codecov.yml
  • .github/workflows/container-security.yml
  • .github/workflows/coverage.yml
  • .github/workflows/docs.yml
  • .github/workflows/mutation-testing.yml
  • .github/workflows/performance-regression.yml
  • .github/workflows/pr-validation.yml
  • .github/workflows/publish-pypi.yml
  • .github/workflows/python-compatibility.yml
  • .github/workflows/qlty.yml
  • .github/workflows/release.yml
  • .github/workflows/sbom.yml
  • .github/workflows/scorecard.yml
  • .github/workflows/security-analysis.yml
  • .github/workflows/slsa-provenance.yml
  • .github/workflows/sonarcloud.yml
  • docs/template_feedback.md
  • pyproject.toml
  • src/rag_processor/auth/cloudflare.py
  • src/rag_processor/auth/models.py
  • src/rag_processor/models/batch.py
  • src/rag_processor/models/job.py
  • src/rag_processor/queue/jobs.py
  • src/rag_processor/queue/redis_store.py
  • src/rag_processor/utils/time_utils.py
  • src/rag_processor/websocket/events.py
  • tests/unit/test_auth_middleware.py
  • tests/unit/test_models.py
  • tests/unit/test_websocket.py

Walkthrough

Pins many org-level reusable GitHub Actions workflows to a fixed commit SHA, refactors SonarCloud to call a pinned reusable workflow, standardizes UTC usage to timezone.utc across source/tests, updates dependencies, and adds template feedback entries.

Changes

GitHub Actions Workflow Updates

Layer / File(s) Summary
Reusable workflow reference pinning
.github/workflows/ci.yml, .github/workflows/codecov.yml, .github/workflows/container-security.yml, .github/workflows/coverage.yml, .github/workflows/docs.yml, .github/workflows/mutation-testing.yml, .github/workflows/performance-regression.yml, .github/workflows/publish-pypi.yml, .github/workflows/python-compatibility.yml, .github/workflows/qlty.yml, .github/workflows/release.yml, .github/workflows/scorecard.yml, .github/workflows/security-analysis.yml, .github/workflows/slsa-provenance.yml
Replace floating @main reusable workflow references with a pinned commit SHA to lock upstream workflow implementations.
Workflow inputs, no-build flags, and secrets
.github/workflows/ci.yml, .github/workflows/mutation-testing.yml, .github/workflows/performance-regression.yml, .github/workflows/pr-validation.yml, .github/workflows/release.yml, .github/workflows/sbom.yml, .github/workflows/container-security.yml
Add explicit no-build: false where passed to reusable workflows; set CI SonarCloud inputs (enable-sonarcloud: false, sonarcloud-organization); tighten secrets passed into reusable callers; dynamically compute --ignore-vuln args for pip-audit.
SonarCloud workflow refactor and docs
.github/workflows/sonarcloud.yml
Replace inline SonarCloud analysis with a pinned reusable workflow call, grant PR decoration permission (pull-requests: write), and update top-of-file documentation and inputs.

Python UTC compatibility

Layer / File(s) Summary
Auth and token models
src/rag_processor/auth/cloudflare.py, src/rag_processor/auth/models.py
Define UTC = timezone.utc locally instead of importing UTC from datetime; behavior unchanged otherwise.
Job and Batch models
src/rag_processor/models/batch.py, src/rag_processor/models/job.py
Define module-level UTC = timezone.utc for timestamp defaults and serialization.
Queue and Redis store
src/rag_processor/queue/jobs.py, src/rag_processor/queue/redis_store.py
Use local UTC = timezone.utc when recording started_at, completed_at, and updated_at.
Time utilities and WebSocket events
src/rag_processor/utils/time_utils.py, src/rag_processor/websocket/events.py
time_utils continues exporting UTC but now defines it via timezone.utc; websocket events use the same local UTC constant.
Test modules UTC migration
tests/unit/test_auth_middleware.py, tests/unit/test_models.py, tests/unit/test_websocket.py
Tests import timezone and define UTC = timezone.utc for generating timezone-aware timestamps used in assertions.

Dependencies and Documentation

Layer / File(s) Summary
Dependency updates and feedback documentation
pyproject.toml, docs/template_feedback.md
Bump pymdown-extensions to 10.21.3; gate atheris to Python >=3.11 in dev extras; remove safety from dev and supply-chain optional groups; add PYSEC-2026-89 to pip-audit ignore list; add template feedback items documenting CI/workflow/tooling issues.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

Possibly related PRs

Suggested labels

ci, dependencies, documentation, python, tests

"I hopped through YAML lanes today,
Pinned SHAs to keep drift at bay,
UTC now sleeps in timezone's shade,
Docs and deps a tidy braid,
A rabbit cheers the steady way."

🚥 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 main changes: migrating SonarCloud to org workflow and pinning @main references to specific commit SHAs across CI workflows.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
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 unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/fix-sonarcloud-ci-issues-9hioH

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.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 15, 2026

⚠️ Deprecation Warning: The deny-licenses option is deprecated for possible removal in the next major release. For more information, see issue 997.

Dependency Review

The following issues were found:
  • ✅ 0 vulnerable package(s)
  • ✅ 0 package(s) with incompatible licenses
  • ✅ 0 package(s) with invalid SPDX license definitions
  • ⚠️ 1 package(s) with unknown licenses.
See the Details below.

License Issues

pyproject.toml

PackageVersionLicenseIssue Type
pymdown-extensions>= 10.21.3NullUnknown License
Denied Licenses: GPL-2.0, GPL-3.0

OpenSSF Scorecard

PackageVersionScoreDetails
actions/ByronWilliamsCPA/.github/.github/workflows/python-docs.yml 1b2d33c47cc11a96b9757b49f41873c54e75f57c UnknownUnknown
actions/ByronWilliamsCPA/.github/.github/workflows/python-compatibility.yml 1b2d33c47cc11a96b9757b49f41873c54e75f57c UnknownUnknown
actions/ByronWilliamsCPA/.github/.github/workflows/python-security-analysis.yml 1b2d33c47cc11a96b9757b49f41873c54e75f57c UnknownUnknown
actions/ByronWilliamsCPA/.github/.github/workflows/python-sonarcloud.yml 1b2d33c47cc11a96b9757b49f41873c54e75f57c UnknownUnknown
pip/pymdown-extensions >= 10.21.3 UnknownUnknown
pip/markdown 3.10.2 UnknownUnknown

Scanned Files

  • .github/workflows/docs.yml
  • .github/workflows/python-compatibility.yml
  • .github/workflows/security-analysis.yml
  • .github/workflows/sonarcloud.yml
  • pyproject.toml
  • uv.lock

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the repository’s CI security posture and SonarCloud integration by migrating SonarCloud scanning to an org-level reusable workflow and pinning previously floating reusable workflow references to immutable commit SHAs.

Changes:

  • Replaced the inline SonarCloud workflow implementation with a thin caller to the org reusable python-sonarcloud.yml workflow (including skip-if-no-token and non-blocking quality gate behavior).
  • Pinned org reusable workflow references that previously used @main to a specific commit SHA to reduce supply-chain risk.
  • Updated the main CI caller to disable inline SonarCloud handling and set the correct SonarCloud organization value.

Reviewed changes

Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.

Show a summary per file
File Description
.github/workflows/sonarcloud.yml Migrates SonarCloud analysis to org reusable workflow with configured inputs/secrets.
.github/workflows/ci.yml Pins org CI workflow to SHA; disables SonarCloud in CI reusable workflow and sets org name.
.github/workflows/codecov.yml Pins org Codecov reusable workflow reference to SHA.
.github/workflows/container-security.yml Pins org container security reusable workflow reference to SHA.
.github/workflows/coverage.yml Pins org Qlty coverage reusable workflow reference to SHA.
.github/workflows/docs.yml Pins org docs reusable workflow reference to SHA.
.github/workflows/mutation-testing.yml Pins org mutation testing reusable workflow reference to SHA.
.github/workflows/performance-regression.yml Pins org performance regression reusable workflow reference to SHA.
.github/workflows/publish-pypi.yml Pins org PyPI publish reusable workflow reference to SHA.
.github/workflows/python-compatibility.yml Pins org compatibility matrix reusable workflow reference to SHA.
.github/workflows/qlty.yml Pins org Qlty coverage reusable workflow reference to SHA.
.github/workflows/release.yml Pins org release reusable workflow reference to SHA.
.github/workflows/sbom.yml Pins org SBOM reusable workflow reference to SHA.
.github/workflows/scorecard.yml Pins org Scorecard reusable workflow reference to SHA.
.github/workflows/security-analysis.yml Pins org security analysis reusable workflow reference to SHA.
.github/workflows/slsa-provenance.yml Pins org SLSA reusable workflow reference to SHA.

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 20, 2026

✅ FIPS Compatibility Check

Metric Count
Errors 0
Warnings 0
Info 3

Status: ✅ PASSED

What is FIPS?

FIPS 140-2/140-3 is a US government standard for cryptographic modules.
Systems running Ubuntu LTS with fips-updates or similar configurations
restrict cryptographic algorithms to NIST-approved ones.

Common issues:

  • Using hashlib.md5() without usedforsecurity=False
  • Dependencies using non-approved algorithms (bcrypt, DES, RC4)
  • Weak cipher configurations

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.33 2.34 +0.4%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.92 1.92 📈 0.1%
p95_ms 2.33 2.34 📈 0.4%
p99_ms 2.38 2.39 📈 0.5%
mean_ms 1.37 1.37 📈 0.1%
min_ms 0.05 0.05 📉 -3.8%
max_ms 2.38 2.48 📈 3.8%
throughput_ops 730.15 729.05 📉 -0.2%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.93 0.94 📈 0.1%
avg_throughput_all_benchmarks_ops 1092467.81 1095316.23 📈 0.3%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.27 2.34 +3.0%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.92 1.92 📉 -0.1%
p95_ms 2.27 2.34 📈 3.0%
p99_ms 2.34 2.37 📈 1.1%
mean_ms 1.37 1.37 📈 0.4%
min_ms 0.05 0.05 📈 2.0%
max_ms 2.36 2.39 📈 1.3%
throughput_ops 731.64 728.13 📉 -0.5%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.91 0.92 📈 1.7%
avg_throughput_all_benchmarks_ops 1086280.98 1061198.45 📉 -2.3%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

williaby pushed a commit that referenced this pull request May 20, 2026
Two more template defaults discovered while resolving SonarCloud and
Python compatibility matrix failures on PR #27.
@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.35 2.40 +2.0%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.92 1.94 📈 0.7%
p95_ms 2.35 2.40 📈 2.0%
p99_ms 2.40 2.49 📈 3.6%
mean_ms 1.38 1.40 📈 1.1%
min_ms 0.05 0.05 📈 2.0%
max_ms 2.43 2.56 📈 5.3%
throughput_ops 724.10 716.49 📉 -1.1%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.95 0.96 📈 1.3%
avg_throughput_all_benchmarks_ops 1039124.73 1002857.78 📉 -3.5%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@github-actions
Copy link
Copy Markdown

🎉 Performance Regression Check

Status: PERFORMANCE IMPROVED

Metric Baseline (main) PR Branch Change
p95_ms 2.70 2.50 -7.7%

Threshold: +/-10% allowed regression

Great work!: Performance has improved.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.88 1.88 📈 0.3%
p95_ms 2.70 2.50 📉 -7.7%
p99_ms 3.01 2.60 📉 -13.8%
mean_ms 1.50 1.43 📉 -5.1%
min_ms 0.06 0.06 ➡️ 0.0%
max_ms 3.18 2.69 📉 -15.4%
throughput_ops 665.53 700.89 📈 5.3%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 1.21 0.99 📉 -17.7%
avg_throughput_all_benchmarks_ops 1106323.82 973046.53 📉 -12.0%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.36 2.30 -2.5%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.92 1.91 📉 -0.4%
p95_ms 2.36 2.30 📉 -2.5%
p99_ms 2.41 2.37 📉 -1.7%
mean_ms 1.39 1.37 📉 -1.3%
min_ms 0.05 0.05 ➡️ 0.0%
max_ms 2.48 2.42 📉 -2.5%
throughput_ops 721.43 731.24 📈 1.4%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.94 0.92 📉 -2.2%
avg_throughput_all_benchmarks_ops 996680.96 1104852.02 📈 10.9%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.28 2.27 -0.6%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.93 1.91 📉 -0.8%
p95_ms 2.28 2.27 📉 -0.6%
p99_ms 2.39 2.36 📉 -1.3%
mean_ms 1.37 1.36 📉 -0.7%
min_ms 0.05 0.05 ➡️ 0.0%
max_ms 2.41 2.47 📈 2.5%
throughput_ops 727.76 732.87 📈 0.7%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.91 0.92 📈 0.5%
avg_throughput_all_benchmarks_ops 1160602.35 1110122.97 📉 -4.3%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.23 2.33 +4.5%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.93 1.93 📈 0.2%
p95_ms 2.23 2.33 📈 4.5%
p99_ms 2.44 2.40 📉 -1.7%
mean_ms 1.37 1.38 📈 0.5%
min_ms 0.05 0.05 ➡️ 0.0%
max_ms 2.45 2.45 📈 0.1%
throughput_ops 728.75 725.17 📉 -0.5%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.91 0.93 📈 2.3%
avg_throughput_all_benchmarks_ops 1122166.51 1057163.35 📉 -5.8%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@williaby
Copy link
Copy Markdown
Contributor Author

@copilot resolve the merge conflicts in this pull request

Copy link
Copy Markdown
Contributor

Copilot AI commented May 20, 2026

@copilot resolve the merge conflicts in this pull request

Resolved in 9f58c37. Three workflow files had conflicts with the baa8ed3 commit that landed on main:

  • ci.yml — kept our enable-sonarcloud: false / sonarcloud-organization: 'williaby' lines and adopted main's explanatory comment above no-build: false
  • python-compatibility.yml — adopted main's updated test-command (adds --ignore=tests/load) and its inline comment explaining why the -m marker filter was dropped
  • security-analysis.yml — adopted main's no-build comment (our version had no content between run-osv: false and no-build: false)

@coderabbitai coderabbitai Bot added documentation Improvements or additions to documentation python ci tests dependencies labels May 20, 2026
@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.44 2.46 +0.5%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.87 1.87 📈 0.1%
p95_ms 2.44 2.46 📈 0.5%
p99_ms 2.57 2.56 📉 -0.5%
mean_ms 1.42 1.42 📉 -0.1%
min_ms 0.06 0.06 📈 1.8%
max_ms 2.57 2.62 📈 1.9%
throughput_ops 702.70 703.48 📈 0.1%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.98 0.98 📈 0.3%
avg_throughput_all_benchmarks_ops 1087709.53 1064837.43 📉 -2.1%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

coderabbitai[bot]
coderabbitai Bot previously requested changes May 20, 2026
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

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

⚠️ Outside diff range comments (3)
.github/workflows/mutation-testing.yml (1)

43-53: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Avoid broad secret inheritance in this caller.

Line 53 inherits all repository secrets into the reusable workflow. Restrict to explicit secret mappings required by python-mutation.yml.

As per coding guidelines, .github/workflows/**: Review GitHub Actions workflows for “Proper secret handling”.

🤖 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/mutation-testing.yml around lines 43 - 53, The workflow
currently uses a broad secret inheritance via the secrets: inherit setting when
calling the reusable workflow (python-mutation.yml); replace that with explicit
secret mappings by identifying which secrets the reusable workflow actually
needs (e.g., tokens or API keys referenced inside python-mutation.yml) and add
only those as named mappings (for example GITHUB_TOKEN, PYPI_TOKEN,
CUSTOM_API_KEY) under the call instead of inherit so only required secrets are
passed to the reusable workflow; update the caller to remove secrets: inherit
and add the minimal secrets: block with the exact secret names used by
python-mutation.yml.
.github/workflows/container-security.yml (1)

42-55: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Limit secret scope for reusable workflow calls.

Line 55 uses secrets: inherit, which grants all repository secrets to the called workflow. Replace with explicit secret mapping. The reusable workflow only requires DHI_USERNAME and DHI_PAT:

secrets:
  DHI_USERNAME: ${{ secrets.DHI_USERNAME }}
  DHI_PAT: ${{ secrets.DHI_PAT }}

This follows the least-privilege principle per GitHub Actions security best practices.

🤖 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/container-security.yml around lines 42 - 55, The workflow
call using the reusable workflow (the uses: ByronWilliamsCPA/... line) currently
uses "secrets: inherit" which exposes all repo secrets; replace that with an
explicit secret mapping that only passes DHI_USERNAME and DHI_PAT (map
DHI_USERNAME: ${{ secrets.DHI_USERNAME }} and DHI_PAT: ${{ secrets.DHI_PAT }})
so the reusable workflow receives only the needed credentials.
.github/workflows/python-compatibility.yml (1)

44-69: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Remove secrets: inherit from this external reusable workflow call.

This testing workflow has no apparent need for repository secrets. Inheriting all secrets (via secrets: inherit) unnecessarily expands the blast radius if the external workflow is ever compromised. Follow least-privilege: explicitly pass only required secrets using the secrets key, or omit it entirely if none are needed.

Suggested change
     uses: ByronWilliamsCPA/.github/.github/workflows/python-compatibility.yml@1b2d33c47cc11a96b9757b49f41873c54e75f57c # main
     with:
@@ -66,7 +66,8 @@
       # rag-processor uses hatchling as build backend, so editable installs
       # require the build step. The reusable defaults no-build: true; override.
       no-build: false
-    secrets: inherit
+    # Omit secrets entirely unless explicitly required by the reusable workflow.
+    # secrets:
+    #   REQUIRED_SECRET: ${{ secrets.REQUIRED_SECRET }}

As per coding guidelines, .github/workflows/** should follow "Proper secret handling" and "Security best practices (minimal permissions)".

🤖 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/python-compatibility.yml around lines 44 - 69, The call to
the external reusable workflow currently uses "secrets: inherit", which exposes
all repository secrets unnecessarily; remove the "secrets: inherit" line from
the reusable workflow invocation (the block using "uses:
ByronWilliamsCPA/.github/.github/workflows/python-compatibility.yml") or replace
it with an explicit minimal mapping of only the specific secrets that workflow
requires (e.g., "secrets: { REQUIRED_SECRET: ${{ secrets.REQUIRED_SECRET }}") if
any are actually needed.
🤖 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 `@docs/template_feedback.md`:
- Around line 53-55: The fenced code block containing the error message "error:
Distribution `<project>==0.1.0 @ editable+.` can't be installed because it is
marked as `--no-build` but has no binary distribution" should include a language
specifier for proper syntax highlighting; update the opening triple-backtick for
that block to "```text" (and keep the closing "```") so the snippet is rendered
with the text language identifier.

---

Outside diff comments:
In @.github/workflows/container-security.yml:
- Around line 42-55: The workflow call using the reusable workflow (the uses:
ByronWilliamsCPA/... line) currently uses "secrets: inherit" which exposes all
repo secrets; replace that with an explicit secret mapping that only passes
DHI_USERNAME and DHI_PAT (map DHI_USERNAME: ${{ secrets.DHI_USERNAME }} and
DHI_PAT: ${{ secrets.DHI_PAT }}) so the reusable workflow receives only the
needed credentials.

In @.github/workflows/mutation-testing.yml:
- Around line 43-53: The workflow currently uses a broad secret inheritance via
the secrets: inherit setting when calling the reusable workflow
(python-mutation.yml); replace that with explicit secret mappings by identifying
which secrets the reusable workflow actually needs (e.g., tokens or API keys
referenced inside python-mutation.yml) and add only those as named mappings (for
example GITHUB_TOKEN, PYPI_TOKEN, CUSTOM_API_KEY) under the call instead of
inherit so only required secrets are passed to the reusable workflow; update the
caller to remove secrets: inherit and add the minimal secrets: block with the
exact secret names used by python-mutation.yml.

In @.github/workflows/python-compatibility.yml:
- Around line 44-69: The call to the external reusable workflow currently uses
"secrets: inherit", which exposes all repository secrets unnecessarily; remove
the "secrets: inherit" line from the reusable workflow invocation (the block
using "uses:
ByronWilliamsCPA/.github/.github/workflows/python-compatibility.yml") or replace
it with an explicit minimal mapping of only the specific secrets that workflow
requires (e.g., "secrets: { REQUIRED_SECRET: ${{ secrets.REQUIRED_SECRET }}") if
any are actually needed.
🪄 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: 6d79777c-ffe3-404d-85a7-97c5f4dc2a98

📥 Commits

Reviewing files that changed from the base of the PR and between baa8ed3 and 9f58c37.

⛔ Files ignored due to path filters (1)
  • uv.lock is excluded by !**/*.lock, !**/*.lock
📒 Files selected for processing (30)
  • .github/workflows/ci.yml
  • .github/workflows/codecov.yml
  • .github/workflows/container-security.yml
  • .github/workflows/coverage.yml
  • .github/workflows/docs.yml
  • .github/workflows/mutation-testing.yml
  • .github/workflows/performance-regression.yml
  • .github/workflows/pr-validation.yml
  • .github/workflows/publish-pypi.yml
  • .github/workflows/python-compatibility.yml
  • .github/workflows/qlty.yml
  • .github/workflows/release.yml
  • .github/workflows/sbom.yml
  • .github/workflows/scorecard.yml
  • .github/workflows/security-analysis.yml
  • .github/workflows/slsa-provenance.yml
  • .github/workflows/sonarcloud.yml
  • docs/template_feedback.md
  • pyproject.toml
  • src/rag_processor/auth/cloudflare.py
  • src/rag_processor/auth/models.py
  • src/rag_processor/models/batch.py
  • src/rag_processor/models/job.py
  • src/rag_processor/queue/jobs.py
  • src/rag_processor/queue/redis_store.py
  • src/rag_processor/utils/time_utils.py
  • src/rag_processor/websocket/events.py
  • tests/unit/test_auth_middleware.py
  • tests/unit/test_models.py
  • tests/unit/test_websocket.py

Comment thread docs/template_feedback.md Outdated
@coderabbitai coderabbitai Bot removed documentation Improvements or additions to documentation python ci tests dependencies labels May 20, 2026
williaby and others added 4 commits May 20, 2026 10:49
ci.yml passed `sonarcloud-organization: 'williaby'` while sonarcloud.yml
passes `sonar-organization: 'byronwilliamscpa'`. The conflict is the same
issue documented in docs/template_feedback.md (entry "Stale
sonar-organization default"): williaby is a leftover personal handle and
the project actually lives under the byronwilliamscpa SonarCloud org.

Although `enable-sonarcloud: false` in ci.yml currently makes the value
unused at runtime, leaving the documented-wrong value in code contradicts
the PR's stated goal of fixing the SonarCloud organization and will
mislead future readers when ci.yml's enable flag flips back to true.

Surface findings origin: PR #27 self-review (Critical tier).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address CodeRabbit's three outside-diff comments on PR #27 about
`secrets: inherit` granting all repository secrets to org reusable
workflows:

- container-security.yml: replace `secrets: inherit` with an explicit
  `DHI_USERNAME` + `DHI_PAT` mapping. The org python-container-security.yml
  only consumes those two credentials.
- mutation-testing.yml: drop `secrets: inherit`. python-mutation.yml does
  not need repository secrets for the mutation run; re-add a specific
  mapping if a future change adds an authenticated step.
- python-compatibility.yml: drop `secrets: inherit`. The compatibility
  matrix runs pure unit tests against multiple Python versions and has
  no apparent secret dependency.

Follows the least-privilege principle in OWASP / GitHub Actions security
best practices: minimize the blast radius if an org reusable workflow is
ever compromised.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…wing them

The IGNORE_ARGS step in pr-validation.yml previously used
`$(python3 -c "..." 2>/dev/null || true)` which silently swallowed any
tomllib parse failure. If pyproject.toml became unreadable, pip-audit
would run without the intended `[tool.pip-audit].ignore-vuln` flags and
re-flag advisories that were deliberately ignored, causing a confusing
"why is this suddenly failing" diagnosis with no audit-log trail.

Replace the silent fallback with an explicit `if ! IGNORE_ARGS=$(...)`
branch that:
- Lets stderr from python3 surface in the workflow log
- Emits a `::warning::` annotation so reviewers see the parse failure
  on the run summary
- Resets IGNORE_ARGS to an empty string so pip-audit still runs and
  surfaces the real vulnerabilities loudly

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The `UTC = timezone.utc  # noqa: UP017` pattern is repeated across 11
files (8 src + 3 tests). The previous module docstring claimed "Python
3.12 idioms" which contradicted the backport. Without an inline
explanation, future maintainers see only a suppressed ruff rule with no
hint of when it can be removed.

Add a comment on time_utils.py (the canonical home of UTC for the
project) that:
- States why the alias exists: `datetime.UTC` was added in Python 3.11
  and `requires-python = ">=3.10"` still supports 3.10
- States the removal condition: when the project minimum moves to 3.11,
  switch to `from datetime import UTC` and drop the noqa annotations

Also correct the module docstring from "Python 3.12 idioms" to "Python
3.10+ compatible" so the file's own description matches its actual
constraint.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
williaby pushed a commit that referenced this pull request May 20, 2026
- pr-validation.yml: build pip-audit --ignore-vuln flags as a bash array
  and pass them quoted instead of relying on unquoted $IGNORE_ARGS
  expansion. Current PYSEC-* IDs are shell-safe, but the array pattern
  is robust against future entries with shell-significant characters.
- template_feedback.md: hard-wrap the new safety-removal section at the
  120-char limit called out by the repo's markdown guideline.

Verified locally: pip-audit clean ('No known vulnerabilities found, 3
ignored').
@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.47 2.51 +1.5%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.87 1.88 📈 0.1%
p95_ms 2.47 2.51 📈 1.5%
p99_ms 2.63 2.67 📈 1.7%
mean_ms 1.43 1.44 📈 0.2%
min_ms 0.06 0.06 ➡️ 0.0%
max_ms 3.14 2.73 📉 -12.9%
throughput_ops 697.20 695.95 📉 -0.2%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.99 1.01 📈 1.1%
avg_throughput_all_benchmarks_ops 1046725.82 1071101.14 📈 2.3%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@williaby williaby force-pushed the claude/fix-sonarcloud-ci-issues-9hioH branch from d03effd to c15bd5f Compare May 20, 2026 17:56
@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.25 2.25 +0.0%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.91 1.91 ➡️ 0.0%
p95_ms 2.25 2.25 📈 0.0%
p99_ms 2.33 2.40 📈 2.9%
mean_ms 1.36 1.36 📈 0.6%
min_ms 0.05 0.05 📈 2.0%
max_ms 2.33 2.43 📈 4.0%
throughput_ops 736.89 732.37 📉 -0.6%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.90 0.90 📉 -0.3%
avg_throughput_all_benchmarks_ops 1145285.48 1130775.07 📉 -1.3%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@williaby
Copy link
Copy Markdown
Contributor Author

PR Fix Summary

Rebased onto current main (resolving 5 file conflicts across ci.yml, python-compatibility.yml, security-analysis.yml, pyproject.toml, pr-validation.yml) and applied the 4 in-scope findings from the pr-review comment above. Force-pushed to c15bd5f.

Note on rebase: The original 14 PR commits were replayed onto the post-PR#33 / post-PR#20 main. The merge commit (9f58c37) and duplicate-of-main commit (e96ed27 fix(ci): disable --no-build) were resolved into clean cherry-picks. Inline review-thread anchors from before the rebase may now point at orphaned SHAs.

Fixes applied

Critical

  • ci.yml sonarcloud-organization mismatch -> Changed 'williaby' to 'byronwilliamscpa' to match sonarcloud.yml and the value documented in docs/template_feedback.md. Commit 9dc6e0e.

Important (CodeRabbit's 3 outside-diff comments)

  • mutation-testing.yml secrets: inherit -> Dropped. python-mutation.yml has no apparent secret dependency. Commit 1d49cff.
  • container-security.yml secrets: inherit -> Replaced with explicit DHI_USERNAME + DHI_PAT mapping (the two creds the org workflow consumes). Commit 1d49cff.
  • python-compatibility.yml secrets: inherit -> Dropped. Compat matrix runs pure unit tests, no secrets needed. Commit 1d49cff.

Suggested

  • pr-validation.yml IGNORE_ARGS silent failure -> Replaced 2>/dev/null || true with an if ! branch that surfaces tomllib parse errors via ::warning:: and resets IGNORE_ARGS to empty so pip-audit still runs loudly. Commit ecb8b23.
  • noqa: UP017 rationale -> Added a documentation comment on time_utils.py (the canonical home of UTC) explaining why the alias exists (datetime.UTC requires 3.11+; requires-python = ">=3.10") and when to remove it. Module docstring also corrected from "Python 3.12 idioms" -> "Python 3.10+ compatible". Commit c15bd5f.

Rebase conflict resolutions

  • pyproject.toml [tool.pip-audit] ignore-vuln -> Kept the PR's richer-documented PYSEC-2026-89 (markdown) + PYSEC-2025-183 (pyjwt) entries with inline justifications; dropped main's PYSEC-2024-277 (joblib) + PYSEC-2026-97 (nltk) because both were transitive via safety, which this PR removes from dev/supply-chain extras.
  • ci.yml with: block -> Combined main's no-build: false (PR fix(ci): override no-build for hatchling editable installs #33) with this PR's enable-sonarcloud: false block.
  • pr-validation.yml pip-audit step -> Preserved this PR's dynamic tomllib-expansion approach over main's hardcoded --ignore-vuln flags; this is the change PR fix(ci): migrate sonarcloud to org workflow and pin @main to SHA #27 intentionally introduces.

Skipped (already addressed in PR before review)

  • CodeRabbit's fenced-code-block language tag in docs/template_feedback.md -> Already labeled text in the current PR state; CodeRabbit comment was against an earlier version.

Remaining (manual follow-up recommended)

  • PR description body: still references stale SHA e067cdb7... and the now-incorrect 'williaby' claim. The actual PR now uses 1b2d33c4... for org workflows and 'byronwilliamscpa' for SonarCloud. Author may want to refresh the description.
  • Test Plan checkboxes: 4 boxes unchecked in PR body; CI was green pre-rebase and will run again post-push.

Pre-commit hooks passed locally on each commit. CI will re-run on push.

Generated with Claude Code

The rebase replay reintroduced a duplicate `no-build: false` entry at
the end of the `with:` block (one came from PR #33's mainline edit, the
other from this PR's earlier no-build sweep). YAML silently keeps the
last duplicate, but Actions emits a warning and lint tools flag it. Drop
the trailing duplicate so the key appears exactly once.
@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.42 2.43 +0.3%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.87 1.87 📉 -0.1%
p95_ms 2.42 2.43 📈 0.3%
p99_ms 2.51 2.56 📈 2.3%
mean_ms 1.42 1.42 📈 0.4%
min_ms 0.06 0.06 ➡️ 0.0%
max_ms 2.55 2.61 📈 2.3%
throughput_ops 706.72 703.64 📉 -0.4%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.98 0.97 📉 -1.3%
avg_throughput_all_benchmarks_ops 1091619.02 1104927.57 📈 1.2%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

williaby and others added 3 commits May 20, 2026 11:11
The org python-ci.yml reusable workflow at SHA 1b2d33c4 does not expose
`enable-sonarcloud` or `sonarcloud-organization` inputs (see the
`workflow_call.inputs` schema in the org repo at that pin). GitHub
Actions rejects the entire workflow run at load time when a caller
passes unknown inputs, producing `startup_failure` rather than a real
job run. The cascading effect: the top-level `ci-gate` job never runs,
which means no status is reported for the org ruleset's required
`CI Gate` check, which leaves the PR in `mergeStateStatus: BLOCKED`
indefinitely.

The previous commits (this PR and a follow-up) tried to fix the wrong
problem by changing the value of `sonarcloud-organization` from
'williaby' to 'byronwilliamscpa'. Neither value is recognized; the
inputs themselves are not in the schema.

The PR's stated intent (delegate SonarCloud to the dedicated
sonarcloud.yml caller) is achieved by the absence of any inline
SonarCloud configuration in ci.yml, not by passing flags the reusable
workflow does not expose. Remove both lines entirely.

Surface findings origin: PR #27 self-review CI Gate stuck-required-check
diagnosis. Matches memory entry `project_reusable_input_schema_sha_pin`.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address CodeRabbit's inline comment on PR #27 (pr-validation.yml:164):
the previous version built a single space-separated string and expanded
it unquoted with `# shellcheck disable=SC2086`. While the values
(PYSEC-* IDs) are whitespace and glob-free in practice, the array form
is the idiomatic shell pattern: each `--ignore-vuln` flag and its value
arrives at pip-audit's argv as a discrete element, no word-splitting,
no shellcheck disable needed.

The python heredoc now emits two lines per vuln ID (one for the flag,
one for the value); `mapfile -t IGNORE_ARGS` reads them into the array.
The error-handling branch from the prior commit is preserved: a tomllib
parse failure emits a `::warning::` annotation rather than silently
running pip-audit without ignores.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address CodeRabbit's inline comment on PR #27 (docs/template_feedback.md):
several lines in the newly-added template-feedback entries exceeded the
120-character convention CodeRabbit applies, even though the project's
own `.markdownlint.json` disables MD013/line-length checking.

- Hard-wrap the prose lines in the four new entries (no-build,
  sonar-organization, test-command word-splitting, atheris-3.10 wheel)
  to a 120-char column.
- Convert the long brace-expansion file-path on the no-build entry to
  a bulleted list under a shared parent path; the resulting list is
  more readable and stays well under 120 chars per line.
- Leave the literal pip error message inside the `text` code block
  unwrapped: wrapping inside a fenced code block would corrupt the
  reproduction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@williaby
Copy link
Copy Markdown
Contributor Author

Follow-up: Root cause of stuck CI Gate required check

The earlier "Critical" finding about ci.yml's sonarcloud-organization: 'williaby' was a symptom, not the root cause. Diagnosis on the new push:

The CI workflow run for this PR finished with startup_failure (status: completed, conclusion: startup_failure), not a real job run. GitHub Actions rejected the workflow at load time because ci.yml passed two inputs that are not in the python-ci.yml@1b2d33c4 reusable workflow's schema:

  • enable-sonarcloud: false
  • sonarcloud-organization: 'byronwilliamscpa'

Verified by reading the org workflow's workflow_call.inputs at that SHA - only these inputs are accepted: python-version, python-versions-pr, python-versions-comprehensive, enable-matrix-testing, coverage-threshold, source-directory, test-directory, run-integration-tests, run-security-tests, fail-on-llm-tags, enable-dead-code-check, dead-code-confidence, fail-on-dead-code, fail-on-security-findings, no-build.

When ci.yml startup-fails, its top-level ci-gate: name: CI Gate job never runs, so the org ruleset's required check CI Gate stays Expected — Waiting for status to be reported indefinitely. This matches the memory invariant "Reusable workflows reject unknown with: keys at load time; SHA-pinned callers must match input schema at that exact SHA" (project_reusable_input_schema_sha_pin).

Commits pushed (fast-forward, no history rewrite)

  • 25f42ef fix(ci): remove unrecognized SonarCloud inputs that break CI startup -> deletes both unknown inputs from ci.yml. The PR's stated intent (delegate SonarCloud to the dedicated sonarcloud.yml caller) is achieved by the absence of inline SonarCloud config, not by passing flags the reusable workflow does not expose.

  • 92b2473 style(ci): convert pip-audit IGNORE_ARGS to bash array -> addresses CodeRabbit's inline comment on pr-validation.yml:164. mapfile -t IGNORE_ARGS < <(...) replaces the unquoted string expansion; # shellcheck disable=SC2086 removed.

  • 747b9f9 style(docs): hard-wrap template_feedback prose to 120 chars -> addresses CodeRabbit's docs/template_feedback.md comment. The long brace-expansion file path was restructured into a bulleted list. The literal pip error message inside the text code block is intentionally left unwrapped (wrapping inside fenced code corrupts the reproduction).

Side note: stale Critical finding

My original Critical finding on ci.yml's sonarcloud-organization value was misdirected: I treated it as an org-name mismatch (williaby vs byronwilliamscpa) without checking the reusable workflow's input schema. The earlier "fix" commit (9dc6e0e, change williaby -> byronwilliamscpa) had no functional effect because the entire input was unrecognized. Net result after this batch: both lines deleted entirely. Audit trail in git history is preserved for future reference.

Generated with Claude Code

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.46 2.51 +1.9%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.87 1.87 📉 -0.1%
p95_ms 2.46 2.51 📈 1.9%
p99_ms 2.56 2.60 📈 1.3%
mean_ms 1.43 1.43 📈 0.3%
min_ms 0.06 0.06 ➡️ 0.0%
max_ms 2.64 2.60 📉 -1.5%
throughput_ops 699.91 697.69 📉 -0.3%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.99 1.00 📈 1.3%
avg_throughput_all_benchmarks_ops 1080065.07 1053253.38 📉 -2.5%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

…ter repos

CodeRabbit was configured with `request_changes_workflow: true`, which
makes CodeRabbit submit formal CHANGES_REQUESTED reviews. Combined with
the default GitHub branch protection behavior (any reviewer with write
access blocks merge until their review is dismissed or addressed), this
caused PR #27 to stay in `mergeStateStatus: BLOCKED` after CodeRabbit
filed its second review pass.

Sister repos under ByronWilliamsCPA (audio-processor, fragrance-rater,
cookiecutter-python-template, reference-library) all run with this
setting disabled or omitted (default false). With the setting off,
CodeRabbit findings still appear as inline comments and a review
summary, but the review state is COMMENTED rather than CHANGES_REQUESTED,
so it does not gate merge. Humans and Copilot keep their veto.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@williaby williaby dismissed stale reviews from coderabbitai[bot] and coderabbitai[bot] May 20, 2026 18:17

All actionable findings have been addressed in subsequent commits: bash-array refactor (commit 92b2473) for pr-validation.yml, prose hard-wrap (commit 747b9f9) for template_feedback.md, and the underlying ci.yml startup_failure fix (commit 25f42ef). CodeRabbit config also updated to disable request_changes_workflow (commit 8f9af6c) so future PRs do not block on CR reviews. Dismissing this stale review to clear the merge gate.

@github-actions
Copy link
Copy Markdown

✅ Performance Regression Check

Status: PERFORMANCE OK

Metric Baseline (main) PR Branch Change
p95_ms 2.47 2.44 -0.9%

Threshold: +/-10% allowed regression

✅ Performance is within acceptable range.

Additional Metrics

Metric Baseline PR Change
p50_ms 1.88 1.87 📉 -0.2%
p95_ms 2.47 2.44 📉 -0.9%
p99_ms 2.52 2.55 📈 1.0%
mean_ms 1.41 1.42 📈 0.1%
min_ms 0.06 0.06 📉 -1.8%
max_ms 2.53 2.58 📈 2.3%
throughput_ops 707.07 706.20 📉 -0.1%
total_iterations 500.00 500.00 ➡️ 0.0%
avg_p95_all_benchmarks_ms 0.99 0.97 📉 -1.1%
avg_throughput_all_benchmarks_ops 1074770.55 923058.32 📉 -14.1%
About Performance Regression Testing

This automated check compares p95_ms on this PR against the main branch baseline.

  • Regression Threshold: 10%
  • Warmup Iterations: 5
  • Benchmark Iterations: 50
  • Baseline Source: generated

To reproduce locally:

uv run --frozen  python scripts/benchmark.py --iterations 1000 

@sonarqubecloud
Copy link
Copy Markdown

@williaby williaby merged commit 4055d57 into main May 20, 2026
43 checks passed
williaby pushed a commit that referenced this pull request May 21, 2026
PR #26 review (Important #1 and #2).

#1 (bypass identity mismatch): verify_ws_token returned
    {"email": "anonymous@local", "user_id": "local"}
in dev-bypass mode, while CloudflareAuthMiddleware._get_bypass_user
returned email="dev@localhost" / user_id="dev-user-001". After
batch_is_owned_by was introduced, a batch created over the HTTP
path (creator = dev@localhost) could no longer be subscribed to
over WebSocket (caller = anonymous@local) — ownership check failed.
Align verify_ws_token to return the same identity the HTTP path
uses, and (Suggested #4) emit the same CRITICAL log so production
misconfiguration is loud on every WS upgrade too.

#2 (unhandled network errors): verify_cloudflare_token can raise
httpx.HTTPStatusError / ConnectError / TimeoutException and
json.JSONDecodeError when the JWKS fetch fails. These aren't
subclasses of jwt.InvalidTokenError, so they previously propagated
out of verify_ws_token, closing the socket with 1011 (internal
error) instead of 1008 (policy violation). The HTTP middleware
already handles this with a broad except at cloudflare.py:145-147;
add the matching fallback in the WS path.

#6 (PII in success log): swap user_email out of the success-path
WebSocket connection log for parity with the redacted unauthorized
path.

Tests:
- Updated test_verify_ws_token_bypass_mode (test_websocket.py) +
  test_verify_ws_token_auth_disabled (test_websocket_router.py) to
  assert the dev@localhost / dev-user-001 identity.
- New test_verify_ws_token_swallows_network_errors covering
  httpx.ConnectError → returns None.

Docs:
- SECURITY-FINDINGS.md §6 (Summary of fixes): note that
  sonarcloud.yml has been migrated on main (#27, 4055d57) so the
  SHA-pin from this PR's first commit will be overwritten on merge.
- SECURITY-FINDINGS.md follow-ups: track tightening the
  batch_is_owned_by email fallback once all batches have user_id.

334 passed, 1 skipped (pre-existing). ruff/format clean.
williaby added a commit that referenced this pull request May 21, 2026
* fix(security): close batch IDOR, harden CORS, pin CI actions

- api/batch.py, websocket/router.py: require ownership (created_by_user_id /
  created_by_email) on GET /batch/{id}, GET /batch/job/{id}, and the
  /ws/batch/{id} upgrade; non-owners get 404 / WS_1008_POLICY_VIOLATION so
  batch existence is not leaked.
- core/config.py, main.py: read CORS origins from
  RAG_PROCESSOR_CORS_ALLOWED_ORIGINS; refuse to start on "*" with
  credentials; replace allow_methods/allow_headers wildcards with explicit
  lists.
- auth/cloudflare.py: log CRITICAL on every request while bypass mode
  (cloudflare_enabled=false) is active so a prod misconfig is loud.
- workflows/sonarcloud.yml: pin sonarsource/sonarqube-quality-gate-action
  from @master to v1.2.0 SHA; add harden-runner to both jobs.
- workflows/dependency-review.yml: pin actions/dependency-review-action
  from @v4 to v4.9.0 SHA; add harden-runner.
- SECURITY-FINDINGS.md: full review with severities and follow-ups.

* test(security): cover batch/WS ownership branches; fix ruff format

- ruff format ran across the new ownership condition in
  websocket/router.py; commit the formatter output.
- New tests/unit/test_batch_authz.py exercises _user_owns_batch and the
  owner / non-owner / missing-batch / missing-job / orphaned-job branches of
  GET /batch/{batch_id} and GET /batch/job/{job_id}.
- Added a WebSocket non-owner test alongside the existing
  rejects-unauthenticated / rejects-invalid-batch cases.

Total coverage 81.12% -> 82.76%. api/batch.py coverage 57% -> ~95%,
websocket/router.py 91% -> 96%. SonarCloud "new code coverage" should
now clear the 80% gate.

* ci: re-trigger checks after org workflow update

* security(cors): drop hardcoded http:// dev defaults, fail closed

SonarCloud python:S5332 (correctly) flagged the previous
cors_allowed_origins default list of `http://localhost:*` URLs as
insecure plaintext origins baked into production source. The defaults
also weakened the secure-by-default posture the rest of the PR was
aiming for: a misconfigured prod deploy would silently trust dev
origins.

- core/config.py: default cors_allowed_origins to an empty list. Empty
  combined with the existing wildcard guard in main.py means the
  backend fails closed; CORS preflights are denied until the operator
  sets RAG_PROCESSOR_CORS_ALLOWED_ORIGINS explicitly.
- .env.example: document the recommended local-dev value so reviewers
  / new contributors aren't stuck guessing what the dev origins are.
- SECURITY-FINDINGS.md §2.2: updated to reflect the new default and
  to note the SonarCloud rule that's now resolved.

* test(cors): set dev origins in conftest after empty-default change

The previous commit moved cors_allowed_origins to empty-by-default
(SonarCloud S5332 + secure-by-default), which broke the existing
TestCORSHeaders.test_cors_headers_present_on_get integration test:
the test sends Origin: http://localhost:3000 and asserts the
Access-Control-Allow-Origin header comes back, but with no origins
configured the middleware (correctly) returns no CORS headers.

CORSMiddleware reads allow_origins at app construction, so the env
var has to be set in conftest.py before the app module is imported -
the same pattern already used for RAG_PROCESSOR_RATE_LIMITING_ENABLED
and RAG_PROCESSOR_CLOUDFLARE_ENABLED.

* style(batch): use Annotated[] form for FastAPI Depends parameters

SonarCloud python:S8410 flagged the legacy
`user: CloudflareUser = Depends(get_current_user)` form on the two
endpoints added in this PR. The Annotated[] form is FastAPI's
recommended pattern and (per Sonar) avoids subtle issues with mutable
default values in function signatures.

No behavior change; tests/unit/test_batch_authz.py still passes its
mocked user via the same kwarg name.

* security(authz): consolidate ownership check + redact PII from logs

Addresses 6 CodeRabbit review comments on PR #26.

1. (security) src/rag_processor/websocket/router.py: the WS ownership
   check used `owns_by_id OR owns_by_email`, so a caller whose email
   coincidentally matched the batch owner's email could authenticate
   as the owner even with a different Cloudflare user_id. The REST
   path in api/batch.py had the correct user_id-takes-precedence
   logic; the two paths could not diverge silently.

   Extract the helper to auth/dependencies.py::batch_is_owned_by
   (keyword-only requester_user_id / requester_email so both the REST
   path with a CloudflareUser and the WS path with a verify-token
   dict can call it). Both endpoints now share the same enforcement.

2. (privacy) api/batch.py + websocket/router.py: unauthorized-access
   warnings previously logged owner_email, requester_email, and the
   requester user_id. owner_email lets an attacker probing batch IDs
   harvest owner identities from logs; requester_email is PII we
   don't need for incident response when we already have
   requester_user_id. Strip both fields; keep batch_id / job_id /
   requester_user_id only.

3. (tests) tests/unit/test_batch_authz.py: add
   test_user_id_mismatch_does_not_fall_back_to_email regression
   covering the bypass described above.

4. (tests) tests/unit/test_websocket_router.py: add the WebSocket
   variant — same email, mismatched user_id, assert close with
   WS_1008_POLICY_VIOLATION and connection_manager.connect never
   called.

5. (style) SECURITY-FINDINGS.md §"Summary of fixes applied in this
   PR": replace the wide markdown table with a bulleted list so no
   line exceeds the project's 120-char limit.

Tests: 333 passed, 1 skipped (pre-existing). ruff check + format
both clean.

* security(ws): align bypass identity + catch JWKS network errors

PR #26 review (Important #1 and #2).

#1 (bypass identity mismatch): verify_ws_token returned
    {"email": "anonymous@local", "user_id": "local"}
in dev-bypass mode, while CloudflareAuthMiddleware._get_bypass_user
returned email="dev@localhost" / user_id="dev-user-001". After
batch_is_owned_by was introduced, a batch created over the HTTP
path (creator = dev@localhost) could no longer be subscribed to
over WebSocket (caller = anonymous@local) — ownership check failed.
Align verify_ws_token to return the same identity the HTTP path
uses, and (Suggested #4) emit the same CRITICAL log so production
misconfiguration is loud on every WS upgrade too.

#2 (unhandled network errors): verify_cloudflare_token can raise
httpx.HTTPStatusError / ConnectError / TimeoutException and
json.JSONDecodeError when the JWKS fetch fails. These aren't
subclasses of jwt.InvalidTokenError, so they previously propagated
out of verify_ws_token, closing the socket with 1011 (internal
error) instead of 1008 (policy violation). The HTTP middleware
already handles this with a broad except at cloudflare.py:145-147;
add the matching fallback in the WS path.

#6 (PII in success log): swap user_email out of the success-path
WebSocket connection log for parity with the redacted unauthorized
path.

Tests:
- Updated test_verify_ws_token_bypass_mode (test_websocket.py) +
  test_verify_ws_token_auth_disabled (test_websocket_router.py) to
  assert the dev@localhost / dev-user-001 identity.
- New test_verify_ws_token_swallows_network_errors covering
  httpx.ConnectError → returns None.

Docs:
- SECURITY-FINDINGS.md §6 (Summary of fixes): note that
  sonarcloud.yml has been migrated on main (#27, 4055d57) so the
  SHA-pin from this PR's first commit will be overwritten on merge.
- SECURITY-FINDINGS.md follow-ups: track tightening the
  batch_is_owned_by email fallback once all batches have user_id.

334 passed, 1 skipped (pre-existing). ruff/format clean.

---------

Co-authored-by: Claude <noreply@anthropic.com>
@coderabbitai coderabbitai Bot mentioned this pull request May 22, 2026
3 tasks
@williaby williaby deleted the claude/fix-sonarcloud-ci-issues-9hioH branch May 24, 2026 00:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci dependencies documentation Improvements or additions to documentation python tests

Projects

None yet

4 participants