Why It Exists

witr treats everything as a process question. Ports, services, containers and commands all eventually map to a PID. Once witr has a PID, it builds the chain that explains why that PID exists right now.

systemd (pid 1) → pm2 (pid 5034) → node (pid 14233)

Read it left to right: init started pm2, pm2 started your node process. If pm2 is what keeps it alive, killing the node process will not help you — it will come back.

The four questions behind the chain#

  1. What is running? The executable, its PID, the user, the full command line.
  2. How did it start? The ancestry chain from init down to the target.
  3. What is keeping it running? The supervisor or service manager responsible — see Sources.
  4. What context does it belong to? Working directory, git repository, container, bind address.

Why not just read the parent PID#

A parent PID is one hop. It tells you sh started node, which is usually the least interesting fact available. The chain is what carries the answer, because the thing that will restart your process is rarely its direct parent.

On a shell-launched process, the chain also survives detail that ppid loses:

systemd (pid 1)
  └─ init-systemd(Ub (pid 2)
    └─ SessionLeader (pid 143858)
      └─ Relay(143860) (pid 143859)
        └─ bash (pid 143860)
          └─ sh (pid 143886)
            └─ node (pid 143895)
              ├─ node (pid 143930)
              ├─ node (pid 144189)
              └─ node (pid 144234)

That is --tree output. It adds children (up to 10) below the target and highlights the process you asked about.

Best effort, stated explicitly#

Some links in a chain cannot be recovered on every platform — a process whose parent already exited, an environment variable behind macOS SIP restrictions, a container runtime that is not on PATH. witr shows what it can determine and says where it is uncertain rather than inventing a confident answer.

See also: Sources and Supervisors and Warnings.