Emberwake spread/waterhole UI, campaign DB, spread handler, spread-kit web publisher, and SPREAD_TECHNIQUES doc. Crucible Phase A-C: expanded ops, port-forward matrix, remote dir browser, crucible help/tests. Linux agent hardening: credential vault, persistence audit, firewall/defender deploy, SMB spread status, CPU stats, screenshots/crypt/file-ops split. Docker compose and agent/server images with e2e validation script and docs. Musical dashboard: ambient music player, hover SFX, SoundContext/AmbientMusicContext, steampunk polish. Public builds API, dropper handler updates, SessionGate and fleet UX. README and PROBLEMS.md refresh.
11 KiB
11 KiB
Builder / Forge
Scope: B-01–B-13 (2026-06-04 pass). go test ./internal/builder/... ./internal/api/... — run after changes.
Fixed in this pass
| ID | Fix |
|---|---|
| B-01 | checkBuildSizeFile enforced on universal/spread-kit and universal-fusion ZIP outputs (limits.go, build_universal.go). |
| B-02 | signExecutable runs on spread-kit workers and universal-fusion runners when sign_build is set (build_universal.go). |
| B-03 | Dropper /get resolves DownloadURL artifact paths before FilePath (dropper_handler.go; dataDir on handler). |
| B-04 | Fusion launcher compile respects shouldObfuscate / garble (fusion_media.go). |
| B-05 | Fusion estimate uses paired/embedded sizing; removed stale "video" kind branch (estimate.go). |
| B-06 | Estimate adds signingToolMissingNote when cert configured but signtool/osslsigncode absent (estimate.go, sign_*.go). |
| B-07 | Universal fusion README RunnerName uses disguisedRunnerName(payloadBase) (build_universal.go). |
| B-08 | publishFusionDeliverable falls back to dataDir when projectRoot empty (fusion_media.go). |
| B-09 | PathForge Placed excludes hint file from count (pathforge.go). |
| B-10 | Multipart parse limit raised to multipartMaxMemory (2 GiB + headroom) (limits.go, handler.go). |
| B-11 | Dropper PS1 ZIP handler also tries start.bat / deploy.bat (dropper_handler.go). |
| B-12 | DownloadBuild Content-Disposition uses FileName (handler.go). |
| B-13 | resolveToolPaths probes bundled toolchain/gopath/bin for garble and go-winres (winres.go). |
Open
(none in B-01–B-13 scope)
Dashboard (React/Vite)
Audit fixes: 2026-06-04. npm run test -- --run in server/web — pass.
Fixed in this pass
| Fix | Area |
|---|---|
| SessionGate distinguishes 401 vs transport errors; network blip keeps saved credentials with degraded banner | SessionGate.tsx |
Session expiry message when 401 clears auth mid-session (consumeAuthExpiredFlag) |
auth.ts; client.ts; SessionGate.tsx |
Download timeouts + AbortError messaging: downloadAuthedFile, downloadAgentLog, downloadBackup (5 min / 10 min) |
download.ts; client.ts |
Agent log refresh=1 uses 90s timeout (long-poll) |
client.ts |
| Re-forge requires confirmation before compile; fusion prep picker highlights on missing payload | BuilderPage.tsx |
BuildManager delete/pin errors surfaced; dropper copy clarifies pinned vs latest; serverBase prefers suggested_url via parallel getServerInfo |
BuildManagerPage.tsx |
Open (document-only / deferred)
| Issue | Notes |
|---|---|
| Emberwake public-build toggle in Builds UI | API PUT /builds/{id}/public exists; Builds page checkbox not wired yet — use API or Calibrate public_builds_enabled |
| 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 |
Server API — deeper issues only
Source: server/internal/api audit (2026-06-04). API-D01–D10 addressed 2026-06-04 (go test ./internal/api/... -count=1 PASS).
Fixed (2026-06-04)
| ID | Fix |
|---|---|
| API-D01 | POST /api/v1/auth/ws-ticket issues 2‑min one-time tickets; dashboard WS prefers ?ticket=; legacy ?token= retained as fallback. |
| API-D02 | Per-IP agent WS upgrade rate limit (429) + 45s pre-auth read deadline before disconnect. |
| API-D03 | MarkBeaconSeen / EnqueueBeaconCommand require agent row in DB; beacon upsert runs before mark. |
| API-D04 | CoinGecko fetch checks HTTP status; retries 429/5xx up to 3 attempts with backoff. |
| API-D05 | POST /api/v1/users validates username (3–32, alnum/_/-) and password (4–128); 409 on existing username. |
| API-D06 | Agent WS read loop logs unknown msg.Type in default branch. |
| API-D07 | notifyCmdCallback uses blocking channel send (no drop on full buffer). |
| API-D08 | GET /agents/{id}/stats returns 404 when agent missing (parity with GET /agents/{id}). |
| API-D09 | By design — /api/download/agent-* and dropper /get stay unauthenticated; URL knowledge is the gate. |
| API-D10 | Legacy ?token= WS auth uses authSessionCache (bcrypt skip on cache hit), same as REST. |
Fixed (2026-06-04)
mergeConfig: now mergesserver.fleet_secretandtunnel_defaults(file load still usesmergeConfigExplicitfor bool safety).pool.Manager:poolKeyincludesPaymentIDto avoid integrated-address proxy collisions.GetSpreadFunnelStats:new_connects_todaynow uses callersince(aligned withby_buildwindow).LAUNCH.bat/devrun.bat: readportfromdata/config.jsonfor display; launch without-portso config wins.
Low (open)
db.NewignoresMkdirAllfailure.
Fusion / PathForge
Audit: fusion pathforge (2026-06-04). Builder + API tests — pass.
Fixed (2026-06-04)
- F1 — Path Tracer WireGuard peer topology:
buildHopPeersadds client peer on hop 1 (10.66.0.1/32); single-hop no longer gets emptypeers; multi-hop adds reverse peers on middle/exit hops. Tests:pathtracer_handler_test.go(TestBuildHopPeers*,TestPathTracerOrchestrationConfigurePeers). - Path Tracer session expiry: background cleanup goroutine removes sessions after 2h and sends
wg_teardown. Test:TestPathTracerSessionExpiry. - PathForge
Skippedcounter: incremented for non-matching files during walk. - PathForge
dataDir: used as fallback search path infindAgentBinary. - Mac PathForge
server_url: required whentarget_macis enabled (400 if missing). - Tests added:
pathforge_test.go(HTTP validation, skipped counter, placement);pathtracer_handler_test.go(peer topology + mock-agent orchestration).
High (open)
fusion/package has no tests (coverage only inserver/internal/builder/fusion_*_test.go).
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).
Crucible (Remote Operations Theater)
Expansion pass: 2026-06-04. npm run test -- --run in server/web; go test ./agent/client/....
Phase A — wired (done)
| Op | Command / API | Notes |
|---|---|---|
| Connectivity Probe | connectivity_probe |
JSON to terminal |
| Listen Ports / Patch Status | listen_ports, patch_status |
Individual chips (Deep Scan still runs both) |
| Firewall suite | firewall_punch, firewall_off, firewall_on, firewall_profiles, firewall_remove |
canRunAggressiveAction gates |
| UPnP | hole_punch_status, hole_punch_close |
Hole Punch forge flag |
| Bulk Tunnel Stop | tunnel_stop + all |
Selected online nodes |
| Mesh Peers | mesh_status |
Mesh P2P forge flag |
| Persistence | bits_persist, host_binary_persist |
Win + Remote Aggressive |
| Fleet Upgrade | build picker → upgrade |
listBuilds download URL |
| Registry panel | registry_read / write / delete |
Single or bulk Win (confirm) |
| Live Desktop | screenshot poll 3s |
Single-node toggle |
| Wake-on-LAN | POST /agents/{id}/wol |
Works offline |
UI: collapsible Network, Persistence, Fleet Maintenance groups in CrucibleExpandedOps.tsx; styling in CruciblePage.css.
Phase B — partial
| Op | Status |
|---|---|
arp_neighbors |
Done — deploy.ArpNeighborIPs() JSON |
camera_list + picker |
Done — device via command on camera_snapshot |
persistence_audit |
Done — read-only Run/tasks/systemd/launchd JSON |
kill_process |
Done — { command: pid } |
delete_path / move_path |
Done — file_ops guards (no dirs/system roots) |
Phase C — done (2026-06-04)
| 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).
Agent (Go)
Linux / macOS parity (2026-06-04 pass)
| 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 still stub. |
| 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: firewall aggressive ops, camera, GPU miner — stubs or partial.
- Linux screenshot: headless containers need
xvfb+ scrot or customcommandfield.
Fixed (2026-06-04)
| Area | Fix |
|---|---|
| Mesh | Relay path uses write() under AgentClient.mu (no direct conn read); MeshNode.Stop() tears down mDNS/host; one-way relay documented; unit tests in client/mesh_test.go and client/mesh_p2p_test.go (-tags p2p). |
| Miner | HashAtNonce returns ErrEngineNotReady / ErrBlobTooShort instead of empty+nil; edge-case tests updated in miner/engine_test.go. |
| Spread | Shared deploy/subnet.go: IPv6 local IPs + /64 prefix matching, IPv4-only active sweep; SSH/SMB prerequisites documented in subnet.go and autospread entrypoints. |