Skip to content

Feat/support comp quality category#651

Merged
riteshnoronha merged 8 commits into
interlynk-io:mainfrom
viveksahu26:feat/support_comp_quality_category
May 8, 2026
Merged

Feat/support comp quality category#651
riteshnoronha merged 8 commits into
interlynk-io:mainfrom
viveksahu26:feat/support_comp_quality_category

Conversation

@viveksahu26
Copy link
Copy Markdown
Collaborator

@viveksahu26 viveksahu26 commented Apr 1, 2026

This PR adds following changes:

  • add supports for comp_quality features
  • updated docs
  • performed testing.

Demo:

  • With Interlynk API
$ go run main.go score ../sbomasm/samples/cdx/sbomqs-cdx.json --url="https://api.interlynk.io/" --api-key="$INTERLYNK_SECURITY_TOKEN"
  • With Local Interlynk API
$ go run main.go score ../sbomasm/samples/cdx/sbomqs-cdx.json --url="http://127.0.0.1:3000" --api-key="$API_KEY"
  • Score category-wise:
$ go run main.go score --category cinfo,identification,integrity ../sbomasm/samples/cdx/sbomqs-cdx.json --url="https://api.interlynk.io/" --api-key="$INTERLYNK_SECURITY_TOKEN"
SBOM Quality Score: 3.8/10.0	 Grade: F	Components: 210 	 EngineVersion: 6	File: ../sbomasm/samples/cdx/sbomqs-cdx.json
Category Breakdown:
+-------------------+--------+----------+-------+
|     CATEGORY      | WEIGHT |  SCORE   | GRADE |
+-------------------+--------+----------+-------+
| Component Quality | 40.0%  | 6.0/10.0 | D     |
+-------------------+--------+----------+-------+
| Identification    | 40.0%  | 9.4/10.0 | A     |
+-------------------+--------+----------+-------+
| Integrity         | 60.0%  | 0.0/10.0 | F     |
+-------------------+--------+----------+-------+

Score Breakdown:
+------------------------+--------------------------------+-----------+-----------------------+
|        CATEGORY        |            FEATURE             |   SCORE   |         DESC          |
+------------------------+--------------------------------+-----------+-----------------------+
| Component Quality      | comp_eol_eos                   | 0.0/10.0  | N/A                   |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_malicious                 | 0.0/10.0  | N/A                   |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_vuln_sev_critical         | 0.0/10.0  | N/A                   |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_kev                       | 0.0/10.0  | N/A                   |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_purl_valid                | 9.2/10.0  | add to 16 components  |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_cpe_valid                 | 2.7/10.0  | add to 154 components |
+------------------------+--------------------------------+-----------+-----------------------+
| Identification (40.0%) | comp_with_name (16.0%)         | 10.0/10.0 | complete              |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_with_version (14.0%)      | 8.4/10.0  | add to 34 components  |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_with_local_id (10.0%)     | 10.0/10.0 | complete              |
+------------------------+--------------------------------+-----------+-----------------------+
| Integrity (60.0%)      | comp_with_strong_checksums     | 0.0/10.0  | add to 210 components |
|                        | (30.0%)                        |           |                       |
+                        +--------------------------------+-----------+-----------------------+
|                        | comp_with_weak_checksums       | 0.0/10.0  | no checksums found    |
|                        | (24.0%)                        |           |                       |
+                        +--------------------------------+-----------+-----------------------+
|                        | sbom_signature (6.0%)          | 0.0/10.0  | add signature         |
+------------------------+--------------------------------+-----------+-----------------------+


Love to hear your feedback https://forms.gle/anFSspwrk7uSfD7Q6

Copilot AI review requested due to automatic review settings April 1, 2026 15:16
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 adds v2 scoring support for the “Component Quality” (compinfo/cinfo) category by optionally fetching findings from the Interlynk Component Quality API and feeding them into comprehensive feature evaluators.

Changes:

  • Introduces interlynkapi client/types for batching /api/v1/doctor/check requests and merging findings.
  • Plumbs a new catalog.EvalInput (SBOM doc + optional ComponentQuality results) through comprehensive evaluation and updates extractor signatures accordingly.
  • Implements real scoring logic for Component Quality extractors and adds cinfo as an alias for compinfo; adds CLI flags (--url, --api-key) and config plumbing.

