steam-backlog-enforcer/README.md
Krzysztof kuhy Rudnicki 87c6f200e3 Research window: keep Steam dir, extend once
kuhy 2026-11-11, multi-day research without re-setup.

W1: once a window was used in a lock, the block's purge spares
~/.local/share/Steam (Librarian's install and local saves) for the
rest of the lock; ~/steam, ~/.steam and the rest still go. The
package stays removed, hosts/iptables are re-applied, and since the
kept install could otherwise be launched without the package, every
Steam game is killed on sight. A record that cannot be read also
keeps the folder (an irreversible delete never rests on unknown
state); the block itself stays fully applied.

W2: the 48 h cap is gone; --until is bounded by the lock's end. An
open window may be extended ONCE, to the lock end at most, never
shortened, never reopened after it ended. The extension is a
separate extended_until field beside until, so a daemon still on
the previous code reads the original window instead of rejecting the
record as corrupt (which would have purged the folder).

Failure modes unchanged: missing/corrupt record = no window, and a
corrupt one refuses a new window or extension.

Checked: 3325 tests at 100% coverage; pylint 10/10 in parts; vmbox:
extension accepted once, refused beyond the lock end, earlier or
equal, second time and non-root; extended end honoured past the
original end; at close the Steam dir and a save survive, ~/steam and
~/.steam go, a game started after close is killed; extension to
exactly the lock end accepted. Not verified on the host.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWWzuCEg1m87jpKyRrw
2026-11-11 16:28:43 +01:00

3.5 KiB

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
total-block-research --until T Root. One window per total block, up to its end, extendable once: Steam and the store open, only Librarian may be played; the daemon re-applies the full block at T and keeps ~/.local/share/Steam
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.