mirror of
https://github.com/kuhyx/steam-backlog-enforcer.git
synced 2026-11-11 14:27:33 +01:00
A manual pick had no escape hatch: once locked in, every command except done/check/status/enforce/setup/serve exited 1 for 14 days or until 100% achievements. A wrong pick meant two weeks stuck with it. Adds a short mistake-correction window: - MANUAL_GRACE_DAYS = 4 — within 4 days, 'abandon-pick <app_id>' backs out of the pick. Outside it the command refuses and exits 1. - The app_id must be passed explicitly and must match the active pick, so an abandon cannot be triggered by muscle memory. - 'abandon-pick' joins _MANUAL_LOCK_EXEMPT_COMMANDS — the pre-dispatch lock check would otherwise block the only way out. It is dropped from the advertised command list once the window closes. - Abandoning clears the lock and the assignment, uninstalls the game, and reuses the existing skipped_until cooldown for ABANDON_COOLDOWN_DAYS=30 so 'scan' does not hand it straight back. - _actions.abandon_manual_pick is state-only (no uninstall cascade), matching apply_manual_pick, so the gated MCP abandon_pick tool reuses it. Also fixes a crash surfaced while picking a replacement game: the SteamUnavailableError family (including SteamUpdateInProgressError, raised when a game update defers a Steam restart) was only caught in the enforce loop. cmd_hide, cmd_pick, cmd_pick_manual and both cmd_done reconciliation points called hide_other_games bare, so an undrivable Steam aborted the command with a traceback — after the pick had already been saved. All six sites now go through the new stdout-free try_hide_other_games wrapper and report "Library hiding: skipped (<reason>)" instead. Verified live: lock message advertises the window, expired/wrong-id/no-arg paths exit 1, and abandoning released the AoE2 lock, uninstalled it and recorded the 30-day cooldown. 1030 tests pass at 100% coverage. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .. | ||
| __init__.py | ||
| conftest.py | ||
| test_actions.py | ||
| test_cmd_done_part2.py | ||
| test_config.py | ||
| test_enforce_loop_part2.py | ||
| test_enforce_loop_part3.py | ||
| test_enforce_loop.py | ||
| test_enforcer_part2.py | ||
| test_enforcer.py | ||
| test_game_install_part2.py | ||
| test_game_install_part3.py | ||
| test_game_install.py | ||
| test_hltb_detail.py | ||
| test_hltb_part2.py | ||
| test_hltb_part3.py | ||
| test_hltb_search_part2.py | ||
| test_hltb_search.py | ||
| test_hltb.py | ||
| test_library_hider_part2.py | ||
| test_library_hider.py | ||
| test_main_part2.py | ||
| test_main_part3.py | ||
| test_main_part4.py | ||
| test_main_part5.py | ||
| test_main.py | ||
| test_mcp.py | ||
| test_polls_tracking_part2.py | ||
| test_polls_tracking.py | ||
| test_protondb.py | ||
| test_scanning_part2.py | ||
| test_scanning_part3.py | ||
| test_scanning_part4.py | ||
| test_scanning.py | ||
| test_stats.py | ||
| test_steam_api.py | ||
| test_store_blocker_part2.py | ||
| test_store_blocker.py | ||
| test_total_block.py | ||
| test_update_restart_guard.py | ||
| test_web_dataset.py | ||
| test_web_server.py | ||
| test_whitelist.py | ||