danielmiessler / danielmiessler/LifeOS
LIFEOS/MEMORY ships as a real directory instead of a symlink into the USER data repo — boundary guard refuses every KNOWLEDGE and proposal write
- Dominant language
- TypeScript
- Stars
- 19k
- Forks
- 2.5k
- Avg merge
- 8d 17h
- Merged PRs (30d)
- 1
Description
## Summary
`DeployCore` scaffolds `/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 \LIFEOS\MEMORY\WORK
mkdir -p \LIFEOS\MEMORY\KNOWLEDGE
mkdir -p \LIFEOS\MEMORY\LEARNING
mkdir -p \LIFEOS\MEMORY\STATE
mkdir -p \LIFEOS\MEMORY\OBSERVABILITY
mkdir -p \LIFEOS\MEMORY\SKILLS
```
`LinkUser` then reports `"\LIFEOS\USER → \USER"` and stops. `MEMORY`
is never relocated or linked, and `/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
\LIFEOS\MEMORY\KNOWLEDGE\Companies\.md is outside the USER_DATA repo
(\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 /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 /LIFEOS/MEMORY /USER/MEMORY
# Windows, unelevated (see #1730 for why a junction rather than a symlink):
New-Item -ItemType Junction -Path \LIFEOS\MEMORY -Target \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.
Contributor guide
No contributing guide indexed for this repository
Research direction
Start with the DeployCore and LinkUser entry points and compare their behavior with LIFEOS/DOCUMENTATION/SystemUserBoundary.md, line 57. Reproduce a fresh install with USER on a separate data root, then run a memory reviewer that emits knowledge and proposal items; done means MEMORY is relocated and linked into the USER data repo and those writes succeed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- devops, infrastructure
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100