feat: v1.0 — télémétrie anonyme opt-in : compteurs agrégés uniquement, settings.telemetry (désactivé par défaut), batch périodique avec backoff, fire-and-forget, zéro PII (closes #76)
- src/telemetry.rs : compteurs par kind + succès/échec des runs, fichier telemetry.json à côté du state, envoi au seuil (10 events ou 7 jours), backoff 3 échecs consécutifs, reset après succès - app.emit → maybe_record (no-op si désactivé, rien n'est même écrit localement) ; real_main → maybe_flush - config.yaml : bloc telemetry documenté (enabled + endpoint optionnel) - 5 tests : disabled (rien), compteurs agrégés (zéro identifiant dans le JSON), local-only sans endpoint, envoi+reset (serveur tiny_http sur thread dédié), backoff
This commit is contained in:
@@ -136,6 +136,10 @@ pub struct Settings {
|
||||
/// Push automatically when the REPL exits (issue #66, opt-in).
|
||||
#[serde(default)]
|
||||
pub sync_on_exit: Option<bool>,
|
||||
/// Anonymous opt-in telemetry (issue #76): aggregated counters only.
|
||||
/// Nothing is collected or sent while `enabled` is false (the default).
|
||||
#[serde(default)]
|
||||
pub telemetry: Option<TelemetrySettings>,
|
||||
/// Plugin scripts (issue #75): default timeout and enable list.
|
||||
#[serde(default)]
|
||||
pub plugins: Option<PluginSettings>,
|
||||
@@ -151,6 +155,18 @@ pub struct Settings {
|
||||
pub providers: Option<BTreeMap<String, Option<ProviderDef>>>,
|
||||
}
|
||||
|
||||
/// Anonymous opt-in telemetry (issue #76): aggregated counters only — never
|
||||
/// paths, commands, agent names or identifiers. Disabled by default.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(default)]
|
||||
pub struct TelemetrySettings {
|
||||
/// Explicit opt-in: nothing is collected or sent while false.
|
||||
pub enabled: bool,
|
||||
/// Batch endpoint (e.g. https://am-telemetry.example/v1/ping). When
|
||||
/// unset, counters stay local even when enabled.
|
||||
pub endpoint: Option<String>,
|
||||
}
|
||||
|
||||
/// One entry of the LLM provider registry (issue #88).
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
@@ -853,6 +869,9 @@ pub fn merge(base: &mut Config, overlay: Config) {
|
||||
if o.sync_on_exit.is_some() {
|
||||
s.sync_on_exit = o.sync_on_exit;
|
||||
}
|
||||
if o.telemetry.is_some() {
|
||||
s.telemetry = o.telemetry;
|
||||
}
|
||||
if o.plugins.is_some() {
|
||||
s.plugins = o.plugins;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user