When I open the Fenris TUI, I can't tell at a glance what application I'm looking at — there is no product name or maker credit on screen. I can't tell whether monitoring keeps running when I close the TUI, or whether it will come back after a reboot: nothing on screen states the persistence fact, and fenris status doesn't state it either. When I want to leave the screen, the quit affordance looks like a monitoring control, so I'm never sure whether pressing it stops the data collection I deliberately started (a Deliberate disable). When privileged actions prompt for authentication, nothing prepared me for it, and the wording never explains the elevation mechanism. And when a new release appears, its Gitea entry carries no notes — I have to diff the repository to learn what changed or how to verify the download.
Solution
Five dashboard clarity additions plus a changelog-driven release-notes mechanism, fully decided in the dashboard clarity specification:
Branding — the TUI header bar reads Fenris — NVMe endurance monitor, with a dimmed by Bongbetic credit inline with the service facts.
Continuity line — a labelled continuity row in the TUI service strip, mirrored verbatim by fenris status, reporting the boot fact as-is: monitoring: active in background · persists across reboots or monitoring: does not start on next boot.
Distinct stop indicators — a strong full-width paused block clearly identifying Deliberate disable (title + consequence + resume hint), visually separate from a bordered q QUIT TUI rail; the footer becomes p pause · r resume · c collect · d disclosures (the rail owns quit).
Auth banner — a one-time, polkit-accurate launch banner: privileged actions will prompt for authentication (polkit), cleared on the first refresh tick and never shown again in the session.
Release notes — a Keep a Changelog CHANGELOG.md as the source of truth; at tag time a fail-closed extractor slices the version's section and the release body is that section verbatim plus a standing install/verification footer; re-runs PATCH the body.
User Stories
As a TUI user, I want the header bar to read Fenris — NVMe endurance monitor, so that I immediately know which application I'm looking at and what it does.
As a TUI user, I want a dimmed by Bongbetic credit inline with the service facts, so that I know who makes Fenris without the credit competing with drive state.
As a TUI user, I want a continuity row reading monitoring: active in background · persists across reboots, so that I know closing the TUI does not stop collection and rebooting does not lose it.
As a TUI user, I want the continuity row to read monitoring: does not start on next boot when the timer is disabled, so that I'm not surprised after a reboot.
As a TUI user, I want the continuity row to keep reporting the boot fact as-is even while monitoring is paused, so that the row always tells me the plain fact rather than an inference.
As a CLI user, I want fenris status to print the same continuity line as the TUI, so that both surfaces answer the persistence question identically.
As a TUI user, when monitoring is paused I want a strong full-width block titled monitoring: paused — deliberate disable, so that I can't miss that collection has deliberately stopped.
As a TUI user, I want the paused block's subline paused time is excluded from your usage habit · resume: fenris monitor resume, so that I know the consequence for my data and exactly how to undo it.
As a CLI user, I want fenris status to print the same paused state line and consequence line when paused, so that script or terminal checks match the TUI word for word.
As a TUI user, I want a prominent bordered q QUIT TUI rail visually separate from the paused block, so that quitting the screen never looks like disabling monitoring.
As a TUI user, I want the footer to read p pause · r resume · c collect · d disclosures with no quit entry, so that the key hints I see match the keys that own each action.
As a TUI user, I want quitting the TUI to leave monitoring untouched, so that closing the dashboard and stopping collection remain two clearly separate acts.
As a TUI user, I want a launch banner saying privileged actions will prompt for authentication (polkit), so that the first authentication prompt doesn't surprise me.
As a TUI user, I want that banner to clear on the first refresh tick and never reappear, so that it informs once without becoming clutter.
As a user, I want elevation wording to be polkit-accurate everywhere and never say "sudo", so that instructions match what my system actually asks for.
As a release consumer, I want each Gitea release entry to list what was Added, Changed, and Fixed, so that I can decide whether and how to upgrade.
As a release consumer, I want every release entry to carry the standing install one-liners, checksum verification, and rollback pointer, so that I can act on the entry without hunting through docs.
As a maintainer, I want every changelog entry to land in [Unreleased] as part of the fixing change, so that notes never depend on a later write-up step I might forget.
As a maintainer, I want one release commit that bumps the version, renames [Unreleased] to the version heading, and restores an empty [Unreleased], so that tag, project version, and changelog always triple-match.
As a maintainer, I want the release workflow to fail closed when the section is missing or empty, the date is malformed, or the tag doesn't match the project version, so that a broken release can never publish silently.
As a maintainer, I want a re-run against an existing release to PATCH the body while uploaded assets skip idempotently, so that fixing a note never duplicates artifacts.
As a new user, I want a README "Reading the dashboard" section, so that the continuity line, paused-vs-quit distinction, auth banner, and release-notes location are explained where I first look.
As an implementer, I want every parity string defined once in the status composition layer with the TUI importing it, so that TUI/CLI wording drift is structurally impossible.
As an implementer, I want the locked strings, typography rules, and visual treatments recorded verbatim in the dashboard clarity specification, so that I need no ticket or map access to build this.
Implementation Decisions
Visual treatments (from the approved prototype): quiet integration as the base — the existing Panes information architecture is preserved; strong state blocks for the paused presentation; labelled rails for the quit affordance and the continuity row; the auth notice is a quiet informational line.
Locked TUI-only strings: header bar Fenris — NVMe endurance monitor; credit by Bongbetic (dimmed, inline with service facts, never in the action row); auth banner privileged actions will prompt for authentication (polkit); quit rail q QUIT TUI (bordered, labelled); footer p pause · r resume · c collect · d disclosures.
Locked parity strings (TUI and fenris status identical): monitoring: active in background · persists across reboots; monitoring: does not start on next boot; monitoring: paused — deliberate disable; paused time is excluded from your usage habit · resume: fenris monitor resume.
Typography: em-dash — separates a title from its qualifier; middle dot · joins facts within a line; UTF-8 assumed. Source strings are lowercase; any uppercase rendering is styling only.
Single string source: parity strings are defined once in the status composition layer; the TUI imports them — one definition point makes CI-2 wording drift structurally impossible.
Continuity semantics: keyed to the boot fact as-is, independently of run state (a Deliberate disable implies boot-disabled; the row still reports the fact, including while paused).
Paused presentation: strong full-width high-contrast block, title + consequence subline; fenris status prints the same two lines with identical wording. The resume hint uses the CLI form only; the footer owns key hints — no duplication.
Quit semantics: the rail owns quit; the footer carries no quit entry; quitting the TUI never alters monitoring state. This amends the register's TUI-4 binding list.
Auth banner lifecycle: full-width under the header at launch, cleared on the first refresh tick, never reappears in the session; TUI-only — fenris status never shows it. No user-facing string anywhere uses "sudo" (sudo belongs to install/upgrade docs).
Branding surfaces are TUI-only: fenris status never renders the header, credit, or auth banner.
Changelog shape (Keep a Changelog 1.1): ## [Unreleased] always present at top, even empty; version headings ## [X.Y.Z] - YYYY-MM-DD with strict ISO date; categories ### Added, ### Changed, ### Fixed only (security folds into Fixed); entries are single - bullets in imperative mood, user-facing, no commit hashes or issue numbers.
Extractor: a checked-in, unit-tested script takes the changelog path and a version, slices that version's section verbatim, and never reads [Unreleased]. It fails closed — a workflow error annotation plus nonzero exit — when the section is missing or empty or the date is malformed.
Tag guard: the release workflow fails when the pushed tag ≠ v{version from pyproject.toml}; the guard is skipped on manual dispatch.
Release body assembly: body = extracted section verbatim + standing footer from the release footer file (channel install one-liners, checksum verification, rollback pointer). The footer is standing text; only the changelog section varies. A re-run against an existing release PATCHes the body (re-sync is a feature); uploaded assets keep the existing idempotent-skip behavior.
Discipline: entries land in [Unreleased] as part of the fixing change; one release commit bumps the version, renames the section, restores an empty [Unreleased], and the tag points at it (tag ↔ version ↔ changelog triple-match enforced fail-closed); no backfill — per-release notes begin with the release shipping this mechanism, and the changelog starts with an empty [Unreleased].
README: gains a "Reading the dashboard" section (verbatim text locked in the dashboard clarity specification §8) placed after the CLI reference.
No glossary or ADR change: strings reuse existing terms (Deliberate disable); the mechanism implements the existing Release term.
Testing Decisions
Good tests assert external behavior only: rendered screen text under a headless pilot, rendered status output from a synthetic observation store, and extractor output/exit codes. No widget-tree internals, no string constants tested in isolation.
Seams (confirmed with the developer):
Headless Textual Pilot over the real TUI app — synthetic stores drive the app; covers branding visibility (DC-1), quit rail/footer bindings and quit-leaves-monitoring-alone (DC-4), and the auth banner lifecycle including clear-on-first-refresh-tick (DC-5). Prior art: the existing headless TUI tests.
CI-2 parity sweep — synthetic stores rendered through both surfaces, compared as lowercase source strings; covers continuity under both boot facts including while paused (DC-2) and the paused two-line presentation (DC-3). Prior art: the existing cross-cutting acceptance sweep.
Status render seam — synthetic store → rendered status text; covers the CLI side of the continuity and paused lines. Prior art: the existing status tests.
New pure-function extractor seam — changelog text + version → section slice or fail-closed error, as plain unit tests; the workflow wiring (tag guard, body assembly, PATCH logic) is tested structurally per the existing release dry-run test prior art. The one scripted manual-dispatch verification of body assembly is scripted-probe evidence, not CI.
Modules tested: the TUI app, the status composition layer, the extractor, and the release workflow (structural).
Out of Scope
Any TUI layout or information-architecture redesign beyond the five additions.
Backfilling historical releases with notes.
Editing the CI-2/CI-4 criterion texts (the new criteria carry their own test-impact notes).
Glossary or ADR changes.
Authoring new standing-footer content beyond what the release-packaging specification already fixes.
Further Notes
Decision sources: docs/spec/dashboard-clarity.md (decision-complete companion spec — verbatim strings, treatments, mechanism, README text) and the "Dashboard clarity and release notes" section (DC-1–DC-8) plus the TUI-4 amendment in docs/spec/acceptance-criteria.md. The Wayfinder map Chart Fenris dashboard clarity is closed; no ticket access needed.
The approved prototype on branch prototype/dashboard-clarity (commit 482c2ac) is visual reference only.
Standing constraints: TUI/CLI wording parity is binding (CI-2); elevation wording must be polkit-accurate; the CONTEXT.md glossary governs; docs/spec/fenris-redesign.md is frozen and remains authoritative.
## Problem Statement
When I open the Fenris TUI, I can't tell at a glance what application I'm looking at — there is no product name or maker credit on screen. I can't tell whether monitoring keeps running when I close the TUI, or whether it will come back after a reboot: nothing on screen states the persistence fact, and `fenris status` doesn't state it either. When I want to leave the screen, the quit affordance looks like a monitoring control, so I'm never sure whether pressing it stops the data collection I deliberately started (a *Deliberate disable*). When privileged actions prompt for authentication, nothing prepared me for it, and the wording never explains the elevation mechanism. And when a new release appears, its Gitea entry carries no notes — I have to diff the repository to learn what changed or how to verify the download.
## Solution
Five dashboard clarity additions plus a changelog-driven release-notes mechanism, fully decided in the dashboard clarity specification:
1. **Branding** — the TUI header bar reads `Fenris — NVMe endurance monitor`, with a dimmed `by Bongbetic` credit inline with the service facts.
2. **Continuity line** — a labelled continuity row in the TUI service strip, mirrored verbatim by `fenris status`, reporting the boot fact as-is: `monitoring: active in background · persists across reboots` or `monitoring: does not start on next boot`.
3. **Distinct stop indicators** — a strong full-width paused block clearly identifying *Deliberate disable* (title + consequence + resume hint), visually separate from a bordered `q QUIT TUI` rail; the footer becomes `p pause · r resume · c collect · d disclosures` (the rail owns quit).
4. **Auth banner** — a one-time, polkit-accurate launch banner: `privileged actions will prompt for authentication (polkit)`, cleared on the first refresh tick and never shown again in the session.
5. **Release notes** — a Keep a Changelog `CHANGELOG.md` as the source of truth; at tag time a fail-closed extractor slices the version's section and the release body is that section verbatim plus a standing install/verification footer; re-runs PATCH the body.
## User Stories
1. As a TUI user, I want the header bar to read `Fenris — NVMe endurance monitor`, so that I immediately know which application I'm looking at and what it does.
2. As a TUI user, I want a dimmed `by Bongbetic` credit inline with the service facts, so that I know who makes Fenris without the credit competing with drive state.
3. As a TUI user, I want a continuity row reading `monitoring: active in background · persists across reboots`, so that I know closing the TUI does not stop collection and rebooting does not lose it.
4. As a TUI user, I want the continuity row to read `monitoring: does not start on next boot` when the timer is disabled, so that I'm not surprised after a reboot.
5. As a TUI user, I want the continuity row to keep reporting the boot fact as-is even while monitoring is paused, so that the row always tells me the plain fact rather than an inference.
6. As a CLI user, I want `fenris status` to print the same continuity line as the TUI, so that both surfaces answer the persistence question identically.
7. As a TUI user, when monitoring is paused I want a strong full-width block titled `monitoring: paused — deliberate disable`, so that I can't miss that collection has deliberately stopped.
8. As a TUI user, I want the paused block's subline `paused time is excluded from your usage habit · resume: fenris monitor resume`, so that I know the consequence for my data and exactly how to undo it.
9. As a CLI user, I want `fenris status` to print the same paused state line and consequence line when paused, so that script or terminal checks match the TUI word for word.
10. As a TUI user, I want a prominent bordered `q QUIT TUI` rail visually separate from the paused block, so that quitting the screen never looks like disabling monitoring.
11. As a TUI user, I want the footer to read `p pause · r resume · c collect · d disclosures` with no quit entry, so that the key hints I see match the keys that own each action.
12. As a TUI user, I want quitting the TUI to leave monitoring untouched, so that closing the dashboard and stopping collection remain two clearly separate acts.
13. As a TUI user, I want a launch banner saying `privileged actions will prompt for authentication (polkit)`, so that the first authentication prompt doesn't surprise me.
14. As a TUI user, I want that banner to clear on the first refresh tick and never reappear, so that it informs once without becoming clutter.
15. As a user, I want elevation wording to be polkit-accurate everywhere and never say "sudo", so that instructions match what my system actually asks for.
16. As a release consumer, I want each Gitea release entry to list what was Added, Changed, and Fixed, so that I can decide whether and how to upgrade.
17. As a release consumer, I want every release entry to carry the standing install one-liners, checksum verification, and rollback pointer, so that I can act on the entry without hunting through docs.
18. As a maintainer, I want every changelog entry to land in `[Unreleased]` as part of the fixing change, so that notes never depend on a later write-up step I might forget.
19. As a maintainer, I want one release commit that bumps the version, renames `[Unreleased]` to the version heading, and restores an empty `[Unreleased]`, so that tag, project version, and changelog always triple-match.
20. As a maintainer, I want the release workflow to fail closed when the section is missing or empty, the date is malformed, or the tag doesn't match the project version, so that a broken release can never publish silently.
21. As a maintainer, I want a re-run against an existing release to PATCH the body while uploaded assets skip idempotently, so that fixing a note never duplicates artifacts.
22. As a new user, I want a README "Reading the dashboard" section, so that the continuity line, paused-vs-quit distinction, auth banner, and release-notes location are explained where I first look.
23. As an implementer, I want every parity string defined once in the status composition layer with the TUI importing it, so that TUI/CLI wording drift is structurally impossible.
24. As an implementer, I want the locked strings, typography rules, and visual treatments recorded verbatim in the dashboard clarity specification, so that I need no ticket or map access to build this.
## Implementation Decisions
- **Visual treatments** (from the approved prototype): quiet integration as the base — the existing Panes information architecture is preserved; strong state blocks for the paused presentation; labelled rails for the quit affordance and the continuity row; the auth notice is a quiet informational line.
- **Locked TUI-only strings**: header bar `Fenris — NVMe endurance monitor`; credit `by Bongbetic` (dimmed, inline with service facts, never in the action row); auth banner `privileged actions will prompt for authentication (polkit)`; quit rail `q QUIT TUI` (bordered, labelled); footer `p pause · r resume · c collect · d disclosures`.
- **Locked parity strings** (TUI and `fenris status` identical): `monitoring: active in background · persists across reboots`; `monitoring: does not start on next boot`; `monitoring: paused — deliberate disable`; `paused time is excluded from your usage habit · resume: fenris monitor resume`.
- **Typography**: em-dash `—` separates a title from its qualifier; middle dot `·` joins facts within a line; UTF-8 assumed. Source strings are lowercase; any uppercase rendering is styling only.
- **Single string source**: parity strings are defined once in the status composition layer; the TUI imports them — one definition point makes CI-2 wording drift structurally impossible.
- **Continuity semantics**: keyed to the boot fact as-is, independently of run state (a Deliberate disable implies boot-disabled; the row still reports the fact, including while paused).
- **Paused presentation**: strong full-width high-contrast block, title + consequence subline; `fenris status` prints the same two lines with identical wording. The resume hint uses the CLI form only; the footer owns key hints — no duplication.
- **Quit semantics**: the rail owns quit; the footer carries no quit entry; quitting the TUI never alters monitoring state. This amends the register's TUI-4 binding list.
- **Auth banner lifecycle**: full-width under the header at launch, cleared on the first refresh tick, never reappears in the session; TUI-only — `fenris status` never shows it. No user-facing string anywhere uses "sudo" (sudo belongs to install/upgrade docs).
- **Branding surfaces are TUI-only**: `fenris status` never renders the header, credit, or auth banner.
- **Changelog shape** (Keep a Changelog 1.1): `## [Unreleased]` always present at top, even empty; version headings `## [X.Y.Z] - YYYY-MM-DD` with strict ISO date; categories `### Added`, `### Changed`, `### Fixed` only (security folds into Fixed); entries are single `- ` bullets in imperative mood, user-facing, no commit hashes or issue numbers.
- **Extractor**: a checked-in, unit-tested script takes the changelog path and a version, slices that version's section verbatim, and never reads `[Unreleased]`. It fails closed — a workflow error annotation plus nonzero exit — when the section is missing or empty or the date is malformed.
- **Tag guard**: the release workflow fails when the pushed tag ≠ `v{version from pyproject.toml}`; the guard is skipped on manual dispatch.
- **Release body assembly**: body = extracted section verbatim + standing footer from the release footer file (channel install one-liners, checksum verification, rollback pointer). The footer is standing text; only the changelog section varies. A re-run against an existing release PATCHes the body (re-sync is a feature); uploaded assets keep the existing idempotent-skip behavior.
- **Discipline**: entries land in `[Unreleased]` as part of the fixing change; one release commit bumps the version, renames the section, restores an empty `[Unreleased]`, and the tag points at it (tag ↔ version ↔ changelog triple-match enforced fail-closed); no backfill — per-release notes begin with the release shipping this mechanism, and the changelog starts with an empty `[Unreleased]`.
- **README**: gains a "Reading the dashboard" section (verbatim text locked in the dashboard clarity specification §8) placed after the CLI reference.
- **No glossary or ADR change**: strings reuse existing terms (*Deliberate disable*); the mechanism implements the existing *Release* term.
## Testing Decisions
- **Good tests assert external behavior only**: rendered screen text under a headless pilot, rendered status output from a synthetic observation store, and extractor output/exit codes. No widget-tree internals, no string constants tested in isolation.
- **Seams** (confirmed with the developer):
1. **Headless Textual Pilot over the real TUI app** — synthetic stores drive the app; covers branding visibility (DC-1), quit rail/footer bindings and quit-leaves-monitoring-alone (DC-4), and the auth banner lifecycle including clear-on-first-refresh-tick (DC-5). Prior art: the existing headless TUI tests.
2. **CI-2 parity sweep** — synthetic stores rendered through both surfaces, compared as lowercase source strings; covers continuity under both boot facts including while paused (DC-2) and the paused two-line presentation (DC-3). Prior art: the existing cross-cutting acceptance sweep.
3. **Status render seam** — synthetic store → rendered status text; covers the CLI side of the continuity and paused lines. Prior art: the existing status tests.
4. **New pure-function extractor seam** — changelog text + version → section slice or fail-closed error, as plain unit tests; the workflow wiring (tag guard, body assembly, PATCH logic) is tested structurally per the existing release dry-run test prior art. The one scripted manual-dispatch verification of body assembly is scripted-probe evidence, not CI.
- **Modules tested**: the TUI app, the status composition layer, the extractor, and the release workflow (structural).
## Out of Scope
- Any TUI layout or information-architecture redesign beyond the five additions.
- Backfilling historical releases with notes.
- Editing the CI-2/CI-4 criterion texts (the new criteria carry their own test-impact notes).
- Glossary or ADR changes.
- Authoring new standing-footer content beyond what the release-packaging specification already fixes.
## Further Notes
- Decision sources: `docs/spec/dashboard-clarity.md` (decision-complete companion spec — verbatim strings, treatments, mechanism, README text) and the "Dashboard clarity and release notes" section (DC-1–DC-8) plus the TUI-4 amendment in `docs/spec/acceptance-criteria.md`. The Wayfinder map [Chart Fenris dashboard clarity](https://git.bongbetic.com/xavierk/Fenris/issues/55) is closed; no ticket access needed.
- The approved prototype on branch `prototype/dashboard-clarity` (commit `482c2ac`) is visual reference only.
- Standing constraints: TUI/CLI wording parity is binding (CI-2); elevation wording must be polkit-accurate; the `CONTEXT.md` glossary governs; `docs/spec/fenris-redesign.md` is frozen and remains authoritative.
All eight dashboard clarity criteria and the release-notes mechanism are implemented, tested, and verified.
What shipped
TUI additions (DC-1–DC-5):
Header bar reads Fenris — NVMe endurance monitor; dimmed by Bongbetic inline with service facts (TUI-only)
Continuity row: monitoring: active in background · persists across reboots or monitoring: does not start on next boot — keyed to boot fact as-is, independent of run state
CI-2 parity sweep: three monitoring states through both views
Status render: continuity, paused, TUI-exclusion
Extractor: verbatim extraction, fail-closed, body assembly, release-request decisions
## Acceptance completion — DC-1–DC-8
All eight dashboard clarity criteria and the release-notes mechanism are implemented, tested, and verified.
### What shipped
**TUI additions (DC-1–DC-5):**
- Header bar reads `Fenris — NVMe endurance monitor`; dimmed `by Bongbetic` inline with service facts (TUI-only)
- Continuity row: `monitoring: active in background · persists across reboots` or `monitoring: does not start on next boot` — keyed to boot fact as-is, independent of run state
- Paused block: strong full-width `monitoring: paused — deliberate disable` with consequence subline
- Bordered `q QUIT TUI` rail, visually separate from monitoring state; footer `p pause · r resume · c collect · d disclosures` (no quit)
- Auth banner: `privileged actions will prompt for authentication (polkit)` — clears on first refresh, never reappears
- Quitting the TUI never alters monitoring state
**Parity (CI-2):**
- Single source in `status.py`; TUI imports `monitoring_continuity`, `deliberate_pause_lines`, `is_deliberately_paused`
- CI-2 sweep tests all three states (active+enabled, boot-disabled, deliberately-paused) through both views
**Release notes (DC-6–DC-8):**
- `CHANGELOG.md` — Keep a Changelog 1.1 shape, `[Unreleased]` always first
- `scripts/extract_changelog.py` — unit-tested extractor, fails closed on missing/empty/malformed
- `scripts/release_request.py` — POST vs PATCH decision for Gitea releases
- Release workflow: tag guard, changelog extraction, body assembly with standing footer, PATCH on re-run
- `packaging/release-footer.md` — channel install, checksum verification, rollback pointer
**README:** "Reading the dashboard" section added after CLI reference.
### Commits
`7bbe5ce` feat(tui): branding + auth banner
`d01df64` feat(tui): continuity, paused state, quit rail
`f077fa6` feat(release): changelog-driven notes
`608ad7f` docs(release): consumer pointer
`cfdef63` fix(release): safe publication request
`f406285` release: v0.3.4
### Test evidence
405 passed, 34 skipped (Docker-dependent packaging tests). DC coverage:
- Headless TUI pilot: branding, auth banner lifecycle, continuity, paused block, quit rail, quit-leaves-monitoring
- CI-2 parity sweep: three monitoring states through both views
- Status render: continuity, paused, TUI-exclusion
- Extractor: verbatim extraction, fail-closed, body assembly, release-request decisions
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Problem Statement
When I open the Fenris TUI, I can't tell at a glance what application I'm looking at — there is no product name or maker credit on screen. I can't tell whether monitoring keeps running when I close the TUI, or whether it will come back after a reboot: nothing on screen states the persistence fact, and
fenris statusdoesn't state it either. When I want to leave the screen, the quit affordance looks like a monitoring control, so I'm never sure whether pressing it stops the data collection I deliberately started (a Deliberate disable). When privileged actions prompt for authentication, nothing prepared me for it, and the wording never explains the elevation mechanism. And when a new release appears, its Gitea entry carries no notes — I have to diff the repository to learn what changed or how to verify the download.Solution
Five dashboard clarity additions plus a changelog-driven release-notes mechanism, fully decided in the dashboard clarity specification:
Fenris — NVMe endurance monitor, with a dimmedby Bongbeticcredit inline with the service facts.fenris status, reporting the boot fact as-is:monitoring: active in background · persists across rebootsormonitoring: does not start on next boot.q QUIT TUIrail; the footer becomesp pause · r resume · c collect · d disclosures(the rail owns quit).privileged actions will prompt for authentication (polkit), cleared on the first refresh tick and never shown again in the session.CHANGELOG.mdas the source of truth; at tag time a fail-closed extractor slices the version's section and the release body is that section verbatim plus a standing install/verification footer; re-runs PATCH the body.User Stories
Fenris — NVMe endurance monitor, so that I immediately know which application I'm looking at and what it does.by Bongbeticcredit inline with the service facts, so that I know who makes Fenris without the credit competing with drive state.monitoring: active in background · persists across reboots, so that I know closing the TUI does not stop collection and rebooting does not lose it.monitoring: does not start on next bootwhen the timer is disabled, so that I'm not surprised after a reboot.fenris statusto print the same continuity line as the TUI, so that both surfaces answer the persistence question identically.monitoring: paused — deliberate disable, so that I can't miss that collection has deliberately stopped.paused time is excluded from your usage habit · resume: fenris monitor resume, so that I know the consequence for my data and exactly how to undo it.fenris statusto print the same paused state line and consequence line when paused, so that script or terminal checks match the TUI word for word.q QUIT TUIrail visually separate from the paused block, so that quitting the screen never looks like disabling monitoring.p pause · r resume · c collect · d disclosureswith no quit entry, so that the key hints I see match the keys that own each action.privileged actions will prompt for authentication (polkit), so that the first authentication prompt doesn't surprise me.[Unreleased]as part of the fixing change, so that notes never depend on a later write-up step I might forget.[Unreleased]to the version heading, and restores an empty[Unreleased], so that tag, project version, and changelog always triple-match.Implementation Decisions
Fenris — NVMe endurance monitor; creditby Bongbetic(dimmed, inline with service facts, never in the action row); auth bannerprivileged actions will prompt for authentication (polkit); quit railq QUIT TUI(bordered, labelled); footerp pause · r resume · c collect · d disclosures.fenris statusidentical):monitoring: active in background · persists across reboots;monitoring: does not start on next boot;monitoring: paused — deliberate disable;paused time is excluded from your usage habit · resume: fenris monitor resume.—separates a title from its qualifier; middle dot·joins facts within a line; UTF-8 assumed. Source strings are lowercase; any uppercase rendering is styling only.fenris statusprints the same two lines with identical wording. The resume hint uses the CLI form only; the footer owns key hints — no duplication.fenris statusnever shows it. No user-facing string anywhere uses "sudo" (sudo belongs to install/upgrade docs).fenris statusnever renders the header, credit, or auth banner.## [Unreleased]always present at top, even empty; version headings## [X.Y.Z] - YYYY-MM-DDwith strict ISO date; categories### Added,### Changed,### Fixedonly (security folds into Fixed); entries are single-bullets in imperative mood, user-facing, no commit hashes or issue numbers.[Unreleased]. It fails closed — a workflow error annotation plus nonzero exit — when the section is missing or empty or the date is malformed.v{version from pyproject.toml}; the guard is skipped on manual dispatch.[Unreleased]as part of the fixing change; one release commit bumps the version, renames the section, restores an empty[Unreleased], and the tag points at it (tag ↔ version ↔ changelog triple-match enforced fail-closed); no backfill — per-release notes begin with the release shipping this mechanism, and the changelog starts with an empty[Unreleased].Testing Decisions
Out of Scope
Further Notes
docs/spec/dashboard-clarity.md(decision-complete companion spec — verbatim strings, treatments, mechanism, README text) and the "Dashboard clarity and release notes" section (DC-1–DC-8) plus the TUI-4 amendment indocs/spec/acceptance-criteria.md. The Wayfinder map Chart Fenris dashboard clarity is closed; no ticket access needed.prototype/dashboard-clarity(commit482c2ac) is visual reference only.CONTEXT.mdglossary governs;docs/spec/fenris-redesign.mdis frozen and remains authoritative.Acceptance completion — DC-1–DC-8
All eight dashboard clarity criteria and the release-notes mechanism are implemented, tested, and verified.
What shipped
TUI additions (DC-1–DC-5):
Fenris — NVMe endurance monitor; dimmedby Bongbeticinline with service facts (TUI-only)monitoring: active in background · persists across rebootsormonitoring: does not start on next boot— keyed to boot fact as-is, independent of run statemonitoring: paused — deliberate disablewith consequence sublineq QUIT TUIrail, visually separate from monitoring state; footerp pause · r resume · c collect · d disclosures(no quit)privileged actions will prompt for authentication (polkit)— clears on first refresh, never reappearsParity (CI-2):
status.py; TUI importsmonitoring_continuity,deliberate_pause_lines,is_deliberately_pausedRelease notes (DC-6–DC-8):
CHANGELOG.md— Keep a Changelog 1.1 shape,[Unreleased]always firstscripts/extract_changelog.py— unit-tested extractor, fails closed on missing/empty/malformedscripts/release_request.py— POST vs PATCH decision for Gitea releasespackaging/release-footer.md— channel install, checksum verification, rollback pointerREADME: "Reading the dashboard" section added after CLI reference.
Commits
7bbe5cefeat(tui): branding + auth bannerd01df64feat(tui): continuity, paused state, quit railf077fa6feat(release): changelog-driven notes608ad7fdocs(release): consumer pointercfdef63fix(release): safe publication requestf406285release: v0.3.4Test evidence
405 passed, 34 skipped (Docker-dependent packaging tests). DC coverage: