betterwithage commited on
Commit
872bfd2
·
verified ·
1 Parent(s): 74b47dc

chore(sync): mirror backend .py + Dockerfile to Space (hf-sync-backend)

Browse files

Automated backend sync from szl-holdings/a11oy main via hf-sync-backend.
Updated (differed from the Space): Dockerfile, szl_cheapest_watt.py
Deleted (gone from the repo + Dockerfile COPY set): (none)

Keeps the Space-built backend (serve.py + the Dockerfile-COPY'd .py
modules) identical to GitHub main so the Space never rebuilds from a
stale backend, new endpoints don't 404 there, and orphaned modules
removed from the repo don't linger in the Space tree.

Files changed (2) hide show
  1. Dockerfile +1 -1
  2. szl_cheapest_watt.py +528 -0
Dockerfile CHANGED
@@ -150,7 +150,7 @@ COPY szl_formula_wiring.py a11oy_code_engine.py a11oy_code.py a11oy_seismic.py s
150
  COPY szl_energy_budget.py szl_energy_sovereign.py szl_energy_provenance.py szl_heart_blood.py szl_engine_status.py szl_backend_hardening.py revenue_endpoints.py a11oy_harvest_endpoints.py ./
151
  # energy operator/ledger/projection modules — imported by serve.py (guarded);
152
  # MUST be per-file COPY'd (this Dockerfile uses no `COPY . .`) or the import falls back to a STUB.
153
- COPY joule_billing.py szl_energy_ledger.py szl_energy_operator.py szl_energy_projection.py ./
154
  # K-Verify governed-inference benchmark — imported by serve.py (guarded). MUST be
155
  # per-file COPY'd (this Dockerfile uses no `COPY . .`) or the import falls back and
156
  # /api/a11oy/v1/kverify/* 404s. Reuses szl_energy_operator (inference + NVML joules)
 
150
  COPY szl_energy_budget.py szl_energy_sovereign.py szl_energy_provenance.py szl_heart_blood.py szl_engine_status.py szl_backend_hardening.py revenue_endpoints.py a11oy_harvest_endpoints.py ./
151
  # energy operator/ledger/projection modules — imported by serve.py (guarded);
152
  # MUST be per-file COPY'd (this Dockerfile uses no `COPY . .`) or the import falls back to a STUB.
153
+ COPY joule_billing.py szl_energy_ledger.py szl_energy_operator.py szl_energy_projection.py szl_cheapest_watt.py ./
154
  # K-Verify governed-inference benchmark — imported by serve.py (guarded). MUST be
155
  # per-file COPY'd (this Dockerfile uses no `COPY . .`) or the import falls back and
156
  # /api/a11oy/v1/kverify/* 404s. Reuses szl_energy_operator (inference + NVML joules)
