Commit Graph

233 Commits

Author SHA1 Message Date
f73d2fa513 Numeric dates; progress items without words
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:57:55 +01:00
8dbcc462c0 web: library, store, picks and jobs paint glyphs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:56:01 +01:00
7e0ae61164 web: dashboard, gaming and health paint glyphs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:55:42 +01:00
9f52d27893 web: backlog page paints glyphs and numbers
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:55:30 +01:00
f74e70221f web: system and setup pages paint glyphs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:54:44 +01:00
30416da9b8 web: runner, palette and countdown paint glyphs
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:54:44 +01:00
291a5ed26f Desktop toasts paint glyphs and numbers only
Guard test walks every toast call for literal words.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:54:20 +01:00
138abc6ce9 web: pills, card and dialog titles spoken only
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:45:30 +01:00
13df1dd14d web: command buttons paint glyphs only
Labels, descriptions and lock reasons are spoken only.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 11:36:41 +01:00
582ce6b2b6 web: empty() always speaks its label
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 02:26:15 +01:00
ca59039ba0 web: icon rail nav, spoken-only page heads
Sidebar paints a glyph and digit per section, the palette button a
magnifier and ⌃K; page titles, subtitles and the Actions heading are
spoken only. web/scripts/visible_words.mjs lists chrome words in the
built pages (146 -> 4, the command-button labels).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 02:23:47 +01:00
f5f921ebf4 web: icons for job state, notices, empty, copy
Partial textgate rework: job state pills, notices, empty and
loading states, copy button and timeline legend paint icons; the
old wording is spoken only. Guard test covers these pieces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 02:20:43 +01:00
a80652e91a deps(web): astro 7.4.8, typescript-eslint 8.72.2
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-11 02:20:21 +01:00
57d262b711 Pylint gate 10 over the whole package
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Raise the pylint hook to --fail-under=10.0 and make it lint the whole
package on every run (pass_filenames: false): over the staged subset a
9.99 tree passed at commit time.

Ports de2aea3 (9b9342ba-1) onto main, minus its web/ and requirements.txt
bumps and the iptables dedupe f1822f1 already landed; _hltb_confidence and
_hltb_search keep main's 429 handling. _search_batch splits out
_acquire_auth / _search_headers, and _stats.py is back to 250 lines.

Drops the min-similarity-lines = 8 floor (0 duplicate-code hits at the
default) and sets max-attributes = 15 for the flat persisted records, as
kuhy decided. Tests stay outside pylint, as at every site already at 10.

Todo: fda71ed1

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 16:57:35 +01:00
f1822f154f Dedupe iptables chain code; pylint jobs=1
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Set [tool.pylint.similarities] min-similarity-lines = 8 (as diet-guard)
and refactor the remaining R0801 hits: the store and total-block
iptables modules now share create_fresh_chain / add_drop_rule /
drop_chain in _store_tools. No duplicate-code disable or exclude.

