aboutsummaryrefslogtreecommitdiff
path: root/configs/maintenance-thresholds.toml
blob: 161b4c2c588c1833e0fc0027d142b8f85f531464 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
# maintenance-thresholds.toml — every severity value the maintenance console
# and the system-health-check workflow grade against, plus the shipped
# curation defaults. Owned and installed by archsetup (canonical:
# configs/maintenance-thresholds.toml in the archsetup repo; installed to
# ~/.config/archsetup/maintenance-thresholds.toml). Both consumers read the
# installed path, so severity rules can never drift between them.
#
# User curation and overrides live in ~/.config/maint/curation.toml and merge
# over this file (scalars: user wins; [curation.*]: entries − disable + add).
# Never record user marks here — an archsetup update replaces this file.
#
# Seed values migrated 2026-07-07 from the system-health-check workflow's
# hard-won prose rules (the 2026-05-26 /home snapshot lesson, the 10 GB cache
# trigger, the 35/60-day scrub bands) and the maintenance-console design doc.

[storage]
df_warn_pct = 80
df_crit_pct = 90
btrfs_scrub_warn_days = 35
btrfs_scrub_crit_days = 60
btrfs_unalloc_warn_gb = 10          # chunk headroom floor before ENOSPC weirdness
zfs_scrub_warn_days = 35
zfs_scrub_crit_days = 60
zfs_capacity_warn_pct = 80          # ZFS performance degrades past 80
zfs_capacity_crit_pct = 90
zfs_frag_info_pct = 50
smart_wear_warn_pct = 80            # NVMe percentage_used (100 = rated life)
smart_temp_warn_c = 70
fstrim_stale_days = 10              # weekly timer + slack (continuous discard exempts)
hog_roots = ["/home/cjennings", "/var"] # disk top-consumers scan roots (slow-local); depth-1 of /home is just the user dir, so scan inside it
hog_top = 8                         # digest rows kept

[snapshots]
# Sane snapper TIMELINE limits — the 2026-05-26 /home pile-up fix.
timeline_hourly = 6
timeline_daily = 7
timeline_weekly = 2
timeline_monthly = 2
timeline_quarterly = 0
timeline_yearly = 0
single_keep = 2                     # DELETE STALE keeps the newest N singles
zfs_count_warn = 1000               # runaway retention
zfs_space_warn_pct = 20             # snapshot space vs pool capacity

[packages]
cache_warn_gb = 10                  # suggest paccache beyond the weekly keep-3
keyring_warn_days = 60              # stale archlinux-keyring silently breaks updates

[security]
cve_min_warn = "high"               # arch-audit severity floor that warns (the
                                    # constant Unknown/Low tail is background)

[updates]
pending_warn = 50                   # "a lot" — reddens the strip border
cache_stale_hours = 6               # network-tier cache older than this warns
topgrade_warn_days = 14             # topgrade freshness
# The live-update guard (never -Syu the graphics/wayland runtime under a
# live session — the 2026-06-07 mesa+hyprland crash). fnmatch patterns
# against pending package names; a hit arms UPDATE/TOPGRADE instead of
# running ("press again to run anyway — or apply from a TTY").
guard_patterns = [
  "mesa", "mesa-*", "lib32-mesa*",
  "hyprland", "hyprland-*", "aquamarine", "hyprutils", "hyprlang",
  "hyprcursor", "hyprgraphics",
  "*wayland*", "wlroots*",
  "vulkan-radeon", "lib32-vulkan-radeon",   # ratio's GPU driver
  "vulkan-intel", "lib32-vulkan-intel",     # velox's GPU driver
]

[systemd]
# The capability-derived expected set (paccache/reflector always;
# btrfs-scrub@ + snapper timers on btrfs; sanoid + zfs-scrub-weekly@ on ZFS)
# lives in code — this list adds host-agnostic extras on top.
expected_timers_extra = []

