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:
2026-08-19 21:28:26 -04:00
parent 6d51ce9504
commit 7cab1a0b5c
6 changed files with 379 additions and 2 deletions
+7 -1
View File
@@ -49,6 +49,7 @@ pub mod sessions;
pub mod shell;
pub mod state;
pub mod sync;
pub mod telemetry;
pub mod playbook;
pub mod plugins;
pub mod tables;
@@ -105,8 +106,13 @@ fn real_main() -> i32 {
app.log.verbose(&format!("session retention skipped: {e:#}"));
}
match commands::execute(&app) {
Ok(code) => code,
Ok(code) => {
// Issue #76: batched anonymous telemetry, fire-and-forget.
crate::telemetry::maybe_flush(&app);
code
}
Err(err) => {
crate::telemetry::maybe_flush(&app);
if app.json() {
let payload = serde_json::json!({
"error": format!("{:#}", err),