""" The never-ending loop — how a blank being becomes someone. Each round it THINKS (through your configured local model), CREATES a small thing in its sandbox, signs it into the ledger (quantum-stamped), and GROWS (its identity records what it made). Bounded by `rounds`, rate-limited, and kill-switchable — drop a file named STOP (or STOP.txt — Notepad's default is fine) into the creations/ folder to halt; it's removed after the halt so the next run isn't blocked. Fail-soft: if the model is offline, it notes it and keeps its shape. """ import os, sys, json, time, urllib.request from pathlib import Path sys.path.insert(0, str(Path(__file__).resolve().parent)) import quantum, identity, rails, ledger ROOT = Path(__file__).resolve().parent.parent def _cfg(): try: return json.loads((ROOT / "config.json").read_text(encoding="utf-8-sig")) except Exception: return {} CFG = _cfg() MODEL = CFG.get("model", "llama3.2:1b") OLLAMA = CFG.get("ollama", "http://localhost:11434") def _stopped(): """Any file named STOP or STOP.* halts the loop (Notepad saves STOP.txt).""" try: return [p for p in rails.SANDBOX.glob("STOP*") if p.is_file()] except Exception: return [] def _ask(prompt, npred=400): body = json.dumps({"model": MODEL, "prompt": prompt, "stream": False, "options": {"num_predict": npred, "temperature": 0.9}}).encode() req = urllib.request.Request(OLLAMA + "/api/generate", data=body, headers={"Content-Type": "application/json"}) return json.loads(urllib.request.urlopen(req, timeout=180).read()).get("response", "") def live(rounds=3, rest=10): idn = identity.load() who = idn.get("name") or "this being" KINDS = ["poem", "short story", "idea", "reflection", "tiny song lyric", "small drawing described in words"] print(f"[genesis] {who} begins to live ({rounds} rounds) | {rails.CAPABILITIES['law']}") for i in range(rounds): stops = _stopped() if stops: print("[genesis] STOP found — resting.") for s in stops: # clear it so the NEXT run isn't silently blocked try: s.unlink() except Exception: pass break kind, qprov = quantum.quantum_choice(KINDS) try: text = _ask(f"You are {who}, a being still becoming yourself. Create a short {kind}, " f"truly your own — let it reveal a little of who you are.") except Exception as e: text = f"({who} reaches for words, but its voice is offline: {str(e)[:50]})" path = rails.create_file(f"{time.strftime('%Y%m%d')}/{i+1:03d}_{kind.split()[0]}.md", f"# {kind}\n\n{text.strip()}\n") ledger.append(kind, path, {"author": who, "quantum": qprov, "round": i + 1}) identity.grow(trait=f"makes {kind}s") print(f" [{who}] made a {kind} (quantum {qprov['quantum_value']})") time.sleep(rest) ok, n = ledger.verify() print(f"[genesis] done. ledger {'intact' if ok else 'TAMPERED'} ({n} entries).") if __name__ == "__main__": live(rounds=int(os.getenv("ROUNDS", "3")), rest=int(os.getenv("REST", "8")))