testsAndMisc/linux_configuration/scripts/digital_wellbeing/README_MIDNIGHT_SHUTDOWN_LLM.md
2026-02-06 21:43:26 +01:00

10 KiB

Midnight Shutdown System - LLM Reference Guide

For AI assistants: This document explains the automatic shutdown system so you can make correct modifications.

System Purpose

Automatically shut down the PC during configured time windows to enforce healthy sleep schedules:

  • Monday-Wednesday: Shutdown at 24:00 (midnight)
  • Thursday-Sunday: Shutdown at 24:00 (midnight)
  • Morning: Safe time starts at 00:00 (effectively no morning block)

The times above are defaults; actual values in /etc/shutdown-schedule.conf.

Architecture Overview

┌─────────────────────────────────────────────────────────────────────┐
│                    SHUTDOWN SYSTEM LAYERS                           │
├─────────────────────────────────────────────────────────────────────┤
│                                                                     │
│  Layer 1: Systemd Timer                                             │
│  ─────────────────────                                              │
│  day-specific-shutdown.timer fires every minute                     │
│  day-specific-shutdown.service runs the check script                │
│                                                                     │
│  Layer 2: Check Script                                              │
│  ────────────────────                                               │
│  /usr/local/bin/day-specific-shutdown-check.sh                      │
│  Reads config, checks current time, initiates shutdown if in window │
│                                                                     │
│  Layer 3: Config Protection                                         │
│  ────────────────────────                                           │
│  /etc/shutdown-schedule.conf has chattr +i                          │
│  Canonical copy at /usr/local/share/locked-shutdown-schedule.conf   │
│  Path watcher auto-restores if tampered                             │
│                                                                     │
│  Layer 4: Timer Monitor                                             │
│  ─────────────────────                                              │
│  shutdown-timer-monitor.service watches timer status                │
│  Re-enables timer if user tries to disable it                       │
│                                                                     │
│  Layer 5: Script Protection                                         │
│  ────────────────────────                                           │
│  Setup script blocks making schedule MORE LENIENT                   │
│  Can only make it STRICTER without the unlock script                │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

File Locations

File Purpose Protection
/etc/shutdown-schedule.conf Runtime config chattr +i, path watcher
/usr/local/share/locked-shutdown-schedule.conf Canonical copy chattr +i
/usr/local/bin/day-specific-shutdown-check.sh Shutdown logic None
/usr/local/bin/day-specific-shutdown-manager.sh Status/management None
/usr/local/bin/shutdown-timer-monitor.sh Timer re-enabler None
/usr/local/sbin/enforce-shutdown-schedule.sh Config restoration None
/usr/local/sbin/unlock-shutdown-schedule Delayed config edit None
/etc/systemd/system/day-specific-shutdown.timer Timer unit systemd
/etc/systemd/system/day-specific-shutdown.service Service unit systemd
/etc/systemd/system/shutdown-schedule-guard.path Config watcher systemd
/etc/systemd/system/shutdown-schedule-guard.service Enforcement systemd
/etc/systemd/system/shutdown-timer-monitor.service Timer guardian systemd
/var/log/shutdown-schedule-guard.log Tampering log None

Config File Format

# /etc/shutdown-schedule.conf

# Shutdown hour for Monday-Wednesday (24-hour format)
MON_WED_HOUR=21

# Shutdown hour for Thursday-Sunday (24-hour format)
THU_SUN_HOUR=22

# Morning end hour (shutdown window ends at this hour)
MORNING_END_HOUR=5

Interpretation:

  • Mon-Wed: Shutdown if current hour >= 21 OR current hour < 5
  • Thu-Sun: Shutdown if current hour >= 22 OR current hour < 5

Schedule Protection Logic

The setup script (setup_midnight_shutdown.sh) has constants at the top:

SCHEDULE_MON_WED_HOUR=24
SCHEDULE_THU_SUN_HOUR=24
SCHEDULE_MORNING_END_HOUR=0

When re-run, it compares these to the canonical config:

Change Type Action
Making shutdown EARLIER Allowed without unlock
Making shutdown LATER Blocked, requires unlock
Making morning end EARLIER Always blocked
Making morning end LATER Allowed (extends shutdown window)

Example blocked attempt:

╔══════════════════════════════════════════════════════════════════╗
║     ❌ SCHEDULE MODIFICATION BLOCKED - CHEATING DETECTED! ❌     ║
╚══════════════════════════════════════════════════════════════════╝

