Silent Op Recovery
A long op with no progress signal is a black box. You can't tell if it's working, hung, or waiting on input. Waiting blindly risks a 10-minute hang. The recovery is: kill by PID, restart with visible output.
The move
- Recognize silence. The op has produced no output for longer than you'd expect for its type (an install silent for 90s+; a build silent for 2m+; a test silent for 30s+). Silence ≠ progress.
- Check interim progress directly (lighter first move). Before killing, poll the op's interim state:
- List the directory it's writing to (
Get-ChildItem <build-dir>/ls <build-dir>) — are files appearing / growing? - Read a partial output file or log it's writing.
- Query a status endpoint if the op exposes one. The background notification fires on exit; "is it making progress?" is a now question. If interim state shows progress, keep waiting. If interim state is frozen, escalate to kill-and-restart.
- List the directory it's writing to (
- Kill by PID, not by name. Use the PID you recorded at launch:
- PowerShell:
Stop-Process -Id <pid> -Force -ErrorAction SilentlyContinue - POSIX:
kill -9 <pid>Never use a name-based kill (Stop-Process -Name node -Force,pkill node) — it nukes unrelated processes.
- PowerShell:
- Restart with a visible-output reporter. Re-run the same command with a flag that emits progress:
- pnpm:
--reporter=append-only - npm:
--loglevel=infoor--foreground-scripts - pip/uv:
-vor--verbose - pytest: remove
-q, or add--progress
- pnpm:
- Tail the output.
2>&1 | Select-Object -Last 15(PowerShell) or2>&1 | tail -n 15(POSIX) — visible but bounded. - Compare. If the restart progresses, the original was hung. If the restart also goes silent, the op is genuinely slow or blocked on something external — diagnose that, don't keep killing.
Track PIDs at launch (the enabler)
You can only kill by PID if you recorded it. When you launch a long-running op, capture its PID:
- PowerShell background job:
$j = Start-Process pnpm -ArgumentList "install" -PassThru; $j.Id - POSIX:
pnpm install & echo $!
Record the PID in your board or a triage note so it's findable when silence hits.
When NOT to kill-and-restart
- The op is genuinely slow but progressing (you saw output recently). Wait.
- The op is a deploy or migration — killing mid-flight can leave damaged state. Assess before killing (see
background-failure-triage). - The op is interactive and waiting on your input — killing loses the input; answer the prompt instead.
Anti-patterns
- Waiting blindly. A silent 10-minute install is not "being patient"; it's gambling.
- Name-based kill.
pkill nodeends your dev server, your background build, and the unrelated worker. - Restart without a reporter. Re-running the same silent command reproduces the same silence.
- No tail. Visible output without a tail floods context; the tail keeps the signal bounded.
- Kill loop. After one silent restart, diagnose root cause.
Extended patterns
Capture exit + tail idiom, error-grep variant: reference.md
Pair with
cost-transparency— the elapsed-time signal is what tells you silence has gone on too long.background-failure-triage— a killed-and-restarted op that then fails is triaged at the next boundary.fill-the-wait— while the restarted op runs, fill the wait with an independent in-lane task.