-
-
Notifications
You must be signed in to change notification settings - Fork 6
Persistence and local models
Mount /data to preserve state:
| Default path | Contents |
|---|---|
/data/accounts.json |
Accounts, aliases, dashboard API keys, application policies, webhooks, and settings |
/data/oauth-state.json |
In-progress OAuth state |
/data/requests-trace.jsonl |
Recent retained traces |
/data/requests-stats-history.jsonl |
Lightweight long-term usage history |
/data/anonymous-usage-state.json |
Mode-0600 anonymous daily retry envelope without a stable installation ID |
/data/provider-agent-selection.json |
Mode-0600 explicit local provider model selection |
/data/provider-agent-runtime-endpoints.json |
Mode-0600 loopback endpoints and optional runtime bearers |
/data/provider-agent-device-identity.json |
Mode-0600 Ed25519 device identity and relay-shadow sequence |
/data/provider-agent-cloud-enrollment.json |
Mode-0600 submitted Cloud shadow node view; never the enrollment grant |
/data/codex-projects.json |
Codex session/project registry |
/data/v1-edge-jobs.json |
Native Rust jobs, results, retries, and webhook delivery state |
/data/jobs.sqlite |
Legacy/control-plane jobs and pre-Rust migration source |
The Compose deployment mounts ./data:/data. Recent trace retention defaults
to 1,000 entries. Persistent state is not encrypted at rest: accounts.json
can contain provider access/refresh tokens, proxy keys, and webhook secrets;
oauth-state.json can contain temporary OAuth verifiers; traces and the native
job file or legacy database can contain request and response payloads. Files created by MultiVibe
use restrictive permissions, but the volume and its backups should still be
encrypted, access-controlled, and excluded from public shares.
Job content delivered by webhook or consumed by a client receives a one-hour
grace period; unretrieved content is purged after 30 days. For a consistent
backup, stop the service cleanly, copy the entire data/ directory (including
v1-edge-jobs.json, the *.pre-rust-backup.sqlite migration copy, and any
SQLite -wal or -shm files), then start it again. Restore the complete
directory only while the service is stopped.
Set PROVIDER_AGENT_ENABLED=true to let Core supervise the packaged provider
agent. PROVIDER_AGENT_BINARY selects its absolute binary path and
PROVIDER_AGENT_STATE_PATH selects the clean absolute local selection file;
by default the file is placed beside STORE_PATH as
provider-agent-selection.json. PROVIDER_AGENT_RUNTIME_STATE_PATH selects
the separate protected manual-runtime file and defaults to
provider-agent-runtime-endpoints.json beside STORE_PATH. The admin APIs
can inventory the reviewed loopback candidates, configure one literal
loopback endpoint per manual adapter, and persist an explicit model selection
locally. Runtime bearers are accepted only through the local authenticated
admin path, never returned by either API, and retained when an update omits the
secret field.
PROVIDER_AGENT_DEVICE_KEY_PATH selects the separate mode-0600 Ed25519
device identity. The agent exposes only its public key and key ID in the local
manifest. Its authenticated relay-shadow endpoint signs Cloud-compatible
30-second session-open envelopes with a persisted monotonic sequence and fixed
non-commercial locks. This endpoint cannot carry customer content, open a
socket to a relay, enable routing, or create compensation eligibility.
PROVIDER_AGENT_ENROLLMENT_STATE_PATH selects the separate submitted-node
state. The authenticated Cloud-shadow enrollment route sends only the exact
selected-model consent manifest to PROVIDER_AGENT_CLOUD_API_URL, which is
restricted to https://auth.multivibe.cloud (or literal loopback HTTP in
tests), signs the returned challenge, persists no grant or proof, freezes the
submitted selection, and keeps routing and compensation false.
The autonomous host archive also pins PROVIDER_AGENT_MANAGED_ROOT,
PROVIDER_AGENT_BUNDLED_OLLAMA_ROOT,
PROVIDER_AGENT_DEPENDENCY_MANIFEST_PATH,
PROVIDER_AGENT_MANAGED_PLANNER_STATE_PATH and
PROVIDER_AGENT_MODEL_CATALOG_PATH to its private data directory and signed
bundle layout. Managed demand reconciliation is enabled only when an operator
also supplies MULTIVIBE_PROVIDER_DEMAND_TRUSTED_KEYS to the host launcher.
That value is an explicit Ed25519 public-key trust root; the repository's RFC
interop test key is never used as a packaged Cloud key. Without a configured
production trust root, Core still starts but signed demand and managed Ollama
remain unavailable.
The local-account Share models · Preview experience exposes the same inventory and revisioned selection without requiring a separate agent UI. It does not submit automatically: enrollment requires an explicit one-time grant and exact manifest. Submission does not advertise capacity, accept community workloads, or enable earnings and payouts.
If the marketplace is later activated after every production gate passes, the announced commercial split for eligible, cleared community-workload revenue is 85% to the host operator and a 15% MultiVibe service fee. Applicable taxes, reserves, disputes and reversals are handled after that split and may reduce or delay the amount payable. The separate 5% fee applies only to customer purchases or top-ups; it is not an additional deduction from the host operator's 85% share. This repository currently implements no payable, settlement or compensation activation.
The multiarchitecture Core container build compiles the Go agent for the same
target OS and architecture as the final image, runs its complete Go test suite
on the build platform, and installs the static executable at the default
/opt/multivibe/bin/multivibe-provider-agent path with no separate download.
The binary remains inert unless PROVIDER_AGENT_ENABLED=true; enabling it does
not bypass any of the shadow-only routing or compensation locks above.
The ordinary docker-compose.yml runs Core as a gateway. The separate
packaging/container/docker-compose.host.yml runs the complete security-bounded MultiVibe Host
bundle for Linux amd64 systems with a supported NVIDIA GPU. Official tagged
Host releases publish the exact verified Linux bundle as
ghcr.io/thibautrey/multivibe-host:<version> and update the latest tag only
after the image has started and reported the expected Host version.
Set the exact URL used by browsers, then start the Host:
MULTIVIBE_HOST_PUBLIC_URL=http://192.168.1.20:1455 \
docker compose -f packaging/container/docker-compose.host.yml up -dUse an HTTPS reverse-proxy origin instead when applicable. Container mode sets
MULTIVIBE_HOST_BIND=0.0.0.0, but a non-loopback bind fails closed unless
MULTIVIBE_HOST_PUBLIC_URL is an explicit path-free HTTP(S) origin. Core uses
that origin for its OAuth callback. Native Host installs retain the secure
127.0.0.1 default and need no additional setting.
Only Core port 1455 is published. The provider-agent bearer endpoint and the
managed Ollama listener remain on literal loopback inside the same container.
The image uses a read-only root filesystem, prepares only the two declared
mount roots, then drops to fixed uid/gid 10001:10001 with no capabilities.
Random admin and proxy credentials remain in /data/host-credentials.json and
are never Compose or Unraid parameters.
/data contains small private application state. /models is a separate
large persistent volume; the managed runtime uses /models/runtime. When the
operator explicitly creates the local capacity policy, use /models/weights
as its model storage path. MultiVibe does not silently create that policy,
enable downloads, enroll the device, accept Cloud work, or activate
compensation.
packaging/unraid/multivibe-host.xml and packaging/unraid/ca_profile.xml follow the official Unraid
Community Applications v2 layout. The template is deliberately marked beta,
requires the Unraid Nvidia Driver runtime, keeps the app unprivileged, and
mounts application state separately from models. The files are ready for
validation and a later Community Applications submission; their presence in
this source repository does not mean the app has already been accepted or
listed in the Unraid catalog.
Provider-agent admin endpoints:
GET /admin/provider-agent/adaptersGET /admin/provider-agent/manifestGET/PUT /admin/provider-agent/runtime-endpointsGET /admin/provider-agent/detected-modelsGET/PUT /admin/provider-agent/selectionGET /admin/provider-agent/cloud-shadow/enrollmentPOST /admin/provider-agent/cloud-shadow/enrollPOST /admin/provider-agent/relay-shadow/session-openGET /admin/provider-agent/managed-ollama/statusPOST /admin/provider-agent/managed-ollama/installPOST /admin/provider-agent/managed-ollama/startPOST /admin/provider-agent/managed-ollama/stopPOST /admin/provider-agent/managed-ollama/reconcile
Anonymous sharing is enabled by default for new and upgraded installations and can be changed immediately in the Tracing tab. The activation timestamp is materialized during upgrade, so historical usage from before activation is never backfilled. Re-enabling creates a new activation timestamp.
For each completed UTC day, Core first downloads the public hosted-inference allowlist. It then reads the lightweight local trace history and prepares at most 50 contributions containing only an exact allowlisted canonical model ID and output-token volume rounded down to thousands, capped at one billion tokens per model. The envelope also contains the UTC-day window and a random event UUID used only to retry that day safely.
Before each send, Core obtains a short-lived, single-use Cloud admission ticket and solves a bounded computational challenge. This limits mass submission without an installation ID; it does not prove the reported usage. Cloud labels these volumes self-reported and excludes them from popularity ranking and billing. Admission requires the corresponding updated Cloud deployment and migration; failed admission retains the pending envelope for a later retry.
Core never shares prompts, responses, input-token volumes, projects, accounts, emails, hardware, hostnames, request headers, fine-grained timestamps, or a stable installation ID. If the allowlist or Cloud API is unavailable, the cycle fails closed and inference continues normally. Unchecking the control aborts future sends and deletes any unsent envelope immediately.