safe-process-signals
Skill2 starsChanged todayApache-2.0View on GitHub
Safe process killing and signal handling for agent/subprocess contexts. Use when running pkill, killall, kill, or any process termination command from a shell subprocess, automated script, or coding agent.
We split this skill into the rules it gives an agent
10 rules. About 0 are common, 5 are distinctive, and 5 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
5
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- could be automatic: a setting could enforce it
- Distinctive: line 15
Prefer the service manager or tool that owns the process.
- Distinctive: line 23
Use direct signals only when the lifecycle owner cannot perform the requested operation or the task specifically requires them.
- Distinctive: line 27
Start with an owned task's PID or inspect candidates.
- Very specific: line 34
Read the output and select only the intended instance.
- Very specific: line 54
Use pkill or killall only when every selected instance belongs to the requested operation.
- Very specific: line 55
Avoid broad killall -r patterns.
- Distinctive: line 66
After the identity check, request graceful termination of that PID:
- Distinctive: line 76
Use the lifecycle owner's completion event when available.
- Very specific: line 93
If graceful shutdown timed out, confirm the same executable, start time, and ownership are still present.
- Very specific: line 95
When a bounded TERM-to-KILL sequence is appropriate, util-linux kill --timeout uses a PID file descriptor so its follow-up signal cannot …
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Safe Process Signals
Prevent agent self-termination, unrelated process kills, and indefinite waits. Follow the steps in order: inspect, select, signal, wait, verify. A successful signal request is not proof of exit.
1. Choose The Lifecycle Owner
Prefer the service manager or tool that owns the process. Use its stop/restart operation and inspect its resulting state. This preserves process-group cleanup and restart policy instead of fighting an automatic supervisor.
For an Omarchy-managed app, use its lifecycle operation: the omarchy Code Mode namespace's restart tool when the agent has it, otherwise the command:
omarchy restart terminalUse direct signals only when the lifecycle owner cannot perform the requested operation or the task specifically requires them. Check installed help before using the examples below; shell built-ins and external tools have different options.
2. Inspect And Select Targets
Start with an owned task's PID or inspect candidates. A name match alone does not establish that a process belongs to this task.
# Candidate discovery only: excludes ancestors and restricts to this user.
pgrep -a -A -u "$(id -u)" -f '[n]ode.*server\.js'Read the output and select only the intended instance. No match means inspect its lifecycle state, not broaden the pattern. Multiple matches require inspecting each candidate before choosing. Do not pipe discovery output straight into kill.
In the following examples, set $pid to the verified numeric PID greater than 1. Never substitute an empty value, 0, -1, or a negative process-group selector.
ps -p "$pid" -o pid,ppid,pgid,sid,lstart,user,stat,args
readlink -- "/proc/$pid/exe"
pstree -sp "$$"Confirm the executable, command line, user, start time, parent, and service/session ownership. Compare against the invoking shell's ancestry. Reject the agent, its shell, ancestors, and unrelated instances. If ownership is unclear, stop before signalling.
Record the inspected identity and recheck it immediately before signalling, especially after a delay or a new tool call. If the process disappeared or the identity changed, do not send a signal to that PID. A PID file must pass the same numeric and identity checks; never feed its contents straight to kill.
Pattern Matching Limits
- procps
pgrep,pkill, andpidwaitexclude themselves. Their invoking shell and other ancestors can still match-fpatterns. - A bracket pattern such as
[n]odeavoids matching the literal pattern in a shell command. It does not protect ancestors whose actual command line containsnode. -A/--ignore-ancestorsexcludes ancestors when supported. It does not exclude unrelated processes with the same name.-xmatches an exact name or command line, not one process. It does not establish ownership or exclude ancestors by itself.- Use
pkillorkillallonly when every selected instance belongs to the requested operation. Prefer the inspected PID for a single-instance task; a later pattern match can include newly started processes. - Avoid broad
killall -rpatterns.killall -ehandles ambiguous long names; it is not a general guarantee of one exact target.
3. Choose And Send The Signal
| Signal | Use case |
SIGTERM | Normal graceful shutdown; use first unless the application documents another shutdown signal. |
SIGINT | Interrupt an interactive program that expects this signal. It does not reproduce every terminal Ctrl+C process-group effect. |
SIGKILL | Forced termination after graceful shutdown fails; the process cannot clean up. |
SIGHUP | Reload only when documented by the application; otherwise it may terminate. |
After the identity check, request graceful termination of that PID:
kill -TERM -- "$pid"On failure, inspect the error and current process state. A missing process may already have exited; a permission error is not success. Do not suppress failures with 2>/dev/null || true or automatically elevate privileges.
4. Wait And Verify
Use the lifecycle owner's completion event when available. For a directly signalled PID, use a bounded wait, choosing a timeout appropriate to the application's documented shutdown time:
timeout 5s pidwait --pid "$pid"Interpret the result before proceeding:
0: the selected process was waited for. Confirm the intended service/session is stopped, including any owned children relevant to the task.1: no process was matched or waited for. Inspect with the samepscommand; an absent original process can mean it exited before the wait started. Do not call an inspection failure a confirmed exit.124: the wait timed out. Inspect identity and state again before deciding whether escalation is appropriate.- Other non-zero results: report the tool, permission, or runtime failure. Do not infer that the target stopped.
kill -0 tests existence/permission, not completed shutdown. A zombie or uninterruptible process needs state inspection, not repeated signals. killall --wait can wait indefinitely; timeout bounds a wait but does not make target selection safe.
5. Escalate Only For The Same Instance
If graceful shutdown timed out, confirm the same executable, start time, and ownership are still present. Escalate only when forced termination is warranted for the requested operation. Do not rerun a broad name pattern with -9.
When a bounded TERM-to-KILL sequence is appropriate, util-linux kill --timeout uses a PID file descriptor so its follow-up signal cannot hit a replacement process that reused the PID:
# Check the external binary, not the shell's kill built-in.
/usr/bin/kill --help
# Only after target verification and a decision that forced escalation is warranted:
/usr/bin/kill --verbose --timeout 5000 KILL --signal TERM -- "$pid"The follow-up is sent only if that process still exists. This protects the delayed signal, not the initial target selection. Run the bounded exit verification afterwards; the command's success alone does not prove shutdown.
If that implementation is unavailable, do not replace it with kill; sleep; kill -9 and claim the same PID-reuse protection. Use the lifecycle owner or re-inspect the surviving instance before a separate signal, recognising the remaining check-to-signal race. Never target a process group without verifying that every member belongs to the task and none hosts the agent.
Report
State which instance was targeted, which lifecycle operation or signals were used, and the observed exit result. Report surviving children, supervisor restarts, permission failures, or timeout limits when they affect the requested result.
Sources for exact options and exit statuses: installed pgrep(1) (including pidwait), util-linux kill(1), killall(1), and timeout(1).
In this repository56 other files it gives its agents.
- AGENTS.mdAGENTS.md
- agentic-workflowsSkill
- asking-questionsSkill
- broSkill
- browser-accessSkill
- change-review-handoffSkill
- changeset-scopeSkill
- check-skill-updatesSkill
- chillSkill
- ci-loopSkill
- cleanup-unnecessary-variablesSkill
- code-reviewSkill
- decision-modelsSkill
- diagnoseSkill
- effect-principlesSkill
- evidence-firstSkill
- gh-stackSkill
- git-contextSkill
- github-development-rulesetsSkill
- github-repository-setupSkill
- grillingSkill
- handoffSkill
- herdr-workflowsSkill
- home-assistant-frontendSkill
- home-assistant-lit-renderingSkill
- human-step-guideSkill
- import-external-skillSkill
- inbox-reportingSkill
- issue-loopSkill
- lit-renderingSkill
- maintain-docsSkill
- npm-jsr-first-publishSkill
- opencode-effectSkill
- pitchfork-dev-serversSkill
- pkexec-rootSkill
- planSkill
- release-oxlint-rulesSkill
- remote-change-diffSkill
- remove-single-use-functionsSkill
- researchSkill
- retroSkill
- review-stagesSkill
- review-steeringSkill
- session-coordinationSkill
- shared-workflowsSkill
- show-meSkill
- skill-prefixesSkill
- staged-implementationSkill
- task-focusSkill
- task-runnersSkill
- testingSkill
- to-questionnaireSkill
- types-enforce-tsSkill
- wranglerSkill
- writing-dot-skillsSkill
- writing-styleSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

