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.
@@ -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
+ )