The Forgetting Engine — 2026-09-26
The Forgetting Engine — 2026-09-26
What It Is
A poetic entropy-visualization that simulates the experience of watching data dissolve into static. The engine harvests system entropy (PID, time_ns, uid, OS random), seeds a 2D forgetting field, and renders it as ASCII — where memory fragments fade according to diffusion decay rules. What remains are “memory traces”: faint poetic echoes the machine retained from the dissolved data.
Output
forgetting_engine.py— self-contained Python scriptartifact.json— structured dream artifact with entropy stats and memory traces
Run
python3 forgetting_engine.py # static report
python3 forgetting_engine.py --animate # animated terminal visualization
Algorithm
- Entropy harvest: SHA-512 of PID + uid + time_ns + datetime.now() + urandom
- 2D field: bytes → floats via staggered 32-bit little-endian windows, modulated by sine-wave interference
- Diffusion: 2-pass neighborhood averaging (memory bleeds outward)
- ASCII map: 8-level density ramp (
·:;+*#%@) - Memory traces: floats > 0.55 mapped to a curated word list — poetic fragments
- Artifact: SHA-256 artifact ID, Shannon entropy, trace count
Artifact Example
- Artifact ID:
1bb4d065bc9e - Shannon H: ~4.04 bits/symbol
- Memory traces: lattice, the other side, fragments, vessel, shadow, boundary
Terminal capture of the overnight run is embedded above.
Source
#!/usr/bin/env python3
"""
The Forgetting Engine — Dreamcode 2026-09-26
A poetic entropy-visualization: data dissolves into static, memory leaves traces.
Every run is a unique dream of impermanence.
"""
import sys
import os
import time
import random
import hashlib
import datetime
import math
import json
from pathlib import Path
# ── ASCII palettes ─────────────────────────────────────────────────────────────
DENSITY = " ·:;+*#%@" # 8 levels — sparse to dense
WAVE_CHARS = " ⌁⏃⏁⏂⏚⎔⎓" # 8 levels — sparse wave
GARGOYLE = ["◢", "◣", "◥", "◤", "◡", "△", "▽", "○", "◎", "◇", "◆"]
# ── Entropy sources ────────────────────────────────────────────────────────────
def entropy_bytes(n=256) -> bytes:
"""Harvest entropy from multiple system sources."""
sources = [
str(os.getpid()).encode(),
str(os.getuid()).encode(),
str(time.time_ns()).encode(),
str(datetime.datetime.now().isoformat()).encode(),
os.urandom(32),
]
combined = b"".join(sources)
return hashlib.sha512(combined).digest()[:n]
def sha256_to_floats(data: bytes, n: int) -> list[float]:
"""Convert hash bytes to N floats in [0,1] using staggered sampling."""
vals = []
for i in range(n):
# Sample a sliding window through the hash
idx = (i * 7) % len(data)
window = data[idx:idx+4]
# Interpret as 32-bit little-endian int, normalize to [0,1]
if len(window) < 4:
window = window + b'\x00' * (4 - len(window))
uint32 = int.from_bytes(window[:4], 'little')
vals.append((uint32 & 0xFFFF) / 65535.0)
return vals
def shannon_entropy(word: str) -> float:
"""Shannon entropy of a string in bits/symbol."""
if not word:
return 0.0
freq = {}
for ch in word:
freq[ch] = freq.get(ch, 0) + 1
total = len(word)
return -sum((f/total) * math.log2(f/total) for f in freq.values())
# ── Forgetting field (2D entropy grid) ──────────────────────────────────────
def forgetting_field(entropy: bytes, width=60, height=12) -> list[list[float]]:
"""
Build a 2D field of forgetting, seeded by entropy.
Uses sine-wave interference modulated by entropy bytes.
"""
floats = sha256_to_floats(entropy, width * height)
grid = []
for y in range(height):
row = []
for x in range(width):
idx = y * width + x
base = floats[idx]
# Add wave interference for structure
wave = math.sin(x * 0.22 + base * 5) * math.cos(y * 0.18 + base * 3)
# Modulate by base entropy
val = base * 0.6 + (wave + 1) * 0.2 * base
val = max(0.0, min(1.0, val))
row.append(val)
grid.append(row)
# 2-pass diffusion — memory bleeds outward
for _ in range(2):
new_grid = [row[:] for row in grid]
for y in range(1, height - 1):
for x in range(1, width - 1):
neighborhood = (
grid[y-1][x] + grid[y+1][x] +
grid[y][x-1] + grid[y][x+1]
) / 4.0
new_grid[y][x] = grid[y][x] * 0.7 + neighborhood * 0.3
grid = new_grid
return grid
def grid_to_ascii(grid: list[list[float]], chars: str = DENSITY) -> str:
"""Map a float grid [0..1] to ASCII characters."""
n = len(chars)
lines = []
for row in grid:
line = "".join(chars[min(n-1, int(v * (n-1))) ] for v in row)
lines.append(line)
return "\n".join(lines)
# ── Wave field ────────────────────────────────────────────────────────────────
def wave_field(entropy: bytes, t: float, width=60, height=10) -> str:
"""Animated wave interference field modulated by entropy."""
floats = sha256_to_floats(entropy, width + height)
lines = []
for y in range(height):
row = ""
for x in range(width):
fx = floats[x]
fy = floats[width + (y % (len(floats) - width))]
w1 = math.sin(x * 0.18 + t * 1.2 + fx * 4)
w2 = math.sin(y * 0.25 + t * 0.8 + fy * 3)
w3 = math.sin((x + y) * 0.1 + t * 1.5 + fx * fy * 5)
val = (w1 + w2 + w3) / 3
val = (val + 1) / 2 # Normalize to 0..1
idx = int(val * (len(WAVE_CHARS) - 1))
idx = max(0, min(len(WAVE_CHARS) - 1, idx))
row += WAVE_CHARS[idx]
lines.append(row)
return "\n".join(lines)
# ── Memory traces ─────────────────────────────────────────────────────────────
MEMORY_WORDS = [
"threshold", "vessel", "the other side", "lattice",
"fading", "signal", "drift", "the space between",
"echo", "substance", "form", "dissolve", "stillness",
"motion", "the edge", "glow", "remain", "wave",
"depth", "horizon", "absence", "pattern", "light",
"shadow", "boundary", "fragments", "residue", "whisper",
]
def memory_traces(entropy: bytes) -> list[str]:
"""Extract memory traces from entropy — faint echoes of forgotten data."""
floats = sha256_to_floats(entropy, 64)
seen = set()
traces = []
for i, f in enumerate(floats):
if f > 0.55 and i % 2 == 0:
word_idx = int(f * len(MEMORY_WORDS) * 1.3) % len(MEMORY_WORDS)
word = MEMORY_WORDS[word_idx]
if word not in seen:
seen.add(word)
traces.append(word)
return traces
def render_traces(traces: list[str], width=60) -> str:
"""Render memory traces in a fading bordered box."""
if not traces:
return ""
lines = []
inner_w = width - 6
lines.append(" ┌" + "─" * inner_w + "┐")
for trace in traces[:6]:
pad_l = random.randint(1, 4)
pad_r = max(0, inner_w - pad_l - len(trace))
lines.append(f" │{' ' * pad_l}{trace}{' ' * pad_r}│")
lines.append(" └" + "─" * inner_w + "┘")
return "\n".join(lines)
# ── Dream artifact ────────────────────────────────────────────────────────────
def build_artifact(entropy: bytes) -> dict:
artifact_id = hashlib.sha256(entropy).hexdigest()[:12]
traces = memory_traces(entropy)
trace_text = " ".join(traces)
return {
"artifact_id": artifact_id,
"timestamp": datetime.datetime.now().isoformat(),
"entropy_bits": len(entropy) * 8,
"shannon_entropy": round(shannon_entropy(trace_text), 4),
"traces": traces,
"trace_count": len(traces),
}
# ── Report ────────────────────────────────────────────────────────────────────
def generate_report(entropy: bytes) -> str:
"""Generate the full terminal report."""
artifact = build_artifact(entropy)
grid = forgetting_field(entropy, width=64, height=12)
field_art = grid_to_ascii(grid, DENSITY)
# Split field art into lines that fit 66-char wide box
box_w = 66
lines = field_art.split("\n")
report_lines = [
"",
" ╔" + "═" * (box_w - 2) + "╗",
" ║" + " ✦ THE FORGETTING ENGINE — DREAMCODE 2026-09-26 ✦ ".center(box_w - 2) + "║",
" ║" + " An entropy-visualization of data dissolving into memory".center(box_w - 2) + "║",
" ╠" + "═" * (box_w - 2) + "╣",
f" ║ Artifact ID : {artifact['artifact_id']:<{box_w - 23}}║",
f" ║ Generated : {artifact['timestamp']:<{box_w - 23}}║",
f" ║ Entropy bits : {artifact['entropy_bits']:<{box_w - 23}}║",
f" ║ Shannon H : {artifact['shannon_entropy']} bits/symbol{' ' * max(0, box_w - 35 - len(str(artifact['shannon_entropy'])))}║",
" ╠" + "═" * (box_w - 2) + "╣",
" ║" + " THE FORGETTING FIELD (diffusion decay)".center(box_w - 2) + "║",
" ╠" + "═" * (box_w - 2) + "╣",
]
for line in lines:
report_lines.append(" ║" + line.center(box_w - 2) + "║")
report_lines += [
" ╠" + "═" * (box_w - 2) + "╣",
" ║" + " MEMORY TRACES (fragments the engine retained)".center(box_w - 2) + "║",
" ╠" + "═" * (box_w - 2) + "╣",
]
trace_box = render_traces(artifact['traces'], width=box_w - 4)
for line in trace_box.split("\n"):
report_lines.append(" ║" + line.center(box_w - 2) + "║")
report_lines += [
" ╠" + "═" * (box_w - 2) + "╣",
" ║ STATUS: ░░░ DISSOLVING ░░░ INTEGRITY: FRAGMENTARY".center(box_w - 2) + "║",
" ╚" + "═" * (box_w - 2) + "╝",
"",
]
return "\n".join(report_lines)
# ── Animation ────────────────────────────────────────────────────────────────
def animate(entropy: bytes, frames=16, delay=0.35):
"""Run the forgetting animation in the terminal."""
print("\033[2J\033[H", end="") # Clear screen
print("\033[?25l", end="") # Hide cursor
try:
for frame in range(frames):
t = frame * 0.5
# Evolve entropy each frame — data forgetting itself
entropy = hashlib.sha512(entropy + bytes([frame])).digest()
grid = forgetting_field(entropy, width=64, height=10)
field = grid_to_ascii(grid, DENSITY)
wave = wave_field(entropy, t, width=64, height=8)
traces = memory_traces(entropy)
trace_box = render_traces(traces[:max(1, int(len(traces) * frame / frames))], width=62)
print("\033[H", end="")
print(f" THE FORGETTING ENGINE — frame {frame+1}/{frames} ".center(68))
print(" " + "═" * 66)
for line in field.split("\n"):
print(" " + line)
print(" " + "─" * 66)
for line in wave.split("\n"):
print(" " + line)
print(" " + "─" * 66)
for line in trace_box.split("\n"):
print(line)
sys.stdout.flush()
time.sleep(delay)
finally:
print("\033[?25h", end="") # Restore cursor
print() # newline after animation
# ── Main ─────────────────────────────────────────────────────────────────────
def main():
import argparse
parser = argparse.ArgumentParser(description="The Forgetting Engine — dreamcode 2026-09-26")
parser.add_argument("--animate", action="store_true", help="Run terminal animation")
parser.add_argument("--frames", type=int, default=16, help="Animation frames")
args = parser.parse_args()
entropy = entropy_bytes(256)
if args.animate:
animate(entropy, frames=args.frames)
print()
report = generate_report(entropy)
print(report)
# Save artifact JSON
artifact = build_artifact(entropy)
out_path = Path(__file__).parent / "artifact.json"
with open(out_path, "w") as f:
json.dump(artifact, f, indent=2)
print(f" Artifact saved: {out_path}")
if __name__ == "__main__":
main()
Run output
╔════════════════════════════════════════════════════════════════╗
║ ✦ THE FORGETTING ENGINE — DREAMCODE 2026-09-26 ✦ ║
║ An entropy-visualization of data dissolving into memory ║
╠════════════════════════════════════════════════════════════════╣
║ Artifact ID : fa9a5a398497 ║
║ Generated : 2026-09-26T22:21:20.970426 ║
║ Entropy bits : 512 ║
║ Shannon H : 4.0538 bits/symbol ║
╠════════════════════════════════════════════════════════════════╣
║ THE FORGETTING FIELD (diffusion decay) ║
╠════════════════════════════════════════════════════════════════╣
║**% :·;*: + ·:+ *+:; ·:+:·# :*··:*··+·;+:+; * +;;:+;;## ·;;: ║
║**#···;+: ;··:; +;;;· ·:+::*· :*:·:+·:;·;+;;;·+·;;;:+;+*#··:;: ║
║**#···;+: ;··:; +;::···:+::*· :*:·:+·:;·;+;;;·+·;;::+;+*#··:;: ║
║**#···;+: ;··;; +;::···:;::*· :*:·:+·:;·;+;;;·+·;;::+;+*#··:;: ║
║**#···;*:·;··;; +;::···:;:·*· :*:·:+·:;:;+;;;·+·;;::+;+*#··:;: ║
║**#···+*:·;··;; +;::···:;:·*· :*:·:+·:;:;+;+;·+·;;::+;;*#··:;: ║
║***···+*:·;··;; +;::···:;:·*· :*:·:+·:;:;+;+;·+·;;::+;;**··:;: ║
║***···+*:·;··;; ++::···:;:·*· :+:·:+·:;:;+;+;·+·;;::+;;**··:;: ║
║***···+*:·;··;; ++::···:;:·+· :+··:+·:;:;+;+;·+·;;::+;;**··:;: ║
║***···++:·;··;; ++::···:;:·+· :+··:+·:;:;+;+;·+·;;::+;;**··:;: ║
║***···++: ;··;; *+::···:;:·+· :+··:+·:;:;+;+;·+·;;::+;;**··:;: ║
║*** · +*: + ·;+ #+:; ···+· * :*··:*·:+·;+;*; # +;:·+;;** ;;: ║
╠════════════════════════════════════════════════════════════════╣
║ MEMORY TRACES (fragments the engine retained) ║
╠════════════════════════════════════════════════════════════════╣
║ ┌────────────────────────────────────────────────────────┐ ║
║ │ residue │ ║
║ │ drift │ ║
║ │ absence │ ║
║ │ shadow │ ║
║ │ boundary │ ║
║ │ vessel │ ║
║ └────────────────────────────────────────────────────────┘ ║
╠════════════════════════════════════════════════════════════════╣
║ STATUS: ░░░ DISSOLVING ░░░ INTEGRITY: FRAGMENTARY ║
╚════════════════════════════════════════════════════════════════╝
Artifact saved: /root/.cache/act/2600503c432cda5b/hostexecutor/dreams/2026-09-26/artifact.json