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 merges server.fleet_secret and tunnel_defaults (file load still uses mergeConfigExplicit for bool safety).
pool.Manager: poolKey includes PaymentID to avoid integrated-address proxy collisions.
GetSpreadFunnelStats: new_connects_today now uses caller since (aligned with by_build window).
LAUNCH.bat / devrun.bat: read port from data/config.json for display; launch without -port so config wins.
Low (open)
db.New ignores MkdirAll failure.
Fusion / PathForge
Audit: fusion pathforge (2026-06-04). Builder + API tests — pass.
Fixed (2026-06-04)
- F1 — Path Tracer WireGuard peer topology:
buildHopPeers adds client peer on hop 1 (10.66.0.1/32); single-hop no longer gets empty peers; 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
Skipped counter: incremented for non-matching files during walk.
- PathForge
dataDir: used as fallback search path in findAgentBinary.
- Mac PathForge
server_url: required when target_mac is 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 in server/internal/builder/fusion_*_test.go).
Medium (open)
- Agent WireGuard auto-download: Windows agent
ensureWGExe() downloads and silently installs WireGuard from download.wireguard.com on 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
.command still depends on server_url + /api/download/agent-mac at 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 custom command field.
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. |
Integration audit (2026-06-04)
Post–alive-UI wave verification. Commands: go test ./... in agent/ and server/; go test ./internal/api/... ./internal/db/...; npm run test -- --run + npm run build in server/web.
Fixed in this pass
| Item |
Fix |
Stale server/webroot |
Clean-synced from server/web/dist after npm run build (59 files; includes Mission Deck chunks, wiki search, spread landing). Run devrun.bat or xcopy dist → webroot after each frontend build. |
fleetModules.ts fallbacks |
UI fallbacks aligned with embedded ModuleManifest packs in modules.go (capabilities + descriptions). |
data/modules/*.json |
Verified consistent with embedded manifests (signatures computed at load time). |
Verified (no code change needed)
| Item |
Status |
modules_test.go, fleet_policy_test.go, campaign.go |
Compile + tests PASS (go test ./internal/api/... ./internal/db/...) |
operatorDeck.css import |
Layout.tsx imports ../../styles/operatorDeck.css — build passes |
/mission-deck route |
Registered in App.tsx; App.test.tsx + MissionDeckPage.test.tsx pass |
/docs wiki search |
public/docs/index.html + wiki.js ship in dist/docs/; search indexes h3/h4 + body blocks |
Root go test ./... |
N/A — no root go.mod; run per-module (agent/, server/) |
Open (document-only / ops)
| Issue |
Notes |
server/webroot not auto-synced on npm run build |
Manual step via devrun.bat or copy; stale webroot served old hashed assets (e.g. missing MissionDeckPage-* chunks) |
| Vitest stderr noise |
FleetTopologyMap three.js tags warn in happy-dom — tests pass (63 files / 562 tests) |
fusion/ package tests |
Still none — coverage only in server/internal/builder/fusion_*_test.go |