Skip to content

fix(desktop): first Windows update attempt no longer fails on the app's own dying backends (#74805, salvage #78037) - #95313

Merged
teknium1 merged 1 commit into
mainfrom
fix/74805-kill-to-scan-race
Aug 26, 2026
Merged

fix(desktop): first Windows update attempt no longer fails on the app's own dying backends (#74805, salvage #78037)#95313
teknium1 merged 1 commit into
mainfrom
fix/74805-kill-to-scan-race

Conversation

@teknium1

Copy link
Copy Markdown
Contributor

Summary

The first Windows update attempt from the Desktop no longer fails on the app's own dying backend processes (#74805; salvage of #78037 fix 1 by @3x3xX3N0N, reworked onto current main with his authorship preserved). Fleet relevance (#91277): the Desktop is the fleet's control seat — a first-attempt-always-fails local update poisons every rollout that starts there.

Root cause: taskkill /T /F returns when termination is INITIATED, and the pre-handoff unlock gate only probed the venv hermes.exe shim — which the python.exe -m hermes_cli.main serve backend need not hold at all. The gate passed with zero dwell while killed pythons were still unmapping .pyd files; the venv-blocker scan (no liveness filter) reported those dying processes as holders and aborted. Every first attempt failed; the manual retry succeeded because the table had settled.

Changes

  • apps/desktop/electron/backend-release-gate.ts (new, dependency-free per the backend-child.ts pattern): the gate now requires BOTH the shim unlocked AND every signalled PID to have actually left the process table; per-pass stragglers are killed and join the watch set; on deadline the old shim-only criterion survives as the escape hatch (lingering residue is the re-scan's job, a REAL holder still fails the shim probe)
  • apps/desktop/electron/main.ts: releaseBackendLock seeds and delegates to the gate; applyUpdates re-scans up to 2x with a 1.5s settle before aborting on blocked (covers the plain path AND the post-stopSafeBlockers path)
  • 6 unit tests (fake clock/table, contract-pinning) + 3 live Windows tests (real spawned processes, real taskkill, real process.kill(pid,0) probe)

Attribution: @3x3xX3N0N's design (exit-wait + re-scan dwell, #78037 fix 1); re-scan settle first submitted by @MaheshBhushan (#74831); killed-PID tracking seam matches @webtecnica's #74956 — both credited via Co-authored-by.

Validation

Result
windows-latest, head (unit + live suites) 9/9 passed — run 32937871944
windows-latest, A/B sabotage (gate reverted to merge-base shim-only) 3 contract tests FAILED as required, live premise tests still passed — run 32937891610
Local: gate suite 6/6 · adjacent suites (backend-child, venv-blocker-scan) 24/24 · tsc -p tsconfig.json clean

Live repro: windows-latest — before: with the merge-base shim-only gate the #74805 shape passes the gate at t=0 while a real killed PID is still enumerable (contract tests fail proving it); after: the gate dwells until the PID genuinely leaves the live process table (9/9). Ephemeral single-use lane per the live-repro-gate rule; no workflow files in this diff.

Fixes #74805. Closes out #78037 fix 1; supersedes #74831 and #74956 (credit above).

Infographic

Release gate

@github-actions

github-actions Bot commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

૮ >ﻌ< ა ci review

ran on 8a49725 — fix(desktop): first Windows update attempt no longer fails o

⚠️ Warnings

OSV vulnerability scan · View job

7 known vulnerabilities found in pinned dependencies.

How to fix:

Review the findings in the Security tab. Update the affected dependencies if a patched version is available.


debug info

CI timings

CI timings · View report · View job

Wall time 1m47s vs 4m17s (-58.4%). 2 job(s) slower, 3 faster, 1 unchanged.

  • JS & TS checks / JS & TS checks: -29.0s
  • OSV scan / Emit review status: +4.0s
  • OSV scan / Scan lockfiles / osv-scan: -2.0s
  • Detect affected areas: -2.0s
  • All required checks pass: +2.0s

…ackend processes (#74805)

taskkill /T /F returns when termination is INITIATED, not completed, and
the pre-handoff unlock gate only probed the venv hermes.exe shim — which
the 'python.exe -m hermes_cli.main serve' backend need not hold at all.
The gate could therefore pass on its first iteration with zero dwell
while the killed pythons were still unmapping .pyd files; the
venv-blocker scan (no liveness filter) then reported those dying
processes as holders and aborted the hand-off. Every first update
attempt from the footbar failed; the manual retry succeeded because the
process table had settled by then.

The unlock gate now lives in backend-release-gate.ts (dependency-free,
backend-child.ts pattern) and requires BOTH the shim unlocked AND every
signalled PID to have actually left the process table; stragglers
collected per-pass are killed and join the watch set. On deadline the
old shim-only criterion survives as the escape hatch — lingering PIDs
past 15s are the venv-blocker re-scan's job. applyUpdates additionally
re-scans up to 2x with a 1.5s settle before aborting on 'blocked', so
untracked grandchildren an AV driver holds in teardown stop failing the
update while a REAL holder still aborts on the third scan.

Surgical reapply of PR #78037 fix 1 by @3x3xX3N0N onto the post-#87599
code shape (stopBackendTreesForUpdate extraction, stopSafeBlockers
re-scan path). The re-scan settle idea was first submitted by
@MaheshBhushan (#74831); the killed-PID tracking seam matches
@webtecnica's #74956.

Co-authored-by: MaheshBhushan <128616744+MaheshBhushan@users.noreply.github.com>
Co-authored-by: webtecnica <75556242+webtecnica@users.noreply.github.com>
Co-authored-by: Hermes <hermes@nousresearch.com>
@teknium1
teknium1 force-pushed the fix/74805-kill-to-scan-race branch from c39ad41 to 8a49725 Compare August 26, 2026 06:34
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists comp/desktop Electron desktop app (apps/desktop/*) platform/windows Native Windows-specific behavior or breakage area/install-update Installer, updater, packaging, wheels, doctor sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades labels Aug 26, 2026
@teknium1
teknium1 merged commit b04f857 into main Aug 26, 2026
33 checks passed
@teknium1
teknium1 deleted the fix/74805-kill-to-scan-race branch August 26, 2026 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/install-update Installer, updater, packaging, wheels, doctor comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists platform/windows Native Windows-specific behavior or breakage sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-platform-windows Sweeper risk: may break or behave differently on native Windows type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] Windows: footbar-triggered update races process table on first attempt, no auto-relaunch after retry

3 participants