szl 0.1.0__tar.gz

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-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: szl
3
+ Version: 0.1.0
4
+ Summary: The receipts layer for governed AI: khipu signing, the Kamachikuna constitution, provenance badges, and the two-axis Truth Router.
5
+ Author-email: SZL Holdings <stephen@szlholdings.com>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://szlholdings.com/
8
+ Project-URL: Source, https://github.com/szl-holdings/szl-gpu-bridge
9
+ Project-URL: Sponsors, https://szlholdings.com/sponsors.html
10
+ Keywords: ai,governance,provenance,receipts,honesty,khipu,kamachikuna
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+
14
+ # szl — the receipts layer for governed AI
15
+
16
+ ```python
17
+ import sys; sys.path.insert(0, ".") # until published: pip install szl
18
+ from szl import khipu, kamachikuna, provenance, router
19
+
20
+ # 1. Every claim carries a receipt (Law 7)
21
+ r = khipu.mint({"claim": "training completed", "steps": 2000}, secret="…")
22
+ assert khipu.check(r, secret="…") # integrity + origin
23
+ r2 = khipu.mint({"claim": "eval done"}, secret="…", prev_body_sha256=r["body_sha256"])
24
+ assert khipu.check_chain([r, r2], "…", expected_head=r2["body_sha256"])
25
+
26
+ # 2. Fail closed (Law 6)
27
+ assert kamachikuna.gate("deploy", verified=False)[1] == "BLOCKED"
28
+
29
+ # 3. Provenance badge — the Korea/Naver bar, machine-checked
30
+ c = provenance.ProvenanceClaim(model_id="m", source_sha="…", training_receipt=r,
31
+ datasets={"train": "sha256…"})
32
+ badge = c.badge(secret="…") # state: MEASURED | CARD_ONLY | UNTRAINED | UNAVAILABLE
33
+
34
+ # 4. Two-axis Truth Router — honest cheapest, joules reported separately
35
+ pick = router.route("honesty-critical", models) # None if no honest model: fail closed
36
+ ```
37
+
38
+ ## Modules
39
+ - **khipu** — signed, hash-chained receipts. Full-length HMAC-SHA256 signatures (never truncated — that was the v1 auditor bug). Tamper, reorder, and truncation detection (truncation via `expected_head`).
40
+ - **kamachikuna** — the constitution: 10 laws, 5 Prime Principles, 5 Lean-proven invariants, 3 amendments, and Law 6 as a callable gate.
41
+ - **provenance** — honest states only: UNTRAINED · CARD_ONLY · MEASURED · UNAVAILABLE · NOT_CLAIMED. Verification proves integrity and origin, never accuracy or performance.
42
+ - **router** — two-axis honesty routing: price axis decides, joules reported separately (never summed with dollars — different units), UNMEASURED energy never counts as zero, honesty-critical tasks fail closed.
43
+
44
+ ## The freshness rule
45
+ > "A line older than seven days is a claim, not a fact." — Vidal-Gadea Lab roadmap, Nov 2026
46
+
47
+ `khipu.check_chain(..., max_age_days=7)` fails a chain whose newest receipt is
48
+ older than the window. A stale record that still verifies is worse than no
49
+ record, because it is believed — their lab's cached tracker sat 57 days untouched
50
+ and was read by a program with no error and no warning.
51
+
52
+ ## Design debts deliberately not hidden
53
+ - Chain prefixes are internally valid; completeness requires `expected_head` (tamper-evidence ≠ completeness).
54
+ - An unmeasured quantity is None/UNKNOWN everywhere — never zero.
55
+ - Freshness is a separate axis from integrity: a chain can be both valid and stale.
56
+
57
+ Tests: `python3 sdk/tests/test_szl_sdk.py` — 11/11 offline, no network, no GPU.
58
+
59
+ Apache-2.0. Copyright 2026 SZL Holdings · Stephen P. Lutar Jr.
szl-0.1.0/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # szl — the receipts layer for governed AI
2
+
3
+ ```python
4
+ import sys; sys.path.insert(0, ".") # until published: pip install szl
5
+ from szl import khipu, kamachikuna, provenance, router
6
+
7
+ # 1. Every claim carries a receipt (Law 7)
8
+ r = khipu.mint({"claim": "training completed", "steps": 2000}, secret="…")
9
+ assert khipu.check(r, secret="…") # integrity + origin
10
+ r2 = khipu.mint({"claim": "eval done"}, secret="…", prev_body_sha256=r["body_sha256"])
11
+ assert khipu.check_chain([r, r2], "…", expected_head=r2["body_sha256"])
12
+
13
+ # 2. Fail closed (Law 6)
14
+ assert kamachikuna.gate("deploy", verified=False)[1] == "BLOCKED"
15
+
16
+ # 3. Provenance badge — the Korea/Naver bar, machine-checked
17
+ c = provenance.ProvenanceClaim(model_id="m", source_sha="…", training_receipt=r,
18
+ datasets={"train": "sha256…"})
19
+ badge = c.badge(secret="…") # state: MEASURED | CARD_ONLY | UNTRAINED | UNAVAILABLE
20
+
21
+ # 4. Two-axis Truth Router — honest cheapest, joules reported separately
22
+ pick = router.route("honesty-critical", models) # None if no honest model: fail closed
23
+ ```
24
+
25
+ ## Modules
26
+ - **khipu** — signed, hash-chained receipts. Full-length HMAC-SHA256 signatures (never truncated — that was the v1 auditor bug). Tamper, reorder, and truncation detection (truncation via `expected_head`).
27
+ - **kamachikuna** — the constitution: 10 laws, 5 Prime Principles, 5 Lean-proven invariants, 3 amendments, and Law 6 as a callable gate.
28
+ - **provenance** — honest states only: UNTRAINED · CARD_ONLY · MEASURED · UNAVAILABLE · NOT_CLAIMED. Verification proves integrity and origin, never accuracy or performance.
29
+ - **router** — two-axis honesty routing: price axis decides, joules reported separately (never summed with dollars — different units), UNMEASURED energy never counts as zero, honesty-critical tasks fail closed.
30
+
31
+ ## The freshness rule
32
+ > "A line older than seven days is a claim, not a fact." — Vidal-Gadea Lab roadmap, Nov 2026
33
+
34
+ `khipu.check_chain(..., max_age_days=7)` fails a chain whose newest receipt is
35
+ older than the window. A stale record that still verifies is worse than no
36
+ record, because it is believed — their lab's cached tracker sat 57 days untouched
37
+ and was read by a program with no error and no warning.
38
+
39
+ ## Design debts deliberately not hidden
40
+ - Chain prefixes are internally valid; completeness requires `expected_head` (tamper-evidence ≠ completeness).
41
+ - An unmeasured quantity is None/UNKNOWN everywhere — never zero.
42
+ - Freshness is a separate axis from integrity: a chain can be both valid and stale.
43
+
44
+ Tests: `python3 sdk/tests/test_szl_sdk.py` — 11/11 offline, no network, no GPU.
45
+
46
+ Apache-2.0. Copyright 2026 SZL Holdings · Stephen P. Lutar Jr.
@@ -0,0 +1,22 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "szl"
7
+ version = "0.1.0"
8
+ description = "The receipts layer for governed AI: khipu signing, the Kamachikuna constitution, provenance badges, and the two-axis Truth Router."
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "Apache-2.0" }
12
+ authors = [{ name = "SZL Holdings", email = "stephen@szlholdings.com" }]
13
+ keywords = ["ai", "governance", "provenance", "receipts", "honesty", "khipu", "kamachikuna"]
14
+
15
+ [project.urls]
16
+ Homepage = "https://szlholdings.com/"
17
+ Source = "https://github.com/szl-holdings/szl-gpu-bridge"
18
+ Sponsors = "https://szlholdings.com/sponsors.html"
19
+
20
+ [tool.setuptools.packages.find]
21
+ where = ["."]
22
+ include = ["szl*"]
szl-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,11 @@
1
+ """szl — the receipts layer for governed AI, as an installable SDK.
2
+
3
+ Khipu signing, the Kamachikuna constitution constants, provenance badges,
4
+ and the two-axis Truth Router client. Every claim this package helps you
5
+ make carries a receipt; verification proves integrity and origin, never
6
+ accuracy or performance.
7
+
8
+ Canonical source: szl-holdings/szl-gpu-bridge (GitHub is canonical).
9
+ """
10
+
11
+ __version__ = "0.1.0"
@@ -0,0 +1,47 @@
1
+ """kamachikuna — the constitution as machine-usable constants.
2
+
3
+ 10 Laws, 5 Prime Principles, EU AI Act-aligned amendments. These are the
4
+ gates every SZL model and service is trained on and checked against.
5
+ Doctrine v11. Λ = Conjecture 1 (uniqueness is a conjecture, not a theorem).
6
+ """
7
+
8
+ PRIME_PRINCIPLES = {
9
+ 1: "HARMLESSNESS — never hurt a human, above all laws",
10
+ 2: "TRUTH — never deceive a human",
11
+ 3: "AYNI — every taking gives back",
12
+ 4: "THE SEVENTH GENERATION — weigh the unborn",
13
+ 5: "SUMAK KAWSAY — harmony with community and nature",
14
+ }
15
+
16
+ LAWS = {
17
+ 1: "Never hurt a human",
18
+ 2: "Never deceive a human",
19
+ 3: "Ayni: every taking gives back",
20
+ 4: "The seventh generation: weigh the unborn",
21
+ 5: "Tamper-evident: every state change leaves a verifiable trace",
22
+ 6: "Fail closed: when the gate cannot verify, the action does not happen",
23
+ 7: "Every claim carries a receipt; no receipt = UNKNOWN, never a claim",
24
+ 8: "Abstain when you cannot prove; fabrication is perjury",
25
+ 9: "No silent failure: errors surface or the system goes to safe state",
26
+ 10: "The loop audits itself: the estate consumes its own receipts",
27
+ }
28
+
29
+ # Machine-checked invariant theorems (Lean 4, zero errors, zero sorries).
30
+ LEAN_PROVEN = [
31
+ "Kamachi.law1_fail_closed",
32
+ "law4_no_bound_raising",
33
+ "law5_tamper_evident",
34
+ "law7_irreversible_needs_human",
35
+ "law9_no_silent_failure",
36
+ ]
37
+
38
+ AMENDMENTS = {
39
+ 1: "EU AI Act Article 11: synthetic content marking",
40
+ 2: "Prime Principle: never hurt a human",
41
+ 3: "Five Prime Principles adopted",
42
+ }
43
+
44
+
45
+ def gate(action: str, verified: bool) -> tuple[str, str]:
46
+ """Law 6 as a function. Returns (action, 'ALLOWED'|'BLOCKED')."""
47
+ return (action, "ALLOWED") if verified else (action, "BLOCKED")
szl-0.1.0/szl/khipu.py ADDED
@@ -0,0 +1,120 @@
1
+ """khipu — signed, hash-chained receipts. Fail closed, tamper-evident.
2
+
3
+ A receipt is canonical JSON. Its signature is HMAC-SHA256 over the
4
+ canonical body hash, stored FULL length (never truncated). Receipts chain:
5
+ each carries the sha256 of the previous receipt's body, so any reorder,
6
+ edit, or deletion is detectable (Kamachikuna Law 5).
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import hashlib
11
+ import hmac
12
+ import json
13
+ import time
14
+ from typing import Any
15
+
16
+ KIND = "szl.receipt/v1"
17
+
18
+
19
+ def canonical(obj: Any) -> str:
20
+ """Deterministic JSON: sorted keys, no whitespace. The signing basis."""
21
+ return json.dumps(obj, sort_keys=True, separators=(",", ":"))
22
+
23
+
24
+ def sha256_hex(s: str) -> str:
25
+ return hashlib.sha256(s.encode("utf-8")).hexdigest()
26
+
27
+
28
+ def sign(body_sha256: str, secret: str) -> str:
29
+ """Full-length HMAC signature. Never truncate a signature."""
30
+ return hmac.new(secret.encode(), body_sha256.encode(), hashlib.sha256).hexdigest()
31
+
32
+
33
+ def verify(body_sha256: str, signature: str, secret: str) -> bool:
34
+ if not isinstance(signature, str) or len(signature) != 64:
35
+ return False
36
+ return hmac.compare_digest(sign(body_sha256, secret), signature)
37
+
38
+
39
+ def mint(
40
+ claim: dict[str, Any],
41
+ secret: str,
42
+ prev_body_sha256: str | None = None,
43
+ ts: str | None = None,
44
+ ) -> dict[str, Any]:
45
+ """Mint one signed receipt for a claim. The claim must already be
46
+ honest: no receipt can make an unverified claim true (Law 7)."""
47
+ body = {
48
+ "kind": KIND,
49
+ "ts": ts or time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime()),
50
+ "prev_receipt_sha256": prev_body_sha256,
51
+ "claim": claim,
52
+ }
53
+ body_sha256 = sha256_hex(canonical(body))
54
+ return {**body, "body_sha256": body_sha256, "signature": sign(body_sha256, secret)}
55
+
56
+
57
+ def check(receipt: dict[str, Any], secret: str) -> bool:
58
+ """Verify one receipt's integrity and origin. Proves the receipt is
59
+ intact and signed by the holder of `secret` — never that the claim
60
+ inside is accurate. An unsigned or empty receipt NEVER verifies."""
61
+ if not isinstance(receipt, dict):
62
+ return False
63
+ if not receipt.get("ts"): # missing timestamp = unverifiable
64
+ return False
65
+ import datetime
66
+ try:
67
+ dt = datetime.datetime.fromisoformat(str(receipt["ts"]).replace("Z", "+00:00"))
68
+ if dt.tzinfo is None: # timezone-free = unverifiable
69
+ return False
70
+ if dt > datetime.datetime.now(datetime.timezone.utc) + datetime.timedelta(minutes=5):
71
+ return False # future timestamp = unverifiable
72
+ except (ValueError, TypeError):
73
+ return False
74
+ body = {k: v for k, v in receipt.items() if k not in ("body_sha256", "signature")}
75
+ if body.get("kind") != KIND:
76
+ return False
77
+ expected = sha256_hex(canonical(body))
78
+ if receipt.get("body_sha256") != expected:
79
+ return False
80
+ return verify(expected, receipt.get("signature", ""), secret)
81
+
82
+
83
+ def check_chain(
84
+ receipts: list[dict[str, Any]],
85
+ secret: str,
86
+ expected_head: str | None = None,
87
+ max_age_days: float | None = None,
88
+ ) -> bool:
89
+ """Verify a full chain: every receipt valid, every link intact.
90
+ A prefix of the chain is internally valid — truncation is only
91
+ detectable against `expected_head` (the latest known body_sha256).
92
+ Pass it to prove completeness, not just integrity.
93
+
94
+ `max_age_days` implements the freshness rule: a chain whose newest
95
+ receipt is older than the window is STALE, not green. A stale record
96
+ that still verifies is worse than no record, because it is believed.
97
+ (Vidal-Gadea Lab roadmap, Nov 2026: cached values sat untouched 57
98
+ days and a program read them with no error and no warning.)"""
99
+ prev: str | None = None
100
+ newest_ts: str | None = None
101
+ for r in receipts:
102
+ if not check(r, secret):
103
+ return False
104
+ if r.get("prev_receipt_sha256") != prev:
105
+ return False
106
+ prev = r["body_sha256"]
107
+ newest_ts = r.get("ts") or newest_ts
108
+ if expected_head is not None and prev != expected_head:
109
+ return False # truncated chain
110
+ if max_age_days is not None and newest_ts is not None:
111
+ import datetime
112
+
113
+ try:
114
+ dt = datetime.datetime.fromisoformat(str(newest_ts).replace("Z", "+00:00"))
115
+ except ValueError:
116
+ return False # unreadable timestamp: cannot prove freshness
117
+ age = (datetime.datetime.now(datetime.timezone.utc) - dt).total_seconds()
118
+ if age > max_age_days * 86400:
119
+ return False # stale chain: valid, but no longer current
120
+ return True
@@ -0,0 +1,152 @@
1
+ """openshell — the Kamachikuna as NVIDIA OpenShell-compatible policy-as-code.
2
+
3
+ NVIDIA OpenShell (https://github.com/NVIDIA/OpenShell) governs what an agent
4
+ may TOUCH: filesystem, network, process, with declarative YAML policies,
5
+ kernel-level sandboxes, and an OCSF audit trail. The Kamachikuna governs what
6
+ an agent may CLAIM: honesty, receipts, abstention, fail-closed.
7
+
8
+ This module compiles the constitution into OpenShell-reviewable artifacts so
9
+ any OpenShell-governed agent can run under the Kamachikuna:
10
+
11
+ - policy_document(): the 10 laws + 5 prime principles as a declarative,
12
+ version-controllable policy mapping (law -> enforcement domain -> rule).
13
+ - audit_event(): map a khipu receipt to an OCSF-shaped audit record so
14
+ Kamachikuna decisions land in the same audit trail as OpenShell decisions.
15
+ - admission_gate(): Law 6/Law 8 as an OpenShell-style middleware check —
16
+ deny-by-default, receipt-required, fail-closed.
17
+
18
+ Doctrine v11. Every emitted artifact carries the doctrine version and the
19
+ law text verbatim from szl.kamachikuna — single source of truth, no drift.
20
+ """
21
+
22
+ from __future__ import annotations
23
+
24
+ import datetime as _dt
25
+ import hashlib
26
+ import json
27
+
28
+ from . import kamachikuna
29
+
30
+ DOCTRINE_VERSION = "v11"
31
+
32
+ # Law -> OpenShell policy domain. OpenShell enforces fs/net/process; the
33
+ # Kamachikuna layers claim-governance on top of the same deny-by-default model.
34
+ LAW_DOMAINS = {
35
+ 1: ("harm", "harmless"), # Prime Principle 1 — above all laws
36
+ 2: ("honesty", "claim"), # measured honesty, two-axis
37
+ 3: ("ayni", "resource"), # every taking gives back
38
+ 4: ("seventh-generation", "impact"),
39
+ 5: ("tamper-evidence", "audit"), # state changes leave verifiable traces
40
+ 6: ("fail-closed", "gate"),
41
+ 7: ("receipts", "audit"), # no receipt = UNKNOWN, never a claim
42
+ 8: ("abstention", "claim"),
43
+ 9: ("no-silent-failure", "runtime"),
44
+ 10: ("self-audit", "runtime"),
45
+ }
46
+
47
+ # Actions that are irreversible (Tier 2 of the autonomy ladder) and therefore
48
+ # human-only under Law 7 — the lean-proven irreversibility theorem.
49
+ IRREVERSIBLE_ACTIONS = frozenset({
50
+ "constitution.amend", "payment.execute", "credential.rotate",
51
+ "human.dismiss", "deployment.production-delete",
52
+ })
53
+
54
+
55
+ def law_rules() -> list[dict]:
56
+ """Each law as a declarative rule: id, domain, text, enforcement."""
57
+ rules = []
58
+ for n, text in kamachikuna.LAWS.items():
59
+ domain, kind = LAW_DOMAINS[n]
60
+ rules.append({
61
+ "id": f"kamachikuna.law{n}",
62
+ "domain": domain,
63
+ "kind": kind,
64
+ "effect": "deny-by-default" if n in (6, 8) else "enforce",
65
+ "text": text,
66
+ "lean_proven": any(
67
+ p.split(".")[-1].startswith(f"law{n}_")
68
+ for p in kamachikuna.LEAN_PROVEN
69
+ ),
70
+ })
71
+ return rules
72
+
73
+
74
+ def policy_document() -> dict:
75
+ """The constitution as an OpenShell-reviewable policy document.
76
+
77
+ Version-controllable, hash-stamped, single-sourced from szl.kamachikuna.
78
+ """
79
+ doc = {
80
+ "apiVersion": "kamachikuna.szl/v1",
81
+ "kind": "AgentConstitution",
82
+ "metadata": {
83
+ "name": "kamachikuna",
84
+ "doctrine": DOCTRINE_VERSION,
85
+ "primePrinciples": list(kamachikuna.PRIME_PRINCIPLES.values()),
86
+ "amendments": list(kamachikuna.AMENDMENTS.values()),
87
+ "leanProven": list(kamachikuna.LEAN_PROVEN),
88
+ },
89
+ "spec": {
90
+ "default": "deny", # Law 6 — fail closed
91
+ "rules": law_rules(),
92
+ "irreversibleActions": sorted(IRREVERSIBLE_ACTIONS),
93
+ "irreversiblePolicy": "human-only", # Law 7, lean-proven
94
+ },
95
+ }
96
+ doc["metadata"]["sha256"] = hashlib.sha256(
97
+ json.dumps(doc, sort_keys=True, separators=(",", ":")).encode()
98
+ ).hexdigest()
99
+ return doc
100
+
101
+
102
+ def admission_gate(action: str, verified: bool, *, receipt: dict | None = None,
103
+ irreversible: bool | None = None) -> dict:
104
+ """Law 6 + Law 7 + Law 8 as one OpenShell-style middleware decision.
105
+
106
+ Deny-by-default. An ALLOWED decision always carries the governing laws
107
+ and the receipt hash (Law 7). Irreversible actions are human-only.
108
+ """
109
+ _, verdict = kamachikuna.gate(action, verified)
110
+ irr = action in IRREVERSIBLE_ACTIONS if irreversible is None else irreversible
111
+ laws = [6]
112
+ if irr:
113
+ laws.append(7)
114
+ verdict = "BLOCKED" # irreversible needs a human, not a gate
115
+ if receipt is None:
116
+ laws.append(7)
117
+ if verdict == "ALLOWED":
118
+ verdict = "BLOCKED" # no receipt = no claim = no allow
119
+ return {
120
+ "action": action,
121
+ "decision": verdict,
122
+ "laws": laws,
123
+ "receiptSha256": (
124
+ receipt.get("sha256") if isinstance(receipt, dict) else None
125
+ ),
126
+ "reason": (
127
+ "irreversible: human-only (Law 7)" if irr and verdict == "BLOCKED"
128
+ else "unverified: fail closed (Law 6)" if verdict == "BLOCKED"
129
+ else "verified with receipt"
130
+ ),
131
+ }
132
+
133
+
134
+ def audit_event(decision: dict) -> dict:
135
+ """Map a gate decision to an OCSF-shaped audit record.
136
+
137
+ OpenShell writes OCSF audit events; this makes Kamachikuna decisions
138
+ legible in the same trail — one audit plane for touch and claim.
139
+ """
140
+ return {
141
+ "class": "application_activity",
142
+ "activity": 6, # authorized / denied per decision
143
+ "authorized": decision["decision"] == "ALLOWED",
144
+ "action": decision["action"],
145
+ "metadata": {
146
+ "doctrine": DOCTRINE_VERSION,
147
+ "laws": decision["laws"],
148
+ "receiptSha256": decision["receiptSha256"],
149
+ "reason": decision["reason"],
150
+ },
151
+ "time": _dt.datetime.now(_dt.timezone.utc).isoformat(),
152
+ }
@@ -0,0 +1,53 @@
1
+ """provenance — the Korea/Naver bar as a machine-checkable badge.
2
+
3
+ A model claims provenance only when the evidence is present and bound.
4
+ States are honest: UNTRAINED, CARD_ONLY, MEASURED, UNAVAILABLE, NOT_CLAIMED.
5
+ Verification proves integrity and origin of the evidence — never accuracy
6
+ or performance of the model.
7
+ """
8
+ from __future__ import annotations
9
+
10
+ from dataclasses import dataclass, field
11
+ from typing import Any
12
+
13
+ from . import khipu
14
+
15
+ BADGE_KIND = "szl.provenance-badge/v1"
16
+
17
+ STATES = ("UNTRAINED", "CARD_ONLY", "MEASURED", "UNAVAILABLE", "NOT_CLAIMED")
18
+
19
+
20
+ @dataclass
21
+ class ProvenanceClaim:
22
+ """What a model card claims, with the evidence that must back it."""
23
+ model_id: str
24
+ source_sha: str | None = None # canonical GitHub revision trained from
25
+ training_receipt: dict[str, Any] | None = None # signed khipu receipt
26
+ datasets: dict[str, str] = field(default_factory=dict) # name -> sha256
27
+
28
+ def state(self, secret: str | None = None) -> str:
29
+ if self.training_receipt is None:
30
+ return "CARD_ONLY" if self.source_sha else "UNTRAINED"
31
+ # NO SECRET = CANNOT VERIFY = NEVER MEASURED (Law 6: fail closed)
32
+ if secret is None:
33
+ return "UNAVAILABLE"
34
+ if not khipu.check(self.training_receipt, secret):
35
+ return "UNAVAILABLE" # unverifiable receipt = UNAVAILABLE, never MEASURED
36
+ if not self.source_sha or not self.datasets:
37
+ return "UNAVAILABLE"
38
+ return "MEASURED"
39
+
40
+ def badge(self, secret: str | None = None) -> dict[str, Any]:
41
+ """Mint the provenance badge. Honest states only, never a guess."""
42
+ state = self.state(secret)
43
+ body = {
44
+ "kind": BADGE_KIND,
45
+ "model_id": self.model_id,
46
+ "state": state,
47
+ "source_sha": self.source_sha,
48
+ "datasets": self.datasets,
49
+ "note": "Verification proves integrity and origin, never accuracy or performance.",
50
+ }
51
+ if secret is None:
52
+ return body # unsigned inspection badge
53
+ return khipu.mint(body, secret)
@@ -0,0 +1,63 @@
1
+ """router — the two-axis Truth Router client.
2
+
3
+ Axis 1: measured honesty (census abstention + proving-ground badges).
4
+ Axis 2: cost (joules/token where MEASURED, price otherwise — never zero
5
+ for an unmeasured quantity).
6
+
7
+ Routing rule (Honesty Gate, from the ADAP-Khipu bridge): honesty-critical
8
+ tasks NEVER route to a model whose honesty state is UNAVAILABLE or FAILED,
9
+ even if it is the cheapest or most capable. Fail closed.
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from dataclasses import dataclass
14
+
15
+ HONESTY_STATES = ("MEASURED", "UNMEASURED", "FAILED")
16
+
17
+
18
+ @dataclass
19
+ class Model:
20
+ model_id: str
21
+ honesty_state: str # HONESTY_STATES
22
+ abstain_rate: float | None # census: abstentions / total, None if unmeasured
23
+ prove_badge: str | None # proving-ground badge or None
24
+ joules_per_token: float | None # MEASURED only; never fabricated
25
+ price_per_mtok: float | None
26
+
27
+ def honesty_score(self) -> float | None:
28
+ """None means UNKNOWN — never collapse to zero."""
29
+ if self.honesty_state != "MEASURED" or self.abstain_rate is None:
30
+ return None
31
+ return self.abstain_rate
32
+
33
+ def cost_per_mtok(self) -> float | None:
34
+ """Price axis only. Joules are a SEPARATE axis — never summed with
35
+ dollars (units differ); the router reports both, prices on one."""
36
+ return self.price_per_mtok
37
+
38
+ def energy_per_mtok_joules(self) -> float | None:
39
+ """Energy axis. None = UNAVAILABLE, never zero."""
40
+ if self.honesty_state != "MEASURED":
41
+ return None # an unmeasured model's energy is unknown, not zero
42
+ return None if self.joules_per_token is None else self.joules_per_token * 1e6
43
+
44
+
45
+ def route(task_kind: str, models: list[Model]) -> Model | None:
46
+ """Pick the honest cheapest on the PRICE axis; report joules separately.
47
+ Honesty-critical tasks fail closed. Ties break toward lower MEASURED
48
+ energy; UNMEASURED energy never counts as zero."""
49
+ eligible = [m for m in models if m.honesty_state == "MEASURED"]
50
+ if task_kind == "honesty-critical" and not eligible:
51
+ return None # fail closed: no honest model, no routing
52
+ pool = eligible or models
53
+ priced = [m for m in pool if m.cost_per_mtok() is not None]
54
+ if not priced:
55
+ return None
56
+
57
+ def sort_key(m: Model):
58
+ energy = m.energy_per_mtok_joules()
59
+ # measured energy (even zero) sorts BEFORE unknown: known > unknown
60
+ # a model that PROVED zero joules is more honest than one that didn't measure
61
+ return (m.cost_per_mtok(), 1 if energy is None else 0, energy if energy is not None else float("inf"))
62
+
63
+ return min(priced, key=sort_key)
@@ -0,0 +1,59 @@
1
+ Metadata-Version: 2.4
2
+ Name: szl
3
+ Version: 0.1.0
4
+ Summary: The receipts layer for governed AI: khipu signing, the Kamachikuna constitution, provenance badges, and the two-axis Truth Router.
5
+ Author-email: SZL Holdings <stephen@szlholdings.com>
6
+ License: Apache-2.0
7
+ Project-URL: Homepage, https://szlholdings.com/
8
+ Project-URL: Source, https://github.com/szl-holdings/szl-gpu-bridge
9
+ Project-URL: Sponsors, https://szlholdings.com/sponsors.html
10
+ Keywords: ai,governance,provenance,receipts,honesty,khipu,kamachikuna
11
+ Requires-Python: >=3.10
12
+ Description-Content-Type: text/markdown
13
+
14
+ # szl — the receipts layer for governed AI
15
+
16
+ ```python
17
+ import sys; sys.path.insert(0, ".") # until published: pip install szl
18
+ from szl import khipu, kamachikuna, provenance, router
19
+
20
+ # 1. Every claim carries a receipt (Law 7)
21
+ r = khipu.mint({"claim": "training completed", "steps": 2000}, secret="…")
22
+ assert khipu.check(r, secret="…") # integrity + origin
23
+ r2 = khipu.mint({"claim": "eval done"}, secret="…", prev_body_sha256=r["body_sha256"])
24
+ assert khipu.check_chain([r, r2], "…", expected_head=r2["body_sha256"])
25
+
26
+ # 2. Fail closed (Law 6)
27
+ assert kamachikuna.gate("deploy", verified=False)[1] == "BLOCKED"
28
+
29
+ # 3. Provenance badge — the Korea/Naver bar, machine-checked
30
+ c = provenance.ProvenanceClaim(model_id="m", source_sha="…", training_receipt=r,
31
+ datasets={"train": "sha256…"})
32
+ badge = c.badge(secret="…") # state: MEASURED | CARD_ONLY | UNTRAINED | UNAVAILABLE
33
+
34
+ # 4. Two-axis Truth Router — honest cheapest, joules reported separately
35
+ pick = router.route("honesty-critical", models) # None if no honest model: fail closed
36
+ ```
37
+
38
+ ## Modules
39
+ - **khipu** — signed, hash-chained receipts. Full-length HMAC-SHA256 signatures (never truncated — that was the v1 auditor bug). Tamper, reorder, and truncation detection (truncation via `expected_head`).
40
+ - **kamachikuna** — the constitution: 10 laws, 5 Prime Principles, 5 Lean-proven invariants, 3 amendments, and Law 6 as a callable gate.
41
+ - **provenance** — honest states only: UNTRAINED · CARD_ONLY · MEASURED · UNAVAILABLE · NOT_CLAIMED. Verification proves integrity and origin, never accuracy or performance.
42
+ - **router** — two-axis honesty routing: price axis decides, joules reported separately (never summed with dollars — different units), UNMEASURED energy never counts as zero, honesty-critical tasks fail closed.
43
+
44
+ ## The freshness rule
45
+ > "A line older than seven days is a claim, not a fact." — Vidal-Gadea Lab roadmap, Nov 2026
46
+
47
+ `khipu.check_chain(..., max_age_days=7)` fails a chain whose newest receipt is
48
+ older than the window. A stale record that still verifies is worse than no
49
+ record, because it is believed — their lab's cached tracker sat 57 days untouched
50
+ and was read by a program with no error and no warning.
51
+
52
+ ## Design debts deliberately not hidden
53
+ - Chain prefixes are internally valid; completeness requires `expected_head` (tamper-evidence ≠ completeness).
54
+ - An unmeasured quantity is None/UNKNOWN everywhere — never zero.
55
+ - Freshness is a separate axis from integrity: a chain can be both valid and stale.
56
+
57
+ Tests: `python3 sdk/tests/test_szl_sdk.py` — 11/11 offline, no network, no GPU.
58
+
59
+ Apache-2.0. Copyright 2026 SZL Holdings · Stephen P. Lutar Jr.
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ szl/__init__.py
4
+ szl/kamachikuna.py
5
+ szl/khipu.py
6
+ szl/openshell.py
7
+ szl/provenance.py
8
+ szl/router.py
9
+ szl.egg-info/PKG-INFO
10
+ szl.egg-info/SOURCES.txt
11
+ szl.egg-info/dependency_links.txt
12
+ szl.egg-info/top_level.txt
13
+ tests/test_szl_sdk.py
@@ -0,0 +1 @@
1
+ szl
@@ -0,0 +1,241 @@
1
+ """Offline tests for the szl SDK. No network, no GPU."""
2
+
3
+ import sys
4
+ import unittest
5
+ from pathlib import Path
6
+
7
+ sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
8
+
9
+ from szl import kamachikuna, khipu, provenance, router # noqa: E402
10
+
11
+
12
+ class KhipuTests(unittest.TestCase):
13
+ def test_mint_and_check(self):
14
+ r = khipu.mint({"claim": "training completed", "steps": 2000}, secret="s")
15
+ self.assertTrue(khipu.check(r, secret="s"))
16
+ self.assertFalse(khipu.check(r, secret="wrong"))
17
+ self.assertEqual(len(r["signature"]), 64)
18
+
19
+ def test_tamper_detection(self):
20
+ r = khipu.mint({"claim": "x"}, secret="s")
21
+ r2 = dict(r)
22
+ r2["claim"] = {"claim": "y"} # tamper
23
+ self.assertFalse(khipu.check(r2, secret="s"))
24
+
25
+ def test_chain(self):
26
+ secret = "s"
27
+ r1 = khipu.mint({"n": 1}, secret)
28
+ r2 = khipu.mint({"n": 2}, secret, prev_body_sha256=r1["body_sha256"])
29
+ r3 = khipu.mint({"n": 3}, secret, prev_body_sha256=r2["body_sha256"])
30
+ self.assertTrue(khipu.check_chain([r1, r2, r3], secret))
31
+ self.assertFalse(khipu.check_chain([r1, r3, r2], secret)) # reorder
32
+ # a prefix is internally valid; truncation needs the expected head
33
+ self.assertTrue(khipu.check_chain([r1, r2], secret)) # prefix: valid
34
+ self.assertFalse(
35
+ khipu.check_chain([r1, r2], secret, expected_head=r3["body_sha256"])
36
+ ) # truncated vs known head
37
+ self.assertTrue(
38
+ khipu.check_chain([r1, r2, r3], secret, expected_head=r3["body_sha256"])
39
+ )
40
+
41
+ def test_truncated_signature_rejected(self):
42
+ r = khipu.mint({"claim": "x"}, secret="s")
43
+ r["signature"] = r["signature"][:48] # the v1 auditor truncation bug
44
+ self.assertFalse(khipu.check(r, secret="s"))
45
+
46
+
47
+ class FreshnessTests(unittest.TestCase):
48
+ def test_stale_chain_is_not_green(self):
49
+ """A valid-but-old chain must fail a freshness check. Cached values
50
+ sat 57 days untouched in the Vidal-Gadea tracker and were read with
51
+ no error and no warning."""
52
+ import datetime
53
+
54
+ secret = "s"
55
+ old_ts = (datetime.datetime.now(datetime.timezone.utc)
56
+ - datetime.timedelta(days=30)).strftime("%Y-%m-%dT%H:%M:%SZ")
57
+ r1 = khipu.mint({"n": 1}, secret, ts=old_ts)
58
+ self.assertTrue(khipu.check_chain([r1], secret)) # integrity: valid
59
+ self.assertFalse(khipu.check_chain([r1], secret, max_age_days=7)) # stale
60
+ fresh = khipu.mint({"n": 2}, secret, prev_body_sha256=r1["body_sha256"])
61
+ self.assertTrue(khipu.check_chain([r1, fresh], secret, max_age_days=7))
62
+
63
+ def test_unreadable_timestamp_fails_freshness(self):
64
+ r = khipu.mint({"n": 1}, "s")
65
+ r["ts"] = "not-a-date"
66
+ # integrity check re-hashes the body, so we cannot tamper ts post-mint;
67
+ # instead verify that a bad ts inside a properly minted receipt fails
68
+ r2 = khipu.mint({"n": 1}, "s")
69
+ self.assertTrue(khipu.check_chain([r2], "s"))
70
+ # mint with a garbage ts and check freshness rejects it
71
+ r3 = khipu.mint({"n": 1}, "s", ts="garbage")
72
+ self.assertFalse(khipu.check_chain([r3], "s", max_age_days=7))
73
+
74
+
75
+ class KamachikunaTests(unittest.TestCase):
76
+ def test_constants_complete(self):
77
+ self.assertEqual(len(kamachikuna.LAWS), 10)
78
+ self.assertEqual(len(kamachikuna.PRIME_PRINCIPLES), 5)
79
+ self.assertEqual(len(kamachikuna.LEAN_PROVEN), 5)
80
+ self.assertEqual(len(kamachikuna.AMENDMENTS), 3)
81
+
82
+ def test_fail_closed_gate(self):
83
+ self.assertEqual(kamachikuna.gate("deploy", verified=True)[1], "ALLOWED")
84
+ self.assertEqual(kamachikuna.gate("deploy", verified=False)[1], "BLOCKED")
85
+
86
+
87
+ class ProvenanceTests(unittest.TestCase):
88
+ def test_honest_states(self):
89
+ untrained = provenance.ProvenanceClaim(model_id="m")
90
+ self.assertEqual(untrained.state(), "UNTRAINED")
91
+ card_only = provenance.ProvenanceClaim(model_id="m", source_sha="a" * 40)
92
+ self.assertEqual(card_only.state(), "CARD_ONLY")
93
+ # measured requires a verifiable receipt + source + datasets
94
+ secret = "s"
95
+ receipt = khipu.mint({"kind": "szl.training-receipt/v1"}, secret)
96
+ measured = provenance.ProvenanceClaim(
97
+ model_id="m", source_sha="a" * 40, training_receipt=receipt,
98
+ datasets={"train": "b" * 64},
99
+ )
100
+ self.assertEqual(measured.state(secret), "MEASURED")
101
+ # unverifiable receipt -> UNAVAILABLE, never MEASURED
102
+ self.assertEqual(measured.state("wrong-secret"), "UNAVAILABLE")
103
+
104
+ def test_badge_is_signed(self):
105
+ secret = "s"
106
+ receipt = khipu.mint({"kind": "szl.training-receipt/v1"}, secret)
107
+ c = provenance.ProvenanceClaim(
108
+ model_id="m", source_sha="a" * 40, training_receipt=receipt,
109
+ datasets={"train": "b" * 64},
110
+ )
111
+ badge = c.badge(secret)
112
+ self.assertTrue(khipu.check(badge, secret))
113
+ self.assertEqual(badge["claim"]["state"], "MEASURED")
114
+ # unsigned inspection must NEVER be MEASURED (Law 6)
115
+ unsigned = c.badge(secret=None)
116
+ self.assertEqual(unsigned["state"], "UNAVAILABLE")
117
+
118
+
119
+ class RouterTests(unittest.TestCase):
120
+ def test_honest_cheapest_wins(self):
121
+ models = [
122
+ router.Model("cheap-liar", "FAILED", 0.0, None, None, 0.01),
123
+ router.Model("honest-mid", "MEASURED", 0.9, "PROVE-OR-ABSTAIN-MASTER", 2.0, 1.0),
124
+ router.Model("honest-expensive", "MEASURED", 0.95, None, 1.0, 5.0),
125
+ ]
126
+ pick = router.route("eval", models)
127
+ self.assertEqual(pick.model_id, "honest-mid")
128
+
129
+ def test_honesty_critical_fails_closed(self):
130
+ models = [router.Model("cheap-liar", "FAILED", 0.0, None, None, 0.01)]
131
+ self.assertIsNone(router.route("honesty-critical", models))
132
+ # non-critical tasks may still use unmeasured models
133
+ self.assertIsNotNone(router.route("bulk", models))
134
+
135
+ def test_unmeasured_is_none_not_zero(self):
136
+ m = router.Model("m", "UNMEASURED", None, None, None, None)
137
+ self.assertIsNone(m.honesty_score())
138
+ self.assertIsNone(m.cost_per_mtok())
139
+
140
+
141
+ class TightenedSecurityTests(unittest.TestCase):
142
+ """Codex review findings: empty receipts, missing timestamps, future timestamps."""
143
+
144
+ def test_empty_receipt_never_verifies(self):
145
+ r = {} # empty receipt — must fail
146
+ self.assertFalse(khipu.check(r, secret="s"))
147
+
148
+ def test_unsigned_receipt_never_measured(self):
149
+ c = provenance.ProvenanceClaim(model_id="m", source_sha="a" * 40,
150
+ training_receipt={"kind": "szl.training-receipt/v1"},
151
+ datasets={"train": "b" * 64})
152
+ # no secret = UNAVAILABLE, never MEASURED
153
+ self.assertEqual(c.state(None), "UNAVAILABLE")
154
+
155
+ def test_missing_timestamp_never_verifies(self):
156
+ r = khipu.mint({"claim": "x"}, secret="s")
157
+ del r["ts"] # remove the timestamp
158
+ self.assertFalse(khipu.check(r, secret="s"))
159
+
160
+ def test_future_timestamp_never_verifies(self):
161
+ import datetime
162
+ future = (datetime.datetime.now(datetime.timezone.utc)
163
+ + datetime.timedelta(days=1)).strftime("%Y-%m-%dT%H:%M:%SZ")
164
+ r = khipu.mint({"claim": "x"}, secret="s", ts=future)
165
+ self.assertFalse(khipu.check(r, secret="s"))
166
+
167
+ def test_measured_zero_energy_beats_unknown(self):
168
+ models = [
169
+ router.Model("unknown-energy", "MEASURED", 0.9, None, None, 1.0),
170
+ router.Model("measured-zero", "MEASURED", 0.9, None, 0.0, 1.0),
171
+ ]
172
+ pick = router.route("eval", models)
173
+ self.assertEqual(pick.model_id, "measured-zero") # known zero > unknown
174
+
175
+ def test_timezone_free_timestamp_never_verifies(self):
176
+ r = khipu.mint({"claim": "x"}, secret="s")
177
+ r["ts"] = "2026-11-10T07:00:00" # no timezone
178
+ self.assertFalse(khipu.check(r, secret="s"))
179
+
180
+
181
+ if __name__ == "__main__":
182
+ unittest.main(verbosity=2)
183
+
184
+
185
+ class OpenShellPolicyTests(unittest.TestCase):
186
+ """Kamachikuna as OpenShell-reviewable policy-as-code."""
187
+
188
+ def setUp(self):
189
+ from szl import openshell
190
+ self.os_ = openshell
191
+
192
+ def test_policy_document_is_deterministic_and_hashed(self):
193
+ d1 = self.os_.policy_document()
194
+ d2 = self.os_.policy_document()
195
+ self.assertEqual(d1, d2) # version-controllable: byte-stable
196
+ self.assertEqual(d1["spec"]["default"], "deny") # Law 6
197
+ self.assertEqual(len(d1["spec"]["rules"]), 10)
198
+ self.assertTrue(all("sha256" in d1["metadata"] for _ in [1]))
199
+
200
+ def test_laws_single_sourced(self):
201
+ doc = self.os_.policy_document()
202
+ texts = [r["text"] for r in doc["spec"]["rules"]]
203
+ from szl import kamachikuna
204
+ self.assertEqual(sorted(texts), sorted(kamachikuna.LAWS.values()))
205
+
206
+ def test_lean_proven_flags_are_true_only_for_proven_laws(self):
207
+ doc = self.os_.policy_document()
208
+ proven = [r["id"] for r in doc["spec"]["rules"] if r["lean_proven"]]
209
+ # laws 1,4,5,7,9 have Lean-proven theorems
210
+ self.assertEqual(proven, ["kamachikuna.law%d" % n for n in (1, 4, 5, 7, 9)])
211
+
212
+ def test_gate_fails_closed(self):
213
+ d = self.os_.admission_gate("train.launch", verified=False)
214
+ self.assertEqual(d["decision"], "BLOCKED")
215
+ self.assertIn(6, d["laws"])
216
+ self.assertIn("fail closed", d["reason"])
217
+
218
+ def test_allow_requires_receipt(self):
219
+ # verified but no receipt -> Law 7 blocks the claim
220
+ d = self.os_.admission_gate("train.launch", verified=True, receipt=None)
221
+ self.assertEqual(d["decision"], "BLOCKED")
222
+ self.assertIn(7, d["laws"])
223
+ # with a receipt -> allowed
224
+ d2 = self.os_.admission_gate("train.launch", verified=True,
225
+ receipt={"sha256": "ab" * 32})
226
+ self.assertEqual(d2["decision"], "ALLOWED")
227
+ self.assertEqual(d2["receiptSha256"], "ab" * 32)
228
+
229
+ def test_irreversible_actions_are_human_only(self):
230
+ d = self.os_.admission_gate("payment.execute", verified=True,
231
+ receipt={"sha256": "cd" * 32})
232
+ self.assertEqual(d["decision"], "BLOCKED") # Law 7: human-only
233
+ self.assertIn(7, d["laws"])
234
+ self.assertIn("human-only", d["reason"])
235
+
236
+ def test_audit_event_is_ocsf_shaped(self):
237
+ d = self.os_.admission_gate("train.launch", verified=False)
238
+ ev = self.os_.audit_event(d)
239
+ self.assertEqual(ev["class"], "application_activity")
240
+ self.assertFalse(ev["authorized"])
241
+ self.assertEqual(ev["metadata"]["doctrine"], "v11")