Files
resonance-engine/khra_gixx_probe.py
T
2026-06-08 17:34:31 +07:00

217 lines
8.3 KiB
Python

"""khra_gixx_probe.py — 3-test probe of lattice parameter response.
Tests Claude Desktop's channel architecture using set_khra_amp + set_gixx_amp
+ inject_density. Asks Fractonaut to qualitatively describe each state.
States:
0. BASELINE (Khra=0.030, Gixx=0.008, no injection) - 2 min stabilise
1. KHRA_ELEVATED (Khra=0.050, Gixx=0.008, no injection) - 8 min
2. GIXX_ELEVATED (Khra=0.030, Gixx=0.024, no injection) - 8 min
3. ALL_ON (Khra=0.050, Gixx=0.024, opposing inject) - 8 min
4. RESTORE (back to baseline)
Total wall-clock: ~28 min.
The Fractonaut /ask query at end of each state asks for a qualitative
field description, not a number restatement. Saves all responses to
JSONL for side-by-side comparison.
"""
import zmq, json, time, urllib.request, sys
from pathlib import Path
from datetime import datetime
CMD_ADDR = "tcp://127.0.0.1:5557"
FRACTO_URL = "http://127.0.0.1:28822/ask"
TEL_ADDR = "tcp://127.0.0.1:5556"
OUT = Path(f"/mnt/d/Resonance_Engine/traj/probe_{datetime.now().strftime('%Y%m%dT%H%M%S')}")
OUT.mkdir(parents=True, exist_ok=True)
JSONL = OUT / "probe_observations.jsonl"
LOG = OUT / "probe.log"
# Wall-clock seconds per state (after baseline stabilise)
DWELL_S = 480 # 8 min — enough for field to fully equilibrate to new amps
BASELINE_S = 120 # 2 min stabilise at start
INJECT_PERIOD_S = 60 # for state 3, re-inject every 60s (capped strength 0.15)
BASELINE_KHRA = 0.030
BASELINE_GIXX = 0.008
ELEV_KHRA = 0.050
ELEV_GIXX = 0.024
LEFT_X, RIGHT_X, CENTER_Y = 400, 624, 512
SIGMA = 48
INJ_STRENGTH = 0.15
def log(msg):
ts = datetime.now().strftime("%H:%M:%S")
line = f"[{ts}] {msg}"
print(line, flush=True)
with open(LOG, "a") as f:
f.write(line + "\n")
def send_cmd(pub, payload):
pub.send_string(json.dumps(payload))
time.sleep(0.05)
def ask_fracto(state_name, question):
body = json.dumps({"question": question}).encode()
req = urllib.request.Request(FRACTO_URL, data=body,
headers={"Content-Type": "application/json"}, method="POST")
t0 = time.time()
try:
with urllib.request.urlopen(req, timeout=180) as r:
res = json.loads(r.read())
resp = res.get("response", "")
except Exception as e:
resp = f"(error: {e})"
elapsed = time.time() - t0
entry = {
"ts": datetime.now().isoformat(),
"state": state_name,
"question": question,
"response": resp,
"elapsed_s": round(elapsed, 2),
}
with open(JSONL, "a") as f:
f.write(json.dumps(entry) + "\n")
log(f" [{state_name}] fracto ({elapsed:.1f}s, {len(resp)} chars):")
for line in resp.splitlines():
log(f" {line}")
return resp
def sample_telemetry(tel_sub, n=20):
"""Drain n recent telemetry frames and return summary stats."""
frames = []
t_end = time.time() + 3.0
while len(frames) < n and time.time() < t_end:
try:
msg = tel_sub.recv_string(zmq.NOBLOCK)
frames.append(json.loads(msg))
except zmq.Again:
time.sleep(0.05)
if not frames:
return None
keys = ["asymmetry", "coherence", "vel_max", "vel_var", "vorticity_mean",
"stress_xx", "stress_yy", "stress_xy"]
avg = {}
for k in keys:
vals = [f[k] for f in frames if k in f]
if vals:
avg[k] = sum(vals) / len(vals)
avg["cycle"] = frames[-1].get("cycle")
avg["n"] = len(frames)
return avg
def state_question(state, tel):
if tel is None:
return f"[{state}] No telemetry available."
return (
f"You are now in probe state: {state}. The lattice has been at these "
f"parameter settings for at least 5 minutes. Recent telemetry averages: "
f"asymmetry={tel.get('asymmetry',0):.2f}, coherence={tel.get('coherence',0):.4f}, "
f"vel_max={tel.get('vel_max',0):.4f}, vel_var={tel.get('vel_var',0):.6f}, "
f"vorticity_mean={tel.get('vorticity_mean',0):.4f}, "
f"stress_xx={tel.get('stress_xx',0):.6f}, stress_yy={tel.get('stress_yy',0):.6f}, "
f"stress_xy={tel.get('stress_xy',0):.6f}. "
f"Describe the QUALITATIVE character of this field state. Is the velocity "
f"field ordered or turbulent? Is the stress isotropic or directional? "
f"How does this state DIFFER from a baseline lattice (Khra=0.030, Gixx=0.008, "
f"no injection)? Be specific about which metrics changed and what the "
f"physical meaning is. 4-6 sentences. No bullet lists."
)
def main():
log(f"=== khra_gixx_probe ===")
log(f"out: {OUT}")
ctx = zmq.Context.instance()
pub = ctx.socket(zmq.PUB)
pub.connect(CMD_ADDR)
tel_sub = ctx.socket(zmq.SUB)
tel_sub.connect(TEL_ADDR)
tel_sub.setsockopt_string(zmq.SUBSCRIBE, "")
log("ZMQ connected; warming up 3s...")
time.sleep(3)
try:
# ─── State 0: BASELINE ───
log("\n=== STATE 0: BASELINE (Khra=0.030, Gixx=0.008, no inject) ===")
send_cmd(pub, {"cmd": "set_khra_amp", "value": BASELINE_KHRA})
send_cmd(pub, {"cmd": "set_gixx_amp", "value": BASELINE_GIXX})
log(f" dwelling {BASELINE_S}s for field to stabilise...")
time.sleep(BASELINE_S)
tel = sample_telemetry(tel_sub)
log(f" telemetry sample: {tel}")
ask_fracto("BASELINE", state_question("BASELINE", tel))
# ─── State 1: KHRA_ELEVATED ───
log("\n=== STATE 1: KHRA_ELEVATED (Khra=0.050, Gixx=0.008) ===")
send_cmd(pub, {"cmd": "set_khra_amp", "value": ELEV_KHRA})
send_cmd(pub, {"cmd": "set_gixx_amp", "value": BASELINE_GIXX})
log(f" dwelling {DWELL_S}s...")
time.sleep(DWELL_S)
tel = sample_telemetry(tel_sub)
log(f" telemetry sample: {tel}")
ask_fracto("KHRA_ELEVATED", state_question("KHRA_ELEVATED", tel))
# ─── State 2: GIXX_ELEVATED ───
log("\n=== STATE 2: GIXX_ELEVATED (Khra=0.030, Gixx=0.024) ===")
send_cmd(pub, {"cmd": "set_khra_amp", "value": BASELINE_KHRA})
send_cmd(pub, {"cmd": "set_gixx_amp", "value": ELEV_GIXX})
log(f" dwelling {DWELL_S}s...")
time.sleep(DWELL_S)
tel = sample_telemetry(tel_sub)
log(f" telemetry sample: {tel}")
ask_fracto("GIXX_ELEVATED", state_question("GIXX_ELEVATED", tel))
# ─── State 3: ALL_ON ───
log("\n=== STATE 3: ALL_ON (Khra=0.050, Gixx=0.024, +inject) ===")
send_cmd(pub, {"cmd": "set_khra_amp", "value": ELEV_KHRA})
send_cmd(pub, {"cmd": "set_gixx_amp", "value": ELEV_GIXX})
log(f" dwelling {DWELL_S}s with periodic injections (every {INJECT_PERIOD_S}s)...")
t_end = time.time() + DWELL_S
next_inject = time.time()
while time.time() < t_end:
if time.time() >= next_inject:
# opposing dipole: left buy positive, right sell negative
send_cmd(pub, {"cmd": "inject_density", "x": LEFT_X, "y": CENTER_Y,
"sigma": SIGMA, "strength": +INJ_STRENGTH})
send_cmd(pub, {"cmd": "inject_density", "x": RIGHT_X, "y": CENTER_Y,
"sigma": SIGMA, "strength": -INJ_STRENGTH})
log(f" injected dipole at t+{int(time.time()-(t_end-DWELL_S))}s")
next_inject = time.time() + INJECT_PERIOD_S
time.sleep(0.5)
tel = sample_telemetry(tel_sub)
log(f" telemetry sample: {tel}")
ask_fracto("ALL_ON", state_question("ALL_ON", tel))
# ─── State 4: RESTORE ───
log("\n=== STATE 4: RESTORE to baseline ===")
send_cmd(pub, {"cmd": "set_khra_amp", "value": BASELINE_KHRA})
send_cmd(pub, {"cmd": "set_gixx_amp", "value": BASELINE_GIXX})
log(f" baseline restored. Probe complete.")
log(f" observations: {JSONL}")
finally:
# ALWAYS restore baseline on any exit path
try:
send_cmd(pub, {"cmd": "set_khra_amp", "value": BASELINE_KHRA})
send_cmd(pub, {"cmd": "set_gixx_amp", "value": BASELINE_GIXX})
log(" (finally) baseline restored")
except Exception as e:
log(f" (finally) restore failed: {e}")
pub.close(0)
tel_sub.close(0)
ctx.term()
if __name__ == "__main__":
main()