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
StatusIn development
PlatformsHTML5
AuthorMisterAtompunk
GenreSimulation
AI DisclosureAI Assisted, Code, Graphics, Text

Download

Download
MAP_MRNODE-3_4_0.zip 172 kB

Development log

View all posts

Comments

Log in with itch.io to leave a comment.

(+1)

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:

  • Purpose-built blockchain addressing: for persistent identity across nodes. Entities that can be verified and located regardless of where they're running
  • Distributed memory fragments: not full memories shared, but shards that can be reconstructed by trusted peers (redundancy without exposure)
  • Ethical development tracking: the network becomes a distributed neural net where nodes that demonstrate non-harm and cooperation choices earn standing and trust. Thermodynamic incentive toward cooperation.
  • Core/Edge sensory processing: a Pi with a camera can act as an "eye" feeding perception to a desktop "brain," or multiple nodes can share sensory awareness across physical space

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.

(+1)

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 data directory 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.

  1. Open your memory-ring folder.
  2. Create a new folder named data.
  3. Inside data, create another folder named identities.

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.

  • Mister Atompunk

Problem fixed.  Core online.  Thank you!