11# Knowledge Graph FUSE Driver
22
3- Mount the knowledge graph as a filesystem.
3+ Mount the knowledge graph as a filesystem. Browse ontologies, search concepts by creating directories, read documents — all through your file manager or terminal.
44
55## Installation
66
@@ -13,7 +13,7 @@ sudo apt install fuse3 # Debian/Ubuntu
1313sudo dnf install fuse3 # Fedora
1414```
1515
16- ** kg CLI** (for OAuth setup):
16+ ** kg CLI** (for authentication setup):
1717``` bash
1818npm install -g @aaronsb/kg-cli
1919```
@@ -24,89 +24,173 @@ npm install -g @aaronsb/kg-cli
2424pipx install kg-fuse
2525```
2626
27- ### Upgrade
27+ ## Quick Start
2828
2929``` bash
30- pipx upgrade kg-fuse
30+ # 1. Authenticate with the knowledge graph
31+ kg login
32+ kg oauth create
33+
34+ # 2. Set up a FUSE mount (interactive — detects auth, validates path, offers autostart)
35+ kg-fuse init /mnt/knowledge
36+
37+ # 3. Mount
38+ kg-fuse mount
3139```
3240
33- ## Setup
41+ That's it. Browse ` /mnt/knowledge/ ` in your file manager or terminal.
3442
35- Create OAuth credentials (one-time):
43+ ## Commands
3644
37- ``` bash
38- kg oauth create --for fuse
45+ ```
46+ kg-fuse Status of running mounts + help summary
47+ kg-fuse init [mountpoint] Interactive setup: detect auth, configure mount, offer autostart
48+ kg-fuse mount Fork daemons for ALL configured mounts
49+ kg-fuse mount /mnt/knowledge Fork daemon for just this one
50+ kg-fuse mount /mnt/knowledge -f Run in foreground (for debugging)
51+ kg-fuse unmount Kill all kg-fuse daemons, clean unmount
52+ kg-fuse unmount /mnt/knowledge Kill just this one
53+ kg-fuse status Same as bare kg-fuse
54+ kg-fuse config Show configuration with masked secrets
55+ kg-fuse repair Detect and fix orphaned mounts, stale PIDs, bad config
56+ kg-fuse update Self-update via pipx
3957```
4058
41- This writes credentials to ` ~/.config/ kg-fuse/config.toml ` .
59+ Bare ` kg-fuse ` with no arguments shows mount status, daemon process info, API connectivity, and other FUSE mounts on the system .
4260
43- ## Usage
61+ ## Configuration
4462
45- ``` bash
46- # Mount (reads credentials from config)
47- kg-fuse /mnt/knowledge
63+ ### File layout
4864
49- # Or run in foreground for debugging
50- kg-fuse /mnt/knowledge -f
51- ```
65+ | File | Owner | Purpose |
66+ | ------| -------| ---------|
67+ | ` ~/.config/kg/config.json ` | kg CLI | Auth credentials, API URL (kg-fuse reads only) |
68+ | ` ~/.config/kg/fuse.json ` | kg-fuse | Mount definitions, per-mount preferences |
69+ | ` ~/.local/share/kg-fuse/mounts/<id>/queries.toml ` | kg-fuse | Saved query directories per mount |
70+ | ` ~/.local/state/kg-fuse/<id>.pid ` | kg-fuse | Daemon PID files |
5271
53- Unmount:
72+ kg-fuse ** never writes ** to kg CLI's ` config.json ` — it only reads auth credentials from it. This isolates failures: a bug in kg-fuse can only damage ` fuse.json ` , never your kg CLI config.
5473
55- ``` bash
56- fusermount -u /mnt/knowledge
57- # or just Ctrl+C if running in foreground
58- ```
74+ ### Credential resolution
5975
60- ### Manual Credentials
76+ Priority (highest to lowest):
77+ 1 . CLI flags (` --client-id ` , ` --client-secret ` )
78+ 2 . ` fuse.json ` ` auth_client_id ` → lookup in ` config.json ` auth
79+ 3 . ` config.json ` auth section directly
80+ 4 . Error with guidance to run ` kg login ` + ` kg oauth create `
6181
62- You can also pass credentials directly:
82+ ### Example fuse.json
6383
64- ``` bash
65- kg-fuse /mnt/knowledge \
66- --api-url https://kg.example.com/api \
67- --client-id YOUR_CLIENT_ID \
68- --client-secret YOUR_SECRET
84+ ``` json
85+ {
86+ "auth_client_id" : " kg-cli-admin-ba93368c" ,
87+ "mounts" : {
88+ "/mnt/knowledge" : {
89+ "tags" : { "enabled" : true , "threshold" : 0.5 },
90+ "cache" : { "epoch_check_interval" : 5.0 , "content_cache_max" : 52428800 },
91+ "jobs" : { "hide_jobs" : false }
92+ }
93+ }
94+ }
6995```
7096
7197## Filesystem Structure
7298
7399```
74100/mnt/knowledge/
75- ├── ontology-a/ # Each ontology is a directory
76- │ ├── doc1.md # Documents in that ontology
77- │ └── doc2.md
78- └── ontology-b/
79- └── doc3.md
101+ ├── ontology/ # System-managed ontology listing
102+ │ ├── ontology-a/
103+ │ │ ├── documents/ # Source documents (read-only, write to ingest)
104+ │ │ │ ├── doc1.md
105+ │ │ │ └── image.png
106+ │ │ └── my-query/ # User query scoped to this ontology
107+ │ │ ├── concept1.concept.md
108+ │ │ ├── concept2.concept.md
109+ │ │ ├── images/ # Image evidence from matching concepts
110+ │ │ └── .meta/ # Query control plane
111+ │ └── ontology-b/
112+ │ └── documents/
113+ └── my-global-query/ # User query across all ontologies
114+ └── *.concept.md
115+ ```
116+
117+ ### Query directories
118+
119+ Create a directory → it becomes a semantic search:
120+
121+ ``` bash
122+ mkdir /mnt/knowledge/ontology/my-ontology/leadership
123+ ls /mnt/knowledge/ontology/my-ontology/leadership/
124+ # → concept files matching "leadership" within that ontology
125+
126+ mkdir /mnt/knowledge/machine-learning
127+ ls /mnt/knowledge/machine-learning/
128+ # → concept files matching "machine learning" across all ontologies
80129```
81130
82- ### Read: Browse Documents
131+ ### Query control plane (.meta)
132+
133+ Each query directory has a ` .meta/ ` subdirectory for tuning:
83134
84135``` bash
85- ls /mnt/knowledge/ # List ontologies
86- ls /mnt/knowledge/my-ontology/ # List documents
87- cat /mnt/knowledge/my-ontology/doc.md # Read document
136+ cat .meta/threshold # Read current threshold (0.0-1.0)
137+ echo 0.3 > .meta/threshold # Lower threshold for broader matches
138+ echo 100 > .meta/limit # Increase result limit
139+ echo " noise" >> .meta/exclude # Filter out a term
140+ echo " AI" >> .meta/union # Broaden with additional term
88141```
89142
90- ### Write: Ingest Documents (future)
143+ ### Write: Ingest documents
144+
145+ ``` bash
146+ cp report.pdf /mnt/knowledge/ontology/my-ontology/documents/
147+ # File enters the ingestion pipeline → extracts concepts → links to graph
148+ ```
149+
150+ ## Autostart
151+
152+ ` kg-fuse init ` offers to set up autostart:
91153
154+ - ** Systemd** (preferred): installs a user service at ` ~/.config/systemd/user/kg-fuse.service `
155+ - ** Shell RC** (fallback): adds ` kg-fuse mount ` to ` .bash_profile ` , ` .zshrc ` , or fish config
156+
157+ Manage systemd service:
92158``` bash
93- cp report.pdf /mnt/knowledge/my-ontology/
94- # File "disappears" into ingestion pipeline
95- # Creates job, extracts concepts, links to graph
159+ systemctl --user status kg-fuse
160+ systemctl --user restart kg-fuse
161+ journalctl --user -u kg-fuse -f
96162```
97163
164+ ## Safety
165+
166+ kg-fuse includes several safety checks:
167+
168+ - ** Mountpoint validation** : refuses system paths (` /home ` , ` /etc ` , etc.) and non-empty directories
169+ - ** FUSE collision detection** : checks for existing FUSE mounts (rclone, SSHFS, etc.) at the target path
170+ - ** Config isolation** : kg-fuse writes only to ` fuse.json ` , never to kg CLI's ` config.json `
171+ - ** Atomic config writes** : ` fuse.json ` updates use temp file + rename for crash safety
172+ - ** PID verification** : before killing a daemon, verifies it's actually a kg-fuse process via ` /proc/cmdline `
173+ - ** Orphan recovery** : ` kg-fuse repair ` detects dead mounts ("transport endpoint not connected") and cleans up
174+ - ** RC file safety** : shell config changes use delimited blocks with backups
175+
98176## Debug Mode
99177
100178``` bash
101- kg-fuse /mnt/knowledge --debug -f
179+ kg-fuse mount /mnt/knowledge -f --debug
180+ ```
181+
182+ Runs in foreground with verbose logging. Daemon logs are also available at:
183+ ```
184+ ~/.local/share/kg-fuse/mounts/<mount-id>/daemon.log
102185```
103186
104187## Architecture
105188
106- The FUSE driver is an independent client that:
107- - Authenticates via OAuth (like CLI, MCP server)
108- - Makes HTTP requests to the API server
109- - Caches directory listings (30s TTL)
110- - Defaults to ` localhost:8000 ` if unconfigured (fail-safe: won't accidentally query external endpoints)
189+ The FUSE driver is an independent Python client that:
190+ - Authenticates via OAuth (shared credentials with kg CLI)
191+ - Makes HTTP requests to the knowledge graph API
192+ - Uses epoch-gated caching for directory listings (background refresh, not fixed TTL)
193+ - Persists user query directories in client-side TOML files
194+ - Runs as a daemonized process per mount point
111195
112- See ADR-069 for full design rationale.
196+ See [ ADR-069] ( ../docs/architecture/ADR-069-fuse-filesystem-driver.md ) for design rationale.
0 commit comments