Add universal forge, fusion disguise, remote deploy, and stability fixes.

Ship cross-platform spread kits and fusion ZIPs with per-OS launchers, one-liner dropper endpoints, Windows file disguise, and a large batch of wiring/bug fixes so agents connect reliably across a LAN test fleet.
This commit is contained in:
drjones
2026-05-29 20:53:13 -07:00
parent c6c2e73359
commit 0f9e04f5f6
108 changed files with 5937 additions and 1233 deletions

View File

@@ -28,6 +28,30 @@ Findings grouped by severity. Updated after full bug-hunt pass (May 2026).
| B16 | **Fusion `worker_first` blocked forever** — worker launches async; media runs immediately |
| B17 | **Agent empty `new_job`** — logs error and re-requests job |
| B18 | **Agent WS read deadline**`PongHandler` extends deadline on server ping |
| B19 | **Windows-only forge/agent** — cross-platform workers (Linux/macOS), universal ZIP, Spread Kit, OS badges on dashboard |
| B20 | **generateBuiltinConfig / BuiltinConfig mismatch** — added `BackupServerURLs`, `ServiceMasquerade`, `ServiceName`, `ServiceDonor` to `BuiltinConfig`; template now matches struct exactly; new unit test `TestGenerateBuiltinConfigValid` guards against regression |
| B21 | **Fusion media files not copied for Linux/macOS**`prepareFusionProject` now copies `media_linux.go`, `media_darwin.go`, `cache_unix.go`, `cache_windows.go`; removed deleted `media_stub.go` from copy list |
| B22 | **Universal fusion launch scripts called `worker --spread-install`** — replaced with `fusionUniversalStartSh/Bat/Command()` that invoke the `runner` binary per-platform; README updated with per-OS instructions |
| B23 | **Dashboard WS concurrent write race** — introduced `DashboardConn` wrapper with `sync.Mutex`; `broadcastDashboard` and `runPingLoopDash` serialize writes per connection |
| B24 | **Spread kit `FileSize`/`BundleSize` from worker stat** — both now use ZIP stat; also fixed same issue in `finishUniversalFusion` |
| B25 | **InsertBuild errors silently ignored in universal paths** — now logged; error returned without failing the build (ZIP is still valid) |
| B26 | **Duplicate `auto_start` key in `spreadKitPreset`** — removed duplicate that caused TS1117 compile error |
| B27 | **AgentsPage empty state Windows-only message** — updated to mention Windows, Linux, and macOS |
| B28 | **H15: submitShare conn data race**`c.conn` now snapshotted under mutex before use |
| B29 | **H14: mergeConfig bool corruption**`mergeConfigExplicit` only applies booleans when the parent JSON key was present; partial PUT can no longer reset `UseTLS`, `SilentMode`, `AutoStart`, etc. to false |
| B30 | **M13: command_result dropped** — replaced single `latestMessage` slot with `commandResults` FIFO queue (cap 50); `AgentRemoteActions` iterates all new entries so no result is missed |
| B31 | **L6: terminalLog memory leak** — capped at 500 entries; oldest lines dropped automatically |
| B32 | **H17: pool requestID race**`requestID` increments in `subscribe()` and `submitShareToPool()` now guarded by the write lock |
| B33 | **M20: AutoSpread goroutine storm**`/24` sweep uses a 16-slot semaphore on both Windows and Unix; max 16 concurrent spread attempts at any time |
| B34 | **H16: AI reinstall on Windows** — move-old trick: live exe renamed to `.exe.old` before replacing; restored on failure |
| B35 | **M17: MaxAgents TOCTOU** — count check moved inside the write lock at registration time; two concurrent new agents can no longer both slip past the cap |
| B36 | **M18: GetAgentLog blocks**`?refresh=1` now fire-and-forget; result arrives via WS `command_result` broadcast instead of 1.8 s polling loop |
| B37 | **M16: Earnings estimator race**`AbortController` per fetch; stale response ignored if a newer request already fired |
| B38 | **M12: Duplicate WS connections**`WebSocketProvider` mounts one connection at the `App` level; all components share it via context; `useWebSocket()` is now a thin context read |
| B39 | **M15: Re-forge without prep file** — clear error message shown immediately when `fusion_enabled` but no payload uploaded, with instructions to re-upload first |
| B40 | **L1/L2: Dead CSS + duplicate imports** — removed dead `.agent-actions` rule from `FleetPanels.css`; removed redundant CSS imports from `AgentsPage`, `DashboardPage`, `BuilderPage` (each component already imports its own CSS) |
| B41 | **L7: Matrix animation restarts on share**`recentShares` moved to a `useRef` read inside the draw loop; `useEffect` dependency list now only contains `active` |
| B42 | **L9: Blueprint file permissions**`os.WriteFile` mode changed from `0644` to `0600` |
---
@@ -77,11 +101,6 @@ Findings grouped by severity. Updated after full bug-hunt pass (May 2026).
| H9 | `upload_log` returns content in tool report only | No dedicated log ingest API |
| H11 | `AutoSpread` runs when baked `true` in forge | Feature-gated but dangerous if enabled |
| H12 | Process hollowing with `-tags hollow` + forge flag | Bounds/reloc issues in `hollow_windows.go` |
| H14 | **Partial config PUT corrupts bools** | `mergeConfig` overwrites `UseTLS`, logging flags, etc. with zero values |
| H15 | **Agent `conn` data race** | `submitShare` reads `c.conn` without mutex |
| H16 | **AI reinstall while running** | `os.Rename` fails on Windows when exe in use |
| H17 | **Pool `requestID` / write races** | Concurrent share submits can interleave Stratum lines |
| H18 | **WS concurrent writes** | Ping loop vs broadcast on same dashboard connections |
---
@@ -92,15 +111,8 @@ Findings grouped by severity. Updated after full bug-hunt pass (May 2026).
| M1 | Compact agent list default | Expand on click |
| M6 | Remote actions disabled unless `online` | By design |
| M9 | Fusion uses vendored `go-winres` | Optional via run.bat |
| M12 | **Multiple `useWebSocket()` hooks** | Dashboard + Matrix overlay = duplicate connections |
| M13 | **`latestWsMessage` drops rapid results** | Only last message kept; command results can be lost |
| M14 | **Batch forge no cancel/abort** | State updates after navigate away |
| M15 | **Re-forge fusion without re-upload** | `reForgeFromBuild` needs prep file |
| M16 | **Earnings estimator race** | Stale API response can overwrite newer estimate |
| M17 | **`MaxAgents` TOCTOU** | Limit checked before lock on agent WS auth |
| M18 | **`GetAgentLog?refresh=1` blocks** | Up to ~1.8s synchronous sleep per request |
| M19 | **`SetJob` non-atomic** | Partial engine update on multi-thread miners |
| M20 | **Autospread goroutine storm** | Up to ~254 goroutines per /24 sweep |
| M19 | **`SetJob` non-atomic** | Partial engine update on multi-thread miners (low real-world impact) |
---
@@ -108,15 +120,10 @@ Findings grouped by severity. Updated after full bug-hunt pass (May 2026).
| ID | Issue |
|----|-------|
| L1 | Dead CSS `.agent-actions` in `FleetPanels.css` |
| L2 | Duplicate CSS imports on Dashboard/Agents |
| L3 | WS payloads typed in two places (`types/ws.ts` + Go) |
| L4 | No integration tests for remote actions |
| L5 | Mesh P2P requires build tag `p2p` |
| L6 | `terminalLog` / `agentLogs` grow without bound |
| L7 | Matrix overlay restarts animation on every share |
| L8 | Settings config import shallow-merge |
| L9 | Blueprint files written mode `0644` |
| L10 | XOR media crypto — weak confidentiality by design |
---
@@ -144,8 +151,7 @@ See **[tests/README.md](tests/README.md)** for phase breakdown and E2E options.
## Priority for next pass
1. Agent WS token auth (bind `agent_id` to build secret)
2. Dashboard WS auth (match REST Basic auth)
3. Config merge with pointer types / explicit fields
4. Shared WebSocket context (single connection app-wide)
5. Process hollowing bounds + reloc (`hollow_windows.go`)
1. **Agent WS token auth** bind `agent_id` to build secret baked into each forged binary; verify on connect (S2)
2. **Dashboard WS auth** — require session cookie on WS upgrade (S3)
3. **Process hollowing bounds + reloc** — fix `hollow_windows.go` (H12)
4. **Batch forge cancel** — AbortController + server-side queue cancel (M14)