Files
David F GliddenandClaude Opus 5 1e40b01d70 [FIX] Normalization tested at its single point; the dry run had bypassed it (PENDING-149)
The jurist's pre-25th condition: confirm lowercasing happens at exactly one
point and is unit-tested against a known uppercase input.

Single point confirmed at derive_fool.py:79 — the only .lower()/.upper()/
casefold in the file. Four checks added, including a negative control proving
the test can fail. Selftest 16/16.

Checking it found the defect the condition was aimed at, in my own work: the
2026-08-22 dry run lowercased the value OUTSIDE the code and passed it in
already normalized, so the single normalization point was never exercised on
uppercase input in the only end-to-end run. The test's subject was the
pipeline; it excluded the step under scrutiny.

Re-run with the raw uppercase value through the real path reproduces the same
seed. Binding procedure added: on the 25th the outputValue is passed exactly
as served.

Jurist ruling on the URL correction recorded verbatim — no veto, with the
reasoning, since it will be read later.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQKeKY9T9d95KpvHwwok8T
2026-08-22 21:30:16 +02:00

162 lines
7.1 KiB
Python
Executable File

#!/usr/bin/env python3
"""
Fool bones derivation — PENDING-149 §6 / §6b.
Deterministic. No salt. No reroll path. Nothing is cached: the caller supplies
the two seed components and the bones are recomputed from them every time.
This file implements the FILED RULE (FOOL-SEED-RULE.md). Where this code and the
filed rule disagree, THE FILED RULE GOVERNS and this file is the defect.
Usage:
derive_fool.py --beacon <outputValue-hex> # bones from a pulse value
derive_fool.py --selftest # determinism + range checks, no network
"""
import argparse, hashlib, subprocess, sys
# ---- the filed rule's constants. Do not edit without amending the filed rule. ----
PROVENANCE_COMMIT = "4d2ae87a4e5350c4d3bb3aa50f9544b521d9c53d"
PROVENANCE_PATH = "CLAUDE.md"
PROVENANCE_REPO = "/Users/davidglidden/dotfiles"
PROVENANCE_SHA256 = "2d6e250a347d25698fb147f80e2dababbb930c4b3b3f9bb822478f360153120d"
AXES = ["SUCCESSION", "ABSENCE", "AIM", "SCALE", "STAKE"] # §5, ratified order
PEAK_RANGE = (85, 100) # "near max" — executor-specified, filed pre-beacon
DUMP_RANGE = (0, 15) # "near floor" — executor-specified, filed pre-beacon
SCATTER_RANGE = (25, 75) # "scattered" — executor-specified, filed pre-beacon
def provenance_sha() -> str:
"""SHA-256 of CLAUDE.md at the named past commit. Recomputed, never trusted from the constant."""
blob = subprocess.run(
["git", "-C", PROVENANCE_REPO, "cat-file", "-p", f"{PROVENANCE_COMMIT}:{PROVENANCE_PATH}"],
capture_output=True, check=True).stdout
got = hashlib.sha256(blob).hexdigest()
if got != PROVENANCE_SHA256:
raise SystemExit(f"STOP: provenance blob does not match the filed rule.\n"
f" filed: {PROVENANCE_SHA256}\n got: {got}")
return got
def fnv1a_32(data: bytes) -> int:
h = 0x811C9DC5
for b in data:
h ^= b
h = (h * 0x01000193) & 0xFFFFFFFF
return h
def mulberry32(a: int):
"""Reference Mulberry32, 32-bit wrapped to match the JS original exactly:
a = a + 0x6D2B79F5 | 0
t = Math.imul(a ^ a >>> 15, 1 | a)
t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t
return ((t ^ t >>> 14) >>> 0) / 4294967296
"""
M = 0xFFFFFFFF
state = a & M
def imul(x, y):
r = (x * y) & M
return r - 0x100000000 if r & 0x80000000 else r
def rnd():
nonlocal state
state = (state + 0x6D2B79F5) & M
a_ = state
t = imul(a_ ^ (a_ >> 15), 1 | a_) & M
t = ((t + imul(t ^ (t >> 7), 61 | t)) & M) ^ t
return ((t ^ (t >> 14)) & M) / 4294967296.0
return rnd
def draw_int(rnd, lo: int, hi: int) -> int:
return lo + int(rnd() * (hi - lo + 1))
def derive(beacon_output_value: str) -> dict:
beacon = beacon_output_value.strip().lower()
if not beacon or any(c not in "0123456789abcdef" for c in beacon):
raise SystemExit("STOP: beacon outputValue must be non-empty lowercase hex.")
prov = provenance_sha()
seed_string = prov + beacon
seed = hashlib.sha256(seed_string.encode()).hexdigest()
rnd = mulberry32(fnv1a_32(seed.encode()))
order = list(range(len(AXES))) # Fisher-Yates over the PRNG
for i in range(len(order) - 1, 0, -1):
j = int(rnd() * (i + 1))
order[i], order[j] = order[j], order[i]
stats = {}
stats[AXES[order[0]]] = draw_int(rnd, *PEAK_RANGE)
stats[AXES[order[1]]] = draw_int(rnd, *DUMP_RANGE)
for k in order[2:]:
stats[AXES[k]] = draw_int(rnd, *SCATTER_RANGE)
return {"provenance_sha256": prov, "beacon_outputValue": beacon,
"seed_string": seed_string, "seed": seed,
"peak": AXES[order[0]], "dump": AXES[order[1]],
"stats": {a: stats[a] for a in AXES}}
def selftest() -> int:
"""No network. Fixed synthetic vectors only — never a live or near-future pulse."""
ok = True
V1 = "0" * 128
V2 = "f" * 128
r1, r1b, r2 = derive(V1), derive(V1), derive(V2)
checks = [
("determinism: same input twice -> identical bones", r1 == r1b),
("sensitivity: different beacon -> different seed", r1["seed"] != r2["seed"]),
("provenance recomputed matches filed rule", r1["provenance_sha256"] == PROVENANCE_SHA256),
("seed_string is prov||beacon, no salt", r1["seed_string"] == PROVENANCE_SHA256 + V1),
("exactly five axes", sorted(r1["stats"]) == sorted(AXES)),
("peak in range", PEAK_RANGE[0] <= r1["stats"][r1["peak"]] <= PEAK_RANGE[1]),
("dump in range", DUMP_RANGE[0] <= r1["stats"][r1["dump"]] <= DUMP_RANGE[1]),
("peak is not dump", r1["peak"] != r1["dump"]),
("three scattered in range", all(SCATTER_RANGE[0] <= v <= SCATTER_RANGE[1]
for a, v in r1["stats"].items()
if a not in (r1["peak"], r1["dump"]))),
("no floor: dump can reach the bottom of its range",
min(derive(f"{i:0128x}")["stats"][derive(f"{i:0128x}")["dump"]] for i in range(200)) <= DUMP_RANGE[0] + 1),
]
# --- normalization: the jurist's pre-25th condition. outputValue is served UPPERCASE. ---
UP = "A1B2C3D4E5F6" * 10 + "ABCDEFAB" # 128 chars, uppercase hex
LOW = UP.lower()
r_up, r_low = derive(UP), derive(LOW)
# independent expectation, computed here rather than read back from derive()
import hashlib as _h
expected_seed = _h.sha256((PROVENANCE_SHA256 + LOW).encode()).hexdigest()
wrong_seed = _h.sha256((PROVENANCE_SHA256 + UP ).encode()).hexdigest()
checks += [
("UPPERCASE input normalizes: bones identical to lowercase", r_up == r_low),
("UPPERCASE input matches independently computed seed", r_up["seed"] == expected_seed),
("recorded beacon field is stored lowercased", r_up["beacon_outputValue"] == LOW),
("NEGATIVE CONTROL: un-normalized input WOULD give a different seed "
"(so the check above can fail)", expected_seed != wrong_seed),
]
# positive control: the PRNG must actually move both peak and dump around the axes
peaks = {derive(f"{i:0128x}")["peak"] for i in range(200)}
dumps = {derive(f"{i:0128x}")["dump"] for i in range(200)}
checks.append(("POSITIVE CONTROL: peak lands on all five axes over 200 draws", peaks == set(AXES)))
checks.append(("POSITIVE CONTROL: dump lands on all five axes over 200 draws", dumps == set(AXES)))
for name, passed in checks:
print(f" {'PASS' if passed else 'FAIL'} {name}")
ok &= passed
print(f"\n{'SELFTEST PASSED' if ok else 'SELFTEST FAILED — do not run against a live pulse'}")
return 0 if ok else 1
if __name__ == "__main__":
p = argparse.ArgumentParser()
p.add_argument("--beacon"); p.add_argument("--selftest", action="store_true")
a = p.parse_args()
if a.selftest:
sys.exit(selftest())
if not a.beacon:
p.error("--beacon <outputValue-hex> required (or --selftest)")
import json; print(json.dumps(derive(a.beacon), indent=2))