diff --git a/docs/spec/acceptance-criteria.md b/docs/spec/acceptance-criteria.md index 9902422..89e6a8e 100644 --- a/docs/spec/acceptance-criteria.md +++ b/docs/spec/acceptance-criteria.md @@ -21,6 +21,7 @@ Status: Accepted — resolves [Define cross-cutting acceptance criteria](https:/ - **CI-2** (P/A; ADR 0003 §§4–9) *TUI/CLI parity*: every TUI action has a CLI twin — pause (`fenris monitor pause`), resume (`fenris monitor resume`), collect-now (`fenris sample`), baseline set/clear, and the status fact set — with identical outcomes and wording. - **CI-3** *Prohibition set* (A = test, P = probe; each cites its clause): - No code path outside `fenris-collect` interrogates the device (ADR 0003 §7). + - No `/run/fenris` coordination surface or export layer exists anywhere; state lives in the observation store and coordination in systemd (ADR 0003 §1, ADR 0001 §2). - Polkit authorizes exactly one binary, `fenris-monitor`, under `com.bongbetic.fenris.monitor` `auth_admin` (ADR 0003 §5, ADR 0004 §3). - No absent hour is ever interpolated, estimated, or fabricated (ADR 0005 §2). - No alerting, notification, or escalation machinery exists anywhere (ADR 0005 §§5–6). @@ -76,6 +77,7 @@ Status: Accepted — resolves [Define cross-cutting acceptance criteria](https:/ - **PR-14** (P) `baseline set` / `baseline clear` persist through the polkit-guarded `fenris-monitor` verb after CLI-side validation. - **PR-15** (A) An identity-degraded controller segment (blank identity key — every rung of the key ladder empty) caps projection confidence at Limited evidence, with the contributing fact "controller identity unavailable — replacement detection relies on write-counter continuity only" rendered in every state; the cap combines idempotently with the 48-hour staleness drop, and ephemeral markers (model "Linux", non-pcie transport) never render as confidence facts ([Decide how degraded identity affects projection confidence](https://git.bongbetic.com/xavierk/Fenris/issues/15); ADR 0002 §§8–9 as amended). - **PR-16** (A) Identity-change semantics extend to blank keys verbatim: any visible change of the recorded identity key — including to or from a blank key — quarantines prior history from projection as a controller-identity change, while equal blank keys continue the segment segmented by DUW monotonicity alone (ADR 0002 §9 as amended). +- **PR-17** (A) Projection arithmetic is exactly `E_rated = entered_TBW × 10¹²` bytes, `E_implied = 100 · W_t / p` computed only for `1 ≤ p ≤ 254` (Percentage Used of 0 or saturated 255 implies no baseline — that precedence tier is unavailable), and `projected = max(E_baseline − W_t, 0) / rate` for `rate > 0` (ADR 0002 §2). ## Controller identity ([Verify the controller identity that segments observation history](https://git.bongbetic.com/xavierk/Fenris/issues/11), [Decide controller-segment metadata columns](https://git.bongbetic.com/xavierk/Fenris/issues/14); ADR 0001 §3 as amended) @@ -89,6 +91,7 @@ Status: Accepted — resolves [Define cross-cutting acceptance criteria](https:/ - **TUI-1** (A) Variant A "Panes": one dense keyboard-first screen; confidence rendered as evidence (state + contributing facts); boot enablement, runtime activity, last collect outcome, and freshness displayed as four separate facts. - **TUI-2** (M) Pause/resume asymmetry and polkit tty passthrough work in a live terminal: pause confirms, resume does not, and the platform agent prompts without breaking the TUI. - **TUI-3** (P) Textual runs on Python 3.9+, gated at install time, never a runtime crash. +- **TUI-4** (A) The Panes screen layout is normative: a full-width headline band (lifespan headline or its no-projection wording, confidence state with contributing facts, scenario range); a usage-history pane on the left (write-history sparkline with ▲ habit-change and ? unexplained-gap markers plus legend, habit-split bar with active/idle/powered-off/unknown shares); a drive-health and settings pane on the right (health facts, vendor-wear context line, read-only settings with the endurance baseline and its provenance label); a full-width service strip at the bottom (the four separate service facts, the monitoring-period line, the action legend). Production bindings are `p` pause (asks), `r` resume (does not), `c` collect now, `d` disclosures, `q` quit ([Prototype the TUI information architecture](https://git.bongbetic.com/xavierk/Fenris/issues/3)); the prototype branch is visual reference only. ## Failure and recovery (ADR 0005) @@ -112,6 +115,7 @@ Status: Accepted — resolves [Define cross-cutting acceptance criteria](https:/ - **IN-7** (P) `make uninstall` performs the sanctioned disable first (open period closes `user_disabled`), then removes venv, helpers, units, polkit policy, and wrapper while keeping `/etc/fenris` and the observation store; `make purge` additionally removes configuration and store. - **IN-8** (P) Dependencies are exact pins in a committed lockfile installed by both install and upgrade; refreshing pins is an explicit `make update-deps` step, never an install side effect. - **IN-9** (P) The installer verifies `python3 ≥ 3.9` and fails cleanly otherwise; `/var/lib/fenris` is created with root-written group-read permissions; the database file is created lazily by the first write. +- **IN-10** (P) Installed artifacts sit only at their fixed locations — units in `/etc/systemd/system`, helpers in `/usr/libexec/fenris`, polkit policy under `/usr/share/polkit-1/actions/`, configuration at `/etc/fenris`, observation store under `/var/lib/fenris` — and every placed file is recorded in the manifest (ADR 0004 §2; ADR 0003 §4). ## Collector acquisition path (ADR 0006)