Go to file
Krzysztof kuhy Rudnicki 401031602e Always allow games with zero achievements
Owned games Steam confirms have no achievements can never be assigned or
completed, so the enforcer no longer uninstalls, hides or kills them as
unauthorized. The gaming-time budget kill still applies to them.

Fail-closed: unknown status (no cache, other account, unreadable config
or snapshot, request error) keeps a game enforced. The set comes from
no_achievements_cache.json minus snapshot.json, so a game that gains
achievements is enforced again after the next scan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWWAkVShjD2Bo6hM88B
2026-11-01 22:00:35 +01:00
.github/workflows pick keeps already-picked games; fast install reports progress 2026-10-23 20:14:12 +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 Always allow games with zero achievements 2026-11-01 22:00:35 +01:00
web web deps: @tanstack/react-router 1.170.46; sync pnpm-lock.yaml 2026-10-24 08:39:45 +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 LeetCode hour needs the day paid in full (earned_time 0.18.0); gate_off read live from leetcode-guard 2026-10-24 13:26:28 +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 fast install: never report a failed run as success; queue the manifest first 2026-10-24 08:36:57 +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 LeetCode hour needs the day paid in full (earned_time 0.18.0); gate_off read live from leetcode-guard 2026-10-24 13:26:28 +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 LeetCode hour needs the day paid in full (earned_time 0.18.0); gate_off read live from leetcode-guard 2026-10-24 13:26:28 +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-astro-migration.md Note Astro migration happens last 2026-11-01 19:04:10 +01: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.