Define the persistent observation store and legacy migration #2
Notifications
Due Date
No due date set.
Blocks
Depends on
#4 Define the lifespan projection and confidence model
xavierk/Fenris
#5 Verify NVMe endurance signals and projection constraints
xavierk/Fenris
Reference: xavierk/Fenris#2
Reference in New Issue
Block a user
Parent map: Chart Fenris’s persistent TUI monitoring redesign
Question
What persistent observation model should Fenris use to represent monitoring periods, hourly active/idle/powered-off/unknown observations, compact long-term aggregates, recent raw samples, projection inputs, and schema versioning? Decide retention boundaries and an idempotent migration from history.jsonl and hourly.jsonl that preserves existing observation history and recovers safely from interruption.
Resolution — decided by grilling, all questions approved with recommendations.
Substrate & access: one SQLite database in WAL mode at
/var/lib/fenris/observations.db; root-owned, group-readable via the packaging-createdfenrisread group; the TUI opens it read-only. No/runsnapshot layer.Entities:
samples— recent raw SMART samples (ts, controller identity, raw DUW/DUR ints, percentage_used, available_spare, media_errors, power_on_hours, power_cycles, unsafe_shutdowns, temperature, critical_warning)hour_observations— one row per UTC hour: usage-habit split (seconds_active/seconds_idle/seconds_powered_off/seconds_unknown), DUW/DUR deltas, temp min/avg/max, sample count, coverage flag. Classification thresholds belong to the projection model (#4), not the store.day_aggregates— one row per UTC day (habit-evidence grain), keyed on UTC so derivation from hour rows is monotonic and DST-ambiguous days never exist.monitoring_periods—started_at,ended_at(NULL = open),end_causeenum (user_disabled,migrated, …). Powered-off time stays inside a period; deliberately disabled time does not.controller_segments— boundaries where controller identity changes or DUW decreases; write deltas never cross a segment.endurance_baseline— verified rated-TBW override in bytes plus provenance (source URL, doc revision, entry date), edited via the CLI;/etc/fenris/keeps operational config only.Retention: raw samples 14 days, pruned opportunistically by the collector; hour observations and day aggregates indefinite.
Migration (runs on first new-version collection): no-op if the legacy-import marker exists;
history.jsonlis the sole authority (import raw, derive hours and days, ignorehourly.jsonl— diff and log mismatches only); one implicit monitoring period opens at the first legacy sample and closes withend_cause = migrated; single transaction (interruption leaves the DB fully pre- or post-migration); legacy files renamed to*.migratedonly after commit, never deleted; malformed lines quarantined with a logged count, never silently dropped.Versioning:
PRAGMA user_versionplus ordered transactional migration steps; the collector refuses to run against an unknown newer version.Collector health: not stored — failures go to the journal per #7; the freshest sample timestamp is the store's staleness signal.
Assets: