ADR 023: Optional telemetry remote upload
Status
Accepted — implementation ships as vox telemetry with a local file spool and explicit upload (see telemetry-remote-sink-spec).
Context
Vox records many operator-controlled diagnostics and research metrics locally (Codex / research_metrics, completion audits, benchmark hooks). Some deployments may want a separate, explicit path to copy aggregated JSON to an operator-run HTTPS ingest. That path must never be default-on, must not bypass Clavis for credentials, and must respect data residency and legal review outside this ADR.
Decision
- No default remote upload. The product does not phone home. Transmission requires an explicit CLI invocation (
vox telemetry upload) and configured ingest URL. - Local spool first. Pending payloads live as one JSON file per event under a configurable directory (default under the current working tree’s
.vox/telemetry-upload-queue/pending/, overridable viaVOX_TELEMETRY_SPOOL_DIR). Operators enqueue withvox telemetry enqueueor out-of-band file drops consistent with the spool layout. - Secrets via Clavis only. Ingest URL and bearer token are
SecretId::VoxTelemetryUploadUrlandSecretId::VoxTelemetryUploadToken(VOX_TELEMETRY_UPLOAD_URL,VOX_TELEMETRY_UPLOAD_TOKEN). CLI code usesvox_clavis::resolve_secret; do not add parallelstd::env::varreads for those values. - Normative wire behavior (rate limits, signing roadmap, headers) lives in telemetry-remote-sink-spec, not in this ADR.
- Legal / security sign-off for any organization-wide or end-user upload policy is recorded in that organization’s process; this ADR defines the technical guardrails (opt-in, explicit command, Clavis, delete-after-ack on success).
Consequences
- New CLI surface:
vox telemetry status|export|enqueue|upload(catalog + command-registry generated fromcontracts/operations/catalog.v1.yaml). - New documentation: remote sink spec + env-var rows in env-vars.
- Future HMAC or mTLS layers extend the sink spec and Clavis
SecretIdlist without changing the “explicit upload” invariant.