[logs]
app_log_warn_days = 7               # log-cleanup cron should hold ~7 days
journal_digest_top = 10             # groups shown in the journal digest
journal_disk_warn_gb = 2            # journald footprint before vacuum suggested
coredump_window_days = 14           # dumps older than this age out of the count

[memory]
used_warn_pct = 90                  # 1 - available/total (reclaimable-aware)
used_crit_pct = 97
oom_window_days = 7                 # kernel-journal OOM lookback

[power]
battery_low_pct = 15                # feeds the diagnostic state (glyph red)
charge_limit_pct = 80               # the SET 80% longevity cap on velox
cpu_temp_warn_c = 90                # k10temp Tctl / coretemp package
gpu_temp_warn_c = 95                # amdgpu edge
battery_health_warn_pct = 80        # charge_full vs design floor
unclean_warn_pct = 25               # unclean-shutdown rate over recent boots
unclean_boot_sample = 10            # boots assessed for the rate

[network]
ntp_offset_warn_ms = 100            # chrony last-offset bound (typical is sub-ms)

[backups]
rsyncshot_daily_crit_hours = 48     # daily backup older than this is a fire
rsyncshot_hourly_warn_hours = 3     # graded only on hosts whose log shows hourly runs

[services]
docker_reclaim_warn_gb = 5
docker_reclaim_warn_pct = 50
# Expected crontab entries (substring match, comment lines ignored). Root
# expectations apply only on backup sources (hosts with a rsyncshot log).
cron_expected_root = ["rsyncshot"]
cron_expected_user = ["log-cleanup"]

[refresh]
# Cadence knobs (seconds unless named otherwise) — spec Decision 8.
live_secs = 3
fast_secs = 30
glyph_scan_mins = 30
net_scan_mins = 60

# --- shipped curation defaults (user layer adds/disables, never edits) ------

[curation.known_noise]
# Journal-noise patterns bind to identifier + message snippet, never a whole
# unit — a muted service's new errors still surface.
entries = [
  { identifier = "bluetoothd", pattern = "HFP" },
  { identifier = "pixman", pattern = "Invalid glyph" },
  { identifier = "xkbcomp", pattern = "Could not resolve keysym" },
]

[curation.expected_listeners]
entries = ["sshd", "mpd", "tailscaled"]

[curation.session_critical]
# Process names KILL must never fire on (the lever renders disabled) —
# systemd, the compositor and its plumbing, the audio stack, the panel
# itself, and sshd (a remote session's lifeline). fnmatch patterns.
entries = [
  "systemd*", "Hyprland", "Xwayland", "waybar",
  "dbus-broker*", "dbus-daemon",
  "pipewire*", "wireplumber",
  "maint*", "sshd",
]

[curation.expected_containers]
entries = ["winvm"]

[curation.pacnew_safe_delete]
# Regenerated files whose .pacnew is safe to drop (reflector-managed / local).
entries = ["/etc/pacman.d/mirrorlist", "/etc/locale.gen"]

[curation.kept_orphans]
# Packages pacman calls orphaned that are deliberate keeps (the rust lesson):
# listed in evidence but never counted or warned on. KEEP/UNMARK levers write
# the user layer; this shipped list stays empty.
entries = []

[curation.qkk_known]
# pacman -Qkk mismatches that are config knowledge, not integrity findings
# (fnmatch patterns). Unverifiable reads and mtime-only mismatches are
# already excluded in code; this covers managed symlinks, regenerated
# caches, and files archsetup itself edits.
entries = [
  "/etc/resolv.conf",                              # resolver-managed symlink
  "/usr/lib/jvm/default",                          # archlinux-java symlinks
  "/usr/lib/jvm/default-runtime",
  "/usr/lib/ghc-*/lib/package.conf.d/package.cache", # regenerated by ghc-pkg
  "/usr/lib/vlc/plugins/plugins.dat",              # regenerated plugin cache
  "/etc/conf.d/pacman-contrib",                    # archsetup sets PACCACHE_ARGS
]