fix: harden Windows updater restart handoff - #8
Conversation
Use creation-time-bound Toolhelp snapshots to prove candidate and restored-old listener ownership across Windows launcher descendants. Capture the candidate tree again at the real stop boundary and explicitly terminate and reap every test-owned Popen.
Use PID plus creation time as the stable identity key across reparenting, listener membership, and survivor checks. Add deterministic stale-PID and native Toolhelp/query failure controls.
Gate 3 live updater validation: failed safelyCorrection: the first version of this comment incorrectly attributed a retained v0.2.1 stderr traceback to the new beta.2 attempt. Hash/line-number reconciliation proved that traceback predated Gate 3. The corrected failure boundary is below. An authorized live validation of the exact published
The transactional rollback behaved correctly: transaction The published beta.2 tag/release/assets remain unchanged, but beta.2 is not live-updater qualified and its candidate restart path was not exercised. A successor needs to launch the helper from a trusted stable cwd outside the installation and staged trees, retain a regression that starts the parent from inside the install root and performs the real Windows swap/finalization path, preserve the causal swap error in evidence, and pass another separately authorized live update gate. |
Status
Gate 1 complete — PR #8 merged from the independently accepted exact snapshot. Gate 2 remains pending.
PR #8 was merged into
developon 2026-08-19 using merge commitbb71453e5b53b7293ed9967d6efb1e748e7944d4. Beta.2 publication, release-asset changes, and any live updater operation remain unauthorized.Exact snapshot
6148ecd84cccfbad69e4ac94899311c87745a1e778e70a24f2869a9719607f26da039745482bf745c54be2a629deef3dbd79a2d55a0df140acd17a5bf38a56e2c897eb3094eb37180ae4862a8607f7a09265cc0ad407f27755d6abcf248168b9291689f403d4c63b9c03ab86532aa40893557cc3ad68c8f9Review history and remediation
The original implementation at
6aa3779d…had two production P0 defects: retained exited Windows process objects could be accepted as live startup owners, and failed recovery could relaunch an installation not re-established as trusted. Both were fixed at production remediation head3e2d60adb12e14c482f1ab270e1b3c4f287565cfand independently closed.The later evidence head
c54be2a…failed because normal Windows/Hermespythoncan expose a launcher asPopen.pidwhile a descendant owns the listening socket, and because test-ownedPopenobjects were not reliably reaped.Head
f38a56e2…corrected launcher-tree attribution and reaping, but a fresh independent review found that fullProcessIdentityequality still treated mutableparent_pidand executable observations as identity. A reparented process with unchanged PID and creation time could therefore be falsely classified as absent. The same review required durable native-boundary controls.The current append-only remediation at
9265cc0a…:(pid, creation_time);Process32FirstW,Process32NextW,OpenProcess, andGetProcessTimesfailures;A fresh final independent technical re-review of
9265cc0a…explicitly closed both prior P1/P2 technical findings. Its only blocking result was that this PR body and the Project Hub had not yet been reconciled to the new snapshot; this update addresses that record-only gate without changing code.Exact changed-file scope
Exactly eight files differ from required
develop:appdock.pyscripts/update_helper.pytests/test_generation9_remediation.pytests/test_update_real_finalize_rollback_process.pytests/test_update_real_rollback_process.pytests/test_update_restart_handoff_regression.pytests/test_windows_process_tree_deterministic.pytests/windows_process_tree.pyThe current remediation commit changes only the four test/evidence files numbered 4, 5, 7, and 8.
Production code is unchanged after
3e2d60adb12e14c482f1ab270e1b3c4f287565cf:appdock.py:b9aa89cbf4c3d0317ddd54905186536b0522521bscripts/update_helper.py:aa85150b10427f65ac74930eba265887fe8a48e9Local Windows validation
All process runs used
ResourceWarningas an error.ResourceWarningorsubprocess is still runningwarningThe normal Hermes launcher topology was independently reproduced: the
Popen.pidlauncher had a different descendant PID owning the disposable listener; stable identity correctly attributed it to the owned tree and cleanup removed it.Exact-head CI
Run 31898113799 is bound to
9265cc0ad407f27755d6abcf248168b9291689f4and completed SUCCESS, with all 10 jobs passing:ResourceWarning; zerosubprocess is still runningInformational only: GitHub forced older Node 20 artifact actions onto Node 24; no gate was affected.
Gate 1 merge result
Ethan explicitly authorized Gate 1. Immediately before merge, GitHub still reported the exact accepted head/tree/base,
MERGEABLE/CLEAN, and all 10 exact-head checks successful. The guarded merge used GitHub's exact-head match and preserved the seven reviewed commits.2026-08-19T19:58:58Zbb71453e5b53b7293ed9967d6efb1e748e7944d46148ecd84cccfbad69e4ac94899311c87745a1e7and9265cc0ad407f27755d6abcf248168b9291689f4developtree:03d4c63b9c03ab86532aa40893557cc3ad68c8f9No tag, release, release-asset, updater, live AppDock, Startup, Tailscale, channel, private-state, or retained-evidence operation occurred under Gate 1.
Safety and approval gates
The live machine remains healthy on managed v0.2.1 / Stable. Startup, Tailscale, channel, private state, and retained beta.1 failure evidence remain preserved.
A final different record-aware independent verifier directly read the current PR body and authenticated Google Docs Project Hub, confirmed no branch drift or remaining technical/record blocker, and returned RESULT: PASS.
Next bounded action: prepare and independently verify the beta.2 version commit and release artifacts without publishing them, then return for Gate 2: beta.2 publication authorization. Any live updater run remains a separate Gate 3 authorization.