Go to file
2026-10-19 12:44:33 +02:00
.github/workflows deps: bump node 24.22.0, ruff 0.17.1, pre-commit 4.7.0, web deps (freshness gate) 2026-10-16 15:24:36 +02:00
docs/explanations feat(enforcer): raise manual pick cap from 2 to 3 concurrent games 2026-07-23 18:05:29 +02:00
pacman-hooks Add a daily gaming-time budget with a binary-level cutoff 2026-08-04 20:00:08 +02:00
prompts Re-point paths for the ~ reorganisation (home-tidy) 2026-09-11 19:55:43 +02:00
scripts web control UI: all 24 commands in React, ctl.sock daemon, jobs, library browser; earned_time 0.7.0 2026-10-10 16:07:42 +02:00
steam_backlog_enforcer playtime: shadow leisure billing (C4); /proc scan from leisure_watch 2026-10-19 12:37:01 +02:00
web web deps: @tanstack/react-query 5.104.4, @tanstack/react-router 1.170.45 2026-10-19 12:44:33 +02:00
.gitignore Add CI-mirror pre-push gate + requirements-sync check 2026-07-11 17:47:14 +02:00
.mcp.json Add MCP server exposing the enforcer to Claude Code 2026-07-10 21:05:17 +02:00
.pre-commit-config.yaml playtime: shadow leisure billing (C4); /proc scan from leisure_watch 2026-10-19 12:37:01 +02:00
AGENTS.md repo contract: CLAUDE.md commands, test_changed, CI gate 2026-10-04 17:18:00 +02:00
CLAUDE.md Adopt the four markdown namespaces and gate them 2026-08-24 15:54:34 +02:00
DOCS-ctl-socket.md playtime: drop the Fri-Mon carry-over; log budget on change only 2026-10-18 21:37:29 +02:00
DOCS-web-control-api.md serve runs unconfigured (fresh installs could not reach web Setup); web control UI finished 2026-10-10 19:22:17 +02:00
install.sh web control UI: all 24 commands in React, ctl.sock daemon, jobs, library browser; earned_time 0.7.0 2026-10-10 16:07:42 +02:00
LICENSE chore: add MIT LICENSE 2026-10-11 18:12:51 +02:00
pyproject.toml playtime: shadow leisure billing (C4); /proc scan from leisure_watch 2026-10-19 12:37:01 +02:00
README.md Timed store window that survives hosts reinstalls; whitelist exceptions stay visible 2026-10-03 13:43:32 +02:00
requirements.txt playtime: shadow leisure billing (C4); /proc scan from leisure_watch 2026-10-19 12:37:01 +02:00
run.sh web control UI: all 24 commands in React, ctl.sock daemon, jobs, library browser; earned_time 0.7.0 2026-10-10 16:07:42 +02:00
steam-backlog-enforcer-web.service Stop the web UI serving numbers the enforcer is not applying 2026-08-29 23:39:40 +02:00
steam-backlog-enforcer.desktop web control UI: all 24 commands in React, ctl.sock daemon, jobs, library browser; earned_time 0.7.0 2026-10-10 16:07:42 +02:00
steam-backlog-enforcer.service web control UI: all 24 commands in React, ctl.sock daemon, jobs, library browser; earned_time 0.7.0 2026-10-10 16:07:42 +02:00
TODO-file-length-250.md Re-point paths for the ~ reorganisation (home-tidy) 2026-09-11 19:55:43 +02:00

Steam Backlog Enforcer

Forces you to play one Steam game at a time: earn at least one new achievement in the assigned game before moving on to the next.

Requiring 100% completion kept you locked onto one game for weeks, which proved ineffective. A game released after one new achievement stays in the backlog (it is not counted as finished) and comes round again later.

Features

  • Achievement tracking: Picks the least-recently-assigned game next, then the shortest HLTB completionist time; a released game sits out a 7-day cooldown
  • Store blocking: Blocks store.steampowered.com via /etc/hosts
  • Game uninstalling: Removes all installed games except the assigned one
  • Process enforcement: Kills unauthorized game processes
  • Tampering detection: Detects achievement unlocks on non-assigned games
  • HLTB integration: Estimates completion time with persistent cache

Setup

python -m python_pkg.steam_backlog_enforcer.main setup

Commands

Command Description
scan Scan library, fetch HLTB data, assign game
check Check assigned game for a new achievement
status Show current assignment and blocking
list List incomplete games from snapshot
skip Skip the currently assigned game
enforce Run enforcer (block, uninstall, kill)
unblock [minutes] Unblock the store for a window (default 15, max 30); the daemon keeps it open and re-blocks after
buy-dlc Same 15-minute store window, to buy a game or DLC
reset Reset all state
installed List currently installed Steam games
uninstall Interactively uninstall non-assigned games
setup First-time configuration

Enforce mode

sudo python -m python_pkg.steam_backlog_enforcer.main enforce

This will:

  1. Block Steam store in /etc/hosts
  2. Uninstall all games except the assigned one
  3. Continuously kill any unauthorized game processes

Game Uninstall

Directly removes appmanifest files and game directories from ~/.local/share/Steam/steamapps/. Preserves Proton versions and Steam Linux Runtime.

python -m python_pkg.steam_backlog_enforcer.main uninstall

MCP server (Claude Code integration)

The enforcer exposes an MCP server (steam_backlog_enforcer._mcp) so Claude Code and its subagents can query the backlog and drive it through typed tools.

  • Read tools: get_dataset, get_status, get_stats, list_backlog.
  • Gated write tools: pick_manual, block_gaming — each defaults to a dry-run preview; pass confirm=true to actually apply. These write tools must never be added to a permission allowlist (a subagent could otherwise bypass the human confirmation).

The mcp SDK is an optional dependency (pip install -e '.[mcp]'), kept out of the CLI/systemd system-python path. One-time setup of the dedicated venv that Claude Code spawns:

./scripts/setup_mcp.sh

Registration lives in the checked-in .mcp.json (project scope). Restart Claude Code in this repo and approve the project MCP-server prompt for it to load. Verify with claude mcp list.