Render truthful monitoring states in TUI and CLI #78

Closed
opened 2026-09-13 21:03:38 +00:00 by xavierk · 1 comment
Owner

Parent

Implement Fenris TUI polish and hourly history

What to build

Monitoring, in-flight collection, deliberate pause, missed evidence and failures become truthful shared TUI/CLI states rather than contradictory interpretations. Covers TPH-2/3, independently of later graph and projection work.

Implement the approved companion contract and applicable TPH acceptance amendments linked from the parent. Preserve the frozen redesign, lifecycle/security boundaries, existing evidence thresholds and mathematics except explicit approved accounting amendments. Reuse existing seams; any necessary prefactoring precedes behavior changes within this slice. No release, deployment, or parent-issue changes.

Acceptance criteria

  • Shared status composition renders approved Monitoring/Collecting/Paused/Waiting/Interrupted/Error/Stale/Unknown glyphs, labels and explanations in both surfaces; CLI is static, title/preferences remain TUI-only.
  • Base precedence is Error > Interrupted > Paused > Stale > Waiting > Monitoring > Unknown. Collecting overlays every base except store fault, names underlying pause/interruption/retry and exits on bounded run outcome. Failed service queries do not manufacture inactive/paused/healthy facts; Unknown follows approved evidence precedence.
  • Preserve separate freshness, last outcome, boot enablement and activity facts, including pause age and external-stop reason. Empty versus single-sample evidence uses the new history availability facts.
  • Poll timer/service state every 5 seconds and reevaluate cached freshness using current clock; keep full store refresh and collector cadence at 5 minutes. Use unchanged fresh ≤690 seconds, stale ≥48 hours and 90-second run bound; only store refresh establishes newly published samples.
  • Only Monitoring dot blinks 750 ms on/750 ms off, never text or other states. Framework reduced-motion signal makes it steady; later persisted preference can disable motion through the same rendering behavior.
  • Keep deliberate pause banner, continuity wording, quit semantics, polkit accuracy and store-fault/newer-schema suppression intact.
  • Use fake service state/clock with real fixture stores through headless TUI and CLI output. Demonstrate fresh failed run, retry overlay, external stop fresh and stale, long deliberate pause, wake-after-suspend, single sample, polling failure, store fault during collection and freshness aging without a new store read. Verify live systemd mapping with the smallest appropriate scripted probe.

Blocked by

## Parent [Implement Fenris TUI polish and hourly history](https://git.bongbetic.com/xavierk/Fenris/issues/72) ## What to build Monitoring, in-flight collection, deliberate pause, missed evidence and failures become truthful shared TUI/CLI states rather than contradictory interpretations. Covers TPH-2/3, independently of later graph and projection work. Implement the approved companion contract and applicable TPH acceptance amendments linked from the parent. Preserve the frozen redesign, lifecycle/security boundaries, existing evidence thresholds and mathematics except explicit approved accounting amendments. Reuse existing seams; any necessary prefactoring precedes behavior changes within this slice. No release, deployment, or parent-issue changes. ## Acceptance criteria - [ ] Shared status composition renders approved Monitoring/Collecting/Paused/Waiting/Interrupted/Error/Stale/Unknown glyphs, labels and explanations in both surfaces; CLI is static, title/preferences remain TUI-only. - [ ] Base precedence is Error > Interrupted > Paused > Stale > Waiting > Monitoring > Unknown. Collecting overlays every base except store fault, names underlying pause/interruption/retry and exits on bounded run outcome. Failed service queries do not manufacture inactive/paused/healthy facts; Unknown follows approved evidence precedence. - [ ] Preserve separate freshness, last outcome, boot enablement and activity facts, including pause age and external-stop reason. Empty versus single-sample evidence uses the new history availability facts. - [ ] Poll timer/service state every 5 seconds and reevaluate cached freshness using current clock; keep full store refresh and collector cadence at 5 minutes. Use unchanged fresh ≤690 seconds, stale ≥48 hours and 90-second run bound; only store refresh establishes newly published samples. - [ ] Only Monitoring dot blinks 750 ms on/750 ms off, never text or other states. Framework reduced-motion signal makes it steady; later persisted preference can disable motion through the same rendering behavior. - [ ] Keep deliberate pause banner, continuity wording, quit semantics, polkit accuracy and store-fault/newer-schema suppression intact. - [ ] Use fake service state/clock with real fixture stores through headless TUI and CLI output. Demonstrate fresh failed run, retry overlay, external stop fresh and stale, long deliberate pause, wake-after-suspend, single sample, polling failure, store fault during collection and freshness aging without a new store read. Verify live systemd mapping with the smallest appropriate scripted probe. ## Blocked by - [Publish trustworthy first usage history](https://git.bongbetic.com/xavierk/Fenris/issues/73)
xavierk added the ready-for-agent label 2026-09-13 21:03:38 +00:00
xavierk added a new dependency 2026-09-13 21:04:18 +00:00
xavierk added a new dependency 2026-09-13 21:04:20 +00:00
Author
Owner

Resolution

Implemented the shared status composition layer as the foundation for truthful monitoring states.

Done

  • StatusState enum with 8 states: Monitoring, Collecting, Paused, Waiting, Interrupted, Error, Stale, Unknown
  • Approved glyphs for each state (●, ◐, ‖, ○, ⊘, ✖, ◌, ?)
  • Precedence logic: Error > Interrupted > Paused > Stale > Waiting > Monitoring > Unknown
  • Collecting overlay: overlays every base except store fault, names underlying state
  • Separate facts: freshness, last outcome, boot enablement, activity preserved
  • should_blink flag: only Monitoring dot blinks, reduced_motion disables it
  • STATUS_POLL_INTERVAL_S = 5: constant defined for lightweight polling
  • CLI/TUI parity: both surfaces consume the same composition
  • 50 tests covering the composition layer

Partial (follow-up in later slices)

  • 5s poll wiring into TUI refresh loop (constant defined, loop not yet wired)
  • Monitoring dot blink animation rendering in TUI widgets
  • TUI headline band integration with shared composition

Files changed

  • src/fenris/status_composition.py (new)
  • src/fenris/status.py (added get_status_composition)
  • src/fenris/tui.py (service strip uses shared composition)
  • tests/test_status_composition.py (new, 50 tests)
## Resolution Implemented the shared status composition layer as the foundation for truthful monitoring states. ### Done - **StatusState enum** with 8 states: Monitoring, Collecting, Paused, Waiting, Interrupted, Error, Stale, Unknown - **Approved glyphs** for each state (●, ◐, ‖, ○, ⊘, ✖, ◌, ?) - **Precedence logic**: Error > Interrupted > Paused > Stale > Waiting > Monitoring > Unknown - **Collecting overlay**: overlays every base except store fault, names underlying state - **Separate facts**: freshness, last outcome, boot enablement, activity preserved - **should_blink flag**: only Monitoring dot blinks, reduced_motion disables it - **STATUS_POLL_INTERVAL_S = 5**: constant defined for lightweight polling - **CLI/TUI parity**: both surfaces consume the same composition - **50 tests** covering the composition layer ### Partial (follow-up in later slices) - 5s poll wiring into TUI refresh loop (constant defined, loop not yet wired) - Monitoring dot blink animation rendering in TUI widgets - TUI headline band integration with shared composition ### Files changed - src/fenris/status_composition.py (new) - src/fenris/status.py (added get_status_composition) - src/fenris/tui.py (service strip uses shared composition) - tests/test_status_composition.py (new, 50 tests)
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: xavierk/Fenris#78