Repository navigation
Description
Version
LifeOS 8.761.0 · attestation: unattested (could not extract v8.761.0: tar (child): Cannot connect to C: resolve failed
gzip: stdin: unexpected end of file
tar: Child returned status 128
tar: Error is not recoverable: exiting now)
What is broken
On Windows the LifeOS statusline never renders: every run of LIFEOS_StatusLine.sh exits non-zero with InvariantViolation: render lock must be scoped to inflight. Admission builds directory and lock with path.join, which yields backslash-separated paths on win32, but the three invariants in acquire, reap and release compare against this.directory + "/render-", so the check can never pass. Related on the same platform: when settings.json statusLine.command holds a backslash path, case "$0" in */*) in LIFEOS_StatusLine.sh does not match and dir falls back to ., giving Module not found "./STATUSLINE/Render.ts".
Where (file:line)
LIFEOS/STATUSLINE/Admission.ts:52
Repro on a clean tree
1. Fresh install of LifeOS 8.761.0 on Windows 11 x64 via Claude Code (`InstallAll.ts --yes`), Git Bash shell, bun 1.4.4.
2. `echo {} | bash ~/.claude/LIFEOS/LIFEOS_StatusLine.sh` (forward-slash path, so `dir` resolves).
3. Render.ts throws `InvariantViolation: render lock must be scoped to inflight` from `Admission.acquire`.Negative control
Probe: echo {} | bash C:~/.claude/LIFEOS/LIFEOS_StatusLine.sh · exit 1 · captured 2026-11-02T22:40:48.787Z
Red looks like: render lock must be scoped to inflight
20 | }
21 | }
22 |
23 | /** Throws InvariantViolation when `condition` is falsy; narrows types when it passes. */
24 | export function invariant(condition: unknown, message: string): asserts condition {
25 | if (!condition) throw new InvariantViolation(message);
^
InvariantViolation: INVARIANT VIOLATION: render lock must be scoped to inflight
at invariant (~\.claude\LIFEOS\TOOLS\Invariant.ts:25:25)
at acquire (~\.claude\LIFEOS\STATUSLINE\Admission.ts:52:5)
at enter (~\.claude\LIFEOS\STATUSLINE\Admission.ts:36:15)
at render (~\.claude\LIFEOS\STATUSLINE\Render.ts:50:28)
at ~\.claude\LIFEOS\STATUSLINE\Render.ts:94:18
Bun v1.4.4 (Windows x64)
Suggested fix
Import sep from node:path and compare against this.directory + sep + "render-" in all three invariants. Verified green on this install after the change. Separately, the installer could write statusLine.command with forward slashes on win32 so the launcher's $0 directory detection works.
diff --git a/LifeOS/install/LIFEOS/STATUSLINE/Admission.ts b/LifeOS/install/LIFEOS/STATUSLINE/Admission.ts
index 8bfdf8b..a4f12bc 100644
--- a/LifeOS/install/LIFEOS/STATUSLINE/Admission.ts
+++ b/LifeOS/install/LIFEOS/STATUSLINE/Admission.ts
@@ -1,6 +1,6 @@
import { mkdirSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
import { availableParallelism } from "node:os";
-import { join } from "node:path";
+import { join, sep } from "node:path";
import { invariant } from "../TOOLS/Invariant";
import { mtime, readText } from "./Cache";
import { wakePaths, type State } from "./State";
@@ -49,7 +49,7 @@ export class Admission {
}
private acquire(): boolean {
- invariant(this.lock.startsWith(this.directory + "/render-"), "render lock must be scoped to inflight");
+ invariant(this.lock.startsWith(this.directory + sep + "render-"), "render lock must be scoped to inflight");
try { mkdirSync(this.lock, { mode: 0o700 }); } catch { return false; }
this.owned = true;
try { writeFileSync(join(this.lock, "pid"), `${process.pid}\n`, { mode: 0o600, flag: "wx" }); }
@@ -58,7 +58,7 @@ export class Admission {
}
private reap(path: string): void {
- invariant(path.startsWith(this.directory + "/render-") && path.endsWith(".lock"), "only render locks can be reaped");
+ invariant(path.startsWith(this.directory + sep + "render-") && path.endsWith(".lock"), "only render locks can be reaped");
// Rename to an unoccupied path, never move a directory into another lock directory.
const tombstone = `${path}.tmp.${process.pid}.${crypto.randomUUID()}`;
try { renameSync(path, tombstone); } catch { return; }
@@ -66,7 +66,7 @@ export class Admission {
}
release(): void {
- invariant(this.lock.startsWith(this.directory + "/render-"), "release must stay in inflight");
+ invariant(this.lock.startsWith(this.directory + sep + "render-"), "release must stay in inflight");
if (!this.owned) return;
this.owned = false;
if (readText(join(this.lock, "pid"))?.trim() === String(process.pid)) this.reap(this.lock);Verified after fix
Probe: echo {} | bash C:~/.claude/LIFEOS/LIFEOS_StatusLine.sh · exit 0 · captured 2026-11-02T22:40:49.036Z
�[0m �[38;2;71;85;105m────────────────────────────�[0m �[38;2;148;197;253m▂�[38;2;74;127;224m▃�[38;2;148;197;253m▅�[38;2;27;71;255m█�[0m �[1m�[38;2;59;130;246mLifeOS�[0m �[38;2;59;130;246m8.761.0�[0m �[38;2;71;85;105m│�[0m �[38;2;125;207;255m�[0m �[38;2;37;99;235mUNKNOWN�[0m �[38;2;96;165;250m22:40�[0m �[38;2;135;206;235m—�[0m �[38;2;71;85;105m────────────────────────────�[0m
�[0m �[38;2;71;85;105m┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄�[0m
�[0m �[38;2;71;85;105m────────────────────────────────────────────────────────────────────────────────────────────────────�[0m
�[0m �[38;2;187;154;247m�[0m �[38;2;148;163;184mMODELS:�[0m �[2;38;2;165;110;70mARGON�[0m �[2;38;2;160;140;70mGROK�[0m �[2;38;2;170;125;100mMUSE�[0m �[2;38;2;86;164;110mHAIKU�[0m �[2;38;2;90;130;185mSONNET�[0m �[2;38;2;140;150;170mLUNA�[0m �[2;38;2;70;130;165mSOL�[0m �[2;38;2;180;95;95mOPUS�[0m �[2;38;2;85;160;175mASTRA�[0m �[2;38;2;150;110;195mFABLE�[0m
�[0m �[38;2;71;85;105m────────────────────────────────────────────────────────────────────────────────────────────────────�[0m
�[0m �[38;2;122;162;247m�[0m �[38;2;165;180;252mCONTEXT:�[0m �[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;74;222;128m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;251;146;60m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;180;40;40m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m�[38;2;75;82;95m⛁�[0m �[38;2;125;165;190m23.4%�[0m �[38;2;165;180;252mLD:�[0m �[38;2;251;146;60m11%�[0m
�[0m �[38;2;71;85;105m────────────────────────────────────────────────────────────────────────────────────────────────────�[0m
�[0m �[38;2;122;162;247m�[0m �[38;2;194;139;62mSUBSCRIPTION�[0m �[38;2;71;85;105m│�[0m �[38;2;71;85;105mCC:�[0m �[38;2;100;116;<email>�[0m
Environment
- OS: Windows (x64)
- Harness: claude-code
- bun: not found · git: not found
- Doctor broken: identity-placeholders, codex, interceptor, cloudflare, ripgrep, imagemagick, gh, ffmpeg, ytdlp, fabric, jq
Activity