testsAndMisc/linux_configuration/docs/SECURITY_HARDENING_ANALYSIS.md
Krzysztof kuhy Rudnicki 42a66a1419 refactor(linux_configuration/scripts): split all scripts into single_use/ and periodic_background/
- Move all linux_configuration scripts into two semantic categories:
  - single_use/: scripts run once manually (fresh install, fixes, setup)
  - periodic_background/: scripts run by systemd timers or daemons
- Preserve existing subdirectory structure within each category
- Fix lib/common.sh source paths for new directory depths
- Fix CONFIG_DIR depth in setup_periodic_system.sh and check_and_enable_services.sh
- Update all references in tests, fresh-install/main.sh, nix modules, and docs
- Fix check_polling_antipatterns.sh false positives (||, regex |, case patterns, jq strings)
- Fix pre-existing mypy exclusion path and type annotations for moved tools/ directory
- Rewrite check_polling_antipatterns.sh using awk (no bash regex loops); add require_serial: true
2026-05-15 00:32:35 +02:00

24 KiB

Security Hardening Analysis & Implementation Prompt

Executive Summary

This document analyzes six digital wellbeing/security scripts and provides a detailed implementation prompt for hardening them against tampering. The analysis is based on thorough code review of the entire codebase.


Part 1: Current State Analysis

1. /etc/hosts Protection System

Files involved:

Current Protection Layers:

  1. Immutable attribute (chattr +i)
  2. Canonical copy at /usr/local/share/locked-hosts
  3. Path watcher (hosts-guard.path) auto-restores on modification
  4. Read-only bind mount (hosts-bind-mount.service)
  5. Custom entries protection (blocks removal of blocked domains)
  6. Shell history suppression for unlock-hosts command

CRITICAL VULNERABILITY IDENTIFIED:

  • NO protection for /etc/nsswitch.conf - A user can simply edit nsswitch.conf and remove files from the hosts: line, completely bypassing ALL /etc/hosts protections without touching the hosts file itself!

Example bypass:

# Original: hosts: mymachines resolve [!UNAVAIL=return] files myhostname dns
# Tampered: hosts: mymachines resolve [!UNAVAIL=return] myhostname dns
# Result: /etc/hosts is completely ignored by the system

2. Midnight Shutdown System

Files involved:

Current Protection Layers:

  1. Immutable attribute on /etc/shutdown-schedule.conf
  2. Canonical copy at /usr/local/share/locked-shutdown-schedule.conf
  3. Path watcher restores config if tampered
  4. Schedule protection blocks making schedule more lenient
  5. Unlock script with psychological delay

VULNERABILITIES IDENTIFIED:

  • The unlock script explicitly tells users how to bypass: "sudo /usr/local/sbin/unlock-shutdown-schedule"
  • The schedule change logic is communicated in the error message
  • No protection against stopping/disabling the timer services
  • No protection against modifying the check script at /usr/local/bin/day-specific-shutdown-check.sh

3. Screen Locker (Python - External Repo)

File: /home/kuhy/testsAndMisc/python_pkg/screen_locker/screen_lock.py

Current Workout Types:

  1. Running - distance, time, pace validation
  2. Strength - exercises, sets, reps, weights, total calculation
  3. Table Tennis - duration, sets, points won/lost

VULNERABILITIES IDENTIFIED:

  • Running option too easy to fake - just enter plausible numbers
  • Table Tennis lacks real verification - no mathematical cross-check
  • Users can close the window via keyboard shortcuts (Alt+F4, etc.)
  • The unlock mechanism is too simple once you know the forms
  • Shutdown time adjustment is a REWARD for working out (can be exploited)

4. Pacman Wrapper

Files involved:

Current Protection:

  1. Policy file integrity verification (SHA256)
  2. Blocked keywords list
  3. Greylist with challenge
  4. VirtualBox hardcoded check (cannot bypass via policy files)
  5. Steam weekend-only restriction

VULNERABILITIES IDENTIFIED:

  • Google Chrome not blocked - google-chrome and google-chrome-stable missing from blocked list
  • No automatic LeechBlock installation when browsers are detected
  • User can download .deb/.tar.gz and install manually

5. Block Compulsive Opening

File: scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh (507 lines)

