# Unified Trust Score > **Ownership:** Signals Guild / Platform Guild > **Services:** `StellaOps.Signals.UnifiedScore` > **API:** `POST /api/v1/score/evaluate`, `GET /api/v1/score/{id}/replay` > **CLI:** `stella score compute|explain|replay|verify`, `stella gate score evaluate` ## Overview The Unified Trust Score is a facade over existing EWS (Evidence-Weighted Score) and Determinization systems. It provides a single API for computing risk scores, uncertainty metrics, and score replay proofs without replacing any underlying scoring logic. --- ## How It Works 1. **Input** — Caller provides signal values (reachability, runtime, exploit, etc.) and optional context (CVE ID, PURL, SBOM ref) 2. **EWS computation** — The facade delegates to `IEvidenceWeightedScoreCalculator` using weights from a versioned manifest 3. **Entropy calculation** — `IUncertaintyScoreCalculator` computes the unknowns fraction (U) from signal presence/absence 4. **Conflict detection** — `IConflictDetector` identifies contradictory signals 5. **Delta calculation** — For missing signals, computes potential score impact ranges 6. **Result assembly** — Returns `UnifiedScoreResult` combining all outputs --- ## The Unknowns Fraction (U) The `UnknownsFraction` exposes how much of the score depends on absent data: ``` U = 1 - (weighted_present_signals / total_weight) ``` ### Unknowns Bands | U Range | Band | Meaning | Recommended Action | |---------|------|---------|-------------------| | 0.0 – 0.2 | **Complete** | All signals present | Automated decisions safe | | 0.2 – 0.4 | **Adequate** | Sufficient signal coverage | Automated decisions safe | | 0.4 – 0.6 | **Sparse** | Signal gaps exist | Manual review recommended | | 0.6 – 1.0 | **Insufficient** | Critical data missing | Block until more signals arrive | Band thresholds align with Determinization configuration: - `RefreshEntropyThreshold: 0.40` — triggers signal refresh attempt - `ManualReviewEntropyThreshold: 0.60` — requires human review --- ## Delta-If-Present When signals are absent, the facade calculates how the score would change if each missing signal were provided: ```json { "signal": "reachability", "min_impact": -15, "max_impact": 8, "weight": 0.30, "description": "If reachability confirmed as not-reachable, score decreases by up to 15" } ``` This helps operators prioritize which signals to gather first. --- ## Weight Manifests EWS weights are stored in versioned JSON files under `etc/weights/`: ``` etc/weights/v2026-01-22.weights.json ``` Manifests are: - **Immutable** once published - **Content-addressed** via SHA-256 hash - **Pinnable** by policy rules via `weights_ref` - **Auditable** — the manifest version and hash are included in every score result See [Scoring Algebra §4](../../technical/scoring-algebra.md) for the manifest schema. --- ## API Endpoints | Method | Path | Purpose | |--------|------|---------| | `POST` | `/api/v1/score/evaluate` | Compute unified score | | `GET` | `/api/v1/score/{scoreId}` | Retrieve previously computed score | | `GET` | `/api/v1/score/weights` | List weight manifest versions | | `GET` | `/api/v1/score/weights/{version}` | Get specific manifest | | `GET` | `/api/v1/score/weights/effective` | Get effective manifest for a date | | `GET` | `/api/v1/score/{scoreId}/replay` | Fetch signed replay proof | | `POST` | `/api/v1/score/verify` | Verify a replay log | ### Evaluate Request ```json { "cve_id": "CVE-2024-1234", "purl": "pkg:npm/lodash@4.17.0", "signals": { "reachability": 0.9, "runtime": 0.7, "exploit": 0.3, "backport": 0.0, "source": 0.5, "mitigation": 0.0 }, "options": { "include_breakdown": true, "include_delta": true, "weight_set_id": "v2026-01-22" } } ``` ### Evaluate Response (key fields) ```json { "score_id": "score_a1b2c3d4e5f67890", "score_value": 72, "bucket": "ScheduleNext", "unknowns_fraction": 0.15, "unknowns_band": "Complete", "weight_manifest": { "version": "v2026-01-22", "content_hash": "sha256:..." }, "ews_digest": "sha256:...", "determinization_fingerprint": "sha256:...", "computed_at": "2026-01-23T10:00:00Z" } ``` --- ## CLI Commands ### `stella score compute` Compute a unified score from signal values: ```bash stella score compute \ --finding-id CVE-2024-1234@pkg:npm/lodash@4.17.0 \ --cvss 7.5 --epss 0.15 \ --reachability 0.9 --runtime 0.7 \ --format table ``` ### `stella score explain` Show a detailed breakdown of a score: ```bash stella score explain CVE-2024-1234@pkg:npm/lodash@4.17.0 ``` ### `stella score replay` Fetch the signed replay proof for a previously computed score: ```bash stella score replay score_a1b2c3d4e5f67890 ``` ### `stella score verify` Re-execute the computation and verify it matches the original: ```bash stella score verify score_a1b2c3d4e5f67890 ``` ### `stella gate score evaluate` (enhanced) Existing gate command with new flags: ```bash stella gate score evaluate \ --finding-id CVE-2024-1234@pkg:npm/lodash \ --cvss 7.5 --epss 0.15 \ --show-unknowns --show-deltas \ --weights-version v2026-01-22 ``` ### `stella gate score weights` Manage weight manifests: ```bash stella gate score weights list stella gate score weights show v2026-01-22 stella gate score weights diff v2026-01-22 v2026-02-01 ``` --- ## Score Replay and Verification Every computed score can produce a **replay proof** — a DSSE-signed attestation (payload type `application/vnd.stella.score+json`) that records: 1. Canonical input hashes (SBOM, VEX, etc.) 2. Transform versions applied (canonicalization, normalization, decay) 3. Step-by-step algebra decisions (signal × weight = contribution) 4. Final score and metadata Replay proofs enable: - **Independent verification** — auditors re-execute the computation - **Transparency logging** — optional anchoring to Rekor for non-repudiation - **OCI storage** — proofs stored as OCI referrers ("StellaBundle" pattern) --- ## Troubleshooting ### High Unknowns Fraction (U > 0.6) **Symptom:** Score shows "Insufficient" band, decisions are blocked. **Causes:** - Missing reachability analysis (run `stella scan` with `--reachability`) - No VEX data available (check VEX feed configuration) - Runtime observations not collected (configure runtime agent) **Resolution:** 1. Run `stella score explain ` to see which signals are missing 2. Use `--show-deltas` to understand which signals would have the most impact 3. Prioritize gathering signals with the highest weight × delta ### Score Disagrees with CVSS **Symptom:** EWS score is much lower than expected from CVSS alone. **Explanation:** EWS incorporates reachability, runtime, backport, and mitigation signals that CVSS does not. A high-CVSS vulnerability that is not reachable or already mitigated will have a lower EWS score. **Resolution:** Run `stella score explain` to see the per-dimension breakdown and understand which signals are reducing the score. ### Replay Verification Fails **Symptom:** `stella score verify` reports `score_matches: false`. **Causes:** - Weight manifest version changed between compute and verify - Signal inputs were modified after scoring - Non-determinism in signal providers (check for time-dependent signals) **Resolution:** 1. Pin the weight manifest version in the verify request 2. Ensure canonical inputs match (compare SHA-256 hashes) 3. Check the `differences` field in the verify response for specific mismatches