/** * Opt-in local-only telemetry event emitter (Sprint 28). * * When config.telemetry.enabled === true, appends one newline-terminated JSON * line to .bober/telemetry/.jsonl. When disabled (default), emit() * is a no-op and performs ZERO file IO. * * File is created with mode 0600 on first append via fs.open(O_WRONLY|O_APPEND| * O_CREAT). Mirrors the Sprint 13 audit pattern verbatim (see audit.ts:86 for * the rationale on why fs.appendFile is NOT used). * * NETWORK EGRESS: forbidden by design. No import of node:http, node:https, * node:net, node:tls, undici, or fetch — enforced by ESLint no-restricted-imports * rule scoped to src/telemetry/** in eslint.config.js. * * PRIVACY: event payloads MUST be IDs / counts / enum outcomes only. NEVER pass * user-content strings (feedbackText, prompts, file contents, MCP response * bodies). Reviewers grep `emit(` across src/ to enforce this discipline. * * Sprint 28 — src/telemetry/emit.ts */ import type { BoberConfig } from "../config/schema.js"; export type TelemetryEventType = "checkpoint-approved" | "checkpoint-rejected" | "checkpoint-edited" | "sprint-pass" | "sprint-fail-retry" | "incident-resolved" | "incident-aborted" | "agent-spawn" | "agent-error"; /** Allowed payload fields. NO string values from user input. */ export interface TelemetryEventData { runId?: string; incidentId?: string; specId?: string; sprintId?: string; contractId?: string; agentName?: string; checkpointId?: string; iteration?: number; durationMs?: number; outcome?: string; retryCount?: number; errorKind?: string; } /** Emit a telemetry event. No-op when telemetry.enabled !== true. */ export declare function emit(projectRoot: string, config: BoberConfig, eventType: TelemetryEventType, data?: TelemetryEventData): Promise; //# sourceMappingURL=emit.d.ts.map