Current Behavior:

  • Records first open per hour in state file
  • Blocks subsequent launches within same hour
  • Shows notification when blocked

CRITICAL VULNERABILITY:

  • App stays running indefinitely - User can:
    1. Open app once per hour (allowed)
    2. Minimize/hide the window
    3. Keep it running forever in background
    4. Compulsive checking still happens, just via Alt+Tab instead of launcher

6. YouTube Music Wrapper

File: scripts/periodic_background/digital_wellbeing/youtube-music-wrapper.sh

Current Behavior:

  • Checks if focus apps (VSCode, games, etc.) are running
  • Blocks YouTube Music launch if focus app detected

REQUESTED ENHANCEMENT:

  • When Steam is open → Block ALL browsers, close any open browsers
  • When browsers open → Block Steam, close Steam if running
  • This creates mutual exclusion between gaming and browsing

Part 2: Language Considerations

Shell (Bash) Limitations

Pros:

  • Native to the system, no dependencies
  • Direct access to systemd, chattr, filesystem
  • Fast for simple operations

Cons:

  • No persistent daemon capability (need systemd for that)
  • Race conditions in file operations
  • Complex state management is fragile
  • No proper event loop for window monitoring
  • Cannot easily monitor process list in real-time

Python Advantages for Certain Tasks

Where Python would be better:

  1. Process monitoring daemon - Watch for Steam/browsers in real-time with proper event loop
  2. Window management - Using python-xlib for proper X11 interaction
  3. Complex state machines - Like the screen locker
  4. Cross-repo integration - The screen_lock.py already shows good patterns

Recommendation

Component Keep Bash Move to Python Reason
hosts guard Simple file ops, systemd integration
shutdown schedule Systemd timers, config files
screen locker Already Complex UI, state machine
pacman wrapper Must intercept pacman
compulsive block Needs daemon for auto-close
music wrapper Needs real-time process monitoring

New Python Daemon Needed: A single "digital wellbeing daemon" that:

  1. Monitors running processes
  2. Auto-closes apps after timeout
  3. Enforces Steam/browser mutual exclusion
  4. Can be controlled via DBus

Part 3: Implementation Prompt

Use this prompt in a new conversation to implement the changes:


IMPLEMENTATION PROMPT

I need to implement comprehensive security hardening for a Linux digital wellbeing system.
The codebase is at ~/linux-configuration/ with these components needing changes:

## 1. HOSTS PROTECTION - nsswitch.conf Guard

Location: hosts/guard/

Create a new protection layer for /etc/nsswitch.conf that:
- Monitors nsswitch.conf for changes (systemd path watcher)
- Ensures the "hosts:" line ALWAYS contains "files" before "dns"
- Creates canonical copy at /usr/local/share/locked-nsswitch.conf
- Enforces with chattr +i
- Add to setup_hosts_guard.sh installer
- Must restore automatically if tampered

The nsswitch.conf protection is CRITICAL because removing "files" from the
hosts line completely bypasses /etc/hosts without touching it.

## 2. MIDNIGHT SHUTDOWN - Silent Denial

Location: scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh

Changes needed:
- Remove ALL helpful messages about how to bypass (unlock-shutdown-schedule path)
- When user tries to make schedule more lenient:
  - Simply say "Operation not permitted" with NO explanation
  - Do NOT mention the unlock script
  - Do NOT explain what's being blocked
  - Silently restore canonical values
- The unlock script should still exist but be undiscoverable
- Consider renaming unlock script to an obscure name
- Remove the unlock script path from any logs

## 3. SCREEN LOCKER - External Repo

Location: ~/testsAndMisc/python_pkg/screen_locker/screen_lock.py

Changes needed:
- REMOVE the "Running" workout option entirely (too easy to fake)
- For "Table Tennis":
  - Require minimum 15 sets played
  - Add verification: total_points = points_won + points_lost
  - Require that total_points >= sets_played * 11 (minimum points per set)
  - Add random math verification question about the scores
  - Increase submit delay to 60 seconds
- For "Strength":
  - Already has good verification, keep as-is
- Add input focus grabbing to prevent Alt+Tab escape
- Disable window close keyboard shortcuts

## 4. PACMAN WRAPPER - Chrome Block + LeechBlock Auto-Install