You modified the script to make the shutdown schedule MORE LENIENT:
  • Mon-Wed shutdown: 21:00 → 23:00 (later)

Nice try! But this is exactly the kind of late-night bargaining
that this protection is designed to prevent. 😉

Unlock Script Behavior

/usr/local/sbin/unlock-shutdown-schedule:

  1. Stops shutdown-schedule-guard.path
  2. Removes chattr from both config files
  3. Opens editor on temp copy
  4. Checks what changed:
    • Stricter (earlier): No delay, applies immediately
    • Lenient (later): 45-second countdown, then applies
    • Lower morning end: ALWAYS BLOCKED (cannot shorten window)
  5. Updates both config and canonical
  6. Re-applies chattr +i
  7. Restarts path watcher

Integration Points

i3blocks Countdown

i3blocks/shutdown_countdown.sh reads the config to show time remaining:

source /etc/shutdown-schedule.conf
# Calculates and displays "Shutdown in X:XX"

Screen Locker

screen_lock.py can adjust shutdown time:

  • Sick day: Moves shutdown 1.5 hours EARLIER (penalty)
  • Workout completed: Moves shutdown 1.5 hours LATER (reward)

Uses adjust_shutdown_schedule.sh helper script.

Systemd Units

Timer (fires every minute)

[Timer]
OnCalendar=*:*:00
Persistent=false
AccuracySec=1s

Check Service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/day-specific-shutdown-check.sh

Path Watcher

[Path]
PathChanged=/etc/shutdown-schedule.conf
Unit=shutdown-schedule-guard.service

Check Script Logic

# Pseudocode for day-specific-shutdown-check.sh

source /etc/shutdown-schedule.conf
day=$(date +%u)  # 1=Monday, 7=Sunday
hour=$(date +%H)

if [[ $day -le 3 ]]; then
  shutdown_hour=$MON_WED_HOUR
else
  shutdown_hour=$THU_SUN_HOUR
fi

# Check if in shutdown window
if [[ $hour -ge $shutdown_hour ]] || [[ $hour -lt $MORNING_END_HOUR ]]; then
  systemctl poweroff
fi

Common Tasks

Check Current Status

/usr/local/bin/day-specific-shutdown-manager.sh status
# Or run setup script with 'status' argument

Make Schedule Stricter

Edit the constants in setup_midnight_shutdown.sh:

SCHEDULE_MON_WED_HOUR=20  # Changed from 21 to 20 (earlier)

Then re-run:

sudo ./setup_midnight_shutdown.sh

Make Schedule More Lenient (Requires Unlock)

sudo /usr/local/sbin/unlock-shutdown-schedule
# Wait for delay, edit config, save

Disable Timer (Will Be Re-Enabled!)

sudo systemctl disable --now day-specific-shutdown.timer
# Monitor service will re-enable it automatically

Check Protection Status

lsattr /etc/shutdown-schedule.conf
# Should show: ----i--------e--

systemctl status shutdown-schedule-guard.path
systemctl status shutdown-timer-monitor.service

KNOWN VULNERABILITIES

  1. Information Disclosure: Error messages tell user exactly how to bypass
  2. Unlock Script Discoverable: Path mentioned in error messages
  3. Timer Monitor Killable: User can stop the monitor then the timer
  4. Check Script Unprotected: /usr/local/bin/day-specific-shutdown-check.sh can be edited

TODO:

  • Remove helpful bypass instructions from error messages
  • Rename unlock script to obscure name
  • Protect check script with integrity verification

Troubleshooting

Timer not firing

systemctl status day-specific-shutdown.timer
systemctl list-timers | grep shutdown

Config not being enforced

# Check path watcher
systemctl status shutdown-schedule-guard.path

# Manually trigger enforcement
sudo /usr/local/sbin/enforce-shutdown-schedule.sh

Wrong time shown in i3blocks

# Verify config
cat /etc/shutdown-schedule.conf

# Check i3blocks config
cat ~/.config/i3blocks/config | grep shutdown

DO NOT

  1. Edit setup script constants to make schedule later (will be blocked)
  2. Delete canonical config (breaks restoration)
  3. Stop shutdown-timer-monitor.service (timer will be re-enabled anyway)
  4. Modify check script to skip shutdown (defeats purpose)
  5. Lower MORNING_END_HOUR (always blocked, shortens shutdown window)