fix: 2026-06-04 audit pass — README, USB pack, multi-area fixes
WS ticket dashboard auth, builder universal signing/size limits/fusion obfuscation/dropper bundles, Path Tracer WireGuard topology, SessionGate degraded mode and download timeouts, server bootstrap (data dir, cloudflared dedupe, config port precedence), agent mesh/miner/spread fixes. README refreshed; usb bundle repacked; PROBLEMS.md audit log updated.
This commit is contained in:
285
PROBLEMS.md
285
PROBLEMS.md
@@ -1,191 +1,128 @@
|
||||
# Problems
|
||||
|
||||
Findings from systematic bug-hunt and test expansion (May 2026).
|
||||
## Builder / Forge
|
||||
|
||||
**Verification:** `test.bat` from project root (→ `scripts/test-suite.ps1`), or `go test ./...` in `server`/`agent` and `npm test` in `server/web`. Live API matrix: `scripts/smoke-test.ps1` with server on :8989. AI handler only: `cd server && go test ./internal/api/... -run AI -v`.
|
||||
*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)*
|
||||
|
||||
---
|
||||
|
||||
## Open
|
||||
## Dashboard (React/Vite)
|
||||
|
||||
### Critical / security
|
||||
*Audit fixes: 2026-06-04. `npm run test -- --run` in `server/web` — pass.*
|
||||
|
||||
- [HIGH] **server/internal/api/fleet_handler.go** — Remote code execution via authenticated API (`powershell`/`exec`/`upload`). By design — treat dashboard login as root.
|
||||
### Fixed in this pass
|
||||
|
||||
### Frontend production (server/web)
|
||||
| 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` |
|
||||
|
||||
- [LOW] **server/web** — Vite build still warns on `three` vendor chunk (~760 kB gzip ~201 kB). Split out of `DashboardPage`; inherent library size — revisit on next Three/R3F bump.
|
||||
- [LOW] **server/web** — `npm audit fix` (no `--force`, May 2026) applied **0** semver-safe patches; **6 remain** (5 moderate, 1 critical). **Critical:** `happy-dom@15.x` (Vitest DOM env only — not shipped; fix needs `happy-dom@20.9+`, major bump). **Moderate:** `esbuild@0.21.x` via `vite@5` → `vitest`/`vite-node` (dev-server SSRF — [GHSA-67mh-4wv8-2f99]; prod build unaffected; fix needs `vite@8+`, major bump). Do **not** run `npm audit fix --force` — also pulls Recharts v3 / React 19 transitives. Planned upgrade batch: Vite 8 + Vitest 3 + happy-dom 20 + Recharts 3 + React 18→19.
|
||||
- [LOW] **server/web** — Transitive `three-mesh-bvh@0.7.8` deprecated vs pinned `three@0.170` (drei pulls 0.7.x; needs `0.8.0+` on next Three/R3F bump). `@types/three` now pinned to `0.170.0` (aligned with runtime).
|
||||
### Open (document-only / deferred)
|
||||
|
||||
### Untested packages (next coverage targets)
|
||||
|
||||
- [LOW] **server/internal/builder/** — Unit tests cover compile/fusion/disguise **helpers** (fake-go success/fail/cancel, `compileWorker`, `buildFileFusion` paired/embedded, spread-kit/fusion finish paths, manifest patching). **Integration-only** (needs real toolchain on host): successful agent/fusion `go build`/`garble` binaries, Windows PE disguise (`go-winres`, system icon extract), code signing (`signtool`/`osslsigncode`), Darwin `.app` bundle, full `buildAgent`/`buildUniversalAgent` happy-path end-to-end.
|
||||
- [LOW] **agent/stats/** — Live kernel/sysctl/vm_stat sampling still integration-only; unit tests cover pure parsers (`parseKB`, `parseMeminfo`, `parseVmStat*`, `filetimeToUint64`, `cpuBusyPercentFromDeltas`).
|
||||
- [LOW] **agent/deploy/** — Live SSDP multicast/SMB/SSH/cloudflared still integration-only; unit tests cover UPnP XML/URL/SOAP helpers, SSDP LOCATION parsing, passive-spread name/launcher helpers, and platform stubs (`go test ./deploy/...`).
|
||||
- [LOW] **agent/client/** — Live WS/commands/posture probes still integration-only; unit tests cover pure helpers in `client.go`/`ai.go` (`truncateStr`, JSON types, job payload parsing, mock HTTP for `/decide`/`/heartbeat`/`/report`).
|
||||
- [LOW] **agent/miner/** — RandomX hashing (`engine.go`), pool worker loop, and stratum TCP login/submit still integration-only; unit tests cover target/schedule helpers, stratum wire types, resource-limit guards, and hex/target math (no VM, no live TCP).
|
||||
- [LOW] ~~**server/web/src/types/ws.ts + server/internal/api/ws_types.go** — WS payloads typed in two places; drift risk.~~ **Fixed May 2026** — `testdata/ws_types_fixture.json` golden file; Go `ws_types_test.go` reflects struct tags; TS `ws.test.ts` asserts same keys/shapes.
|
||||
|
||||
---
|
||||
|
||||
## Documented / by design
|
||||
|
||||
Findings reclassified after code verification (May 2026). Not bugs — documented in README, tests/README, help text, or tests.
|
||||
|
||||
| Was | Resolution |
|
||||
|-----|------------|
|
||||
| [HIGH] Plaintext passwords in `users.json` | `users.json` stores bcrypt hashes (cost 12). Legacy plaintext auto-migrates on startup and login via `checkPassword` in `router.go`. Documented in README Security + First-run login. |
|
||||
| [HIGH] `upload_log` no dedicated ingest API | By design: logs via `get_log` command / Fetch Log UI and AI `upload_log` tool reports. Documented in README Fleet Roster, tests/README, Field Guide tips. |
|
||||
| [MEDIUM] Compact list / expand on click | Implemented in `AgentListItem.tsx` (`compact-row`, click toggles expand). Documented in README Fleet Roster UX. |
|
||||
| [MEDIUM] Remote actions disabled when offline | Intentional — requires live WebSocket. Documented in README, `settingHelp.ts`, Field Guide tips. Vitest + Playwright `e2e/remote-actions.spec.ts`. |
|
||||
| [MEDIUM] Fusion uses vendored go-winres | Optional tool; `devrun.bat` installs, builder uses `go run github.com/tc-hib/go-winres`. Documented in README Forge section. |
|
||||
| [LOW] SettingsPage = Calibrate / no CalibratePage | Nav label **Calibrate** → route `/settings` → `SettingsPage`. Navigation table in README. (A11y `htmlFor` remains in Open.) |
|
||||
| [LOW] `types/index.ts` no runtime guards | Compile-time contracts only; comment block at top of file + tests/README Architecture note. |
|
||||
| [LOW] No e2e for remote actions | Added `server/web/e2e/remote-actions.spec.ts` (offline agent mock → disabled buttons). Vitest coverage in `components.test.tsx`. |
|
||||
| [LOW] Mesh P2P needs `p2p` tag | Forge adds `-tags p2p` when mesh enabled (`compile.go`); manual builds documented in README agent section. |
|
||||
|
||||
---
|
||||
|
||||
## Fixed (this session — dead code / wiring pass)
|
||||
|
||||
- **[LOW] server/web + server/internal/db** — `BuildRecord.extra_files` persisted in SQLite (`extra_files` JSON column). Build Manager lists extra artifact downloads via `api.buildArtifactUrl` for historical builds, not only the post-forge strip on Forge.
|
||||
- **[LOW] server/internal/api/router.go + server/web/src/api/client.ts** — Documented agent-only `POST /agent/{decide,report,heartbeat}` (fleet-secret REST; intentionally omitted from dashboard client).
|
||||
- **[LOW] server/web/src/types/index.ts** — `BuildRecord.download_url` required in TS; added `BuildExtraFile` type. Build Manager uses stored `download_url` for primary download (ZIP/artifact paths).
|
||||
|
||||
- **server/web/src/api/client.ts** — Added `rotateFleetSecret()` for `POST /server/rotate-secret` (was raw `fetch` in Calibrate only).
|
||||
- **server/web/src/pages/SettingsPage.tsx** — Fleet secret rotation uses `api.rotateFleetSecret()`.
|
||||
- **server/web/src/pages/BuilderPage.tsx** — Wired `blueprintDiff` + `compareBlueprint` / `blueprintName` into a dismissible diff panel after blueprint load/import; extra forge artifacts use `api.buildArtifactUrl` on the last-build strip.
|
||||
- **server/web/src/pages/BuildManagerPage.tsx** — Primary download uses stored `build.download_url` when present (artifact/ZIP paths from universal/Fusion builds).
|
||||
|
||||
## Fixed (this session — frontend production pass)
|
||||
|
||||
- **[LOW] server/web** — Vite large-chunk warning for `DashboardPage` (~898 kB → ~33 kB): `manualChunks` splits `three` / `recharts` / `vendor` in `vite.config.ts`; lazy `HashrateChart`, `FleetTopologyMap`, and `MatrixStreamOverlay` in `DashboardPage.tsx`. `npm run build` PASS (remaining warning is isolated `three` chunk only).
|
||||
- **[LOW] server/web** — React Router v7 future flags (`v7_startTransition`, `v7_relativeSplatPath`) opted in via shared `routerFuture` in `main.tsx` and Vitest `MemoryRouter` wrappers; Vitest stderr warnings cleared.
|
||||
- **[LOW] server/web/package.json** — Moved `@types/qrcode` and `@types/three` to `devDependencies` (types-only; runtime deps unchanged). `npm ci`, `npm run build`, `npm test -- --run`, and `depcheck` all PASS (33 files / 372 tests).
|
||||
|
||||
---
|
||||
|
||||
## Fixed (this session — May 2026 full pass)
|
||||
|
||||
- **[MEDIUM] server/web/src/pages/BuilderPage.tsx** — Added `useEffect` cleanup on unmount that calls `api.cancelBuild(cancelTokenRef.current)` and sets `batchCancelRef.current = true`. Navigating away from the Forge page now cancels any in-progress server-side compile (M14 UI desync closed).
|
||||
- **[MEDIUM] agent/miner/pool.go** — Added atomic `jobGen` counter incremented in `SetJob`. Workers snapshot `jobGen` before each 256-nonce inner loop and break early when it changes, eliminating the "stale batch" window. Engine updates moved outside the pool write-lock (each `Engine` has its own `RWMutex`).
|
||||
- **[LOW] server/internal/api/fleet_handler.go** — `xmrPriceCache` moved from package-global vars (`xmrPriceMu`, `xmrPriceCache`) into `FleetHandler` struct fields (`xmrPriceMu`, `xmrPriceCache`). Multiple routers in one process no longer share a stale cache. Tests updated.
|
||||
- **[LOW] server/config.go** — `LoadConfig` now calls `mergeConfigExplicit` (with a key-presence map) instead of legacy `mergeConfig`. Boolean fields absent from a hand-edited `config.json` now keep `DefaultConfig` values rather than being zeroed on restart.
|
||||
- **[LOW] server/internal/api/config_handler.go** — Removed unused `db *db.Database` field from `ConfigHandler` and updated `NewConfigHandler` signature. All call sites updated (`router_test.go`, `integration_test.go`, `config_handler_test.go`, `main.go`).
|
||||
- **[LOW] server/main.go** — `UpdateConfigFromJSON` now validates semantic constraints before merging: port ranges 1–65535, pool port range, non-negative max_agents/stats_retention_hours/build_retention_days/max_build_size_mb. Invalid values return `"invalid config: …"` 400 without touching disk.
|
||||
- **[LOW] server/internal/db/agent_meta.go** — `decodeTags` now logs corrupt tag JSON via `log.Printf` instead of silently discarding it.
|
||||
- **[LOW] server/web/src/pages/SettingsPage.tsx** — All `<label>` elements paired with text inputs now carry `htmlFor` attributes matching corresponding `id` attributes on their inputs (33 label/input pairs). A11y issue closed.
|
||||
|
||||
## Fixed (this session — May 2026 security pass)
|
||||
|
||||
- **[CRITICAL] server/internal/api/router.go** — Build download/artifact/uninstall routes (`/api/v1/builds/{id}/download`, `/artifact/`, `/uninstall`) now require either `X-Fleet-Secret` (for agent self-upgrade) or Basic Auth. Removed unconditional public bypass. Tests updated: `TestBasicAuthMiddlewareBuildDownloadRequiresAuth`, `TestRouterBuildDownloadAuth`.
|
||||
- **[CRITICAL] server/internal/api/router.go** — Agent API paths (`/api/v1/agent/*`) now explicitly return 503 when fleet secret is not configured, rather than silently allowing unauthenticated access. Fleet secret is always auto-generated at first startup via `main.go` so this state should not occur in production.
|
||||
- **[CRITICAL] server/internal/api/ai_handler.go** — SSRF fixed: `handleDecide` no longer accepts or uses the caller-supplied `ollama_endpoint` to create a new engine. It now requires the engine to be pre-registered when the agent authenticates via WebSocket, returning 403 otherwise. Tests updated: `TestAIHandleDecideSuccess`, `TestAIHandleDecideOllamaFailureFallback`, renamed `TestAIHandleDecideCreatesEngineOnFirstRequest` → `TestAIHandleDecideRejectsUnregisteredAgent`.
|
||||
- **[HIGH] agent/deploy/hollow_windows.go** — Added bounds checks in `rvaToFileOffset` (section header array), relocation entry loop (2-byte entry boundary), and `RunHollowed` section-write loop (header and raw-data bounds). Prevents out-of-bounds panics on malformed/truncated PE payloads.
|
||||
- **[HIGH] agent/deploy/autospread.go** — `StartAutoSpreader` moved from unconditional startup in `main.go` to `AgentClient.authenticate()` behind a `sync.Once`. Lateral movement only begins after the server accepts the fleet secret, ensuring the agent is on an owned fleet. First-run spread marker also gated behind auth.
|
||||
- **[LOW] server/internal/builder/platform.go** — `platformsForRequest` universal + `TargetArch: arm64` now returns ALL matching platforms (linux-arm64 and darwin-arm64), not just the first. Test `TestPlatformsForRequestUniversalFilteredArch` updated.
|
||||
- **[LOW] server/internal/maintenance/retention.go** — DB record is now deleted before artifact files (so failed DB deletes don't leave orphaned rows pointing to deleted files). `os.RemoveAll` errors are now logged instead of silently discarded.
|
||||
- **[LOW] server/internal/maintenance/retention.go** — `StopRetentionJobs` cancels the background retention loop; `main.go` defers it on exit. Test: `TestStopRetentionJobs_StopsBackgroundLoop`.
|
||||
|
||||
---
|
||||
|
||||
## Fixed (prior session)
|
||||
|
||||
- **agent/deploy/** — Added `natpunch_test.go` (10), `hollow_test.go`, `tunnel_test.go`, `autospread_test.go` (2): UPnP XML/SOAP mocks, `xmlEscape`/`getSubnet`/`intSliceStr`, tunnel URL validation, autospread stub paths, hollow unavailable without `-tags hollow`.
|
||||
- **agent/client/** — Added `client_test.go` (8), `listen_ports_test.go` (2), `dns_config_test.go` (3), `posture_windows_test.go` (5), `listen_ports_parse_test.go` (5, `!windows`): server URL list/WS URL builders, log tail, listen-port/patch JSON, DNS JSON parser, ss/netstat parsers, Windows posture JSON helpers.
|
||||
- **agent/client/client.go** — `readLogTail` ignored trailing newline when counting lines; `tail_lines=2` on a 4-line log with final `\n` returned only `"line4\n"` instead of last two content lines.
|
||||
- **agent/stats/** — Added `reporter_test.go` (4 smoke tests), `reporter_linux_test.go` (`parseKB`, linux tag).
|
||||
- **server/internal/models/** — Added `agent_test.go` (10 tests): JSON round-trips for all exported structs; omitempty/minimal decode.
|
||||
- **server/internal/ollama/** — Added `engine_test.go` (14 tests): `NewEngine` defaults, type JSON round-trips, mock decide/health paths, markdown JSON extraction, error branches.
|
||||
- **server/internal/sys/** — Added `firewall_test.go` (2 tests): invalid port; non-Windows stub error.
|
||||
- **server/internal/alerts/** — Added `notify_test.go` (6 tests): Telegram/email no-op paths, SMTP defaults, `NotifyAll` no-panic.
|
||||
- **server/internal/pool/** — Added `manager_test.go` (8 tests): validation, `poolKey`, status levels, setters, `ListStatus`.
|
||||
- **server/internal/db/sqlite.go** — `SetPinnedBuild` returns error when id not found; `TestSetPinnedBuildUnknownID`.
|
||||
- **agent/client/** — Added `protocol_test.go`, `posture_types_test.go`, `resource_pressure_test.go` (25 tests).
|
||||
- **agent/client/client.go** — Empty `"error"` in job payload no longer treated as server error.
|
||||
- **agent/config/** — Added `schedule_test.go` (6 tests): mining mode, clock parse, schedule windows.
|
||||
- **agent/deploy/** — Added `common_test.go`, `identity_test.go` (18 tests): naming, install paths, agent ID lifecycle.
|
||||
- **agent/job/** — Added `job_test.go` (2 tests): JSON round-trip.
|
||||
- **server/internal/api/websocket.go** — `checkDashboardWSToken` compared plain password to bcrypt hash; dashboard WS auth failed after user migration. Now uses `checkPassword`.
|
||||
- **server/internal/api/** — Added unit/integration tests for remaining handlers: `handlers.go` (agent/build REST), `router.go` (auth middleware, users, rotate-secret, SPA/dropper routes), `websocket.go` (agent/dashboard WS, fleet secret, max agents, log tail), `dropper_handler.go`, `blueprint_handler.go`, `ws_types.go`. New files: `router_test.go`, `dropper_handler_test.go`, `blueprint_handler_test.go`, `websocket_test.go`, `ws_types_test.go`; expanded `handlers_test.go`. `go test ./internal/api/...` — 159 tests PASS.
|
||||
- **server/web/src/components/** — Added `components.test.tsx` (57 tests) covering all 22 component TSX modules (NeonCard, HelpTip, downloads, ErrorBoundary, SessionGate, charts, fleet panels/toolbar/list/remote actions, forge hints, visual widgets, layout, ambient/matrix/cursor). Vitest `environmentMatchGlobs` includes `src/components/**`.
|
||||
- **server/web/src/pages/AgentsPage.test.tsx** — `AgentRemoteActions` mocked to avoid live `listBuilds` / ECONNREFUSED :3000 in detail-panel tests.
|
||||
- **server/web/src/api/client.ts** — `fetchJSON` spread `...options` after merged headers could drop `Content-Type` and `Authorization` when callers pass `options.headers`; headers now merged after rest spread.
|
||||
- **server/web/src/api/** — Added `client.test.ts` (20) and `download.test.ts` (6): paths, query params, auth headers, FormData fusion builds, error bodies. Expanded `auth.test.ts` (+1 sessionStorage throw path).
|
||||
- **server/web/src/context/** — Added `WebSocketContext.test.tsx` (2), `WebSocketProvider.test.tsx` (8), `ForgeContext.test.tsx` (4): mock WebSocket connect URL/token, message handlers, `_seq` ring buffer, reconnect timer, forge state machine.
|
||||
- **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` (12); 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/web/e2e/smoke.spec.ts** — E2E login used hardcoded `drjones`/`czapiewski`; now reads `AETHERFORGE_E2E_USER`/`AETHERFORGE_E2E_PASS` via `e2e/fixtures.ts` (defaults `testuser`/`testpass`, matching `integration_test.go`). `test-suite.ps1` seeds BOM-free `users.json` before E2E server start; `smoke-test.ps1` defaults updated.
|
||||
- **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/help/buildManager.test.ts** — 9 tests: `blueprintDiff` (added/removed/changed, sort, nested, arrays, empty), `buildRequestFromRecord` merge/override.
|
||||
- **server/web/src/help/cheatSheetContent.test.ts** — 19 tests: pipeline/network/fusion/AI guides, `FORGE_VS_CALIBRATE`, `TROUBLESHOOTING`, `ROADMAP_FEATURES`, `CHEAT_SECTIONS` registry.
|
||||
- **server/web/src/help/forgeDefaults.test.ts** — 7 tests: `FORGE_BUILD_DEFAULTS` shape, `forgeDefaultsFromServer` public URL / pool / sign / obfuscate.
|
||||
- **server/web/src/help/remoteActions.test.ts** — Expanded to 11 tests: `aggressiveActionHint`, spread/mesh gating, legacy undefined caps.
|
||||
- **server/web/src/help/cheatSheetContent.ts** — Troubleshooting "Shares all rejected" wallet text aligned to 90–106 chars (was stale "95 chars").
|
||||
- **server/internal/builder/** — Added unit tests across compile, disguise, fusion media, polymorph, limits, media lock, handler HTTP/cancel, spread-kit helpers (~110 tests). Fixed wallet validation error text (90–106 chars). `go test ./internal/builder/...` — PASS.
|
||||
- **server/web/src/help/settingHelp.ts** — `calibrate_wallet` / `wallet` help aligned to 90–106 chars (was stale "~95 characters"); `settingHelp.test.ts` assertions.
|
||||
- **server/web/src/components/Charts/GaugeRing.tsx** — Center label now uses clamped value (matches SVG arc 0–100%); `components.test.tsx` updated.
|
||||
- **server/web/src/pages/AgentsPage.tsx** — Fleet Roster `FleetToolbar` wired with `onSelectAllFiltered` / `filteredCount` (Dashboard parity).
|
||||
- **server/web/src/api/client.ts** — `estimateFusion` client-side prep-file guard (parity with `buildAgent`); `client.test.ts` reject test.
|
||||
- **agent/miner/** — Added `stratum_test.go` (8), `pool_test.go` (8); expanded `target_test.go` (+6), `schedule_test.go` (+3). **29 tests PASS** — endpoints, Stratum JSON wire types, nonce hex, difficulty/target math, schedule guard.
|
||||
- **agent/miner/schedule.go** — `MiningModeNormalized()` `"schedule"` was treated as always-on; now accepts `"scheduled"` and `"schedule"`; `allowedAt` for deterministic tests.
|
||||
- **server/web** — Pinned `@types/three@0.170.0` to match `three@0.170.0` (was `^0.184.1`, skewed from runtime; `skipLibCheck` masked). `@react-three/drei@9.122` / `@react-three/fiber@8.18` unchanged; `tsc`, `npm run build`, vitest (373) — PASS.
|
||||
|
||||
---
|
||||
|
||||
## 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. **agent/stats/** + **agent/deploy/** integration paths — platform reporters, autospread/hollow
|
||||
2. **Agent WS token auth** (S2) — security hardening
|
||||
|
||||
---
|
||||
|
||||
## Test run snapshot (this session)
|
||||
|
||||
| Suite | Result |
|
||||
| Issue | Notes |
|
||||
|-------|--------|
|
||||
| `server/internal/api/...` (full) | PASS |
|
||||
| `server` Go tests | PASS (all packages) |
|
||||
| `agent` Go tests | PASS (full `./...`) |
|
||||
| `server/web` vitest (full suite) | PASS — 33 files, 373 tests |
|
||||
| `server/web` `npm run build` (tsc + vite) | PASS |
|
||||
| `server/web` `npm ci` + depcheck | PASS — no missing/unused deps |
|
||||
| `server/web` Playwright e2e | PASS — 5 tests |
|
||||
| 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` |
|
||||
|
||||
---
|
||||
|
||||
## Backend dependency audit (May 2026)
|
||||
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).
|
||||
|
||||
| Module | `go mod tidy` | `go build ./...` | `go test ./...` | Notes |
|
||||
|--------|---------------|------------------|-----------------|-------|
|
||||
| `server/` | Updated | PASS | PASS | Promoted `golang.org/x/crypto` to direct (bcrypt in `router.go`). Removed stale indirects (`go-winres`, `nfnt/resize`) — winres stays `go run` at build time per README. |
|
||||
| `agent/` | Updated | PASS | PASS | Promoted `github.com/libp2p/go-libp2p`, `github.com/google/uuid` to direct (`mesh_p2p.go` / `p2p` tag). `go build -tags p2p` and `-tags hollow` PASS on Windows. |
|
||||
| `fusion/` | No dep changes | PASS | N/A (no `_test.go`) | Stdlib-only module; matches `test-suite.ps1` phase 3/8. |
|
||||
### Fixed (2026-06-04)
|
||||
|
||||
**Dead/orphan code:** None removed. All agent/server/fusion `.go` files belong to wired packages; build-tag stubs (`mesh_p2p_stub`, `hollow_stub_*`, platform splits) are intentional feature gates, not duplicates.
|
||||
| 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. |
|
||||
|
||||
**Fix applied:** `fleet_handler_test.go` nil-WS cases used struct value-copy (`bad := *fh`) which tripped `go vet` (mutex copy). Replaced with `NewFleetHandler(..., nil, ...)`.
|
||||
---
|
||||
|
||||
|
||||
|
||||
### 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).
|
||||
|
||||
---
|
||||
|
||||
## Agent (Go)
|
||||
|
||||
### Open
|
||||
|
||||
- **Client:** WebSocket/beacon paths integration-only in CI.
|
||||
|
||||
### 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. |
|
||||
|
||||
Reference in New Issue
Block a user