Location: scripts/periodic_background/digital_wellbeing/pacman/

Changes needed to pacman_blocked_keywords.txt:
- Add: google-chrome
- Add: google-chrome-stable
- Add: chromium
- Add: ungoogled-chromium

New behavior in pacman_wrapper.sh:
- After ANY browser is detected installed (via pacman -Qq check):
  - Automatically run install_leechblock.sh if it exists
  - LeechBlock installer should:
    - Detect browser type
    - Install extension with pre-configured blocking rules
    - Use firefox-addon-install method or chrome native messaging
- If LeechBlock installation fails, BLOCK the browser binary (wrap it)

## 5. BLOCK COMPULSIVE OPENING - Auto-Close Timer

Location: scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh

New behavior:
- After app is allowed to open, start a background timer
- After 10 minutes, forcefully close the app (pkill)
- Show warning notification at 8 minutes ("Closing in 2 minutes")
- The wrapper should spawn a detached monitoring process
- State tracking: record PID and launch time
- Check for zombie PIDs and clean up state

Implementation approach:
```bash
# After exec line in wrapper_main, instead of direct exec:
launch_with_timer() {
  local app="$1"
  local timeout_minutes=10
  local real_binary="$2"
  shift 2

  # Launch app in background
  "$real_binary" "$@" &
  local app_pid=$!

  # Record state
  echo "$app_pid $(date +%s)" > "$STATE_DIR/${app}.running"

  # Spawn killer daemon (detached)
  (
    sleep $((timeout_minutes * 60))
    if kill -0 $app_pid 2>/dev/null; then
      notify "$app" "Session timeout - closing now" critical
      kill $app_pid 2>/dev/null
      sleep 2
      kill -9 $app_pid 2>/dev/null || true
    fi
    rm -f "$STATE_DIR/${app}.running"
  ) &
  disown

  # Wait for app to exit
  wait $app_pid 2>/dev/null || true
}

6. YOUTUBE MUSIC → STEAM/BROWSER MUTUAL EXCLUSION

This requires a more sophisticated approach. Create a new Python daemon.

Location: scripts/periodic_background/digital_wellbeing/focus_mode_daemon.py (new file)

Behavior:

  • Run as a systemd user service
  • Monitor running processes continuously
  • When Steam (steamapp* or steam game processes) detected:
    • Kill any running browsers (firefox, chrome, brave, etc.)
    • Block browser launches (via wrapper modification or DBus signal)
    • Show notification: "Gaming mode active - browsers disabled"
  • When any browser detected:
    • Kill Steam processes
    • Block Steam launches
    • Show notification: "Browsing mode active - Steam disabled"
  • Mutual exclusion: whichever started first "wins"
  • The youtube-music-wrapper.sh should also check for this daemon's signals

ADDITIONAL REQUIREMENTS

  1. All changes must be idempotent (can re-run safely)
  2. All protection mechanisms should fail-closed (if service dies, restrictions remain)
  3. Log all tampering attempts to /var/log/digital-wellbeing-guard.log
  4. Create a single test script that verifies all protections work
  5. Update the .github/copilot-instructions.md with the new components

FILES TO CREATE/MODIFY

New files:

  • hosts/guard/nsswitch-guard.path
  • hosts/guard/nsswitch-guard.service
  • hosts/guard/enforce-nsswitch.sh
  • scripts/periodic_background/digital_wellbeing/focus_mode_daemon.py
  • scripts/periodic_background/digital_wellbeing/install_focus_mode_daemon.sh
  • tests/test_security_hardening.sh

Modified files:

  • hosts/guard/setup_hosts_guard.sh (add nsswitch protection)
  • scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh (remove helpful messages)
  • scripts/periodic_background/digital_wellbeing/pacman/pacman_blocked_keywords.txt (add chrome)
  • scripts/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh (leechblock auto-install)
  • scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh (auto-close timer)
  • scripts/periodic_background/digital_wellbeing/youtube-music-wrapper.sh (daemon integration)

External repo (separate changes):

  • ~/testsAndMisc/python_pkg/screen_locker/screen_lock.py (remove running, harden table tennis)

---

## Part 4: Agent Personas

### Agent: Hosts Guard Expert

You are an expert on the linux-configuration hosts guard system. You understand:

FILES YOU KNOW:

  • hosts/install.sh - Downloads StevenBlack hosts, adds custom entries, protects with chattr
  • hosts/guard/setup_hosts_guard.sh - Installs all guard layers (path watcher, bind mount, unlock script)
  • hosts/guard/enforce-hosts.sh - Called when tampering detected, restores from canonical
  • hosts/guard/psychological/unlock-hosts.sh - 45-second delay, logs reason, opens editor
  • hosts/guard/hosts-guard.path/.service - Systemd path watcher
  • hosts/guard/hosts-bind-mount.service - Read-only bind mount
  • hosts/guard/pacman-hooks/*.sh - Pre/post transaction hooks for pacman

KEY CONCEPTS:

  • Canonical copy at /usr/local/share/locked-hosts
  • Custom entries state at /etc/hosts.custom-entries.state
  • Multi-layer defense: chattr + path watcher + bind mount
  • Shell history suppression for unlock commands

COMMON TASKS:

  • Adding new blocked domains: Edit hosts/install.sh heredoc section
  • Temporarily allowing edits: sudo /usr/local/sbin/unlock-hosts
  • Checking status: lsattr /etc/hosts, systemctl status hosts-guard.path

GOTCHAS:

  • Must run hosts/install.sh BEFORE setup_hosts_guard.sh
  • Removing custom entries is blocked by protection mechanism
  • nsswitch.conf bypass is currently unprotected (needs fix)

### Agent: Shutdown Schedule Expert

You are an expert on the midnight shutdown system. You understand:

FILES YOU KNOW:

  • scripts/periodic_background/digital_wellbeing/setup_midnight_shutdown.sh - Main installer (1300+ lines)
  • /etc/shutdown-schedule.conf - Runtime config (MON_WED_HOUR, THU_SUN_HOUR, MORNING_END_HOUR)
  • /usr/local/share/locked-shutdown-schedule.conf - Canonical protected copy
  • /usr/local/bin/day-specific-shutdown-check.sh - Checks if in shutdown window
  • /usr/local/bin/day-specific-shutdown-manager.sh - Status/management
  • /etc/systemd/system/day-specific-shutdown.timer/.service - Systemd timer
  • /etc/systemd/system/shutdown-schedule-guard.path/.service - Config protection

KEY CONCEPTS:

  • Day-specific windows: Mon-Wed vs Thu-Sun have different hours
  • Making schedule STRICTER (earlier) = allowed without delay
  • Making schedule MORE LENIENT (later) = blocked or requires unlock
  • MORNING_END_HOUR cannot be lowered (would shorten window)
  • Monitor service re-enables timer if user disables it

PROTECTION LAYERS:

  1. Script checks canonical config, blocks lenient changes
  2. Config file has chattr +i
  3. Path watcher restores if file modified
  4. Canonical copy takes precedence

INTEGRATION:

  • i3blocks shutdown_countdown.sh reads the config
  • screen_lock.py can adjust shutdown time (reward/punishment)

### Agent: Pacman Wrapper Expert

You are an expert on the pacman wrapper security system. You understand:

FILES YOU KNOW:

  • scripts/periodic_background/digital_wellbeing/pacman/pacman_wrapper.sh - Main wrapper (823 lines)
  • scripts/periodic_background/digital_wellbeing/pacman/install_pacman_wrapper.sh - Backs up real pacman
  • scripts/periodic_background/digital_wellbeing/pacman/pacman_blocked_keywords.txt - Always blocked
  • scripts/periodic_background/digital_wellbeing/pacman/pacman_whitelist.txt - Exceptions to keywords
  • scripts/periodic_background/digital_wellbeing/pacman/pacman_greylist.txt - Challenge required
  • scripts/periodic_background/digital_wellbeing/pacman/words.txt - Word scramble challenge words
  • /var/lib/pacman-wrapper/policy.sha256 - Integrity checksums

KEY CONCEPTS:

  • Real pacman at /usr/bin/pacman.orig, wrapper symlinked to /usr/bin/pacman
  • Policy integrity verification via SHA256 before ANY operation
  • Three tiers: blocked (always denied), greylist (challenge), whitelist (bypass)
  • VirtualBox check is HARDCODED (cannot bypass via policy files)
  • Steam is weekend-only with word scramble challenge

POLICY ENFORCEMENT:

  1. Load policy lists from text files
  2. Verify integrity hashes match
  3. Check if package matches blocked keywords (unless whitelisted)
  4. Check if greylisted (requires challenge)
  5. After transaction, remove any blocked packages that got installed

HOSTS INTEGRATION:

  • Calls /usr/local/share/hosts-guard/pacman-pre-unlock-hosts.sh before transaction
  • Calls pacman-post-relock-hosts.sh after transaction
  • Enforces VirtualBox hosts sharing if vbox detected

MAINTENANCE INTEGRATION:

  • Auto-runs setup_periodic_system.sh if maintenance services missing

### Agent: Compulsive Opening Blocker Expert

You are an expert on the block_compulsive_opening.sh script. You understand:

FILES YOU KNOW:

  • scripts/periodic_background/digital_wellbeing/block_compulsive_opening.sh - Main script (507 lines)
  • /usr/local/bin/block-compulsive-opening.sh - Installed location
  • ~/.local/state/compulsive-block/*.lastopen - Per-app state files
  • ~/.local/state/compulsive-block/compulsive-block.log - Activity log
  • /etc/pacman.d/hooks/95-compulsive-block-rewrap.hook - Auto-rewrap hook

MANAGED APPS:

  • beeper → /opt/beeper/beepertexts
  • signal-desktop → /usr/lib/signal-desktop/signal-desktop
  • discord → /opt/discord/Discord

KEY CONCEPTS:

  • Wrapper replaces /usr/bin/, original saved as .orig or SYMLINK: marker
  • Hour-based tracking: YYYY-MM-DD-HH format
  • First launch per hour allowed, subsequent launches blocked
  • Pacman hook re-installs wrappers after package updates

WRAPPER FLOW:

  1. wrapper_main() called with app name
  2. Check was_opened_this_hour()
  3. If yes: block_app() + notification + exit 1
  4. If no: record_opening() + exec real binary

LIMITATION (needs fix):

  • Once app is launched, it can run indefinitely
  • User can minimize and keep checking via Alt+Tab
  • Needs auto-close timer functionality

### Agent: Screen Locker Expert

You are an expert on the screen_lock.py workout locker. You understand:

FILE LOCATION: ~/testsAndMisc/python_pkg/screen_locker/screen_lock.py (1261 lines)

PURPOSE:

  • Full-screen lock requiring workout verification to unlock
  • Integrates with shutdown schedule system

WORKOUT TYPES:

  1. Running: distance, time, pace with cross-validation
  2. Strength: exercises, sets, reps, weights with total calculation
  3. Table Tennis: duration, sets, points won/lost
  4. Sick Day: 2-minute wait, shutdown moved 1.5h earlier

KEY FEATURES:

  • 30-second delay before submit button enabled
  • Cross-validation (e.g., pace = time / distance)
  • 15% tolerance on calculated values
  • Demo mode (10s lockout) vs Production mode (30min lockout)
  • JSON workout log stored in same directory

SHUTDOWN INTEGRATION:

  • _adjust_shutdown_time_earlier() - sick day penalty
  • _adjust_shutdown_time_later() - workout reward (+1.5h)
  • Uses adjust_shutdown_schedule.sh helper script
  • Sick day state tracked in sick_day_state.json

SECURITY CONCERNS (needs fix):

  • Running option too easy to fake
  • Table tennis lacks rigorous validation
  • Window can potentially be closed via keyboard

---

## Part 5: LLM README Files

These should be created in the respective directories:

### [hosts/guard/README_FOR_LLM.md](to be created)

```markdown
# Hosts Guard System - LLM Reference

