Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,17 @@ own; propose, with the reasoning, and let the maintainer decide.

**Needs explicit approval, every time:** creating the public repository,
pushing to it, publishing a release, changing the scheduled tasks or the
configuration on the maintainer's machine, and any history rewrite.
configuration on the maintainer's machine, and rewriting the history of
`main`.

**A branch's history is the agent's to rewrite until it reaches `main`**,
unpushed or pushed for a pull request, and it should be: before a push,
reduce a lot's commits to its logical steps. A fix to code written on the
same branch, a second attempt, a page touched again for the same purpose
belong in the commit they complete, not after it. A reader of `main` sees
one commit per thing done; nobody returns to a state corrected an hour
later, and the repository does not carry it. Force-pushing a pull
request's branch is part of this; `main` is never rewritten.

**The standing rule:** a change to what the user sees updates
`docs/getting-started.md` and `docs/how-it-works.md` in the same commit. A
Expand Down Expand Up @@ -235,8 +245,6 @@ commands; do not.
- A process started after `WM_QUERYENDSESSION` dies with
`STATUS_DLL_INIT_FAILED`. Nothing can run a command at logoff; the session
marker runs it at the next start instead.
- The refinement's single timed attempt is a known margin, not a calibration
— `docs/design/09-robustness.md`.
- `.git/HEAD` does not change on commit; `build.rs` watches the ref it names
and `packed-refs` too, or the stamp goes stale.

Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ a section is written.
file: a short-lived helper opens them and takes that cost with it when it
ends.

### Fixed

- A game still on its loading screen twenty seconds in no longer keeps its
launcher's name for the whole session: the watcher asks again every
twenty seconds, for two minutes at most.

### Removed

- The *Writing your own* recipe: the starter configuration's comments and the
Expand Down
8 changes: 5 additions & 3 deletions config.example.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,11 @@ stop_delay = "2s"
# A title brings several processes that all match Windows' known game list: a
# launcher stub, an anti-cheat service, and the game. The satellites usually
# start first, so the name captured at the very start is often the wrong one.
# Once, this far into a session, the per-process GPU counters are read and the
# candidate that is actually rendering wins. Set to "0s" to skip it and keep
# whichever process matched first.
# This far into a session, the per-process GPU counters are read and the
# candidate that is actually rendering wins. While there is no answer yet --
# nothing rendering, no match -- they are read again at the same interval, six
# times at most. Set to "0s" to skip it and keep whichever process matched
# first.
#
# This only ever changes the *name*: detection never depends on it, and being
# unable to read the counters simply means no answer.
Expand Down
22 changes: 21 additions & 1 deletion docs/design/00-detection.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,17 @@ back during the Starfield session did not release the reference, so the writer
does not blink on focus changes — its lifetime is the session. Starfield was
launched into the background and the writer still started, with another
application in the foreground, so detection does not depend on focus.
*Corrected 2026-09-25:* it can. Battlefield 6, launched and left loading
behind another window, ran from 15:05:34 without a writer; the writer
started at 15:08:02, the second the maintainer brought the game to the
front, and stayed when the focus went away again. Windows' page says the
writer is told when a game gets focus, and this is Windows starting it on
that event. Starfield's run stands as measured; what differs between the
two was not looked at. Either way it is Windows' verdict, and a game
loading behind another window has no need of its gaming commands yet.
The same day, Wreckfest 2's *Change settings* window started the writer
too: it is `Wreckfest2.exe` itself, and Windows took it for the game, a
14-second session.
`GameDVR\LastGameActivity` matched the start timestamp to the second in both
sessions. As a negative control, launching and focusing Notepad spawned nothing.

Expand All @@ -73,7 +84,16 @@ same afternoon. [Lot 1](01-console-watcher.md) has those figures and the
decision they led to. *Corrected 2026-09-25:* what it waits for is the
user's next keyboard or mouse input after the game has exited — some twenty
seconds after it, and 2 h 22 min once, with nobody at the machine;
[Lot 18](18-game-gone-nobody-there.md).
[Lot 18](18-game-gone-nobody-there.md). *And later that day:* not twenty
seconds. With the maintainer at the keyboard, six titles took 0.6 s to
85 s. The writer is never released while nobody touches the machine; what
decides the time otherwise is not known.

Nor is the writer one per title. Two games running together share it:
American Truck Simulator and Euro Truck Simulator 2, then Wreckfest 2 from
Steam and Starfield from the Store, on 2026-09-25. Each pair had one writer
process from the first game's start to after the second's exit
([Lot 9](09-robustness.md)).

## The limit found in the field, 2026-09-20

Expand Down
3 changes: 3 additions & 0 deletions docs/design/01-console-watcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ the party chat change nothing. The per-title theory stays dead; what the two
sessions of each title above differed in is most likely when the maintainer
next touched the machine, which was not noted then — inferred, not
measured. [Lot 18](18-game-gone-nobody-there.md) has the details.
*Corrected the same afternoon:* not twenty seconds. With the maintainer at
the keyboard, six titles took 0.6 s to 85 s; only "never while nobody
touches the machine" stands.

The second sessions were measured from independent sources, since the log did
not yet record the writer's exit: Steam's `gameoverlay_ui.txt` for Battlefield
Expand Down
15 changes: 10 additions & 5 deletions docs/design/03-game-naming.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,15 @@ allowed in exactly one narrow form, and its absence is a normal outcome.

## The refinement

Once, a little way into the session (`identify_after`, 20 s by default), the
A little way into the session (`identify_after`, 20 s by default), the
candidates the Known Game List produced are ranked by their share of the 3D
GPU engine over a one-second sample. The one rendering wins. The rule never
promotes a process the list did not match; a single candidate, unreadable
counters, or a game still on its loading screen all mean "keep the current
name", and the log says which.
promotes a process the list did not match; a single candidate that is the
name in use, or the GPU confirming it, means "keep the current name", and
the log says which. *Corrected 2026-09-25:* this said "once", and that
unreadable counters and a loading screen kept the name too. Those, and no
match at all, are no answer rather than a verdict, and the question is asked
again at the same interval, six times at most — [Lot 9](09-robustness.md).

**One match left is not nothing to say.** Measured 2026-09-15 on Battlefield 6:
the EA anti-cheat *launcher* matches the install folder, starts before the
Expand Down Expand Up @@ -93,7 +96,9 @@ harmless.
session, `status` read 0.0 % for every candidate; ten seconds later, 75 %. The
single timed attempt landed just inside the window that makes it work. That is
a margin, not a calibration — [Lot 9](09-robustness.md) has the design that
would replace the timer.
would replace the timer. *Since 2026-09-25* an attempt that reads nothing
rendering is followed by another, so a loading screen costs twenty seconds
rather than the name.

## Packaged titles are matched wherever they are installed

Expand Down
6 changes: 5 additions & 1 deletion docs/design/05-windowless-watcher.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,8 @@ next start — [Lot 9](09-robustness.md).

No icon, no menu, nothing drawn. No `ShutdownBlockReasonCreate` either
("Restoring the fan profile…" on Windows' shutdown screen) — worth having,
belongs with the rest of the shutdown work in Lot 9.
belongs with the rest of the shutdown work in Lot 9. *Corrected
2026-09-25:* not worth having. Windows never lists a program without a
visible window on that screen, registering a reason is what would put it
there, and nothing is restored at session end to announce; decided against
in [Lot 9](09-robustness.md).
Loading