# Improvement plan Priority order: (1) agent endpoints, (2) recent issues for the web UI, (3) a Sentry-like frontend error collector. ## Phase 1 — Agent endpoints (highest priority) - [x] Fix `HandleHistoryByType`: it only filtered the in-memory ring buffer (capped at `historySize`, default 100) instead of the persistent store, so `/api/history/traces|metrics|logs` silently returned far less than `/api/history/search` could see. Now routed through `SearchHistory`. - [x] Structured filters on `/api/history/search` and `/api/history/wait`: `type=`, `since=`, `until=` (unix nanoseconds), combinable with the existing free-text `q=`. - [x] `GET /api/traces/{traceId}` — assemble all entries referencing one trace id in a single call, instead of relying on substring search matching the id inside raw JSON. - [x] Basic per-IP rate limiting on `/api/history/wait` (a blocking long-poll, cheap to abuse). - [ ] Cursor-based pagination for `/api/history/search` (deferred). - [ ] Machine-readable tool manifest (`/.well-known/agent-tools.json` or an MCP server) replacing `agents_example.md` (deferred). ## Phase 2 — Recent issues for the web UI - [x] Fingerprint spans with `status=ERROR`/exception events and logs with `severity >= ERROR` into deduped Issues (count, firstSeen, lastSeen, sample entries, affected services), updated incrementally on ingest. `internal/issues` (fingerprinting/dedup) + `internal/collector/issue_extract.go` (OTLP field extraction). - [x] `GET /api/issues`, `GET /api/issues/{id}`. - [ ] UI "Issues" tab (lives in the separate frontend/`dist` project — this repo's API is ready for it). ## Phase 3 — Frontend error collector (Sentry-style) - [x] `static/otel-rum.js`: captures uncaught errors, `unhandledrejection`, resource load failures; translates them to OTLP log records client-side and POSTs to the existing `/v1/logs` endpoint (so Phase 2's issue derivation picks them up for free via a `source: frontend` attribute). Verified end-to-end against a running server: an ingested frontend error shows up in `GET /api/issues` and `GET /api/traces/{traceId}`. - [x] Correlation-id injection: `traceHeaders()` (manual) and auto-injection into same-origin `fetch` calls, using a W3C `traceparent` header so a backend span sharing that trace id and the frontend error that triggered it show up together via `/api/traces/{traceId}`. - [x] CORS support on the OTLP HTTP endpoints (`withCORS` in `cmd/server/main.go`), verified with a live cross-origin POST. - [x] Lightweight ingest key (`OTEL_INGEST_KEY`, checked via `Collector.checkIngest`) for scoping noisy pages, plus a per-IP rate limit (20 rps/burst 50) on the OTLP HTTP ingestion endpoints so a runaway error loop can't hammer the collector. Not real auth. - [x] Explicitly out of scope for v1: source map resolution, session replay, PII scrubbing (documented in README.md and the script's header comment).