Version
LifeOS 7.40.4 (latest release, 2026-08-14) — component LIFEOS/LIFEOS_StatusLine.sh; repro run against main @ 5e2f2e8, which carries the same file.
What is broken
The startup context estimate asks git how large the working tree's status block will be, and bounds that call with timeout 1. macOS ships no timeout(1) — it is a GNU coreutils program, absent from a stock install and from the Xcode command line tools. On a Mac the command therefore fails before git runs, its error is discarded by the 2>/dev/null already on the line, and the empty output falls through wc -c as 0. Two things follow. The git contribution to the pre-first-API context estimate is always zero whatever the state of the working tree, so STARTUP LOAD under-reports by about a token per three and a half bytes of git status --porcelain output. And the bound itself does not exist on macOS: on a repository where git status is genuinely slow there is nothing stopping it from stalling the render, which is the case the timeout was presumably written for. The branch is reached on the pre-first-API ticks only, gated at :400 by [ "$context_pct" = "0" ] && [ "$total_input" -eq 0 ], so the wrong figure is the one shown while a session is starting up. The same file already branches on platform for stat at :209-211, so it knows it runs on both and this looks like an oversight rather than a GNU-only choice.
Where (file:line)
LifeOS/install/LIFEOS/LIFEOS_StatusLine.sh:447 (writer; consumer is :448, timeout appears nowhere else in the file)
Repro on a clean tree
# macOS, stock PATH, no GNU coreutils. Nothing here reads $HOME or the installed
# LifeOS, so the numbers do not depend on how your install is configured.
git clone https://github.com/danielmiessler/LifeOS.git /tmp/lifeos-clean
sed -n '447p' /tmp/lifeos-clean/LifeOS/install/LIFEOS/LIFEOS_StatusLine.sh
# A throwaway repo with a known amount of status output:
R=$(mktemp -d); cd "$R"; git init -q .
for i in $(seq 1 60); do echo "content $i" > "file-$i.txt"; done
echo "timeout on PATH: $(command -v timeout || echo NONE)"
# Line 447, character for character as it appears in the clean tree:
v=$(timeout 1 git -C "$R" status --porcelain 2>/dev/null | wc -c | tr -d ' ')
echo "_git_bytes=$v"
# What git actually reports for the same tree, and what :448 would have added:
b=$(git -C "$R" status --porcelain | wc -c | tr -d ' ')
echo "git status --porcelain bytes: $b"
echo "tokens :448 should add: $(( b * 10 / 35 ))"
Negative control
Run on unpatched main @ 5e2f2e8, macOS 27.0, /bin/bash 3.2.57, stock PATH:
timeout on PATH: NONE
_git_bytes=0
git status --porcelain bytes: 891
tokens :448 should add: 254
The line reports zero bytes of git status for a tree that has 891 bytes of it, so line 448 adds 0 tokens where it should add 254. A three-file tree gives the same _git_bytes=0 against 26 real bytes, so the result is zero independent of the tree rather than a rounding artefact. Running the whole unpatched script against that same 60-file repo with a startup payload (used_percentage: 0, total_input_tokens: 0) and reading startup_tokens back out of /tmp/pai-startup-estimate-<session_id>.sh gives a figure that is 254 lower than the same script with a working _git_bytes; the absolute total there depends on the reader's own install, the 254 does not.
Suggested fix
Built and run against the clean tree, not a sketch. Use the wrapper when one exists and run bare when neither does, so the value survives either way:
if command -v timeout >/dev/null 2>&1; then _TIMEOUT=(timeout 1)
elif command -v gtimeout >/dev/null 2>&1; then _TIMEOUT=(gtimeout 1)
else _TIMEOUT=(); fi
_git_bytes=$("${_TIMEOUT[@]}" git -C "$current_dir" status --porcelain 2>/dev/null | wc -c | tr -d ' ')
Verified end to end on main @ 5e2f2e8, macOS 27.0, /bin/bash 3.2.57: two copies of the file differing only in that line, the same 60-file dirty repo as current_dir, the startup payload above. startup_tokens reads 61129 unpatched and 61383 with the guard — a difference of exactly 254, the contribution the line is supposed to make. The empty-array expansion is safe here: the file sets only set -o pipefail at :8, not set -u.
What this does not do is give macOS the bound itself. It restores the value and keeps the timeout wherever one exists; a genuinely portable bound means backgrounding git and polling, which is more machinery than this line probably deserves. Happy to send it as a PR if that is useful.
Worth noting for the other direction: on Linux, where timeout exists, this line runs a real git status --porcelain on every startup tick that macOS silently skips.
Before submitting
Version
LifeOS 7.40.4 (latest release, 2026-08-14) — component
LIFEOS/LIFEOS_StatusLine.sh; repro run againstmain@5e2f2e8, which carries the same file.What is broken
The startup context estimate asks git how large the working tree's status block will be, and bounds that call with
timeout 1. macOS ships notimeout(1)— it is a GNU coreutils program, absent from a stock install and from the Xcode command line tools. On a Mac the command therefore fails before git runs, its error is discarded by the2>/dev/nullalready on the line, and the empty output falls throughwc -cas0. Two things follow. The git contribution to the pre-first-API context estimate is always zero whatever the state of the working tree, so STARTUP LOAD under-reports by about a token per three and a half bytes ofgit status --porcelainoutput. And the bound itself does not exist on macOS: on a repository wheregit statusis genuinely slow there is nothing stopping it from stalling the render, which is the case thetimeoutwas presumably written for. The branch is reached on the pre-first-API ticks only, gated at:400by[ "$context_pct" = "0" ] && [ "$total_input" -eq 0 ], so the wrong figure is the one shown while a session is starting up. The same file already branches on platform forstatat:209-211, so it knows it runs on both and this looks like an oversight rather than a GNU-only choice.Where (file:line)
LifeOS/install/LIFEOS/LIFEOS_StatusLine.sh:447(writer; consumer is:448,timeoutappears nowhere else in the file)Repro on a clean tree
Negative control
Run on unpatched
main@5e2f2e8, macOS 27.0,/bin/bash3.2.57, stock PATH:The line reports zero bytes of git status for a tree that has 891 bytes of it, so line 448 adds 0 tokens where it should add 254. A three-file tree gives the same
_git_bytes=0against 26 real bytes, so the result is zero independent of the tree rather than a rounding artefact. Running the whole unpatched script against that same 60-file repo with a startup payload (used_percentage: 0,total_input_tokens: 0) and readingstartup_tokensback out of/tmp/pai-startup-estimate-<session_id>.shgives a figure that is 254 lower than the same script with a working_git_bytes; the absolute total there depends on the reader's own install, the 254 does not.Suggested fix
Built and run against the clean tree, not a sketch. Use the wrapper when one exists and run bare when neither does, so the value survives either way:
Verified end to end on
main@5e2f2e8, macOS 27.0,/bin/bash3.2.57: two copies of the file differing only in that line, the same 60-file dirty repo ascurrent_dir, the startup payload above.startup_tokensreads61129unpatched and61383with the guard — a difference of exactly 254, the contribution the line is supposed to make. The empty-array expansion is safe here: the file sets onlyset -o pipefailat:8, notset -u.What this does not do is give macOS the bound itself. It restores the value and keeps the timeout wherever one exists; a genuinely portable bound means backgrounding git and polling, which is more machinery than this line probably deserves. Happy to send it as a PR if that is useful.
Worth noting for the other direction: on Linux, where
timeoutexists, this line runs a realgit status --porcelainon every startup tick that macOS silently skips.Before submitting