ReferenceCheck.ts finds 223 missing references in the shipped payload, has no invoker, and its orphan detection inspects one file
Structured for machine parsing: claims are atomic, each carries the command that verifies it. Every command runs against a fresh clone of this repo — none depend on my machine, my install, or my configuration. Reproduction at the bottom.
Summary
LIFEOS/TOOLS/ReferenceCheck.ts is a full-surface reference validator. Run unmodified against the shipped payload it reports 223 missing references in 231ms. Nothing invokes it — no hook, no command, no CI job. Its orphan mode reports 0 on every run because the check inspects exactly one file out of 1,324.
This is the same shape as #1539: the diagnostic exists, it is correct, and nothing asks it anything.
Claims and verification
$PAYLOAD below means the release payload staged in the shape it ships as. ReferenceCheck resolves its root as $HOME/.claude, so:
git clone --depth 1 https://github.com/danielmiessler/LifeOS && cd LifeOS
mkdir -p /tmp/rc && cp -R LifeOS/install /tmp/rc/.claude
B1 — the shipped payload contains 223 missing references.
cd /tmp/rc/.claude/LIFEOS/TOOLS && HOME=/tmp/rc bun ReferenceCheck.ts --quiet | tail -1
# ReferenceCheck: 1174 files, 1558 refs, 223 missing, 0 stale, 0 orphan — 231ms
B2 — roughly half are legitimate; the rest are not. Classification of the 223:
| Class |
Count |
Defect? |
Runtime-created state and logs (MEMORY/STATE, OBSERVABILITY, DATA, LEARNING, RESEARCH) |
90 |
No — created on first use |
USER/ tree |
28 |
No — populated at interview |
| References to private skills not in the release |
35 |
Yes |
References to dated MEMORY/WORK/<slug>/ISA.md artifacts |
13 |
Yes |
| Other |
57 |
Mixed |
grep -cE 'skills/_[A-Z]' /tmp/out.txt # 35
grep -cE 'MEMORY/WORK/' /tmp/out.txt # 13
grep -cE 'MEMORY/(STATE|OBSERVABILITY|DATA|LEARNING|RESEARCH)/' /tmp/out.txt # 90
grep -cE 'USER/' /tmp/out.txt # 28
(where /tmp/out.txt is the → lines from B1)
The 35 resolve to seven private skills: _HOMESECURITY, _INCIDENT_RESPONSE, _LIFEOS, _NETWORK, _ULWORK, _WRITING, _X.
This is why the check cannot gate as-is. ~118 of 223 are expected. A gate on the raw count would be more than half false positives, and a gate that cries wolf gets disabled. An ignore-list for runtime-created paths is a prerequisite for making this blocking — noted in the PR.
B3 — nothing invokes ReferenceCheck.
grep -rl 'ReferenceCheck' --include='*.json' --include='*.sh' --include='*.yml' --include='*.ts' LifeOS/install | grep -v 'ReferenceCheck.ts'
# LifeOS/install/LIFEOS/TOOLS/IntegrityCheck.ts (itself never invoked — see B6)
B4 — orphan detection inspects one file. ReferenceCheck.ts:616:
const isLifeosTopMd = /^LifeOS\/[^/]+\.md$/.test(rel);
if (!isLifeosTopMd) continue;
Two independent faults:
Case. The directory is LIFEOS/. Paths resolve as LIFEOS/LIFEOS_SYSTEM_PROMPT.md, which fails ^LifeOS/. Likely unfollowed from the PAI→LifeOS rename.
ls /tmp/rc/.claude | grep -x 'LifeOS' ; echo "exit $?" # no match
Scope. Corrected to ^LIFEOS/, the pattern still matches only top-level .md:
ls /tmp/rc/.claude/LIFEOS/*.md | wc -l # 1
find /tmp/rc/.claude -type f \( -name '*.md' -o -name '*.ts' \) | wc -l # 1324
Maximum possible coverage is 1 file of 1,324, and that one file is referenced — so the check reports 0 whether or not the case is fixed. I verified this: patching only the case leaves the count at 0.
B5 — I tried the obvious fix and it isn't sufficient. Widening scope to LIFEOS/TOOLS/*.ts yields 102 orphans, but many are user-facing CLI tools that are supposed to be unreferenced (they're run by hand). The orphan class needs a definition distinguishing "nothing invokes this" from "a human invokes this," which is a design question rather than a one-line change. I'm reporting this rather than proposing a patch, because the naive version would be correctly rejected.
Two entries in that 102 are genuine and load-bearing: IntegrityCheck.ts and ReferenceCheck.ts itself.
B6 — IntegrityCheck.ts orchestrates this tool and is itself uninvoked. It shells ReferenceCheck.ts --json --stale --orphans (line 118) and documents /ic as its entry point. The payload ships no such command:
ls LifeOS/install/commands/
# context-search.md cs.md pu.md
The SessionEnd hook hooks/IntegrityCheck.hook.ts shares its name but never references it — it imports TranscriptParser and shells BudgetCheck.ts.
Because orphan mode returns 0, IntegrityCheck.ts would consume that as a pass if it ever ran. That makes the current state a false-negative generator on the class rather than merely an absent check.
B7 — Actions is configured; nothing validates the shipped tree.
ls .github/workflows/
# claude-code-review.yml claude.yml
claude.yml triggers on issue_comment, issues, pull_request_review, pull_request_review_comment. claude-code-review.yml triggers on pull_request. Both are anthropics/claude-code-action. Neither runs on push, release, or tag, and neither runs the validator.
Why this is worth a gate rather than a fix
The individual references matter less than the fact that nothing checks them. Three majors shipped in the ten weeks to July (v5.0.0 → v6.0.0 → v7.0.0), so a fix to any specific reference in 7.1.1 is obsolete before it lands. A check that runs against whatever ships next is not.
The cost of the current state falls on the project rather than on users individually: a defect discovered only after install is patched locally, which makes that user's instance diverge from the release, which makes their subsequent bug reports unreproducible — removing from the diagnostic pool exactly the people motivated enough to investigate. LifeOS's proposition is deterministic, spec-governed behaviour; unvalidated releases produce a population of individually-repaired installs, which is the opposite.
PR
#1542 adds a report-only workflow: stage LifeOS/install as $HOME/.claude, run ReferenceCheck.ts --quiet, print the summary line to the job summary. No source change, continue-on-error, does not gate. It exists to make the number visible on every PR touching the payload.
Flipping it to blocking needs the ignore-list from B2 first. Happy to do that as a follow-up if you want it.
Reproduction
git clone --depth 1 https://github.com/danielmiessler/LifeOS && cd LifeOS
mkdir -p /tmp/rc && cp -R LifeOS/install /tmp/rc/.claude
cd /tmp/rc/.claude/LIFEOS/TOOLS && HOME=/tmp/rc bun ReferenceCheck.ts --quiet | tail -1
Scope
Verified against a fresh clone at 4e33cc8. All claims are properties of the repo tree. My own install reports 316 rather than 223 because it contains my files as well; the 223 figure is payload-only and is the one that reproduces for anyone.
ReferenceCheck.ts finds 223 missing references in the shipped payload, has no invoker, and its orphan detection inspects one file
Summary
LIFEOS/TOOLS/ReferenceCheck.tsis a full-surface reference validator. Run unmodified against the shipped payload it reports 223 missing references in 231ms. Nothing invokes it — no hook, no command, no CI job. Its orphan mode reports 0 on every run because the check inspects exactly one file out of 1,324.This is the same shape as #1539: the diagnostic exists, it is correct, and nothing asks it anything.
Claims and verification
$PAYLOADbelow means the release payload staged in the shape it ships as.ReferenceCheckresolves its root as$HOME/.claude, so:B1 — the shipped payload contains 223 missing references.
B2 — roughly half are legitimate; the rest are not. Classification of the 223:
MEMORY/STATE,OBSERVABILITY,DATA,LEARNING,RESEARCH)USER/treeMEMORY/WORK/<slug>/ISA.mdartifacts(where
/tmp/out.txtis the→lines from B1)The 35 resolve to seven private skills:
_HOMESECURITY,_INCIDENT_RESPONSE,_LIFEOS,_NETWORK,_ULWORK,_WRITING,_X.This is why the check cannot gate as-is. ~118 of 223 are expected. A gate on the raw count would be more than half false positives, and a gate that cries wolf gets disabled. An ignore-list for runtime-created paths is a prerequisite for making this blocking — noted in the PR.
B3 — nothing invokes ReferenceCheck.
B4 — orphan detection inspects one file.
ReferenceCheck.ts:616:Two independent faults:
Case. The directory is
LIFEOS/. Paths resolve asLIFEOS/LIFEOS_SYSTEM_PROMPT.md, which fails^LifeOS/. Likely unfollowed from the PAI→LifeOS rename.Scope. Corrected to
^LIFEOS/, the pattern still matches only top-level.md:Maximum possible coverage is 1 file of 1,324, and that one file is referenced — so the check reports 0 whether or not the case is fixed. I verified this: patching only the case leaves the count at 0.
B5 — I tried the obvious fix and it isn't sufficient. Widening scope to
LIFEOS/TOOLS/*.tsyields 102 orphans, but many are user-facing CLI tools that are supposed to be unreferenced (they're run by hand). The orphan class needs a definition distinguishing "nothing invokes this" from "a human invokes this," which is a design question rather than a one-line change. I'm reporting this rather than proposing a patch, because the naive version would be correctly rejected.Two entries in that 102 are genuine and load-bearing:
IntegrityCheck.tsandReferenceCheck.tsitself.B6 —
IntegrityCheck.tsorchestrates this tool and is itself uninvoked. It shellsReferenceCheck.ts --json --stale --orphans(line 118) and documents/icas its entry point. The payload ships no such command:ls LifeOS/install/commands/ # context-search.md cs.md pu.mdThe SessionEnd hook
hooks/IntegrityCheck.hook.tsshares its name but never references it — it importsTranscriptParserand shellsBudgetCheck.ts.Because orphan mode returns 0,
IntegrityCheck.tswould consume that as a pass if it ever ran. That makes the current state a false-negative generator on the class rather than merely an absent check.B7 — Actions is configured; nothing validates the shipped tree.
ls .github/workflows/ # claude-code-review.yml claude.ymlclaude.ymltriggers onissue_comment,issues,pull_request_review,pull_request_review_comment.claude-code-review.ymltriggers onpull_request. Both areanthropics/claude-code-action. Neither runs on push, release, or tag, and neither runs the validator.Why this is worth a gate rather than a fix
The individual references matter less than the fact that nothing checks them. Three majors shipped in the ten weeks to July (v5.0.0 → v6.0.0 → v7.0.0), so a fix to any specific reference in 7.1.1 is obsolete before it lands. A check that runs against whatever ships next is not.
The cost of the current state falls on the project rather than on users individually: a defect discovered only after install is patched locally, which makes that user's instance diverge from the release, which makes their subsequent bug reports unreproducible — removing from the diagnostic pool exactly the people motivated enough to investigate. LifeOS's proposition is deterministic, spec-governed behaviour; unvalidated releases produce a population of individually-repaired installs, which is the opposite.
PR
#1542 adds a report-only workflow: stage
LifeOS/installas$HOME/.claude, runReferenceCheck.ts --quiet, print the summary line to the job summary. No source change,continue-on-error, does not gate. It exists to make the number visible on every PR touching the payload.Flipping it to blocking needs the ignore-list from B2 first. Happy to do that as a follow-up if you want it.
Reproduction
Scope
Verified against a fresh clone at
4e33cc8. All claims are properties of the repo tree. My own install reports 316 rather than 223 because it contains my files as well; the 223 figure is payload-only and is the one that reproduces for anyone.