|
| 1 | +# Developer Guide: Running, Debugging, and Resetting InferNode |
| 2 | + |
| 3 | +This guide covers running InferNode from the command line for development, |
| 4 | +debugging, and testing. For building from source, see QUICKSTART.md. For |
| 5 | +the testing framework, see the Testing System section in CLAUDE.md. |
| 6 | + |
| 7 | +## Running from the Command Line |
| 8 | + |
| 9 | +### Minimal Startup (Interpreter Only, No GUI) |
| 10 | + |
| 11 | +```sh |
| 12 | +cd infernode |
| 13 | +./emu/MacOSX/o.emu -r. sh -l |
| 14 | +``` |
| 15 | + |
| 16 | +This starts the Inferno shell with your profile loaded (`-l`). You get a |
| 17 | +text console — no GUI, no agent, no LLM. |
| 18 | + |
| 19 | +### Full GUI Startup |
| 20 | + |
| 21 | +```sh |
| 22 | +cd infernode/emu/MacOSX |
| 23 | +./o.emu -c1 -pheap=1024m -pmain=1024m -pimage=1024m -r../.. \ |
| 24 | + sh -l -c "wm/logon; \ |
| 25 | + llmsrv &; sleep 1; \ |
| 26 | + /dis/veltro/wallet9p.dis &; sleep 1; \ |
| 27 | + luciuisrv; \ |
| 28 | + echo activity create Main > /n/ui/ctl; sleep 1; \ |
| 29 | + /dis/veltro/tools9p -v -m /tool \ |
| 30 | + -b read,list,find,search,grep,write,edit,editor,exec,launch,spawn,diff,json,fractal,webfetch,git,say,memory,todo,plan,websearch,mail,keyring,present,gap \ |
| 31 | + -p /dis/wm read list find present say hear task memory gap keyring editor shell; \ |
| 32 | + lucibridge -a 0 -v -s &; sleep 1; \ |
| 33 | + echo 'create id=tasks type=taskboard label=Tasks' > /n/ui/activity/0/presentation/ctl; \ |
| 34 | + lucifer" |
| 35 | +``` |
| 36 | + |
| 37 | +This is equivalent to what the app bundle does via `lib/sh/profile` and |
| 38 | +`lib/lucifer/boot.sh`, but laid out explicitly so you can see and modify |
| 39 | +each step. |
| 40 | + |
| 41 | +### Breaking Down the Command |
| 42 | + |
| 43 | +**Emulator flags:** |
| 44 | + |
| 45 | +| Flag | Purpose | |
| 46 | +|------|---------| |
| 47 | +| `-c1` | Enable JIT compilation (ARM64 or AMD64). Use `-c0` for interpreter only. | |
| 48 | +| `-pheap=1024m` | Heap pool size (memory for Limbo allocations) | |
| 49 | +| `-pmain=1024m` | Main pool size (memory for kernel data structures) | |
| 50 | +| `-pimage=1024m` | Image pool size (memory for draw images/GUI) | |
| 51 | +| `-r../..` | Inferno root directory. Points to the project checkout. The path is concatenated directly to `-r` with no space. | |
| 52 | + |
| 53 | +**Boot sequence (inside `sh -l -c "..."`):** |
| 54 | + |
| 55 | +The `-l` flag loads `lib/sh/profile` which sets up networking, the host |
| 56 | +filesystem mount (`trfs`), the `~/.infernode` writable overlay, secstored, |
| 57 | +and factotum. Then `-c` runs the quoted command string: |
| 58 | + |
| 59 | +| Step | Command | Purpose | |
| 60 | +|------|---------|---------| |
| 61 | +| 1 | `wm/logon` | Login screen. Creates secstore account on first run, unlocks and loads keys on subsequent runs. Blocks until the user enters their password. | |
| 62 | +| 2 | `llmsrv &` | LLM 9P file server. Mounts at `/n/llm`. Reads config from `lib/ndb/llm` (via profile). The `&` backgrounds it. | |
| 63 | +| 3 | `wallet9p &` | Cryptocurrency wallet 9P server. Experimental. | |
| 64 | +| 4 | `luciuisrv` | UI 9P server. Creates the `/n/ui` namespace that lucifer, lucipres, luciconv, and lucibridge all communicate through. This is the hub. | |
| 65 | +| 5 | `echo activity create Main > /n/ui/ctl` | Creates the default "Main" activity (task/conversation). | |
| 66 | +| 6 | `tools9p -v -m /tool -b ... -p ...` | Veltro tool server. `-b` lists built-in tool modules. `-p` lists tools available to the agent as "passive" (invocable). Mounts at `/tool`. | |
| 67 | +| 7 | `lucibridge -a 0 -v -s &` | Agent bridge. Connects the conversation zone to the LLM. `-a 0` targets activity 0, `-v` verbose, `-s` enables speech. | |
| 68 | +| 8 | `echo 'create id=tasks ...' > /n/ui/...` | Creates the Tasks taskboard tab in the presentation zone. | |
| 69 | +| 9 | `lucifer` | Main GUI. Blocks until the user exits. When lucifer returns, emu shuts down. | |
| 70 | + |
| 71 | +**Important:** Commands are separated by `;` not `&&`. The Inferno shell |
| 72 | +is rc-style and does not support `&&` or `||` operators. |
| 73 | + |
| 74 | +### Capturing Logs |
| 75 | + |
| 76 | +The app bundle suppresses stderr. To see diagnostic output: |
| 77 | + |
| 78 | +```sh |
| 79 | +/path/to/InferNode.app/Contents/MacOS/InferNode 2>/tmp/infernode.log |
| 80 | +``` |
| 81 | + |
| 82 | +Or from a dev checkout: |
| 83 | + |
| 84 | +```sh |
| 85 | +cd infernode/emu/MacOSX |
| 86 | +./o.emu -c1 -pheap=1024m -pmain=1024m -pimage=1024m -r../.. \ |
| 87 | + sh -l /lib/lucifer/boot.sh 2>/tmp/infernode.log |
| 88 | +``` |
| 89 | + |
| 90 | +Key log messages to look for: |
| 91 | + |
| 92 | +| Message | Meaning | |
| 93 | +|---------|---------| |
| 94 | +| `logon: loaded N keys from secstore` | Secstore unlocked successfully, N keys restored | |
| 95 | +| `logon: secstore has no factotum file` | No saved keys (first run or read failure) | |
| 96 | +| `factotum: secstore configured` | Save-back to secstore is active | |
| 97 | +| `lucibridge: ready` | Agent is connected and waiting for input | |
| 98 | +| `lucibridge: llm configured but not ready` | LLM service failed to start | |
| 99 | +| `tools9p: warning: cannot load tool X` | A tool's .dis file is missing (rebuild needed) | |
| 100 | + |
| 101 | +### Running Without the Agent |
| 102 | + |
| 103 | +To test the GUI without Veltro/LLM (useful for UI work): |
| 104 | + |
| 105 | +```sh |
| 106 | +cd infernode/emu/MacOSX |
| 107 | +./o.emu -c1 -pheap=1024m -pmain=1024m -pimage=1024m -r../.. \ |
| 108 | + sh -l -c "wm/logon; luciuisrv; echo activity create Main > /n/ui/ctl; sleep 1; lucifer" |
| 109 | +``` |
| 110 | + |
| 111 | +This starts logon, the UI server, and lucifer — but no llmsrv, no |
| 112 | +lucibridge, no tools9p. The conversation zone will be empty. |
| 113 | + |
| 114 | +## The ~/.infernode Directory |
| 115 | + |
| 116 | +InferNode stores all user data in `~/.infernode`, separate from the |
| 117 | +read-only emu root (whether that's an app bundle or a dev checkout). |
| 118 | +The profile creates this directory on first run and bind-mounts its |
| 119 | +subdirectories over the corresponding paths in the Inferno namespace. |
| 120 | + |
| 121 | +### Directory Structure |
| 122 | + |
| 123 | +``` |
| 124 | +~/.infernode/ |
| 125 | + usr/inferno/secstore/ # Encrypted key storage (PAK + factotum files) |
| 126 | + usr/inferno/tmp/ # Persistent temp files |
| 127 | + lib/ndb/ # LLM config (lib/ndb/llm) |
| 128 | + lib/lucifer/theme/ # GUI theme (current) |
| 129 | + lib/veltro/ # Agent state (welcome_shown, tour_offered, meta.txt) |
| 130 | + lib/veltro-agents/ # Task agent prompts |
| 131 | + lib/veltro-keys/ # Agent API keys |
| 132 | + tmp/ # Session temp files |
| 133 | +``` |
| 134 | + |
| 135 | +### How It Works |
| 136 | + |
| 137 | +The profile (`lib/sh/profile`) uses `bind -bc` to overlay each |
| 138 | +`~/.infernode` subdirectory onto the corresponding Inferno path: |
| 139 | + |
| 140 | +``` |
| 141 | +bind -bc ~/.infernode/usr/inferno/secstore /usr/inferno/secstore |
| 142 | +bind -bc ~/.infernode/lib/ndb /lib/ndb |
| 143 | +bind -bc ~/.infernode/lib/veltro /lib/veltro |
| 144 | +... |
| 145 | +``` |
| 146 | + |
| 147 | +The `-bc` flags mean: **b**efore (overlay takes priority over the |
| 148 | +original) and **c**reate (new files go to the overlay, not the original). |
| 149 | +This means writes always go to `~/.infernode` while reads fall through |
| 150 | +to the emu root for defaults. |
| 151 | + |
| 152 | +### Why It Exists |
| 153 | + |
| 154 | +Without the overlay, user data would be written into the emu root. |
| 155 | +In an app bundle, the emu root is inside the signed `.app` — read-only. |
| 156 | +Even in a dev checkout, mixing user data with source code is messy. |
| 157 | +The overlay keeps the emu root clean and user state portable. |
| 158 | + |
| 159 | +## Resetting |
| 160 | + |
| 161 | +### Reset the Guided Tour |
| 162 | + |
| 163 | +The tour is offered once per installation. To see it again: |
| 164 | + |
| 165 | +```sh |
| 166 | +rm ~/.infernode/lib/veltro/tour_offered |
| 167 | +``` |
| 168 | + |
| 169 | +On next launch, Veltro will offer the guided tour again. |
| 170 | + |
| 171 | +### Reset the Welcome Message |
| 172 | + |
| 173 | +```sh |
| 174 | +rm ~/.infernode/lib/veltro/welcome_shown |
| 175 | +``` |
| 176 | + |
| 177 | +### Full Reset (Start Fresh) |
| 178 | + |
| 179 | +**WARNING: This deletes your secstore password, all saved API keys, |
| 180 | +LLM configuration, theme, and agent state. You will need to set up |
| 181 | +everything from scratch on next launch.** |
| 182 | + |
| 183 | +```sh |
| 184 | +rm -rf ~/.infernode |
| 185 | +``` |
| 186 | + |
| 187 | +On next launch, the profile detects the missing directory, recreates |
| 188 | +it, seeds defaults, and the login screen shows the first-run setup. |
| 189 | + |
| 190 | +### Reset Only Secstore (Keep Config) |
| 191 | + |
| 192 | +To clear saved keys without wiping everything: |
| 193 | + |
| 194 | +```sh |
| 195 | +rm -rf ~/.infernode/usr/inferno/secstore |
| 196 | +``` |
| 197 | + |
| 198 | +On next launch, logon will show the first-run password setup. |
| 199 | + |
| 200 | +## Debugging Common Issues |
| 201 | + |
| 202 | +### "Launching..." Stuck on App Tab |
| 203 | + |
| 204 | +The app's .dis file may be stale (compiled against an old module |
| 205 | +interface). Rebuild: |
| 206 | + |
| 207 | +```sh |
| 208 | +export ROOT=$PWD PATH=$PWD/MacOSX/arm64/bin:$PATH |
| 209 | +cd appl/cmd && mk install # or the specific directory |
| 210 | +``` |
| 211 | + |
| 212 | +### Blank Conversation Zone / "LLM configured but not ready" |
| 213 | + |
| 214 | +llmsrv failed to start. Common causes: |
| 215 | + |
| 216 | +- **No API key:** Add one via Keyring, or set `ANTHROPIC_API_KEY` env var |
| 217 | +- **Wrong backend:** Check `~/.infernode/lib/ndb/llm` — `backend=openai` |
| 218 | + needs a URL like `http://127.0.0.1:11434/v1` (not `localhost`) |
| 219 | +- **Model doesn't support tools:** Use a tool-capable model (llama3.2, |
| 220 | + qwen2.5, mistral) — llama2 does not support tools and returns empty |
| 221 | + |
| 222 | +### Login Asks for Password Setup Again |
| 223 | + |
| 224 | +The secstore overlay may not have loaded. Check: |
| 225 | + |
| 226 | +```sh |
| 227 | +ls ~/.infernode/usr/inferno/secstore/$(whoami)/PAK |
| 228 | +``` |
| 229 | + |
| 230 | +If PAK exists, it's a trfs timing issue (see boot.sh warmup). If it |
| 231 | +doesn't exist, secstore wasn't saved — you'll need to set up again. |
| 232 | + |
| 233 | +### "link typecheck" Errors |
| 234 | + |
| 235 | +A `.dis` file was compiled against an old `.m` interface. Rebuild |
| 236 | +the affected directory: |
| 237 | + |
| 238 | +```sh |
| 239 | +export ROOT=$PWD PATH=$PWD/MacOSX/arm64/bin:$PATH |
| 240 | +cd appl/xenith && mk install # if xenith modules changed |
| 241 | +cd appl/cmd && mk install # if cmd modules changed |
| 242 | +``` |
| 243 | + |
| 244 | +See the "Stale bytecode problem" section in CLAUDE.md for details. |
| 245 | + |
| 246 | +### Tests Fail With "cannot load testing module" |
| 247 | + |
| 248 | +The testing framework .dis is missing or stale: |
| 249 | + |
| 250 | +```sh |
| 251 | +export ROOT=$PWD PATH=$PWD/MacOSX/arm64/bin:$PATH |
| 252 | +cd appl/lib && mk testing.dis |
| 253 | +cd tests && mk install |
| 254 | +``` |
| 255 | + |
| 256 | +## Environment Variables |
| 257 | + |
| 258 | +| Variable | Purpose | |
| 259 | +|----------|---------| |
| 260 | +| `ANTHROPIC_API_KEY` | API key fallback (used if not in secstore) | |
| 261 | +| `SECSTORE_PASSWORD` | Headless mode: auto-unlock secstore without login screen | |
| 262 | +| `OLLAMA_HOST` | Not used by InferNode — configure via Settings or `lib/ndb/llm` | |
| 263 | + |
| 264 | +## Platform Notes |
| 265 | + |
| 266 | +### macOS (Apple Silicon) |
| 267 | + |
| 268 | +- Emulator binary: `emu/MacOSX/o.emu` (or `InferNode.app/Contents/MacOS/emu`) |
| 269 | +- Native tools: `MacOSX/arm64/bin/mk`, `MacOSX/arm64/bin/limbo` |
| 270 | +- JIT: ARM64 JIT with `-c1` |
| 271 | + |
| 272 | +### Linux (AMD64) |
| 273 | + |
| 274 | +- Build: `./build-linux-amd64.sh` |
| 275 | +- Emulator binary: `emu/Linux/o.emu` |
| 276 | +- Native tools: `Linux/amd64/bin/mk`, `Linux/amd64/bin/limbo` |
| 277 | +- JIT: AMD64 JIT with `-c1` |
| 278 | + |
| 279 | +### Linux (ARM64, e.g. NVIDIA Jetson) |
| 280 | + |
| 281 | +- Build: `./build-linux-arm64.sh` |
| 282 | +- Native tools: `Linux/arm64/bin/mk`, `Linux/arm64/bin/limbo` |
| 283 | +- JIT: ARM64 JIT with `-c1` |
0 commit comments