# Linux

A Linux computer can capture articles and PDFs, draft summaries, sync, and keep your save
queue moving as a service. Use Node.js 24.20 or newer and the released `@hraness/sponge`
package. [Requirements and platforms](/docs/requirements) compares Linux with macOS.

## Join your account

If you already have a library on another computer, upload it from there first with
`sponge login`, then `sponge sync`. On Linux:

```sh
npm install -g @hraness/sponge
sponge init
sponge login --label "Linux server"
sponge sync --join
sponge sync status
```

Open the printed link on any browser (your laptop or phone) and confirm the code. The terminal
stores a private, revocable device credential. For a detached setup, use
`sponge login --no-wait` followed by `sponge login --finish` after approval.
There is no need for a browser on the Linux host.

An existing populated library with a different UUID cannot join. Back it up and
initialize a separate empty directory using `--library /absolute/new/library`.
Do not replace or copy a running SQLite database between hosts.

## Local models

| Capability | Linux support |
| --- | --- |
| Read, notes, FTS search, sync | Portable Node/SQLite implementation |
| Article and PDF capture | Built in; PDF extraction needs Poppler |
| Managed digest drafting | x64/ARM64 CPU llama.cpp, verified pinned archives |
| Existing local GPU model server | Explicit literal-loopback HTTP endpoint |
| Media transcripts, English speech recognition, CLI semantic search, map building | Not on Linux; these use Apple Silicon macOS helpers |
| Capture through a signed-in browser, `worker install` | macOS only; use `worker foreground` on Linux |

The x64 runtime requires glibc 2.35 or newer; ARM64 requires glibc 2.39 or newer.
Ubuntu 24.04 is the native CI qualification target for both architectures. Other
compatible distributions must pass the same local preflight. Alpine/musl,
Windows and GPU archive variants are not managed targets.

On Ubuntu 24.04, install the system prerequisites yourself:

```sh
sudo apt-get update
sudo apt-get install bubblewrap libgomp1 libssl3t64 libstdc++6 poppler-utils
sponge setup --digest
sponge run --drain
```

On x64 Ubuntu 22.04 the OpenSSL package is `libssl3`. The conservative glibc
floor comes from upstream release dependencies; that distribution is not a
separate live qualification claim.

`setup --digest` selects Qwen3.5-9B Q4_K_M with 16–32 GiB of effective RAM or
Gemma 4 26B-A4B Q4_K_M with at least 32 GiB. The downloads are about 5.6 GB or
16.9 GB respectively, plus the small runtime. Container/cgroup memory limits
count, even if the host has more physical RAM. Runtime threads respect available
CPUs and quotas, capped at eight. Existing GGUF weights can be copied with
`--model-file /absolute/model.gguf`; their exact pinned hash is still verified.

Bubblewrap must be able to create user and network namespaces. Managed inference
fails preflight when host/container policy forbids them; Sponge does not change
kernel settings or run the server without isolation. The server receives a
read-only runtime/model and one owned scratch directory, communicates through a
private Unix socket and is collected under the existing worker supervisor.

Ubuntu's AppArmor user-namespace policy may require an administrator to admit
`/usr/bin/bwrap` explicitly. Installing the package alone does not establish that
permission. `sponge setup --digest --debug` reports
`prerequisite: user-network-namespaces` when the probe is denied. The native CI
runner installs a narrow, temporary profile for bubblewrap; it does not disable
the global policy. Ask the host administrator for an equivalent reviewed policy
when needed. Sponge never installs that profile on your host.

Below 16 GiB, choose and run a smaller model independently and use:

```sh
sponge digest ITEM --endpoint http://127.0.0.1:8080 --model MODEL_ID
```

The endpoint must implement Sponge's llama.cpp-compatible model/health contract,
and the model must appear at `/v1/models`. Quality is checked by the same digest
validator; different weights, hardware or runtime builds are not a parity claim.
Linux namespace/ELF tests do not measure full-model drafting quality or speed.

## Keep work running

Two foreground commands have separate jobs:

```sh
sponge worker foreground   # captures and due local model/index jobs
sponge sync --watch        # exchange changes every 30 seconds
```

Use separate terminals or two systemd user services. For example, save the
following as `~/.config/systemd/user/sponge-sync.service`, replacing both absolute
paths with your installed command and library. Node must be on the service PATH.

```ini
[Unit]
Description=Sponge private library sync
After=network-online.target

[Service]
ExecStart=/absolute/path/to/sponge sync --watch --library /absolute/path/to/library
Environment=PATH=/absolute/node/bin:/usr/bin:/bin
Restart=on-failure
RestartSec=30
UMask=0077
KillMode=control-group
TimeoutStopSec=90

[Install]
WantedBy=default.target
```

Create a second `sponge-worker.service` with `ExecStart` ending in
`worker foreground --library /absolute/path/to/library`; keep the same process
cleanup settings. Then enable them as your ordinary user:

```sh
systemctl --user daemon-reload
systemctl --user enable --now sponge-sync.service sponge-worker.service
```

`worker foreground` checks for a Sponge release once a day between jobs. After
installing one it exits with an error, so `Restart=on-failure` starts it on the new
version; `sponge update auto off` or `Environment=SPONGE_NO_AUTO_UPDATE=1` turns that
off. It checks only when the npm prefix it was installed into is writable by this
user; a root-owned global install needs `sudo npm install -g @hraness/sponge`. With
no worker, a one-off `sponge sync` (from cron or a timer) runs the same daily check
after it syncs, when no other Sponge command or worker is running. A long-running
`sync --watch` never updates; run `sponge update` yourself when only that runs. Keep any wrapper script outside npm's `bin` directory: npm
relinks `<prefix>/bin/sponge` on every install. Restart `sponge-sync.service` (or
any `sync --watch` or MCP server) after an update.

Session/boot persistence depends on the host's systemd user-manager policy;
Sponge does not enable lingering or install a system daemon. `worker install`
continues to manage only the macOS LaunchAgent. Inspect `queue status`, `doctor`,
`journalctl --user -u sponge-sync -u sponge-worker` and the library's service log.
After a hard interruption, `sponge queue recover` preserves uncertain cleanup
until it can prove that the old processes have stopped.

To draft an item received through sync, run `sponge digest ITEM --draft`, then
`sponge sync` to send its draft back. Automatic drafting queues new captures made
on that host; existing synced captures are drafted explicitly. Each host chooses
its own model and processing settings. [Summaries](/docs/summaries) covers review.
