szl-kernels 0.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- szl_kernels/__init__.py +286 -0
- szl_kernels/_chain.py +372 -0
- szl_kernels/_kernel_api.py +167 -0
- szl_kernels/_ops.py +269 -0
- szl_kernels/estate.py +344 -0
- szl_kernels/metadata.json +22 -0
- szl_kernels/miniembed.py +549 -0
- szl_kernels/retrieval.py +172 -0
- szl_kernels-0.2.0.dist-info/METADATA +601 -0
- szl_kernels-0.2.0.dist-info/RECORD +13 -0
- szl_kernels-0.2.0.dist-info/WHEEL +5 -0
- szl_kernels-0.2.0.dist-info/licenses/LICENSE +202 -0
- szl_kernels-0.2.0.dist-info/top_level.txt +1 -0
szl_kernels/__init__.py
ADDED
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
|
|
3
|
+
"""szl_kernels — SZL Holdings' unified governed-kernel SUITE.
|
|
4
|
+
|
|
5
|
+
ONE get_kernel-discoverable package that ties the three governed kernels plus
|
|
6
|
+
the energy meter into a single suite with a SHARED, op-agnostic
|
|
7
|
+
``UnifiedReceiptChain`` — cross-kernel provenance in one auditable forward pass.
|
|
8
|
+
This is the gap the Kernel Hub leaders leave open: they optimize FLOPs per op;
|
|
9
|
+
SZL governs provenance ACROSS ops.
|
|
10
|
+
|
|
11
|
+
Suite members (each independently published as its own Hub kernel):
|
|
12
|
+
* governed_norm -> SZLHOLDINGS/szl-governed-norm (RMSNorm/LayerNorm + receipts)
|
|
13
|
+
* lambda_gate -> SZLHOLDINGS/szl-lambda-gate (advisory Λ gate; Conjecture 1)
|
|
14
|
+
* energy_core -> szl_energy_core / governed-inference-meter (MEASURED joules)
|
|
15
|
+
* govsign -> SZLHOLDINGS/szl-govsign (signed governance attestation; DSSE / in-toto)
|
|
16
|
+
* blocked -> SZLHOLDINGS/szl-blocked (honest-BLOCKED first-class state + EU AI Act Annex IV)
|
|
17
|
+
* provctl -> SZLHOLDINGS/szl-provctl (provenance-DAG verify + in-toto v1 / SLSA v1 interop + per-kernel MEASURED energy)
|
|
18
|
+
|
|
19
|
+
The first three are the NUMERIC core exercised by the shared forward pass.
|
|
20
|
+
govsign + blocked are GOVERNANCE-LAYER series companions: govsign makes a
|
|
21
|
+
verdict third-party-verifiable (sign/verify offline), and blocked makes a
|
|
22
|
+
refusal a first-class, provenanced state (the op never runs — no fake-green)
|
|
23
|
+
and derives an EU AI Act Annex IV DRAFT skeleton from the same chain.
|
|
24
|
+
|
|
25
|
+
Companion table (NOT a numeric kernel, NOT a transformer LM, NOT Chaski/Khipu):
|
|
26
|
+
* MiniEmbed -> SZL-MiniEmbed v1 (PPMI+TruncatedSVD word-embedding table)
|
|
27
|
+
|
|
28
|
+
Discover + use the suite:
|
|
29
|
+
|
|
30
|
+
from kernels import get_kernel
|
|
31
|
+
suite = get_kernel("SZLHOLDINGS/szl-kernels", version=1, trust_remote_code=True)
|
|
32
|
+
print(suite.list_kernels()) # {'governed_norm':..., 'lambda_gate':..., 'energy_core':...}
|
|
33
|
+
print(suite.list_series()) # {'govsign':..., 'blocked':..., 'provctl':...}
|
|
34
|
+
print(suite.selfcheck()) # one-shot suite health (CPU only)
|
|
35
|
+
|
|
36
|
+
# ONE shared chain spanning multiple ops:
|
|
37
|
+
chain = suite.UnifiedReceiptChain()
|
|
38
|
+
import torch
|
|
39
|
+
x = torch.randn(4, 64)
|
|
40
|
+
y = suite.governed_rms_norm(chain, x, eps=1e-6)
|
|
41
|
+
gate = suite.governed_lambda_gate(chain, torch.tensor([0.9, 0.8, 0.95]), threshold=0.5)
|
|
42
|
+
e = suite.governed_measure_energy(chain) # None joules when no NVML — never faked
|
|
43
|
+
ok, depth, brk = chain.verify() # the WHOLE pass verifies as one chain
|
|
44
|
+
print(chain.kernels_touched()) # ['governed_norm','lambda_gate','energy_core']
|
|
45
|
+
|
|
46
|
+
# Flagship composition — a governed transformer sub-block:
|
|
47
|
+
blk = suite.GovernedBlock()
|
|
48
|
+
res = blk.forward(x, gov_axes=torch.tensor([0.95, 0.9, 0.92]))
|
|
49
|
+
print(res["chain_ok"], res["chain_depth"], res["kernels_touched"])
|
|
50
|
+
|
|
51
|
+
HONESTY (SZL doctrine v11):
|
|
52
|
+
* Λ is the weighted-geometric-mean ADVISORY aggregator; its uniqueness is
|
|
53
|
+
Conjecture 1 (OPEN). A recorded gate "pass" is advisory, NEVER proven trust.
|
|
54
|
+
* Energy joules are MEASURED-only (real NVML delta). No GPU/NVML => None /
|
|
55
|
+
UNAVAILABLE_NO_NVML, NEVER a fabricated joule.
|
|
56
|
+
* Receipt digests are SHA3-256 integrity fingerprints — tamper-evidence +
|
|
57
|
+
ordering, NOT signatures and NOT proof of authorship.
|
|
58
|
+
* This is a UNIVERSAL (pure-Python) suite: a correctness + provenance
|
|
59
|
+
reference, not a hand-tuned CUDA speed record. No fabricated benchmarks.
|
|
60
|
+
"""
|
|
61
|
+
from typing import Any, Dict
|
|
62
|
+
|
|
63
|
+
import torch
|
|
64
|
+
|
|
65
|
+
from ._chain import GENESIS, UnifiedReceiptChain, tensor_digest
|
|
66
|
+
from ._ops import (
|
|
67
|
+
GovernedBlock,
|
|
68
|
+
governed_layer_norm,
|
|
69
|
+
governed_lambda_gate,
|
|
70
|
+
governed_measure_energy,
|
|
71
|
+
governed_rms_norm,
|
|
72
|
+
)
|
|
73
|
+
from .miniembed import MiniEmbed, PUBLISHED_SHA256
|
|
74
|
+
from .retrieval import governed_cosine_topk
|
|
75
|
+
from .estate import (
|
|
76
|
+
ESTATE,
|
|
77
|
+
cuda_status,
|
|
78
|
+
get_estate_member,
|
|
79
|
+
list_estate,
|
|
80
|
+
probe_estate,
|
|
81
|
+
probe_member,
|
|
82
|
+
)
|
|
83
|
+
|
|
84
|
+
__all__ = [
|
|
85
|
+
"UnifiedReceiptChain",
|
|
86
|
+
"tensor_digest",
|
|
87
|
+
"GENESIS",
|
|
88
|
+
"governed_rms_norm",
|
|
89
|
+
"governed_cosine_topk",
|
|
90
|
+
"governed_layer_norm",
|
|
91
|
+
"governed_lambda_gate",
|
|
92
|
+
"governed_measure_energy",
|
|
93
|
+
"GovernedBlock",
|
|
94
|
+
"MiniEmbed",
|
|
95
|
+
"PUBLISHED_SHA256",
|
|
96
|
+
"list_kernels",
|
|
97
|
+
"list_series",
|
|
98
|
+
"get_member",
|
|
99
|
+
"selfcheck",
|
|
100
|
+
"ESTATE",
|
|
101
|
+
"list_estate",
|
|
102
|
+
"probe_estate",
|
|
103
|
+
"probe_member",
|
|
104
|
+
"get_estate_member",
|
|
105
|
+
"cuda_status",
|
|
106
|
+
"DOCTRINE_FOOTER",
|
|
107
|
+
"PROVENANCE",
|
|
108
|
+
"__version__",
|
|
109
|
+
]
|
|
110
|
+
|
|
111
|
+
__version__ = "0.2.0"
|
|
112
|
+
|
|
113
|
+
DOCTRINE_FOOTER = (
|
|
114
|
+
"SZL Holdings · unified governed-kernel suite · cross-kernel provenance · "
|
|
115
|
+
"Λ = Conjecture 1 (advisory) · energy MEASURED-only · honesty over checklist"
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
# Suite registry: maps a suite-member key to its Hub coordinates + role. In
|
|
119
|
+
# production, get_member() would resolve these via kernels.get_kernel(); the
|
|
120
|
+
# reference package ships byte-faithful numerics so it runs standalone.
|
|
121
|
+
_REGISTRY: Dict[str, Dict[str, str]] = {
|
|
122
|
+
"governed_norm": {
|
|
123
|
+
"hub_id": "SZLHOLDINGS/szl-governed-norm",
|
|
124
|
+
"role": "RMSNorm/LayerNorm + SHA3-256 hash-chained receipts",
|
|
125
|
+
"honesty": "integrity fingerprint, not a signature",
|
|
126
|
+
},
|
|
127
|
+
"lambda_gate": {
|
|
128
|
+
"hub_id": "SZLHOLDINGS/szl-lambda-gate",
|
|
129
|
+
"role": "advisory Λ weighted-geometric-mean gate",
|
|
130
|
+
"honesty": "Λ uniqueness = Conjecture 1 (open); advisory, NOT proven trust",
|
|
131
|
+
},
|
|
132
|
+
"energy_core": {
|
|
133
|
+
"hub_id": "SZLHOLDINGS/governed-inference-meter",
|
|
134
|
+
"role": "MEASURED-joule energy accounting (real NVML delta)",
|
|
135
|
+
"honesty": "no GPU/NVML => UNAVAILABLE_NO_NVML, joules None — never fabricated",
|
|
136
|
+
},
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# Governance-layer series companions (not part of the numeric forward pass).
|
|
140
|
+
# Each is independently published and operates on the SAME UnifiedReceiptChain
|
|
141
|
+
# provenance, extending the suite from "govern provenance ACROSS ops" to
|
|
142
|
+
# "sign that provenance" and "refuse-and-record honestly."
|
|
143
|
+
_SERIES: Dict[str, Dict[str, str]] = {
|
|
144
|
+
"govsign": {
|
|
145
|
+
"hub_id": "SZLHOLDINGS/szl-govsign",
|
|
146
|
+
"role": "signed governance attestation (DSSE / in-toto, ECDSA P-256)",
|
|
147
|
+
"honesty": "signature proves authorship+integrity, NOT Λ uniqueness; proven_trust locked False; a BLOCKED verdict is signed as BLOCKED",
|
|
148
|
+
},
|
|
149
|
+
"blocked": {
|
|
150
|
+
"hub_id": "SZLHOLDINGS/szl-blocked",
|
|
151
|
+
"role": "honest-BLOCKED first-class state + EU AI Act Annex IV DRAFT derivation",
|
|
152
|
+
"honesty": "a BLOCKED op never executes (no fake-green); Annex IV output is a DRAFT skeleton, NOT legal advice",
|
|
153
|
+
},
|
|
154
|
+
"provctl": {
|
|
155
|
+
"hub_id": "SZLHOLDINGS/szl-provctl",
|
|
156
|
+
"role": "provenance-DAG verify + in-toto v1 / SLSA v1 interop + per-kernel MEASURED energy",
|
|
157
|
+
"honesty": "in-toto/SLSA field names spec-exact; proven_trust locked False; energy MEASURED-only (never fabricated); honest-BLOCKED DAG nodes surfaced, never dropped",
|
|
158
|
+
},
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
PROVENANCE = {
|
|
162
|
+
"suite": "szl_kernels",
|
|
163
|
+
"members": _REGISTRY,
|
|
164
|
+
"series_companions": _SERIES,
|
|
165
|
+
"miniembed": {
|
|
166
|
+
"kind": "distributional_word_embedding_table",
|
|
167
|
+
"not": ["transformer_lm", "chaski", "khipu"],
|
|
168
|
+
"files": {"vectors": "vectors.npz", "vocab": "vocab.json"},
|
|
169
|
+
"method": "PPMI+TruncatedSVD",
|
|
170
|
+
"receipt_chain": "UnifiedReceiptChain",
|
|
171
|
+
},
|
|
172
|
+
"lean_repo": "szl-holdings/lutar-lean",
|
|
173
|
+
"doi_lutar_lean": "10.5281/zenodo.20434308",
|
|
174
|
+
"lambda_status": "Conjecture 1 (open) — uniqueness unproven; advisory only",
|
|
175
|
+
"shared_chain": "UnifiedReceiptChain — op-agnostic SHA3-256 cross-kernel provenance",
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def list_kernels() -> Dict[str, Dict[str, str]]:
|
|
180
|
+
"""Return the suite registry: member key -> {hub_id, role, honesty}."""
|
|
181
|
+
return {k: dict(v) for k, v in _REGISTRY.items()}
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
def list_series() -> Dict[str, Dict[str, str]]:
|
|
185
|
+
"""Return the governance-layer series companions (govsign, blocked, provctl).
|
|
186
|
+
|
|
187
|
+
These extend the numeric suite with signed attestation (govsign),
|
|
188
|
+
honest-BLOCKED + EU AI Act Annex IV derivation (blocked), and provenance-DAG
|
|
189
|
+
verification + in-toto/SLSA interop + per-kernel MEASURED energy (provctl).
|
|
190
|
+
They operate on the same UnifiedReceiptChain but are not part of the numeric
|
|
191
|
+
forward pass.
|
|
192
|
+
"""
|
|
193
|
+
return {k: dict(v) for k, v in _SERIES.items()}
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
def get_member(key: str) -> Dict[str, str]:
|
|
197
|
+
"""Resolve one suite member's Hub coordinates + honest role string."""
|
|
198
|
+
if key not in _REGISTRY:
|
|
199
|
+
raise KeyError(f"unknown suite member {key!r}; have {list(_REGISTRY)}")
|
|
200
|
+
return dict(_REGISTRY[key])
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
def selfcheck() -> Dict[str, Any]:
|
|
204
|
+
"""One-shot CPU-only suite health check; never raises.
|
|
205
|
+
|
|
206
|
+
Proves the suite's CENTRAL claim end-to-end: a single shared chain spans
|
|
207
|
+
governed_norm + lambda_gate + energy_core in ONE forward pass, verifies as
|
|
208
|
+
one tamper-evident sequence, AND a deliberately mutated copy fails
|
|
209
|
+
verification (so the tamper-evidence is real, not decorative).
|
|
210
|
+
|
|
211
|
+
Returns {ok, version, checks:{...}, chain_head, kernels_touched,
|
|
212
|
+
tamper_detected, error}.
|
|
213
|
+
"""
|
|
214
|
+
checks: Dict[str, bool] = {}
|
|
215
|
+
error = None
|
|
216
|
+
chain_head = GENESIS
|
|
217
|
+
kernels_touched = []
|
|
218
|
+
tamper_detected = False
|
|
219
|
+
try:
|
|
220
|
+
torch.manual_seed(0)
|
|
221
|
+
x = torch.randn(4, 64, dtype=torch.float32)
|
|
222
|
+
w = torch.randn(64, dtype=torch.float32)
|
|
223
|
+
|
|
224
|
+
chain = UnifiedReceiptChain()
|
|
225
|
+
|
|
226
|
+
# norm matches a fp32 RMSNorm reference
|
|
227
|
+
y = governed_rms_norm(chain, x, weight=w, eps=1e-6)
|
|
228
|
+
ref = (x * torch.rsqrt(x.pow(2).mean(-1, keepdim=True) + 1e-6)) * w
|
|
229
|
+
checks["norm_correct"] = bool(torch.allclose(y, ref, rtol=1e-5, atol=1e-5))
|
|
230
|
+
|
|
231
|
+
# advisory Λ gate runs and is recorded as advisory
|
|
232
|
+
gate = governed_lambda_gate(
|
|
233
|
+
chain, torch.tensor([0.9, 0.8, 0.95]), threshold=0.5
|
|
234
|
+
)
|
|
235
|
+
checks["lambda_advisory"] = bool(gate["advisory"] is True)
|
|
236
|
+
|
|
237
|
+
# energy is MEASURED-only: no NVML here => joules None, honest label
|
|
238
|
+
e = governed_measure_energy(chain)
|
|
239
|
+
checks["energy_honest"] = bool(
|
|
240
|
+
e["joules"] is None and e["label"] == "UNAVAILABLE_NO_NVML"
|
|
241
|
+
)
|
|
242
|
+
|
|
243
|
+
# the WHOLE multi-op pass verifies as ONE chain
|
|
244
|
+
ok, depth, brk = chain.verify()
|
|
245
|
+
checks["cross_kernel_verify"] = bool(ok and depth == 3 and brk == -1)
|
|
246
|
+
chain_head = chain.head()
|
|
247
|
+
kernels_touched = chain.kernels_touched()
|
|
248
|
+
checks["spans_three_kernels"] = bool(
|
|
249
|
+
kernels_touched == ["governed_norm", "lambda_gate", "energy_core"]
|
|
250
|
+
)
|
|
251
|
+
|
|
252
|
+
# offline re-verification of the exported chain
|
|
253
|
+
ok2, _, _ = UnifiedReceiptChain.verify_json(chain.to_json())
|
|
254
|
+
checks["offline_reverify"] = bool(ok2)
|
|
255
|
+
|
|
256
|
+
# tamper-evidence is REAL: mutate one recorded attr and confirm break
|
|
257
|
+
blob = chain.to_json()
|
|
258
|
+
import json as _json
|
|
259
|
+
recs = _json.loads(blob)
|
|
260
|
+
recs[0]["attrs"]["eps"] = 9.99e-3 # flip a recorded value
|
|
261
|
+
ok3, _, brk3 = UnifiedReceiptChain.verify_json(_json.dumps(recs))
|
|
262
|
+
tamper_detected = bool((not ok3) and brk3 == 0)
|
|
263
|
+
checks["tamper_detected"] = tamper_detected
|
|
264
|
+
|
|
265
|
+
# GovernedBlock composition runs and self-verifies
|
|
266
|
+
blk = GovernedBlock()
|
|
267
|
+
res = blk.forward(x, weight=w, gov_axes=torch.tensor([0.95, 0.9, 0.92]))
|
|
268
|
+
checks["block_forward"] = bool(
|
|
269
|
+
res["chain_ok"]
|
|
270
|
+
and res["chain_depth"] == 4
|
|
271
|
+
and res["kernels_touched"]
|
|
272
|
+
== ["governed_norm", "lambda_gate", "energy_core", "governed_block"]
|
|
273
|
+
)
|
|
274
|
+
except Exception as exc: # never raise from a health probe
|
|
275
|
+
error = f"{type(exc).__name__}: {exc}"
|
|
276
|
+
|
|
277
|
+
ok = bool(checks) and all(checks.values()) and error is None
|
|
278
|
+
return {
|
|
279
|
+
"ok": ok,
|
|
280
|
+
"version": __version__,
|
|
281
|
+
"checks": checks,
|
|
282
|
+
"chain_head": chain_head,
|
|
283
|
+
"kernels_touched": kernels_touched,
|
|
284
|
+
"tamper_detected": tamper_detected,
|
|
285
|
+
"error": error,
|
|
286
|
+
}
|
szl_kernels/_chain.py
ADDED
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
|
|
3
|
+
"""SHA3-256 linked receipts shared by SZL kernel operations.
|
|
4
|
+
|
|
5
|
+
Unanchored verification checks internal consistency, not complete history,
|
|
6
|
+
authorship or execution. An independently retained head/depth checkpoint can
|
|
7
|
+
bind the expected extent and recorded contents. The caller must authenticate
|
|
8
|
+
that checkpoint separately and bind it to the relevant run/source/policy.
|
|
9
|
+
|
|
10
|
+
Receipts preserve the legacy hashed fields and digest encoding. Timestamps
|
|
11
|
+
remain outside the hashed body; finite timestamps are not authenticated time.
|
|
12
|
+
Tensor fingerprints retain the existing rounded-float32 encoding; equal
|
|
13
|
+
fingerprints are not evidence that the original tensor bytes were equal.
|
|
14
|
+
|
|
15
|
+
Public methods return detached snapshots. This prevents ordinary aliasing from
|
|
16
|
+
mutating stored records, but is not protection against a hostile Python process.
|
|
17
|
+
No network, persistent storage, signing, training or publication is performed.
|
|
18
|
+
"""
|
|
19
|
+
from __future__ import annotations
|
|
20
|
+
|
|
21
|
+
import copy
|
|
22
|
+
import hashlib
|
|
23
|
+
import hmac
|
|
24
|
+
import json
|
|
25
|
+
import math
|
|
26
|
+
import re
|
|
27
|
+
import struct
|
|
28
|
+
import threading
|
|
29
|
+
import time
|
|
30
|
+
from typing import Any, Dict, List, Optional, Tuple
|
|
31
|
+
|
|
32
|
+
try: # torch is optional at import time so the chain stays inspectable headless
|
|
33
|
+
import torch # noqa: F401
|
|
34
|
+
_HAS_TORCH = True
|
|
35
|
+
except Exception: # pragma: no cover - exercised only in torch-less envs
|
|
36
|
+
_HAS_TORCH = False
|
|
37
|
+
|
|
38
|
+
# Genesis link: 64 hex zeros, identical to szl_governed_norm and szl_energy_core
|
|
39
|
+
# so the unified chain's genesis is byte-compatible with the per-kernel chains.
|
|
40
|
+
GENESIS = "0" * 64
|
|
41
|
+
|
|
42
|
+
# Default rounding precision for tensor fingerprints. MUST match
|
|
43
|
+
# szl_governed_norm._receipt._tensor_digest so a unified-chain norm receipt's
|
|
44
|
+
# out_digest is bit-identical to the standalone kernel's.
|
|
45
|
+
_DECIMALS = 6
|
|
46
|
+
_DIGEST_CHUNK_ELEMENTS = 4096
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def tensor_digest(t: "Any", decimals: int = _DECIMALS) -> str:
|
|
50
|
+
"""Deterministic SHA3-256 over a tensor's rounded float32 contents.
|
|
51
|
+
|
|
52
|
+
Identical scheme to szl_governed_norm._receipt._tensor_digest: round to a
|
|
53
|
+
fixed number of decimals, integerize, hash the raw little-endian bytes. This
|
|
54
|
+
makes the digest stable across devices/dtypes for the same logical values
|
|
55
|
+
(tiny FP noise won't change it). Integrity fingerprint, NOT a signature.
|
|
56
|
+
|
|
57
|
+
Falls back to hashing the repr only if torch is unavailable (headless
|
|
58
|
+
inspection); in a real kernel run torch is always present.
|
|
59
|
+
"""
|
|
60
|
+
if _HAS_TORCH and hasattr(t, "detach"):
|
|
61
|
+
flat = t.detach().to(torch.float32).reshape(-1)
|
|
62
|
+
scaled = torch.round(flat * (10 ** decimals)).to(torch.int64).cpu()
|
|
63
|
+
digest = hashlib.sha3_256()
|
|
64
|
+
for chunk in scaled.split(_DIGEST_CHUNK_ELEMENTS):
|
|
65
|
+
values = chunk.tolist()
|
|
66
|
+
digest.update(struct.pack(f"<{len(values)}q", *values))
|
|
67
|
+
return digest.hexdigest()
|
|
68
|
+
return hashlib.sha3_256(repr(t).encode("utf-8")).hexdigest()
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
class UnifiedReceiptChain:
|
|
72
|
+
"""Append-only, SHA3-256 hash-chained log spanning MANY kernel ops.
|
|
73
|
+
|
|
74
|
+
Each receipt body is canonical JSON with a fixed, sorted schema:
|
|
75
|
+
{seq, kernel, op, attrs, prev}
|
|
76
|
+
where:
|
|
77
|
+
seq -- 0-based position in the chain
|
|
78
|
+
kernel -- which suite member emitted it ('governed_norm', 'lambda_gate',
|
|
79
|
+
'energy_core', or a composed block name)
|
|
80
|
+
op -- the operation ('rms_norm', 'lambda_gate', 'measure_energy', ...)
|
|
81
|
+
attrs -- an op-agnostic, JSON-able dict of honest, reproducible
|
|
82
|
+
attributes (shapes, eps, out_digest, advisory Λ fields,
|
|
83
|
+
energy label/joules, ...). NEVER fabricated.
|
|
84
|
+
prev -- digest of the previous receipt (GENESIS for seq 0)
|
|
85
|
+
|
|
86
|
+
digest = SHA3-256 over the canonical JSON of {seq,kernel,op,attrs,prev}
|
|
87
|
+
(ts is excluded so the digest is reproducible offline).
|
|
88
|
+
|
|
89
|
+
verify() re-walks the chain and returns (ok, depth, first_break_seq):
|
|
90
|
+
it checks every sequence number, digest and prev-link. Without a separately
|
|
91
|
+
retained checkpoint this establishes only internal consistency: a valid
|
|
92
|
+
prefix or a fully recomputed history can still pass. Use expected_head and
|
|
93
|
+
expected_depth from trusted external custody to detect such replacement.
|
|
94
|
+
Timestamps are finite metadata but remain outside the hashed body. This is
|
|
95
|
+
not a signature, a proof of execution, or protection from a hostile process.
|
|
96
|
+
Public read methods return detached snapshots, not references to storage.
|
|
97
|
+
"""
|
|
98
|
+
|
|
99
|
+
def __init__(self) -> None:
|
|
100
|
+
self._lock = threading.RLock()
|
|
101
|
+
self._records: List[Dict[str, Any]] = []
|
|
102
|
+
|
|
103
|
+
# -- canonical hashing (sorted keys, tight separators, strict no-NaN) --
|
|
104
|
+
@staticmethod
|
|
105
|
+
def _digest_body(body: Dict[str, Any]) -> str:
|
|
106
|
+
raw = json.dumps(
|
|
107
|
+
body, sort_keys=True, separators=(",", ":"), allow_nan=False
|
|
108
|
+
).encode("utf-8")
|
|
109
|
+
return hashlib.sha3_256(raw).hexdigest()
|
|
110
|
+
|
|
111
|
+
def emit(self, kernel: str, op: str, attrs: Dict[str, Any]) -> Dict[str, Any]:
|
|
112
|
+
"""Append one op-agnostic receipt and return it (with digest + ts).
|
|
113
|
+
|
|
114
|
+
``attrs`` must be JSON-able and finite (no NaN/Inf) — a non-finite value
|
|
115
|
+
would make the receipt un-attestable by a strict third-party verifier,
|
|
116
|
+
so it is rejected at hash time by allow_nan=False. Callers screen
|
|
117
|
+
non-finite numbers to None/UNKNOWN upstream (the energy kernel already
|
|
118
|
+
does this).
|
|
119
|
+
"""
|
|
120
|
+
with self._lock:
|
|
121
|
+
prev = self._records[-1]["digest"] if self._records else GENESIS
|
|
122
|
+
seq = len(self._records)
|
|
123
|
+
body = {
|
|
124
|
+
"seq": seq,
|
|
125
|
+
"kernel": str(kernel),
|
|
126
|
+
"op": str(op),
|
|
127
|
+
# Normalize to a detached JSON value before hashing. Later caller
|
|
128
|
+
# mutation cannot invalidate stored history or future prev-links.
|
|
129
|
+
"attrs": self._snapshot_attrs(attrs),
|
|
130
|
+
"prev": prev,
|
|
131
|
+
}
|
|
132
|
+
digest = self._digest_body(body)
|
|
133
|
+
rec = dict(body, digest=digest, ts=time.time())
|
|
134
|
+
self._records.append(rec)
|
|
135
|
+
return copy.deepcopy(rec)
|
|
136
|
+
|
|
137
|
+
@staticmethod
|
|
138
|
+
def _snapshot_attrs(attrs: Dict[str, Any]) -> Dict[str, Any]:
|
|
139
|
+
if not isinstance(attrs, dict):
|
|
140
|
+
raise TypeError("receipt attrs must be a JSON object")
|
|
141
|
+
return json.loads(json.dumps(attrs, sort_keys=True, allow_nan=False))
|
|
142
|
+
|
|
143
|
+
def checkpoint(self) -> Dict[str, Any]:
|
|
144
|
+
"""Atomically capture depth/head; preserve it OUTSIDE this chain.
|
|
145
|
+
|
|
146
|
+
This unsigned dictionary has no authentication by itself. The caller
|
|
147
|
+
must bind it to a separately trusted signed receipt or retained record.
|
|
148
|
+
Two separate calls to count() and head() are not an atomic checkpoint.
|
|
149
|
+
"""
|
|
150
|
+
with self._lock:
|
|
151
|
+
if not self._verify_records(self._records)[0]:
|
|
152
|
+
raise ValueError("cannot checkpoint an inconsistent chain")
|
|
153
|
+
return {
|
|
154
|
+
"schema": "szl.receipt-checkpoint/v1",
|
|
155
|
+
"depth": len(self._records),
|
|
156
|
+
"head": self._records[-1]["digest"] if self._records else GENESIS,
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# -- convenience emitters that enforce the honesty schema per kernel ----
|
|
160
|
+
def emit_norm(self, op: str, x: "Any", out: "Any", eps: float) -> Dict[str, Any]:
|
|
161
|
+
"""Record a governed-norm op. out_digest matches szl_governed_norm."""
|
|
162
|
+
return self.emit(
|
|
163
|
+
"governed_norm",
|
|
164
|
+
op,
|
|
165
|
+
{
|
|
166
|
+
"in_shape": list(getattr(x, "shape", [])),
|
|
167
|
+
"in_dtype": str(getattr(x, "dtype", "")).replace("torch.", ""),
|
|
168
|
+
"eps": float(eps),
|
|
169
|
+
"out_digest": tensor_digest(out),
|
|
170
|
+
},
|
|
171
|
+
)
|
|
172
|
+
|
|
173
|
+
def emit_lambda(
|
|
174
|
+
self,
|
|
175
|
+
score: float,
|
|
176
|
+
threshold: float,
|
|
177
|
+
passed: bool,
|
|
178
|
+
k: int,
|
|
179
|
+
) -> Dict[str, Any]:
|
|
180
|
+
"""Record an ADVISORY Λ-gate evaluation.
|
|
181
|
+
|
|
182
|
+
``advisory`` is hard-coded True and ``lambda_status`` is stamped on every
|
|
183
|
+
entry so the chain itself is self-documenting: a recorded pass is NEVER
|
|
184
|
+
proven trust (Λ uniqueness = Conjecture 1, open).
|
|
185
|
+
"""
|
|
186
|
+
return self.emit(
|
|
187
|
+
"lambda_gate",
|
|
188
|
+
"lambda_gate",
|
|
189
|
+
{
|
|
190
|
+
"score": float(score),
|
|
191
|
+
"threshold": float(threshold),
|
|
192
|
+
"passed": bool(passed),
|
|
193
|
+
"k": int(k),
|
|
194
|
+
"advisory": True,
|
|
195
|
+
"lambda_status": "Conjecture 1 (open) — advisory only, NOT proven trust",
|
|
196
|
+
},
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
def emit_energy(self, measurement: Dict[str, Any]) -> Dict[str, Any]:
|
|
200
|
+
"""Record an energy reading VERBATIM (label + joules as-given).
|
|
201
|
+
|
|
202
|
+
``joules`` may be None (UNAVAILABLE/UNKNOWN) — it is recorded as None,
|
|
203
|
+
never upgraded to a fabricated number. ``label`` is the kernel's honest
|
|
204
|
+
MEASURED/SAMPLE/UNAVAILABLE_NO_NVML/ESTIMATE/UNKNOWN string.
|
|
205
|
+
"""
|
|
206
|
+
joules = measurement.get("joules", None)
|
|
207
|
+
return self.emit(
|
|
208
|
+
"energy_core",
|
|
209
|
+
"measure_energy",
|
|
210
|
+
{
|
|
211
|
+
"label": str(measurement.get("label", "UNKNOWN")),
|
|
212
|
+
"joules": (None if joules is None else float(joules)),
|
|
213
|
+
"source": str(measurement.get("source", "")),
|
|
214
|
+
},
|
|
215
|
+
)
|
|
216
|
+
|
|
217
|
+
# -- read surface --------------------------------------------------------
|
|
218
|
+
def head(self) -> str:
|
|
219
|
+
with self._lock:
|
|
220
|
+
return self._records[-1]["digest"] if self._records else GENESIS
|
|
221
|
+
|
|
222
|
+
def count(self) -> int:
|
|
223
|
+
with self._lock:
|
|
224
|
+
return len(self._records)
|
|
225
|
+
|
|
226
|
+
def tail(self, n: int = 10) -> List[Dict[str, Any]]:
|
|
227
|
+
if type(n) is not int or n < 0:
|
|
228
|
+
raise ValueError("tail length must be a nonnegative integer")
|
|
229
|
+
with self._lock:
|
|
230
|
+
return copy.deepcopy(self._records[-n:]) if n else []
|
|
231
|
+
|
|
232
|
+
def kernels_touched(self) -> List[str]:
|
|
233
|
+
"""Distinct kernels that appear in the chain, in first-seen order.
|
|
234
|
+
|
|
235
|
+
This summarizes the recorded kernel labels; it does not prove that
|
|
236
|
+
any named implementation actually executed.
|
|
237
|
+
"""
|
|
238
|
+
with self._lock:
|
|
239
|
+
seen: List[str] = []
|
|
240
|
+
for r in self._records:
|
|
241
|
+
if r["kernel"] not in seen:
|
|
242
|
+
seen.append(r["kernel"])
|
|
243
|
+
return seen
|
|
244
|
+
|
|
245
|
+
@staticmethod
|
|
246
|
+
def _validate_checkpoint(expected_head: Optional[str], expected_depth: Optional[int]) -> None:
|
|
247
|
+
if expected_head is None and expected_depth is None:
|
|
248
|
+
return
|
|
249
|
+
if (not isinstance(expected_head, str)
|
|
250
|
+
or re.fullmatch(r"[0-9a-f]{64}", expected_head) is None
|
|
251
|
+
or type(expected_depth) is not int or expected_depth < 0):
|
|
252
|
+
raise ValueError("checkpoint requires a full lowercase head and nonnegative depth")
|
|
253
|
+
if (expected_depth == 0) != (expected_head == GENESIS):
|
|
254
|
+
raise ValueError("genesis checkpoint must have exactly zero depth")
|
|
255
|
+
|
|
256
|
+
@staticmethod
|
|
257
|
+
def _verify_records(
|
|
258
|
+
records: Any,
|
|
259
|
+
*,
|
|
260
|
+
expected_head: Optional[str] = None,
|
|
261
|
+
expected_depth: Optional[int] = None,
|
|
262
|
+
) -> Tuple[bool, int, int]:
|
|
263
|
+
# Checkpoint argument errors are programmer errors, not corrupt history.
|
|
264
|
+
UnifiedReceiptChain._validate_checkpoint(expected_head, expected_depth)
|
|
265
|
+
if not isinstance(records, list):
|
|
266
|
+
return (False, 0, 0)
|
|
267
|
+
depth = len(records)
|
|
268
|
+
# OfflineNavigator's existing deterministic projection omits ts.
|
|
269
|
+
# Only that unhashed metadata is optional; all hashed/digest fields
|
|
270
|
+
# remain required and unrelated extra fields are rejected.
|
|
271
|
+
fields = {"seq", "kernel", "op", "attrs", "prev", "digest"}
|
|
272
|
+
prev = GENESIS
|
|
273
|
+
for i, rec in enumerate(records):
|
|
274
|
+
try:
|
|
275
|
+
if (not isinstance(rec, dict) or set(rec) not in (fields, fields | {"ts"})
|
|
276
|
+
or type(rec["seq"]) is not int or rec["seq"] != i
|
|
277
|
+
or not isinstance(rec["kernel"], str)
|
|
278
|
+
or not isinstance(rec["op"], str)
|
|
279
|
+
or not isinstance(rec["attrs"], dict)
|
|
280
|
+
or not isinstance(rec["prev"], str)
|
|
281
|
+
or re.fullmatch(r"[0-9a-f]{64}", rec["prev"]) is None
|
|
282
|
+
or not isinstance(rec["digest"], str)
|
|
283
|
+
or re.fullmatch(r"[0-9a-f]{64}", rec["digest"]) is None
|
|
284
|
+
or ("ts" in rec and (type(rec["ts"]) not in (int, float)
|
|
285
|
+
or not math.isfinite(rec["ts"])))):
|
|
286
|
+
return (False, depth, i)
|
|
287
|
+
body = {key: rec[key] for key in ("seq", "kernel", "op", "attrs", "prev")}
|
|
288
|
+
actual = UnifiedReceiptChain._digest_body(body)
|
|
289
|
+
if rec["prev"] != prev or not hmac.compare_digest(rec["digest"], actual):
|
|
290
|
+
return (False, depth, i)
|
|
291
|
+
prev = rec["digest"]
|
|
292
|
+
except (ValueError, TypeError, KeyError, OverflowError, RecursionError):
|
|
293
|
+
return (False, depth, i)
|
|
294
|
+
if expected_head is not None:
|
|
295
|
+
if depth != expected_depth or not hmac.compare_digest(prev, expected_head):
|
|
296
|
+
# The observed chain is internally consistent but not the
|
|
297
|
+
# expected extent/history. Report the boundary, not a fake row.
|
|
298
|
+
return (False, depth, min(depth, expected_depth))
|
|
299
|
+
return (True, depth, -1)
|
|
300
|
+
|
|
301
|
+
def verify(
|
|
302
|
+
self,
|
|
303
|
+
*,
|
|
304
|
+
expected_head: Optional[str] = None,
|
|
305
|
+
expected_depth: Optional[int] = None,
|
|
306
|
+
) -> Tuple[bool, int, int]:
|
|
307
|
+
"""Verify consistency, optionally against a separately retained checkpoint.
|
|
308
|
+
|
|
309
|
+
Returns (ok, observed_depth, first_break). For checkpoint mismatch,
|
|
310
|
+
first_break is min(observed_depth, expected_depth), an extent boundary.
|
|
311
|
+
Unanchored success cannot detect valid-prefix truncation or rehashing.
|
|
312
|
+
"""
|
|
313
|
+
with self._lock:
|
|
314
|
+
return self._verify_records(
|
|
315
|
+
self._records, expected_head=expected_head, expected_depth=expected_depth
|
|
316
|
+
)
|
|
317
|
+
|
|
318
|
+
def export_with_checkpoint(self) -> Tuple[str, Dict[str, Any]]:
|
|
319
|
+
"""Capture one export and matching checkpoint under the same lock.
|
|
320
|
+
|
|
321
|
+
The checkpoint still needs separate authenticated custody. Keeping
|
|
322
|
+
it only beside the export cannot prevent replacement of both.
|
|
323
|
+
"""
|
|
324
|
+
with self._lock:
|
|
325
|
+
checkpoint = self.checkpoint()
|
|
326
|
+
return self.to_json(), checkpoint
|
|
327
|
+
|
|
328
|
+
def to_json(self) -> str:
|
|
329
|
+
"""Serialize stored records, not evidence of authorship or execution.
|
|
330
|
+
|
|
331
|
+
Preserve an independently trusted checkpoint to verify this export's
|
|
332
|
+
expected head and length. A checkpoint bundled only with the export
|
|
333
|
+
cannot protect against coordinated replacement of both.
|
|
334
|
+
"""
|
|
335
|
+
with self._lock:
|
|
336
|
+
return json.dumps(self._records, sort_keys=True, separators=(",", ":"), allow_nan=False)
|
|
337
|
+
|
|
338
|
+
@staticmethod
|
|
339
|
+
def verify_json(
|
|
340
|
+
blob: str,
|
|
341
|
+
*,
|
|
342
|
+
expected_head: Optional[str] = None,
|
|
343
|
+
expected_depth: Optional[int] = None,
|
|
344
|
+
) -> Tuple[bool, int, int]:
|
|
345
|
+
"""Verify strict JSON, then consistency and an optional external checkpoint.
|
|
346
|
+
|
|
347
|
+
Duplicate object keys, nonfinite numbers, malformed records and wrong
|
|
348
|
+
sequence ordinals are rejected. Invalid JSON returns (False, 0, 0).
|
|
349
|
+
No signature, origin, timestamp authenticity or execution claim follows.
|
|
350
|
+
"""
|
|
351
|
+
UnifiedReceiptChain._validate_checkpoint(expected_head, expected_depth)
|
|
352
|
+
|
|
353
|
+
def unique_object(pairs):
|
|
354
|
+
result = {}
|
|
355
|
+
for key, value in pairs:
|
|
356
|
+
if key in result:
|
|
357
|
+
raise ValueError("duplicate JSON key")
|
|
358
|
+
result[key] = value
|
|
359
|
+
return result
|
|
360
|
+
|
|
361
|
+
def reject_constant(value):
|
|
362
|
+
raise ValueError("nonfinite JSON constant")
|
|
363
|
+
|
|
364
|
+
if not isinstance(blob, str):
|
|
365
|
+
return (False, 0, 0)
|
|
366
|
+
try:
|
|
367
|
+
records = json.loads(blob, object_pairs_hook=unique_object, parse_constant=reject_constant)
|
|
368
|
+
except (ValueError, TypeError, OverflowError, RecursionError):
|
|
369
|
+
return (False, 0, 0)
|
|
370
|
+
return UnifiedReceiptChain._verify_records(
|
|
371
|
+
records, expected_head=expected_head, expected_depth=expected_depth
|
|
372
|
+
)
|