Kernels
kernel
inference
energy
nvml
governance
provenance
audit
receipts
tokens-per-joule
sovereign-ai
deprecated
superseded
Instructions to use SZLHOLDINGS/governed-inference-meter with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Kernels
How to use SZLHOLDINGS/governed-inference-meter with Kernels:
# !pip install kernels from kernels import get_kernel kernel = get_kernel("SZLHOLDINGS/governed-inference-meter") - Notebooks
- Google Colab
- Kaggle
mirror: sync kernel from GitHub source-of-truth
Browse files- README.md +89 -0
- SECURITY.md +63 -0
- build/torch-universal/governed_inference_meter/__init__.py +43 -2
- build/torch-universal/governed_inference_meter/_attest.py +223 -0
- build/torch-universal/governed_inference_meter/_spine.py +376 -0
- pyproject.toml +5 -4
- tests/test_attest.py +119 -0
- tests/test_spine.py +215 -0
README.md
CHANGED
|
@@ -197,6 +197,91 @@ that mutating a past record is detected. It requires no GPU.
|
|
| 197 |
|
| 198 |
---
|
| 199 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 200 |
## What's in the repo
|
| 201 |
|
| 202 |
```
|
|
@@ -206,9 +291,13 @@ build/torch-universal/governed_inference_meter/
|
|
| 206 |
_energy.py # NVML energy + power-integral measurement, honest degrade
|
| 207 |
_receipt.py # SHA-256 hash-chained, tamper-evident receipts
|
| 208 |
_policy.py # advisory policy gate (allow_all default, fail-closed)
|
|
|
|
|
|
|
| 209 |
metadata.json
|
| 210 |
pyproject.toml # also pip-installable from source
|
| 211 |
tests/test_meter.py # runs on CPU, no GPU needed
|
|
|
|
|
|
|
| 212 |
LICENSE # Apache-2.0
|
| 213 |
```
|
| 214 |
|
|
|
|
| 197 |
|
| 198 |
---
|
| 199 |
|
| 200 |
+
## Attestation & compliance evidence (interop layer)
|
| 201 |
+
|
| 202 |
+
A receipt is only as useful as the tools that can *carry* it. This module renders
|
| 203 |
+
any receipt into the formats the wider ecosystem already understands — without
|
| 204 |
+
changing a single measured value.
|
| 205 |
+
|
| 206 |
+
```python
|
| 207 |
+
import governed_inference_meter as gim
|
| 208 |
+
|
| 209 |
+
rec, out = gim.meter(run, args=("hi",), model="my-llm", tokens_in=2, tokens_out=7)
|
| 210 |
+
|
| 211 |
+
# 1) The receipt as an in-toto Statement v1 — the exact payload that
|
| 212 |
+
# Sigstore / DSSE / SCITT tooling signs and stores in a transparency log.
|
| 213 |
+
stmt = gim.to_intoto_statement(rec) # SLSA-shaped predicate, our own type URI
|
| 214 |
+
|
| 215 |
+
# 2) EU AI Act / NIST AI RMF controls this receipt provides EVIDENCE for,
|
| 216 |
+
# with an explicit does_not_establish note per control (honest, not a cert).
|
| 217 |
+
ev = gim.compliance_evidence(rec)
|
| 218 |
+
|
| 219 |
+
# 3) Confirm the Statement is cryptographically bound to this exact receipt.
|
| 220 |
+
ok, why = gim.verify_statement(stmt, rec) # -> (True, "ok")
|
| 221 |
+
```
|
| 222 |
+
|
| 223 |
+
Honest boundaries (doctrine):
|
| 224 |
+
|
| 225 |
+
- The predicate uses **our own** `predicateType` URI and is only SLSA-*shaped*
|
| 226 |
+
for auditor recognizability — it is **not** a claim of official SLSA
|
| 227 |
+
conformance. Signing (DSSE/Sigstore) is out-of-band; this emits the unsigned
|
| 228 |
+
Statement payload a signer would then cover.
|
| 229 |
+
- Energy fields are copied **verbatim**. On an unmeasured receipt, energy-dependent
|
| 230 |
+
controls (e.g. `NIST-AI-RMF-MEASURE-2.x`) report **`UNAVAILABLE`** — never a
|
| 231 |
+
fabricated joule. Logging / record-keeping controls (EU AI Act Art. 12 & 19)
|
| 232 |
+
are supported regardless of GPU.
|
| 233 |
+
- A receipt is **evidence** toward a control, never a conformity assessment,
|
| 234 |
+
certification, or safety guarantee.
|
| 235 |
+
|
| 236 |
+
---
|
| 237 |
+
|
| 238 |
+
## Canonical PCGI receipt (spine fold)
|
| 239 |
+
|
| 240 |
+
The meter is also a first-class **Proof-Carrying Governed Intelligence (PCGI)**
|
| 241 |
+
receipt producer on the org-canonical [`szl-receipt`](https://huggingface.co/SZLHOLDINGS)
|
| 242 |
+
spine. One call folds a metered inference into a single signed receipt that binds
|
| 243 |
+
**model id + input digest + output digest + governing policy id + energy** — the
|
| 244 |
+
same shape every other decision producer emits, so provenance unifies.
|
| 245 |
+
|
| 246 |
+
```python
|
| 247 |
+
import governed_inference_meter as gim
|
| 248 |
+
from szl_receipt import generate_keypair
|
| 249 |
+
|
| 250 |
+
priv, pub = generate_keypair() # or sign_key=None for UNSIGNED-honest
|
| 251 |
+
|
| 252 |
+
# End-to-end: meter the call AND emit ONE canonical szl-receipt for it.
|
| 253 |
+
env, out = gim.meter_szl_receipt(
|
| 254 |
+
run, args=("hi",), model="my-llm",
|
| 255 |
+
policy_id="default-allow", sign_key=priv, organ="meter",
|
| 256 |
+
)
|
| 257 |
+
ok, why = gim.verify_szl_receipt(env, pub) # -> (True, "ok")
|
| 258 |
+
stmt = gim.to_statement(env) # in-toto Statement v1, SLSA-shaped
|
| 259 |
+
ok2, _ = gim.verify_szl_statement(stmt, env) # bound to this exact receipt
|
| 260 |
+
|
| 261 |
+
# Or fold an existing meter receipt you already have:
|
| 262 |
+
rec, out = gim.meter(run, args=("hi",), model="my-llm", tokens_in=2, tokens_out=7)
|
| 263 |
+
env = gim.from_meter_receipt(rec, input="hi", output=out, policy_id="default-allow")
|
| 264 |
+
```
|
| 265 |
+
|
| 266 |
+
Honest boundaries (doctrine):
|
| 267 |
+
|
| 268 |
+
- Reuses szl-receipt's **canonicalization + signing + in-toto shapes** — it does
|
| 269 |
+
**not** invent a new receipt shape.
|
| 270 |
+
- **Energy** is bound **verbatim** only when the meter actually measured it
|
| 271 |
+
(NVML present). Otherwise `energy.joules` is the literal string
|
| 272 |
+
**`"UNAVAILABLE"`** and `energy.measured` is `False` — the meter is the one
|
| 273 |
+
place in the spine where energy *can* be real, and it is never fabricated.
|
| 274 |
+
- The canonical body is **deterministic**: identical inputs serialize to
|
| 275 |
+
byte-identical canonical JSON (no timestamps in the body).
|
| 276 |
+
- Keyless => **UNSIGNED-honest** (`signed=False`); a signature is never faked.
|
| 277 |
+
- The receipt is **evidence** binding a decision, **not** a proof the model's
|
| 278 |
+
output is correct.
|
| 279 |
+
|
| 280 |
+
Requires the shared `szl-receipt` library (install extra `[sign]`); the import is
|
| 281 |
+
lazy, so importing this package stays zero-hard-dependency.
|
| 282 |
+
|
| 283 |
+
---
|
| 284 |
+
|
| 285 |
## What's in the repo
|
| 286 |
|
| 287 |
```
|
|
|
|
| 291 |
_energy.py # NVML energy + power-integral measurement, honest degrade
|
| 292 |
_receipt.py # SHA-256 hash-chained, tamper-evident receipts
|
| 293 |
_policy.py # advisory policy gate (allow_all default, fail-closed)
|
| 294 |
+
_attest.py # in-toto/SLSA-shaped Statements + EU AI Act / NIST AI RMF evidence
|
| 295 |
+
_spine.py # PCGI spine fold: metered inference -> ONE canonical szl-receipt
|
| 296 |
metadata.json
|
| 297 |
pyproject.toml # also pip-installable from source
|
| 298 |
tests/test_meter.py # runs on CPU, no GPU needed
|
| 299 |
+
tests/test_attest.py # attestation + compliance, no GPU needed
|
| 300 |
+
tests/test_spine.py # canonical PCGI receipt fold, no GPU needed
|
| 301 |
LICENSE # Apache-2.0
|
| 302 |
```
|
| 303 |
|
SECURITY.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Security Policy
|
| 2 |
+
|
| 3 |
+
## Supported Versions
|
| 4 |
+
|
| 5 |
+
| Version | Supported |
|
| 6 |
+
| ------- | ------------------ |
|
| 7 |
+
| 1.x | :white_check_mark: |
|
| 8 |
+
| < 1.0 | :x: |
|
| 9 |
+
|
| 10 |
+
## Reporting a Vulnerability
|
| 11 |
+
|
| 12 |
+
**Do NOT open a public GitHub issue for security vulnerabilities.**
|
| 13 |
+
|
| 14 |
+
Please report security vulnerabilities via email to **security@szlholdings.ai** with:
|
| 15 |
+
|
| 16 |
+
1. Description of the vulnerability
|
| 17 |
+
2. Steps to reproduce
|
| 18 |
+
3. Potential impact assessment
|
| 19 |
+
4. Any suggested mitigations
|
| 20 |
+
|
| 21 |
+
### Response SLA
|
| 22 |
+
|
| 23 |
+
| Severity | Initial Response | Resolution Target |
|
| 24 |
+
|---|---|---|
|
| 25 |
+
| Critical | 24 hours | 7 days |
|
| 26 |
+
| High | 48 hours | 30 days |
|
| 27 |
+
| Medium | 5 business days | 90 days |
|
| 28 |
+
| Low | 10 business days | 180 days |
|
| 29 |
+
|
| 30 |
+
We follow a **90-day responsible disclosure** policy. After 90 days from initial report, details may be published regardless of patch status (with appropriate notice to reporter).
|
| 31 |
+
|
| 32 |
+
## Supply-Chain Security
|
| 33 |
+
|
| 34 |
+
- **SLSA Build Level 1** — build provenance generated per release (honest; not L2/L3)
|
| 35 |
+
- **DCO required** — all commits carry `Signed-off-by:` trailers per [Linux Foundation DCO](https://developercertificate.org/)
|
| 36 |
+
- **Cosign keyless signing** — containers signed via Sigstore OIDC keyless mode; verify with `cosign verify ghcr.io/szl-holdings/governed-inference-meter:<tag>`
|
| 37 |
+
- **SBOM** — CycloneDX SBOM attached to each GitHub Release
|
| 38 |
+
|
| 39 |
+
## Section 889 Attestation
|
| 40 |
+
|
| 41 |
+
SZL Holdings attests that no covered telecommunications equipment or services from the following vendors are used in this software:
|
| 42 |
+
|
| 43 |
+
1. Huawei Technologies Company
|
| 44 |
+
2. ZTE Corporation
|
| 45 |
+
3. Hytera Communications Corporation
|
| 46 |
+
4. Hangzhou Hikvision Digital Technology Company
|
| 47 |
+
5. Dahua Technology Company
|
| 48 |
+
|
| 49 |
+
Per NDAA Section 889, 41 U.S.C. § 4713.
|
| 50 |
+
|
| 51 |
+
## Doctrine
|
| 52 |
+
|
| 53 |
+
- Doctrine v11 LOCKED — kernel commit `c7c0ba17` (749 declarations / 14 axioms / 163 sorries)
|
| 54 |
+
- Λ = Conjecture 1 (never a theorem)
|
| 55 |
+
- No Iron Bank, FedRAMP, CMMC, or SWFT claims
|
| 56 |
+
|
| 57 |
+
## Contact
|
| 58 |
+
|
| 59 |
+
- **Security disclosures:** security@szlholdings.ai
|
| 60 |
+
- **General:** hello@szlholdings.ai
|
| 61 |
+
- **Website:** https://szlholdings.ai
|
| 62 |
+
|
| 63 |
+
*This policy follows [OpenSSF Vulnerability Disclosure Guide](https://github.com/ossf/oss-vulnerability-guide).*
|
build/torch-universal/governed_inference_meter/__init__.py
CHANGED
|
@@ -57,7 +57,15 @@ import contextlib
|
|
| 57 |
import time
|
| 58 |
from typing import Any, Callable, Dict, Optional, Sequence, Tuple
|
| 59 |
|
| 60 |
-
from . import _energy, _policy, _receipt
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 61 |
from ._energy import (
|
| 62 |
MODE_ENERGY_COUNTER,
|
| 63 |
MODE_POWER_INTEGRAL,
|
|
@@ -68,6 +76,20 @@ from ._energy import (
|
|
| 68 |
)
|
| 69 |
from ._policy import ALLOW, DENY, PolicyResult, allow_all, deny_all, evaluate
|
| 70 |
from ._receipt import ReceiptChain, default_chain
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 71 |
|
| 72 |
__all__ = [
|
| 73 |
"meter",
|
|
@@ -84,16 +106,35 @@ __all__ = [
|
|
| 84 |
"receipt_tail",
|
| 85 |
"receipt_verify",
|
| 86 |
"selfcheck",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 87 |
"DOCTRINE_FOOTER",
|
| 88 |
"MODE_UNMEASURED",
|
| 89 |
"MODE_ENERGY_COUNTER",
|
| 90 |
"MODE_POWER_INTEGRAL",
|
| 91 |
"ALLOW",
|
| 92 |
"DENY",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 93 |
"__version__",
|
| 94 |
]
|
| 95 |
|
| 96 |
-
__version__ = "0.
|
| 97 |
DOCTRINE_FOOTER = (
|
| 98 |
"SZL Holdings · governed, energy-metered inference receipts · "
|
| 99 |
"MEASURED only with NVML · policy gate is advisory (host-enforced) · "
|
|
|
|
| 57 |
import time
|
| 58 |
from typing import Any, Callable, Dict, Optional, Sequence, Tuple
|
| 59 |
|
| 60 |
+
from . import _attest, _energy, _policy, _receipt
|
| 61 |
+
from ._attest import (
|
| 62 |
+
IN_TOTO_STATEMENT_TYPE,
|
| 63 |
+
SZL_PREDICATE_TYPE,
|
| 64 |
+
attest,
|
| 65 |
+
compliance_evidence,
|
| 66 |
+
to_intoto_statement,
|
| 67 |
+
verify_statement,
|
| 68 |
+
)
|
| 69 |
from ._energy import (
|
| 70 |
MODE_ENERGY_COUNTER,
|
| 71 |
MODE_POWER_INTEGRAL,
|
|
|
|
| 76 |
)
|
| 77 |
from ._policy import ALLOW, DENY, PolicyResult, allow_all, deny_all, evaluate
|
| 78 |
from ._receipt import ReceiptChain, default_chain
|
| 79 |
+
from ._spine import (
|
| 80 |
+
CANONICAL_KIND,
|
| 81 |
+
ENERGY_UNAVAILABLE,
|
| 82 |
+
PREDICATE_TYPE,
|
| 83 |
+
SPEC_VERSION,
|
| 84 |
+
canonical_receipt_body,
|
| 85 |
+
digest,
|
| 86 |
+
emit_szl_receipt,
|
| 87 |
+
from_meter_receipt,
|
| 88 |
+
meter_szl_receipt,
|
| 89 |
+
to_statement,
|
| 90 |
+
verify_szl_receipt,
|
| 91 |
+
verify_szl_statement,
|
| 92 |
+
)
|
| 93 |
|
| 94 |
__all__ = [
|
| 95 |
"meter",
|
|
|
|
| 106 |
"receipt_tail",
|
| 107 |
"receipt_verify",
|
| 108 |
"selfcheck",
|
| 109 |
+
"attest",
|
| 110 |
+
"to_intoto_statement",
|
| 111 |
+
"compliance_evidence",
|
| 112 |
+
"verify_statement",
|
| 113 |
+
"IN_TOTO_STATEMENT_TYPE",
|
| 114 |
+
"SZL_PREDICATE_TYPE",
|
| 115 |
"DOCTRINE_FOOTER",
|
| 116 |
"MODE_UNMEASURED",
|
| 117 |
"MODE_ENERGY_COUNTER",
|
| 118 |
"MODE_POWER_INTEGRAL",
|
| 119 |
"ALLOW",
|
| 120 |
"DENY",
|
| 121 |
+
# PCGI spine fold — canonical szl-receipt for a metered inference.
|
| 122 |
+
"emit_szl_receipt",
|
| 123 |
+
"from_meter_receipt",
|
| 124 |
+
"meter_szl_receipt",
|
| 125 |
+
"canonical_receipt_body",
|
| 126 |
+
"to_statement",
|
| 127 |
+
"verify_szl_receipt",
|
| 128 |
+
"verify_szl_statement",
|
| 129 |
+
"digest",
|
| 130 |
+
"CANONICAL_KIND",
|
| 131 |
+
"PREDICATE_TYPE",
|
| 132 |
+
"SPEC_VERSION",
|
| 133 |
+
"ENERGY_UNAVAILABLE",
|
| 134 |
"__version__",
|
| 135 |
]
|
| 136 |
|
| 137 |
+
__version__ = "0.2.0"
|
| 138 |
DOCTRINE_FOOTER = (
|
| 139 |
"SZL Holdings · governed, energy-metered inference receipts · "
|
| 140 |
"MEASURED only with NVML · policy gate is advisory (host-enforced) · "
|
build/torch-universal/governed_inference_meter/_attest.py
ADDED
|
@@ -0,0 +1,223 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
|
| 3 |
+
"""Standards-interop + compliance-evidence layer for governed-inference receipts.
|
| 4 |
+
|
| 5 |
+
A governed-inference receipt (see :mod:`._receipt`) is an honest, tamper-evident,
|
| 6 |
+
hash-chained record of one metered inference call. This module lets that record
|
| 7 |
+
*speak the wider ecosystem's language* without changing a single measured value:
|
| 8 |
+
|
| 9 |
+
1. :func:`to_intoto_statement` renders a receipt as an **in-toto Statement v1**
|
| 10 |
+
— the exact JSON payload that Sigstore / DSSE / IETF SCITT tooling already
|
| 11 |
+
knows how to carry, sign, and store in a transparency log. The predicate is
|
| 12 |
+
laid out in SLSA-v1 provenance shape (``buildDefinition`` / ``runDetails``).
|
| 13 |
+
2. :func:`compliance_evidence` maps the receipt onto the specific **EU AI Act**
|
| 14 |
+
articles and **NIST AI RMF** functions it provides operational evidence for
|
| 15 |
+
and — per the honesty doctrine — states plainly what it does **NOT** establish.
|
| 16 |
+
3. :func:`verify_statement` re-derives the receipt body digest and confirms the
|
| 17 |
+
Statement's subject is bound to that exact receipt.
|
| 18 |
+
|
| 19 |
+
CONSOLIDATION (the ecosystem shapes + regulator catalogue live in ONE place):
|
| 20 |
+
The in-toto Statement envelope, the SLSA-shaped predicate skeleton, the
|
| 21 |
+
EU AI Act / NIST AI RMF control catalogue, and the subject-digest verifier are
|
| 22 |
+
the SHARED :mod:`szl_receipt.attest` module — the same library that already
|
| 23 |
+
provides receipt signing. This module is a thin, receipt-schema-specific
|
| 24 |
+
adapter over it: it maps this package's receipt fields onto capability flags
|
| 25 |
+
and predicate parameters, then delegates the ecosystem-facing shapes. That
|
| 26 |
+
keeps a single source of truth so the regulator mapping can never drift
|
| 27 |
+
between SZL packages. Attestation is therefore an interop feature that, like
|
| 28 |
+
signing, requires the shared ``szl-receipt`` library (install extra ``[sign]``);
|
| 29 |
+
the import is lazy so importing this package stays zero-hard-dependency.
|
| 30 |
+
|
| 31 |
+
HONESTY (Λ = Conjecture 1, advisory — NOT a theorem):
|
| 32 |
+
* We emit our OWN predicate type URI. We do NOT claim official SLSA-provenance
|
| 33 |
+
conformance; the shape is SLSA-*inspired* for recognizability only.
|
| 34 |
+
* Energy fields are copied verbatim from the receipt. When the receipt is
|
| 35 |
+
``mode="unmeasured"`` the energy evidence is reported ``UNAVAILABLE`` — never
|
| 36 |
+
a fabricated joule or efficiency number.
|
| 37 |
+
* A receipt is EVIDENCE toward a control, never a conformity assessment,
|
| 38 |
+
certification, or safety guarantee. Every mapping entry carries an explicit
|
| 39 |
+
``does_not_establish`` note.
|
| 40 |
+
* Stdlib only in this module. Nothing is written to disk or the network here;
|
| 41 |
+
signing (DSSE/Sigstore) is a separate, out-of-band concern.
|
| 42 |
+
"""
|
| 43 |
+
import hashlib
|
| 44 |
+
import json
|
| 45 |
+
from typing import Any, Dict, Optional, Tuple
|
| 46 |
+
|
| 47 |
+
from ._receipt import _BODY_FIELDS, canonical_json
|
| 48 |
+
|
| 49 |
+
# In-toto Statement envelope type — the stable, ecosystem-standard URI. Defined
|
| 50 |
+
# locally (not imported) so importing this package never requires szl-receipt at
|
| 51 |
+
# import time; it mirrors the identical constant in ``szl_receipt.attest``.
|
| 52 |
+
IN_TOTO_STATEMENT_TYPE = "https://in-toto.io/Statement/v1"
|
| 53 |
+
|
| 54 |
+
# Our OWN predicate type. Honest: this is an SZL predicate, SLSA-*shaped* for
|
| 55 |
+
# recognizability — it is NOT a claim of official SLSA-provenance conformance.
|
| 56 |
+
SZL_PREDICATE_TYPE = "https://a-11-oy.com/attest/governed-inference/v0.1"
|
| 57 |
+
|
| 58 |
+
ATTEST_DOCTRINE = (
|
| 59 |
+
"SZL Holdings · in-toto/SLSA-shaped attestation over an honest, hash-chained "
|
| 60 |
+
"governed-inference receipt · MEASURED energy only (else UNAVAILABLE) · "
|
| 61 |
+
"EVIDENCE toward a control, NOT a conformity assessment or safety guarantee · "
|
| 62 |
+
"Lambda = Conjecture 1 (advisory) · trust never 100%"
|
| 63 |
+
)
|
| 64 |
+
|
| 65 |
+
|
| 66 |
+
def _shared():
|
| 67 |
+
"""Lazily import the shared :mod:`szl_receipt.attest` layer.
|
| 68 |
+
|
| 69 |
+
Attestation is an interop feature that reuses the ONE canonical home for the
|
| 70 |
+
ecosystem shapes and the regulator catalogue (the same ``szl-receipt`` library
|
| 71 |
+
used for signing). If it is not installed we raise a clear, honest error —
|
| 72 |
+
never a silent, drift-prone local reimplementation.
|
| 73 |
+
"""
|
| 74 |
+
try:
|
| 75 |
+
from szl_receipt import attest as _a # type: ignore
|
| 76 |
+
except Exception as exc: # noqa: BLE001
|
| 77 |
+
raise ImportError(
|
| 78 |
+
"governed_inference_meter attestation requires the shared 'szl-receipt' "
|
| 79 |
+
"library (pip install 'governed-inference-meter[sign]', or "
|
| 80 |
+
"pip install szl-receipt). Underlying import error: %r" % (exc,)
|
| 81 |
+
) from exc
|
| 82 |
+
return _a
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
def _receipt_body(receipt: Dict[str, Any]) -> Dict[str, Any]:
|
| 86 |
+
"""Extract the exact canonical body (the hashed fields) from a receipt."""
|
| 87 |
+
return {k: receipt[k] for k in _BODY_FIELDS}
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def _body_digest(body: Dict[str, Any]) -> str:
|
| 91 |
+
return hashlib.sha256(canonical_json(body).encode("utf-8")).hexdigest()
|
| 92 |
+
|
| 93 |
+
|
| 94 |
+
def _measured(receipt: Dict[str, Any]) -> bool:
|
| 95 |
+
"""True only when real energy was measured (mode set and joules present)."""
|
| 96 |
+
return receipt.get("mode") != "unmeasured" and receipt.get("joules") is not None
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
def to_intoto_statement(
|
| 100 |
+
receipt: Dict[str, Any],
|
| 101 |
+
*,
|
| 102 |
+
subject_name: Optional[str] = None,
|
| 103 |
+
) -> Dict[str, Any]:
|
| 104 |
+
"""Render *receipt* as an in-toto Statement v1 with an SLSA-shaped predicate.
|
| 105 |
+
|
| 106 |
+
The Statement's single subject is the receipt itself, bound by its SHA-256
|
| 107 |
+
body digest, so the attestation is inseparable from the exact record it
|
| 108 |
+
describes. All energy fields are copied verbatim (honest ``null`` when the
|
| 109 |
+
receipt was unmeasured). The returned dict is the *unsigned* payload that a
|
| 110 |
+
DSSE/Sigstore signer would then wrap.
|
| 111 |
+
"""
|
| 112 |
+
a = _shared()
|
| 113 |
+
body = _receipt_body(receipt)
|
| 114 |
+
digest = receipt.get("digest") or _body_digest(body)
|
| 115 |
+
measured = _measured(receipt)
|
| 116 |
+
name = subject_name or "governed-inference-receipt/seq-{}".format(
|
| 117 |
+
receipt.get("seq", "?")
|
| 118 |
+
)
|
| 119 |
+
predicate = a.slsa_predicate(
|
| 120 |
+
build_type=SZL_PREDICATE_TYPE,
|
| 121 |
+
external_parameters={
|
| 122 |
+
"model": receipt.get("model"),
|
| 123 |
+
"tokens_in": receipt.get("tokens_in"),
|
| 124 |
+
"tokens_out": receipt.get("tokens_out"),
|
| 125 |
+
},
|
| 126 |
+
internal_parameters={
|
| 127 |
+
"policy_decision": receipt.get("policy_decision"),
|
| 128 |
+
"policy_reason": receipt.get("policy_reason"),
|
| 129 |
+
},
|
| 130 |
+
builder_id=SZL_PREDICATE_TYPE,
|
| 131 |
+
metadata={
|
| 132 |
+
"energy_mode": receipt.get("mode"),
|
| 133 |
+
"measured": measured,
|
| 134 |
+
# Verbatim, honest-null when unmeasured. Never fabricated.
|
| 135 |
+
"joules": receipt.get("joules"),
|
| 136 |
+
"wall_seconds": receipt.get("wall_seconds"),
|
| 137 |
+
"tokens_per_joule": receipt.get("tokens_per_joule"),
|
| 138 |
+
},
|
| 139 |
+
extra={"doctrine": ATTEST_DOCTRINE},
|
| 140 |
+
)
|
| 141 |
+
# Bind the receipt's chain position into the run details (product-specific).
|
| 142 |
+
predicate["runDetails"]["receipt"] = {
|
| 143 |
+
"seq": receipt.get("seq"),
|
| 144 |
+
"prev": receipt.get("prev"),
|
| 145 |
+
"digest": digest,
|
| 146 |
+
}
|
| 147 |
+
return a.build_statement(
|
| 148 |
+
subject_name=name,
|
| 149 |
+
subject_digest=digest,
|
| 150 |
+
predicate=predicate,
|
| 151 |
+
predicate_type=SZL_PREDICATE_TYPE,
|
| 152 |
+
)
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
def compliance_evidence(receipt: Dict[str, Any]) -> Dict[str, Any]:
|
| 156 |
+
"""Map *receipt* onto EU AI Act / NIST AI RMF controls it evidences.
|
| 157 |
+
|
| 158 |
+
Returns a dict with per-control ``status`` — ``"supports"`` when the receipt
|
| 159 |
+
provides operational evidence for that control, or ``"UNAVAILABLE"`` for an
|
| 160 |
+
energy-dependent control on an unmeasured receipt. Every entry carries an
|
| 161 |
+
explicit ``does_not_establish`` note. This is EVIDENCE, never a conformity
|
| 162 |
+
assessment or certification.
|
| 163 |
+
"""
|
| 164 |
+
a = _shared()
|
| 165 |
+
measured = _measured(receipt)
|
| 166 |
+
# A governed-inference receipt always logs (hash chain), is tamper-evident,
|
| 167 |
+
# and records an advisory governance decision; energy is capability-gated.
|
| 168 |
+
capabilities = {
|
| 169 |
+
"logging": True,
|
| 170 |
+
"integrity": True,
|
| 171 |
+
"governance": True,
|
| 172 |
+
"energy": measured,
|
| 173 |
+
}
|
| 174 |
+
ev = a.compliance_evidence(
|
| 175 |
+
capabilities=capabilities,
|
| 176 |
+
subject_digest=receipt.get("digest"),
|
| 177 |
+
extra={
|
| 178 |
+
"receipt_seq": receipt.get("seq"),
|
| 179 |
+
"receipt_digest": receipt.get("digest"),
|
| 180 |
+
"doctrine": ATTEST_DOCTRINE,
|
| 181 |
+
},
|
| 182 |
+
)
|
| 183 |
+
return ev
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
def attest(
|
| 187 |
+
receipt: Dict[str, Any],
|
| 188 |
+
*,
|
| 189 |
+
subject_name: Optional[str] = None,
|
| 190 |
+
) -> Dict[str, Any]:
|
| 191 |
+
"""Convenience: the in-toto Statement plus its compliance-evidence mapping."""
|
| 192 |
+
return {
|
| 193 |
+
"statement": to_intoto_statement(receipt, subject_name=subject_name),
|
| 194 |
+
"compliance": compliance_evidence(receipt),
|
| 195 |
+
}
|
| 196 |
+
|
| 197 |
+
|
| 198 |
+
def verify_statement(
|
| 199 |
+
statement: Dict[str, Any],
|
| 200 |
+
receipt: Dict[str, Any],
|
| 201 |
+
) -> Tuple[bool, str]:
|
| 202 |
+
"""Confirm *statement* is bound to *receipt*. Returns ``(ok, reason)``.
|
| 203 |
+
|
| 204 |
+
Re-derives the receipt body digest and checks it matches BOTH the receipt's
|
| 205 |
+
own ``digest`` and the Statement subject digest — so an attestation cannot
|
| 206 |
+
drift from, or be swapped away from, the exact record it claims to describe.
|
| 207 |
+
"""
|
| 208 |
+
a = _shared()
|
| 209 |
+
try:
|
| 210 |
+
body = _receipt_body(receipt)
|
| 211 |
+
except KeyError as exc: # receipt missing a hashed field
|
| 212 |
+
return (False, "receipt-missing-field:{}".format(exc.args[0]))
|
| 213 |
+
recomputed = _body_digest(body)
|
| 214 |
+
if receipt.get("digest") != recomputed:
|
| 215 |
+
return (False, "receipt-digest-mismatch")
|
| 216 |
+
return a.verify_statement(
|
| 217 |
+
statement, expected_digest=recomputed, predicate_type=SZL_PREDICATE_TYPE
|
| 218 |
+
)
|
| 219 |
+
|
| 220 |
+
|
| 221 |
+
def to_json(obj: Dict[str, Any]) -> str:
|
| 222 |
+
"""Canonical (sorted, compact) JSON — the bytes a DSSE signer would cover."""
|
| 223 |
+
return json.dumps(obj, sort_keys=True, separators=(",", ":"))
|
build/torch-universal/governed_inference_meter/_spine.py
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
|
| 3 |
+
"""PCGI spine fold — a metered inference as ONE canonical szl-receipt.
|
| 4 |
+
|
| 5 |
+
This is the WAVE-2 spine UNIFY step: it folds a governed-inference metering
|
| 6 |
+
result onto the org-canonical ``szl-receipt`` shape so the meter becomes a
|
| 7 |
+
first-class *Proof-Carrying Governed Intelligence* (PCGI) receipt producer on
|
| 8 |
+
the same spine as every other decision producer (a11oy, yarqa, killinchu, ...).
|
| 9 |
+
|
| 10 |
+
A canonical receipt binds, in ONE signed record:
|
| 11 |
+
|
| 12 |
+
* ``model`` — the model id that produced the output,
|
| 13 |
+
* ``input_digest`` — SHA-256 over the canonical input,
|
| 14 |
+
* ``output_digest`` — SHA-256 over the canonical output,
|
| 15 |
+
* ``policy`` — the governing policy id + advisory decision/reason,
|
| 16 |
+
* ``energy`` — MEASURED joules verbatim, or honest ``UNAVAILABLE``.
|
| 17 |
+
|
| 18 |
+
It does NOT invent a new receipt shape: it uses ``szl_receipt.Receipt`` +
|
| 19 |
+
``szl_receipt.sign_receipt`` for the canonical body + DSSE signing, and
|
| 20 |
+
``szl_receipt.build_statement`` / ``slsa_predicate`` / ``verify_statement`` for
|
| 21 |
+
the in-toto Statement. The shared library is the ONE source of truth for
|
| 22 |
+
canonicalization, signing, and the ecosystem shapes.
|
| 23 |
+
|
| 24 |
+
HONESTY (Λ = Conjecture 1, advisory — NOT a theorem):
|
| 25 |
+
* Energy is bound VERBATIM only when the meter actually measured it (NVML
|
| 26 |
+
present, ``mode != "unmeasured"``, ``joules`` present). Otherwise the
|
| 27 |
+
``energy.joules`` field is the literal string ``"UNAVAILABLE"`` and
|
| 28 |
+
``energy.measured`` is ``False``. A joule figure is NEVER fabricated. This
|
| 29 |
+
meter is the one place in the spine where energy CAN be real — the honest
|
| 30 |
+
counterpart to killinchu's edge ``UNAVAILABLE``.
|
| 31 |
+
* The receipt is EVIDENCE binding a decision (model+input+output+policy+
|
| 32 |
+
energy), NOT a proof that the model's output is correct.
|
| 33 |
+
* Keyless => UNSIGNED-honest (``signed=False``); a signature is never faked.
|
| 34 |
+
* The canonical body is deterministic: given identical inputs it serializes to
|
| 35 |
+
byte-identical canonical JSON (no timestamps / wall-clock in the body).
|
| 36 |
+
|
| 37 |
+
Import stays zero-hard-dependency: ``szl_receipt`` is imported lazily, so
|
| 38 |
+
importing this package never requires it. Producing a canonical receipt does
|
| 39 |
+
require it (install extra ``[sign]``), and its absence raises a clear error.
|
| 40 |
+
"""
|
| 41 |
+
import hashlib
|
| 42 |
+
from typing import Any, Callable, Dict, Optional, Sequence, Tuple, Union
|
| 43 |
+
|
| 44 |
+
# Canonical receipt kind (matches the additive signing layer in _receipt.py).
|
| 45 |
+
CANONICAL_KIND = "governed-inference"
|
| 46 |
+
|
| 47 |
+
# Our OWN predicate type — SLSA-*shaped* for recognizability, NOT a claim of
|
| 48 |
+
# official SLSA-provenance conformance (mirrors _attest.SZL_PREDICATE_TYPE).
|
| 49 |
+
PREDICATE_TYPE = "https://a-11-oy.com/attest/governed-inference/v0.1"
|
| 50 |
+
|
| 51 |
+
# Canonical body schema version for the PCGI fold.
|
| 52 |
+
SPEC_VERSION = "pcgi-governed-inference/0.1"
|
| 53 |
+
|
| 54 |
+
# Honest sentinel for energy that was not measured (never a fabricated joule).
|
| 55 |
+
ENERGY_UNAVAILABLE = "UNAVAILABLE"
|
| 56 |
+
|
| 57 |
+
# Default logical signing-authority label stamped onto the envelope.
|
| 58 |
+
_ORGAN = "governed-inference-meter"
|
| 59 |
+
|
| 60 |
+
SPINE_DOCTRINE = (
|
| 61 |
+
"SZL Holdings · PCGI spine · a metered inference as ONE canonical "
|
| 62 |
+
"szl-receipt binding model+input+output+policy+energy · MEASURED joules "
|
| 63 |
+
"verbatim else UNAVAILABLE (never fabricated) · receipt = evidence trail, "
|
| 64 |
+
"NOT a proof the output is correct · Lambda = Conjecture 1 (advisory) · "
|
| 65 |
+
"trust never 100%"
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def _shared():
|
| 70 |
+
"""Lazily import the shared ``szl_receipt`` library (the ONE canonical home).
|
| 71 |
+
|
| 72 |
+
Producing a canonical receipt reuses szl-receipt's canonicalization, signing,
|
| 73 |
+
and in-toto shapes. If it is not installed we raise a clear, honest error —
|
| 74 |
+
never a silent, drift-prone local reimplementation.
|
| 75 |
+
"""
|
| 76 |
+
try:
|
| 77 |
+
import szl_receipt as _s # type: ignore
|
| 78 |
+
except Exception as exc: # noqa: BLE001
|
| 79 |
+
raise ImportError(
|
| 80 |
+
"governed_inference_meter canonical szl-receipt output requires the "
|
| 81 |
+
"shared 'szl-receipt' library (pip install "
|
| 82 |
+
"'governed-inference-meter[sign]', or pip install szl-receipt). "
|
| 83 |
+
"Underlying import error: %r" % (exc,)
|
| 84 |
+
) from exc
|
| 85 |
+
return _s
|
| 86 |
+
|
| 87 |
+
|
| 88 |
+
def _canonical_bytes(obj: Any) -> bytes:
|
| 89 |
+
"""Deterministic bytes for *obj*, reusing szl-receipt's canonicalization.
|
| 90 |
+
|
| 91 |
+
``bytes`` are hashed as-is; ``str`` as its UTF-8 bytes; any JSON-serialisable
|
| 92 |
+
object via szl-receipt's ``canonical_json`` (sorted, compact) so digests are
|
| 93 |
+
stable across processes. Non-JSON objects fall back to a stable ``repr`` —
|
| 94 |
+
honest and deterministic, never an exception that would hide the binding.
|
| 95 |
+
"""
|
| 96 |
+
if isinstance(obj, bytes):
|
| 97 |
+
return obj
|
| 98 |
+
if isinstance(obj, str):
|
| 99 |
+
return obj.encode("utf-8")
|
| 100 |
+
try:
|
| 101 |
+
# Reuse szl-receipt's ONE canonicalization when available.
|
| 102 |
+
from szl_receipt._canonical import canonical_json # type: ignore
|
| 103 |
+
except Exception: # noqa: BLE001 - defensive against version drift
|
| 104 |
+
import json as _json
|
| 105 |
+
|
| 106 |
+
def canonical_json(o): # byte-identical fallback to szl-receipt's
|
| 107 |
+
return _json.dumps(
|
| 108 |
+
o, sort_keys=True, separators=(",", ":"), ensure_ascii=False
|
| 109 |
+
).encode("utf-8")
|
| 110 |
+
|
| 111 |
+
try:
|
| 112 |
+
return canonical_json(obj)
|
| 113 |
+
except TypeError:
|
| 114 |
+
# Not JSON-serialisable (e.g. a tensor/handle): bind a stable repr so the
|
| 115 |
+
# digest is still deterministic and honest about what it covers.
|
| 116 |
+
return ("repr::" + repr(obj)).encode("utf-8")
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def digest(obj: Any) -> str:
|
| 120 |
+
"""SHA-256 hex digest over the canonical bytes of *obj* (see ``_canonical_bytes``)."""
|
| 121 |
+
return hashlib.sha256(_canonical_bytes(obj)).hexdigest()
|
| 122 |
+
|
| 123 |
+
|
| 124 |
+
def _energy_binding(energy: Optional[Dict[str, Any]]) -> Dict[str, Any]:
|
| 125 |
+
"""Honest energy binding from a meter ``energy`` dict OR a meter receipt.
|
| 126 |
+
|
| 127 |
+
Both an ``EnergyMeter.stop()`` dict and a receipt carry ``mode``/``joules``.
|
| 128 |
+
MEASURED joules are copied verbatim; otherwise ``joules`` is the literal
|
| 129 |
+
``"UNAVAILABLE"`` sentinel and ``measured`` is ``False``. Never fabricated.
|
| 130 |
+
"""
|
| 131 |
+
e = dict(energy or {})
|
| 132 |
+
mode = e.get("mode", "unmeasured")
|
| 133 |
+
joules = e.get("joules", None)
|
| 134 |
+
measured = (mode != "unmeasured") and (joules is not None)
|
| 135 |
+
if measured:
|
| 136 |
+
return {
|
| 137 |
+
"measured": True,
|
| 138 |
+
"mode": str(mode),
|
| 139 |
+
"joules": round(float(joules), 6), # verbatim measured value
|
| 140 |
+
}
|
| 141 |
+
return {
|
| 142 |
+
"measured": False,
|
| 143 |
+
"mode": str(mode),
|
| 144 |
+
"joules": ENERGY_UNAVAILABLE, # honest sentinel — no fabricated joule
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
|
| 148 |
+
def canonical_receipt_body(
|
| 149 |
+
*,
|
| 150 |
+
model: str,
|
| 151 |
+
input: Any = None,
|
| 152 |
+
output: Any = None,
|
| 153 |
+
policy_id: str = "unspecified",
|
| 154 |
+
policy_decision: str = "allow",
|
| 155 |
+
policy_reason: str = "",
|
| 156 |
+
energy: Optional[Dict[str, Any]] = None,
|
| 157 |
+
input_digest: Optional[str] = None,
|
| 158 |
+
output_digest: Optional[str] = None,
|
| 159 |
+
) -> Dict[str, Any]:
|
| 160 |
+
"""Assemble the DETERMINISTIC canonical receipt body (the PCGI binding).
|
| 161 |
+
|
| 162 |
+
Provide either the raw ``input``/``output`` (they will be digested) or a
|
| 163 |
+
precomputed ``input_digest``/``output_digest``. The body contains no
|
| 164 |
+
timestamp or wall-clock, so identical inputs serialize byte-identically.
|
| 165 |
+
"""
|
| 166 |
+
idig = input_digest if input_digest is not None else digest(input)
|
| 167 |
+
odig = output_digest if output_digest is not None else digest(output)
|
| 168 |
+
return {
|
| 169 |
+
"spec_version": SPEC_VERSION,
|
| 170 |
+
"model": str(model),
|
| 171 |
+
"input_digest": "sha256:" + idig,
|
| 172 |
+
"output_digest": "sha256:" + odig,
|
| 173 |
+
"policy": {
|
| 174 |
+
"id": str(policy_id),
|
| 175 |
+
"decision": str(policy_decision),
|
| 176 |
+
"reason": str(policy_reason),
|
| 177 |
+
},
|
| 178 |
+
"energy": _energy_binding(energy),
|
| 179 |
+
}
|
| 180 |
+
|
| 181 |
+
|
| 182 |
+
def emit_szl_receipt(
|
| 183 |
+
*,
|
| 184 |
+
model: str,
|
| 185 |
+
input: Any = None,
|
| 186 |
+
output: Any = None,
|
| 187 |
+
policy_id: str = "unspecified",
|
| 188 |
+
policy_decision: str = "allow",
|
| 189 |
+
policy_reason: str = "",
|
| 190 |
+
energy: Optional[Dict[str, Any]] = None,
|
| 191 |
+
input_digest: Optional[str] = None,
|
| 192 |
+
output_digest: Optional[str] = None,
|
| 193 |
+
sign_key: Optional[Union[str, bytes]] = None,
|
| 194 |
+
organ: str = _ORGAN,
|
| 195 |
+
) -> Dict[str, Any]:
|
| 196 |
+
"""Produce ONE canonical szl-receipt (DSSE envelope) for a metered inference.
|
| 197 |
+
|
| 198 |
+
Binds model id + input digest + output digest + governing policy id + energy
|
| 199 |
+
into a ``szl_receipt.Receipt`` and signs it. With a PEM ECDSA-P256 *sign_key*
|
| 200 |
+
the envelope is signed; keyless it is UNSIGNED-honest (``signed=False``). The
|
| 201 |
+
envelope's ``digest`` is the SHA-256 over the canonical body — byte-stable
|
| 202 |
+
for identical inputs.
|
| 203 |
+
"""
|
| 204 |
+
s = _shared()
|
| 205 |
+
body = canonical_receipt_body(
|
| 206 |
+
model=model,
|
| 207 |
+
input=input,
|
| 208 |
+
output=output,
|
| 209 |
+
policy_id=policy_id,
|
| 210 |
+
policy_decision=policy_decision,
|
| 211 |
+
policy_reason=policy_reason,
|
| 212 |
+
energy=energy,
|
| 213 |
+
input_digest=input_digest,
|
| 214 |
+
output_digest=output_digest,
|
| 215 |
+
)
|
| 216 |
+
return s.sign_receipt(s.Receipt(kind=CANONICAL_KIND, body=body), sign_key, organ=organ)
|
| 217 |
+
|
| 218 |
+
|
| 219 |
+
def from_meter_receipt(
|
| 220 |
+
meter_receipt: Dict[str, Any],
|
| 221 |
+
*,
|
| 222 |
+
input: Any = None,
|
| 223 |
+
output: Any = None,
|
| 224 |
+
policy_id: str = "unspecified",
|
| 225 |
+
input_digest: Optional[str] = None,
|
| 226 |
+
output_digest: Optional[str] = None,
|
| 227 |
+
sign_key: Optional[Union[str, bytes]] = None,
|
| 228 |
+
organ: str = _ORGAN,
|
| 229 |
+
) -> Dict[str, Any]:
|
| 230 |
+
"""Fold an existing meter receipt (from :func:`meter`) onto a canonical receipt.
|
| 231 |
+
|
| 232 |
+
Reads ``model``, ``mode``/``joules`` (energy), and ``policy_decision``/
|
| 233 |
+
``policy_reason`` from the meter receipt, and binds the given ``input``/
|
| 234 |
+
``output`` (or precomputed digests). Energy honesty is preserved verbatim.
|
| 235 |
+
"""
|
| 236 |
+
return emit_szl_receipt(
|
| 237 |
+
model=meter_receipt.get("model", "unspecified"),
|
| 238 |
+
input=input,
|
| 239 |
+
output=output,
|
| 240 |
+
policy_id=policy_id,
|
| 241 |
+
policy_decision=meter_receipt.get("policy_decision", "allow"),
|
| 242 |
+
policy_reason=meter_receipt.get("policy_reason", ""),
|
| 243 |
+
energy={
|
| 244 |
+
"mode": meter_receipt.get("mode", "unmeasured"),
|
| 245 |
+
"joules": meter_receipt.get("joules", None),
|
| 246 |
+
},
|
| 247 |
+
input_digest=input_digest,
|
| 248 |
+
output_digest=output_digest,
|
| 249 |
+
sign_key=sign_key,
|
| 250 |
+
organ=organ,
|
| 251 |
+
)
|
| 252 |
+
|
| 253 |
+
|
| 254 |
+
def meter_szl_receipt(
|
| 255 |
+
fn: Callable[..., Any],
|
| 256 |
+
*,
|
| 257 |
+
args: Sequence[Any] = (),
|
| 258 |
+
kwargs: Optional[Dict[str, Any]] = None,
|
| 259 |
+
model: str = "unspecified",
|
| 260 |
+
policy_id: str = "unspecified",
|
| 261 |
+
policy: Optional[Callable[..., Any]] = None,
|
| 262 |
+
chain: Optional[Any] = None,
|
| 263 |
+
device_index: int = 0,
|
| 264 |
+
sample_hz: float = 100.0,
|
| 265 |
+
sign_key: Optional[Union[str, bytes]] = None,
|
| 266 |
+
organ: str = _ORGAN,
|
| 267 |
+
) -> Tuple[Dict[str, Any], Any]:
|
| 268 |
+
"""End-to-end: meter ``fn`` AND emit a canonical szl-receipt for the call.
|
| 269 |
+
|
| 270 |
+
Runs the standard energy meter + advisory policy gate (so the existing
|
| 271 |
+
tamper-evident chain still records the call), then folds the result onto a
|
| 272 |
+
canonical szl-receipt binding the input (args/kwargs) and output digests.
|
| 273 |
+
Returns ``(envelope, output)``. On a policy DENY, ``fn`` is not executed and
|
| 274 |
+
the receipt binds a ``null`` output digest with energy ``UNAVAILABLE``.
|
| 275 |
+
"""
|
| 276 |
+
import governed_inference_meter as _pkg # package fully loaded by call time
|
| 277 |
+
|
| 278 |
+
kwargs = dict(kwargs or {})
|
| 279 |
+
rec, output = _pkg.meter(
|
| 280 |
+
fn,
|
| 281 |
+
args=args,
|
| 282 |
+
kwargs=kwargs,
|
| 283 |
+
model=model,
|
| 284 |
+
policy=policy,
|
| 285 |
+
chain=chain,
|
| 286 |
+
device_index=device_index,
|
| 287 |
+
sample_hz=sample_hz,
|
| 288 |
+
)
|
| 289 |
+
env = from_meter_receipt(
|
| 290 |
+
rec,
|
| 291 |
+
input={"args": list(args), "kwargs": kwargs},
|
| 292 |
+
output=output,
|
| 293 |
+
policy_id=policy_id,
|
| 294 |
+
sign_key=sign_key,
|
| 295 |
+
organ=organ,
|
| 296 |
+
)
|
| 297 |
+
return env, output
|
| 298 |
+
|
| 299 |
+
|
| 300 |
+
def to_statement(
|
| 301 |
+
envelope_or_body: Dict[str, Any],
|
| 302 |
+
*,
|
| 303 |
+
subject_name: Optional[str] = None,
|
| 304 |
+
) -> Dict[str, Any]:
|
| 305 |
+
"""Render a canonical receipt as an in-toto Statement v1 (SLSA-shaped).
|
| 306 |
+
|
| 307 |
+
Accepts either a DSSE envelope (from :func:`emit_szl_receipt`, whose
|
| 308 |
+
``payload`` is the base64 canonical body) or a raw body dict. The Statement's
|
| 309 |
+
single subject is bound to the receipt body's SHA-256 digest, so the
|
| 310 |
+
attestation is inseparable from the exact record. All energy fields are
|
| 311 |
+
copied verbatim (honest ``"UNAVAILABLE"`` when unmeasured).
|
| 312 |
+
"""
|
| 313 |
+
s = _shared()
|
| 314 |
+
body = _body_of(envelope_or_body)
|
| 315 |
+
subject_digest = s.Receipt(kind=CANONICAL_KIND, body=body).digest()
|
| 316 |
+
energy = body.get("energy", {})
|
| 317 |
+
predicate = s.slsa_predicate(
|
| 318 |
+
build_type=PREDICATE_TYPE,
|
| 319 |
+
external_parameters={
|
| 320 |
+
"model": body.get("model"),
|
| 321 |
+
"input_digest": body.get("input_digest"),
|
| 322 |
+
"output_digest": body.get("output_digest"),
|
| 323 |
+
},
|
| 324 |
+
internal_parameters={"policy": body.get("policy")},
|
| 325 |
+
builder_id=PREDICATE_TYPE,
|
| 326 |
+
metadata={
|
| 327 |
+
"energy_measured": bool(energy.get("measured", False)),
|
| 328 |
+
"energy_mode": energy.get("mode"),
|
| 329 |
+
# Verbatim: a float when measured, the "UNAVAILABLE" sentinel else.
|
| 330 |
+
"joules": energy.get("joules"),
|
| 331 |
+
},
|
| 332 |
+
extra={"doctrine": SPINE_DOCTRINE},
|
| 333 |
+
)
|
| 334 |
+
name = subject_name or "governed-inference-receipt/{}".format(subject_digest[:16])
|
| 335 |
+
return s.build_statement(
|
| 336 |
+
subject_name=name,
|
| 337 |
+
subject_digest=subject_digest,
|
| 338 |
+
predicate=predicate,
|
| 339 |
+
predicate_type=PREDICATE_TYPE,
|
| 340 |
+
)
|
| 341 |
+
|
| 342 |
+
|
| 343 |
+
def _body_of(envelope_or_body: Dict[str, Any]) -> Dict[str, Any]:
|
| 344 |
+
"""Return the canonical body from a DSSE envelope or pass a raw body through."""
|
| 345 |
+
if "payload" in envelope_or_body and "payloadType" in envelope_or_body:
|
| 346 |
+
import base64
|
| 347 |
+
import json
|
| 348 |
+
|
| 349 |
+
return json.loads(base64.b64decode(envelope_or_body["payload"]).decode("utf-8"))
|
| 350 |
+
return envelope_or_body
|
| 351 |
+
|
| 352 |
+
|
| 353 |
+
def verify_szl_receipt(
|
| 354 |
+
envelope: Dict[str, Any],
|
| 355 |
+
public_key_pem: Optional[Union[str, bytes]] = None,
|
| 356 |
+
) -> Tuple[bool, str]:
|
| 357 |
+
"""Verify a canonical receipt envelope. Delegates to ``szl_receipt.verify_receipt``.
|
| 358 |
+
|
| 359 |
+
Signed => ``(True, "ok")`` with the right key; keyless => the honest
|
| 360 |
+
``(False, "unsigned-honest")``; tamper/wrong-key => ``(False, ...)``.
|
| 361 |
+
"""
|
| 362 |
+
s = _shared()
|
| 363 |
+
return s.verify_receipt(envelope, public_key_pem)
|
| 364 |
+
|
| 365 |
+
|
| 366 |
+
def verify_szl_statement(
|
| 367 |
+
statement: Dict[str, Any],
|
| 368 |
+
envelope_or_body: Dict[str, Any],
|
| 369 |
+
) -> Tuple[bool, str]:
|
| 370 |
+
"""Confirm *statement* is bound to the exact canonical receipt. ``(ok, reason)``."""
|
| 371 |
+
s = _shared()
|
| 372 |
+
body = _body_of(envelope_or_body)
|
| 373 |
+
expected = s.Receipt(kind=CANONICAL_KIND, body=body).digest()
|
| 374 |
+
return s.verify_statement(
|
| 375 |
+
statement, expected_digest=expected, predicate_type=PREDICATE_TYPE
|
| 376 |
+
)
|
pyproject.toml
CHANGED
|
@@ -10,7 +10,7 @@ build-backend = "setuptools.build_meta"
|
|
| 10 |
|
| 11 |
[project]
|
| 12 |
name = "governed-inference-meter"
|
| 13 |
-
version = "0.
|
| 14 |
description = "Energy-metered, governed inference receipts: NVML joules, tokens/joule, an advisory policy gate, and a tamper-evident SHA-256 hash-chained receipt. Honest by design — MEASURED only with NVML."
|
| 15 |
readme = "README.md"
|
| 16 |
requires-python = ">=3.8"
|
|
@@ -43,9 +43,10 @@ dependencies = []
|
|
| 43 |
gpu = ["pynvml>=11.0.0"]
|
| 44 |
# torch is optional and only used to synchronize CUDA around the metered call.
|
| 45 |
torch = ["torch"]
|
| 46 |
-
# Optional DSSE/ECDSA-P256 signing
|
| 47 |
-
#
|
| 48 |
-
|
|
|
|
| 49 |
test = ["pytest"]
|
| 50 |
|
| 51 |
[project.urls]
|
|
|
|
| 10 |
|
| 11 |
[project]
|
| 12 |
name = "governed-inference-meter"
|
| 13 |
+
version = "0.3.0"
|
| 14 |
description = "Energy-metered, governed inference receipts: NVML joules, tokens/joule, an advisory policy gate, and a tamper-evident SHA-256 hash-chained receipt. Honest by design — MEASURED only with NVML."
|
| 15 |
readme = "README.md"
|
| 16 |
requires-python = ">=3.8"
|
|
|
|
| 43 |
gpu = ["pynvml>=11.0.0"]
|
| 44 |
# torch is optional and only used to synchronize CUDA around the metered call.
|
| 45 |
torch = ["torch"]
|
| 46 |
+
# Optional DSSE/ECDSA-P256 signing AND in-toto/SLSA + EU AI Act / NIST AI RMF
|
| 47 |
+
# attestation of receipts, both via the shared szl-receipt lib (one source of
|
| 48 |
+
# truth). Core stays zero-hard-dependency: these are opt-in and imported lazily.
|
| 49 |
+
sign = ["szl-receipt>=0.2.0"]
|
| 50 |
test = ["pytest"]
|
| 51 |
|
| 52 |
[project.urls]
|
tests/test_attest.py
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
|
| 3 |
+
"""Tests for the standards-interop + compliance-evidence attestation layer.
|
| 4 |
+
|
| 5 |
+
Runs WITHOUT a GPU. On a GPU-less box every receipt is honestly
|
| 6 |
+
``unmeasured``; the tests assert the attestation preserves that honesty
|
| 7 |
+
(no fabricated joules, energy-dependent controls report ``UNAVAILABLE``) and
|
| 8 |
+
that the in-toto Statement is cryptographically bound to its exact receipt.
|
| 9 |
+
|
| 10 |
+
Run directly (no pytest needed): python tests/test_attest.py
|
| 11 |
+
Or with pytest: pytest tests/
|
| 12 |
+
"""
|
| 13 |
+
import json
|
| 14 |
+
import os
|
| 15 |
+
import sys
|
| 16 |
+
|
| 17 |
+
sys.path.insert(
|
| 18 |
+
0,
|
| 19 |
+
os.path.join(os.path.dirname(__file__), "..", "build", "torch-universal"),
|
| 20 |
+
)
|
| 21 |
+
|
| 22 |
+
import governed_inference_meter as gim # noqa: E402
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def _one_receipt():
|
| 26 |
+
ch = gim.ReceiptChain()
|
| 27 |
+
rec, _ = gim.meter(
|
| 28 |
+
lambda p: p.upper(), args=("hi",),
|
| 29 |
+
model="attest-stub", tokens_in=1, tokens_out=2, chain=ch,
|
| 30 |
+
)
|
| 31 |
+
return rec
|
| 32 |
+
|
| 33 |
+
|
| 34 |
+
def test_statement_shape_and_binding():
|
| 35 |
+
rec = _one_receipt()
|
| 36 |
+
stmt = gim.to_intoto_statement(rec)
|
| 37 |
+
assert stmt["_type"] == gim.IN_TOTO_STATEMENT_TYPE
|
| 38 |
+
assert stmt["predicateType"] == gim.SZL_PREDICATE_TYPE
|
| 39 |
+
# Subject is bound to the receipt's own digest.
|
| 40 |
+
assert stmt["subject"][0]["digest"]["sha256"] == rec["digest"]
|
| 41 |
+
# SLSA-shaped predicate is present and echoes the call parameters.
|
| 42 |
+
ext = stmt["predicate"]["buildDefinition"]["externalParameters"]
|
| 43 |
+
assert ext["model"] == "attest-stub"
|
| 44 |
+
assert ext["tokens_in"] == 1 and ext["tokens_out"] == 2
|
| 45 |
+
# Verifier confirms the statement is bound to this receipt.
|
| 46 |
+
ok, why = gim.verify_statement(stmt, rec)
|
| 47 |
+
assert ok and why == "ok", (ok, why)
|
| 48 |
+
|
| 49 |
+
|
| 50 |
+
def test_verifier_rejects_wrong_receipt():
|
| 51 |
+
rec = _one_receipt()
|
| 52 |
+
stmt = gim.to_intoto_statement(rec)
|
| 53 |
+
# A different receipt (different seq/model) must NOT verify against stmt.
|
| 54 |
+
ch = gim.ReceiptChain()
|
| 55 |
+
other, _ = gim.meter(
|
| 56 |
+
lambda p: p, args=("x",), model="other", tokens_in=9, tokens_out=9,
|
| 57 |
+
chain=ch,
|
| 58 |
+
)
|
| 59 |
+
ok, why = gim.verify_statement(stmt, other)
|
| 60 |
+
assert ok is False, (ok, why)
|
| 61 |
+
|
| 62 |
+
# Tampering with the receipt body must break verification (real digest check).
|
| 63 |
+
tampered = dict(rec)
|
| 64 |
+
tampered["tokens_out"] = rec["tokens_out"] + 1
|
| 65 |
+
bad_ok, bad_why = gim.verify_statement(stmt, tampered)
|
| 66 |
+
assert bad_ok is False and bad_why == "receipt-digest-mismatch", bad_why
|
| 67 |
+
|
| 68 |
+
|
| 69 |
+
def test_energy_honesty_when_unmeasured():
|
| 70 |
+
# On a GPU-less box the receipt is unmeasured; the attestation must NOT
|
| 71 |
+
# invent joules and energy-dependent controls must report UNAVAILABLE.
|
| 72 |
+
if gim.nvml_available():
|
| 73 |
+
return # only assert the honest-degrade path when there is no GPU
|
| 74 |
+
rec = _one_receipt()
|
| 75 |
+
assert rec["mode"] == gim.MODE_UNMEASURED
|
| 76 |
+
stmt = gim.to_intoto_statement(rec)
|
| 77 |
+
md = stmt["predicate"]["runDetails"]["metadata"]
|
| 78 |
+
assert md["measured"] is False
|
| 79 |
+
assert md["joules"] is None
|
| 80 |
+
assert md["tokens_per_joule"] is None
|
| 81 |
+
|
| 82 |
+
ev = gim.compliance_evidence(rec)
|
| 83 |
+
by_id = {c["id"]: c for c in ev["controls"]}
|
| 84 |
+
assert by_id["NIST-AI-RMF-MEASURE-2.x"]["status"] == "UNAVAILABLE"
|
| 85 |
+
# Logging/record-keeping controls are supported regardless of GPU.
|
| 86 |
+
assert by_id["EU-AI-Act-Art-12"]["status"] == "supports"
|
| 87 |
+
assert by_id["EU-AI-Act-Art-19"]["status"] == "supports"
|
| 88 |
+
|
| 89 |
+
|
| 90 |
+
def test_compliance_is_evidence_not_conformity():
|
| 91 |
+
rec = _one_receipt()
|
| 92 |
+
ev = gim.compliance_evidence(rec)
|
| 93 |
+
# Doctrine: every control states what it does NOT establish.
|
| 94 |
+
for c in ev["controls"]:
|
| 95 |
+
assert c["does_not_establish"], c
|
| 96 |
+
assert "not a conformity assessment" in ev["disclaimer"].lower()
|
| 97 |
+
# Art-15 must be explicit that it does not establish model accuracy.
|
| 98 |
+
art15 = next(c for c in ev["controls"] if c["id"] == "EU-AI-Act-Art-15")
|
| 99 |
+
assert "does not establish model accuracy" in art15["does_not_establish"].lower()
|
| 100 |
+
|
| 101 |
+
|
| 102 |
+
def test_statement_is_json_serializable():
|
| 103 |
+
rec = _one_receipt()
|
| 104 |
+
bundle = gim.attest(rec)
|
| 105 |
+
# Must round-trip through canonical JSON (the bytes a DSSE signer covers).
|
| 106 |
+
s = gim.to_intoto_statement(rec)
|
| 107 |
+
from governed_inference_meter._attest import to_json # noqa: E402
|
| 108 |
+
reparsed = json.loads(to_json(s))
|
| 109 |
+
assert reparsed == s
|
| 110 |
+
assert "statement" in bundle and "compliance" in bundle
|
| 111 |
+
|
| 112 |
+
|
| 113 |
+
if __name__ == "__main__":
|
| 114 |
+
test_statement_shape_and_binding()
|
| 115 |
+
test_verifier_rejects_wrong_receipt()
|
| 116 |
+
test_energy_honesty_when_unmeasured()
|
| 117 |
+
test_compliance_is_evidence_not_conformity()
|
| 118 |
+
test_statement_is_json_serializable()
|
| 119 |
+
print("ok: all attest tests passed")
|
tests/test_spine.py
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# SPDX-License-Identifier: Apache-2.0
|
| 2 |
+
# © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
|
| 3 |
+
"""PCGI spine fold: a metered inference as ONE canonical szl-receipt.
|
| 4 |
+
|
| 5 |
+
Proves the doctrine contract for the WAVE-2 spine UNIFY:
|
| 6 |
+
* The canonical receipt binds model id + input digest + output digest +
|
| 7 |
+
governing policy id + energy, using the shared szl-receipt shapes (no new
|
| 8 |
+
receipt shape is invented).
|
| 9 |
+
* Determinism: identical inputs => byte-identical canonical body/digest.
|
| 10 |
+
* A signed receipt verifies; a wrong key does not; tamper is rejected.
|
| 11 |
+
* Energy honesty: MEASURED joules are bound verbatim; unmeasured energy is the
|
| 12 |
+
literal "UNAVAILABLE" sentinel — never a fabricated joule.
|
| 13 |
+
* The in-toto Statement is cryptographically bound to its exact receipt.
|
| 14 |
+
|
| 15 |
+
Runs WITHOUT a GPU. On a GPU-less box every metered call is honestly unmeasured
|
| 16 |
+
and the tests assert exactly that honest-degrade behavior.
|
| 17 |
+
|
| 18 |
+
Run directly (no pytest needed): python tests/test_spine.py
|
| 19 |
+
Or with pytest: pytest tests/
|
| 20 |
+
"""
|
| 21 |
+
import base64
|
| 22 |
+
import json
|
| 23 |
+
import os
|
| 24 |
+
import sys
|
| 25 |
+
|
| 26 |
+
sys.path.insert(
|
| 27 |
+
0,
|
| 28 |
+
os.path.join(os.path.dirname(__file__), "..", "build", "torch-universal"),
|
| 29 |
+
)
|
| 30 |
+
|
| 31 |
+
import governed_inference_meter as gim # noqa: E402
|
| 32 |
+
from szl_receipt import generate_keypair, verify_receipt # noqa: E402
|
| 33 |
+
|
| 34 |
+
|
| 35 |
+
def _body(env):
|
| 36 |
+
return json.loads(base64.b64decode(env["payload"]).decode("utf-8"))
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
def test_binds_the_five_pcgi_fields():
|
| 40 |
+
env = gim.emit_szl_receipt(
|
| 41 |
+
model="llm-7b",
|
| 42 |
+
input="hello",
|
| 43 |
+
output="olleh",
|
| 44 |
+
policy_id="default-allow",
|
| 45 |
+
policy_decision="allow",
|
| 46 |
+
policy_reason="allow_all",
|
| 47 |
+
)
|
| 48 |
+
body = _body(env)
|
| 49 |
+
assert body["model"] == "llm-7b"
|
| 50 |
+
assert body["input_digest"] == "sha256:" + gim.digest("hello")
|
| 51 |
+
assert body["output_digest"] == "sha256:" + gim.digest("olleh")
|
| 52 |
+
assert body["policy"]["id"] == "default-allow"
|
| 53 |
+
assert body["policy"]["decision"] == "allow"
|
| 54 |
+
assert "energy" in body and "joules" in body["energy"]
|
| 55 |
+
# Uses the canonical szl-receipt kind (not a new shape).
|
| 56 |
+
assert env["payloadType"].startswith("application/vnd.szl.receipt")
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
def test_energy_unavailable_is_honest_not_fabricated():
|
| 60 |
+
# No energy provided => honest UNAVAILABLE, never a fabricated joule.
|
| 61 |
+
env = gim.emit_szl_receipt(model="m", input="i", output="o")
|
| 62 |
+
e = _body(env)["energy"]
|
| 63 |
+
assert e["measured"] is False
|
| 64 |
+
assert e["joules"] == gim.ENERGY_UNAVAILABLE
|
| 65 |
+
assert e["joules"] == "UNAVAILABLE"
|
| 66 |
+
|
| 67 |
+
|
| 68 |
+
def test_energy_measured_is_bound_verbatim():
|
| 69 |
+
# When the meter DID measure, joules are copied verbatim (the one real place).
|
| 70 |
+
env = gim.emit_szl_receipt(
|
| 71 |
+
model="m",
|
| 72 |
+
input="i",
|
| 73 |
+
output="o",
|
| 74 |
+
energy={"mode": gim.MODE_ENERGY_COUNTER, "joules": 12.5},
|
| 75 |
+
)
|
| 76 |
+
e = _body(env)["energy"]
|
| 77 |
+
assert e["measured"] is True
|
| 78 |
+
assert e["mode"] == gim.MODE_ENERGY_COUNTER
|
| 79 |
+
assert e["joules"] == 12.5
|
| 80 |
+
|
| 81 |
+
|
| 82 |
+
def test_determinism_byte_identical_canonical():
|
| 83 |
+
kw = dict(
|
| 84 |
+
model="m", input={"prompt": "x", "n": 3}, output=["a", "b"],
|
| 85 |
+
policy_id="p1", policy_decision="allow", policy_reason="ok",
|
| 86 |
+
energy={"mode": gim.MODE_ENERGY_COUNTER, "joules": 3.25},
|
| 87 |
+
)
|
| 88 |
+
e1 = gim.emit_szl_receipt(**kw)
|
| 89 |
+
e2 = gim.emit_szl_receipt(**kw)
|
| 90 |
+
# Canonical payload + digest are byte-identical for identical inputs.
|
| 91 |
+
assert e1["payload"] == e2["payload"]
|
| 92 |
+
assert e1["digest"] == e2["digest"]
|
| 93 |
+
assert _body(e1) == _body(e2)
|
| 94 |
+
|
| 95 |
+
|
| 96 |
+
def test_signed_receipt_verifies_and_wrong_key_fails():
|
| 97 |
+
priv, pub = generate_keypair()
|
| 98 |
+
env = gim.emit_szl_receipt(
|
| 99 |
+
model="m", input="i", output="o", sign_key=priv, organ="meter",
|
| 100 |
+
)
|
| 101 |
+
assert env["signed"] is True and env["organ"] == "meter"
|
| 102 |
+
ok, why = gim.verify_szl_receipt(env, pub)
|
| 103 |
+
assert ok and why == "ok", (ok, why)
|
| 104 |
+
# Delegation matches the shared library directly.
|
| 105 |
+
assert verify_receipt(env, pub) == (ok, why)
|
| 106 |
+
# Wrong key must NOT verify (real crypto).
|
| 107 |
+
_, other_pub = generate_keypair()
|
| 108 |
+
bad_ok, _ = gim.verify_szl_receipt(env, other_pub)
|
| 109 |
+
assert bad_ok is False
|
| 110 |
+
|
| 111 |
+
|
| 112 |
+
def test_keyless_is_unsigned_honest():
|
| 113 |
+
env = gim.emit_szl_receipt(model="m", input="i", output="o") # no key
|
| 114 |
+
assert env["signed"] is False
|
| 115 |
+
ok, why = gim.verify_szl_receipt(env)
|
| 116 |
+
assert (ok, why) == (False, "unsigned-honest")
|
| 117 |
+
|
| 118 |
+
|
| 119 |
+
def test_tamper_is_rejected():
|
| 120 |
+
priv, pub = generate_keypair()
|
| 121 |
+
env = gim.emit_szl_receipt(
|
| 122 |
+
model="m", input="i", output="o", sign_key=priv, organ="meter",
|
| 123 |
+
)
|
| 124 |
+
# Tamper the output digest inside the signed payload; signature must fail.
|
| 125 |
+
body = _body(env)
|
| 126 |
+
body["output_digest"] = "sha256:" + "0" * 64
|
| 127 |
+
tampered = dict(env)
|
| 128 |
+
tampered["payload"] = base64.b64encode(
|
| 129 |
+
json.dumps(body, sort_keys=True, separators=(",", ":")).encode("utf-8")
|
| 130 |
+
).decode("ascii")
|
| 131 |
+
ok, _ = gim.verify_szl_receipt(tampered, pub)
|
| 132 |
+
assert ok is False
|
| 133 |
+
|
| 134 |
+
|
| 135 |
+
def test_statement_binds_to_exact_receipt():
|
| 136 |
+
env = gim.emit_szl_receipt(
|
| 137 |
+
model="m", input="i", output="o",
|
| 138 |
+
energy={"mode": gim.MODE_ENERGY_COUNTER, "joules": 7.0},
|
| 139 |
+
)
|
| 140 |
+
stmt = gim.to_statement(env)
|
| 141 |
+
assert stmt["_type"] == "https://in-toto.io/Statement/v1"
|
| 142 |
+
assert stmt["predicateType"] == gim.PREDICATE_TYPE
|
| 143 |
+
ext = stmt["predicate"]["buildDefinition"]["externalParameters"]
|
| 144 |
+
assert ext["model"] == "m"
|
| 145 |
+
md = stmt["predicate"]["runDetails"]["metadata"]
|
| 146 |
+
assert md["energy_measured"] is True and md["joules"] == 7.0
|
| 147 |
+
ok, why = gim.verify_szl_statement(stmt, env)
|
| 148 |
+
assert ok and why == "ok", (ok, why)
|
| 149 |
+
# A statement for one receipt must not verify against a different receipt.
|
| 150 |
+
other = gim.emit_szl_receipt(model="other", input="x", output="y")
|
| 151 |
+
bad_ok, _ = gim.verify_szl_statement(stmt, other)
|
| 152 |
+
assert bad_ok is False
|
| 153 |
+
|
| 154 |
+
|
| 155 |
+
def test_end_to_end_meter_szl_receipt_honest_degrade():
|
| 156 |
+
priv, pub = generate_keypair()
|
| 157 |
+
env, out = gim.meter_szl_receipt(
|
| 158 |
+
lambda p: p.upper(), args=("hi",), model="t",
|
| 159 |
+
policy_id="default-allow", sign_key=priv, organ="meter",
|
| 160 |
+
)
|
| 161 |
+
assert out == "HI"
|
| 162 |
+
body = _body(env)
|
| 163 |
+
assert body["model"] == "t"
|
| 164 |
+
assert body["input_digest"].startswith("sha256:")
|
| 165 |
+
assert body["output_digest"] == "sha256:" + gim.digest("HI")
|
| 166 |
+
# On a GPU-less box energy must be honest UNAVAILABLE, never fabricated.
|
| 167 |
+
if not gim.nvml_available():
|
| 168 |
+
assert body["energy"]["measured"] is False
|
| 169 |
+
assert body["energy"]["joules"] == "UNAVAILABLE"
|
| 170 |
+
ok, why = gim.verify_szl_receipt(env, pub)
|
| 171 |
+
assert ok and why == "ok", (ok, why)
|
| 172 |
+
|
| 173 |
+
|
| 174 |
+
def test_deny_binds_null_output_and_unavailable_energy():
|
| 175 |
+
env, out = gim.meter_szl_receipt(
|
| 176 |
+
lambda p: p, args=("p",), model="t",
|
| 177 |
+
policy_id="lockdown", policy=gim.deny_all,
|
| 178 |
+
)
|
| 179 |
+
assert out is None
|
| 180 |
+
body = _body(env)
|
| 181 |
+
assert body["policy"]["decision"] == gim.DENY
|
| 182 |
+
assert body["output_digest"] == "sha256:" + gim.digest(None)
|
| 183 |
+
assert body["energy"]["joules"] == "UNAVAILABLE"
|
| 184 |
+
|
| 185 |
+
|
| 186 |
+
def test_from_meter_receipt_fold_preserves_energy_state():
|
| 187 |
+
ch = gim.ReceiptChain()
|
| 188 |
+
rec, out = gim.meter(
|
| 189 |
+
lambda p: p.upper(), args=("hi",), model="foldme",
|
| 190 |
+
tokens_in=1, tokens_out=2, chain=ch,
|
| 191 |
+
)
|
| 192 |
+
env = gim.from_meter_receipt(rec, input="hi", output=out, policy_id="p")
|
| 193 |
+
body = _body(env)
|
| 194 |
+
assert body["model"] == "foldme"
|
| 195 |
+
# Energy binding must mirror the meter receipt's real measured/unmeasured state.
|
| 196 |
+
if rec["mode"] == gim.MODE_UNMEASURED:
|
| 197 |
+
assert body["energy"]["measured"] is False
|
| 198 |
+
assert body["energy"]["joules"] == "UNAVAILABLE"
|
| 199 |
+
else:
|
| 200 |
+
assert body["energy"]["measured"] is True
|
| 201 |
+
assert body["energy"]["joules"] == rec["joules"]
|
| 202 |
+
|
| 203 |
+
|
| 204 |
+
if __name__ == "__main__":
|
| 205 |
+
failures = 0
|
| 206 |
+
for name, obj in sorted(globals().items()):
|
| 207 |
+
if name.startswith("test_") and callable(obj):
|
| 208 |
+
try:
|
| 209 |
+
obj()
|
| 210 |
+
print(f"PASS {name}")
|
| 211 |
+
except AssertionError as e: # noqa: PERF203
|
| 212 |
+
failures += 1
|
| 213 |
+
print(f"FAIL {name}: {e}")
|
| 214 |
+
print(f"\n{'ALL PASS' if failures == 0 else str(failures) + ' FAILED'}")
|
| 215 |
+
sys.exit(1 if failures else 0)
|