feat: T1007 System Service Discovery - fixed allowlist probe in posture heartbeat

This commit is contained in:
AetherForge
2026-05-30 23:16:50 -07:00
parent 4207f6c21b
commit d010292333
26 changed files with 2499 additions and 134 deletions

View File

@@ -35,28 +35,43 @@ Findings from systematic bug-hunt and test expansion (May 2026).
### Low
- [LOW] **server/internal/api/fleet_handler.go** — Package-global `xmrPriceCache` shared across requests/tests; no per-server isolation if multiple routers in one process (unlikely in production).
- [LOW] **server/web/src/types/ws.ts + server/internal/api/ws_types.go** — WS payloads typed in two places; drift risk.
- [LOW] **tests/** — No integration tests for remote actions end-to-end.
- [LOW] **agent/** — Mesh P2P requires build tag `p2p`.
- [LOW] **server/internal/api/config_handler.go** — Settings config import shallow-merge.
- [LOW] **server/internal/builder/fusion_media.go** — XOR media crypto — weak confidentiality by design.
- [LOW] **server/config.go**`LoadConfig` uses legacy `mergeConfig` (not `mergeConfigExplicit`); a hand-edited `config.json` omitting bool fields can still zero them on restart.
- [LOW] **server/internal/api/config_handler.go**`ConfigHandler.db` is unused; handler delegates entirely to `ConfigProvider`.
- [LOW] **server/main.go**`UpdateConfigFromJSON` has no semantic validation (negative ports, empty pool host, etc.); invalid values persist to disk.
- [LOW] **server/internal/db/agent_meta.go**`decodeTags` silently drops invalid JSON in `tags` column (corrupt values become empty slice).
- [LOW] **server/web/e2e/smoke.spec.ts** — E2E login still uses hardcoded `drjones`/`czapiewski`; fails against first-run random `admin` password. Suggested fix: seed `users.json` in E2E fixture or read creds from env.
- [LOW] **server/web/src/types/index.ts** — Interfaces only; no runtime type guards for API JSON (validation ad hoc in components).
- [LOW] **server/web/src/pages/AgentsPage.test.tsx** — Vitest stderr `ECONNREFUSED :3000` when detail panel mounts `AgentRemoteActions`; tests pass but component may hit live fetch — mock in follow-up.
- [LOW] **server/web/src/pages/SettingsPage.tsx** — Calibrate UI lives here (`/settings` route); no separate `CalibratePage.tsx`. Form labels lack `htmlFor` — a11y follow-up.
- [LOW] **server/internal/maintenance/retention.go**`os.RemoveAll` errors ignored; failed disk cleanup is silent.
- [LOW] **server/internal/maintenance/retention.go** — Artifact dir removed before `DeleteBuild`; if DB delete fails, build row remains without files on disk.
- [LOW] **server/internal/maintenance/retention.go**`StartRetentionJobs` goroutine has no shutdown hook (acceptable for server process lifetime).
### Untested packages (next coverage targets)
- [LOW] **server/internal/maintenance/** — No unit tests for retention jobs (uses `db.ListBuildsOlderThan`; db layer now covered).
- [LOW] **server/internal/models/** — No unit tests.
- [LOW] **server/internal/ollama/** — No unit tests.
- [LOW] **server/internal/sys/** — No unit tests.
- [LOW] **server/web/src/help/buildManager.ts**, **cheatSheetContent.ts** — No unit tests yet.
- [LOW] **server/web/src/components/** — Fleet panels, forge form, WebSocket provider — no vitest coverage yet.
---
## Fixed (this session)
- **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 90106 chars. Exported `formatBytes` helper.
- **server/web/src/pages/SettingsPage.tsx** — Wallet placeholder aligned to 90106 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).
@@ -66,6 +81,7 @@ Findings from systematic bug-hunt and test expansion (May 2026).
- **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 95106 but validator accepts 90106; 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/types/index.test.ts** — Structural fixture tests for all major exported interfaces (20 tests); documents no runtime type guards.
@@ -80,10 +96,10 @@ See git history and prior audit IDs (B1B42, C1C6, H1H8, etc.) in README
## Recommended next section
1. **server/web/src/pages/**Add `BuilderPage`, `SettingsPage`, `CalibratePage` coverage (Dashboard + Agents done)
2. **server/web/src/components/** — Fleet panels, forge form, WebSocket provider
3. **server/web/src/help/buildManager.ts**, **cheatSheetContent.ts** — remaining untested help modules
4. **server/internal/maintenance/** — retention job unit tests
1. **server/web/src/components/**Fleet panels, forge form, WebSocket provider; mock `AgentRemoteActions` fetch in AgentsPage tests
2. **server/web/src/help/buildManager.ts**, **cheatSheetContent.ts** — remaining untested help modules
3. **server/web/e2e/smoke.spec.ts** — seed first-run admin creds for E2E
4. **server/internal/models/** — struct/JSON round-trip tests
5. **Agent WS token auth** (S2) — security hardening
---
@@ -93,7 +109,10 @@ See git history and prior audit IDs (B1B42, C1C6, H1H8, etc.) in README
| Suite | Result |
|-------|--------|
| `server` Go tests | PASS (all packages) |
| `server/internal/api` `-run Config` | PASS (13 tests) |
| `server` `-run Config\|Merge` | PASS (13 tests) |
| `server/internal/api` `-run AI` | PASS (17 tests) |
| `server/internal/api` `-run Fleet` | PASS (39 tests) |
| `agent` Go tests | PASS |
| `server/web` vitest (page tests) | PASS — 2 files, 22 tests |
| `server/web` vitest (full suite) | Run `npm test` for current count |
| `server/web` vitest (page tests) | PASS — 4 files, 46 tests |
| `server/web` vitest (full suite) | PASS — 19 files, 206 tests |