The Principia Machina/TPC-PY/diff volunteer.py: Difference between revisions
Appearance
TPC-PY source diff_volunteer.py (0.1.0), SHA-256 34cb5260e9e0fbe0; conformed TPS 0.3.0; PROPOSED, not declared (CO-8) |
m 1 revision imported |
||
(No difference)
| |||
Latest revision as of 04:32, 28 September 2026
"""diff_volunteer 0.1.0: the cross-residence differential for
tpc_volunteer 0.1.0. Random inputs from a seed over every function
(random r values, states across every branch of the draw, the params
fixture varied), both residences on the same inputs, every render
compared byte for byte; 0 differences is the pass.
Usage: python3 diff_volunteer.py [seed] [cases]."""
import json
import os
import random
import subprocess
import sys
import tempfile
here = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, here)
from params_fixture import FLEET, fleet # noqa: E402
from tpc_volunteer import run_case, FNS # noqa: E402
seed = int(sys.argv[1]) if len(sys.argv) > 1 else 1
count = int(sys.argv[2]) if len(sys.argv) > 2 else 20000
rnd = random.Random(seed)
def pick(xs):
return xs[rnd.randrange(len(xs))]
def bad():
return rnd.random() < 0.03
def kind(good, more):
return pick(more) if bad() else pick(good)
def rhex():
if bad():
return pick(["", "zz", "0" * 31, "A" * 32, 5])
return "%032x" % rnd.getrandbits(128)
def cnt(lo, hi):
if bad():
return pick([True, None, "5", 1.5, -1])
return rnd.randint(lo, hi)
def unit():
if bad():
return pick([True, None, "0.5", -0.1, 1.5])
return round(rnd.random(), rnd.randint(0, 6))
def flag():
return (rnd.random() < 0.5) if not bad() else pick([1, "x", None])
def params():
p = fleet()
r = rnd.random()
if r < 0.5:
return p
invalid = r > 0.93
for _ in range(rnd.randint(1, 3)):
k = pick(["VOLUNTEER TIER", "VOLUNTEER RATE", "VOLUNTEER BURST", "BACKOFF BASE", "BACKOFF CAP",
"INTAKE w_q", "INTAKE MIN", "INTAKE MAX", "INTAKE MAX_P", "P_V BOUNDS", "P_V ROTATION",
"EARLY CALL LIMIT", "VOLUNTEER COOL-OFF", "CONSISTENCY SHARE"])
if k == "VOLUNTEER TIER":
p[k] = pick(["ANY GREEN", "TRUST TIER"] + (["TOP"] if invalid else []))
elif k == "P_V BOUNDS":
p[k] = pick([[0.25, 0.5], [0.1, 0.2], [0.4, 0.4], [0.01, 0.99]] + ([[0, 0.5], [0.5, 1], [0.5, 0.25]] if invalid else []))
elif k in ("VOLUNTEER BURST", "EARLY CALL LIMIT", "VOLUNTEER COOL-OFF"):
p[k] = pick([1, 2, 3, 5, 10, 200] + ([0, -1, 1.5] if invalid else []) if k != "EARLY CALL LIMIT" else [0, 1, 3, 5] + ([-1, 1.5] if invalid else []))
elif k in ("BACKOFF BASE", "BACKOFF CAP"):
p[k] = pick([60, 300, 3600, 14400] + ([0.5, 100000000000000] if invalid else []))
elif k == "VOLUNTEER RATE":
p[k] = pick([2, 60, 0.5, 1] + ([0, -1] if invalid else []))
else:
p[k] = pick([0.1, 0.2, 0.25, 0.5, 0.9, 1, 0] + ([1.5, -0.1, "x"] if invalid else []))
if invalid and rnd.random() < 0.3:
del p[pick(["VOLUNTEER TIER", "VOLUNTEER RATE", "BACKOFF CAP", "INTAKE MIN", "P_V BOUNDS"])]
return p
def facts():
f = {"certificate_current": rnd.random() < 0.96, "dis_match": rnd.random() < 0.96,
"state": kind(["GREEN"] * 8 + ["YELLOW", "ORANGE", "SUSPENDED"], ["RED"]),
"reset_in_force": rnd.random() < 0.05, "suspended": rnd.random() < 0.03, "in_tier": rnd.random() < 0.5}
if bad():
f["certificate_current"] = 1
if bad():
del f["in_tier"]
return f
def bucket():
return {"tokens": kind([0, 0.5, 1, 1.75, 2, 3, round(rnd.uniform(0, 3), 4)], [-1, True, "1"]),
"updated": cnt(0, 2000000)}
def gen(fn):
p = params()
if fn == "standing":
return {"facts": facts(), "params": p}
if fn == "refill":
b = bucket()
now = b["updated"] + rnd.randint(0, 40000) if isinstance(b["updated"], int) and not bad() else cnt(0, 100)
return {"bucket": b, "now": now, "params": p}
if fn == "take":
return {"bucket": bucket()}
if fn == "retry":
return {"attempt": kind([0, 1, 2, 3, 5, 6, 10, 1023, 1024, 5000], [-1, 1.5]), "r": rhex(), "params": p}
if fn == "intake":
landed = cnt(0, 100)
vol = rnd.randint(0, landed) if isinstance(landed, int) and landed >= 0 and not bad() else cnt(0, 100)
return {"intake": unit(), "volunteer_blocks": vol, "landed_blocks": landed, "params": p}
if fn == "p_nw":
return {"intake": kind([0, 0.25, 0.375, 0.5, 0.51, 1, round(rnd.random(), 4)], [-0.1, 1.1]), "params": p}
if fn == "pv":
return {"state": {"p_v": kind([None, 0.3, 0.25, 0.5, round(rnd.random(), 4)], [1.5, "x"])} if not bad() else {},
"r": rhex(), "params": p}
if fn == "share":
return {"window": [{"volunteer": flag(), "weight": kind([0, 0.5, 1, 2, round(rnd.uniform(0, 3), 3)], [-1, "1"])}
for _ in range(rnd.randint(0, 6))] if not bad() else {},
"g": kind([1, 2, 0.5], [0, -1]), "v_max": kind([0.25, 0.5, 0.1], [0, 1])}
now = rnd.randint(2000, 8000)
st = {"bucket": {"tokens": pick([3, 2, 1.5, 1, 0.9, 0, round(rnd.uniform(0, 3), 3)]), "updated": now - rnd.randint(0, 5000)},
"retry_until": pick([None] * 6 + [float(now - 10), float(now + 100), float(now), 99999.0, float(rnd.randint(0, 9000))]),
"attempt": rnd.randint(0, 8), "refusals": rnd.randint(0, 4), "period": rnd.randint(0, 3),
"closed_until": pick([None] * 6 + [0, 50, 100, 1000]), "intake": pick([0, 0.1, 0.3, 0.45, 0.6, round(rnd.random(), 3)]),
"p_v": {"p_v": pick([None, 0.3, 0.999, 0.25, 0.5])}}
if rnd.random() < 0.05:
st[pick(list(st.keys()))] = pick([None, -1, "x", 1.5])
per = st["period"] + rnd.randint(0, 1) if isinstance(st["period"], int) else 0
call = {"now": now, "block": rnd.randint(0, 1200), "period": per, "has_item": rnd.random() < 0.6, "has_falcon": rnd.random() < 0.1,
"has_own_record": rnd.random() < 0.5, "ratio_k": pick([1 / 3, 0.5, 1000, 0.000001, 0.2]), "standing": facts()}
if rnd.random() < 0.05:
call[pick(list(call.keys()))] = pick([None, -1, "x", 1.5, 0])
return {"state": st, "call": call, "r": rhex(), "params": p}
cases = []
for _ in range(count):
fn = pick(FNS + ("draw", "draw", "draw"))
cases.append({"fn": fn, "args": gen(fn)})
CASES_PATH = os.environ.get("TPC_DIFF_CASES") # named: kept, for crosspy.py
if not CASES_PATH:
fd, CASES_PATH = tempfile.mkstemp(prefix="tpc_diff_", suffix=".json") # outside the tree
os.close(fd)
with open(CASES_PATH, "w", encoding="utf-8") as f:
json.dump(cases, f, ensure_ascii=False)
py = [run_case(c["fn"], c["args"]) for c in cases]
php = json.loads(subprocess.run(["php", os.path.join(here, "diff_volunteer.php"), CASES_PATH], capture_output=True,
text=True, check=True).stdout)
if not os.environ.get("TPC_DIFF_CASES"):
os.remove(CASES_PATH)
diffs = sum(1 for a, b in zip(py, php) if a != b)
outcomes = {}
for c, a in zip(cases, py):
k = c["fn"] + ("/ERROR" if a.startswith("ERROR") else "")
if c["fn"] == "draw" and not a.startswith("ERROR"):
k = "draw/" + a.split("\n")[0].split("|")[1]
outcomes[k] = outcomes.get(k, 0) + 1
print("seed", seed, "cases", len(cases), "differences", diffs, "php_len", len(php),
json.dumps(outcomes, sort_keys=True))
for c, a, b in zip(cases, py, php):
if a != b:
print(json.dumps(c, ensure_ascii=False)); print(a); print("---"); print(b); break