# 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

```bash
# /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:

```bash
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:

```bash
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)

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

### Check Service

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

### Path Watcher

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

## Check Script Logic

```bash
# 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

```bash
/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`:

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

Then re-run:

```bash
sudo ./setup_midnight_shutdown.sh
```

### Make Schedule More Lenient (Requires Unlock)

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

### Disable Timer (Will Be Re-Enabled!)

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

### Check Protection Status

```bash
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

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

### Config not being enforced

```bash
# 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

```bash
# 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)
