@@ -28,7 +28,7 @@ Apotropaios follows a strict layered architecture. Each layer depends only on la
2828┌─────────────────────────────────────────────┐
2929│ apotropaios.sh │ Entry point, CLI parsing
3030├─────────────────────────────────────────────┤
31- │ lib/menu/menu_main.sh │ Interactive menu UI
31+ │ lib/menu/menu_main.sh │ Interactive menu, wizard, expiry monitor
3232│ lib/menu/help_system.sh │ Progressive help (17 pages)
3333├─────────────────────────────────────────────┤
3434│ lib/rules/ lib/backup/ │ Rule engine, backup/restore
@@ -281,9 +281,9 @@ Each backend implements the standard interface. Key per-backend details:
281281
282282** nftables.sh (14 functions):** Compound actions combined in single nft expression (e.g., ` log prefix "..." drop ` ). Supports ` ct state ` , ` limit rate ` . Table family validated via ` validate_table_family() ` . Direct command execution only — no ` nft -f ` file mode (removed as injection vector).
283283
284- ** firewalld.sh (13 functions):** Rich rule builder (` _firewalld_build_rich_rule ` ) with 12 parameters including log clause, compound actions, and rate limits. Auto-selects rich rule vs simple port add.
284+ ** firewalld.sh (13 functions):** Rich rule builder (` _firewalld_build_rich_rule ` ) with 12 parameters including log clause, compound actions, protocol-only rules, and rate limits. Auto-selects rich rule vs simple port add (rich rule forced for port-less rules). Status shows all zones via ` --list-all-zones ` . Reset iterates all zones. Error logging captures actual ` firewall-cmd ` stderr .
285285
286- ** ufw.sh (12 functions):** Compound action extracts terminal for ufw verb, enables logging separately. Extended syntax auto-detection for source/destination rules. Backend config: 9 options including app profile enable/disable, logging level control, default policy management.
286+ ** ufw.sh (12 functions):** Compound action extracts terminal for ufw verb, enables logging separately. Extended syntax auto-detection for source/destination rules; also forced when no port specified (simple path requires a port). Error logging captures actual ` ufw ` stderr . Backend config: 9 options including app profile enable/disable, logging level control, default policy management.
287287
288288** ipset.sh (14 functions):** Set creation/management plus iptables integration rules. Supports hash: ip , hash: net , hash: ip ,port set types.
289289
@@ -323,7 +323,7 @@ Each backend implements the standard interface. Key per-backend details:
323323
324324### lib/backup/{backup,restore,immutable}.sh — 13 functions
325325
326- ** Purpose:** Timestamped compressed archives, automatic restore points, ` chattr +i ` immutable snapshots.
326+ ** Purpose:** Timestamped compressed archives, automatic restore points, ` chattr +i ` immutable snapshots. Verify returns 3 codes: 0 (all pass), 1 (integrity failure), 2 (no snapshots exist). List handles empty state.
327327
328328### lib/install/installer.sh — 7 functions
329329
@@ -333,19 +333,24 @@ Each backend implements the standard interface. Key per-backend details:
333333
334334## Module Reference — Menu and Help (Layer 5)
335335
336- ### lib/menu/menu_main.sh — 25 functions
336+ ### lib/menu/menu_main.sh — 31 functions
337337
338- ** Purpose:** Interactive menu-driven interface with guided wizards.
338+ ** Purpose:** Interactive menu-driven interface with guided wizards, background expiry monitoring, and cancel-safe input handling .
339339
340340Key internal functions:
341- - ` _menu_create_rule() ` — 5-step rule creation wizard with compound action, connection state, log options, rate limit prompts
341+ - ` _wizard_read(var, default) ` — Cancel-aware input helper (nameref). Detects q/quit/cancel/back/b. Used by all 29 wizard prompts across all 5 backends.
342+ - ` _menu_create_rule() ` — 5-step rule creation wizard with compound action, connection state, log options, rate limit prompts. Full cancel support.
342343- ` _menu_remove_rule() ` , ` _menu_activate_rule() ` , ` _menu_deactivate_rule() ` — UUID validation before engine calls
343344- ` _menu_import_rules() ` — File scanner + validation
344345- ` _menu_export_rules() ` — Default path, overwrite protection
345346- ` _menu_list_system_rules() ` — Multi-backend audit
346347- ` _menu_rule_watcher() ` — Color-coded TTL display with extension
348+ - ` _expiry_monitor_loop() ` — Background daemon (30s interval). Auto-deactivates expired rules, writes terminal alerts at 10-minute mark.
349+ - ` _expiry_monitor_start() ` / ` _expiry_monitor_stop() ` — Lifecycle management with double-start guard and cleanup stack registration.
350+ - ` _menu_check_expiry_alerts() ` — Inline expiry warnings on every main menu render.
351+ - ` _firewalld_select_zone(var, label) ` — Reusable zone picker (nameref, no subshell). Dynamic list from ` firewall-cmd --get-zones ` with cancel support.
347352- ` _menu_backend_config() ` — Dispatch to per-backend config menus
348- - ` _menu_backend_config_{iptables,nftables,firewalld,ufw,ipset}() ` — Backend-specific submenus
353+ - ` _menu_backend_config_{iptables,nftables,firewalld,ufw,ipset}() ` — Backend-specific submenus (firewalld: 8 options zone-aware, iptables: 7 options with table selector)
349354
350355### lib/menu/help_system.sh — 23 functions
351356
@@ -374,10 +379,11 @@ Key internal functions:
374379** Flow:**
3753801 . Determine script location (` APOTROPAIOS_BASE_DIR ` )
3763812 . Source all 24 library modules in dependency order
377- 3 . Parse global options (` --backend ` , ` --log-level ` , ` --help ` , ` --version ` )
378- 4 . Check for per-command ` --help ` (bypass initialization)
379- 5 . Call ` _initialize() ` — logging, security, detection, rule index, backup
380- 6 . Dispatch to command handler or interactive menu
382+ 3 . Parse global options (` --backend ` , ` --log-level ` , ` --interactive ` , ` --non-interactive ` , ` --help ` , ` --version ` )
383+ 4 . Validate mutual exclusivity (` --interactive ` vs ` --non-interactive ` , ` --interactive ` vs CLI commands)
384+ 5 . Check for per-command ` --help ` (bypass initialization)
385+ 6 . Call ` _initialize() ` — logging, security, detection, rule index, backup, expiry check
386+ 7 . Dispatch to command handler or interactive menu (with background expiry monitor)
381387
382388** CLI flags added in v1.1.3:** ` --conn-state ` , ` --log-prefix ` , ` --log-level ` , ` --limit ` , ` --limit-burst `
383389
@@ -475,10 +481,10 @@ tests/
475481│ ├── errors.bats (24)
476482│ ├── rule_engine.bats (19)
477483│ └── backup.bats (14)
478- ├── integration/ # Multi-function flow tests (93 tests)
484+ ├── integration/ # Multi-function flow tests (98 tests)
479485│ ├── lifecycle.bats (22)
480486│ ├── import_export.bats (10)
481- │ ├── cli.bats (29 )
487+ │ ├── cli.bats (34 )
482488│ └── help_system.bats (32)
483489├── security/ # CWE-mapped security tests (48 tests)
484490│ └── injection.bats (48)
@@ -487,7 +493,7 @@ tests/
487493 └── invalid_rules.conf
488494```
489495
490- ** Total: 375 tests across 13 files**
496+ ** Total: 380 tests across 13 files**
491497
492498### Critical Test Patterns
493499
0 commit comments