# System requirements — Codescry

Codescry runs the analysis itself, on your machine, with a model you host. That makes the
requirements less about the app — it is a small Rust + webview binary — and almost entirely
about **the model engine sitting behind it**. This page is the honest version: what runs, on
what hardware, on which OS, and exactly what the app refuses to do until the model is ready.

- [At a glance](#at-a-glance)
- [Supported models](#supported-models)
- [RAM](#ram)
- [Disk](#disk)
- [GPU, NPU and CPU fallback](#gpu-npu-and-cpu-fallback)
- [Per-OS notes](#per-os-notes)
- [The model gate](#the-model-gate)
- [Network](#network)
- [Building from source](#building-from-source)

---

## At a glance

|              | Minimum                                        | Recommended                                    |
| ------------ | ---------------------------------------------- | ---------------------------------------------- |
| **CPU**      | 64-bit x86-64 or ARM64, 4 cores                | 8+ cores, or any supported GPU                 |
| **RAM**      | **8 GB** (~6 GB free for the default model)    | **16 GB**                                      |
| **Disk**     | **~4 GB free** — default model + results store | 10 GB+, so you can hold two models             |
| **GPU/NPU**  | none — CPU fallback always works               | Apple Silicon (Metal), NVIDIA (CUDA), AMD (ROCm) |
| **OS**       | Windows 10/11 64-bit · macOS 12+ · Linux with `webkit2gtk-4.1` | current release of any of them  |
| **Engine**   | [Ollama](https://ollama.com) running on `127.0.0.1:11434` | same, kept running in the background |

The app binary itself is tiny (tens of MB). Every number above is really about the model.

## Supported models

Codescry talks to a local Ollama server and pulls models *through* it, so the supported set is
"Ollama tags that produce valid JSON for our schemas". Four are curated in-app — shown in
onboarding and in **Settings → On-device model** — and you can point the app at any other tag
you have already pulled.

| Ollama tag    | Download | RAM   | Vision | Notes                                                     |
| ------------- | -------- | ----- | ------ | --------------------------------------------------------- |
| `gemma3:4b`   | ~3.3 GB  | 6 GB  | yes    | **Default** — balanced, understands screenshots (UI axis)  |
| `qwen3:4b`    | ~2.6 GB  | 6 GB  | no     | Strong code reasoning, UI axis unavailable                 |
| `gemma3:12b`  | ~8.1 GB  | 12 GB | yes    | Slower, better findings — needs a beefier machine          |
| `llama3.2:3b` | ~2.0 GB  | 4 GB  | no     | Smallest and fastest, lighter findings, no vision          |

**Vision matters for exactly one axis.** The UI axis sends a screenshot you attached to the
model; a text-only tag cannot read it. The other four axes (missing, feature, outdated, bloat)
work with any of the four.

**Other tags.** Settings → On-device model lists every model already installed in your Ollama
instance alongside the curated four, so `ollama pull <anything>` and it shows up as selectable.
That path is unsupported in the sense that we do not test it: Codescry constrains output with a
JSON schema and retries once on invalid output, so a model that ignores the `format` parameter
produces failed axes rather than wrong results. **Test**, next to the active model, runs a
one-call schema check and tells you which it is.

**Requirements the model must meet**, if you go off-catalog:

- Served by an Ollama-compatible `/api/chat` endpoint that honours `format` (JSON-schema
  constrained decoding) — Codescry never parses free prose.
- At least an 8K context window; the app requests `num_ctx: 8192` per call.
- Vision input only if you want the UI axis.

## RAM

The model is resident in memory while a scan runs. The **RAM** column above is what the engine
needs on top of your OS and whatever else is open — so the practical floor is roughly *model
RAM + 2 GB*:

| Your machine | What to run                                                |
| ------------ | ---------------------------------------------------------- |
| 8 GB         | `llama3.2:3b`, or `gemma3:4b` with little else open        |
| 16 GB        | `gemma3:4b` (default) comfortably, `gemma3:12b` if patient |
| 32 GB+       | `gemma3:12b` as your daily driver                          |

If the engine runs out of memory mid-run, the affected axis fails and the run continues — you
get a failed-axis card with a retry, not a lost scan. Repeated failures on one project usually
mean the model is too large for the machine, not that the project is broken.

## Disk

Two separate things take space, in two separate places:

| What                | Where                                                                | Size                                 |
| ------------------- | -------------------------------------------------------------------- | ------------------------------------ |
| **Model weights**   | Ollama's store, *not* Codescry's — see [Per-OS notes](#per-os-notes)  | 2.0–8.1 GB per model, table above    |
| **Codescry's data** | The app-data dir for `org.helveticlabs.codescry`                     | a few MB, plus attached screenshots  |
| **The app**         | Program files                                                        | tens of MB                           |

Codescry's own store is the SQLite database (`codescry.db` plus its WAL sidecars) and the
`screenshots/` folder — see [Where your data lives](USER_GUIDE.md#where-your-data-lives). It
grows with scan history and attached images, not with the size of the projects you scan:
**your project folders are read, never copied, and never modified.**

Uninstalling leaves both stores in place. Deleting a model is
**Settings → On-device model → Delete**; it frees the download size immediately.

## GPU, NPU and CPU fallback

**Codescry never selects a compute device.** It sends a request to the local engine; the engine
decides. Acceleration is therefore entirely Ollama's story:

| Hardware                                | What happens                                                                     |
| --------------------------------------- | -------------------------------------------------------------------------------- |
| Apple Silicon (M-series)                | Metal, automatically. Best experience per watt                                    |
| NVIDIA GPU with current drivers         | CUDA, automatically, when the VRAM fits the model                                 |
| AMD GPU (ROCm-supported, Linux/Windows) | ROCm, automatically                                                               |
| NPUs (Copilot+, Apple Neural Engine)    | **Not used** — the engine has no NPU path, so those machines fall back to CPU     |
| Everything else, including Intel Macs   | **CPU.** Fully supported, just slower                                             |

There is **no GPU requirement**. CPU-only is a first-class configuration: the whole product is
built around a local run taking real time. A CPU-only full-portfolio scan is a
put-the-kettle-on operation, and the Run screen is designed for exactly that — live per-project
status, a rough ETA, pause/resume, skip-this-project, and a cancel that keeps everything
already finished. Each per-axis model call times out at 5 minutes, so one pathological project
cannot hang a run indefinitely.

Rules of thumb for a smaller machine: pick `llama3.2:3b`, turn off the axes you do not care
about (**Settings → Analysis axes**), and scan one project at a time from the Run picker
instead of the whole portfolio.

## Per-OS notes

### Windows

- **Bundle:** `.msi`, 64-bit, Windows 10/11.
- **WebView2** must be present. It ships with Windows 11 and current Windows 10; the installer
  fetches it if it is missing.
- **Ollama** installs as a background service and starts with the session. Models live under
  your user profile in `.ollama\models` — point `OLLAMA_MODELS` elsewhere if the system drive
  is tight.
- Real-time antivirus scanning of large `node_modules` / `target` trees is the usual reason a
  first detection pass feels slow. The bloat axis walks those directories by design.
- Codescry's data: `%APPDATA%\org.helveticlabs.codescry`.

### macOS

- **Bundle:** `.dmg`, universal — Apple Silicon and Intel.
- **Apple Silicon** uses Metal and is the best value per watt. **Intel Macs are CPU-only**;
  prefer `llama3.2:3b` there and expect long runs.
- **Ollama** ships a menu-bar app; leave it running. Models live in `~/.ollama/models`.
- Codescry's data: `~/Library/Application Support/org.helveticlabs.codescry`.
- Check [ollama.com](https://ollama.com) for its current macOS floor (macOS 12 at the time of
  writing) — in practice that, rather than the Codescry bundle, is the binding constraint.

### Linux

- **Bundles:** `.AppImage` and `.deb`, x86-64.
- **Runtime deps** are the standard Tauri 2 set — `libwebkit2gtk-4.1-0`, `libappindicator3`,
  `librsvg2`. The `.deb` pulls them in on Debian/Ubuntu; for the AppImage, install them first.
- **Ollama** is usually a systemd service, and the model store depends on who runs it: a service
  running as the `ollama` user stores models under `/usr/share/ollama/.ollama/models`, while
  `ollama serve` started by you uses `~/.ollama/models`. If a model you pulled by hand does not
  appear in Codescry, this is almost always why — the app only sees the instance answering on
  `127.0.0.1:11434`.
- NVIDIA/AMD acceleration needs the corresponding driver stack; without it the engine runs on
  CPU without complaint.
- Codescry's data: `$XDG_DATA_HOME/org.helveticlabs.codescry`, defaulting to
  `~/.local/share/org.helveticlabs.codescry`.

### All platforms — install prompts

Release bundles carry the **updater signature** used to verify in-app updates, but they are not
OS code-signed or notarized. Expect a Gatekeeper prompt on macOS and a SmartScreen warning on
Windows at first launch. Checksums for every artifact are published with the
[release](https://github.com/makr07-sec/codescry/releases/latest).

## The model gate

**No ready model, no scanning.** This is deliberate, and enforced in two places so it cannot be
clicked past.

Codescry asks the engine two questions — *is it reachable* (`/api/version`) and *is the selected
model installed* (`/api/tags`) — and reduces the answer to one of three states:

| State            | What you see                                                                | What to do                            |
| ---------------- | --------------------------------------------------------------------------- | ------------------------------------- |
| `ready`          | `Model ready`; the nav shows the model name · **ready**                     | nothing — scan away                   |
| `engine_missing` | *"The local model engine (Ollama) isn't running."* Nav shows **engine off** | install or start Ollama, then retry   |
| `not_installed`  | `Model not installed`. Nav shows **not installed**                          | **Download model** — progress streams live |

While the gate is closed:

- The **Run** button in the nav, the dashboard's **Run first scan** and every **Quick run** tile
  are disabled, with `Scanning needs the on-device model — finish setup in Settings.`
- The Run picker's launch button stays disabled whatever scope and axis you select.
- The idea generator's **Generate** is disabled too (it also wants skills and at least one
  domain). Your profile is still saved.
- Everything that does not need the model keeps working: browsing past reports, resolve and
  snooze, history, exports, settings.

**The backend enforces it independently.** `start_run` re-checks model status before it queues
anything and refuses with *"model engine is not running — finish model setup in Settings"* or
*"model … is not installed — finish model setup in Settings"*. A stale frontend cannot start a
run against a missing model.

**A download only counts once it verifies.** A pull is accepted only when the engine reports
success **and** the model then turns up in `/api/tags` — the engine lists a model only after its
manifest is written and every blob digest checks out. Anything else (interrupted stream, digest
mismatch, a "success" that never lands) is reported as `Download not verified`, and that model
**cannot be activated**: delete the partial copy and download again. The blob digest in flight
is shown during the pull and on the verified result, so you can see what was actually fetched.

Status is re-read at launch and after every model action, so starting Ollama and switching back
to Codescry re-opens the gate without a restart.

## Network

The model itself never needs the network — it is on your disk, answering on `127.0.0.1`. Three
things can reach outside, all optional:

| Traffic                  | When                                                                        | Off switch                                  |
| ------------------------ | --------------------------------------------------------------------------- | ------------------------------------------- |
| Model download           | when you pull a model, once per model                                       | don't pull, or pull with `ollama` yourself  |
| Registry version lookups | the **Outdated** axis (npm · PyPI · NuGet) — package names only, never code  | **Go fully offline** in Settings            |
| Update check             | once per launch, asks GitHub whether a newer release exists                 | the same switch                             |

With offline mode on, the Outdated axis reports installed versions without comparisons and the
other four axes are unaffected. See [Offline mode](USER_GUIDE.md#offline-mode) and
[PRIVACY.md](../PRIVACY.md).

## Building from source

Only relevant if you are building rather than installing.

```bash
cd frontend && npm ci
npm run tauri:dev
```

- **Node** 20+ and **Rust** (stable, via [rustup](https://rustup.rs)).
- **Windows:** the Visual Studio "Desktop development with C++" workload (MSVC toolchain).
- **macOS:** Xcode command-line tools.
- **Linux:** `libwebkit2gtk-4.1-dev`, `libappindicator3-dev`, `librsvg2-dev`, `patchelf`.

Everything above still applies — a source build talks to the same local engine.

---

Something not covered here? [Troubleshooting](USER_GUIDE.md#troubleshooting) in the user guide,
or [open an issue](https://github.com/makr07-sec/codescry/issues).
