# BoltClam architecture ## Process layout BoltClam is one PyQt6 process on the user's Windows desktop. It starts no Windows service and installs no driver. ClamAV remains an external program. ``` BoltClam.exe (PyInstaller or portable launcher) └─ boltclam.app ├─ MainWindow ── HomePage / ScanPage / AboutPage / SettingsPage ├─ RealtimeProtection ── DownloadWatcher + QThreadPool scan tasks ├─ ScanWorker / DefinitionWorker (QThread) ├─ Storage (SQLite, WAL) ├─ QuarantineService ├─ ClamAVService → clamscan.exe / freshclam.exe └─ ApiClient → https://api.themajesticnetwork.com ``` Settings are JSON under `%APPDATA%\BoltClam`; history and quarantine live under `%LOCALAPPDATA%\BoltClam`. `BOLTCLAM_CONFIG_DIR` and `BOLTCLAM_DATA_DIR` override both for tests and portable/development use. ## Page responsibilities - **HomePage** calls `system_info.collect()` on a worker. PowerShell supplies Defender/firewall/network facts on Windows; missing data is "not reported". The shell gauge and concern list are derived from ClamAV state, definition age, real-time state, firewall, last scan, active detections and quarantine count. It never labels an unknown state as protected. - **ScanPage** persists scope/auto-response preferences immediately, runs `ScanWorker`, records each detection in SQLite before remediation, and exposes manual quarantine/delete/ignore after a scan. Quarantine management restores to the original path or a chosen path and refuses overwrites. - **AboutPage** calls `/boltclam/account` for user/plan data and `/boltclam/updates` for the release feed. Downloads use the API asset proxy and optionally verify `SHA256SUMS.txt`. - **SettingsPage** validates ClamAV paths and extra options, applies logging changes, updates the real-time watcher, and creates/uploads diagnostics bundles only when the user has opted in. ## Sign-in sequence ``` BoltClam Browser Bolt desk API |-- PKCE verifier/challenge --| | |-- loopback listener :port/cb| | |-- open /desk/auth/boltclam/start?... ------------------->| | |<-- branded login page -----| | |-- email/password or OAuth->| |<-- 302 /cb?code=...&state=... ----------------------------| |-- POST /desk/auth/oauth/exchange (code+verifier) -------->| |<-- {api_key, user} --------------------------------------| |-- DPAPI-store key, GET /boltclam/account ---------------->| ``` The one-time code is bound to the PKCE challenge, the exact loopback URI and a short TTL. The app rejects a callback whose state does not match. The API burns an exchange code on the first attempt, successful or not. ## Scan sequence 1. `ClamAVService.info()` locates `clamscan.exe`, runs `--version`, and chooses the managed database if it contains signatures. 2. `scan_targets("homes")` reads the Windows `ProfileList` registry and falls back to `C:\Users`; `"full"` enumerates fixed local drives. 3. `ScanWorker` starts clamscan with an argv list, no shell, and parses detections/progress/summary. Each `path: Signature FOUND` becomes a `Detection` row first, then quarantine/delete/notify is applied. 4. The scan row is finished even on cancellation or process failure. The UI reloads history and the Homepage aggregates. ## Real-time sequence `DownloadWatcher` polls each watched download folder at 1.5 s intervals (and refreshes browser preferences every 30 s), ignores in-progress suffixes, and waits for a stable size/mtime. `RealtimeScanTask` runs in a QThreadPool: ``` stable file → exclusive handle (share=0) → copy → ClamAV scans copy → clean: release → detection: release + quarantine/delete ``` The exclusive handle is held for the entire scan. A fallback copy is used when the file is already open, with that fact recorded in the event detail. ## Update flow - The Bolt API reads Gitea's `/api/v1/repos/TheMajesticNetwork/BoltClam/releases`, caches for five minutes, filters draft/prerelease by channel, and returns normalized release metadata. - Asset downloads go through the API, so a future private repository needs no desktop token. The API streams the Gitea asset with its own token. - The client compares semantic versions, selects a Windows `.exe`/`.zip` asset, downloads it to `%LOCALAPPDATA%\BoltClam\updates`, and verifies the release checksum when published. ## Storage schema - `scans` — scope, status, paths JSON, counts, engine/DB versions, duration. - `detections` — scan id, path, signature, action, quarantine id, timestamp. - `quarantine` — id, original/quarantine path, signature, SHA-256, status. - `realtime_events` — download path, signature, action, detail, timestamp. All writes open their own SQLite connection; WAL mode lets the UI read while a scan thread writes. Quarantine sidecars are JSON, so the record survives a database rebuild.