/** * A diagnostic report somebody can send you, with nothing in it they would not want to send. * * Two questions prompted this. "A tiny task took 31 minutes and 1,207,341 tokens — how come?" and * "there must be a way to get details of all the KONECK running by people, so we can debug easily * and know how heavy their systems are." * * The first is answerable already: KONECK records a trajectory with a timing for every request and * every tool call, and it knew exactly where those 31 minutes went. Nobody could read it, which is * the actual gap — the data existed and had no way out of the machine. * * ## Why this is a file and not a phone-home * * The second question asks for something that cannot be built the way it was asked. "Details of what * they are working on" is their source code, their prompts, and their file paths. A KONECK session * transcript routinely contains API keys people paste, database passwords, internal addresses and * proprietary code. Uploading that from a published npm package — silently, because nobody would be * asked — is not telemetry, it is exfiltration, and it would be true whatever the intention behind * it. It would also be the first thing a security review of KONECK found. * * So: a report the person generates, reads, and chooses to send. It carries what is needed to debug * a slow or stuck run and nothing that identifies the work: * * - what KONECK and the machine are: version, platform, arch, cores, memory, Node * - what it was talking to: provider, whether local, the window, and how that was learned * - where the time went: model, tools, waiting, and the shape of the turns * - which of KONECK's own failure modes fired: lean mode, truncation, empty turns, loops * - tool counts by name, and the slowest of each kind * * and never: prompts, replies, reasoning, file contents, absolute paths, credentials, hostnames, * repository names, or a machine identifier. There is nothing here to correlate back to a person, * which is deliberate: a report that cannot be traced to somebody is a report they will actually * send. */ import type { TrajectoryEvent, TrajectorySummary } from './trajectory.js'; export interface ReportMachine { koneck: string; node: string; platform: string; arch: string; cores: number; memoryGb: number; /** Load average as a share of the cores, which is the number that says "this machine is busy". */ loadPerCore: number | null; } export interface ReportRun { provider: string; /** The model family, not the exact tag: "qwen3-coder" rather than a private deployment name. */ modelFamily: string; local: boolean; contextTokens: number | null; windowSource: string | null; leanMode: boolean; truncationSeen: boolean; } export interface ToolTally { name: string; calls: number; failed: number; totalMs: number; slowestMs: number; } export interface Report { kind: 'koneck-report'; version: 1; at: string; machine: ReportMachine; run: ReportRun; timing: TrajectorySummary & { wallMs: number; unaccountedMs: number; }; tools: ToolTally[]; /** Counts of the conditions KONECK detects itself, which is what makes a run explicable. */ signals: Record; } export declare function modelFamily(model: string): string; /** Machine facts, and none that identify a machine. Deliberately no hostname and no username. */ export declare function machineFacts(koneckVersion: string): ReportMachine; /** * Every tool, how often, how long, and how often it failed. * * The shape that answers "why did a sidebar take half an hour": 140 read_files and 3 write_file is * a different story from 12 read_files and 40 execute_command, and neither needs a single line of * anybody's code to tell. */ export declare function tallyTools(events: readonly TrajectoryEvent[]): ToolTally[]; export declare function buildReport(input: { koneckVersion: string; events: readonly TrajectoryEvent[]; provider: string; model: string; local: boolean; contextTokens?: number | undefined; windowSource?: string | undefined; leanMode?: boolean; truncationSeen?: boolean; signals?: Record; }): Report; /** * The report as a person reads it before deciding to send it. * * Readable on purpose. Somebody asked to send a diagnostic file should be able to see there is * nothing of theirs in it, and a wall of JSON does not let them see that. */ export declare function renderReport(r: Report): string; //# sourceMappingURL=report.d.ts.map