danielmiessler / danielmiessler/LifeOS
Doctor.ts hook-interpreter false positive still reproduces on 7.40.4 / main (follow-up to #1856)
- Dominant language
- TypeScript
- Stars
- 19k
- Forks
- 2.5k
- Avg merge
- 8d 17h
- Merged PRs (30d)
- 1
Description
### Version
LifeOS 7.40.4 (`main` @ 5e2f2e8c) / Doctor
### What is broken
`bun LIFEOS/TOOLS/Doctor.ts --hooks` reports a hook as unable to start when its command names an interpreter by absolute path with the script as an argument, e.g. `/Users/you/.bun/bin/bun /Users/you/.claude/hooks/Example.hook.ts`. The first token is a path, so it takes the bare-script branch and gets the exec-bit + shebang test applied to it. Reading the first line of the `bun` binary finds no `#!`, and the hook is reported as broken. The hook runs fine. In the default table this surfaces as `Hook interpreter resolution — broken`, one entry in the capability set that the statusline counts as a regression.
This is the same category error as #1856, which was closed 2026-08-17 with "fixed in source". I think that fix simply has not reached the public tree yet: the most recent release is v7.40.4 from 2026-08-14, three days before that close, and no release has been cut since. Filing so it is not lost between releases rather than to reopen a settled question.
### Where (file:line)
`LIFEOS/TOOLS/Doctor.ts:622` — the `if (!/[/\\]/.test(first))` branch treats any first token containing a separator as a script; the shebang test it falls through to is at `:635`. Same file in the repo at `LifeOS/install/LIFEOS/TOOLS/Doctor.ts`.
### Repro on a clean tree
```shell
# Clean config root, nothing personal in it. Doctor honours CLAUDE_CONFIG_DIR (Doctor.ts:46).
R=$(mktemp -d); mkdir -p "$R/hooks"
BUN=$(command -v bun)
printf '#!/usr/bin/env bun\nconsole.log("hook ran");\n' > "$R/hooks/Example.hook.ts"
chmod +x "$R/hooks/Example.hook.ts"
# The hook itself starts and runs:
"$BUN" "$R/hooks/Example.hook.ts" # -> hook ran
# Registered with an absolute interpreter path:
cat > "$R/settings.json" < hook interpreters: 1 hook(s) cannot start —
# -> x bun: no #! shebang
# Positive control: same hook, registered bare.
cat > "$R/settings.json" < hook interpreters: every registered hook resolves
```
### Negative control
On unpatched 7.40.4 the two registrations above differ: the absolute-interpreter form reports `1 hook(s) cannot start — bun: no #! shebang`, while the identical hook registered bare reports `every registered hook resolves`. The only variable is whether an interpreter prefixes the script, and the hook prints `hook ran` under both. So the check is red on a hook that starts, and green on the same hook, which is what identifies the probe rather than the hook as the defect.
Verified against the current public tree, not a local patch: the installed `LIFEOS/TOOLS/Doctor.ts` is byte-identical (`diff` clean, 882 lines) to `origin/main:LifeOS/install/LIFEOS/TOOLS/Doctor.ts` at 5e2f2e8c. Over full history that file has been touched by three commits only, the 7.1.1, 7.28.3 and 7.40.4 release commits, the newest being 2026-08-14.
### Suggested fix
Untested, and #1856 describes the same shape. When the command has more than one token, treat the first as an interpreter: check existence and the exec bit, then apply the shebang test to the script argument instead. Keep the current test for bare invocations. A cheap guard for the ELF/Mach-O case alone would be to skip the shebang test when the resolved first token is not a text file.
### How I checked the gap is real
Four checks, before filing:
1. `git ls-remote origin refs/heads/main` matches the local `origin/main` at 5e2f2e8c, and upstream has four branches, the other three being a readme branch and two GitHub Actions branches. So this is the current public code.
2. `gh release list` shows v7.40.4 (2026-08-14) as the latest release, with nothing newer.
3. The clone was shallow on the first pass, which made any "no commit fixed this" claim unearned, so I ran `git fetch --unshallow` and re-checked. Over full history `Doctor.ts` has three commits, all release commits, newest 2026-08-14.
4. `diff` of the installed file against `origin/main:LifeOS/install/LIFEOS/TOOLS/Doctor.ts` is clean at 882 lines, so the repro above is not running against a modified install.
Worth saying plainly: #1856 closed three days after the 7.40.4 release and no release has been cut since, so "unreleased" fits the evidence better than "lost".
Contributor guide
No contributing guide indexed for this repository
Research direction
Read LIFEOS/TOOLS/Doctor.ts around lines 622 and 635, and compare it with LifeOS/install/LIFEOS/TOOLS/Doctor.ts. Run the clean-tree reproduction with CLAUDE_CONFIG_DIR and Doctor.ts --hooks, then verify that absolute-interpreter commands resolve successfully while bare invocations retain their current behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- bun, typescript
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 72/100