Skip to content

fix(linux): normalize runtime-root dir casing (LifeOS → LIFEOS) — silent memory failure on case-sensitive FS#1406

Open
christauff wants to merge 1 commit into
danielmiessler:mainfrom
christauff:fix/linux-lifeos-dir-casing
Open

fix(linux): normalize runtime-root dir casing (LifeOS → LIFEOS) — silent memory failure on case-sensitive FS#1406
christauff wants to merge 1 commit into
danielmiessler:mainfrom
christauff:fix/linux-lifeos-dir-casing

Conversation

@christauff

Copy link
Copy Markdown
Contributor

Context (friendly heads-up: people are already deploying v6 on Linux!)

First — congrats on the 6.0.0 "one skill, one install" release. I picked it up within hours of the tag and installed it on Linux (Ubuntu), and it mostly came up beautifully. This PR reports one silent failure I hit during that deploy, with a fix. Sharing it partly because it's the kind of thing that only surfaces off-macOS, and you probably want to know early.

The bug: LifeOS vs LIFEOS — a case-sensitivity silent failure on Linux

The runtime is deployed to the all-caps <configRoot>/LIFEOS/DeployCore does this deliberately (its own comment: "Targets the config-root runtime at the ALL-CAPS <configRoot>/LIFEOS/ so it matches the @LIFEOS/... imports in CLAUDE.md"), and CLAUDE.template.md imports @LIFEOS/....

But many runtime tools and hooks resolve the root as mixed-case ~/.claude/LifeOS — e.g. const LIFEOS_DIR = join(HOME, ".claude", "LifeOS").

  • On macOS (case-insensitive FS by default) LifeOS and LIFEOS are the same inode → everything works, invisible.
  • On Linux (case-sensitive) they're different paths → the tools read a directory that doesn't exist and silently return empty.

Repro (Linux)

$ bun ~/.claude/LIFEOS/TOOLS/MemoryStatus.ts
Corpus:
  knowledge   no dir yet        # ← but KNOWLEDGE/ exists at LIFEOS/MEMORY/KNOWLEDGE

It's looking at ~/.claude/LifeOS/MEMORY/KNOWLEDGE (nonexistent on Linux) instead of ~/.claude/LIFEOS/MEMORY/KNOWLEDGE. No error is thrown — the corpus just appears empty, which is the dangerous part. After normalizing the path casing, MemoryStatus correctly reports the corpus.

The fix

Normalize the runtime-root path segment "LifeOS""LIFEOS" (the canonical DeployCore/CLAUDE.md already use) across the install-payload tools and hooks — 119 references across 91 files.

  • No-op on macOS (case-insensitive), a fix on Linux — strictly safe cross-platform.
  • Scoped carefully: only touches runtime-root references (.claude/LifeOS, CLAUDE_ROOT/"LifeOS", etc.). The legitimately mixed-case skills/LifeOS and install/LifeOS source-directory references are deliberately left untouched (verified).

Notes / happy to adjust

  • This is the minimal, mechanical normalization. Longer term a single shared root resolver (e.g. one lifeosDir() helper the tools import, instead of each re-deriving the path) would prevent the casing from drifting again — glad to follow up with that if you'd prefer it over the flat normalization.
  • PLATFORM.md lists Linux as "Fully Supported," so this seemed worth fixing rather than working around locally (a ~/.claude/LifeOS → LIFEOS symlink also masks it, but that's a band-aid).

Thanks for building and open-sourcing this — genuinely a pleasure to deploy.

🤖 Generated with Claude Code

@christauff

Copy link
Copy Markdown
Contributor Author

Note for triage: the diff is a pure LifeOSLIFEOS casing normalization (119 lines, all identical shape) — verified locally on Linux that it makes MemoryStatus/MemoryRetriever find the corpus without a symlink, and it's a no-op on macOS. If the claude-review check goes red, that's the usual fork-PR limitation (secrets/OIDC withheld from pull_request events off a fork), not the change.

Native runtime tools/hooks resolve the config-root runtime as mixed-case
`~/.claude/LifeOS`, but DeployCore deploys it to all-caps `~/.claude/LIFEOS`
(to match the `@LIFEOS/...` imports in CLAUDE.md). On macOS (case-insensitive
FS) these coincide; on Linux (case-sensitive) the tools read a nonexistent
path and silently return empty — e.g. MemoryStatus reports the KNOWLEDGE
corpus as "no dir yet" despite it existing at LIFEOS/MEMORY/KNOWLEDGE.

Normalizes the runtime-root path segment to the canonical LIFEOS across the
install payload (119 refs / 91 files). No-op on macOS; fixes the silent
failure on Linux. Leaves the legitimately mixed-case `skills/LifeOS` and
`install/LifeOS` source-dir references untouched.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@christauff christauff force-pushed the fix/linux-lifeos-dir-casing branch from 088754b to de168be Compare July 3, 2026 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant