Bug fixes: - SRV-B1 through B5: server config, router, server_info, syscheck corrections - BA-03 through BA-06: builder path and universal build cleanup (BLD-D1 through D3) - Frontend WS race condition and useVisibleInterval hook fixed - Drive-root path bug in PathForge resolved - Upload error handling improved Security: - PathForge path traversal guard added - Script injection escaping applied throughout Visual (DV-01 through DV-15): - Cyan design tokens and page headers standardised - Dead CSS removed from Pages.css, PathTracerPage.css, wealth-deck.css - SacredPageHeader deleted (replaced inline); sidebar version display fixed UX: - Emberwake request storm fixed (EmberwakePage.tsx) - Help blurbs UH-01, UH-02, UH-06 added - HelpTips wired into Crucible, Fleet (FleetGroupsStrip, FleetToolbar), Settings Build: - vite.config.ts: webroot auto-sync on build - build_universal.go: universal build artifact cleanup - PROBLEMS.md tracking updated
29 KiB
Open medium / by design
| Issue | Notes |
|-------|-------|
| bof_execute disabled | Agent returns explicit error in-memory BOF execution disabled for safety (client.go). |
| Process hollowing AMSI/ETW | Relocation patching done; Defender/ETW detection causes ~50% failure bypass not implemented (hollow_windows.go). |
| Cloudflared on Linux server | In-process tunnel start is Windows-only; Linux/macOS builds use no-op stub use external connector (AF_TUNNEL_EXTERNAL) or add cross-platform launcher. |
| macOS camera / GPU miner | Stubs return "not supported"; Linux has V4L2 + nvidia-smi path. |
| Agent WireGuard auto-download | Windows ensureWGExe() downloads WireGuard on first Path Tracer use heavy side effect; pre-install recommended. |
| Non-Windows Path Tracer agent parity | pathtracer_stub.go returns error on wg_setup; Linux/macOS agents cannot join WireGuard chains. |
| KEV heuristics | Non-Windows agents return catalog with Status: n/a Windows-only CVE matching.
Open large / deferred
| Issue | Notes |
|-------|-------|
| Non-Windows agent parity | pathtracer_stub.go returns error JSON on wg_setup; Linux/macOS cannot join chains. UI filters platform; server does not validate platform field. |
| In-memory sessions only | TraceSession map in handler RAM server restart loses session state while agents may still hold tunnels; no DB persistence or startup sweep. |
| WireGuard auto-download | Windows ensureWGExe() silently downloads/installs WireGuard on first use heavy, needs admin, no progress UI. |
| No PathTracerPage Vitest | Page logic (polling, chain selection, QR modal) untested; only uiHelp.test.ts covers help keys. |
| No agent-side pathtracer tests | pathtracer_windows.go / stub have zero Go tests. |
| NAT / symmetric UDP | UPnP + DB IP fallback may still yield unreachable endpoints; no STUN/TURN or connectivity probe after configure. |
| Fixed listen port 51820 | All hops use same UDP port multiple agents behind one NAT may conflict; no per-hop port allocation. |
| Agent display name vs hostname | WS auth UpsertAgent overwrites name with hostname on every connect operator-renamed fleet labels may not appear in Path Tracer unless re-saved after connect. |
Open medium / UX
| Issue | Notes |
|-------|-------|
| Visual island (green vs deck) | Page uses #00ffaa WireGuard chrome while data-operator-deck='pathtracer' sets blue accent (operatorDeck.css); intentional branding split (see DV-07). |
| Status polling only | UI polls /status every 2s no WebSocket push for hop progress; acceptable latency but stale during orchestration. |
| Error path leaves tracing UI | On status.error, tracing clears but session remains server-side until operator clicks End or TTL hops show failed state in chain panel. |
Open large / deferred
| Issue | Notes |
|-------|-------|
| No CI-automated HTTP forge | scripts/e2e-validate.ps1 -ForgeAgent still manual (multipart fusion, long compile). Live compile gated behind LIVE_FORGE=1 + -tags liveforge. |
| PathForge test gaps | Only TestPathForgePlacedExcludesHintFile; no skipped-counter, lock-original, or frontend UI tests. |
| Forge cancellation / batch races | Cancel token API tested in isolation; concurrent batch forge + mid-compile cancel not covered. |
| Non-Windows forge host limits | PE disguise (disguise_stub.go) and Windows signing (sign_stub.go / osslsigncode) are platform-constrained by design. |
| Mac PathForge runtime dependency | .command launchers curl /api/download/agent-mac at runtime requires reachable server_url and pre-placed agent binary. |
Open low
| Issue | Notes |
|-------|-------|
| \pathforge_test.go\ dead loop | Fixed. Replaced the no-op loop with meaningful assertions: each entry Files must contain the hint file and at least one launcher companion, confirming the hint is placed but not counted in Placed. Pre-existing err := redeclaration compile error in pathforge.go L128 also fixed. |
Open (document-only / deferred)
| Issue | Notes |
|-------|--------|
| Dual storage without sync policy | Complex cross-tab sync session preferred over local; aetherforge-auth event on logout |
| Flaky progress simulation vs. real compile time | Cosmetic stage timeline caps at 94% until server responds (45 min client timeout) |
| Path Forge / batch fusion test gaps | Cancellation, partial batch failure, cancel-token races needs dedicated tests |
| DashboardPage tests emit ECONNREFUSED stderr | Failure-path tests; happy-dom hits localhost:3000; tests pass |
| DownloadButton mock aliasing pattern | Document for new download helpers shared mock fn already in components.test.tsx |
--
Open (2026-06-06 audit LARGE)
-
tunnel_streamnot implemented server-side TCP reverse relay documented as future work (README.md). -
Server
cloudflaredlauncher no-op on non-Windows Linux server deploy cannot auto-launch tunnels (cloudflared/launcher_stub.go).
Low (open)
Clarified. The API PUT handler usesmergeConfigpartial-PUTUseTLSlegacy behaviormergeConfigExplicitwith a field-mask so absent keys never reset booleans. The legacymergeConfig(file-load fallback only) unconditionally copies bools -- documented with a header comment in config.go. Test at config_test.go L526-528 updated to assert the expected behavior and explain the distinction.
High (open)
- Non-Windows Path Tracer agent parity
pathtracer_stub.goreturns error onwg_setup; Linux/macOS agents cannot join WireGuard chains.
Medium (open)
-
Agent WireGuard auto-download: Windows agent
ensureWGExe()downloads and silently installs WireGuard fromdownload.wireguard.comon first Path Tracer use if not already present (agent/client/pathtracer_windows.go). Heavy side effect; no server-side fix operator should pre-install WireGuard on fleet hosts or accept first-run download latency. -
Mac PathForge
.commandstill depends onserver_url+/api/download/agent-macat runtime (now validated at forge time).
| Op | Command | Notes |
|----|---------|-------|
| SMB share enumeration | smb_shares | Windows + Remote Aggressive; ARP/subnet hosts ? net view JSON |
| Spread status | spread_status | In-memory last sweep (deploy/spread_status.go); read-only |
| Credential names | credential_vault_list | Win Credential Manager / macOS Keychain / Linux secret-tool + ~/.ssh paths names only |
| Secure wipe | secure_wipe | Overwrite-then-delete folder; system-root guards; confirm in UI |
| Port-forward matrix | tunnel_ssh_forward × N | CruciblePortForwardMatrix multi-row grid on selected Windows nodes |
UI: Phase C controls in CrucibleExpandedOps.tsx Fleet Maintenance (replaces coming soon stubs).
Linux / macOS parity
| Area | Status |
|------|--------|
| Mining + hashrate | RandomX pure-Go engine works on Linux/macOS; stats loop sends hashrate_15s/1m/15m + shares over WS. |
| Idle schedule guard | Fixed SystemCPUPercent was always 0 on Unix (reporter_unix.go), blocking idle-mode mining; Linux uses /proc/stat, macOS uses sysctl kern.cp_time. |
| Screenshot | Linux: scrot / ImageMagick import / gnome-screenshot. macOS: screencapture. |
| Camera | Linux V4L2 via ffmpeg/fswebcam (camera_linux.go). macOS: stub. |
| File ops | Cross-platform (file_ops_unix.go / file_ops_windows.go). |
| Posture | Unix collectors return firewall/AV/patch data (posture_unix.go), not all n/a. |
| Spread | SSH path on Linux/macOS (autospread_unix.go); SMB/WinRM Windows-only by design. |
| Firewall ops | Linux ufw/iptables (firewall_linux_ops.go); macOS pf + socketfilterfw (firewall_darwin_ops.go); other Unix stubs. |
| GPU miner | Windows-only T-Rex path; Linux/macOS stub with detect-only. |
| Docker E2E | docker/docker-compose.yml isolated agent + server; see docker/README.md. |
Open
-
Client: WebSocket/beacon paths integration-only in CI (Docker Tier 2 closes Linux slice).
-
macOS: camera, GPU miner stubs or partial; firewall aggressive ops implemented (see Backend BE-04).
-
Linux screenshot: headless containers need
xvfb+ scrot or customcommandfield. -
bof_executepermanently disabled handler always fails (client.go); product/safety decision. -
Linux/macOS GPU RVN mining broken
detectGPU()may find NVIDIA, butspec()downloads Windows.exeminers (gpu_miner.go,gpu_detect_stub.go). -
Mesh P2P without
-tags p2p default build reports 0 peers; UI exposesmesh_statuswith re-forge hint (mesh_p2p_stub.go). -
Process hollowing AMSI/ETW bypass not implemented documented ~50% failure rate (
hollow_windows.go). -
KEV exposure scan non-Windows all CVEs marked
n/a(cve_scan_stub.go). -
Unknown Unix CPU stats stub returns 0 can break idle-mining guard on exotic platforms (
cpu_stub.go).
Open (document-only / deferred)
| Issue | Notes |
|-------|--------|
| Dual storage without sync policy | Complex cross-tab sync session preferred over local; aetherforge-auth event on logout |
| Flaky progress simulation vs. real compile time | Cosmetic stage timeline caps at 94% until server responds (45 min client timeout) |
| Path Forge / batch fusion test gaps | Cancellation, partial batch failure, cancel-token races needs dedicated tests |
| DashboardPage tests emit ECONNREFUSED stderr | Failure-path tests; happy-dom hits localhost:3000; tests pass |
| DownloadButton mock aliasing pattern | Document for new download helpers shared mock fn already in components.test.tsx |
| | Fixed. Changed server/webroot not auto-synced on npm run buildvite.config.ts build.outDir from dist to ../webroot (with emptyOutDir: true). npm run build now writes directly to server/webroot/ -- no manual copy step required. |
| Vitest stderr noise | FleetTopologyMap three.js tags warn in happy-dom tests pass |
Open (needs product copy or broader pass)
| ID | Issue | Notes |
|----|-------|-------|
| UH-01 | Crucible expanded ops (spread/tunnels/recon buttons) | Fixed: Added HelpTip to the four most confusing individual buttons (Spread Now, Subnet Scan, Hole Punch, Start Tunnel) in CrucibleExpandedOps.tsx, plus 10 new keys in uiHelp.ts. All section headers already carry helpField via CrucibleCollapsibleSection. |
| UH-02 | Fleet Roster / Agents page bulk toolbar | Fixed: Added HelpTip to filter row (fl_filter_chips), bulk-action bar (fl_bulk_actions) in FleetToolbar.tsx, and Groups label (fl_groups) in FleetGroupsStrip.tsx. |
| UH-03 | Emberwake / War Room campaign widgets | Funnel stages need HelpTip parity with Command Deck funnel |
| UH-04 | Mission Deck | Page has minimal operator guidance |
| UH-05 | Builder mission wizard chips | Inline blurbs exist on chips; not all advanced forge sections have HelpTip (see docAnchors.test gap list) |
| UH-06 | Settings tabs beyond Calibrate/Forge | Fixed: Added HelpTip to Fleet Alerts heading (set_alerts), Alert Notifications heading (set_alert_notifications), and Webhook URL field (set_webhook) in SettingsPage.tsx. |
Open (visual / UX debt)
| ID | Issue | Files / notes |
|----|-------|----------------|
| DV-01 | Neon cyan fragmentation canonical token is --neon-cyan: #00e8f5 but components hard-code #00f5ff, #00e5ff, and #0ff fallbacks | AgentRemoteActions.css, HashrateChart.tsx, BuildManagerPage.tsx, ProtocolTunnelPanel.css, FileManager.css (fixed), sacred geometry SVGs |
| DV-02 | Page header patterns diverge most pages use deck-hero + eyebrow; Build Manager uses bm-header / bm-title; Path Tracer uses green .pt-title (#00ffaa); Forge says The Forge vs nav Forge | BuildManagerPage.tsx/css, PathTracerPage.css, BuilderPage.tsx, Layout.tsx NAV |
| DV-03 | SacredPageHeader unused component + .page-header--sacred CSS exist but no page imports it; dead design path | SacredPageHeader.tsx, sacred-geometry.css |
| DV-04 | Pages.css duplicate / conflicting rules two .empty-state blocks (L192 vs L1078); second .page-header h1 block overrides visual-polish gradient when page CSS loads after global polish | Pages.css; load order via per-page imports |
| DV-05 | Default dashboard subtitle out-of-box copy is security is just an emotion until Calibrate overrides dashboard_subtitle; reads as placeholder to new operators | DashboardPage.tsx L70; SettingsPage.tsx L131 |
| DV-06 | Path Tracer buried in nav desktop sidebar lists it last; mobile hides it under More while Crucible/Forge are primary tabs | Layout.tsx MOBILE_PRIMARY vs MOBILE_MORE |
| DV-07 | Path Tracer visual island green WireGuard aesthetic (#00ffaa) does not use operator-deck page classes or brass/neon deck chrome | PathTracerPage.css, PathTracerPage.tsx (missing operator-deck-page) |
| DV-08 | Chart lazy-load placeholder is invisible ChartPlaceholder is an empty div at 35% opacity; advanced charts pop in with layout shift | DashboardPage.tsx L5153 |
| DV-09 | Dead chart badge styles .chart-live.sample / .blend in wealth-deck CSS; resolveChartSeries no longer emits sample mode | wealth-deck.css; chartSampleData.ts |
| DV-10 | Docs vs in-app naming drift wiki says Calibrate (Settings), Command Deck, Forge / Builder; nav uses Calibrate, Command Deck, Forge; Emberwake route was /spread redirect | public/docs/index.html, Layout.tsx, App.tsx |
| DV-11 | Public spread landing vs Emberwake /spread/ static kit uses aether.css deck tokens (good) but typography/spacing differs slightly from in-app Emberwake cards | public/spread/assets/aether.css, EmberwakePage.css |
| DV-12 | Emoji in status bar / actions ?? DOCS pill, agent action buttons (?? ? ?) inconsistent with otherwise SVG-icon nav | SystemStatusBar.tsx, AgentRemoteActions.tsx |
| DV-13 | No light theme entire product is dark-only; docs wiki matches but no prefers-color-scheme path | global styles |
| DV-14 | Sidebar version hard-coded footer shows v0.0.1 regardless of server build | Layout.tsx L321 |
| DV-15 | Mission Deck formatting source file has excessive blank lines (likely formatter artifact); harder to maintain, no runtime impact | MissionDeckPage.tsx |
Remaining doc gaps (need product copy / user input)
| Topic | Notes |
|-------|-------|
| Default dashboard subtitle | security is just an emotion until Calibrate override marketing copy decision (DV-05) |
| SocGholish / fake-update lander | Documented in spread playbook #third-party tab; no shipped branded HTML template |
| OAuth redirect abuse playbook | Research only no Entra app wizard in Emberwake |
| Earnings USD quote | TEST_RESULTS.md notes low priority; not wired |
| Screenshot placeholders in wiki | [Screenshot:
] divs need real captures from operator deck |
| Sidebar version v0.0.1 | Hard-coded in Layout.tsx should read server build version (DV-14) |
| Light theme | Dark-only documented; no prefers-color-scheme path (DV-13) |
Deferred needs refactor, heavy mocks, or external deps
| Area | Why deferred |
|------|--------------|
| agent/cmd/mine-validate | Standalone CLI (main package); exercises RandomX + live Stratum; run manually or in mining CI |
| Cloudflared Start with real token | Spawns/downloads binary + network; only empty-token path covered |
| FleetScheduler.Start loop | 1-minute ticker; logic covered via direct tickInterval/tickCron in same-package tests |
| CruciblePage full integration | Large page; helpers + CrucibleExpandedOps + FileManager tested separately |
| Fleet panel widgets | Partially covered via components.test.tsx; full panel flows need WS mocks |
| Path Forge / batch fusion cancel races | Needs dedicated cancel-token harness |
| Playwright E2E (server/web/e2e/) | Phase 8 of test-suite; requires build + temp server |
| Docker mining E2E | .github/workflows/ci-docker-mining.yml separate tier |
| Mesh P2P | Requires -tags p2p build tag |
| Platform-specific fusion launchers | OS-gated; crypto path covered in media_crypto_test.go |
| Suite | Result | Notes |
|-------|--------|-------|
| go test ./... (repo root) | N/A | No root go.mod; use per-module dirs (documented in Integration audit). |
| agent/ | PASS | All packages ok (client ~3s). |
| server/ | PASS | internal/api ~69s, internal/builder ~32s. |
| fusion/ | PASS | Includes media_crypto_test.go (untracked in git at time of pass). |
| server/web Vitest | PASS | 66 files / 587 tests (3 consecutive full runs). |
| Item | Notes |
|------|-------|
| Vitest stderr ECONNREFUSED 127.0.0.1:3000 | Failure-path / bulk-command tests in DashboardPage, AgentsPage, etc. (see Dashboard section). |
| FleetTopologyMap three.js ref warnings | happy-dom; cosmetic stderr. |
| Vite build chunk size warnings | three / vendor bundles > 500 kB; not a test failure. |
Bugs Builder/Security (Bug Team 4 audit, 2026-06-06)
Scope: server/internal/builder/, fusion/, server/config.go, cross-cutting API input validation and auth edge cases.
Fixed in this pass
| ID | Fix |
|----|-----|
| BLD-01 | PowerShell injection in uninstaller processName and persistenceKey were embedded in single-quoted PS1 strings without escaping apostrophes. A WorkerName like foo'; Invoke-Expression
; ' would break out of the string. Now uses strings.ReplaceAll(
, "'", "''") for both fields, consistent with how installRel was already escaped (uninstall.go). |
| BLD-02 | JSON build request body unbounded non-multipart POST /builder/build decoded r.Body without a size limit; a 1 GiB JSON body would buffer entirely. Fixed: http.MaxBytesReader capped to 512 KiB before json.Decode (handler.go). |
| BLD-03 | Unbounded backup pool/URL arrays BackupServerURLs, BackupPools, and RVNBackupPools from user input are concatenated verbatim into the generated Go source (generateBuiltinConfig). A request with 10 000 entries would produce a multi-MB .go file, slowing or crashing go build. Fixed: arrays truncated to 10 entries each in normalizeRequest (handler.go). |
| BLD-04 | Partial build dir not cleaned on failure when compileWorker, buildFusionFromRequest, writeUninstallScript, or MkdirAll fail mid-build, the entire builds/<uuid>/ tree (containing a copy of agent source + uploaded fusion payload) was left on disk. Added cleanupBuild() closure that calls os.RemoveAll(buildDir) on each failure return path (handler.go). |
| BLD-05 | Weak random password entropy generateRandomPassword() used only 4 random bytes (8 hex chars, 32-bit entropy), guessable in ~4 billion attempts. Increased to 8 bytes (16 hex chars, 64-bit entropy) (router.go). Test updated. |
| BLD-06 | Malformed config.json silently ignored json.Unmarshal failure was swallowed; operator saw no indication their config was rejected and defaults were running instead. Added fmt.Fprintf(os.Stderr,
) warning on parse failure (config.go). |
Deferred / large
| ID | Severity | Location | Description |
|----|----------|----------|-------------|
| BLD-D1 | High | server/internal/builder/pathforge.go | FIXED. Added validateRootPath to PathForgeHandler.ServeHTTP: rejects any root_path containing .. segments and enforces an allowlist of safe prefixes (server dataDir, user home directory, OS temp directory) via isAllowedRootPath / isPathUnder. Paths outside these prefixes return HTTP 400. |
| BLD-D2 | Medium | server/internal/builder/pathforge.go batContent / macContent | FIXED. Added four escaping helpers — escapeBat (%→%%, "→\"), escapeBatPS (adds '→'' for PowerShell single-quoted strings inside a cmd.exe -Command argument), escapeShDouble (\, ", $, ` backslash-escaped for bash double-quoted strings), escapeShSingle ('→'\'' for bash single-quoted strings). Applied: batContent uses escapeBat for ren/start arguments and escapeBatPS for the embedded PowerShell -Command string; macContent uses escapeShDouble for filenames and escapeShSingle for serverURL. |
| BLD-D3 | Low | server/internal/builder/build_universal.go | No partial build cleanup for universal builds. Fixed. Added cleanupBuild := func() { _ = os.RemoveAll(buildDir) } at the top of buildUniversalAgent, finishSpreadKit, and finishUniversalFusion, and called it on every failure return, matching the BLD-04 pattern. Also fixed a pre-existing err := → err = redeclaration compile error in pathforge.go L128 that was blocking all builder test compilation. |
Bugs Server (Bug Team 1 audit, 2026-06-06)
Deferred / large
| ID | Severity | Location | Description |
|----|----------|----------|-------------|
| SRV-B1 | High | server/main.go | No graceful shutdown on SIGINT/SIGTERM. Fixed. http.ListenAndServe replaced with http.Server + goroutine; signal.NotifyContext(syscall.SIGINT, syscall.SIGTERM) drives a srv.Shutdown(ctx) with 10 s timeout on signal, allowing all defer calls (cloudflared.Stop(), database.Close(), maintenance.StopRetentionJobs(), fleetSched.Stop()) to run cleanly. |
| SRV-B2 | Medium | server/internal/db/sqlite.go | SQLite max-connections not configured. Fixed. db.SetMaxOpenConns(1) added immediately after sql.Open; the single-connection pool eliminates concurrent-writer WAL-lock contention and SQLITE_BUSY errors under load. |
| SRV-B3 | Medium | server/internal/scheduler/fleet_scheduler.go | O(tasks × agents) DB queries per minute. Fixed. BulkLastFleetTaskRuns added to the db package; tickInterval now pre-fetches all relevant fleet_task_runs rows in a single query and checks an in-memory map[string]time.Time (keyed "agentID:taskID") in the nested loop — 1 query per tick instead of tasks × agents. |
| SRV-B4 | Medium | server/internal/api/websocket.go broadcastDashboard | Stale-conn cleanup races with Fixed. HandleDashboardWS teardown.broadcastDashboard no longer spawns a goroutine to delete the dashboard map entry on write failure. It only closes the connection; HandleDashboardWS already owns all map cleanup via its existing defer, so the double-delete and the spurious presence_update{online:false} are eliminated. |
| SRV-B5 | Low | server/internal/api/agent_ws_limiter.go | Rate-limiter map never purges zero-entry keys. Fixed. delete(agentWSRateLim.attempts, clientIP) called when len(filtered) == 0 after the expiry sweep; map keys are reclaimed as IP addresses churn out of the window. |
Backend
db.New/MkdirAll: Already returns error on failure (server/internal/db/sqlite.go); remove stale Low (open) note in Server API section when editing that doc block.
Frontend
-
RemoteDirBrowserremoval: No broken imports. UI logic lives inFileManager.tsx+src/help/remoteDirBrowser.ts;remoteDirBrowser.test.tscovers helpers. DeletedRemoteDirBrowser.tsx/.cssare not referenced elsewhere. -
FileManager.test.tsx: Untracked but picked up by Vitest (src/**/*.test.{ts,tsx}); 10 tests pass add to git when committing Fleet work. -
Download test mocks: Prefer separate
vi.fn()per export when mockingapi/download(real module aliasesdownloadApiFiletodownloadAuthedFile; shared mock caused order-dependent flakes).
Open large / architecture
| Issue | Notes |
|-------|-------|
| Monolithic WebSocket context | Every useWebSocket() consumer re-renders on any WS state change. Split into FleetContext / EventsContext or selector hook (useAgents()) for true isolation. |
| CruciblePage size (~2k lines) | Single component owns terminal, fleet list, tabs, file manager hard to memoize subtrees; consider section components + React.memo boundaries. |
| Per-agent stats_update broadcast | Backend sends one dashboard message per agent stats tick; no batching/coalescing in websocket.go. Fleet of N agents ? N JSON parses/frame on client. |
| SystemStatusBar REST poll duplicates WS | Polls listAgents every 15s though fleet already streams via WebSocket wire readout to WS or drop agent poll. |
| Vite chunk size | three (~600 kB) and vendor bundles trigger build warnings; FleetTopologyMap loads three on Dashboard already lazy but still heavy first open. |
| No terminal virtualization | DOM cap at 400 lines helps; full virtual list (react-window) needed for 2000-line scrollback without mount cost. |
| MatrixRain always mounted in Layout | Runs on every route including mobile (hidden sidebar but component still mounts on desktop). Consider content-visibility or route-gated mount. |
| Path Tracer 2s REST poll | No WS push for hop progress; acceptable but adds load during orchestration. |
Open medium
| Issue | Notes |
|-------|-------|
| Emberwake war room double feed | 15s client poll + 30s server runWarRoomBroadcast redundant; prefer WS-only with poll fallback. |
| CursorFire + SacredGeometry on all routes | Desktop-only effects still mount with Layout; gate on VisualEffectsContext or route. |
| Earnings estimate on every hashrate change | Dashboard debounces via totalHashrate effect could share chart sampler interval. |
Deferred large / complex
| Issue | Location | Notes |
|-------|----------|-------|
| WebSocketProvider async race | context/WebSocketProvider.tsx | Fixed (2026-06-06). Added openingRef (useRef(false)) in-flight guard -- a second connect() call while a ticket fetch is in progress returns early. Added AbortController (ticketAbortRef) to cancel any prior in-flight fetch; aborted invocations bail before creating a WebSocket. openingRef is always reset in a finally block. |
| | useVisibleInterval calls fn on every dep changehooks/usePageVisible.ts | Fixed (2026-06-06). fn is now stored in a fnRef (useRef). The effect depends only on ms, enabled, and visible -- an unstable fn reference no longer re-runs the effect or triggers an extra immediate call. The interval always invokes fnRef.current() so callers always see the latest fn without extra renders. |
Deferred large / medium
| ID | Issue | Location | Notes |
|----|-------|----------|-------|
| BA-03 | | write() has no write deadlineclient/client.go — write() | Fixed. c.conn.SetWriteDeadline(time.Now().Add(15*time.Second)) is now called immediately before WriteJSON (and cleared afterward), so a stalled TCP socket cannot hold c.mu indefinitely and deadlock share submission, stats, and command-result goroutines. |
| BA-04 | SSH/SCP spread commands have no overall timeout | deploy/autospread_unix.go attemptSSHSpread() | ConnectTimeout=3 limits only the TCP handshake; after a successful connection, scp.Run() and ssh
start.Run() have no deadline. A slow or unresponsive host stalls the goroutine indefinitely, holding a slot in spreadSem (16 total). With 16 such hangs in flight, all future spread goroutines block waiting on the semaphore. Fix: use exec.CommandContext with a ~30 s deadline wrapping the whole SCP + SSH sequence. Fixed: exec.CommandContext with context.WithTimeout(30s) wraps the full SCP + SSH sequence; a hung host releases its semaphore slot after 30 s. |
| BA-05 | GPU miner binary download has no HTTP timeout or body-size cap | client/gpu_miner.go downloadAndExtract() | http.Get(url) with no timeout and io.ReadAll(resp.Body) with no size limit. A slow redirect or a response that trickles bytes forever will hang the goroutine; a gigabyte-scale response could OOM the agent. Fix: use an http.Client with a 5-min overall timeout, and wrap the body in io.LimitReader(resp.Body, 512<<20). Fixed: http.Client{Timeout: 5*time.Minute} + io.LimitReader(resp.Body, 512<<20). |
| BA-06 | | Fixed (simpler approach): Reduced CollectFullSysCheck blocks for 45+ s on empty subnetsmaxHosts from 56 to 20 in ScanLocalSubnet() call in syscheck.go. Caps worst-case scan at ~16 s on an empty /24. No API change needed. |
Infrastructure
-
Root
fix.py,fix3.py,fix4.py: Untracked one-off Python string/regex editors targetingCruciblePage.tsx(ProtocolTunnelonDispatch, GPU hashrate label). Intended changes appear already applied inCruciblePage.tsx. Safe to delete after review; not run in CI do not rely on them for builds. -
CI: Only
.github/workflows/ci-docker-mining.yml(Docker mining); no root Makefile test target found. -
data/login-credentials.json,data/users.json: Untracked; do not commit (secrets/local data).