Opt-in product telemetry for Codewhale.
The whole of what this crate may ever send is [event]. The whole of what
decides whether it may send anything is [decision]. Nothing else in the
tree is permitted to construct a payload or to reach the wire, and nothing in
here reads a prompt, a completion, a tool argument, a file, a path, a git
remote, a branch, a model id, a provider table name, an MCP server name, an
approval rule, an error body, a panic message, or a credential.
The shape of the guarantee
Consent is a value, not a convention. [decide] is the only constructor
of [TelemetryConsent]; [init] takes one by value and there is no
bool-taking sibling. Six init sites cannot each drift from the predicate,
because they never see the predicate.
Arming is a OnceLock, consulted by every write path including
[record_blocking]. This matters because the process panic hook is installed
before the command line is even parsed, long before any config resolution: it
cannot consult a resolved value, but it can consult a lock that is by
construction empty until resolution completes. A disabled user's panic
therefore writes nothing and creates no directory.
Arming also truncates the buffer. No event recorded before consent can ever be in the batch that follows it.
Failure posture
Fail-open is absolute. Every fallible step ends in .ok()? or let _ =.
Nothing here returns an error to a caller, blocks a turn, blocks a tool, or
blocks process exit. Telemetry that costs a user their session is worse than
no telemetry.