betterwithage commited on
Commit
dd0e27a
·
verified ·
1 Parent(s): 65e26a2

Publish verified torch-cpu kernel v1

Browse files

Dedicated Kernel Hub migration from legacy model commit 0494e1caa5ccd28ab946035f67190cbdcb67b608. Locally loaded with kernels 0.16.0 on CPU and passed its bounded verification.

LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ Copyright 2026 SZL Holdings
6
+
7
+ Licensed under the Apache License, Version 2.0 (the "License");
8
+ you may not use this file except in compliance with the License.
9
+ You may obtain a copy of the License at
10
+
11
+ http://www.apache.org/licenses/LICENSE-2.0
12
+
13
+ Unless required by applicable law or agreed to in writing, software
14
+ distributed under the License is distributed on an "AS IS" BASIS,
15
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ See the License for the specific language governing permissions and
17
+ limitations under the License.
18
+
19
+ The full Apache License 2.0 text is available at the URL above.
README.md ADDED
@@ -0,0 +1,137 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ tags:
3
+ - kernel
4
+ - governance
5
+ - invariants
6
+ - provenance
7
+ - receipts
8
+ - ed25519
9
+ - doi:10.5281/zenodo.19944926
10
+ library_name: kernels
11
+ license: apache-2.0
12
+ szl-governance:
13
+ verdict: ADVISORY
14
+ lambda: "Conjecture 1 (open) — uniqueness unproven; untouched by these invariants; advisory only"
15
+ provenance: "recomputes the a11oy receipt/ledger self-consistency invariants offline"
16
+ honest_blocked: "a VIOLATED invariant stays VIOLATED — statuses are never coerced to a pass"
17
+ ---
18
+
19
+ # szl-invariants
20
+
21
+ **The eight falsifiable runtime invariants of the a11oy backbone — as a `get_kernel`-discoverable, offline, stdlib-only governance kernel.** From [SZL Holdings](https://huggingface.co/SZLHOLDINGS).
22
+
23
+ > ## Honest scope box — read this first
24
+ > **This is NOT a trained model. There are NO weights** (`.safetensors` / `.bin` / `.pt` / `.gguf`).
25
+ > It is a **pure-Python, stdlib-only** governance kernel: an **offline replay of the live Alloy
26
+ > surface** — it recomputes the same eight FALSIFIABLE invariants the a11oy backbone checks live at
27
+ > `/api/invariants`, over a receipts/ledger JSONL export you already hold. No network, no torch, no
28
+ > tensors. It is `get_kernel`-discoverable purely so the SZL family loads the same way; it does not
29
+ > import torch. **Λ is not touched here and stays Conjecture 1 (open).**
30
+
31
+ ## Why it exists
32
+
33
+ Every Kernel-Hub leader competes on FLOPs. None of them let you **re-verify a serving ledger's
34
+ self-consistency offline**. This kernel does exactly that: hand it your ledger export and it recomputes,
35
+ row by row, whether the receipt chain closes on its own tail, whether failures are shaped honestly, and
36
+ whether signed receipts still verify under ed25519 — all with **no coercion**: `HOLDS / VIOLATED /
37
+ KEY_ROTATED / NO_DATA / UNAVAILABLE` are all first-class.
38
+
39
+ ## Quickstart (fully offline)
40
+
41
+ ```python
42
+ from kernels import get_kernel
43
+
44
+ # Current `kernels` (>=0.15) requires an explicit revision + trust flag for org kernels:
45
+ inv = get_kernel("SZLHOLDINGS/szl-invariants", revision="main", trust_remote_code=True)
46
+
47
+ rows = inv.load_jsonl("runs_export.jsonl") # your ledger export
48
+ samples = inv.load_jsonl("training_samples.jsonl") # optional flywheel export
49
+ pubkey = "<SPKI base64 from /api/receipts/pubkey>" # optional — enables ed25519
50
+
51
+ report = inv.run_invariants(rows, samples=samples, pubkey=pubkey)
52
+ print(report["summary"]) # {'total':8,'holds':..,'violated':..,'indeterminate':..}
53
+ for i in report["invariants"]:
54
+ print(i["id"], i["status"], i["detail"])
55
+
56
+ print(inv.selfcheck()) # demonstrates falsifiability end-to-end
57
+ ```
58
+
59
+ `verify_ed25519` prefers the audited `cryptography` backend and falls back to a **stdlib-only
60
+ pure-Python RFC 8032 verifier**, so signature checking is genuinely offline-capable with zero deps.
61
+
62
+ ## The eight invariants (all genuinely FALSIFIABLE — theater excluded)
63
+
64
+ | # | id | Predicate (holds ⇔) |
65
+ |---|---|---|
66
+ | 1 | `receipt-chain-continuity` | `rowHash == sha256(prevHash \| contentHash)` and each `prevHash` links the next-older `rowHash` (Ouroboros closure) |
67
+ | 2 | `ledger-failure-shape` | `ok=false` rows carry no `servedProvider` / `latencyMs` |
68
+ | 3 | `served-run-has-model` | `ok ∧ ¬demo ⇒ model IS NOT NULL` |
69
+ | 4 | `signed-columns-atomic` | `(receiptId, signature, keyId, receiptJson)` all-present or all-absent |
70
+ | 5 | `loop-steps-positive` | `ok ∧ ¬demo ⇒ loopSteps ≥ 1` (lower bound only — the upper bound is not persisted) |
71
+ | 6 | `receipt-ed25519-verify` | signed rows verify under the supplied key; `KEY_ROTATED` reported honestly |
72
+ | 7 | `receipt-columns-consistent` | `parse(receiptJson)` agrees with the indexed columns |
73
+ | 8 | `flywheel-lineage` | every sample with a `receiptId` joins a run with `demo=false ∧ servedNode≠null` |
74
+
75
+ > A check that **cannot fail** would be verification theater and is **deliberately excluded**. Counts are
76
+ > enumerated rows only, never a claimed total. `pubkey=None` → invariant #6 is honestly **UNAVAILABLE**
77
+ > (not a pass, not a fail); `samples=None` → invariant #8 is **UNAVAILABLE**.
78
+
79
+ ### `latentVerification` — honest analogy, not a learned embedding
80
+
81
+ The report includes a **MEASURED** `latentVerification` coverage ratio: the fraction of the enumerated
82
+ export whose trust is established purely in **hash/signature space** (ed25519 over sha256 canonical bytes).
83
+ Its docstring states the JEPA-latent-space parallel is an **ANALOGY** — the mechanism is a cryptographic
84
+ digest + signature, **NOT** a trained/predictive embedding, and it does **not** prove or upgrade Λ.
85
+
86
+ ## Tests — MEASURED, local, stdlib-only
87
+
88
+ ```
89
+ PYTHONPATH=build/torch-universal python3 -m pytest tests/ -q
90
+ 14 passed
91
+ ```
92
+
93
+ **14/14 passed** on a local `python3` run (MEASURED, stdlib-only). Each invariant is shown to genuinely
94
+ **flip to VIOLATED** on real corruption/tamper (a clean chain HOLDS; a tampered chain VIOLATED; a real
95
+ ed25519 signature HOLDS; a single tampered canonical byte VIOLATED), and missing capabilities stay
96
+ UNAVAILABLE. `selfcheck()` reports `falsifiable_demonstrated: True`.
97
+
98
+ ## Provenance
99
+
100
+ Mirrors the live a11oy backbone `/api/invariants` recompute (`artifacts/api-server/src/routes/invariants.ts`)
101
+ plus the exact chain hashing from `runLedger.ts` and `receipts.ts`. Backed by the Lean 4 formalization
102
+ [szl-holdings/lutar-lean](https://github.com/szl-holdings/lutar-lean), DOI
103
+ [10.5281/zenodo.20434308](https://doi.org/10.5281/zenodo.20434308). **Λ uniqueness = Conjecture 1 (open).**
104
+
105
+ ## Compatibility
106
+
107
+ Python 3.9+, **standard library only** — no torch, no third-party deps required (the `cryptography`
108
+ backend is used opportunistically if present, else the pure-Python fallback runs).
109
+
110
+ ## License
111
+
112
+ Apache-2.0. Copyright 2026 SZL Holdings.
113
+
114
+ ---
115
+
116
+ ## The SZL honest-model trio + the kernel suite
117
+
118
+ Part of the SZL Holdings honest-model trio — stdlib-only offline replays of the live Alloy surface:
119
+
120
+ | Model | Lane |
121
+ |---|---|
122
+ | **`szl-invariants`** (this repo) | **8 falsifiable receipt/ledger invariants, offline** |
123
+ | [`szl-ouroboros`](https://huggingface.co/SZLHOLDINGS/szl-ouroboros) | bounded-loop trace + MEASURED/DERIVED loop-tax accounting |
124
+ | [`szl-formulas`](https://huggingface.co/SZLHOLDINGS/szl-formulas) | the 21 canonical formulas with per-formula PROOF-STATUS |
125
+
126
+ Anchored by the governed-kernel suite [`szl-kernels`](https://huggingface.co/SZLHOLDINGS/szl-kernels)
127
+ (hub) and its members ([`szl-lambda-gate`](https://huggingface.co/SZLHOLDINGS/szl-lambda-gate),
128
+ [`szl-governed-norm`](https://huggingface.co/SZLHOLDINGS/szl-governed-norm),
129
+ [`governed-inference-meter`](https://huggingface.co/SZLHOLDINGS/governed-inference-meter)).
130
+
131
+ **Live substrate:** [a-11-oy.com](https://a-11-oy.com) · [a11oy Space](https://huggingface.co/spaces/SZLHOLDINGS/a11oy).
132
+
133
+ ---
134
+
135
+ <sub><b>SZL Holdings</b> · falsifiable invariants only (theater excluded) · statuses never coerced · Λ untouched = Conjecture 1 · <a href="https://a-11-oy.com">a-11-oy.com</a> · <a href="https://github.com/szl-holdings">github.com/szl-holdings</a> · <a href="https://huggingface.co/SZLHOLDINGS">huggingface.co/SZLHOLDINGS</a></sub>
136
+
137
+ *Signed-off-by: Stephen Lutar <stephenlutar2@gmail.com>*
build/torch-cpu/metadata.json ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "szl-invariants",
3
+ "id": "_szl_invariants_cpu_1055da7541",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cpu"
9
+ }
10
+ }
build/torch-cpu/szl_invariants/__init__.py ADDED
@@ -0,0 +1,878 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # © 2026 SZL Holdings · Stephen P. Lutar · ORCID 0009-0001-0110-4173
3
+ """szl_invariants — falsifiable runtime self-consistency invariants, offline.
4
+
5
+ ============================ HONEST SCOPE BOX ============================
6
+ This is NOT a trained model. There are NO weights (.safetensors/.bin/.pt/.gguf).
7
+ It is a pure-Python, stdlib-only governance kernel: it *replays* the same eight
8
+ FALSIFIABLE runtime invariants the a11oy backbone recomputes live (see
9
+ /api/invariants) over a receipts/ledger JSONL export you hold — fully offline,
10
+ no network, no torch. `get_kernel`-discoverable purely so the family loads the
11
+ same way; it does not use tensors.
12
+
13
+ DOCTRINE (mirrors artifacts/api-server/src/routes/invariants.ts):
14
+ - Every invariant here is genuinely FALSIFIABLE: real ledger corruption,
15
+ receipt tamper, or a write-path regression can VIOLATE it. A check that
16
+ cannot fail would be verification theater and is DELIBERATELY EXCLUDED.
17
+ - Statuses are NEVER coerced: HOLDS / VIOLATED / KEY_ROTATED / NO_DATA /
18
+ UNAVAILABLE are all first-class. NO_DATA (nothing to check) and UNAVAILABLE
19
+ (a capability is absent, e.g. no public key supplied) are never silently
20
+ upgraded to a pass.
21
+ - Λ (governance trust) is NOT touched here and stays Conjecture 1 — none of
22
+ these invariants prove or upgrade it. They check the ledger's shape and its
23
+ cryptographic self-consistency, not runtime correctness of any answer.
24
+ - Counts are ENUMERATED rows only, never a claimed total.
25
+ =========================================================================
26
+
27
+ Quickstart (offline):
28
+
29
+ from kernels import get_kernel
30
+ inv = get_kernel("SZLHOLDINGS/szl-invariants", revision="main", trust_remote_code=True)
31
+
32
+ rows = inv.load_jsonl("runs_export.jsonl") # your ledger export
33
+ samples = inv.load_jsonl("training_samples.jsonl") # optional flywheel export
34
+ pubkey = "<SPKI base64 from /api/receipts/pubkey>" # optional — enables ed25519
35
+
36
+ report = inv.run_invariants(rows, samples=samples, pubkey=pubkey)
37
+ print(report["summary"]) # {'total':8,'holds':..,'violated':..,'indeterminate':..}
38
+ for i in report["invariants"]:
39
+ print(i["id"], i["status"], i["detail"])
40
+ """
41
+ from __future__ import annotations
42
+
43
+ import json
44
+ from hashlib import sha256
45
+ from typing import Any, Dict, List, Optional, Sequence
46
+
47
+ __all__ = [
48
+ "run_invariants",
49
+ "load_jsonl",
50
+ "sha256_hex",
51
+ "canonical_json",
52
+ "recompute_row_hash",
53
+ "content_hash",
54
+ "verify_ed25519",
55
+ "keyid_from_spki",
56
+ "selfcheck",
57
+ "list_checks",
58
+ "INVARIANT_IDS",
59
+ "DOCTRINE",
60
+ "NOTE",
61
+ "LATENT_VERIFICATION_NOTE",
62
+ "PROVENANCE",
63
+ "DOCTRINE_FOOTER",
64
+ "__version__",
65
+ ]
66
+
67
+ __version__ = "0.1.0"
68
+
69
+ Status = str # "HOLDS" | "VIOLATED" | "KEY_ROTATED" | "NO_DATA" | "UNAVAILABLE"
70
+
71
+ DOCTRINE = (
72
+ "Runtime self-consistency invariants — MEASURED, recomputed over the "
73
+ "enumerated ledger export. DISTINCT from the Lean proof corpus: none of "
74
+ "them prove or upgrade Λ, which stays Conjecture 1. The Ouroboros closes "
75
+ "on its own tail — the receipt chain recomputes its own prior hashes, and "
76
+ "the flywheel consumes only its own verified own-metal serves."
77
+ )
78
+
79
+ NOTE = (
80
+ "Every invariant shown is FALSIFIABLE: it can be VIOLATED by real ledger "
81
+ "corruption, receipt tamper, or a write-path regression. A check that "
82
+ "cannot fail would be verification theater and is deliberately excluded. "
83
+ "Count is enumerated rows only, never a claimed total."
84
+ )
85
+
86
+ LATENT_VERIFICATION_NOTE = (
87
+ "MEASURED coverage — fraction of the enumerated export whose trust is "
88
+ "established purely in hash/signature space (ed25519 over sha256 canonical "
89
+ "bytes, never plaintext). ANALOGY to the JEPA latent-space objective "
90
+ "(verify over a compact derived space, not the raw object); the mechanism "
91
+ "is a cryptographic digest + signature, NOT a learned embedding — nothing "
92
+ "here is trained or predictive, and this does not prove or upgrade Λ. "
93
+ "tamperFailed lowers the ratio; rotated (signed under a rotated key) and "
94
+ "unsigned (rows predating signing) are honest complements, never failures."
95
+ )
96
+
97
+ PROVENANCE = {
98
+ "mirrors": "a11oy backbone /api/invariants (artifacts/api-server/src/routes/invariants.ts)",
99
+ "lean_repo": "szl-holdings/lutar-lean",
100
+ "doi_lutar_lean": "10.5281/zenodo.20434308",
101
+ "lambda_status": "Conjecture 1 (open) — uniqueness unproven; advisory only",
102
+ "trained_weights_present": False,
103
+ }
104
+
105
+ DOCTRINE_FOOTER = (
106
+ "SZL Holdings · falsifiable invariants only (theater excluded) · statuses "
107
+ "never coerced · Λ untouched = Conjecture 1 · honesty over checklist"
108
+ )
109
+
110
+ INVARIANT_IDS = [
111
+ "receipt-chain-continuity",
112
+ "ledger-failure-shape",
113
+ "served-run-has-model",
114
+ "signed-columns-atomic",
115
+ "loop-steps-positive",
116
+ "receipt-ed25519-verify",
117
+ "receipt-columns-consistent",
118
+ "flywheel-lineage",
119
+ ]
120
+
121
+
122
+ # --------------------------------------------------------------------------- #
123
+ # Canonical hashing — EXACTLY mirrors the a11oy runLedger + receipts helpers #
124
+ # (sha256 hex; canonical JSON = recursively key-sorted, no whitespace). #
125
+ # --------------------------------------------------------------------------- #
126
+ def sha256_hex(text: str) -> str:
127
+ """sha256 hex of a UTF-8 string (mirror of receipts.sha256Hex)."""
128
+ return sha256(text.encode("utf-8")).hexdigest()
129
+
130
+
131
+ def canonical_json(value: Any) -> str:
132
+ """Recursively key-sorted, whitespace-free JSON — mirror of
133
+ receipts.canonicalJson. `None` (JS null) is kept; keys mapping to `None`
134
+ that represent an absent field are still serialized as null (the a11oy
135
+ core-facts object never carries `undefined`)."""
136
+ if value is None or isinstance(value, (str, int, float, bool)):
137
+ return json.dumps(value, ensure_ascii=False, separators=(",", ":"))
138
+ if isinstance(value, (list, tuple)):
139
+ return "[" + ",".join(canonical_json(v) for v in value) + "]"
140
+ if isinstance(value, dict):
141
+ keys = sorted(k for k in value.keys() if value[k] is not _UNDEFINED)
142
+ return "{" + ",".join(
143
+ json.dumps(k, ensure_ascii=False, separators=(",", ":"))
144
+ + ":"
145
+ + canonical_json(value[k])
146
+ for k in keys
147
+ ) + "}"
148
+ raise TypeError(f"cannot canonicalize {type(value)!r}")
149
+
150
+
151
+ class _Undefined:
152
+ __slots__ = ()
153
+
154
+
155
+ _UNDEFINED = _Undefined()
156
+
157
+
158
+ def content_hash(row: Dict[str, Any]) -> str:
159
+ """Recompute a row's contentHash exactly as runLedger.insertRow does: the
160
+ signed canonical receipt when present, else canonical core-facts."""
161
+ receipt_json = row.get("receiptJson")
162
+ if receipt_json is not None:
163
+ return sha256_hex(receipt_json)
164
+ core = {
165
+ "endpoint": row.get("endpoint"),
166
+ "mode": row.get("mode"),
167
+ "requestedProvider": row.get("requestedProvider"),
168
+ "servedProvider": row.get("servedProvider"),
169
+ "model": row.get("model"),
170
+ "servedNode": row.get("servedNode"),
171
+ "demo": row.get("demo"),
172
+ "ok": row.get("ok"),
173
+ "latencyMs": row.get("latencyMs"),
174
+ "error": row.get("error"),
175
+ }
176
+ return sha256_hex(canonical_json(core))
177
+
178
+
179
+ def recompute_row_hash(prev_hash: str, row: Dict[str, Any]) -> str:
180
+ """rowHash = sha256Hex(`${prevHash}|${contentHash}`) — mirror of insertRow."""
181
+ return sha256_hex(f"{prev_hash}|{content_hash(row)}")
182
+
183
+
184
+ def keyid_from_spki(spki_base64: str) -> str:
185
+ """keyId = first 16 hex of sha256(SPKI DER) — mirror of receipts.deriveKeys."""
186
+ import base64
187
+
188
+ der = base64.b64decode(spki_base64)
189
+ return sha256(der).hexdigest()[:16]
190
+
191
+
192
+ def verify_ed25519(
193
+ canonical: str,
194
+ signature_base64: str,
195
+ spki_base64: str,
196
+ ) -> bool:
197
+ """ed25519 verify over the EXACT canonical bytes. Prefers the audited
198
+ `cryptography` backend; falls back to a stdlib-only pure-Python RFC 8032
199
+ verifier when `cryptography` is not installed (so verification is genuinely
200
+ offline-capable). Returns False on any failure — never coerced True."""
201
+ import base64
202
+
203
+ try:
204
+ sig = base64.b64decode(signature_base64)
205
+ der = base64.b64decode(spki_base64)
206
+ except Exception:
207
+ return False
208
+ msg = canonical.encode("utf-8")
209
+ try: # audited backend first
210
+ from cryptography.hazmat.primitives.serialization import (
211
+ load_der_public_key,
212
+ )
213
+ from cryptography.exceptions import InvalidSignature
214
+
215
+ pub = load_der_public_key(der)
216
+ try:
217
+ pub.verify(sig, msg) # type: ignore[call-arg]
218
+ return True
219
+ except InvalidSignature:
220
+ return False
221
+ except Exception:
222
+ return False
223
+ except Exception:
224
+ pass
225
+ # stdlib-only fallback: raw key is the trailing 32 bytes of the SPKI DER.
226
+ if len(der) < 32 or len(sig) != 64:
227
+ return False
228
+ raw = der[-32:]
229
+ try:
230
+ return _ed25519_verify_pure(raw, msg, sig)
231
+ except Exception:
232
+ return False
233
+
234
+
235
+ # --------------------------------------------------------------------------- #
236
+ # Pure-Python ed25519 verify (RFC 8032 reference form; stdlib hashlib only). #
237
+ # Used ONLY when `cryptography` is unavailable — keeps the kernel stdlib-only. #
238
+ # --------------------------------------------------------------------------- #
239
+ _p = 2 ** 255 - 19
240
+ _d = (-121665 * pow(121666, _p - 2, _p)) % _p
241
+ _I = pow(2, (_p - 1) // 4, _p)
242
+ _L = 2 ** 252 + 27742317777372353535851937790883648493
243
+
244
+
245
+ def _xrecover(y: int) -> int:
246
+ xx = (y * y - 1) * pow(_d * y * y + 1, _p - 2, _p)
247
+ x = pow(xx, (_p + 3) // 8, _p)
248
+ if (x * x - xx) % _p != 0:
249
+ x = (x * _I) % _p
250
+ if x % 2 != 0:
251
+ x = _p - x
252
+ return x
253
+
254
+
255
+ _By = (4 * pow(5, _p - 2, _p)) % _p
256
+ _Bx = _xrecover(_By)
257
+ _B = (_Bx % _p, _By % _p, 1, (_Bx * _By) % _p)
258
+
259
+
260
+ def _edwards_add(P, Q):
261
+ x1, y1, z1, t1 = P
262
+ x2, y2, z2, t2 = Q
263
+ a = ((y1 - x1) * (y2 - x2)) % _p
264
+ b = ((y1 + x1) * (y2 + x2)) % _p
265
+ c = (2 * t1 * t2 * _d) % _p
266
+ dd = (2 * z1 * z2) % _p
267
+ e = b - a
268
+ f = dd - c
269
+ g = dd + c
270
+ h = b + a
271
+ return ((e * f) % _p, (g * h) % _p, (f * g) % _p, (e * h) % _p)
272
+
273
+
274
+ def _scalarmult(P, e):
275
+ if e == 0:
276
+ return (0, 1, 1, 0)
277
+ Q = _scalarmult(P, e // 2)
278
+ Q = _edwards_add(Q, Q)
279
+ if e & 1:
280
+ Q = _edwards_add(Q, P)
281
+ return Q
282
+
283
+
284
+ def _to_affine(P):
285
+ x, y, z, _t = P
286
+ zi = pow(z, _p - 2, _p)
287
+ return (x * zi) % _p, (y * zi) % _p
288
+
289
+
290
+ def _decodeint(s: bytes) -> int:
291
+ return int.from_bytes(s, "little")
292
+
293
+
294
+ def _decodepoint(s: bytes):
295
+ y = int.from_bytes(s, "little") & ((1 << 255) - 1)
296
+ x = _xrecover(y)
297
+ if x & 1 != (s[31] >> 7) & 1:
298
+ x = _p - x
299
+ P = (x, y, 1, (x * y) % _p)
300
+ return P
301
+
302
+
303
+ def _ed25519_verify_pure(public: bytes, msg: bytes, sig: bytes) -> bool:
304
+ A = _decodepoint(public)
305
+ R = _decodepoint(sig[:32])
306
+ S = _decodeint(sig[32:])
307
+ h = _decodeint(sha256_512(sig[:32] + public + msg))
308
+ left = _to_affine(_scalarmult(_B, S))
309
+ right = _to_affine(_edwards_add(R, _scalarmult(A, h)))
310
+ return left == right
311
+
312
+
313
+ def sha256_512(b: bytes) -> bytes:
314
+ from hashlib import sha512
315
+
316
+ return sha512(b).digest()
317
+
318
+
319
+ # --------------------------------------------------------------------------- #
320
+ # I/O helper #
321
+ # --------------------------------------------------------------------------- #
322
+ def load_jsonl(path: str) -> List[Dict[str, Any]]:
323
+ """Parse a JSONL export into a list of dict rows. One JSON object per line;
324
+ blank lines skipped. No coercion — a malformed line raises."""
325
+ rows: List[Dict[str, Any]] = []
326
+ with open(path, "r", encoding="utf-8") as fh:
327
+ for line in fh:
328
+ line = line.strip()
329
+ if not line:
330
+ continue
331
+ rows.append(json.loads(line))
332
+ return rows
333
+
334
+
335
+ # --------------------------------------------------------------------------- #
336
+ # Invariant builders #
337
+ # --------------------------------------------------------------------------- #
338
+ def _inv(
339
+ id: str,
340
+ title: str,
341
+ predicate: str,
342
+ doctrine_ref: str,
343
+ status: Status,
344
+ checked: int,
345
+ violations: int,
346
+ worst_row_id: Optional[Any],
347
+ detail: str,
348
+ ) -> Dict[str, Any]:
349
+ return {
350
+ "id": id,
351
+ "title": title,
352
+ "predicate": predicate,
353
+ "doctrineRef": doctrine_ref,
354
+ "basis": "MEASURED",
355
+ "status": status,
356
+ "checked": checked,
357
+ "violations": violations,
358
+ "worstRowId": worst_row_id,
359
+ "detail": detail,
360
+ }
361
+
362
+
363
+ def _receipt_chain_continuity(rows: List[Dict[str, Any]]) -> Dict[str, Any]:
364
+ # Order newest-first by id, mirroring the app's `order by id desc`.
365
+ ordered = sorted(
366
+ rows, key=lambda r: (r.get("id") is None, r.get("id")), reverse=True
367
+ )
368
+ entries = []
369
+ for r in ordered:
370
+ verified: Optional[bool] = None
371
+ rh, ph = r.get("rowHash"), r.get("prevHash")
372
+ if rh is not None and ph is not None:
373
+ verified = rh == recompute_row_hash(ph, r)
374
+ entries.append({"prevHash": ph, "rowHash": rh, "verified": verified})
375
+ links_ok = True
376
+ for i in range(len(entries) - 1):
377
+ cur, older = entries[i], entries[i + 1]
378
+ if cur["prevHash"] is not None and older["rowHash"] is not None:
379
+ if cur["prevHash"] != older["rowHash"]:
380
+ links_ok = False
381
+ checked = sum(1 for e in entries if e["verified"] is not None)
382
+ failed = sum(1 for e in entries if e["verified"] is False)
383
+ predate = sum(1 for e in entries if e["verified"] is None)
384
+ if not entries:
385
+ cs = "EMPTY"
386
+ elif any(e["verified"] is False for e in entries) or not links_ok:
387
+ cs = "BROKEN"
388
+ elif any(e["verified"] is None for e in entries):
389
+ cs = "PARTIAL"
390
+ else:
391
+ cs = "VERIFIED"
392
+ status = "NO_DATA" if cs == "EMPTY" else "VIOLATED" if cs == "BROKEN" else "HOLDS"
393
+ detail = {
394
+ "VERIFIED": f"all {checked} hashed links recompute exactly",
395
+ "PARTIAL": f"{checked} link(s) recompute; {predate} row(s) predate the hash chain (stated, not a failure)",
396
+ "BROKEN": f"chain BROKEN — {failed} link(s) failed to recompute or a prev/row hash mismatched",
397
+ "EMPTY": "no rows in the export",
398
+ }[cs]
399
+ return _inv(
400
+ "receipt-chain-continuity",
401
+ "Receipt chain recomputes over its own tail (Ouroboros closure)",
402
+ "for every ledger row with a stored hash: rowHash === sha256(prevHash | contentHash), and each row's prevHash === the next-older row's rowHash",
403
+ "notarized receipt chain — tamper-evident, recomputed per request",
404
+ status,
405
+ checked,
406
+ failed,
407
+ None,
408
+ detail,
409
+ )
410
+
411
+
412
+ def _ledger_failure_shape(rows: List[Dict[str, Any]]) -> Dict[str, Any]:
413
+ subject = [r for r in rows if not r.get("ok")]
414
+ bad = [
415
+ r
416
+ for r in subject
417
+ if r.get("servedProvider") is not None or r.get("latencyMs") is not None
418
+ ]
419
+ status = "NO_DATA" if not subject else "VIOLATED" if bad else "HOLDS"
420
+ detail = (
421
+ f"{len(bad)} failed row(s) carry a served-provider or latency claim — ledger corruption or a write-path regression"
422
+ if bad
423
+ else f"{len(subject)} failed row(s), all shaped honestly (catches corruption/regression, not runtime correctness)"
424
+ )
425
+ return _inv(
426
+ "ledger-failure-shape",
427
+ "Failed runs claim no serving provider or latency",
428
+ "for every row where ok = false: servedProvider IS NULL and latencyMs IS NULL",
429
+ "honest failure — a failed run never fabricates a serve",
430
+ status,
431
+ len(subject),
432
+ len(bad),
433
+ (bad[0].get("id") if bad else None),
434
+ detail,
435
+ )
436
+
437
+
438
+ def _served_run_has_model(rows: List[Dict[str, Any]]) -> Dict[str, Any]:
439
+ subject = [r for r in rows if r.get("ok") and not r.get("demo")]
440
+ bad = [r for r in subject if r.get("model") is None]
441
+ status = "NO_DATA" if not subject else "VIOLATED" if bad else "HOLDS"
442
+ detail = (
443
+ f"{len(bad)} live-served row(s) name no model — provenance gap"
444
+ if bad
445
+ else f"{len(subject)} live-served row(s), all name a model"
446
+ )
447
+ return _inv(
448
+ "served-run-has-model",
449
+ "Live-served runs name the model that served them",
450
+ "for every row where ok = true and demo = false: model IS NOT NULL",
451
+ "provenance — a real serve always records its model",
452
+ status,
453
+ len(subject),
454
+ len(bad),
455
+ (bad[0].get("id") if bad else None),
456
+ detail,
457
+ )
458
+
459
+
460
+ def _signed_columns_atomic(rows: List[Dict[str, Any]]) -> Dict[str, Any]:
461
+ bad = []
462
+ for r in rows:
463
+ flags = [
464
+ r.get("receiptId") is not None,
465
+ r.get("signature") is not None,
466
+ r.get("keyId") is not None,
467
+ r.get("receiptJson") is not None,
468
+ ]
469
+ if not (all(flags) or not any(flags)):
470
+ bad.append(r)
471
+ status = "NO_DATA" if not rows else "VIOLATED" if bad else "HOLDS"
472
+ detail = (
473
+ f"{len(bad)} row(s) have a partial receipt column set — write-path regression or tamper"
474
+ if bad
475
+ else f"{len(rows)} row(s), each fully signed or honestly unsigned"
476
+ )
477
+ return _inv(
478
+ "signed-columns-atomic",
479
+ "Receipt columns are all-present or all-absent",
480
+ "for every row: (receiptId, signature, keyId, receiptJson) are ALL present or ALL absent",
481
+ "no partial receipts — a row is signed or honestly unsigned, never half",
482
+ status,
483
+ len(rows),
484
+ len(bad),
485
+ (bad[0].get("id") if bad else None),
486
+ detail,
487
+ )
488
+
489
+
490
+ def _loop_steps_positive(rows: List[Dict[str, Any]]) -> Dict[str, Any]:
491
+ subject = [r for r in rows if r.get("ok") and not r.get("demo")]
492
+ bad = [
493
+ r
494
+ for r in subject
495
+ if r.get("loopSteps") is None or (r.get("loopSteps") or 0) < 1
496
+ ]
497
+ status = "NO_DATA" if not subject else "VIOLATED" if bad else "HOLDS"
498
+ detail = (
499
+ f"{len(bad)} served row(s) recorded no loop step"
500
+ if bad
501
+ else f"{len(subject)} served row(s), each took at least one step"
502
+ )
503
+ return _inv(
504
+ "loop-steps-positive",
505
+ "Every live-served run took at least one loop step",
506
+ "for every row where ok = true and demo = false: loopSteps >= 1 (lower bound only — the per-run upper bound targets.length is not persisted, so it is not asserted)",
507
+ "LOOP_DOCTRINE — bounded, terminating, receipt-closed",
508
+ status,
509
+ len(subject),
510
+ len(bad),
511
+ (bad[0].get("id") if bad else None),
512
+ detail,
513
+ )
514
+
515
+
516
+ def _receipt_ed25519_verify(
517
+ rows: List[Dict[str, Any]],
518
+ signed_rows: List[Dict[str, Any]],
519
+ tally: Dict[str, Any],
520
+ ) -> Dict[str, Any]:
521
+ if tally["keyId"] is None:
522
+ return _inv(
523
+ "receipt-ed25519-verify",
524
+ "Each signed receipt verifies under ed25519",
525
+ "for every signed row: ed25519_verify(receiptJson, signature) === true under the supplied key",
526
+ "notarized receipts — signature checks the exact canonical bytes",
527
+ "UNAVAILABLE",
528
+ 0,
529
+ 0,
530
+ None,
531
+ "no public key supplied — signatures cannot be verified offline (honest UNAVAILABLE, not a judgment on the receipts)",
532
+ )
533
+ if not signed_rows:
534
+ status = "NO_DATA"
535
+ detail = "no signed rows in the export"
536
+ elif tally["hardFail"]:
537
+ status = "VIOLATED"
538
+ detail = f"{tally['hardFail']} signed receipt(s) fail ed25519 verification — tamper or drift"
539
+ elif tally["rotated"]:
540
+ status = "KEY_ROTATED"
541
+ detail = f"all {len(signed_rows)} signed; {tally['rotated']} were signed under a rotated key (honest KEY_ROTATED, not a tamper verdict)"
542
+ else:
543
+ status = "HOLDS"
544
+ detail = f"all {len(signed_rows)} signed receipts verify under the supplied key"
545
+ return _inv(
546
+ "receipt-ed25519-verify",
547
+ "Each signed receipt verifies under ed25519",
548
+ "for every signed row: ed25519_verify(receiptJson, signature) === true under the supplied key",
549
+ "notarized receipts — signature checks the exact canonical bytes",
550
+ status,
551
+ len(signed_rows),
552
+ tally["hardFail"],
553
+ tally["worst"],
554
+ detail,
555
+ )
556
+
557
+
558
+ def _receipt_columns_consistent(rows: List[Dict[str, Any]]) -> Dict[str, Any]:
559
+ with_receipt = [r for r in rows if r.get("receiptJson") is not None]
560
+ bad = 0
561
+ worst = None
562
+ for r in with_receipt:
563
+ try:
564
+ p = json.loads(r["receiptJson"])
565
+ except Exception:
566
+ bad += 1
567
+ worst = worst if worst is not None else r.get("id")
568
+ continue
569
+ mismatch = (
570
+ p.get("receiptId") != r.get("receiptId")
571
+ or p.get("goalSha256") != r.get("goalSha256")
572
+ or (p.get("outputSha256") if p.get("outputSha256") is not None else None)
573
+ != r.get("outputSha256")
574
+ or p.get("keyId") != r.get("keyId")
575
+ )
576
+ if mismatch:
577
+ bad += 1
578
+ worst = worst if worst is not None else r.get("id")
579
+ status = "NO_DATA" if not with_receipt else "VIOLATED" if bad else "HOLDS"
580
+ detail = (
581
+ f"{bad} receipt(s) disagree with their indexed columns — canonical/column drift or tamper"
582
+ if bad
583
+ else f"{len(with_receipt)} receipt(s), each agreeing exactly with its columns"
584
+ )
585
+ return _inv(
586
+ "receipt-columns-consistent",
587
+ "Receipt payload matches its indexed columns",
588
+ "for every row with a stored receipt: parse(receiptJson).{receiptId, goalSha256, outputSha256, keyId} === the row's indexed columns",
589
+ "canonical/column consistency — the signed payload and the columns cannot disagree",
590
+ status,
591
+ len(with_receipt),
592
+ bad,
593
+ worst,
594
+ detail,
595
+ )
596
+
597
+
598
+ def _flywheel_lineage(
599
+ rows: List[Dict[str, Any]],
600
+ samples: Optional[List[Dict[str, Any]]],
601
+ ) -> Dict[str, Any]:
602
+ title = "Flywheel eats only its own verified tail (own-metal, never demo/cloud)"
603
+ predicate = "every training sample with a receiptId joins to a runs row with demo = false and servedNode IS NOT NULL"
604
+ doctrine = "sovereign flywheel lineage — samples come only from real own-metal serves"
605
+ if samples is None:
606
+ return _inv(
607
+ "flywheel-lineage",
608
+ title,
609
+ predicate,
610
+ doctrine,
611
+ "UNAVAILABLE",
612
+ 0,
613
+ 0,
614
+ None,
615
+ "no flywheel training-sample export supplied — lineage cannot be replayed (honest UNAVAILABLE)",
616
+ )
617
+ # Offline replay of the SQL left-join by receiptId.
618
+ by_receipt = {
619
+ r.get("receiptId"): r for r in rows if r.get("receiptId") is not None
620
+ }
621
+ lineage = []
622
+ for s in samples:
623
+ rid = s.get("receiptId")
624
+ if "runFound" in s: # pre-joined export
625
+ lineage.append(s)
626
+ continue
627
+ row = by_receipt.get(rid) if rid is not None else None
628
+ lineage.append(
629
+ {
630
+ "sampleId": s.get("sampleId", s.get("id")),
631
+ "receiptId": rid,
632
+ "runFound": row is not None,
633
+ "runDemo": (row.get("demo") if row else None),
634
+ "runServedNode": (row.get("servedNode") if row else None),
635
+ }
636
+ )
637
+ linkable = [s for s in lineage if s.get("receiptId") is not None]
638
+ unlinkable = len(lineage) - len(linkable)
639
+ bad = [
640
+ s
641
+ for s in linkable
642
+ if not s.get("runFound")
643
+ or s.get("runDemo") is True
644
+ or s.get("runServedNode") is None
645
+ ]
646
+ status = "NO_DATA" if not linkable else "VIOLATED" if bad else "HOLDS"
647
+ if bad:
648
+ detail = f"{len(bad)} sample(s) trace to a demo/cloud/missing run — the lineage claim is violated"
649
+ else:
650
+ detail = f"{len(linkable)} sample(s) all trace to a real own-metal serve" + (
651
+ f"; {unlinkable} sample(s) have no receiptId to join (excluded, stated)"
652
+ if unlinkable
653
+ else ""
654
+ )
655
+ return _inv(
656
+ "flywheel-lineage",
657
+ title,
658
+ predicate,
659
+ doctrine,
660
+ status,
661
+ len(linkable),
662
+ len(bad),
663
+ (bad[0].get("sampleId") if bad else None),
664
+ detail,
665
+ )
666
+
667
+
668
+ def _ed25519_tally(
669
+ signed_rows: List[Dict[str, Any]], pubkey: Optional[str]
670
+ ) -> Dict[str, Any]:
671
+ """Verify every signed row ONCE; reused by invariant #6 and the latent
672
+ coverage metric (no second verification pass — mirrors the app)."""
673
+ if pubkey is None:
674
+ return {"keyId": None, "verified": 0, "hardFail": 0, "rotated": 0, "worst": None}
675
+ cur_key = keyid_from_spki(pubkey)
676
+ verified = hard_fail = rotated = 0
677
+ worst = None
678
+ for r in signed_rows:
679
+ ok = verify_ed25519(r["receiptJson"], r["signature"], pubkey)
680
+ if ok:
681
+ verified += 1
682
+ continue
683
+ if r.get("keyId") and r.get("keyId") != cur_key:
684
+ rotated += 1
685
+ else:
686
+ hard_fail += 1
687
+ worst = worst if worst is not None else r.get("id")
688
+ return {
689
+ "keyId": cur_key,
690
+ "verified": verified,
691
+ "hardFail": hard_fail,
692
+ "rotated": rotated,
693
+ "worst": worst,
694
+ }
695
+
696
+
697
+ def run_invariants(
698
+ rows: Optional[Sequence[Dict[str, Any]]],
699
+ samples: Optional[Sequence[Dict[str, Any]]] = None,
700
+ pubkey: Optional[str] = None,
701
+ ) -> Dict[str, Any]:
702
+ """Replay all eight falsifiable invariants + the latent-verification
703
+ coverage metric over an offline ledger export.
704
+
705
+ - `rows=None` → the entire report is UNAVAILABLE (mirrors "ledger DB
706
+ unreachable"): nothing is fabricated.
707
+ - `samples=None` → the flywheel-lineage invariant is UNAVAILABLE.
708
+ - `pubkey=None` → the ed25519 invariant + latent coverage are UNAVAILABLE.
709
+
710
+ Returns a dict with `label`, `status`, `summary`, `latentVerification`,
711
+ `invariants`, `doctrine`, `note`.
712
+ """
713
+ if rows is None:
714
+ return {
715
+ "label": "MEASURED",
716
+ "status": "UNAVAILABLE",
717
+ "reason": "no ledger export supplied",
718
+ "window": {"runsEnumerated": 0, "samplesEnumerated": 0},
719
+ "summary": {"total": 0, "holds": 0, "violated": 0, "indeterminate": 0},
720
+ "latentVerification": {
721
+ "status": "UNAVAILABLE",
722
+ "reason": "no ledger export supplied",
723
+ "enumerated": 0,
724
+ "verified": 0,
725
+ "verifiedRatio": None,
726
+ "rotated": 0,
727
+ "unsigned": 0,
728
+ "tamperFailed": 0,
729
+ "note": LATENT_VERIFICATION_NOTE,
730
+ },
731
+ "invariants": [],
732
+ "doctrine": DOCTRINE,
733
+ "note": NOTE,
734
+ }
735
+ rows = list(rows)
736
+ samples_list = list(samples) if samples is not None else None
737
+ signed_rows = [
738
+ r
739
+ for r in rows
740
+ if r.get("receiptJson") is not None and r.get("signature") is not None
741
+ ]
742
+ tally = _ed25519_tally(signed_rows, pubkey)
743
+
744
+ invariants = [
745
+ _receipt_chain_continuity(rows),
746
+ _ledger_failure_shape(rows),
747
+ _served_run_has_model(rows),
748
+ _signed_columns_atomic(rows),
749
+ _loop_steps_positive(rows),
750
+ _receipt_ed25519_verify(rows, signed_rows, tally),
751
+ _receipt_columns_consistent(rows),
752
+ _flywheel_lineage(rows, samples_list),
753
+ ]
754
+
755
+ holds = sum(1 for i in invariants if i["status"] == "HOLDS")
756
+ violated = sum(1 for i in invariants if i["status"] == "VIOLATED")
757
+ indeterminate = len(invariants) - holds - violated
758
+
759
+ if pubkey is None:
760
+ latent = {
761
+ "status": "UNAVAILABLE",
762
+ "reason": "no public key supplied — hash/signature-space verification cannot run",
763
+ "enumerated": len(rows),
764
+ "verified": 0,
765
+ "verifiedRatio": None,
766
+ "rotated": 0,
767
+ "unsigned": len(rows) - len(signed_rows),
768
+ "tamperFailed": 0,
769
+ "note": LATENT_VERIFICATION_NOTE,
770
+ }
771
+ else:
772
+ latent = {
773
+ "status": "MEASURED",
774
+ "enumerated": len(rows),
775
+ "verified": tally["verified"],
776
+ "verifiedRatio": (tally["verified"] / len(rows)) if rows else None,
777
+ "rotated": tally["rotated"],
778
+ "unsigned": len(rows) - len(signed_rows),
779
+ "tamperFailed": tally["hardFail"],
780
+ "note": LATENT_VERIFICATION_NOTE,
781
+ }
782
+
783
+ return {
784
+ "label": "MEASURED",
785
+ "status": "OK",
786
+ "window": {
787
+ "runsEnumerated": len(rows),
788
+ "samplesEnumerated": len(samples_list) if samples_list is not None else 0,
789
+ },
790
+ "summary": {
791
+ "total": len(invariants),
792
+ "holds": holds,
793
+ "violated": violated,
794
+ "indeterminate": indeterminate,
795
+ },
796
+ "latentVerification": latent,
797
+ "invariants": invariants,
798
+ "doctrine": DOCTRINE,
799
+ "note": NOTE,
800
+ }
801
+
802
+
803
+ def list_checks() -> List[Dict[str, str]]:
804
+ """The eight falsifiable invariant ids + one-line titles (registry)."""
805
+ return [
806
+ {"id": "receipt-chain-continuity", "title": "Receipt chain recomputes over its own tail"},
807
+ {"id": "ledger-failure-shape", "title": "Failed runs claim no serving provider or latency"},
808
+ {"id": "served-run-has-model", "title": "Live-served runs name the model that served them"},
809
+ {"id": "signed-columns-atomic", "title": "Receipt columns are all-present or all-absent"},
810
+ {"id": "loop-steps-positive", "title": "Every live-served run took at least one loop step"},
811
+ {"id": "receipt-ed25519-verify", "title": "Each signed receipt verifies under ed25519"},
812
+ {"id": "receipt-columns-consistent", "title": "Receipt payload matches its indexed columns"},
813
+ {"id": "flywheel-lineage", "title": "Flywheel eats only its own verified tail"},
814
+ ]
815
+
816
+
817
+ def selfcheck() -> Dict[str, Any]:
818
+ """One-shot CPU health check on a tiny synthetic ledger: proves the kernel
819
+ computes real HOLDS / VIOLATED / UNAVAILABLE verdicts (falsifiable). NOT a
820
+ proof of anything about Λ, which is untouched (Conjecture 1)."""
821
+ good = _build_demo_chain(tamper=False)
822
+ bad = _build_demo_chain(tamper=True)
823
+ r_good = run_invariants(good, samples=None, pubkey=None)
824
+ r_bad = run_invariants(bad, samples=None, pubkey=None)
825
+ chain_good = next(
826
+ i for i in r_good["invariants"] if i["id"] == "receipt-chain-continuity"
827
+ )
828
+ chain_bad = next(
829
+ i for i in r_bad["invariants"] if i["id"] == "receipt-chain-continuity"
830
+ )
831
+ return {
832
+ "version": __version__,
833
+ "checks_registered": len(INVARIANT_IDS),
834
+ "clean_chain_status": chain_good["status"], # HOLDS
835
+ "tampered_chain_status": chain_bad["status"], # VIOLATED (falsifiable!)
836
+ "ed25519_without_key": next(
837
+ i for i in r_good["invariants"] if i["id"] == "receipt-ed25519-verify"
838
+ )["status"], # UNAVAILABLE, never coerced
839
+ "falsifiable_demonstrated": chain_good["status"] == "HOLDS"
840
+ and chain_bad["status"] == "VIOLATED",
841
+ "lambda_status": "Conjecture 1 (open) — untouched by these invariants",
842
+ }
843
+
844
+
845
+ def _build_demo_chain(tamper: bool) -> List[Dict[str, Any]]:
846
+ """Build a tiny genesis→2 chain the same way runLedger does, for selfcheck
847
+ and tests. When tamper=True the newest row's contentHash is altered so the
848
+ recompute genuinely fails."""
849
+ rows: List[Dict[str, Any]] = []
850
+ prev = "genesis"
851
+ for i in range(1, 4):
852
+ row = {
853
+ "id": i,
854
+ "endpoint": "/api/run",
855
+ "mode": "planner",
856
+ "requestedProvider": "auto",
857
+ "servedProvider": "sovereign",
858
+ "model": "own-metal",
859
+ "servedNode": "tower",
860
+ "demo": False,
861
+ "ok": True,
862
+ "latencyMs": 100 + i,
863
+ "error": None,
864
+ "loopSteps": 1,
865
+ "receiptId": None,
866
+ "receiptJson": None,
867
+ "signature": None,
868
+ "keyId": None,
869
+ "goalSha256": None,
870
+ "outputSha256": None,
871
+ "prevHash": prev,
872
+ }
873
+ row["rowHash"] = recompute_row_hash(prev, row)
874
+ prev = row["rowHash"]
875
+ rows.append(row)
876
+ if tamper:
877
+ rows[-1]["model"] = "TAMPERED" # contentHash now mismatches stored rowHash
878
+ return rows