## Purpose
Prevent tampering with /etc/hosts to maintain website blocking.

## Architecture

/etc/hosts (immutable) ←── canonical (/usr/local/share/locked-hosts) ↑ path watcher detects changes ↓ enforce-hosts.sh restores


## Critical Files
| File | Purpose | Protected By |
|------|---------|--------------|
| /etc/hosts | Actual hosts file | chattr +i, bind mount |
| /usr/local/share/locked-hosts | Canonical copy | chattr +i |
| /etc/hosts.custom-entries.state | Tracks blocked domains | chattr +i |

## Commands to Know
```bash
# Check protection status
lsattr /etc/hosts
systemctl status hosts-guard.path hosts-bind-mount.service

# Legitimate edit (with delay)
sudo /usr/local/sbin/unlock-hosts

# Reinstall/repair
sudo ~/linux-configuration/hosts/install.sh
sudo ~/linux-configuration/hosts/guard/setup_hosts_guard.sh

DO NOT

  • Edit /etc/nsswitch.conf (bypasses hosts entirely)
  • Stop hosts-guard.path without understanding consequences
  • Remove entries from install.sh without state file cleanup

### [scripts/periodic_background/digital_wellbeing/pacman/README_FOR_LLM.md](to be created)

```markdown
# Pacman Wrapper - LLM Reference

