LISAOS // DOCS
GATEWAY // SKILLS TELEMETRY

Gateway Module — `skills-telemetry/`

1. Purpose

The skills-telemetry/ module is the unified skill-usage collector across all three surfaces — Claude Code, Hermes, and CyberShinobi agents (Dispatch 786). Every surface POSTs a telemetry event (invocation / completion / failure / lifecycle change) so the Hermes Curator can build a cross-surface skill-usage profile and drive dormancy detection. It stores events append-only in skills_telemetry and serves both raw event queries and per-skill aggregate summaries.

2. File Inventory

FileLinesResponsibility
repository.ts217skills_telemetry DDL + write + query + aggregate
routes.ts741 POST + 2 GET (aggregate, query)
types.ts76Zod input/query schemas + row/aggregate interfaces
Total367(No index.ts — repository + router wired inline in server/index.ts.)

3. Public API Surface

REST Endpoints

Mounted at /api/skills/telemetry (index.ts line 759). Auth (post-AK-415):

MethodPathAuthBody / QueryResponse
POST/api/skills/telemetryBearer (write only)SkillTelemetryInputSchema201 { data: SkillTelemetryRow }
GET/api/skills/telemetry/aggregateBearerSkillTelemetryAggregateQuerySchema (skill_name?, since?){ data: SkillAggregateResult[] }
GET/api/skills/telemetryBearerSkillTelemetryQuerySchema (filters + limit){ data: SkillTelemetryRow[] }

Route-ordering discipline: /aggregate is registered before the bare GET / so it is not shadowed (the activity-router pattern). The /api/skills/ prefix was formerly GET-exempt; that exemption was closed by AK-415 — all GETs now require a Bearer.

MCP Tools

None directly in this module. (No mcp/index.ts case forwards to /api/skills/telemetry; surfaces log via direct REST or the Hermes curator sync cron.)

4. Internal API

  • createSkillsTelemetryRepository(db): SkillsTelemetryRepositorywrite(input), query(filters), aggregate(skill_name?, since?).
  • createSkillsTelemetryRouter(repo): Router.

5. Background Services

None inside the gateway. An external sync-telemetry-to-curator.sh cron (Hermes side, outside this module) reads the aggregate endpoint to feed the Curator's dormancy detection.

6. Data Contracts

  • SkillTelemetryInputSchemaskill_name, surface (hermes/claude_code/cybershinobi), agent_name?, dispatch_id?, mission_id?, event_type (invocation/completion/failure/lifecycle_change), outcome? (success/partial/failed/stale/archived/revived), duration_ms?, tokens_consumed?, error_summary? (max 200), lifecycle_transition? (max 50).
  • SkillTelemetryQuerySchema — optional skill_name/surface/agent_name/mission_id/event_type/since + coerced limit (≤500).
  • SkillTelemetryAggregateQuerySchema — optional skill_name, since.
  • SkillTelemetryRow (stored) + SkillAggregateResult (per-skill totals, success/partial/failed/lifecycle counts, surfaces breakdown, avg duration, total tokens, last-used).

Table: skills_telemetry (append-only).

7. Dependencies

  • Gateway modules consumed: shared/ (formatZodError).
  • External libraries: better-sqlite3, express, zod.
  • Environment variables: none.

8. Test Coverage

LayerFileCases
Repositorytest/skills-telemetry-repository.test.ts (168 L)8 it blocks

Covers write, filtered query, and per-skill aggregation. (No dedicated routes test file — the router is thin over the tested repository.)

9. Known Limitations

  • No routes-level test file — endpoint validation coverage rides on the repository test + the shared Zod/formatZodError pattern.
  • Append-only with no retention/GC in-module — event volume grows unbounded until an external prune.
  • The POST route carries a nosemgrep suppression for the direct-response-write XSS rule (Dispatch 1015) — res.json() serialises JSON, not HTML, so the finding is a false positive; documented inline.

10. Change History

DateDispatchSummary
2026-07-042297Initial module spec (smoke-clone-3, LisaOS audit campaign Phase 4)
1010 (R-6, AK-325)Verbatim restore from vault mirror under Clean Code Pipeline Gate 0
786Module created — unified cross-surface skill telemetry

On this page