Run pylint serially (pyproject jobs = 1, hook --jobs=1): parallel mode
pickles PyLinter with dill, which crashes on Python 3.15 (co_lnotab).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 15:57:53 +01:00
cef9fccab8 Migrate steam-backlog-enforcer/web to Astro (no R…
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
Tests / web-coverage (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Todo: 9b9342ba
2026-11-09 08:36:38 +01:00
8cc31a2c87 HLTB rate limit (429) wipes confidence data in hl…
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Todo: 9b9342ba
2026-11-09 08:02:55 +01:00
2ec53d977d deps(web): react-query 5.105.1, globals 17.14.0
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
Tests / web-coverage (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Clears the dependency-freshness gate blocking the push.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYGW5NZL5uVpnqmNKo
2026-11-02 15:33:15 +01:00
f435aa8bfa deps: earned_time 0.21.0, leisure-watch 0.2.7
Focus day pays 240 gaming (2/min); full focus day is 8 h.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYGW5NZL5uVpnqmNKo
2026-11-02 15:30:23 +01:00
6387e6819f Add todo app git hooks
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-02 13:55:18 +01:00
fdcf1815ec Move TODOs to todo app
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-11-02 11:18:49 +01:00
bfa4a6260f tests: cmd_stats tests no longer hit the network
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWxdzckyBH7fEbPywpr
2026-11-02 09:31:10 +01:00
2e66502abc deps: newest stable web pins, node 26.13.0
Clears the dependency-freshness gate that blocked pushes (ci-mirror).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWxdzckyBH7fEbPywpr
2026-11-02 09:21:04 +01:00
babe8cbfd9 Pin earned-time v0.20.0, leisure-watch v0.2.6
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWxdzckyBH7fEbPywpr
2026-11-02 09:17:02 +01:00
eba7de8c02 Pin earned-time v0.19.1, leisure-watch v0.2.5
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYcmik6APnHfc9gEVy
2026-11-02 08:47:59 +01:00
73afad98f9 Pin earned-time v0.19.0, leisure-watch v0.2.4
Tests isolate FOCUS_PROJECT_DATA so a live project never leaks in. Also
bumps the freshness gate's stale dev pins and websockets.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYcmik6APnHfc9gEVy
2026-11-02 08:41:27 +01:00
fb866978be Trim pylint TODO to remaining work
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWWcbzoov1KFZJSFcSs
2026-11-01 22:09:12 +01:00
011b76b0a9 Remove done TODO-refactor-250-continue
File cap met; remaining pylint work lives in TODO-pylint-to-ten.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWWcbzoov1KFZJSFcSs
2026-11-01 22:09:12 +01:00
9a62c2de27 Remove done TODO-file-length-250
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWWcbzoov1KFZJSFcSs
2026-11-01 22:09:03 +01:00
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
3e449bd2e6 Note Astro migration happens last
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWXTUM9dpnCS2wtFkx4
2026-11-01 19:04:10 +01:00
e77f5df73b docs: plan Astro migration
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWXTUM9dpnCS2wtFkx4
2026-11-01 18:44:15 +01:00
59a110e5c3 LeetCode hour needs the day paid in full (earned_time 0.18.0); gate_off read live from leetcode-guard
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
Tests / web-coverage (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-24 13:26:28 +02:00
d2a684ebf9 web deps: @tanstack/react-router 1.170.46; sync pnpm-lock.yaml
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
pnpm-lock.yaml had missed the previous bump (react-query 5.104.5,
typescript-eslint 8.72.0, vite 8.3.5); both lockfiles now match package.json.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYmCezqhUjUmMisF5YtM4F
2026-10-24 08:39:45 +02:00
dc22bd557c fast install: never report a failed run as success; queue the manifest first
The BG3 fast install of 2026-10-23 downloaded 160 GB, was refused by the
installer, and the web job still ended on a full bar, "Done!" and Succeeded
while Steam restarted the download from 0%.

- A failed run's reason is read from the installer's own run log (its ERROR
  lines). A waiting job prints "Failed: fast install of <game>: <reason>",
  which fails the job; `install` no longer says "Done!" after it.
- Daemon-started failures stay on the Dashboard's Fast install card (and in
  ctl status, `error`) until a new run starts or the game is installed.
- install_game writes Steam's "needs downloading" manifest before the
  installer runs: it only finishes a manifest it finds, so fresh installs
  were refused for want of one.
- Command building moved to _fast_install_cmd (250-line cap).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GYmCezqhUjUmMisF5YtM4F
2026-10-24 08:36:57 +02:00
0d93539944 total block: two-unit countdown (2w 2d … 45s), ticking every second
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 20:59:41 +02:00
520c4c55d3 deps: leisure-watch 0.2.2 (earned-time 0.17.0), hooks on earned-time 0.17.0
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
leisure-watch 0.2.1 required earned-time 0.16.0, which pip cannot
co-install with the 0.17.0 pin from 55cf19f.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CUaX4zAa6H4sMu3jd6RFdb
2026-10-23 20:26:01 +02:00
1bdf360193 pick keeps already-picked games; fast install reports progress
pick and pick-manual no longer uninstall games that are already allowed:
the outgoing assignment is kept as a released pick (installed, no lock)
until 'pick --replace', done/check, or abandon-pick. The allowed set is
capped at max_manual_picks + 1; a pick over it is refused before the
candidate list / confirmation, naming the games. status and the web
Picks card list kept games with an Abandon button.

Fast install now tracks the installer log from the spawn offset: web
jobs drive the progress bar (per-depot %, phase) and echo a line every
30 s; daemon-started runs are exposed via ctl status / /api/daemon and
shown on the Dashboard.

Also: web deps bumped for dependency freshness (react-query 5.104.5,
typescript-eslint 8.72.0, vite 8.3.5, node 24.22.1 in CI).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CUaX4zAa6H4sMu3jd6RFdb
2026-10-23 20:14:12 +02:00
55cf19fae4 LeetCode bonus: a day paid from banked credits counts (earned_time 0.17.0)
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
2026-10-23 11:33:39 +02:00
d2c4ea7ace deps: earned_time 0.16.0 + leisure-watch 0.2.1
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Has been cancelled
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Has been cancelled
Tests / test (push) Has been cancelled
Tests / web-coverage (push) Has been cancelled
repo-contract / repo contract (push) Has been cancelled
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:17:35 +02:00
7957a1fe12 leisure kill: a reason's start time pins the process (PID reuse)
When a now.json reason carries the start time it saw (leisure-watch
0.2.1 `start`, /proc/<pid>/stat field 22), only the live process with
that start time is signalled; a reused pid is spared. Absent (0.2.0) or
unusable, the old behaviour stands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:10:44 +02:00
bc02f83e7e budget: price the enforced budget by the 06:00 gaming day's leisure switch
earned_time 0.16.0 made resolve(leisure=False) force pre-leisure pricing,
so the enforced call passing False would have stayed 5 h/8 h after
go-live. It now passes leisure_active(gaming day) explicitly (its own
redirectable LEISURE_FROM_PATH): the go-live gaming day is 7 h/10 h, and
00:00-05:59 on the go-live date stays pre-leisure, matching billing. The
shadow resolve keeps leisure=True.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:09:33 +02:00
0ffc773f52 tests: collecting test_budget_view never reads the host's leisure switch
Its module-level rules_for runs before any autouse fixture, so a live
/etc/leisure-watch/leisure_from priced RULES. collection_isolated()
points every switch reader at a path that cannot exist.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:06:22 +02:00
e0cf931d0e leisure kill: sweep only after 30 s of continuous untrusted now.json
One stale moment (resume from sleep, a watcher restart) while spent no
longer kills every browser at once. A trusted or paused tick, a clock
step back, or a gap between ticks over 10 s (a suspend) restarts the
window; untrust is tracked while budget remains too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:04:38 +02:00
cef98a998a leisure kill: never signal the desktop session, whatever now.json says
Defence in depth for a forged or buggy now.json while root: i3 and its
bar, X, systemd --user, dbus, audio, ssh/gpg agents, tmux/screen, every
terminal and shell, sudo, Claude (incl. its versioned native binary and
node), keepassxc, notification daemons, and Python running a locker,
leisure_watch or daily_limits are refused by exe/script. Each refusal is
logged once (journal + budget.jsonl leisure_kill_refused).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:03:09 +02:00
04bd0837f1 leisure kill: wsg-grabber only as the program run; see through (deleted) exes
A path naming the repo (git -C ~/src/wsg-grabber, pytest, an editor) no
longer counts as the reviewer: only the exe itself, or a Python
interpreter's script / -m module, and still never `scrape`. An updated
browser or player (exe link ' (deleted)') is still recognised, for the
sweep and the browser focus exemption.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 17:01:21 +02:00
c99dd12984 deps: leisure-watch 0.2.0 (go-live switch, /status)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 16:44:15 +02:00
26a2aabbc7 leisure Phase 2 (dormant): bill, warn and kill on the leisure budget from go-live
Dormant until earned_time.leisure_active(gaming day) -- the switch file
written by `leisure-watch go-live`. From that day:

- enforced `seconds` are billed by the shadow rule (lock pause, fail-closed,
  once per wall clock); budget from plain resolve(); warnings and the cutoff
  say "Leisure".
- at 0, beside the unchanged Steam path, _leisure_kill SIGTERMs (SIGKILL 30 s
  later, per process) every focus/media pid in now.json except browsers,
  every failclosed browser pid, and -- with now.json untrusted -- every
  browser, media player and wsg-grabber reviewer. Root/system, lockers and
  the enforcer's own chain are never signalled. Kills go to budget.jsonl.
- tests: an autouse fixture redirects both switch readers, so no test reads
  /etc/leisure-watch/leisure_from; existing tests unchanged.

Re-pins earned-time to v0.15.0 (leisure_active).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 16:40:49 +02:00
4e9987c428 deps: leisure-watch 0.1.2 (safe reads, fail-closed display/incognito)
Some checks are pending
dependency freshness / dependencies on newest stable (push) Waiting to run
md-naming / markdown naming convention (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (mypy, mypy, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (pylint, pylint, ) (push) Waiting to run
pre-commit / pre-commit (${{ matrix.group }}) (rest, , mypy,pylint) (push) Waiting to run
Tests / test (push) Waiting to run
Tests / web-coverage (push) Waiting to run
repo-contract / repo contract (push) Waiting to run
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 13:38:42 +02:00
b5a76d6b45 shadow: forget expired warnings so varying messages cannot grow memory
The once-per-window warning map kept every distinct error forever; an
error whose text varies per tick would grow the daemon without bound.
Entries older than the window are now dropped before each check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dsh4Znwh2KnC7q6vbGpX1N
2026-10-19 13:20:08 +02:00