LISAOS // DOCS
GATEWAY // ANALYTICS

Gateway Module — `analytics/`

1. Purpose

The analytics/ module is a read-only reporting layer over the gateway's existing tables. It surfaces four aggregate views — agent performance, context quality, skill usage, and dispatch patterns — computed on demand from agent_dispatch, psychic_cache, context_assembly_log, activity_log, and source_weights. It is the FIP (Fast Improvement Pipeline) Phase 1 read surface (Dispatch 377), with Phase 3 channel-awareness (Dispatch 384) letting every view filter by dispatch origin channel (vscode / hermes / all). It owns no writes and no schema — it is a pure query/aggregation module.

2. File Inventory

FileLinesResponsibility
index.ts21Layer factory createAnalyticsLayer(db){ router } (vault-index layer pattern)
repository.ts493All SQL aggregation queries against the 5 source tables
routes.ts1444 GET endpoints with Zod query-param validation
types.ts148WindowQuerySchema + ChannelSchema Zod, 4 response-shape interfaces, repository contract
Total806

3. Public API Surface

REST Endpoints

Mounted at /api/analytics (index.ts line 750). Auth: all four are GET → require a Bearer (post-AK-415; the former GET exemption is closed).

MethodPathAuthQuery paramsResponse
GET/api/analytics/agent-performanceBearerwindow (Nd, 1–90, default 7d), channel (default all)AgentPerformanceResponse — per-agent dispatch counts, confidence/affinity splits, avg duration, retry + escalation counts
GET/api/analytics/context-qualityBearerwindow (default 7d), channelContextQualityResponse — per-caller assembly totals, feedback rate, avg utilisation, per-source effectiveness (assembled vs used, current weight/token-share)
GET/api/analytics/skill-usageBearerwindow (default 30d), channelSkillUsageResponse — per-skill invocation counts, distinct agents, first/last used. never_used deferred (empty in Phase 1)
GET/api/analytics/dispatch-patternsBearerwindow (default 30d), channelDispatchPatternsResponse — per-agent stall rate + stall-milestone breakdown; escalation targets + reasons

Invalid query params return 400 with formatZodError output.

MCP Tools

None.

4. Internal API

  • createAnalyticsLayer(db): AnalyticsLayer — composes repository + router; exports { router } only.
  • createAnalyticsRepository(db): AnalyticsRepository — 7 query methods: getAgentPerformance, getEscalationCounts, getContextCallerSummary, getContextSourceEffectiveness, getSkillUsage, getStallPatterns, getEscalationPatterns (each takes sqlOffset + channel).

5. Background Services

None. All computation is request-driven.

6. Data Contracts

Two Zod query-param schemas (the only validation surface — no body schemas):

  • WindowQuerySchema — string ^\d+d$, refined to 1–90 days, transformed to { days, sqlOffset: '-N days' }. Default 7d. A standalone string schema (raiden advisory: not extended by channel).
  • ChannelSchemaz.enum(['vscode','hermes','all']).default('all'). Parsed independently as a sibling schema. Channel attribution is tag-based: hermes = dispatches carrying a source:hermes psychic-cache tag; vscode = dispatches without it; all = no filter.

Response shapes are TypeScript interfaces (not Zod — outbound): AgentPerformanceResponse, ContextQualityResponse, SkillUsageResponse, DispatchPatternsResponse plus their nested entry types.

7. Dependencies

  • Gateway modules consumed: shared/ (formatZodError). Reads (does not write) tables owned by dispatch (agent_dispatch), psychic-cache (psychic_cache), context (context_assembly_log, source_weights), activity (activity_log).
  • External libraries: better-sqlite3, express, zod.
  • Environment variables: none.

8. Test Coverage

LayerFileCases
Routes + repositorytest/analytics-routes.test.ts (475 L)28 it blocks

Covers all 4 endpoints, window validation bounds, channel filtering, and escalation-enrichment merge.

9. Known Limitations

  • skill-usage.never_used is a deferred feature — Phase 1 returns an empty array; catalogue cross-reference (skills the registry knows but telemetry has never seen) is not yet implemented.
  • Channel attribution is a heuristic (presence/absence of a source:hermes tag), not a first-class column — a dispatch that never wrote a tagged cache entry defaults to vscode.
  • Read-only module: no aggregation is materialised/cached, so each request re-scans the window. Acceptable at current volume; a candidate for a materialised rollup if window scans grow costly.

10. Change History

DateDispatchSummary
2026-07-042297Initial module spec (smoke-clone-3, LisaOS audit campaign Phase 4)
384Phase 3 channel awareness (vscode/hermes/all)
377FIP Phase 1 — module created (4 read endpoints)

On this page