#2152·LifeOS

Doctor's fabric probe checks `which('fabric')`, but Homebrew installs it as `fabric-ai` — a correct install reports broken, and the fix hint steers to the wrong package

Author: NAmorimCreated Sep 18, 2026Updated Sep 18, 2026

Version

LifeOS 7.40.4 / LIFEOS/TOOLS/Doctor.ts (lines 527–537)

What is broken

The fabric capability probes which('fabric'). Homebrew installs danielmiessler/fabric as fabric-ai, because the fabric formula is already taken by the unrelated Python SSH tool (fabfile.org).

$ brew info fabric
==> fabric: stable 3.2.3 (bottled), HEAD
Library and command-line tool for SSH
https://www.fabfile.org/

$ brew info fabric-ai
==> fabric-ai: stable 1.4.478 (bottled), HEAD
Open-source framework for augmenting humans using AI
https://github.com/danielmiessler/fabric

So brew install fabric-ai produces a fully working install that Doctor reports as broken:

$ which fabric-ai
/opt/homebrew/bin/fabric-ai
$ which fabric
(nothing)

❌ Prompt patterns (fabric) — broken
   fabric not on PATH — pattern runs fall back to native prompting
   fix: see the fabric project for install

This is the inverse of #2066 (which found which() producing false positives on broken binaries). Same function, opposite failure: a false negative on a correct install.

Why the fix hint makes it worse

fixCmd is see the fabric project for install. A user who follows that, finds the project is called "fabric", and types the obvious command installs the Python SSH tool — a 3.2.3 package with nothing to do with prompts. The capability stays broken, and now there is a fabric binary on PATH that Doctor reports as live while every -y call fails. That second state is strictly worse than the first, and it is the state the hint steers toward.

The detail string is also inaccurate

fabric not on PATH — pattern runs fall back to native prompting

and powers claims the binary provides "the Fabric skill's pattern library". Neither holds. skills/Fabric/SKILL.md:37 is explicit:

Patterns run natively — LifeOS reads the pattern's system.md and applies it directly, no CLI round-trip. The fabric CLI is only used for YouTube transcripts (-y) and URL fallback (-u).

All 237 patterns ship in skills/Fabric/Patterns/ and work with no binary at all. Native execution is the primary path, not a fallback. So the real cost of a missing binary is -y and -u only — which makes the capability sound much more broken than it is, and buries the one thing actually lost.

Proposed fix

diff
+    // Homebrew ships danielmiessler/fabric as `fabric-ai`, because the `fabric`
+    // formula is the unrelated Python SSH tool. Accept either name.
+    // Patterns run natively from skills/Fabric/Patterns either way — the binary
+    // is needed only for YouTube transcripts (-y) and URL fallback (-u).
-    probeOffline: async () =>
-      which('fabric')
-        ? { ok: true, detail: 'fabric on PATH' }
-        : { ok: false, detail: 'fabric not on PATH — pattern runs fall back to native prompting' },
-    fixCmd: 'see the fabric project for install',
+    probeOffline: async () => {
+      const found = ['fabric', 'fabric-ai'].find((b) => which(b));
+      return found
+        ? { ok: true, detail: `${found} on PATH` }
+        : { ok: false, detail: 'fabric not on PATH — patterns still run natively; -y/-u unavailable' };
+    },
+    fixCmd: 'brew install fabric-ai   (NOT `fabric` — that is the Python SSH tool)',

Accepting both names also covers users who installed from source or added their own fabric alias, so it does not trade one narrow assumption for another.

Verification

fabric-ai 1.4.478 on macOS arm64. After the change Doctor reports the capability live, and the feature it gates works:

$ fabric -y "https://www.youtube.com/watch?v=aircAruvnKk" --transcript | wc -c
   18536

One setup note worth adding to the Fabric skill separately: the binary exits 0 but prints nothing until ~/.config/fabric/.env exists. An empty file is enough for -y; no vendor key is required for transcripts.