Skip to content

fix(score): keep scoring other frameworks when one has no weight - #197

Merged
matthyx merged 1 commit into
kubescape:mainfrom
VISHNU0906:fix/score-continue-after-unscorable-framework
Nov 10, 2026
Merged

matthyx merged 1 commit into
kubescape:mainfrom
VISHNU0906:fix/score-continue-after-unscorable-framework

Conversation

@VISHNU0906

Copy link
Copy Markdown
Contributor

Hi @matthyx, I found this while reading the scoring code after #195.

CalculatePostureReportV2 returns as soon as it hits a framework with a zero worst-case score that isn't all-irrelevant, for example a framework whose controls were all skipped (not evaluated, missing configuration, manual review). Two things follow:

  • the frameworks after it and SummaryDetails.Score are never scored
  • SetPostureReportComplianceScores returns that error before setting any compliance score, so every framework stays at 0, SummaryDetails.ComplianceScore is 0 and each control's ComplianceScore stays nil (GetComplianceScore() gives -1)

Kubescape only logs "failed to calculate score" and carries on, so one framework like that (say, all of its controls marked not evaluated because the resources couldn't be listed) zeroes the compliance scores of the whole scan. The -1 gauges in kubescape/kubescape#4017 look like the same root cause, seen from the printer side.

This change keeps going after an unscorable framework, still sets all compliance scores, and returns the framework errors joined at the end. The unscorable framework still gets a score of 0 and an error, as before, so the existing empty and skipped framework tests pass unchanged. I also dropped the trailing \n from that error message, since the messages are now joined.

Tests: score/unscorable_framework_test.go puts a skipped-only framework in front of the existing mock report and checks that the other frameworks, the summary and the control compliance scores come out the same as in the plain mock case, plus a case with two empty frameworks to check both are reported. Both fail on main. go vet ./..., go test -race ./... and go build ./... pass, and golangci-lint shows no new findings. I also built kubescape against this branch and ran its opaprocessor, score and cautils tests.

CalculatePostureReportV2 returned on the first framework with a zero
worst-case score, so the frameworks after it and the summary were never
scored. SetPostureReportComplianceScores then returned that error before
setting any compliance score, leaving every framework at 0 and every
control without a compliance score.

Score the remaining frameworks and the summary, set the compliance
scores, and return all framework errors joined at the end.

Signed-off-by: KVR Vishnu <46535652+VISHNU0906@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Nov 10, 2026

Copy link
Copy Markdown

Important

  • Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

Run configuration

  • Source mode: Auto
  • Repository: Unavailable
  • Branch: Unavailable
  • File: No configuration file from this repository applied
  • Commit: Unavailable
  • Layers: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: b903a044-9522-4c64-8599-4cd0397180da
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

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

@matthyx matthyx 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.

Review of head 1b93c457 against main (a2dfde9a).

Verdict: approve.

Need. In main, CalculatePostureReportV2 returns on the first framework whose worst-case score is 0 and not all-irrelevant. This leaves later frameworks and SummaryDetails.Score unscored. SetPostureReportComplianceScores then returns before setting any compliance score. The problem is real and this is the same root-cause family as #158, which fixed only the all-irrelevant case.

History. I searched the PRs and issues in this repo for score, wcs and unscorable terms. I found no duplicate or superseding PR. #158 (merged) is the narrower predecessor. #164 and #186 are unrelated closed score PRs and raised no objection to this approach. The search tool has limits, so this is not proof that no overlap exists.

Soundness.

  • The loop now collects errors and continues, and errors.Join returns them at the end. The unscorable framework still gets score 0 and an error, so existing behaviour and the existing empty/skipped tests are preserved.
  • SetPostureReportComplianceScores now sets all compliance scores and returns the error last.
  • Dropping the trailing \n is sensible now that the messages are joined.
  • Callers that only check err != nil are unaffected. Callers that previously saw scores unset on error now get them populated.

Blockers. None.

Validation.

  • With the PR's score.go: go vet ./score/ passes and go test -race ./score/ passes.
  • With score.go reverted to main and the PR's tests kept, both new tests fail. The failures are control compliance scores being nil and empty-b missing from the error.
  • I did not rebuild kubescape against this branch. The CI build check passes, and DCO and GitGuardian pass.
  • The CodeRabbit check was skipped, and it has no reviews on this PR.

I confirmed the PR was open, not a draft, and unchanged at that head just before submitting.

@matthyx
matthyx merged commit 142c5dd into kubescape:main Nov 10, 2026
5 checks passed
@matthyx matthyx moved this to To Archive in KS PRs tracking Nov 10, 2026
matthyx pushed a commit to kubescape/kubescape that referenced this pull request Nov 11, 2026
…able framework (#4750)

* fix(score): bump opa-utils to v0.0.318 so one unscorable framework no longer blanks every score

opa-utils v0.0.318 (kubescape/opa-utils#197) keeps scoring the remaining
frameworks, the summary and all compliance scores when a framework has no
weight, instead of returning on the first one. Add a test through
ScoreWrapper.Calculate that fails on v0.0.317.

Signed-off-by: KVR Vishnu <46535652+VISHNU0906@users.noreply.github.com>

* test(score): check the namespace summary built from the new scores

Signed-off-by: KVR Vishnu <46535652+VISHNU0906@users.noreply.github.com>

---------

Signed-off-by: KVR Vishnu <46535652+VISHNU0906@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To Archive

Development

Successfully merging this pull request may close these issues.

2 participants