docs(update): scope the stderr-merge comments to legacy hand-offs

The current windows.ps1 hand-off drains both pipes; the deadlock the
merge guards against lives in hand-offs shipped before it. The twin-fix
cross-reference follows the heartbeat helper to main_install_repair.py.
This commit is contained in:
yoniebans
2026-09-05 15:02:53 +02:00
parent 05a18c1333
commit 1819e50081
2 changed files with 19 additions and 19 deletions
+10 -10
View File
@@ -452,16 +452,16 @@ def _run_install_with_heartbeat(
t = threading.Thread(target=_heartbeat, daemon=True)
t.start()
try:
# stderr=STDOUT: uv/pip write progress to stderr. The desktop
# hand-off (scripts/desktop-update.ps1) only drains the child's
# stdout while the child runs, so a full stderr pipe (~64KB)
# blocks the installer forever. Merged into stdout, the output
# rides the pipe that IS drained. This module is imported when
# `hermes update` starts, so an update running from an old base
# executes the old copy regardless of the git reset — this
# protects updates initiated from bases that already ship it.
# (managed_uv.py gets the same fix AND is imported lazily after
# the reset, so its sync is protected even on old bases.)
# stderr=STDOUT: uv/pip write progress to stderr. Legacy desktop
# hand-offs (pre scripts/desktop-update/windows.ps1, which drains
# both pipes) only drain the child's stdout, so a full stderr
# pipe (~64KB) blocks the installer forever. Merged into stdout,
# the output rides the pipe old hand-offs DO drain. This module
# is imported when `hermes update` starts, so an update running
# from an old base executes the old copy regardless of the git
# reset — this protects updates initiated from bases that ship
# it. (managed_uv.py gets the same fix AND is imported lazily
# after the reset, so its sync is protected even on old bases.)
subprocess.run(cmd, cwd=PROJECT_ROOT, check=True, env=env, stderr=subprocess.STDOUT)
finally:
done.set()
+9 -9
View File
@@ -588,15 +588,15 @@ def _stage_candidate_venv(
# and uv 0.12+ refuses --locked.
sync_env = dict(env)
sync_env.pop("UV_NO_CONFIG", None)
# stderr=STDOUT: uv writes progress to stderr. When the desktop
# hand-off (scripts/desktop-update.ps1) runs `hermes update`, it only
# drains the child's stdout while the child runs; a full stderr pipe
# (~64KB) blocks uv forever. Run 31453853006 hung 43 minutes in this
# exact call. Merging into stdout keeps the output streaming through
# the pipe that IS drained. This module is imported lazily by
# update_cmd AFTER the git reset, so even an update running from an
# old base executes THIS copy — unlike main.py, which is imported at
# startup and only protects bases that already ship its twin fix.
# stderr=STDOUT: uv writes progress to stderr. Legacy desktop
# hand-offs (pre scripts/desktop-update/windows.ps1, which drains
# both pipes) only drain the child's stdout while the child runs; a
# full stderr pipe (~64KB) blocks uv forever. Merging into stdout
# keeps the output streaming through the pipe old hand-offs DO
# drain. This module is imported lazily by update_cmd AFTER the git
# reset, so even an update running from an old base executes THIS
# copy — unlike the heartbeat helper (main_install_repair.py), which
# is imported at startup and only protects bases that ship its twin.
synced = subprocess.run(
[uv_bin, "sync", "--extra", "all", "--locked", "--python", str(_venv_python(candidate))],
cwd=project_root, env=sync_env, stderr=subprocess.STDOUT, check=False)