Chart Fenris’s persistent TUI monitoring redesign #1

Closed
opened 2026-08-31 08:02:17 +00:00 by xavierk · 0 comments
Owner

Destination

Produce an implementation-ready specification for replacing Fenris’s HTML dashboard with a keyboard-first TUI backed by an independent systemd collector, persistent compact observation storage, and a usage-adjusted theoretical lifespan whose projection confidence reflects the length, completeness, and stability of real usage history.

Notes

Domain: NVMe usage observation and endurance projection. Read CONTEXT.md, docs/agents/domain.md, and docs/agents/issue-tracker.md. Consult grilling and domain-modeling for decision tickets; also consult research or prototype when required by the ticket type.

Standing preferences: Linux/systemd only; one configured NVMe drive; fully local with no telemetry or vendor-data fetching; retain status and sample; use a maintained TUI framework; preserve existing observations through migration. This map plans the redesign and does not implement it.

Decisions so far

  • Evaluate Python TUI frameworks for Fenris: Choose Textual for the prototype, contingent on raising Fenris to Python 3.9+, with Urwid as the low-dependency and terminal-control fallback.

  • Verify NVMe endurance signals and projection constraints: Project baseline consumption from DUW and wall-clock habits, prefer verified model-specific TBW, and disclose coarse vendor wear plus categorical evidence (research context).

  • Verify systemd lifecycle and privilege constraints — Use a system timer and short-lived privileged collector, keep the TUI unprivileged, and mediate explicit startup toggles through polkit; research context.

  • Define the persistent observation store and legacy migration: One SQLite database in WAL mode at /var/lib/fenris/observations.db, root-written and group-read; entities for samples, hour observations, day aggregates, monitoring periods, controller segments, and the endurance baseline; 14-day raw retention; single-transaction idempotent migration from history.jsonl as sole authority (ADR 0001).

  • Define the lifespan projection and confidence model: One projection from the precedence-chosen baseline with Percentage Used as context only; headline rate from the most recent sustained regime (full history ≤90 days by default) with 7/28/90-day scenario ranges; UTC-day evidence gates and four-state categorical confidence with contributing facts (ADR 0002).

  • Define the collector, service, and CLI lifecycle: Timer-driven oneshot collector on a 5-minute OnUnitInactiveSec cadence, one-key /etc/fenris config, a polkit-guarded fenris-monitor helper owning pause/resume and monitoring-period rows (amending the systemd decision's direct-systemctl toggle), read-only status, helper-mediated sample, retired start/stop/fenris.sh, shared freshness constants (ADR 0003).

  • Prototype the TUI information architecture: Variant A “Panes” — one dense keyboard-first screen with confidence-as-evidence and four separate service facts; pause/resume asymmetry and Textual tty passthrough validated live (prototype branch).

  • Define installation, upgrade, and removal behavior: make install/upgrade/uninstall/purge over an /opt/fenris venv with a file manifest — dormant install with sanctioned-toggle opt-in, installer-run history.jsonl import, forward-only schema migrations behind a one-generation backup, exact dependency lockfile, and sanctioned-disable-before-uninstall (ADR 0004).

  • Define failure and recovery behavior: Refuse invariant-violating writes at the collector, never backfill gaps, treat store faults as visible degradation with human-sanctioned recovery, flat retry with no alerting, and collector-anchored periods for orphaned samples (ADR 0005).

  • Verify the controller identity that segments observation history: Controller segments key on the normalized, kernel-exposed subsystem NQN — kernel composite then model|serial as fallbacks, FR as metadata only — with identity change and DUW decrease as independent axes; legacy history imports under a labeled model-scoped legacy identity (research context).

  • Define endurance-baseline provenance and validation: Mandatory provenance is URL, revision, entry date, model, and nominal capacity; one active row with derived verification (machine match or recorded user attestation), an explicitly acknowledged unverified tier, unprivileged entry-time sysfs validation (normalized model containment, ±1% capacity), read-time applicability as a model match against the current controller segment (retained, never auto-deleted), and a polkit-guarded helper baseline verb (amends ADR 0001 and ADR 0003).

  • Decide controller-segment metadata columns: Segments carry a frozen-at-open, fully nullable metadata snapshot — normalized subnqn/sn/mn/fr plus vid/ssvid/transport and the identity_degraded flag, cntlid excluded; legacy segments import mn-only (amends ADR 0001).

  • Define cross-cutting acceptance criteria: Accepted criteria committed at docs/spec/acceptance-criteria.md — subsystem-organized testable statements with A/P/M evidence classes, ADR-traceability only, exhaustive state-matrix and TUI/CLI parity gates, prohibition set, migration interruption gates; SLOT-A (degraded identity) and SLOT-B (acquisition path) await their tickets.

  • Decide how degraded identity affects projection confidence: Degraded means a blank identity key only; it caps confidence at Limited with the "replacement detection relies on write-counter continuity only" fact, and key changes to or from blank quarantine like any identity change (amends ADR 0002; fills SLOT-A as PR-15/PR-16 + ID-4).

  • Choose the collector's NVMe acquisition path: Pin to smartctl -j for counters plus sysfs for identity — hard pin, no fallback, no partial samples, normalization once at write time; vid/ssvid from the PCI node when present (ADR 0006; fills SLOT-B as AC-1–AC-5).

  • Assemble the implementation-ready specification: One docs/spec/fenris-redesign.md, data-flow ordered, normatively restating every operative contract while rationale stays in ADRs 0001–0006 cited per section; a two-way ADR↔criterion traceability matrix as appendix gates assembly; one AFK task ticket (Write the Fenris redesign specification and close the map) executes it and closes the map.

Not yet specified

Out of scope

  • Retaining the HTML dashboard or HTTP server.
  • Supporting non-systemd operating systems or init systems.
  • Simultaneous monitoring of multiple drives.
  • Network telemetry or automatic vendor-data fetching.
  • Implementing the redesign during this Wayfinder effort.
## Destination Produce an implementation-ready specification for replacing Fenris’s HTML dashboard with a keyboard-first TUI backed by an independent systemd collector, persistent compact observation storage, and a usage-adjusted theoretical lifespan whose projection confidence reflects the length, completeness, and stability of real usage history. ## Notes Domain: NVMe usage observation and endurance projection. Read `CONTEXT.md`, `docs/agents/domain.md`, and `docs/agents/issue-tracker.md`. Consult `grilling` and `domain-modeling` for decision tickets; also consult `research` or `prototype` when required by the ticket type. Standing preferences: Linux/systemd only; one configured NVMe drive; fully local with no telemetry or vendor-data fetching; retain `status` and `sample`; use a maintained TUI framework; preserve existing observations through migration. This map plans the redesign and does not implement it. ## Decisions so far <!-- Closed decision tickets are indexed here by linked name and one-line gist. --> - [Evaluate Python TUI frameworks for Fenris](https://git.bongbetic.com/xavierk/Fenris/issues/6): Choose Textual for the prototype, contingent on raising Fenris to Python 3.9+, with Urwid as the low-dependency and terminal-control fallback. - [Verify NVMe endurance signals and projection constraints](https://git.bongbetic.com/xavierk/Fenris/issues/5): Project baseline consumption from DUW and wall-clock habits, prefer verified model-specific TBW, and disclose coarse vendor wear plus categorical evidence ([research context](https://git.bongbetic.com/xavierk/Fenris/src/branch/research/nvme-endurance-signals/docs/research/nvme-endurance-signals.md)). - [Verify systemd lifecycle and privilege constraints](https://git.bongbetic.com/xavierk/Fenris/issues/7) — Use a system timer and short-lived privileged collector, keep the TUI unprivileged, and mediate explicit startup toggles through polkit; [research context](https://git.bongbetic.com/xavierk/Fenris/src/branch/research/systemd-privilege-lifecycle/docs/research/systemd-privilege-lifecycle.md). - [Define the persistent observation store and legacy migration](https://git.bongbetic.com/xavierk/Fenris/issues/2): One SQLite database in WAL mode at `/var/lib/fenris/observations.db`, root-written and group-read; entities for samples, hour observations, day aggregates, monitoring periods, controller segments, and the endurance baseline; 14-day raw retention; single-transaction idempotent migration from `history.jsonl` as sole authority ([ADR 0001](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0001-observation-store-sqlite.md)). - [Define the lifespan projection and confidence model](https://git.bongbetic.com/xavierk/Fenris/issues/4): One projection from the precedence-chosen baseline with Percentage Used as context only; headline rate from the most recent sustained regime (full history ≤90 days by default) with 7/28/90-day scenario ranges; UTC-day evidence gates and four-state categorical confidence with contributing facts ([ADR 0002](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0002-projection-model-sustained-regime.md)). - [Define the collector, service, and CLI lifecycle](https://git.bongbetic.com/xavierk/Fenris/issues/8): Timer-driven oneshot collector on a 5-minute `OnUnitInactiveSec` cadence, one-key `/etc/fenris` config, a polkit-guarded `fenris-monitor` helper owning pause/resume and monitoring-period rows (amending the systemd decision's direct-systemctl toggle), read-only `status`, helper-mediated `sample`, retired `start`/`stop`/`fenris.sh`, shared freshness constants ([ADR 0003](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0003-service-lifecycle-and-sanctioned-toggle.md)). - [Prototype the TUI information architecture](https://git.bongbetic.com/xavierk/Fenris/issues/3): Variant A “Panes” — one dense keyboard-first screen with confidence-as-evidence and four separate service facts; pause/resume asymmetry and Textual tty passthrough validated live ([prototype branch](https://git.bongbetic.com/xavierk/Fenris/src/branch/prototype/tui-information-architecture/prototype/tui-ia)). - [Define installation, upgrade, and removal behavior](https://git.bongbetic.com/xavierk/Fenris/issues/9): make install/upgrade/uninstall/purge over an /opt/fenris venv with a file manifest — dormant install with sanctioned-toggle opt-in, installer-run history.jsonl import, forward-only schema migrations behind a one-generation backup, exact dependency lockfile, and sanctioned-disable-before-uninstall ([ADR 0004](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0004-install-upgrade-removal-lifecycle.md)). - [Define failure and recovery behavior](https://git.bongbetic.com/xavierk/Fenris/issues/10): Refuse invariant-violating writes at the collector, never backfill gaps, treat store faults as visible degradation with human-sanctioned recovery, flat retry with no alerting, and collector-anchored periods for orphaned samples ([ADR 0005](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0005-failure-detection-and-recovery.md)). - [Verify the controller identity that segments observation history](https://git.bongbetic.com/xavierk/Fenris/issues/11): Controller segments key on the normalized, kernel-exposed subsystem NQN — kernel composite then `model|serial` as fallbacks, FR as metadata only — with identity change and DUW decrease as independent axes; legacy history imports under a labeled model-scoped legacy identity ([research context](https://git.bongbetic.com/xavierk/Fenris/src/branch/research/controller-identity/docs/research/controller-identity.md)). - [Define endurance-baseline provenance and validation](https://git.bongbetic.com/xavierk/Fenris/issues/12): Mandatory provenance is URL, revision, entry date, model, and nominal capacity; one active row with derived verification (machine match or recorded user attestation), an explicitly acknowledged unverified tier, unprivileged entry-time sysfs validation (normalized model containment, ±1% capacity), read-time applicability as a model match against the current controller segment (retained, never auto-deleted), and a polkit-guarded helper `baseline` verb (amends ADR 0001 and ADR 0003). - [Decide controller-segment metadata columns](https://git.bongbetic.com/xavierk/Fenris/issues/14): Segments carry a frozen-at-open, fully nullable metadata snapshot — normalized `subnqn`/`sn`/`mn`/`fr` plus `vid`/`ssvid`/`transport` and the `identity_degraded` flag, `cntlid` excluded; legacy segments import `mn`-only (amends [ADR 0001](https://git.bongbetic.com/xavierk/Fenris/src/commit/305bdd4/docs/adr/0001-observation-store-sqlite.md)). - [Define cross-cutting acceptance criteria](https://git.bongbetic.com/xavierk/Fenris/issues/13): Accepted criteria committed at [docs/spec/acceptance-criteria.md](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/spec/acceptance-criteria.md) — subsystem-organized testable statements with A/P/M evidence classes, ADR-traceability only, exhaustive state-matrix and TUI/CLI parity gates, prohibition set, migration interruption gates; SLOT-A (degraded identity) and SLOT-B (acquisition path) await their tickets. - [Decide how degraded identity affects projection confidence](https://git.bongbetic.com/xavierk/Fenris/issues/15): Degraded means a blank identity key only; it caps confidence at Limited with the "replacement detection relies on write-counter continuity only" fact, and key changes to or from blank quarantine like any identity change (amends [ADR 0002](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0002-projection-model-sustained-regime.md); fills SLOT-A as PR-15/PR-16 + ID-4). - [Choose the collector's NVMe acquisition path](https://git.bongbetic.com/xavierk/Fenris/issues/16): Pin to `smartctl -j` for counters plus sysfs for identity — hard pin, no fallback, no partial samples, normalization once at write time; vid/ssvid from the PCI node when present ([ADR 0006](https://git.bongbetic.com/xavierk/Fenris/src/branch/main/docs/adr/0006-collector-acquisition-path.md); fills SLOT-B as AC-1–AC-5). - [Assemble the implementation-ready specification](https://git.bongbetic.com/xavierk/Fenris/issues/17): One `docs/spec/fenris-redesign.md`, data-flow ordered, normatively restating every operative contract while rationale stays in ADRs 0001–0006 cited per section; a two-way ADR↔criterion traceability matrix as appendix gates assembly; one AFK task ticket ([Write the Fenris redesign specification and close the map](https://git.bongbetic.com/xavierk/Fenris/issues/19)) executes it and closes the map. ## Not yet specified <!-- cleared: exact TUI presentation — settled by the prototype decision; cross-cutting acceptance criteria — graduated to its own ticket; spec assembly — graduated to its own ticket once the acquisition path closed --> ## Out of scope - Retaining the HTML dashboard or HTTP server. - Supporting non-systemd operating systems or init systems. - Simultaneous monitoring of multiple drives. - Network telemetry or automatic vendor-data fetching. - Implementing the redesign during this Wayfinder effort.
xavierk added this to the Wayfinder: Fenris persistent TUI monitoring redesign milestone 2026-08-31 08:02:17 +00:00
xavierk added the wayfinder:map label 2026-08-31 08:02:17 +00:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: xavierk/Fenris#1