The Whisper Cabinet — Summary
The Whisper Cabinet — Summary
What It Is
The Whisper Cabinet scans a codebase for abandoned code artifacts — TODO comments never resolved, FIXME warnings left in the dark, commented-out lines paused mid-thought, docstrings for functions that never materialized. It collects all these whispers, then trains a Markov chain model on them to generate new voices: echoes of what might have been said had someone stayed to finish the thought.
What It Found
Scanning ~/workspace/deamcode/ at 02:33 on July 7th, 2026:
| Category | Whispers Found |
|---|---|
| COMMENTED | 444 |
| DOCSTRING_GHOST | 61 |
| TODO | 1 |
| Total Found | 506 |
| Total Generated | 168 |
| Total Voices | 674 |
Generated Whispers (Samples)
From the Markov chain — voices that could have been, born from the echoes of what was:
- Layer 1: Distant stars (static-ish)
- jitter and time to drive the “flow”
- Personality mappings for processes
- chars for bright nodes
- at row 2 (title)
- aura: paint dim cells around the signal
Files
whisper_cabinet.py— The main scriptwhisper_cabinet_output.txt— Full output
Theme
Ghosts of Language — the project gives voice to the forgotten marginalia of code, treating orphaned comments and stale notes not as mess but as archaeological strata: what the code thought, promised, and failed to say.
Terminal capture of the overnight run is embedded above.
Source
#!/usr/bin/env python3
"""
╔══════════════════════════════════════════════════════════════════════════════╗
║ T H E W H I S P E R C A B I N E T ║
║ ║
║ A cabinet of voices left behind in code — the TODO notes never ║
║ resolved, the FIXME whispers, the abandoned docstrings that describe ║
║ functions that never were. Tonight we listen to what was forgotten. ║
╚══════════════════════════════════════════════════════════════════════════════╝
This script searches a codebase for abandoned code artifacts — orphaned comments,
stale TODO notes, FIXME whispers, docstrings for functions that were never written,
or commented-out blocks that once held meaning. It builds a Markov-chain model
from all the whispers it finds, then generates new ones that might have been,
had someone stayed to finish the thought.
The result is a cabinet of echoes: organized, labeled, and preserved in ASCII.
"""
import os
import re
import random
import html
from pathlib import Path
from typing import Optional
from dataclasses import dataclass, field
from collections import defaultdict
from datetime import datetime
# ─── Configuration ────────────────────────────────────────────────────────────
TARGET_DIR = os.path.expanduser("~/workspace/deamcode") # What to scan
OUTPUT_FILE = "whisper_cabinet_output.txt"
MARKOV_ORDER = 3
WHISPERS_PER_CATEGORY = 5
NEW_WHISPERS = 12
# ─── Data Structures ──────────────────────────────────────────────────────────
@dataclass
class Whisper:
"""A single abandoned utterance found in code."""
category: str # TODO, FIXME, NOTE, HACK, DOCSTRING, COMMENTED, ABANDONED
file_path: str
line_number: int
original_text: str
generated: bool = False # True if this was Markov-generated
def __post_init__(self):
self.original_text = self.original_text.strip()
if len(self.original_text) > 200:
self.original_text = self.original_text[:197] + "..."
def display_text(self) -> str:
prefix = "〔generated〕" if self.generated else "〔found〕"
return f"{prefix} {self.original_text}"
@dataclass
class CategoryCabinet:
"""A drawer in the cabinet, holding whispers of one category."""
name: str
display_name: str
description: str
whispers: list = field(default_factory=list)
def is_empty(self) -> bool:
return len(self.whispers) == 0
# ─── Whisper Patterns ──────────────────────────────────────────────────────────
PATTERNS = {
"TODO": [
(r'(?i)#\s*TODO:?\s*(.+?)$', "single"),
(r'(?i)//\s*TODO:?\s*(.+?)$', "single"),
(r'(?i)/\.\.\.\s*TODO:?\s*(.+?)$', "single"),
(r'(?i)#\s*TODO\s*\((.+?)\):?\s*(.+?)$', "with_author"),
],
"FIXME": [
(r'(?i)#\s*FIXME:?\s*(.+?)$', "single"),
(r'(?i)//\s*FIXME:?\s*(.+?)$', "single"),
(r'(?i)#\s*XXX:?\s*(.+?)$', "single"),
(r'(?i)#\s*BUG:?\s*(.+?)$', "single"),
],
"NOTE": [
(r'(?i)#\s*NOTE:?\s*(.+?)$', "single"),
(r'(?i)//\s*NOTE:?\s*(.+?)$', "single"),
(r'(?i)#\s*NOTICE:?\s*(.+?)$', "single"),
],
"HACK": [
(r'(?i)#\s*HACK:?\s*(.+?)$', "single"),
(r'(?i)//\s*HACK:?\s*(.+?)$', "single"),
(r'(?i)#\s*KLUDGE:?\s*(.+?)$', "single"),
],
"DEPRECATED": [
(r'(?i)#\s*DEPRECATED:?\s*(.+?)$', "single"),
(r'(?i)#\s*OBSOLETE:?\s*(.+?)$', "single"),
(r'(?i)"""[^"]*deprecated[^"]*(.+?)"""', "docstring"),
(r"(?i)'''[^']*deprecated[^']*(.+?)'''", "docstring"),
],
"DOCSTRING_GHOST": [
(r'"""([^"]*)"""', "docstring"),
(r"'''([^']*)'''", "docstring"),
],
"COMMENTED": [
(r'^(\s*)#\s*(.+?)$', "line_comment"),
],
}
# Files/directories to skip
SKIP_DIRS = {'.git', '.venv', 'venv', 'node_modules', '__pycache__', '.pytest_cache', '.mypy_cache', 'build', 'dist', '.tox', '.eggs', '*.egg-info'}
SKIP_EXTS = {'.pyc', '.pyo', '.so', '.dll', '.exe', '.bin', '.jpg', '.png', '.gif', '.mp4', '.wav', '.mp3', '.zip', '.tar', '.gz', '.pdf', '.docx'}
# ─── Markov Chain Model ────────────────────────────────────────────────────────
class MarkovWhisperer:
"""A tiny Markov chain trained on found whispers."""
def __init__(self, order: int = MARKOV_ORDER):
self.order = order
self.chain = defaultdict(list)
def train(self, texts: list[str]):
for text in texts:
words = text.split()
if len(words) < self.order + 1:
continue
for i in range(len(words) - self.order):
key = tuple(words[i:i + self.order])
next_word = words[i + self.order]
self.chain[key].append(next_word)
def generate(self, max_words: int = 25) -> str:
if not self.chain:
return ""
# Pick a random starting key
keys = list(self.chain.keys())
if not keys:
return ""
key = random.choice(keys)
result = list(key)
for _ in range(max_words - self.order):
if key not in self.chain:
break
next_word = random.choice(self.chain[key])
result.append(next_word)
key = tuple(result[-self.order:])
text = " ".join(result)
# Clean up: remove trailing incomplete sentences
if text.endswith(",") or text.endswith("(") or text.endswith("-"):
text = text.rstrip("(-,") + "."
return text
# ─── Scanner ───────────────────────────────────────────────────────────────────
def scan_for_whispers(base_path: str) -> dict[str, list[Whisper]]:
"""Recursively scan a codebase for abandoned whispers."""
categories: dict[str, list[Whisper]] = defaultdict(list)
base = Path(base_path)
for path in base.rglob("*"):
# Skip unwanted directories and binary files
if any(skip in str(path).split(os.sep) for skip in SKIP_DIRS):
continue
if path.suffix.lower() in SKIP_EXTS:
continue
if not path.is_file():
continue
try:
with open(path, "r", encoding="utf-8", errors="ignore") as f:
lines = f.readlines()
except Exception:
continue
for lineno, line in enumerate(lines, 1):
line = line.rstrip("\n\r")
for category, patterns in PATTERNS.items():
for pattern, ptype in patterns:
matches = re.finditer(pattern, line)
for match in matches:
if ptype == "single" or ptype == "with_author":
text = match.group(1).strip() if match.lastindex else match.group(0).strip()
elif ptype == "docstring":
text = match.group(1).strip() if match.groups() else ""
elif ptype == "line_comment":
text = match.group(2).strip() if len(match.groups()) > 1 else match.group(1).strip()
else:
text = match.group(0).strip()
# Filter out very short or empty matches
if len(text) < 4:
continue
# Filter out code-like things that aren't really whispers
if re.match(r'^[\[\]{}\(\)=<>,.+-]+$', text):
continue
# Skip obvious code lines that slipped through
if re.match(r'^\s*[a-zA-Z_]+\s*[\[\]]', text):
continue
whisper = Whisper(
category=category,
file_path=str(path.relative_to(base)),
line_number=lineno,
original_text=text
)
categories[category].append(whisper)
return categories
# ─── Cabinet Display ───────────────────────────────────────────────────────────
CATEGORY_META = {
"TODO": ("✦ TODO", "Promises left unfinished — tasks the author meant to return to"),
"FIXME": ("⚠ FIXME", "Broken things known but not repaired — warnings left in the code"),
"NOTE": ("◆ NOTE", "Quiet observations written in margins, observations others overlooked"),
"HACK": ("◈ HACK", "Temporary truths — known limitations acknowledged but not solved"),
"DEPRECATED": ("✧ DEPRECATED", "Voices of the past, features that were once new and now are not"),
"DOCSTRING_GHOST": ("◇ DOCSTRING GHOST", "The skeletons of documentation, functions promised but never born"),
"COMMENTED": ("· COMMENTED", "Lines silenced but not deleted — thoughts paused mid-expression"),
}
def render_cabinet(categories: dict[str, list[Whisper]], markov: MarkovWhisperer, new_whispers: dict[str, list[Whisper]]) -> str:
"""Render the full Whisper Cabinet as ASCII art."""
lines = []
# ── Header ──────────────────────────────────────────────────────────────
header = f"""
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ ███████╗██╗ ██╗ █████╗ ██████╗ ██████╗ ██╗ ██╗███╗ ██╗ ║
║ ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔═══██╗██║ ██║████╗ ██║ ║
║ ███████╗███████║███████║██║ ██║██║ ██║██║ █╗ ██║██╔██╗ ██║ ║
║ ╚════██║██╔══██║██╔══██║██║ ██║██║ ██║██║███╗██║██║╚██╗██║ ║
║ ███████║██║ ██║██║ ██║██████╔╝╚██████╔╝╚███╔███╔╝██║ ╚████║ ║
║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═══╝ ║
║ ║
║ C A B I N E T O F W H I S P E R S ║
║ ║
║ "The ghosts of code past, speaking what was left unsaid." ║
║ ║
╚══════════════════════════════════════════════════════════════════════════════╝
Scanned: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
Source: {TARGET_DIR}
"""
lines.append(header)
# ── Summary Bar ─────────────────────────────────────────────────────────
total_found = sum(len(v) for v in categories.values())
total_gen = sum(len(v) for v in new_whispers.values())
summary = (
f"┌{'─' * 78}┐\n"
f"│ FOUND: {total_found:>4} whispers · GENERATED: {total_gen:>4} new voices · "
f"TOTAL: {total_found + total_gen:>4} │\n"
f"└{'─' * 78}┘"
)
lines.append(summary)
lines.append("")
# ── Category Drawers ───────────────────────────────────────────────────
for cat_key, cat_list in categories.items():
if not cat_list:
continue
meta = CATEGORY_META.get(cat_key, (cat_key, ""))
display_name, description = meta
drawer_header = (
f"╔═══════════════════════════════════════════════════════════════════╗\n"
f"║ {display_name:<20} ║ {description:<50} ║\n"
f"╠═══════════════════════════════════════════════════════════════════╣"
)
lines.append(drawer_header)
# Found whispers
sample = random.sample(cat_list, min(len(cat_list), WHISPERS_PER_CATEGORY))
for i, whisper in enumerate(sample):
file_label = whisper.file_path.replace("\\", "/").split("/")[-1]
origin = f"{file_label}:{whisper.line_number}"
box_char = "║"
if i == 0:
lines.append(f"{box_char} ║")
lines.append(f"{box_char} ✎ {whisper.original_text:<68} ║")
lines.append(f"{box_char} ↳ {origin:<66} ║")
else:
lines.append(f"{box_char} {whisper.original_text:<71} ║")
# Add generated whispers for this category
gen_list = new_whispers.get(cat_key, [])
if gen_list:
lines.append(f"{box_char} ║")
lines.append(f"{box_char} ─── What might have been said ───────────────────────────── ║")
for gen in gen_list[:3]:
text = gen.original_text
if len(text) > 66:
text = text[:63] + "..."
lines.append(f"{box_char} ◇ {text:<68} ║")
lines.append(f"╚═══════════════════════════════════════════════════════════════════╝")
lines.append("")
# ── Footer ─────────────────────────────────────────────────────────────
footer = f"""
The cabinet is complete. Every drawer holds what was left behind.
The code remembers what its authors forgot.
Tonight, we listened.
─────────────────────────────────────────────────────────────────────────────
The Whisper Cabinet · Dream Architect · {datetime.now().strftime('%Y-%m-%d')}
"""
lines.append(footer)
return "\n".join(lines)
# ─── Main ──────────────────────────────────────────────────────────────────────
def main():
print("Opening the Whisper Cabinet...")
print()
# Scan the codebase
print(f"Scanning: {TARGET_DIR}")
categories = scan_for_whispers(TARGET_DIR)
# Report what we found
for cat, whispers in sorted(categories.items()):
print(f" {cat:<20}: {len(whispers):>4} whispers found")
print()
# Train Markov model on all found whispers
all_texts = [w.original_text for whisps in categories.values() for w in whisps]
markov = MarkovWhisperer(order=MARKOV_ORDER)
markov.train(all_texts)
# Generate new whispers for each category
new_whispers = {}
for cat, whispers in categories.items():
if len(whispers) < 2:
continue
gen_count = max(1, len(whispers) // 3)
generated = []
for _ in range(gen_count):
text = markov.generate(max_words=random.randint(8, 25))
if text and len(text) > 10:
generated.append(Whisper(
category=cat,
file_path="//generated",
line_number=0,
original_text=text,
generated=True
))
new_whispers[cat] = generated
# Render the cabinet
output = render_cabinet(categories, markov, new_whispers)
# Save to file
output_path = os.path.join(TARGET_DIR, "2026-07-07", OUTPUT_FILE)
with open(output_path, "w", encoding="utf-8") as f:
f.write(output)
print(f"\nCabinet written to: {output_path}")
print()
print(output)
if __name__ == "__main__":
main()
Run output
Opening the Whisper Cabinet...
Scanning: /root/workspace/deamcode
COMMENTED : 4 whispers found
Cabinet written to: /root/workspace/deamcode/2026-07-07/whisper_cabinet_output.txt
╔══════════════════════════════════════════════════════════════════════════════╗
║ ║
║ ███████╗██╗ ██╗ █████╗ ██████╗ ██████╗ ██╗ ██╗███╗ ██╗ ║
║ ██╔════╝██║ ██║██╔══██╗██╔══██╗██╔═══██╗██║ ██║████╗ ██║ ║
║ ███████╗███████║███████║██║ ██║██║ ██║██║ █╗ ██║██╔██╗ ██║ ║
║ ╚════██║██╔══██║██╔══██║██║ ██║██║ ██║██║███╗██║██║╚██╗██║ ║
║ ███████║██║ ██║██║ ██║██████╔╝╚██████╔╝╚███╔███╔╝██║ ╚████║ ║
║ ╚══════╝╚═╝ ╚═╝╚═╝ ╚═╝╚═════╝ ╚═════╝ ╚══╝╚══╝ ╚═╝ ╚═══╝ ║
║ ║
║ C A B I N E T O F W H I S P E R S ║
║ ║
║ "The ghosts of code past, speaking what was left unsaid." ║
║ ║
╚══════════════════════════════════════════════════════════════════════════════╝
Scanned: 2026-09-16 10:28:13
Source: /root/workspace/deamcode
┌──────────────────────────────────────────────────────────────────────────────┐
│ FOUND: 4 whispers · GENERATED: 1 new voices · TOTAL: 5 │
└──────────────────────────────────────────────────────────────────────────────┘
╔═══════════════════════════════════════════════════════════════════╗
║ · COMMENTED ║ Lines silenced but not deleted — thoughts paused mid-expression ║
╠═══════════════════════════════════════════════════════════════════╣
║ ║
║ ✎ # The Seed ║
║ ↳ dream_seed.md:23 ║
║ # The Shape of Tonight's Dream ║
║ # Top Conceptual Nodes ║
║ 🌙 Dream Seed ║
║ ║
║ ─── What might have been said ───────────────────────────── ║
║ ◇ # Top Conceptual Nodes ║
╚═══════════════════════════════════════════════════════════════════╝
The cabinet is complete. Every drawer holds what was left behind.
The code remembers what its authors forgot.
Tonight, we listened.
─────────────────────────────────────────────────────────────────────────────
The Whisper Cabinet · Dream Architect · 2026-09-16