szl_cheapest_watt.py ADDED
@@ -0,0 +1,528 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """szl_cheapest_watt.py — SZL Energy: carbon/cost-aware "cheapest-watt" placement policy.
2
+
3
+ WHAT THIS IS (and is NOT)
4
+ -------------------------
5
+ This is PLACEMENT + ACCOUNTING, NOT fused VRAM. Given the reachable sovereign nodes,
6
+ their MEASURED per-node energy intensity (joules-per-token), and the LIVE grid price
7
+ (€/MWh) at decision time, it picks the ONE node that minimizes energy-cost-per-token
8
+ and records the placement decision into a signed, hash-chained receipt. Each separate
9
+ worker keeps its own metered joules — nothing is ever merged/fused across the network.
10
+
11
+ It does NOT execute inference; it reads what the live energy operator already MEASURED
12
+ (per-node joules + tokens + power_w + live grid price) and turns that into an honest,
13
+ re-hashable placement decision plus a cumulative MEASURED-savings tally. The mesh
14
+ coordinator's least-connections balancer still does the actual proxying; this is the
15
+ cost/carbon lens that, when wired in, can re-order candidates by cheapest watt.
16
+
17
+ HONESTY GATES (Doctrine v11 — never weakened here)
18
+ --------------------------------------------------
19
+ * NEVER fabricate a grid price or a saving. A node only has an energy-intensity
20
+ (J/token) when its OWN per-node MEASURED joules and tokens are both > 0 this read.
21
+ A node whose joules are PENDING_EXPORTER / 0 has UNKNOWN intensity and is NOT
22
+ ranked on cost (it is reported, honestly, as "intensity unknown — pending exporter").
23
+ * If fewer than TWO nodes have a comparable MEASURED intensity, there is NO real
24
+ placement choice: we report decision="no_choice" with reason "no placement choice
25
+ this tick" — we never invent an alternative to claim a saving against.
26
+ * The grid price is passed through from the live meter verbatim (€/MWh). If it is
27
+ missing, the per-token COST is UNKNOWN (intensity is still MEASURED) and the cost
28
+ delta is labeled accordingly — we never assume a price.
29
+ * SAVINGS LABELLING: a saving is the cost delta between the CHOSEN node and a NAMED
30
+ baseline. It is MEASURED only when BOTH legs are MEASURED (both nodes' J/token from
31
+ real per-node NVML deltas AND a live grid price). The default baseline is the
32
+ *most-expensive comparable node this tick* (a real alternative we declined) — that
33
+ leg is MEASURED, so the delta is MEASURED. Any baseline that is itself MODELED or
34
+ assumed (e.g. a cloud-grid reference intensity) yields an ESTIMATE saving, never
35
+ MEASURED. We label every saving with exactly one of {MEASURED, ESTIMATE}.
36
+ * Receipts are re-hashable offline (sha256_canon over the canonical decision) and
37
+ hash-chained (prev_digest; genesis = 64 zeros). DSSE signing is layered on by the
38
+ caller when a real cosign key is present; absent a key the receipt is honest-but-
39
+ UNSIGNED, never faked.
40
+ * sovereign=false on this accounting path; Λ = Conjecture 1; trust never 100%.
41
+
42
+ Pure stdlib (hashlib + json). No third-party deps, no network — the caller hands in
43
+ the operator-status dict it already fetched. Offline self-test at the bottom.
44
+ """
45
+
46
+ from __future__ import annotations
47
+
48
+ import hashlib
49
+ import json
50
+ import threading
51
+ import time
52
+ from dataclasses import dataclass, field
53
+ from typing import Any, Dict, List, Optional, Tuple
54
+
55
+ # ---------------------------------------------------------------------------
56
+ # Constants. We mirror joule_billing's canonical hashing when that module is
57
+ # importable (single source of the receipt-hash math); otherwise a byte-identical
58
+ # local fallback so this module also runs fully standalone / offline in tests.
59
+ # ---------------------------------------------------------------------------
60
+ JOULES_PER_KWH = 3_600_000.0
61
+ GENESIS_PREV = "0" * 64
62
+
63
+ LABEL_MEASURED = "MEASURED"
64
+ LABEL_ESTIMATE = "ESTIMATE"
65
+ LABEL_UNKNOWN = "UNKNOWN"
66
+
67
+ DOCTRINE = (
68
+ "Doctrine v11: cheapest-watt PLACEMENT + accounting, NOT fused VRAM. Each node keeps "
69
+ "its own MEASURED joules; nothing merged. Energy-intensity (J/token) is MEASURED only "
70
+ "from a node's own per-node NVML joule delta and tokens (both >0); else intensity is "
71
+ "UNKNOWN and the node is never ranked on cost. Grid price (€/MWh) is the live meter "
72
+ "value passed through verbatim, never assumed. A saving is MEASURED only when BOTH the "
73
+ "chosen leg and the named baseline leg are MEASURED (real per-node J/token + live price); "
74
+ "any modeled/assumed baseline => ESTIMATE. With <2 comparable MEASURED nodes there is no "
75
+ "placement choice this tick (decision=no_choice) — we never invent an alternative. Never "
76
+ "fabricate a price or a saving. Receipts re-hashable offline + hash-chained "
77
+ "(prev_digest). sovereign=false; Λ=Conjecture 1; trust never 100%."
78
+ )
79
+
80
+
81
+ def sha256_canon(obj: dict) -> str:
82
+ """Canonical sha256 over a dict (sorted keys, tight separators). Prefers
83
+ joule_billing.sha256_canon so the hash math is the SAME single source the
84
+ JouleCharge receipts use; falls back to a byte-identical local impl."""
85
+ try:
86
+ from joule_billing import sha256_canon as _sc # type: ignore
87
+ return _sc(obj)
88
+ except Exception:
89
+ return "sha256:" + hashlib.sha256(
90
+ json.dumps(obj, sort_keys=True, separators=(",", ":")).encode()
91
+ ).hexdigest()
92
+
93
+
94
+ # ---------------------------------------------------------------------------
95
+ # Candidate model. One candidate = one reachable, COMPUTING sovereign node with
96
+ # its own metered energy this read. We read per-node joules + tokens from the
97
+ # operator's by_node block (MEASURED-only) and power_w from status when present.
98
+ # ---------------------------------------------------------------------------
99
+ @dataclass
100
+ class Candidate:
101
+ name: str
102
+ sovereign: bool
103
+ joules_label: str # MEASURED | PENDING_EXPORTER | NONE (from operator by_node)
104
+ joules_measured: float # node's own cumulative MEASURED joules (billable)
105
+ tokens: int # node's own cumulative tokens
106
+ power_w: Optional[float] = None # latest live exporter power_w for this node, if known
107
+
108
+ # derived (filled by the policy)
109
+ joules_per_token: Optional[float] = None # MEASURED intensity, or None if UNKNOWN
110
+ intensity_label: str = LABEL_UNKNOWN
111
+ eur_per_token: Optional[float] = None # cost = J/token /3.6e9 *kWh * €/MWh, or None
112
+ note: str = ""
113
+
114
+ def to_dict(self) -> dict:
115
+ return {
116
+ "node": self.name,
117
+ "sovereign": self.sovereign,
118
+ "joules_label": self.joules_label,
119
+ "joules_measured": round(self.joules_measured, 6),
120
+ "tokens": self.tokens,
121
+ "power_w": self.power_w,
122
+ "joules_per_token": (round(self.joules_per_token, 9)
123
+ if self.joules_per_token is not None else None),
124
+ "intensity_label": self.intensity_label,
125
+ "eur_per_token": (None if self.eur_per_token is None
126
+ else float(f"{self.eur_per_token:.6e}")),
127
+ "note": self.note,
128
+ }
129
+
130
+
131
+ def _candidates_from_status(status: Dict[str, Any]) -> List[Candidate]:
132
+ """Build candidates from a live energy-operator status dict (the SAME shape
133
+ /api/a11oy/v1/energy/operator/status returns). Only nodes that are COMPUTING
134
+ this read are candidates (a standby/DEGRADED node never serves, so it is never
135
+ a placement target). Per-node energy comes from status['by_node'] verbatim —
136
+ MEASURED only; PENDING/NONE => intensity UNKNOWN, never fabricated."""
137
+ by_node = status.get("by_node") or {}
138
+ computing = set(status.get("nodes_computing") or [])
139
+ # power_w_sample is the most-recent live exporter watt reading (single source in
140
+ # this status shape). We attach it to the MEASURED node it belongs to (the one
141
+ # whose joules are MEASURED) — never spread to a node we have no reading for.
142
+ power_w = status.get("power_w_sample")
143
+ exporter_measured_node = None
144
+ for name, b in by_node.items():
145
+ if (b or {}).get("joules_label") == LABEL_MEASURED:
146
+ exporter_measured_node = name
147
+ break
148
+ cands: List[Candidate] = []
149
+ for name, b in by_node.items():
150
+ if name not in computing:
151
+ continue # only nodes actually computing this read can be chosen
152
+ b = b or {}
153
+ cands.append(Candidate(
154
+ name=name,
155
+ sovereign=True, # only owned-metal sovereign workers reach by_node compute
156
+ joules_label=str(b.get("joules_label") or "NONE"),
157
+ joules_measured=float(b.get("joules_measured") or 0.0),
158
+ tokens=int(b.get("tokens") or 0),
159
+ power_w=(float(power_w) if (power_w is not None
160
+ and name == exporter_measured_node) else None),
161
+ ))
162
+ return cands
163
+
164
+
165
+ # ---------------------------------------------------------------------------
166
+ # The policy. Compute MEASURED J/token per candidate, then €/token from the live
167
+ # grid price, then pick the cheapest. Build an honest decision + receipt.
168
+ # ---------------------------------------------------------------------------
169
+ def _eur_per_token(joules_per_token: Optional[float],
170
+ grid_price_eur_mwh: Optional[float]) -> Optional[float]:
171
+ """€/token = (J/token / 3.6e9 J/kWh) * (€/MWh / 1000 kWh/MWh).
172
+ Returns None (UNKNOWN) when intensity or price is missing — never assumed."""
173
+ if joules_per_token is None or grid_price_eur_mwh is None:
174
+ return None
175
+ kwh_per_token = joules_per_token / JOULES_PER_KWH
176
+ eur_per_kwh = float(grid_price_eur_mwh) / 1000.0
177
+ return kwh_per_token * eur_per_kwh
178
+
179
+
180
+ def evaluate(status: Dict[str, Any],
181
+ baseline: str = "most_expensive_comparable",
182
+ prev_digest: str = GENESIS_PREV,
183
+ now_ts: Optional[float] = None) -> Dict[str, Any]:
184
+ """Run ONE cheapest-watt placement evaluation against a live operator status.
185
+
186
+ Returns an honest decision dict carrying a re-hashable receipt. NEVER fabricates
187
+ a price or a saving. With <2 comparable MEASURED-intensity nodes it returns
188
+ decision='no_choice' (reason 'no placement choice this tick').
189
+ """
190
+ now_ts = time.time() if now_ts is None else now_ts
191
+ ts_iso = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime(now_ts))
192
+ grid = status.get("grid_price_eur_mwh")
193
+ grid = float(grid) if isinstance(grid, (int, float)) else None
194
+
195
+ cands = _candidates_from_status(status)
196
+ # Derive MEASURED intensity + cost for each candidate.
197
+ for c in cands:
198
+ if c.joules_label == LABEL_MEASURED and c.joules_measured > 0 and c.tokens > 0:
199
+ c.joules_per_token = c.joules_measured / c.tokens
200
+ c.intensity_label = LABEL_MEASURED
201
+ c.eur_per_token = _eur_per_token(c.joules_per_token, grid)
202
+ c.note = "MEASURED J/token from this node's own NVML joule delta / its tokens"
203
+ else:
204
+ c.joules_per_token = None
205
+ c.intensity_label = LABEL_UNKNOWN
206
+ c.eur_per_token = None
207
+ c.note = ("intensity unknown — node computed but per-node MEASURED joules "
208
+ "are pending (%s); never ranked on cost, never fabricated"
209
+ % (c.joules_label,))
210
+
211
+ comparable = [c for c in cands if c.intensity_label == LABEL_MEASURED]
212
+
213
+ base_decision: Dict[str, Any] = {
214
+ "receipt_type": "SZL.Energy.CheapestWattPlacement.v1",
215
+ "ts": ts_iso,
216
+ "grid_price_eur_mwh": grid,
217
+ "grid_price_label": (LABEL_MEASURED if grid is not None else LABEL_UNKNOWN),
218
+ "grid_price_note": ("live meter value at decision time, passed through verbatim"
219
+ if grid is not None else
220
+ "no live grid price this read — cost is UNKNOWN, never assumed"),
221
+ "baseline_policy": baseline,
222
+ "candidates": [c.to_dict() for c in cands],
223
+ "reachable_computing_count": len(cands),
224
+ "comparable_measured_count": len(comparable),
225
+ "honesty": {
226
+ "sovereign": False,
227
+ "lambda": "Conjecture 1",
228
+ "trust": "never 100%",
229
+ "placement": "horizontal cost/carbon-aware placement; VRAM NOT fused",
230
+ "fabrication": "no price or saving is ever fabricated",
231
+ },
232
+ }
233
+
234
+ if len(comparable) < 2:
235
+ decision = dict(base_decision)
236
+ decision.update({
237
+ "decision": "no_choice",
238
+ "chosen_node": None,
239
+ "reason": "no placement choice this tick",
240
+ "detail": (
241
+ "fewer than two nodes have a comparable MEASURED energy-intensity "
242
+ "this read (%d computing, %d MEASURED-intensity); with no real "
243
+ "alternative we decline to claim a saving — never fabricated."
244
+ % (len(cands), len(comparable))
245
+ ),
246
+ "saving": None,
247
+ "saving_label": None,
248
+ })
249
+ return _finalize(decision, prev_digest)
250
+
251
+ # Rank comparable nodes by €/token when a price exists; else by J/token (still a
252
+ # real, MEASURED energy ranking — labeled as energy-only, no monetary claim).
253
+ if grid is not None:
254
+ ranked = sorted(comparable, key=lambda c: c.eur_per_token) # type: ignore[arg-type]
255
+ metric = "eur_per_token"
256
+ else:
257
+ ranked = sorted(comparable, key=lambda c: c.joules_per_token) # type: ignore[arg-type]
258
+ metric = "joules_per_token"
259
+
260
+ chosen = ranked[0]
261
+ # Named baseline = the most-expensive comparable node we DECLINED this tick.
262
+ # That is a REAL alternative leg with MEASURED intensity -> the delta is MEASURED
263
+ # (when a live price also exists; otherwise it is a MEASURED energy delta, and any
264
+ # monetary framing would be ESTIMATE).
265
+ baseline_node = ranked[-1]
266
+
267
+ if metric == "eur_per_token":
268
+ chosen_cost = chosen.eur_per_token
269
+ base_cost = baseline_node.eur_per_token
270
+ delta = base_cost - chosen_cost # €/token saved vs the declined alternative
271
+ # BOTH legs MEASURED (real per-node J/token) AND a live price => MEASURED saving.
272
+ saving_label = LABEL_MEASURED
273
+ saving = {
274
+ "metric": "eur_per_token",
275
+ "chosen_eur_per_token": float(f"{chosen_cost:.6e}"),
276
+ "baseline_eur_per_token": float(f"{base_cost:.6e}"),
277
+ "delta_eur_per_token": float(f"{delta:.6e}"),
278
+ "delta_pct": (round(100.0 * delta / base_cost, 4) if base_cost else None),
279
+ "baseline_node": baseline_node.name,
280
+ "note": (
281
+ "MEASURED: both legs are real per-node NVML J/token AND the grid price "
282
+ "is the live meter value; delta is vs the most-expensive comparable node "
283
+ "we declined this tick (a real alternative), not a hypothetical baseline."
284
+ ),
285
+ }
286
+ else:
287
+ # No live price: we can only state the MEASURED energy delta; any euro figure
288
+ # would require a price we do not have, so we DO NOT emit one (ESTIMATE-or-none).
289
+ chosen_j = chosen.joules_per_token
290
+ base_j = baseline_node.joules_per_token
291
+ jdelta = base_j - chosen_j
292
+ saving_label = LABEL_ESTIMATE # monetary saving cannot be MEASURED w/o a price
293
+ saving = {
294
+ "metric": "joules_per_token",
295
+ "chosen_joules_per_token": round(chosen_j, 9),
296
+ "baseline_joules_per_token": round(base_j, 9),
297
+ "delta_joules_per_token": round(jdelta, 9),
298
+ "delta_pct": (round(100.0 * jdelta / base_j, 4) if base_j else None),
299
+ "baseline_node": baseline_node.name,
300
+ "note": (
301
+ "ESTIMATE (monetary): energy delta is MEASURED (real per-node J/token), "
302
+ "but NO live grid price this read, so a euro saving cannot be MEASURED — "
303
+ "we report the MEASURED joules delta only and never assume a price."
304
+ ),
305
+ }
306
+
307
+ decision = dict(base_decision)
308
+ decision.update({
309
+ "decision": "placed",
310
+ "chosen_node": chosen.name,
311
+ "rank_metric": metric,
312
+ "reason": ("chosen node minimizes %s among comparable MEASURED-intensity "
313
+ "sovereign nodes this tick" % metric),
314
+ "ranking": [c.name for c in ranked],
315
+ "saving": saving,
316
+ "saving_label": saving_label,
317
+ })
318
+ return _finalize(decision, prev_digest)
319
+
320
+
321
+ def _finalize(decision: Dict[str, Any], prev_digest: str) -> Dict[str, Any]:
322
+ """Attach the re-hashable payload_digest and the chain prev_digest. The
323
+ entry_digest binds (prev_digest, payload_digest) the same way the energy ledger
324
+ binds its entries, so a cheapest-watt receipt slots into the same chain shape."""
325
+ payload_digest = sha256_canon(decision)
326
+ entry_digest = sha256_canon({"prev_digest": prev_digest,
327
+ "payload_digest": payload_digest})
328
+ return {
329
+ "decision": decision,
330
+ "payload_digest": payload_digest,
331
+ "prev_digest": prev_digest,
332
+ "entry_digest": entry_digest,
333
+ }
334
+
335
+
336
+ # ---------------------------------------------------------------------------
337
+ # CheapestWattLedger — a small, in-process, hash-chained tally of placement
338
+ # decisions + cumulative MEASURED savings. Thread-safe; bounded recent tail.
339
+ # It NEVER persists a key and NEVER fabricates — it only records what evaluate()
340
+ # returned. Cumulative MEASURED savings sum ONLY the receipts whose saving_label
341
+ # is MEASURED (both legs real). ESTIMATE/none savings are tallied separately.
342
+ # ---------------------------------------------------------------------------
343
+ class CheapestWattLedger:
344
+ def __init__(self, max_tail: int = 50) -> None:
345
+ self._lock = threading.RLock()
346
+ self._head = GENESIS_PREV
347
+ self._count = 0
348
+ self._placed = 0
349
+ self._no_choice = 0
350
+ self._cum_measured_eur_per_token_saved = 0.0 # sum of MEASURED €/token deltas
351
+ self._measured_saving_receipts = 0
352
+ self._estimate_saving_receipts = 0
353
+ self._recent: List[Dict[str, Any]] = []
354
+
355
+ def record(self, status: Dict[str, Any],
356
+ baseline: str = "most_expensive_comparable") -> Dict[str, Any]:
357
+ """Evaluate against a live status and append the resulting receipt to the
358
+ chain. Returns the receipt. MEASURED savings accumulate ONLY from receipts
359
+ whose saving_label==MEASURED — honest by construction."""
360
+ with self._lock:
361
+ receipt = evaluate(status, baseline=baseline, prev_digest=self._head)
362
+ self._head = receipt["entry_digest"]
363
+ self._count += 1
364
+ d = receipt["decision"]
365
+ if d["decision"] == "placed":
366
+ self._placed += 1
367
+ lab = d.get("saving_label")
368
+ sv = d.get("saving") or {}
369
+ if lab == LABEL_MEASURED and "delta_eur_per_token" in sv:
370
+ self._cum_measured_eur_per_token_saved += float(sv["delta_eur_per_token"])
371
+ self._measured_saving_receipts += 1
372
+ elif lab == LABEL_ESTIMATE:
373
+ self._estimate_saving_receipts += 1
374
+ else:
375
+ self._no_choice += 1
376
+ self._recent.append(receipt)
377
+ if len(self._recent) > 50:
378
+ self._recent.pop(0)
379
+ return receipt
380
+
381
+ def verify(self) -> Tuple[bool, int, int]:
382
+ """Re-walk the chain offline: each receipt re-hashes to its payload_digest
383
+ AND its entry_digest binds (prev_digest, payload_digest); each prev links to
384
+ the previous entry_digest. Returns (ok, length, first_break_index)."""
385
+ with self._lock:
386
+ prev = GENESIS_PREV
387
+ for i, r in enumerate(self._recent):
388
+ pd = sha256_canon(r["decision"])
389
+ ed = sha256_canon({"prev_digest": r["prev_digest"],
390
+ "payload_digest": pd})
391
+ if (pd != r["payload_digest"] or ed != r["entry_digest"]
392
+ or r["prev_digest"] != prev):
393
+ return (False, len(self._recent), i)
394
+ prev = r["entry_digest"]
395
+ return (True, len(self._recent), -1)
396
+
397
+ def status(self) -> Dict[str, Any]:
398
+ with self._lock:
399
+ ok, length, brk = self.verify()
400
+ return {
401
+ "service": "cheapest-watt-placement",
402
+ "kind": "carbon/cost-aware placement + accounting (NOT fused VRAM)",
403
+ "decisions_total": self._count,
404
+ "placed": self._placed,
405
+ "no_choice": self._no_choice,
406
+ "cumulative_measured_eur_per_token_saved":
407
+ float(f"{self._cum_measured_eur_per_token_saved:.9e}")
408
+ if self._cum_measured_eur_per_token_saved else 0.0,
409
+ "cumulative_measured_saving_label": LABEL_MEASURED,
410
+ "measured_saving_receipts": self._measured_saving_receipts,
411
+ "estimate_saving_receipts": self._estimate_saving_receipts,
412
+ "chain": {
413
+ "head": self._head,
414
+ "length": length,
415
+ "ok": ok,
416
+ "first_break_index": brk,
417
+ "genesis_prev": GENESIS_PREV,
418
+ },
419
+ "recent_decisions": [r["decision"] for r in self._recent[-10:]],
420
+ "doctrine": DOCTRINE,
421
+ "honesty": (
422
+ "cumulative_measured_eur_per_token_saved sums ONLY receipts whose "
423
+ "saving_label==MEASURED (both the chosen leg and the named declined-"
424
+ "alternative leg are real per-node MEASURED J/token AND a live grid "
425
+ "price). ESTIMATE savings (e.g. no live price this read) are counted "
426
+ "separately and never folded into the MEASURED total. no_choice ticks "
427
+ "(<2 comparable MEASURED nodes) claim NO saving. Never fabricated."
428
+ ),
429
+ }
430
+
431
+
432
+ # Module-level singleton the endpoint drives (one tally per process).
433
+ _LEDGER: Optional[CheapestWattLedger] = None
434
+ _LEDGER_LOCK = threading.Lock()
435
+
436
+
437
+ def get_ledger() -> CheapestWattLedger:
438
+ global _LEDGER
439
+ with _LEDGER_LOCK:
440
+ if _LEDGER is None:
441
+ _LEDGER = CheapestWattLedger()
442
+ return _LEDGER
443
+
444
+
445
+ # ---------------------------------------------------------------------------
446
+ # Offline self-test — proves the honesty gates with NO live GPU and NO network.
447
+ # ---------------------------------------------------------------------------
448
+ def _selftest() -> dict:
449
+ out: dict = {}
450
+
451
+ # (a) Two comparable MEASURED nodes + a live price => MEASURED saving, cheaper wins.
452
+ status_two = {
453
+ "grid_price_eur_mwh": 111.24,
454
+ "power_w_sample": 13.02,
455
+ "nodes_computing": ["rtx-betterwithage", "chaski"],
456
+ "by_node": {
457
+ "rtx-betterwithage": {"joules_label": "MEASURED",
458
+ "joules_measured": 910844.34, "tokens": 12002478},
459
+ # synthetic 2nd MEASURED node for the gate (more J/token = pricier)
460
+ "chaski": {"joules_label": "MEASURED",
461
+ "joules_measured": 200000.0, "tokens": 1024134},
462
+ },
463
+ }
464
+ r = evaluate(status_two)
465
+ d = r["decision"]
466
+ assert d["decision"] == "placed", d
467
+ assert d["saving_label"] == "MEASURED", d
468
+ # cheaper = lower J/token. rtx: ~0.0759 J/tok ; chaski: ~0.1953 J/tok -> rtx chosen
469
+ assert d["chosen_node"] == "rtx-betterwithage", d["chosen_node"]
470
+ assert d["saving"]["delta_eur_per_token"] > 0, d["saving"]
471
+ # receipt re-hashes offline
472
+ assert sha256_canon(d) == r["payload_digest"]
473
+ out["two_measured_live_price_measured_saving"] = True
474
+
475
+ # (b) Only ONE comparable MEASURED node (chaski PENDING) => no placement choice.
476
+ status_one = {
477
+ "grid_price_eur_mwh": 111.24,
478
+ "power_w_sample": 13.02,
479
+ "nodes_computing": ["rtx-betterwithage", "chaski"],
480
+ "by_node": {
481
+ "rtx-betterwithage": {"joules_label": "MEASURED",
482
+ "joules_measured": 910844.34, "tokens": 12002478},
483
+ "chaski": {"joules_label": "PENDING_EXPORTER",
484
+ "joules_measured": 0.0, "tokens": 1024134},
485
+ },
486
+ }
487
+ r1 = evaluate(status_one)
488
+ assert r1["decision"]["decision"] == "no_choice", r1["decision"]
489
+ assert r1["decision"]["reason"] == "no placement choice this tick"
490
+ assert r1["decision"]["saving"] is None
491
+ out["one_node_no_choice"] = True
492
+
493
+ # (c) Two MEASURED nodes but NO live price => energy-only ranking, ESTIMATE saving.
494
+ status_noprice = dict(status_two)
495
+ status_noprice = {**status_two, "grid_price_eur_mwh": None}
496
+ r2 = evaluate(status_noprice)
497
+ d2 = r2["decision"]
498
+ assert d2["decision"] == "placed" and d2["rank_metric"] == "joules_per_token", d2
499
+ assert d2["saving_label"] == "ESTIMATE", d2 # no price => monetary saving not MEASURED
500
+ assert "delta_eur_per_token" not in (d2["saving"] or {}), d2["saving"]
501
+ out["no_price_estimate_saving_no_fabricated_euro"] = True
502
+
503
+ # (d) Ledger: MEASURED savings accumulate ONLY from MEASURED receipts; chain verifies.
504
+ led = CheapestWattLedger()
505
+ led.record(status_two) # MEASURED saving
506
+ led.record(status_one) # no_choice (no saving)
507
+ led.record(status_noprice) # ESTIMATE saving (not folded into MEASURED total)
508
+ st = led.status()
509
+ assert st["decisions_total"] == 3 and st["placed"] == 2 and st["no_choice"] == 1, st
510
+ assert st["measured_saving_receipts"] == 1, st
511
+ assert st["estimate_saving_receipts"] == 1, st
512
+ assert st["cumulative_measured_eur_per_token_saved"] > 0, st
513
+ assert st["chain"]["ok"] is True and st["chain"]["length"] == 3, st["chain"]
514
+ out["ledger_measured_only_accumulation_and_chain_ok"] = True
515
+
516
+ return out
517
+
518
+
519
+ if __name__ == "__main__":
520
+ import sys as _sys
521
+ print("=" * 70)
522
+ print("szl_cheapest_watt — self-test (honesty gates, no live GPU, no network)")
523
+ print("=" * 70)
524
+ res = _selftest()
525
+ print(json.dumps(res, indent=2))
526
+ ok = all(res.values())
527
+ print("\nSELFTEST", "PASS" if ok else "FAIL")
528
+ _sys.exit(0 if ok else 1)