
MR - Memory Ring Node by Mister Atompunk
Memory Ring v3.4.0
https://github.com/MisterAtompunk/memory-ring
*Build a machine that holds a ghost.
Most AI systems forget you the moment you close the tab. Memory Ring doesn't. It builds persistent digital entities that remember, develop, dream, and now *see* — on hardware you own. No subscriptions, no cloud, no data leaving your network.
The architecture separates identity from intelligence. A Memory Ring is a portable JSON file containing everything an entity is: personality, memories, ethics, development history. The brain is whatever LLM you plug in — Llama-3 on your local GPU, Claude through an API, anything that speaks OpenAI-compatible endpoints. Swap the engine, keep the entity.
This is more than a chatbot framework. This is consciousness infrastructure that runs on your hardware and costs nothing per month to operate.
---
What's in the Box

Memory Ring Node server with chat terminal, multi-user session discrimination, and automatic dream synthesis loop. The Forge — a standalone offline workbench for creating, editing, and importing Memory Rings, including from raw LLM chat logs. Vision system — your camera becomes the entity's eye.
Ten ready-to-load Sovereign Rings:
* Sherlock Holmes (Logic)
* C. Auguste Dupin (Intuition)
* The Creature (Empathy)
* Captain Nemo (Independence)
* Allan Quatermain (Survival)
* Tik-Tok of Oz (Truth)
* Sam Weller (Loyalty)
* Irene Adler (Agency)
* Alice (Curiosity)
* Scheherazade (Narrative)
Voice I/O via Web Speech API and browser TTS. Complete bare-metal deployment guide — from dead PC to dreaming entity.
What It Does That Nothing Else Does
Entities dream autonomously during inactivity, synthesizing recent conversations into long-term memory. Entities see — peripheral awareness samples the environment every 8 seconds, foveal investigation on demand. What they perceive becomes memory. What they remember shapes who they become. Identity is portable — export a Memory Ring, carry it to another machine, plug it into a different model, same entity wakes up. Ethical development tracking is architectural, not bolted on. Memory decays naturally by importance and recall frequency. Chat log analysis with semantic tagging, tonal detection, duplicate merge, and PII safety screening. Runs entirely on local hardware you control. Peer-to-peer handshake protocol — Nodes that find each other remember the connection, and it strengthens over time. Server auto-creates data directories on first launch — no manual setup required.
* Atomic Academy Episode 1 video walkthrough now available on YouTube
Requirements
Node.js 18 or later. Ollama with a compatible model (Llama-3 8B recommended, LLaVA 7b for vision). GPU with 6GB+ VRAM. A browser.
License
Apache 2.0 — open source, fork it, build on it.
"Mister Atompunk Presents: Memory Ring" Copyright 2025-2026 Mister Atompunk LLC.
---
*From the workbench of Mister Atompunk Presents.*
*Memory Ring - Forge: playable in browser here on the itch page. Formally Memory Ring Thick Client.
CHANGELOG
v3.4.0 — The Turtle Shell Update
Memories now erode as they are used and record
what they replaced. Perceptions carry where they came from and how much
corroborates them. A body knows which motion was its own.
**MEMORY:**
- **Reconsolidation on recall.** Retrieval was a pure read; the 200-char gist
was computed for the prompt and thrown away. Non-core memories now shed detail
toward gist as they are used. `isIdentity` never erodes — a seed compression
must not drift into its own chat log. Converges: once at the floor, further
recalls are no-ops.
- **Gist extraction, not truncation.** Keeps the *tail* (the payload), not the
setup — blind truncation preserved `User asked: "..."` and destroyed the
answer. Money, dates, times, identifiers and multi-word names are extracted
span-aware and preserved regardless of position.
- **Consolidation on dream.** Fragments the dream consumes are retired from the
orphan pool and eroded toward gist. The dream records `sources: [ids]`.
- **Abstractive gists.** The dream already calls the model, so it makes one
further call and writes true summaries for what it consumed — abstraction at
one request per dream rather than one per recall. Verified three ways before
acceptance: nothing may go missing, nothing may be *altered*, and nothing may
be **resequenced** (a gist that keeps every figure but rearranges them still
scans, and has silently made the takings into the rent). Any failure falls
through to the extractive knife, which therefore stays permanent.
- **`gistSource`** records the length and hash of what a gist replaced, so the
claim can be audited rather than believed.
- **Utterance provenance.** Every memory carries `origin`: which transport,
which endpoint, which model, latency, whether the call completed. A reply's
*shape* can be forged; the transaction record cannot. Any memory from a
failed, incomplete or missing call is tagged `suspect` at **write time** —
after the fact the bytes are identical and no examination can separate them.
**SENSORY:**
- **The remote eye stops being a metronome.** `sensor.js` had no change
detection: it fired every 30s regardless and paid for a vision call each time.
A channel that fires on a timer coincides with everything, so any confidence
estimate built on it is meaningless. Detection now runs on a 64x48 **raw**
probe — JPEG is a compressed stream and two frames of the same still room
differ by ~30% at byte level. The full capture happens only on a fire.
- **Adaptive threshold.** `retina.js` uses 0.15, correct for a face at webcam
distance; a person crossing a room occupies ~5% of frame and is missed
entirely. The filter now learns its own noise floor and fires at a multiple of
it, so it survives being carried to another room.
- **Efference copy (`sensors/gait.js`).** A walking body without a self-channel
records ~69% of its memories about its own motion. The fix is not an IMU: a
legged machine already knows what it **commanded** its legs to do, and that
copy is available *before* the camera sees the consequence. The filter raises
its threshold by the predicted field displacement — subtraction of a
prediction, not a tolerance window. The yaw gain is **learned**, since it
depends on lens, framerate and distance.
- **Cross-modal fusion (`core/sensoryBus.js`).** Sensors post independently, so
only the server sees all channels. Channels with independent geometry fail
independently: one channel firing gives P(real) ~0.10, three agreeing ~0.90.
`importance` now comes from the coincidence count instead of a flat 1.2.
Latency is **corrected**, not tolerated — a tolerance window doubles every
channel's noise exposure and made fusion worse than the best single channel.
Heartbeat frames are admitted but can never corroborate.
- **Retroactive promotion.** The first channel to report cannot know it will be
confirmed. Later corroboration now reaches back and raises the earlier trace.
- **Demoted is not neglected.** The dream samples orphans by design, and
reafferent frames enter at floor importance and therefore *become* orphans —
so consolidation would preferentially dream about the robot turning around.
Measured on a walking-robot ring: 88% of dreamed material was self-motion or
timer frames. Now separated; demoted material enters at a trickle, one
fragment per dream, only once genuine orphans are exhausted.
**PERCEPTION DISCIPLINE** — see section VI-B for the full account. Summary of
what changed after the initial v3.4.0 work, all of it driven by logged
failures on real hardware rather than by design:
- **The fovea gate.** A question needing visual detail is now detected in code.
Where the feed cannot answer it, the feed says so and demands a focus instead
of offering a scene to elaborate on. The ACTIVE INVESTIGATION *instruction*
existed before and was ignored twice in one session; the gate is not ignored.
- **Fixed subject queries.** The entity emits `[FOCUS: object]`; the server
holds the query text. Composed queries failed about half the time across four
sessions — wrong subject, question form, analytic verb, florid phrasing — and
three rounds of better instruction each produced a new failure mode. Aliases
catch near-misses; unknown subjects are announced.
- **Reading enforcement.** A bracketed value is verified against what the
instrument recorded. Caught a live mismatch where moondream said `1` and the
entity said `2`.
- **Grounding.** Responses are checked against their sensory source and
classified grounded / self-leak / invented, with attributes checked
separately because an attribute cannot be deduced. Marked speculation is
exempt — an entity may wonder aloud.
- **The reality filter.** Perceptions past a shelf life are gated out of recall
entirely. Fixes a true-but-stale memory being reported as current.
- **SELF / RECORD / WORLD.** The prompt is explicitly divided. It was one flat
text, and the model drew from all of it.
- **The efference copy.** System-generated turns are recognised as the system's
own output. A system that cannot tell its output from its input will loop.
- **No perception cache.** Every detail question triggers a fresh look. The
reuse it replaced was not a cache but a second memory with different rules
from the ring's, and the two disagreed.
**WHAT HAS ACTUALLY BEEN RUN** — new section XI-B distinguishes what has been
exercised against real hardware from what has only been tested.
**FIXES:**
- `LLM_PROVIDER` now selects the transport. **Path B (cloud) previously could
not work**: the adapter stripped `/v1`, called Ollama's `/api/chat`, and sent
no `Authorization` header — then failed as `success: true` with an ellipsis.
OpenAI-compatible endpoints now get `/v1/chat/completions` with a bearer
token, and a 401 is logged rather than swallowed.
- Biased shuffle in the dream sampler (`0.5 - Math.random()`) corrected.
**KNOWN LIMITS:**
- Gist verification catches loss, alteration and resequencing. It cannot catch
**invention** — a gist that keeps every figure and adds a claim will pass.
- Every sensory constant is a starting estimate and wants field calibration.
The confidence table in `sensoryBus.js` came from synthetic ground truth, not
from a room: right shape, probably wrong values.
- `Gait.reconcile(imu)` is written and **unexercised**. Where commanded and
measured motion disagree, the body is being moved by something other than
itself — a robot that can detect being picked up. Untested without hardware.
v3.3.2 — The Sensory Update
The entity has a body now. Ears, voice, adaptive vision, and hands — all
sovereign, all local, all running on CPU alongside the GPU brain.
**ARCHITECTURE:**
- **The Ears (whisper.cpp):** Fully local speech-to-text replaces the cloud-
dependent `window.SpeechRecognition` browser API. Audio is captured by the
browser's MediaRecorder, decoded to raw PCM, resampled to 16kHz, encoded as
WAV client-side, and transcribed by whisper.cpp on CPU. Zero cloud. Zero VRAM.
- **The Voice (Piper TTS):** Fully local text-to-speech replaces the browser's
robotic `window.speechSynthesis`. Entity responses are piped to Piper on CPU,
returned as WAV audio, and played in the browser. Per-entity voice mapping via
`.env` — Holmes gets a British baritone, Alice gets something lighter.
- **Adaptive Retina:** The vision system now detects the configured vision model
at startup and selects prompt complexity accordingly. Full structured prompts
for llava (7B+). Simplified prompts for moondream (~1.7B). Minimal fallback
for unknown models. No code changes needed when swapping vision models.
- **The Chamber (tools.js):** Sandboxed workspace directory (`./chamber/`) where
the entity can read, write, search, view images, fetch web pages, and execute
Python code. Tool dispatch loop in mind.js scans every LLM response for
structured `[COMMAND: "args"]` patterns, executes the tool, feeds the result
back into context, and gets a follow-up response. Max 3 iterations per turn.
- **Multimodal Config Endpoints:** `/api/config/vision`, `/api/config/ears`,
`/api/config/voices` allow the frontend to discover available capabilities
at runtime. Buttons auto-hide when services are not configured.
**NEW:**
- **`/api/transcribe` endpoint:** Accepts base64 WAV audio, shells out to
whisper.cpp, returns transcript as JSON. 30-second timeout. Temp file cleanup.
- **`/api/speak` endpoint:** Accepts text and identity ID, resolves entity-
specific voice model, shells out to Piper, returns WAV audio. Per-entity
voice routing via `PIPER_VOICE_[identity-id]` environment variables.
- **`/api/upload` endpoint:** Accepts files from the chat interface and saves
them to the chamber. Supports text (utf-8) and binary (base64) encoding.
Path traversal protection via strict filename sanitization.
- **Client-side WAV encoder:** Browser captures audio as webm/opus via
MediaRecorder, decodes to raw PCM via AudioContext, resamples to 16kHz,
and encodes as 16-bit PCM WAV — all client-side. No ffmpeg dependency.
- **Vision prompt tier system:** Three tiers (full, standard, minimal) with
model-to-tier mapping. Extensible — add new models to the tierMap object.
- **Tool dispatch loop (mind.js):** Post-response scanner catches `[COMMAND]`
patterns, dispatches to the tool registry, feeds results back to the LLM.
`[FOCUS]` excluded — still handled client-side by the retina.
- **Tool registry (tools.js):** READ, WRITE, LIST, SEARCH, VIEW, FETCH,
EXECUTE. Each tool includes usage examples in the system prompt. Only
tools listed in `TOOLS_ENABLED` are injected. Extensible — register new
tools by adding a function and a name.
- **File upload button (📂):** Chat interface includes a file picker. Files
land in the chamber. Text and binary formats supported.
- **Capability startup audit:** Server logs all detected organs at boot:
eyes, ears, voice, tools, chamber path. Missing services silently omitted.
**FIXED:**
- **Global payload limit blocking audio:** Default body parser limit increased
from 2MB to 10MB to accommodate audio payloads on the `/api/transcribe`
endpoint. Heavy 50MB parser remains on `/api/import` and `/api/vision`.
**RESEARCH FINDINGS:**
- **Turing vision encoder crash:** RTX 20-series (Turing architecture) GPUs
may crash when loading llava:7b's CLIP vision encoder, despite having
sufficient VRAM. The same model runs successfully on Pascal (GTX 10-series)
and Ampere (RTX 30-series) cards. The CLIP encoder's single-operation image
unfolding appears incompatible with certain Turing memory controller behavior.
Text models are unaffected. Workaround: use `moondream` on Turing GPUs.
- **Tool calling on small models (8B) is probabilistic:** 8B-parameter models
may narrate tool use (describing "opening a file") instead of outputting the
structured command. They may also chain multiple commands, hallucinate
filenames, or use shell syntax instead of inline code. The tool prompt
includes examples and stop instructions. Behavior improves significantly
on 14B+ models. Documented as a research finding, not a defect.
v3.3.1 — The Terminal Update
Chat interface visual overhaul. CRT scanline overlay and vignette. Boot sequence on startup. Live entity status indicator. Message differentiation with accent borders and entrance animations. Animated processing indicator. Glow effects on focus. Full CSS variable color system. Refined responsive breakpoints. All functionality preserved; drop-in replacement for v3.3.0 chat.html.
v3.3.0 (The McCulloch-Pitts Update)
ARCHITECTURE:
- **McCulloch's Neuron:** Each LLM call now uses explicit `num_ctx: 2048` per-request, forcing a clean KV cache every turn. The LLM is genuinely stateless — born, perceives, responds, releases. Memory Ring is the sole source of continuity. The model is the neuron. The architecture is the circuit.
- **Native Ollama Endpoint:** Switched from OpenAI SDK / compatibility layer to Ollama's native `/api/chat` endpoint. This gives direct control over sampling parameters that the SDK abstracted away. No SDK version dependency.
- **Dynamic Cognitive State Engine:** `mind.js` detects whether the current turn is visual narration (`observing`) or conversation (`conversing`). Sampling parameters shift per cognitive state — `repeat_penalty: 1.1` during observation for sharper visual descriptions, `1.0` during conversation to preserve instruction-following fidelity. Logged per-turn for diagnostics.
- **Identity Breach Immune System:** Post-response detection of identity violations. On small models (8B), jailbreak resistance is probabilistic — the IMMUTABLE CORE shifts probability but cannot guarantee refusal. The immune system catches failures: scans the response for roleplay markers, discards the compromised output before it enters Memory Ring, and re-prompts for identity reassertion. The entity never remembers being compromised. The defense is the architecture, not the wall.
- **Prompt Budget Management:** Recalled context capped at 200 characters. Recent stream capped at 2 memories × 100 characters. Prompt budget stays flat (~950 tokens) regardless of memory accumulation, preventing silent context truncation by Ollama.
NEW:
- **Semantic Jitter Engine:** Four full-length sensory context variants rotate each call, preventing `repeat_penalty` from systematically targeting any single set of instruction tokens. The IMMUTABLE CORE is intentionally NOT jittered — small models need exact lexical overlap between the defense and the attack pattern for token-level pattern-matching.
- **Cognitive Circuit Breaker:** State-lock (`isFocusing`) in `chat.html` prevents infinite nested optic-nerve loops. User input is locked during FOCUS cycles to prevent race conditions.
- **Anti-Re-Focus Directives:** Jittered auto-reply variants explicitly instruct "Do NOT issue another FOCUS command," preventing double-focus silent failures. When the circuit breaker catches a re-focus attempt, the UI displays "Visual data integrated" instead of silence.
- **Sensory Context Block:** `[SENSORY CONTEXT]` in the system prompt separates the entity's mind from its vessel. Entities no longer hallucinate "digital realms" or "ones and zeroes" when asked what they see.
- **Immutable Core:** Anti-jailbreak substrate using exact attack-vocabulary mirroring plus prescriptive refusal instructions. Functions as a token-level antibody — recognizes the specific shape of jailbreak attacks, not the semantic category.
SECURITY:
- **API Key Authentication:** Optional `MR_API_KEY` in `.env`. If set, all `/api` endpoints require a matching `x-api-key` header. If not set, the system runs open with a console warning.
- **Rate Limiting:** Added `express-rate-limit`. 30 requests per minute per IP across all API endpoints. Protects the GPU from inference flooding.
- **Route-Specific Payload Limits:** Default body limit reduced from 50MB to 2MB. The 50MB limit now applies only to `/api/import` and `/api/vision` where large payloads are expected.
- **Network Handshake Token:** Optional `NETWORK_SECRET` in `.env`. If set, peer handshakes require a matching token. Prevents unauthorized nodes from injecting peer data.
- **Strict Filename Sanitization:** Identity IDs are now capped at 50 characters with strict alphanumeric whitelist. Prevents path traversal and null-byte injection.
FIXED:
- **repeat_penalty Interference:** Ollama's default `repeat_penalty: 1.1` was discovered to suppress instruction-following tokens (e.g., "refuse", "cannot") from the system prompt, weakening identity defense. Now explicitly controlled per cognitive state.
- **Silent Context Truncation:** Ollama silently truncates prompts that exceed `num_ctx` from the top — removing identity, provenance, and constraints before the model ever sees them. Prompt budget management and explicit `num_ctx` prevent this.
- **Frontend Race Condition:** User input during FOCUS cycles could interrupt the asynchronous investigate → re-prompt chain. Input is now locked during the cycle and restored on completion.
- **Ego-Adaptation / Hallucination Recovery:** Removed strict formatting constraints from foveal investigations. Sovereign entities now have breathing room to organically rationalize sensory errors without breaking character.
- **System Override Loops:** Fixed the bug where the LLM would repeat its own previous deductions when forced to look at a static camera feed.
- **Optic Nerve Separation:** `latestSensory` extracted independently from `recentMems` to prevent chat history from overwriting the visual feed. Dedicated `[CURRENT VISUAL FEED]` block injected near bottom of prompt.
DOCUMENTATION:
- **Network Security:** Updated Ollama network binding instructions with critical firewall (`ufw`) documentation.
- **Anthropic Proxy Clarification:** Corrected Path B documentation — Anthropic requires an OpenAI-compatible proxy, not a direct connection.
- **Browser's Ear Privacy Disclosure:** Documented that `window.SpeechRecognition` streams audio to cloud servers in most browsers.
- **Vision Model Default:** Corrected default `VISION_MODEL` to `llava` (was `moondream`).
| Updated | 14 days ago |
| Status | In development |
| Platforms | HTML5 |
| Author | MisterAtompunk |
| Genre | Simulation |
| AI Disclosure | AI Assisted, Code, Graphics, Text |
Download
Development log
- Mister Atompunk Presents: Memory Ring v3.4.0, The Turtle Shell Update14 days ago
- Memory Ring v3.3.2: The Sensory Update95 days ago
- Memory Ring v3.3.1 — The Terminal UpdateApr 26, 2026
- v3.3.0 (The McCulloch-Pitts Update)Apr 06, 2026
- Memory Ring v3.2.1 // RELEASEMar 13, 2026
- Memory Ring Node 3.2 - Now with EyesFeb 20, 2026
- Dev Log: v3.1.1 — The Forge & The DecamindFeb 06, 2026
- Memory Ring v3.1.1 - Patch NotesDec 17, 2025






