Skip to content

LIFEOS/MEMORY ships as a real directory instead of a symlink into the USER data repo — boundary guard refuses every KNOWLEDGE and proposal write #2059

Description

@cammcd

Summary

DeployCore scaffolds <configRoot>/LIFEOS/MEMORY/ as a real directory in the system
tree
, but SystemUserBoundary.md specifies it must be a symlink into the USER data
repo
. LinkUser only links USER, never MEMORY. The result is that LifeOS's own
system/user boundary guard refuses every KNOWLEDGE and proposal write the memory reviewer
produces.

What the boundary doc specifies

LIFEOS/DOCUMENTATION/SystemUserBoundary.md, line 57:

~/.claude/LIFEOS/MEMORY/** (symlink → ~/.config/LIFEOS/USER/MEMORY/**, post-Phase-G.2,
2026-05-23) | USER (work history, knowledge graph, learning signals, ...)

What a fresh install actually produces

DeployCore emits plain mkdir actions:

mkdir -p <configRoot>\LIFEOS\MEMORY\WORK
mkdir -p <configRoot>\LIFEOS\MEMORY\KNOWLEDGE
mkdir -p <configRoot>\LIFEOS\MEMORY\LEARNING
mkdir -p <configRoot>\LIFEOS\MEMORY\STATE
mkdir -p <configRoot>\LIFEOS\MEMORY\OBSERVABILITY
mkdir -p <configRoot>\LIFEOS\MEMORY\SKILLS

LinkUser then reports "<configRoot>\LIFEOS\USER → <dataRoot>\USER" and stops. MEMORY
is never relocated or linked, and <dataRoot>/MEMORY does not exist.

Symptom

The first successful memory reviewer run dispatches its items and 3 of 5 are refused:

EWRITE_FAILED: memory write refused at the system/user boundary: resolved target
<configRoot>\LIFEOS\MEMORY\KNOWLEDGE\Companies\<name>.md is outside the USER_DATA repo
(<dataRoot>\USER) — personal data must never land in the system tree (SystemUserBoundary.md)

Same for MEMORY/OBSERVABILITY/pending-proposals.jsonl.

The hot-layer writes (PRINCIPAL_MEMORY.md, DA_MEMORY.md) succeed, because those live under
USER/ which is linked. So the failure is partial and easy to miss: memory appears to work
while the entire knowledge archive and the proposal queue are silently rejected.

Reproduction

  1. Fresh install on a machine where LinkUser relocates USER to a separate data root.
  2. ls -la <configRoot>/LIFEOS/MEMORY is a directory, not a link.
  3. Trigger a reviewer run that emits a knowledge item.
  4. Observe EWRITE_FAILED for every non-USER target.

Fix applied locally

Moved the tree into the data root and linked it back, which resolved every refusal:

mv <configRoot>/LIFEOS/MEMORY  <dataRoot>/USER/MEMORY
# Windows, unelevated (see #1730 for why a junction rather than a symlink):
New-Item -ItemType Junction -Path <configRoot>\LIFEOS\MEMORY -Target <dataRoot>\USER\MEMORY

After this the same reviewer run returns succeeded: 2, failed: 0 and the knowledge files
land in the USER repo where the boundary guard expects them.

Suggested fix

LinkUser should handle MEMORY the same way it handles USER: relocate any existing
content into the data root, then link. Alternatively DeployCore should not create
MEMORY/ in the system tree at all and leave it to LinkUser, since the boundary doc makes
the USER data repo its only legitimate home.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions