train-guard supervises one long-running job on a laptop. It can pause the
process tree when AC power is removed, lower its scheduling priority when the
battery is warm, pause at a configured temperature, and continue the same live
processes after power returns.
The operating system remains responsible for CPU and SoC protection. This tool only applies a job-level battery and power policy.
train-guard run --name train -- python train.py --epochs 200
train-guard attach --match "python train.py"
train-guard status
train-guard stop trainThis repository is a public release snapshot. The package is MIT licensed.
Pause and resume use host process APIs through psutil. On POSIX systems this
is equivalent to SIGSTOP and SIGCONT. The process stays in memory, and
multiprocessing children are included.
Gentle mode is a best-effort scheduling request:
- macOS applies
taskpolicy -b. The kernel still chooses the cores, so this does not pin a job to efficiency cores. - Linux narrows CPU affinity and requests idle I/O priority. Full mode restores the original affinity.
- Windows switches the process tree to
IDLE_PRIORITY_CLASSand restores normal priority in full mode.
Charging tools such as AlDente or batt manage charge limits. System tools such
as TLP and auto-cpufreq manage broader machine policy. train-guard only
controls the named job.
The package is not on PyPI. Install it from a checkout:
git clone https://github.com/fus3r/train-guard.git
cd train-guard
python -m pip install -e .You can also run python trainguard/cli.py status without installing the
command. A standalone macOS shell implementation is under macos/.
| Platform | Pause and resume | Gentle mode | Battery temperature | Login restart |
|---|---|---|---|---|
| macOS | process suspend and resume | background scheduling hint | ioreg, no sudo |
launchd starts a new process |
| Linux | process suspend and resume | reduced CPU affinity, idle I/O | psutil sensors or sysfs | systemd user service starts a new process |
| Windows | process suspend and resume | idle priority class | usually unavailable | scheduled task starts a new process |
CI runs the policy, CLI, persistence, sensor and child-process tests on macOS, Linux and Windows with Python 3.9 and 3.13. Battery temperature still depends on the hardware and driver. When no pack sensor is available, thermal rules are skipped while power-source and charge rules remain active.
# Start a command. Its output is written to ~/.train-guard/logs/<name>.log.
train-guard run --name bigtrain -- python train.py --epochs 200
# Adopt an existing process.
train-guard attach --match "python train.py" --name bigtrain
train-guard attach --pid 12345
train-guard list
train-guard status
train-guard stop bigtrain
train-guard stop bigtrain --kill
train-guard config --initSleep preserves RAM. A suspended job can continue after the machine wakes.
A reboot destroys the process and its in-memory state. With
--restart-on-login, train-guard saves the command line and starts a new
process at the next login:
train-guard run --restart-on-login --name bigtrain -- \
python train.py --resume-from-checkpoint latest
train-guard install-agentThe application must load its own checkpoint if it needs to continue prior work. An attached job can wait for a matching process or define a start command:
train-guard attach --restart-on-login --name dataprep \
--match "build_index.py" --start "bash run_prep.sh"--persist remains as a compatibility alias. It restarts or reattaches after
login; it cannot restore RAM.
The supervisor rereads ~/.train-guard/config.json while it runs.
| Key | Default | Meaning |
|---|---|---|
run_on_battery |
false |
pause when unplugged |
battery_floor_pct |
30 |
pause at or below this charge when battery running is enabled |
ac_band |
full |
scheduling band on AC while cool |
battery_band |
gentle |
scheduling band on battery |
temp_charge_gentle_c |
35 |
gentle mode while warm and charging below the cutoff |
temp_gentle_c |
38 |
gentle mode on AC at or above this pack temperature |
temp_pause_c |
42 |
pause at or above this pack temperature |
temp_resume_c |
36 |
leave a thermal pause at or below this pack temperature |
charge_cool_until_pct |
80 |
charge cutoff for the warm-charging rule |
The default pack thresholds are 35, 38 and 42 degrees Celsius, with resume at 36. They are conservative choices for this tool, not manufacturer safety limits. Apple's published 10 to 35 degree range is an ambient operating range, not a battery pack range.
Version 0.1 keys temp_ecore_c and temp_charge_ecore_c still load for
compatibility. New configurations use gentle because no supported API
guarantees a particular core class.
Every poll seconds, the supervisor reads power, charge and available
temperature sensors. It selects full, gentle or stop for the process tree.
Thermal pause has hysteresis: with the defaults, a job paused at 42 degrees
stays paused until the pack reaches 36.
Closing the lid needs no special path because the supervisor and worker sleep with the laptop. Login persistence creates a new process after reboot.
python -m pip install -e '.[test]'
python -m pytest
bash -n macos/train-guard.shThe GitHub Actions matrix runs on ubuntu-latest, macos-latest and
windows-latest.
MIT, 2026.