# Reported issues for Pseudolife Memory

Pod holds 15 of 15 problems reported by people outside the maintainer team. Issues filed by the project's own owners, members and collaborators are excluded entirely — a maintainer's release checklist is not a warning to a prospective user.

Back to [Pseudolife Memory](/mcp/pseudolife-memory).

## Most discussed

### fix(migrate): partial legacy import permanently blocks retry and loses the remainder silently

`migrate_legacy` is not failure-atomic, and its idempotency guard is "the entries table is non-empty" — so any partial import **permanently blocks retry**, silently.

**Where:** `pseudolife_memory/storage/migrate.py` — the guard returns early when entries or facts exist. Each `insert_entry` commits its own transaction, and the source files are renamed to `.pre-v8.bak` only at the very end. The service caller swallows the exception with a single warning and boots normally.

**Scenario:** a legacy

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/187) · 2026-08-20 · closed · 1 comment

### fix(mcp): memory_recall returns an unbounded payload - 93.7 KB measured on a plain 3-hop query

`memory_recall` has no output budget. A plain 3-hop query on a well-connected entity returned **93,683 characters** — measured live during the audit — which the calling client refused.

**Measured:** `memory_recall(query="what does the stdio shim connect to and what runs the MCP tools", hops=3)` with default `top_k=5` and `verbose=False` returned 53 entities (38.6 KB), 75 edges (5.3 KB) and 45 uncapped full entry texts (51.9 KB — 55% of the payload).

**Why it happens:** `top_k` bounds the seeds

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/186) · 2026-08-20 · closed · 1 comment

### fix(release): server.json version guard runs after the irreversible PyPI publish

The release workflow validates `server.json` version fields **after** the PyPI publish step, so a mismatch fails the run at a point where the publish is already irreversible.

**Where:** `.github/workflows/release.yml` — the guard runs in a job that follows publication. `server.json` carries the version in two independent places (top-level and inside packages), and the workflow's own comment notes they drift independently. Nothing local pins either against `pyproject.toml`.

**Scenario:** cut a 

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/185) · 2026-08-20 · closed · 1 comment

### fix(evals): bench reset list missing v24/v27/v31 tables - retrieval events and entity kinds leak across questions

The bench reset helper truncates a hardcoded table list that never grew for schema v24, v27 or v31, so several FK-free tables **leak across bench questions**.

**Where:** `evals/ladder_sweep.py` — `_ALL_TABLES` lists entries, facts, entities, edges, episodes and friends, then runs `TRUNCATE ... RESTART IDENTITY CASCADE`. `CASCADE` only reaches tables holding an FK to a listed table, so `retrieval_events` (+`retrieval_uses`), `entity_kinds`, `outcome_signals`, `dismissed_pairs`, `merge_decisions`

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/181) · 2026-08-20 · closed · 1 comment

### fix(release): package __version__ is stale at 0.6.0 against pyproject 0.14.0, with no guard test

`pseudolife_memory.__version__` is `"0.6.0"` while `pyproject.toml` is `0.14.0` — eight releases of drift, and no guard test pins it.

**Verified:** `pseudolife_memory/__init__.py` line 8 reads `__version__ = "0.6.0"`; `pyproject.toml` line 7 reads `version = "0.14.0"`.