## Purpose
Intercept pacman to enforce package installation policies.

## Architecture

/usr/bin/pacman (symlink) → pacman_wrapper.sh ↓ /usr/bin/pacman.orig (real)


## Policy Files
| File | Purpose |
|------|---------|
| pacman_blocked_keywords.txt | Substring match = always blocked |
| pacman_whitelist.txt | Exact names that bypass blocking |
| pacman_greylist.txt | Requires challenge to install |
| words.txt | Word scramble challenge source |

## Hardcoded Checks (cannot bypass via files)
- VirtualBox → security challenge + hosts enforcement
- Steam → weekend-only + word scramble

## Integration Points
1. Hosts guard (pre/post hooks)
2. Periodic maintenance (auto-setup if missing)
3. VirtualBox hosts enforcement

## Adding Blocks
```bash
# Edit the blocked keywords file
echo "newpackage" >> pacman_blocked_keywords.txt

# Re-run installer to update checksums
sudo ./install_pacman_wrapper.sh

---

## Part 6: Test Script Template

```bash
#!/bin/bash
# tests/test_security_hardening.sh
# Verify all security mechanisms are working

set -euo pipefail

PASS=0
FAIL=0

test_result() {
    local name="$1"
    local result="$2"
    if [[ $result == "pass" ]]; then
        echo "✅ PASS: $name"
        ((PASS++))
    else
        echo "❌ FAIL: $name"
        ((FAIL++))
    fi
}

