Skip to content

Name runs that ended on a sleeping or locked PC instead of calling them unexplained - #199

Merged
Views2k merged 2 commits into
mainfrom
fix/sleep-lock-exit-reason
Nov 9, 2026
Merged

Views2k merged 2 commits into
mainfrom
fix/sleep-lock-exit-reason

Conversation

@Views2k

@Views2k Views2k commented Nov 8, 2026

Copy link
Copy Markdown
Owner

A recovered run without a close request, a Windows fault or a Windows stop event was always shutdown-incomplete ("Wisp stopped without being closed" in Tools). On 2.7.x most of those runs ended on a PC that went to sleep or was locked and never came back, hiding the real unexplained stops among them.

What changed

  • SessionEndSentinel now also handles WM_POWERBROADCAST (PBT_APMSUSPEND, PBT_APMRESUMEAUTOMATIC, PBT_APMRESUMESUSPEND) and WM_WTSSESSION_CHANGE (WTS_SESSION_LOCK, WTS_SESSION_UNLOCK, registered with WTSRegisterSessionNotification) on its own thread, and reports every notice through one SessionNotice callback. The shutdown notices keep their behaviour.
  • The run marker records SuspendedAtUtc and SessionLockedAtUtc. Resuming and unlocking clear them; a checkpoint a minute or more after the sleep notice also clears it, because the checkpoint timer does not run while Windows sleeps. Invalid times (not UTC, before the run started) are dropped on read, so a marker from an earlier version keeps today's reading.
  • PreviousRunRecovery sets RecoveredExitInfo.Suspended / SessionLocked from the previous marker when there is no fault, no native record, no Windows stop and no shutdown event. A matched fault clears both.
  • The incident reason is system-sleep or session-locked (sleep wins when both are set); shutdown-incomplete remains for runs with neither state. Both reasons join the Reasons catalog (the Tools catalog was extended in Views2k/wisp-site first, since ingestion validates reasons).
  • The local report names the state. Like a Windows shutdown, a run that ended on a sleeping or locked PC gets no card on the dashboard; the report stays in the store for the diagnostics bundle and Tools reporting.

Verified

  • New unit tests: PreviousRunRecoveryTests (suspended / locked / both / neither reasons and report text; stop and shutdown events win; fault and recorded shutdown win), RunExitMarkerStoreTests (notices survive checkpoints and restart until withdrawn, invalid times rejected and dropped, late checkpoint clears sleep), SupplementaryIncidentCaptureTests (reason mapping and catalog validity), DiagnosticsViewModelCrashNoticeTests (no card). The PR gate selects these classes.
  • dotnet format whitespace on the changed files; wisp-preflight. Windows build and tests run in CI.

Unverified

  • Real sleep, hibernate, lock and resume on a Windows PC: that the sentinel window receives the notices, that the marker write completes before the PC sleeps, and that the next start labels the run. Needs a desktop check with Wisp running, separately on Steam and on the Xbox app / Microsoft Store build (the change is in the shared app code; neither platform's game path is touched).
  • WTSRegisterSessionNotification on a PC where the Terminal Services service is stopped: the sentinel then records shutdowns and sleep only.

Closes #193

…em unexplained

A recovered run without a close request, a Windows fault or a Windows stop
event was always reported as shutdown-incomplete. Most of those runs on 2.7.x
ended on a PC that went to sleep or was locked and never came back, which
hid the real unexplained stops among them.

The session sentinel window now also receives the sleep, resume, lock and
unlock notices (WM_POWERBROADCAST and WM_WTSSESSION_CHANGE) on its own
thread, and the run marker keeps the last sleep and lock times. Resuming and
unlocking clear them, as does a checkpoint a minute or more after the sleep
notice, since the checkpoint timer does not run while Windows sleeps. The
next start labels such a run system-sleep or session-locked; a Windows fault,
stop or shutdown event still wins, and markers from earlier versions keep
today's reading. Like a Windows shutdown, these runs get no dashboard card.

Closes #193
@Views2k
Views2k marked this pull request as ready for review November 8, 2026 21:38
@Views2k
Views2k merged commit dfadbad into main Nov 9, 2026
10 checks passed
@Views2k
Views2k deleted the fix/sleep-lock-exit-reason branch November 9, 2026 03:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Runs that ended in sleep or on a locked PC are reported as stopped without being closed

1 participant