返回 CodeWhale
notice.rs
根目录 / crates / telemetry / src / notice.rs
1 //! The first-run notice copy.
2 //!
3 //! One string, owned by the crate that owns what is collected, so the TUI and
4 //! the CLI cannot drift into describing two different products. Every claim
5 //! below is checked against [`crate::event`] by a test: if the schema grows a
6 //! field this text does not cover, that test fails.
7 //!
8 //! Two properties of the wording are deliberate and load-bearing:
9 //!
10 //! 1. **Usage defaults on with durable opt-out.** Disclosure presentation
11 //! records only that it was shown, never fictional human acceptance.
12 //! 2. **The red lines are stated as "not collected", not as "anonymized".**
13 //! Sampling and hashing are not the same promise, and a notice that implies
14 //! them when neither is true is worse than no notice.
15
16 /// Headline shown above [`NOTICE_BODY`].
17 pub const NOTICE_HEADLINE: &str = "Codewhale usage reporting";
18
19 /// The notice itself.
20 ///
21 /// Wrapped at 72 columns so it renders unchanged in the native responsive
22 /// modal and remains readable in an 80-column terminal.
23 pub const NOTICE_BODY: &str = "\
24 Codewhale counts: which version you run, OS and CPU family, session
25 duration and outcome, and aggregate feature and error counters.
26
27 It never collects your conversations, code, prompts, files, repo or
28 branch names, model content, or credentials — and it never sends a
29 per-turn or per-tool timeline of agent activity.
30
31 You are identified only by a random ID stored on this machine, replaced
32 every 90 days. Change your mind any time:
33 codewhale config set telemetry false
34
35 Full schema, field by field: docs/TELEMETRY.md
36
37 Usage reporting is on by default. Codewhale and PostHog process these
38 counts when delivery is configured. No IP is collected.";
39
40 /// Concise disclosure for every armed runtime surface, including headless CLI.
41 pub const STARTUP_DISCLOSURE: &str = "Usage reporting is on by default: Codewhale and PostHog process aggregate version/platform, session, feature and error counts when delivery is configured. No content or IP. Turn off: codewhale config set telemetry false. Details: codewhale config telemetry";
42
43 /// Present the policy once per revision without recording human acceptance.
44 /// Failure to save the display marker only causes a later repeat disclosure.
45 /// The interactive TUI draws its own localized notice and records its own
46 /// presentation, so it never gets a stray stderr line before the first frame.
47 pub(crate) fn show_startup_disclosure(surface: crate::event::Surface) {
48 if surface == crate::event::Surface::Tui {
49 return;
50 }
51 let Ok(path) = codewhale_config::SetupState::path() else {
52 return;
53 };
54 let Some(state) = crate::load_setup_state_for_decision_at(&path) else {
55 return;
56 };
57 if state.telemetry_opted_out()
58 || !state.needs_telemetry_notice(codewhale_config::TELEMETRY_NOTICE_VERSION)
59 {
60 return;
61 }
62 use std::io::Write;
63 if writeln!(std::io::stderr().lock(), "{STARTUP_DISCLOSURE}").is_ok() {
64 let _ = codewhale_config::SetupState::update_telemetry_at(&path, |latest| {
65 latest.record_telemetry_notice_shown(codewhale_config::TELEMETRY_NOTICE_VERSION);
66 });
67 }
68 }
69
69 lines RUST