Add test_python_floor to the containerized packaging matrix:
- Sub-check 1: Ubuntu 22.04 (Python 3.10) installs successfully,
confirming the floor is met on the oldest supported deb target.
- Sub-check 2: Debian 11 (Python 3.9) fails to configure due to
unmet python3 (>= 3.10) dependency, verifying clean failure below floor.
Fix Makefile check-python gate to enforce Python >= 3.10, matching the
nfpm depends declaration.
Full compatibility matrix is now green: 17 packaging tests (dormant
install, migration guard, upgrade semantics, removal semantics, and
Python floor) pass across all four targets (Debian 12, Ubuntu 22.04,
Ubuntu 24.04, Fedora 40).
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- Fix nfpm.yaml ghost directory to include `group: fenris` so RPM metadata
matches the tmpfiles.d-created ownership (root:fenris 2750)
- Add RPM-native ownership assertions: store dir reported as package-owned
via `rpm -qf`, store contents verified as never owned by the package
- Add RPM conffile assertion: `rpm -qc` verifies fenris.conf is listed
- Unify store dir stat assertion across both formats (deb and rpm both
assert mode 2750 root:fenris)
- Remove unused `distro` parameter from `_find_package()`
All 16 packaging tests pass across the full matrix (3 deb + 1 rpm × 4 scenarios).
All 289 non-packaging tests pass.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- Copy packages to /pkg/ instead of /tmp/ to avoid tmpfs masking in
docker run --tmpfs /tmp, which hid packages needed at runtime by the
migration guard and upgrade tests
- Add version faking for deb upgrade test: sed the dpkg status to show
version 0.2.0 so dpkg -i treats the reinstall as an upgrade and
postinst receives the old-version argument
- For RPM upgrade test: extract and manually invoke the post scriptlet
with $1=2 (upgrade arguments), since faking a different version in
the binary RPM database is not practical
- Parameterize migration guard and upgrade assertions with pkg_name
(and version) instead of hardcoding filenames
All 16 packaging tests now pass across debian:bookworm, ubuntu:22.04,
ubuntu:24.04, and fedora:40.
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
- Upgrade path restarts only fenris-collect.timer, not fenris-collect.service
(spec §7: "a running oneshot finishes on its old interpreter")
- Remove redundant deb depends override in nfpm.yaml (top-level is sufficient)
- Remove common.sh sourcing — scripts are self-contained to avoid path
dependency when dpkg/rpm run them from /var/lib/dpkg/info/
Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
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.
Hour classification (PR-4):
- Powered-off: POH delta < 90% of wall-clock span
- Active: DUW delta >= 256 MiB
- Idle: powered on + sampled + below active threshold
- Unknown: unsampled without POH evidence
- Four splits sum to exactly wall_clock_seconds
- Disabled time is never an hour state
Monitoring periods (FL-8):
- ensure_period_open: opens period at run moment if none exists
- close_period: closes with end cause
- is_inside_period: checks timestamp against period bounds
- Never backdated; wall-clock outside periods excluded from denominator
Day aggregates (ST-4, PR-5):
- Derived monotonically from hour rows
- UTC-bounded; no 23/25-hour days
- Coverage: known seconds / period wall-clock
- Gap hours inside periods contribute unknown seconds
- Hours outside periods excluded entirely
- No absent hour interpolated/estimated/fabricated (FL-3)
Raw sample pruning (ST-5):
- Prunes samples older than 14 days
- Hour observations and day aggregates retained indefinitely
Closes#22
- Header now shows the Bongbetic icon + light/dark wordmark (linked to
bongbetic.com) next to FENRIS — no more lonely "F" placeholder.
- Footer gets the little b_glyph monogram for that extra polish.
- Wires up real favicons (ico + 16/32) and apple-touch-icon + webmanifest
so the tab and bookmarks actually look like Bongbetic.
- Vendors the missing brand bits: favicon set, apple icon, 192px icons,
hi-res wordmark and contact sheet.
- Rewrite README in a playful, plain-English voice and add Bongbetic
wordmarks/glyph/icons so Gitea renders the brand nicely (light/dark).
- Vendor assets/bongbetic-brand/* from /mnt/Toto/Documents/bongbetic/Logo.
- Remove plan-dash-changes.md from tracking (internal only) and gitignore it.