fix(cal): surface dropped VEVENTs; instrument DAV syncs + store lifecycle; redact DAV config Debug #373

Merged
KofTwentyTwo merged 1 commits from story/obs-6-cal-contacts-store-observability into dev 2026-08-01 00:17:45 +00:00
KofTwentyTwo commented 2026-08-01 00:15:50 +00:00 (Migrated from github.com)

Summary

  • Fixes a silent-drop bug: an unparseable VEVENT inside a CalDAV multistatus response was discarded with no trace (if let Ok(event) = ... and no else). It now logs a WARN with the VEVENT's UID (best-effort extraction, never the full body) and a short parse-error reason.
  • Instruments the CalDAV (fetch_remote_events) and CardDAV (fetch_remote_vcards) round trips with #[instrument] spans plus debug!/info! completion logs reporting fetched/parsed/dropped counts, keyed by account/calendar id only.
  • Adds INFO lifecycle logging to nuncio-store: additive SQLite column migrations (ensure_accounts_*, ensure_messages_identity_columns) now log which table/column was added, and SecretManager::get_or_create_key_bytes logs that a key was minted on first use (purpose + length, never the key bytes).
  • Hardens a latent leak: CalDavAccountConfig/CardDavAccountConfig derived Debug while holding auth_token. Both now use a manual Debug impl that renders auth_token: "<redacted>", so a future debug!(?config) or panic message can never leak the token.

Test plan

  • parse_multistatus_response_surfaces_a_warn_for_a_dropped_vevent_instead_of_silence (nuncio-cal): an unresolvable-TZID VEVENT logs a WARN with its UID; the sibling good VEVENT still parses; the dropped event's summary never appears in any captured telemetry field.
  • fetch_remote_events_logs_completion_counts_including_a_drop (nuncio-cal, wiremock): a CalDAV sync with one bad + one good VEVENT logs fetched=2, parsed=1, dropped=1.
  • fetch_remote_vcards_logs_completion_counts (nuncio-contacts, wiremock): a CardDAV sync logs completion counts; vCard PII never appears in telemetry.
  • debug_impl_redacts_auth_token (both crates): format!("{:?}", config) never contains the raw token, and does contain <redacted>.
  • migrate_logs_when_an_additive_column_migration_actually_runs (nuncio-store): opening an old-schema accounts table logs an INFO naming the migrated column.
  • get_or_create_key_bytes_logs_minting_without_leaking_the_key (nuncio-store): first-use key minting logs INFO with the key's purpose; the minted key bytes (hex-encoded) never appear in the captured log.
  • cargo fmt --all -- --check, cargo check-all, cargo test-all all green (0 failed, 0 ignored) via the local pre-commit hook (CI-equivalent).

Refs #362

## Summary - Fixes a silent-drop bug: an unparseable VEVENT inside a CalDAV `multistatus` response was discarded with no trace (`if let Ok(event) = ...` and no `else`). It now logs a `WARN` with the VEVENT's UID (best-effort extraction, never the full body) and a short parse-error reason. - Instruments the CalDAV (`fetch_remote_events`) and CardDAV (`fetch_remote_vcards`) round trips with `#[instrument]` spans plus `debug!`/`info!` completion logs reporting `fetched`/`parsed`/`dropped` counts, keyed by account/calendar id only. - Adds `INFO` lifecycle logging to `nuncio-store`: additive SQLite column migrations (`ensure_accounts_*`, `ensure_messages_identity_columns`) now log which table/column was added, and `SecretManager::get_or_create_key_bytes` logs that a key was minted on first use (purpose + length, never the key bytes). - Hardens a latent leak: `CalDavAccountConfig`/`CardDavAccountConfig` derived `Debug` while holding `auth_token`. Both now use a manual `Debug` impl that renders `auth_token: "<redacted>"`, so a future `debug!(?config)` or panic message can never leak the token. ## Test plan - [x] `parse_multistatus_response_surfaces_a_warn_for_a_dropped_vevent_instead_of_silence` (nuncio-cal): an unresolvable-TZID VEVENT logs a WARN with its UID; the sibling good VEVENT still parses; the dropped event's summary never appears in any captured telemetry field. - [x] `fetch_remote_events_logs_completion_counts_including_a_drop` (nuncio-cal, wiremock): a CalDAV sync with one bad + one good VEVENT logs `fetched=2, parsed=1, dropped=1`. - [x] `fetch_remote_vcards_logs_completion_counts` (nuncio-contacts, wiremock): a CardDAV sync logs completion counts; vCard PII never appears in telemetry. - [x] `debug_impl_redacts_auth_token` (both crates): `format!("{:?}", config)` never contains the raw token, and does contain `<redacted>`. - [x] `migrate_logs_when_an_additive_column_migration_actually_runs` (nuncio-store): opening an old-schema `accounts` table logs an INFO naming the migrated column. - [x] `get_or_create_key_bytes_logs_minting_without_leaking_the_key` (nuncio-store): first-use key minting logs INFO with the key's purpose; the minted key bytes (hex-encoded) never appear in the captured log. - [x] `cargo fmt --all -- --check`, `cargo check-all`, `cargo test-all` all green (0 failed, 0 ignored) via the local pre-commit hook (CI-equivalent). Refs #362
Sign in to join this conversation.