- Change default collection cadence from 5 minutes to 3 minutes
(CADENCE_DEFAULT_S=180, systemd OnUnitInactiveSec=3min,
runit CADENCE=180)
- Update freshness threshold to 450s (2×180 + AccuracySec + 60)
- Add _query_live_graph_data(): queries raw samples from the last
3 hours and computes interval byte deltas with actual timestamps
- Add LiveActivityGraph widget: vertical bar chart of interval
volumes with read/write toggle (w key), arrow key inspection,
and click support
- Wire live graph into TUI layout (full-width row between daily
graph and drive health), refresh cycle, and CSS grid
- Replace t theme binding with t today/live binding; theme
selection via preferences file
- Add w binding for read/write toggle on live graph
- Update action legend, help screen, and grid layout for new
live-activity row
- Add 20 tests covering cadence constants, live query, widget
rendering, toggle, and TUI integration
- Update all cadence documentation (README, ADR 0003, acceptance
criteria LC-2, fenris-redesign constants table, CHANGELOG)
Deliver end-to-end native monitoring path under runit with existing
CLI/TUI controls and truthful status, preserving systemd behavior.
Changes:
- Add init system abstraction layer (src/fenris/init_system.py) that
detects systemd vs runit and provides unified interface for timer
control, on-demand collection, and service state queries
- Create runit service files (units/runit/) with completion-relative
5-minute cadence, 2-minute boot delay, bounded execution (90s),
no catch-up, and serialized runs via flock
- Update monitor.py to use abstraction layer instead of direct systemctl
- Update status.py to use abstraction layer for service state queries
- Update all packaging scripts (deb, rpm) for init-system-aware setup
- Update Makefile to install runit service files alongside systemd units
- Add 46 tests for init system abstraction layer
Spec: ADR 0008, §8.4, §8.5, §8.6, §8.7, §8.8
Closes#84
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
Headline and scenario rates now describe exact evidence-supported
monitored spans anchored at the latest published usage-evidence
endpoint T, not clock_now. Reader refresh alone never moves T or
dilutes rates.
- Add horizon_reasons field to ScenarioRange for specific unavailability facts
- Modify _compute_horizon_rate to use exact trailing 7/28/90×86400-second starts from T
- Show specific reasons for affected horizons (e.g., "starts before earliest data")
- Update TUI and CLI to display horizon-specific reasons
- Add 6 new tests for evidence-anchored projection rates
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- Schema migration 1-2: add segment_id to samples, unattributed bytes to day_aggregates
- Collector now derives hour observations and day aggregates from sample pairs
- Cross-hour deltas tracked as unattributed (no proportional allocation)
- Display states: 0 samples -> awaiting first, 1 sample -> awaiting another
- Monitoring period ensured open on each collection run
- Derivation failures preserve prior history
Closes#73
- open_store_readonly(): stat() PermissionError (non-group user on the
2750 store dir) now maps to StoreFault so status/TUI degrade instead
of crashing with a traceback.
- init_store(): chmod db + -wal/-shm group rw after WAL setup — SQLite
WAL readers need write access to sidecars even for mode=ro opens.
- Store dir 2750 → 2770 (tmpfiles + make install) and UMask=002 on the
collect unit so root-created files stay group-accessible.
- rpm %post upgrade path re-runs systemd-tmpfiles --create to correct
placement modes on existing machines.
Bump to 0.3.3.
Implement fenris status as the read-only CLI twin of the TUI,
composing from the observation store and allow-listed systemctl
properties per spec section 8.8.
New module src/fenris/status.py:
- Freshness grading with shared constants (section 8.9, LC-10)
- Configuration error from direct config reads (section 8.3, LC-4)
- Store fault / newer-schema exact phrases (section 9.4-9.5, FL-4/FL-5)
- Drive anomalies as ordinary facts (section 9.7, FL-7)
- Four separate service facts (section 7.3, LC-9, CI-2)
- Projection recomputed on read, never stored (section 6.10)
- Retired command rejection with migration pointers (section 8.8)
- Six disclosures via --disclosures flag (section 6.11, CI-4)
Updated fenris.py:
- Replaced old cmd_status with new status module integration
- Added retired command handlers (start/stop/run)
- Added global --device flag rejection
Tests: 43 new, 182 total passing, zero regressions.
Closes#27.