reticle stop reads the pid recorded for the port and stops that process. reticle stop --force asks who is listening on the port instead, and frees it.
reticle kill was removed. It prints that stop --force replaces it and exits 1.
Flags
How it stops
- Ask the daemon to stop with
POST /shutdownon loopback, with the pairing token. The daemon then runs its normal shutdown path on every OS, Windows included. An older daemon without the route, or a refused request, getsSIGTERMinstead. Then poll every 100ms. - Still alive after 5 seconds:
SIGKILL. A daemon that ignoresSIGTERMis wedged, which is the one situation this command exists for, and giving up there left the port held and a human reaching forkill -9. - Still alive 2 seconds after that: report
reticle_daemon_stop_timeoutwith the pid and exit1. SurvivingSIGKILLmeans the pid is not yours to kill, or it is an unkillable zombie. Neither is retryable.
What it prints
Real capture, stopping a port with no live pid recorded for it. It exits
0, because “already not running” is the state you asked for:
--quiet that same run prints nothing at all and still exits 0.
Exit codes
Freeing the port: --force
stop starts from the pid Reticle recorded. When that pid is dead or missing but a Reticle daemon still answers /status on the port (a stale pid file, or a daemon from another checkout), plain stop frees that listener the same way --force does. When nothing answers /status, plain stop reports reticle_daemon_not_running. stop --force always asks the port first, and is the command to reach for when the pid file and the port disagree.
How --force decides
- Look up the listener with
lsof -nP -iTCP:<port> -sTCP:LISTEN. Client sockets are excluded by construction, so the proxy is never a candidate. - It is Reticle’s if it answers
/status, or if it is the pid Reticle recorded for the port./statusoutranks the pid file, so a daemon started from another checkout is still recognised as ours. - Anything else is refused, by name: it is someone else’s process.
- For a Reticle daemon,
POST /shutdownfirst, as above; elseSIGTERM. ThenSIGKILLafter 5 seconds, then report that it survived and exit1.
What --force prints
Real captures, taken against a daemon started on a scratch port. The long note and reason strings are trimmed at the ellipsis. Measured exit codes: 0 for killed and nothing-to-do, 1 for refused.
Killed:
python3 -m http.server 4498 holding the port:
listenerIdentified: false means lsof could not run and the pid came from Reticle’s records rather than from an observed listener. Those are different claims, so the field says which one you got.
With --force, exit 0 means the port is free and 1 means it is still held: refused, or the process survived SIGKILL.