Reviewed changes

Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
pkg/scorer/v2/score/score.go Builds EvalInput, conditionally calls Interlynk API, and passes EvalInput into comprehensive evaluation.
pkg/scorer/v2/registry/registry.go Adds cinfo alias for selecting the Component Quality category.
pkg/scorer/v2/extractors/vulnerability.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/vulnerability_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/structural.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/structural_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/provenance.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/provenance_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/licensing.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/licensing_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/integrity.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/integrity_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/identification.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/identification_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/completeness.go Updates comprehensive extractor signatures to accept context + EvalInput.
pkg/scorer/v2/extractors/completeness_test.go Updates tests to call new extractor signatures with EvalInput.
pkg/scorer/v2/extractors/compquality.go Implements scoring for Component Quality features based on fetched findings.
pkg/scorer/v2/config/config.go Adds Interlynk URL/API key fields to v2 config.
pkg/scorer/v2/compr/compr.go Switches comprehensive evaluation pipeline to pass EvalInput into feature evaluators.
pkg/scorer/v2/catalog/features.go Introduces EvalInput and changes ComprFeatEval signature to accept context + EvalInput.
pkg/interlynkapi/types.go Adds request/response and merged-result types for the Interlynk Component Quality API.
pkg/interlynkapi/map.go Maps SBOM components into API payload objects.
pkg/interlynkapi/client.go Implements HTTP client with batching + 429 retry handling; merges findings across batches.
pkg/interlynkapi/client_test.go Adds unit tests for batching, retries, and auth header behavior.
pkg/interlynkapi/testhelpers_test.go Adds test helper for generating fake SBOM components.
pkg/engine/score.go Plumbs Interlynk URL/API key from engine params into v2 config.
cmd/score.go Adds CLI flags (--url, --api-key) and wires them into engine params.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread pkg/interlynkapi/client.go Outdated

// Adjust Finding.Index by batch offset so indices are globally consistent.
for _, f := range dr.Findings {
globalIdx := start + f.Index
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

The merge logic keys findings by the computed globalIdx, but the Finding.Index field itself is not updated. This contradicts the comment (“Adjust Finding.Index…”) and can be misleading for any downstream code that reads Finding.Index expecting it to be a global component index. Either update f.Index before storing it, or change the comment/type contract to clarify that Index remains batch-local and only the map key is global.

Suggested change
globalIdx := start + f.Index
globalIdx := start + f.Index
f.Index = globalIdx

Copilot uses AI. Check for mistakes.

case "compinfo":
case "compinfo", "cinfo":
finalCats = append(finalCats, CatComponentQualityInfoSpec)
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

Adding the "cinfo" alias makes it easier to select the Component Quality category, but Component Quality feature keys (e.g. comp_eol_eos, comp_malicious, comp_kev, etc.) are not present in CompKeyToEvaluatingFunction, which is used when building categories from YAML config. If a config enables these features, Evaluate will be nil and can lead to a runtime panic when the feature is evaluated. Add these keys to the mapping (or handle missing evaluators explicitly when loading YAML).

Suggested change
finalCats = append(finalCats, CatComponentQualityInfoSpec)
// Component Quality category is currently missing evaluator mappings for its features.
// To avoid a potential nil-function panic at evaluation time, skip enabling it here.
log.Warn("Skipping unsupported Component Quality category; evaluator mappings not available",
zap.String("category", category),
)
continue

Copilot uses AI. Check for mistakes.
Comment thread pkg/scorer/v2/extractors/compquality.go Outdated
Comment on lines +30 to +40
// CompWithEOSOrEOL: components no longer maintained or declared end-of-life.
// Maps to findings with domain "lifecycle" or check_code prefix "EOL-"/"EOS-".
func CompWithEOSOrEOL(_ context.Context, input catalog.EvalInput) catalog.ComprFeatScore {
if input.ComponentQuality == nil {
return formulae.ScoreCompNAA()
}
return scoreByFindings(input.ComponentQuality, func(f interlynkapi.Finding) bool {
return f.Domain == "lifecycle" ||
strings.HasPrefix(f.CheckCode, "EOL-") ||
strings.HasPrefix(f.CheckCode, "EOS-")
}, "components are maintained")
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

These extractors now implement real scoring logic based on input.ComponentQuality findings, but there are no unit tests validating the mapping/predicate logic or the scoreByFindings behavior (e.g., affected component counting, TotalComponents=0 handling, nil ComponentQuality => N/A). Adding focused tests with a small synthetic ComponentQualityResult would help prevent regressions as API domains/check codes evolve.

Copilot uses AI. Check for mistakes.
Comment on lines +221 to +224
if cfg.InterlynkURL != "" && isCompQualityPresent(catal) {
client := interlynkapi.NewClient(cfg.InterlynkURL, cfg.InterlynkAPIKey)
qResult, err := client.FetchComponentQuality(ctx, doc.Components())
if err != nil {
Copy link

Copilot AI Apr 1, 2026

Choose a reason for hiding this comment

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

SBOMEvaluation’s doc comment says cfg is “not currently used in evaluation logic”, but cfg.InterlynkURL/InterlynkAPIKey are now used to optionally fetch Component Quality results. Update the parameter documentation to reflect the new behavior so library callers aren’t surprised by the network call dependency on cfg.

Copilot uses AI. Check for mistakes.
@viveksahu26 viveksahu26 requested a review from riteshnoronha May 7, 2026 17:27
@riteshnoronha riteshnoronha merged commit 3ab6233 into interlynk-io:main May 8, 2026
8 checks passed
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.

4 participants