# Serial Alice Trust Score Specification v1.1

**Date:** 2026-05-30
**Status:** Public · Stable
**Canonical URL:** https://api.serialalice.pt/docs/trust-score-spec
**Contact:** trust@serialalice.pt

---

## Purpose

The Trust Score is a deterministic, publicly auditable number that expresses
how many independent layers of physical evidence support an energy certificate.
It is not a quality rating, not a self-reported claim, and not chosen by Serial
Alice on a per-certificate basis. It is computed from evidence present in the
certificate payload using the fixed table below.

Anyone can reproduce any score given the certificate's evidence fields.

---

## The Independence Principle

Each layer earns points because it represents evidence that **cannot be forged
by the same adversary** that could forge another layer.

- A software-level attacker can manipulate NVML telemetry — but cannot forge a
  TEE quote signed by AMD silicon.
- A hardware-level attacker who controls the physical machine can forge NVML
  readings — but cannot fake a Polygon anchor that was recorded before the
  attack happened.
- A cloud provider who controls the hypervisor can manipulate RAPL counters —
  but cannot retroactively alter a Merkle root already included in a block.

Layers are chosen so that compromising multiple layers simultaneously requires
progressively more powerful, implausible, and expensive adversaries. A score
of 0.80+ means forging the certificate would require simultaneous control of
the GPU hardware, the CPU's power counters, the hardware TEE, and the Ethereum
network.

---

## Scoring Table

| Layer                | Points | Justification |
|----------------------|--------|---------------|
| NVML                 | +0.20  | Physical GPU power sensor. Cannot be fabricated in software without kernel access plus a compromised NVML driver. Cross-checked by RAPL. |
| RAPL (CPU + DRAM)    | +0.25  | Two physically independent hardware domains: the CPU package energy counter and the DRAM energy counter. Each is a separate measurement interface in the CPU's MSR subsystem — a software attacker who controls NVML cannot also forge both RAPL domains without ring-0 MSR write access. Split: CPU package (+0.15) and DRAM domain (+0.10). The higher weight reflects that two independent sensors are present, not one. |
| Signed Exporter      | +0.15  | Ed25519 signature over raw bytes at the exact moment of capture. Any post-hoc modification of the energy number invalidates the signature. The signing key is ephemeral — a different key per measurement session. The machine fingerprint (DMI board serial, CPU model, platform UUID) is captured inside the signed payload, binding the measurement to a specific physical machine without requiring a separate scoring layer. |
| Machine Fingerprint  | +0.00  | Folded into Signed Exporter. The fingerprint is captured and signed inside the exporter payload, so it is not independently verifiable — the same Ed25519 signature covers it. Scoring it separately would double-count the same evidence boundary. It is still present in every certificate's `evidence` field for auditing. |
| TEE Quote            | +0.20  | Hardware-rooted attestation (AMD SEV-SNP, AWS Nitro, or Intel TDX). The operator cannot forge this without breaking the silicon's root of trust. The quote proves that measurement code ran inside a verified hardware boundary. |
| ML-DSA-65            | +0.05  | Post-quantum second signature (FIPS 204). Quantum-resistant evidence chain alongside Ed25519. Does not strengthen classical security but ensures the certificate survives a quantum break of ECDSA/Ed25519. |
| Merkle Proof         | +0.05  | Inclusion proof in an append-only Merkle log. Cannot be backdated — the certificate's position in the log is fixed at issuance. |
| Polygon Anchor       | +0.10  | Merkle root recorded on Polygon mainnet. Immutable once confirmed (≥1 block). The Ethereum global state is an external timestamp that no single party can alter. |
| **MAXIMUM**          | **1.00** | Sum of all non-zero layers. |

---

## Posture Thresholds

| Score     | Posture              | Meaning |
|-----------|----------------------|---------|
| ≥ 0.80    | `hardware_attested`  | At least two independent hardware evidence sources active, including a TEE quote. Suitable for regulatory disclosure under CSRD ESRS E1 and EU AI Act Article 51. |
| ≥ 0.40    | `cross_checked`      | Multiple independent energy sources active. Significantly stronger than self-reported but no hardware root of trust. Suitable for internal reporting and Scope 3 baseline. |
| < 0.40    | `self_reported`      | Single energy source, no cross-check. Equivalent to industry-standard telemetry today. Better than a spreadsheet, but not independently verifiable at the hardware level. |

Posture is **upgrade-only within a certificate's lifetime**: once a Polygon
anchor confirms, the score can only increase.

---

## What the Score Is Not

- **Not a quality rating.** A high score says nothing about whether the model
  performed well or was efficient. It only says how many independent layers of
  evidence support the energy number.

- **Not chosen by Serial Alice.** The score is deterministically computed from
  the evidence fields in the certificate payload. Serial Alice has no discretion
  over the result.

- **Not per-issuer.** The same layer table applies to every certificate from
  every tenant.

- **Not a guarantee of accuracy.** A score of 1.00 means all available evidence
  layers are active. It does not mean the measurement is perfectly accurate —
  hardware sensors have calibration tolerances. It means the reading, whatever
  it is, is bound to hardware evidence that cannot be retrospectively altered.

---

## Computation

```python
LAYER_SCORES = {
    "nvml":                0.20,
    "rapl_cpu":            0.15,  # CPU package domain
    "rapl_dram":           0.10,  # DRAM domain
    "signed_exporter":     0.15,  # Ed25519; machine fingerprint in payload
    "machine_fingerprint": 0.00,  # folded into signed_exporter
    "tee_quote":           0.20,
    "ml_dsa_65":           0.05,
    "merkle_proof":        0.05,
    "polygon_anchor":      0.10,
}

def compute_trust_score(layers_active: list[str]) -> tuple[float, str]:
    score = round(sum(LAYER_SCORES.get(l, 0.0) for l in layers_active), 2)
    if score >= 0.80:
        posture = "hardware_attested"
    elif score >= 0.40:
        posture = "cross_checked"
    else:
        posture = "self_reported"
    return score, posture
```

---

## Alice Benchmark v2.0 — Expected Scores

| Test | Layers Added | Score | Posture |
|------|-------------|-------|---------|
| 1 | NVML | 0.20 | self_reported |
| 2 | + RAPL CPU + RAPL DRAM | **0.45** | cross_checked |
| 3 | + Signed Exporter (+ FP in payload) | 0.60 | cross_checked |
| 4 | + TEE Quote | 0.80 | hardware_attested |
| 5 | + ML-DSA-65 | 0.85 | hardware_attested |
| 6 | + Merkle Proof + Polygon Anchor | **1.00** | hardware_attested |

Live ladder: https://api.serialalice.pt/trust-ladder

---

## Verification

```bash
curl https://api.serialalice.pt/v1/certificates/{cert_id}/verify \
  | jq '.trust_score, .trust_posture, .layers_active'
```

---

## Changelog

| Version | Date       | Change |
|---------|------------|--------|
| 1.1     | 2026-05-30 | RAPL weight increased from +0.15 to +0.25 (CPU and DRAM are two physically independent domains). Machine Fingerprint folded into Signed Exporter (not independently scored). Maximum remains 1.00. |
| 1.0     | 2026-05-30 | Initial public release. |

---

*Serial Alice Trust Score Specification v1.1 · Licensed CC BY 4.0*
