Competitor Parity Testing Guide

Audience: engineers and product owners who need to confirm that the Stella Ops scanner keeps pace with industry-standard tools on coverage, accuracy, and performance — and who maintain the parity harness, fixtures, and drift alerts.

This document describes Stella Ops’ competitor parity testing methodology, which ensures the scanner maintains feature parity and performance competitiveness with industry-standard tools.

Overview

Parity testing compares Stella Ops against three primary competitors:

ToolTypePrimary Function
Syft (Anchore)SBOM GeneratorPackage extraction and SBOM creation
Grype (Anchore)Vulnerability ScannerCVE detection using Syft SBOMs
Trivy (Aqua)Multi-scannerSBOM + vulnerability + secrets + misconfig

Goals

  1. Prevent regression: Detect when StellaOps falls behind competitors on key metrics
  2. Track trends: Monitor parity metrics over time to identify drift patterns
  3. Guide development: Use competitor gaps to prioritize feature work
  4. Validate claims: Ensure marketing claims are backed by measurable data

Fixture Set

Tests run against a standardized set of container images that represent diverse workloads:

Quick Set (Nightly)

Full Set (Weekly)

All quick set images plus:

Metrics Collected

SBOM Metrics

MetricDescriptionTarget
Package CountTotal packages detected≥95% of Syft
PURL CompletenessPackages with valid PURLs≥98%
License DetectionPackages with license info≥90%
CPE MappingPackages with CPE identifiers≥85%

Vulnerability Metrics

MetricDescriptionTarget
RecallCVEs found vs. union of all scanners≥95%
PrecisionTrue positives vs. total findings≥90%
F1 ScoreHarmonic mean of precision/recall≥92%
Severity DistributionBreakdown by Critical/High/Medium/LowMatch competitors ±10%

Latency Metrics

MetricDescriptionTarget
P50Median scan time≤1.5x Grype
P9595th percentile scan time≤2x Grype
P9999th percentile scan time≤3x Grype
Time-to-First-SignalTime to first vulnerability found≤Grype

Error Handling Metrics

ScenarioExpected Behavior
Malformed manifestGraceful degradation with partial results
Network timeoutClear error message; cached feed fallback
Large image (>5GB)Streaming extraction; no OOM
Corrupt layerSkip layer; report warning
Missing base layerReport incomplete scan
Registry auth failureClear auth error; suggest remediation
Rate limitingBackoff + retry; clear message

Running Parity Tests

Locally

# Build the parity test project
dotnet build src/__Tests/parity/StellaOps.Parity.Tests

# Run quick fixture set
dotnet test src/__Tests/parity/StellaOps.Parity.Tests \
  -e PARITY_FIXTURE_SET=quick \
  -e PARITY_OUTPUT_PATH=./parity-results

# Run full fixture set
dotnet test src/__Tests/parity/StellaOps.Parity.Tests \
  -e PARITY_FIXTURE_SET=full \
  -e PARITY_OUTPUT_PATH=./parity-results

Prerequisites

Ensure competitor tools are installed and in PATH:

# Install Syft
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin v1.9.0

# Install Grype
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin v0.79.3

# Install Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin v0.54.1

CI/CD

The dedicated parity workflows (parity-tests.yml, competitor-parity.yml, benchmark-vs-competitors.yml) have been archived to .gitea/workflows-archived/; competitor benchmarking currently runs through .gitea/workflows/dotnet-benchmarks.yml. The intended cadence is:

Results are stored as workflow artifacts and optionally pushed to Prometheus.

Drift Detection

The parity system includes automated drift detection that alerts when StellaOps falls behind competitors:

Thresholds

MetricThresholdTrend Period
SBOM Completeness>5% decline3 days
Vulnerability Recall>5% decline3 days
Latency vs Grype>10% increase3 days
PURL Completeness>5% decline3 days
F1 Score>5% decline3 days

Alert Severity

SeverityConditionAction
Low1-1.5x thresholdMonitor
Medium1.5-2x thresholdInvestigate within sprint
High2-3x thresholdPrioritize fix
Critical>3x thresholdImmediate action required

Analyzing Drift

# Run drift analysis on stored results
dotnet run --project src/__Tests/parity/StellaOps.Parity.Tests \
  -- analyze-drift \
  --results-path ./parity-results \
  --threshold 0.05 \
  --trend-days 3

Result Storage

JSON Format

Results are stored as timestamped JSON files:

parity-results/
├── parity-20250115T020000Z-abc123.json
├── parity-20250116T020000Z-def456.json
└── parity-20250122T000000Z-ghi789.json  # Weekly

Retention Policy

Prometheus Export

Results can be exported to Prometheus for dashboarding:

stellaops_parity_sbom_completeness_ratio{run_id="..."} 0.97
stellaops_parity_vuln_recall{run_id="..."} 0.95
stellaops_parity_latency_p95_ms{scanner="stellaops",run_id="..."} 1250

InfluxDB Export

For InfluxDB time-series storage:

parity_sbom,run_id=abc123 completeness_ratio=0.97,matched_count=142i 1705280400000000000
parity_vuln,run_id=abc123 recall=0.95,precision=0.92,f1=0.935 1705280400000000000

Competitor Version Tracking

Competitor tools are pinned to specific versions to ensure reproducibility:

ToolCurrent VersionLast Updated
Syft1.9.02025-01-15
Grype0.79.32025-01-15
Trivy0.54.12025-01-15

Updating Versions

  1. Update the pinned version in the parity workflow (currently .gitea/workflows-archived/parity-tests.yml)
  2. Update the version constants in src/__Tests/parity/StellaOps.Parity.Tests/ParityHarness.cs
  3. Run the full parity test to establish a new baseline
  4. Document the version change in the sprint execution log

Troubleshooting

Common Issues

Syft not found

Error: Syft executable not found in PATH

Solution: Install Syft or set SYFT_PATH environment variable.

Grype DB outdated

Warning: Grype vulnerability database is 7+ days old

Solution: Run grype db update to refresh the database.

Image pull rate limit

Error: docker pull rate limit exceeded

Solution: Use authenticated Docker Hub credentials or local registry mirror.

Test timeout

Error: Test exceeded 30 minute timeout

Solution: Increase timeout or use quick fixture set.

Debug Mode

Enable verbose logging:

dotnet test src/__Tests/parity/StellaOps.Parity.Tests \
  -e PARITY_DEBUG=true \
  -e PARITY_KEEP_OUTPUTS=true

Architecture

src/__Tests/parity/StellaOps.Parity.Tests/
├── StellaOps.Parity.Tests.csproj    # Project file
├── ParityTestFixtureSet.cs           # Container image fixtures
├── ParityHarness.cs                  # Scanner execution harness
├── SbomComparisonLogic.cs            # SBOM comparison
├── VulnerabilityComparisonLogic.cs   # Vulnerability comparison
├── LatencyComparisonLogic.cs         # Latency comparison
├── ErrorModeComparisonLogic.cs       # Error handling comparison
└── Storage/
    ├── ParityResultStore.cs          # Time-series storage
    └── ParityDriftDetector.cs        # Drift detection

See Also