**Impact:** a user who does the standard `import pseudolife_memory; pseudolife_memory.__version__` on a fresh `pip install pseudolife-mcp` gets a version that has not shipped since 2026-06-25, disagreeing with `importlib.metadat

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/180) · 2026-08-20 · closed · 1 comment

### feat(retrieval-log): log ranking components, not just the fused score, or Phase 1 cannot be trained

The retrieval event log records only the **final fused score** per served entry, so the component features a Phase-1 learned fusion head would learn to combine are not recoverable offline. Supervision is accruing now in a shape that cannot train the thing it was built for.

**Where:** the served payload written per search carries id, rank, score, via and bank — where `score` is the output of the very fusion the head is supposed to learn.

**Why it cannot be reconstructed later:** the inputs are 

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/179) · 2026-08-20 · closed · 1 comment

### fix(graph): junk tombstone auto-delete ignores fact count and can delete a re-minted real entity

The deep-dream junk auto-delete applies its fact-count guard to one branch but not the other, so an entity that has accumulated real evidence can be deleted unattended — and re-deleted on every later tick.

**Where:** `pseudolife_memory/service.py`, deep-dream apply block. `zero_structure` is `(degree == 0 and fact_count <= 1)`; `tombstoned` is `(normalised name in tombstones and degree <= junk_max_degree)`, default 1. The two are combined with `or`, so **fact count is never consulted on the tom

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/177) · 2026-08-20 · closed · 1 comment

### fix(shim): stdio shim re-validates arguments and rejects stringified list params the daemon would accept

The stdio shim re-validates tool arguments with jsonschema **before** forwarding, which defeats the SDK rescue for stringified list/number params — so the same call succeeds over direct HTTP and fails through the shim.

**Where:** `pseudolife_memory/shim.py` registers a bare `@server.call_tool()`. The SDK default is `validate_input=True`, whose handler runs `jsonschema.validate` on the **raw** arguments against the upstream tool's `inputSchema` (the shim's tool cache is filled from the upstream 

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/175) · 2026-08-20 · closed · 1 comment

## Most recent

### docs(adoption): presentation gaps ahead of the publicization push - install front door, comparison page, demo, support surface

Tracking issue from the 2026-08-21 competitive sweep (10 competitors plus a community-sentiment pass) and the process red-team. **The product is stronger than its presentation** — almost every top-priority gap is presentational and cheap.

### Install front door (highest value, near-zero cost)

The README quickstart leads with a git clone, Docker, and a multi-GB image, while the genuinely competitive two-command lite path sits about 100 lines down under a hedged heading. The first 500 words a pr

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/189) · 2026-08-20 · closed · 0 comments

### docs(atlas): migration list stops at v29, retired image size, and a removed tool still published

The System Atlas is advertised as the canonical machine-readable architecture map, and three of its claims are stale as of the v0.14.0 cut — despite that cut's commit message stating the atlas cards were re-verified.

1. **Migration history stops at v29.** The storage card's subtitle says `SCHEMA_META_VERSION 31` while its migration list ends at v29 — v30 (merge-proposal judge verdict) and v31 (retrieval event log) are missing. An agent asked "what changed between my v29 bank and v31?" concludes

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/184) · 2026-08-20 · closed · 0 comments

### fix(retrieval-log): retention never runs when dreaming is disabled, so the event table grows unbounded

Retrieval-event retention never runs on a bank with dreaming disabled, so `retrieval_events` grows without bound — while searches keep writing one row each.

**Where:** `pseudolife_memory/memory/dream.py` — `run_sweep_once` returns `{"fired": False, "reason": "disabled"}` **before** the prune block whenever `memory.dream.enabled` is false, and the sweep thread is never started in that case at all.

**Why it matters:** `memory.dream.enabled: false` is a first-class documented knob (an operator wh

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/178) · 2026-08-20 · closed · 0 comments

### fix(install): install.sh aborts mid-install on PEP 668 distros instead of falling back to HTTP

On a PEP 668 distro (Ubuntu 24.04, Debian 12, Fedora 40, Arch — i.e. the default modern Linux case), `ops/install.sh` **aborts mid-install** after the images are already built, with no fallback and no remediation message. The Windows installer handles the same failure gracefully.

**Where:** `ops/install.sh` sets `set -euo pipefail`. `ensure_shim()` runs `pipx install` / `python3 -m pip install --user pseudolife-mcp` with **no exit-code check** and sets its success flag unconditionally on the ne

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/176) · 2026-08-20 · closed · 0 comments

### fix(daemon): documented LAN sharing is broken - MCP endpoint rejects non-loopback Host with 421

The documented LAN-sharing recipe cannot work: every request to `/mcp` from a non-loopback Host is rejected with `421 Invalid Host header` before any auth or handler code runs.

**Where:** `pseudolife_memory/mcp_server.py` constructs `FastMCP("Pseudolife Memory", instructions=...)` with no `host=` and no `transport_security=`. The SDK's `FastMCP.__init__` defaults `host` to `127.0.0.1` and, seeing a loopback host, **auto-enables DNS-rebinding protection** with `allowed_hosts=["127.0.0.1:*", "loc

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/174) · 2026-08-20 · closed · 1 comment

### fix(console): stored XSS - graph entity names reach an innerHTML tooltip in the galaxy view

The 3D galaxy view hands raw graph entity display names to the vendored renderer as a **string** label. The renderer sets a string label via d3 `.html()`, i.e. `innerHTML`, so a hostile entity name executes on hover.

**Where:** `pseudolife_memory/web/static/js/galaxy.js` — nodes map the entity to `n.id`, then `.nodeLabel((n) => n.id)`. The service builds the node entity from the unescaped entity display name.

**Why nothing stops it upstream:** the write-time name gate `junk_name_reason()` (`ps

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/171) · 2026-08-20 · closed · 0 comments

### fix(concurrency): retrieval-log prune runs off the service lock and can break the shared PG connection

`prune_retrieval_log()` mutates Postgres from the dream-sweep thread without holding `MemoryService._lock`. Every other background-reachable storage mutation takes the lock; this one does not. When it interleaves with a request thread's write, psycopg's transaction nesting can raise `OutOfOrderTransactionNesting`, which either aborts the whole sweep tick before any dream work happens, or leaves the shared connection `idle in transaction`.

**Where:** `pseudolife_memory/service.py` — `prune_retri

[Read the thread](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues/170) · 2026-08-20 · closed · 1 comment

The remaining reports are on [the project's issue tracker](https://github.com/Pseudogiant-xr/Pseudolife-MCP/issues).
