mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-09-27 03:47:55 +00:00
## Summary Addresses the remaining acceptance gap on #1120: a true **5-minute rolling-baseline anomaly detector** for the Perf-page Write Sources table. The endpoints + ingestor wiring + UI scaffolding landed in #1123 (partial); this PR replaces the ad-hoc tx-rate comparison with the rolling baseline the issue actually asks for, and adds a JS unit test that proves the ⚠️ flag fires at 11× baseline. ## What changed - **`public/perf.js`** — new pure helper `detectPerfAnomalies(history, current, opts)`. Computes per-component current rate and rolling baseline rate over a window (default 5 min). Flags components whose current rate > 10× baseline. Includes a 0.05/s floor so a stale `0` baseline doesn't false-positive at startup. - **UI** — Write Sources table now shows `Rate/s`, `Baseline/s`, and `Anomaly` columns. Operators can sanity-check the ⚠️ rather than trusting opaque output. History is kept on `window` and pruned to a 6-min sliding ring. - **`test-perf-anomaly.js`** — new VM-sandbox test asserting: - ⚠️ fires when one component runs at 11× its 5-min baseline - No ⚠️ at 5× (under threshold) - No ⚠️ until ≥30s of history has accumulated ## TDD evidence (red → green) - Red commit `590f04d3`: introduces the stub `detectPerfAnomalies` (returns empty `{flags:{}}`) + the test. Test FAILS on the `assert(r.flags.backfill_path_json === true, ...)` assertion — not a build error. ``` ❌ ⚠️ fires when backfill rate hits 11× the 5-minute baseline: expected backfill_path_json flagged at 11× baseline, got flags={} 2 passed, 1 failed ``` - Green commit `726a5e78`: implements the rolling-baseline detector. All 3 tests pass; existing `test-packet-filter.js` (79 tests) still green; `cmd/server` Go tests for `/api/perf/*` still green. ## What is NOT in this PR (deferred / out of scope per brief) - **SQLite-stats subsection** (WAL size + cache hit rate + pending checkpoint) — `/api/perf/sqlite` already exists (landed in #1123). Issue body lists it as a metric category, brief explicitly marks it OPTIONAL. Not regressed; no changes needed. - **Ingestor `/proc/self/io` bridge** — already lives in the ingestor stats file (`ProcIO` field, `internal/perfio`) and is rendered on the Perf page. No change. - **Issue #1340** (SQLite write-lock instrumentation) — separate PR in flight, not piggybacked. - **No new metrics backend** (no Prometheus, no OpenTelemetry). Pure JSON over `/api/perf/*`. ## Hard-rule compliance - Files changed: 2 (`public/perf.js`, `test-perf-anomaly.js`) — well inside the 3-files-outside-allowed-set cap. - `Stats` struct unchanged. - All colors via CSS variables — no hex literals introduced (grep clean). - TDD: red commit fails on assertion, green commit passes — visible in branch history. - PII preflight: clean on both commits. Partial fix language deliberately not used — this completes the issue's UI acceptance criterion. Leaving `Fixes #1120` off so the user can verify on the staging deploy before closing. --------- Co-authored-by: meshcore-bot <bot@meshcore>