# QVAC runtime and GPU authority ## The single-master rule Only `daemon/qvac-master.js` may import and operate the QVAC SDK for Jarvis runtime work. Skills receive a master facade; they do not call `loadModel()` or create their own workers. The harness is connected through `daemon/harness-bridge.js` and uses the same owner. ```mermaid flowchart LR V[Voice] --> M[Master scheduler] H[Harness] --> M CU[Computer vision] --> M J[Jobs: media / RAG] --> M M --> L{GPU admission} L -->|fit| SDK["QVAC SDK 0.19.1"] L -->|no fit| E[truthful unavailable error] SDK --> W[one QVAC worker] ``` The optional `qvac serve --openai` command is diagnostic/API infrastructure. It is not started alongside `jarvisd` in production and must remain bound to `127.0.0.1` when used. ## Lifecycle 1. Read `QVAC_CONFIG_PATH` and the selected profile. 2. Query GPU visibility and model fit before loading. 3. Admit work through interactive, computer-vision, background, or maintenance lanes. 4. Load one model configuration at a time and serialize worker access. 5. Stream completion or media progress to the daemon. 6. Cancel by request ID/model ID when the user says stop or a grant is revoked. 7. Suspend or unload according to idle policy; close once during shutdown. ```mermaid stateDiagram-v2 [*] --> Uninitialized Uninitialized --> Preflight: start Preflight --> Ready: GPU visible + fit accepted Preflight --> Unavailable: GPU missing / fit rejected Ready --> Loading: admitted request Loading --> Loaded: loadModel Loaded --> Busy: completion / media / vision Busy --> Loaded: stream complete Busy --> Loaded: cancellation Loaded --> Suspended: idle policy Suspended --> Loading: new request Loaded --> Closing: shutdown Suspended --> Closing: shutdown Closing --> [*] ``` ## Configuration The repository config is `qvac.config.json`. Installed user sessions use `~/.config/jarvis/qvac.config.json`, generated from `packaging/qvac.config.template.json`. The server is localhost-only and the default alias is `jarvis-master`. Model cache files belong under the user's cache directory, never under a system-wide writable location. ## GPU policy `JARVIS_GPU_REQUIRED=1` is set by the service. The master requests GPU device and maximum GPU layer offload. An explicit GPU request (or `JARVIS_GPU_REQUIRED=1`) fails directly on a GPU load error rather than loading a CPU copy that the master would reject. Optional `device: 'auto'` callers outside that policy can still fall back, and runtime status labels that backend as CPU. Run `npm run gpu-doctor` and consult [hardware compatibility](hardware-compatibility.md) before changing a model profile.