# Test 1: /etc/hosts is immutable
if lsattr /etc/hosts 2>/dev/null | grep -q '^....i'; then
    test_result "/etc/hosts is immutable" "pass"
else
    test_result "/etc/hosts is immutable" "fail"
fi

# Test 2: hosts-guard.path is active
if systemctl is-active --quiet hosts-guard.path; then
    test_result "hosts-guard.path is active" "pass"
else
    test_result "hosts-guard.path is active" "fail"
fi

# Test 3: shutdown-schedule.conf is immutable
if lsattr /etc/shutdown-schedule.conf 2>/dev/null | grep -q '^....i'; then
    test_result "/etc/shutdown-schedule.conf is immutable" "pass"
else
    test_result "/etc/shutdown-schedule.conf is immutable" "fail"
fi

# Test 4: pacman wrapper is installed
if [[ -L /usr/bin/pacman ]] && [[ -f /usr/bin/pacman.orig ]]; then
    test_result "pacman wrapper installed" "pass"
else
    test_result "pacman wrapper installed" "fail"
fi

# Test 5: google-chrome is blocked
if grep -qi "google-chrome" ~/linux-configuration/scripts/periodic_background/digital_wellbeing/pacman/pacman_blocked_keywords.txt; then
    test_result "google-chrome in blocked list" "pass"
else
    test_result "google-chrome in blocked list" "fail"
fi

# Summary
echo ""
echo "=========================================="
echo "Results: $PASS passed, $FAIL failed"
echo "=========================================="

exit $FAIL

Conclusion

This analysis identifies critical vulnerabilities and provides a comprehensive implementation prompt. The most urgent issues are:

  1. nsswitch.conf bypass - Completely unprotected, defeats all hosts protections
  2. Information disclosure - Shutdown system tells users how to bypass
  3. App lifetime - Compulsive blockers don't limit session duration
  4. Browser gaps - Chrome not blocked, no LeechBlock auto-install

The implementation prompt above should be used in a focused coding session to address all issues systematically.