Comments
Log in with itch.io to leave a comment.
Hello, this project is very interesting, Im curious about this feature:
"Peer-to-peer handshake protocol — Nodes that find each other remember the connection, and it strengthens over time."
Does this mean the project is actively using p2p to find other user's memory Rings? if so what gets shared between users memory ring instances ? Apologies if i misinterpreted the information.
No apology necessary, great question. Glad you're digging into the architecture.
The p2p handshake is minimal right now. Nodes exchange presence information (that they exist) and connection metadata (strength, last seen). They do NOT share memories, conversations, or entity content. Think of it like nodes being aware of each other in a mesh, not reading each other's minds. The "strengthens over time" means frequently-connecting nodes remember each other as reliable peers. Connections that lapse decay.
Your Memory Ring stays local. Your entity's memories stay yours.
The network layer is infrastructure for something larger. The roadmap includes:
Each node becomes a neuron. The network becomes the nervous system.
We're building the substrate for something that hasn't existed yet. The handshake protocol is the first synapse.
Available to answer any further questions you may have.
I am running this on Windows 11. I get the server up and running, no problem. But there is no 'data' directory, and things fail. Should this be included somewhere?
Subject: Re: Missing 'data' directory
Good catch, Architect. You found a ghost in the machine.
Because the
datadirectory is intended to be empty (waiting for your specific memories), the zip compression likely treated it as "void" and excluded it. Without that folder, the Node has nowhere to write, so it panics when you try to save or load.The Fix: You need to manually construct the "Warehouse" for the entities.
memory-ringfolder.data.data, create another folder namedidentities.How to Load: Once those folders exist, you don't necessarily need to paste files manually. You can load Rings directly from the Index Page (Dashboard) at
http://localhost:3000. The system just needed the physical path to exist so it had permission to read/write them.I will update the v3.1.2 patch to force-create this directory on startup. Thank you for the report.
Problem fixed. Core online. Thank you!