# Problems Findings from systematic bug-hunt and test expansion (May 2026). **Verification:** `test.bat` from project root, or `go test ./...` in `server`/`agent` and `npm test` in `server/web`. AI handler only: `cd server && go test ./internal/api/... -run AI -v`. --- ## Open ### Critical / security - [CRITICAL] **server/internal/api/router.go** — Unauthenticated build downloads (`/api/v1/builds/{id}/download`, `/artifact/`). Intentional for agent reinstall (UUID is secret). Suggested fix: optional auth toggle or short-lived signed URLs. - [CRITICAL] **server/internal/api/websocket.go** — Unauthenticated agent WebSocket (`/ws/agent`); any client can claim any `agent_id`. Suggested fix: bind `agent_id` to fleet secret baked into forged binary (S2 from prior audit). - [CRITICAL] **server/internal/api/websocket.go** — Unauthenticated dashboard WebSocket (`/ws/dashboard`); full fleet telemetry without login. Suggested fix: require Basic auth or session cookie on WS upgrade. - [CRITICAL] **server/internal/api/ai_handler.go** — Unauthenticated AI endpoints (`/agent/decide`, `/report`, `/heartbeat`); SSRF via caller-supplied Ollama URL. Suggested fix: require fleet secret or dashboard auth. - [HIGH] **server/internal/api/router.go** — Plaintext passwords in `users.json`; any authed user can POST `/users`. Suggested fix: bcrypt-only storage (partially done), restrict user management to admin role. - [HIGH] **server/internal/api/fleet_handler.go** — Remote code execution via authenticated API (`powershell`/`exec`/`upload`). By design — treat dashboard login as root. ### High - [HIGH] **server/internal/api/fleet_handler.go** — `upload_log` returns content in tool report only; no dedicated log ingest API. - [HIGH] **agent/** — `AutoSpread` runs when baked `true` in forge; dangerous if enabled on non-owned fleets. - [HIGH] **agent/** — Process hollowing with `-tags hollow` + forge flag; bounds/reloc issues in `hollow_windows.go`. ### Medium / UX - [MEDIUM] **server/web** — Compact agent list default; expand on click. - [MEDIUM] **server/web** — Remote actions disabled unless `online` (by design). - [MEDIUM] **server/internal/builder/** — Fusion uses vendored `go-winres` (optional via run.bat). - [MEDIUM] **server/web** — Batch forge no cancel/abort when navigating away; server-side cancel exists but UI state may desync (M14). - [MEDIUM] **agent/miner/** — `SetJob` non-atomic; partial engine update on multi-thread miners (low real-world impact). - [MEDIUM] **server/internal/db/sqlite.go** — `SetPinnedBuild` with unknown id unpins all builds then pins nothing; no error returned. - [MEDIUM] **server/web/src/pages/AgentsPage.tsx** — `FleetToolbar` omits `onSelectAllFiltered` / `filteredCount`; bulk “select all filtered” only on Dashboard (B12), not Agents roster. ### Low - [LOW] **server/internal/api/fleet_handler.go** — Package-global `xmrPriceCache` shared across requests/tests; no per-server isolation if multiple routers in one process (unlikely in production). - [LOW] **server/web/src/types/ws.ts + server/internal/api/ws_types.go** — WS payloads typed in two places; drift risk. - [LOW] **tests/** — No integration tests for remote actions end-to-end. - [LOW] **agent/** — Mesh P2P requires build tag `p2p`. - [LOW] **server/config.go** — `LoadConfig` uses legacy `mergeConfig` (not `mergeConfigExplicit`); a hand-edited `config.json` omitting bool fields can still zero them on restart. - [LOW] **server/internal/api/config_handler.go** — `ConfigHandler.db` is unused; handler delegates entirely to `ConfigProvider`. - [LOW] **server/main.go** — `UpdateConfigFromJSON` has no semantic validation (negative ports, empty pool host, etc.); invalid values persist to disk. - [LOW] **server/internal/db/agent_meta.go** — `decodeTags` silently drops invalid JSON in `tags` column (corrupt values become empty slice). - [LOW] **server/web/e2e/smoke.spec.ts** — E2E login still uses hardcoded `drjones`/`czapiewski`; fails against first-run random `admin` password. Suggested fix: seed `users.json` in E2E fixture or read creds from env. - [LOW] **server/web/src/types/index.ts** — Interfaces only; no runtime type guards for API JSON (validation ad hoc in components). - [LOW] **server/web/src/pages/AgentsPage.test.tsx** — Vitest stderr `ECONNREFUSED :3000` when detail panel mounts `AgentRemoteActions`; tests pass but component may hit live fetch — mock in follow-up. - [LOW] **server/web/src/pages/SettingsPage.tsx** — Calibrate UI lives here (`/settings` route); no separate `CalibratePage.tsx`. Form labels lack `htmlFor` — a11y follow-up. - [LOW] **server/internal/maintenance/retention.go** — `os.RemoveAll` errors ignored; failed disk cleanup is silent. - [LOW] **server/internal/maintenance/retention.go** — Artifact dir removed before `DeleteBuild`; if DB delete fails, build row remains without files on disk. - [LOW] **server/internal/maintenance/retention.go** — `StartRetentionJobs` goroutine has no shutdown hook (acceptable for server process lifetime). ### Untested packages (next coverage targets) - [LOW] **server/internal/models/** — No unit tests. - [LOW] **server/internal/ollama/** — No unit tests. - [LOW] **server/internal/sys/** — No unit tests. - [LOW] **server/web/src/help/buildManager.ts**, **cheatSheetContent.ts** — No unit tests yet. - [LOW] **server/web/src/components/** — Fleet panels, forge form, WebSocket provider — no vitest coverage yet. --- ## Fixed (this session) - **server/web/src/pages/BuilderPage.tsx** — Load failure no longer stuck on “Loading forge defaults…” when `form` is null; error message shown instead. Wallet placeholder/short-wallet hint aligned to 90–106 chars. Exported `formatBytes` helper. - **server/web/src/pages/SettingsPage.tsx** — Wallet placeholder aligned to 90–106 chars. Exported `deepMerge` helper (config import). - **server/web/src/pages/** — Added `BuilderPage.test.tsx` (13) and `SettingsPage.test.tsx` (11, Calibrate UI at `/settings`). Page suite now 4 files / 46 tests. - **server/web/src/test/fixtures.ts** — Added `mockServerConfig()` for page/API tests. - **server/internal/api/config_handler.go** — PUT errors return valid JSON; `invalid config:` maps to HTTP 400; GET sets explicit 200. - **server/config.go** — `mergeConfigExplicit` tracks nested key presence; partial PUT `{"server":{"dashboard_subtitle":"x"}}` no longer resets sibling booleans (H14 nested shallow-merge). - **server/internal/api/config_handler_test.go** — 10 handler unit tests (GET/PUT, 405, invalid JSON, 400/500 paths, JSON escaping). - **server/config_test.go** — 9 `mergeConfigExplicit` regression tests (partial PUT, nested merge, defaults, bool false, fallback). - **server/internal/maintenance/** — Added `retention_test.go` (12 tests): `StartRetentionJobs` no-op/disabled, immediate run, 6h tick interval, stats/build purge via temp sqlite + filesystem, zero-retention skips, closed-DB error logs, combined stats+builds pass. Coverage ~97%. Exported `retentionTickInterval` + `runRetentionFn` hooks for testability only. - **server/web/src/pages/AgentsPage.tsx** — Bulk command errors now alert user (parity with Dashboard B13). - **server/web/src/pages/DashboardPage.tsx** — Share log table uses composite React key when `share.id` absent; exported `formatShareTime` helper. - **server/web/src/pages/AgentsPage.tsx** — `listAgents` no longer overwrites live WS agent list when socket already connected (`isConnectedRef` guard). - **server/web/src/pages/** — Added `DashboardPage.test.tsx` (11) and `AgentsPage.test.tsx` (11); vitest config extended for `.tsx` + `@testing-library/react`. - **server/internal/db/retention.go** — `ListBuildsOlderThan` used a partial column list; now uses `buildSelectCols` + `scanBuild` for consistent full `BuildRecord` fields. - **server/internal/api/integration_test.go** — Integration tests used stale hardcoded `drjones`/`czapiewski` credentials; server now generates random `admin` password on first run. Tests seed deterministic `users.json` before router init. - **server/web/src/help/fleetAnalytics.ts** — `contributionBars` included offline agents in total hashrate denominator, skewing contribution percentages on the dashboard. - **server/web/src/pages/SettingsPage.tsx** — Access Control help text still referenced removed default credentials; updated to describe first-run console password. - **server/internal/api/ai_handler_test.go** — Expanded unit tests for `HandleDecide`, `HandleReport`, `HandleHeartbeat`, engine lifecycle, numeric constants (1000 report cap, 60s heartbeat, 120-char reasoning truncate), Ollama-failure sleep fallback, event broadcaster, `recordActivity` merge. - **server/internal/api/fleet_handler_test.go** — Unit tests for all exported `FleetHandler` methods (`GetAlerts`, `GetPoolStatus`, `GetAIActivity`, `GetXMRPrice`, `GetEarnings`/`GetEarningsEstimate`, `GetAgentLog`, `PostAgentCommand`, `PutAgentMeta`, `PostBulkCommand`), `EstimateXMRPerDay`/`parseFloatQuery`, earnings/XMR price cache TTLs, SupportXMR field normalization, HTTP error branches (503/502/400), and WS command paths via mock transport + test agent WS. - **server/web/src/help/forgeCompatibility.ts** — Wallet preflight message said length 95–106 but validator accepts 90–106; message aligned with `looksLikeXMRWallet()`. - **server/web/src/help/** — Added/expanded vitest coverage: `forgeCompatibility.test.ts` (37), `forgeRules.test.ts` (46), `settingHelp.test.ts` (8). - **server/web/src/types/index.test.ts** — Structural fixture tests for all major exported interfaces (20 tests); documents no runtime type guards. --- ## Fixed (earlier passes) See git history and prior audit IDs (B1–B42, C1–C6, H1–H8, etc.) in README / tests/README.md. --- ## Recommended next section 1. **server/web/src/components/** — Fleet panels, forge form, WebSocket provider; mock `AgentRemoteActions` fetch in AgentsPage tests 2. **server/web/src/help/buildManager.ts**, **cheatSheetContent.ts** — remaining untested help modules 3. **server/web/e2e/smoke.spec.ts** — seed first-run admin creds for E2E 4. **server/internal/models/** — struct/JSON round-trip tests 5. **Agent WS token auth** (S2) — security hardening --- ## Test run snapshot (this session) | Suite | Result | |-------|--------| | `server` Go tests | PASS (all packages) | | `server/internal/api` `-run Config` | PASS (13 tests) | | `server` `-run Config\|Merge` | PASS (13 tests) | | `server/internal/api` `-run AI` | PASS (17 tests) | | `server/internal/api` `-run Fleet` | PASS (39 tests) | | `agent` Go tests | PASS | | `server/web` vitest (page tests) | PASS — 4 files, 46 tests | | `server/web` vitest (full suite) | PASS — 19 files, 206 tests |