1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
//! tmux session side-effects for the cleanup sweep: probing, force-killing, and noting a kill.
//!
//! These are the real-world effects injected into [`super::reap_dir`] (which stays pure and
//! testable). Each is best-effort: a missing `tmux` binary or an already-gone session is never an
//! error, since the only thing that matters is whether a session is running afterwards.
use Path;
/// The `tmux` executable, overridable via `MOADIM_TMUX_BIN`. In test builds, when no override is
/// set, this resolves to a non-existent path so tmux probes/kills are harmless no-ops and tests
/// never touch the real tmux server. Mirrors the `MOADIM_CRONTAB_BIN` seam (#211).
///
/// Outside tests, resolves via [`super::super::command::resolve_tmux_bin`] rather than the bare
/// `"tmux"` name: launchd/systemd start the daemon with a minimal `PATH` that hides a Homebrew- or
/// npm-installed `tmux`, which used to make every probe here silently fail (read as "session
/// dead") — TTL-reaping a hung run's workbench while its tmux session and agent process kept
/// running, untracked, forever.
pub
/// Return `true` if a tmux session named `session` currently exists.
///
/// Uses an exact (`=`) target match so `moadim-foo-1` never matches `moadim-foo-10`. A missing
/// `tmux` binary (exit status unavailable) is treated as "not alive": with no tmux there is no
/// running session to protect, so an expired workbench is safe to reap.
pub
/// Return `true` if any tmux session whose name starts with `prefix` currently exists.
///
/// Unlike [`tmux_session_alive`]'s exact match, this is for the per-routine overlap guard (#514):
/// a routine's fires all share `{routine::command::tmux_session_prefix}` but differ by `$TS`, so
/// detecting "is a previous fire of this routine still running" means matching the prefix, not one
/// exact session name. A missing `tmux` binary, an empty session list, or a non-zero exit (no
/// server running) all read as "not alive" — mirroring `tmux_session_alive`'s "no tmux, nothing to
/// guard against" stance.
pub
/// Count how many live tmux sessions have a name starting with `prefix`.
///
/// Backs the global concurrency cap (#335): every routine's fires share the one
/// [`crate::routines::command::TMUX_SESSION_PREFIX`] (`"moadim-"`) regardless of which routine/slug
/// spawned them, so — unlike [`tmux_session_prefix_alive`]'s per-routine-fire prefix (which further
/// validates the trailing `$RID` shape) — a plain [`str::starts_with`] count over that shared prefix
/// is the total number of routine agent sessions alive right now. Derived from the same
/// `list-sessions` call each time it's needed (no cached/in-memory counter that could drift after a
/// crash). A missing `tmux` binary or non-zero exit (no server running) reads as `0`, mirroring
/// [`tmux_session_alive`]'s "no tmux, nothing running" stance.
pub
/// Return `true` if `name` is a tmux session name for *this* routine's `prefix`
/// (`moadim-{slug}-`), not merely a different routine whose slug happens to be a string-prefix of
/// this one's (e.g. slug `deploy` vs slug `deploy-staging`: `"moadim-deploy-"` is a literal prefix
/// of `"moadim-deploy-staging-<rid>"`). A plain [`str::starts_with`] treated that as a match,
/// falsely suppressing `deploy`'s own fire while an unrelated `deploy-staging` run was alive.
///
/// Requires the remainder after `prefix` to have the exact `$RID` shape `build_routine_command`
/// emits (`${TS}_$$`, i.e. `<digits>_<digits>`) rather than any suffix at all.
/// Force-kill the tmux session named `session` (best-effort).
///
/// Uses an exact (`=`) target match, mirroring [`tmux_session_alive`]. Failures (no `tmux`, session
/// already gone) are ignored: the goal is only that the session is not running afterwards.
pub
/// Record a watchdog kill in the run's `agent.log` *and* its `exit_code` file (best-effort).
///
/// `workbench` is the run directory. The human-readable note is appended to `agent.log` (the same
/// file the live session's output is piped to) so an operator reading the log sees why the session
/// ended. The machine-readable `killed` sentinel is written to `exit_code`, the same file a
/// normally-finishing run writes its numeric `$?` into (see `command::build_routine_command`); the
/// distinct sentinel keeps a watchdog-killed run from masquerading as a clean `0` exit. The kill
/// SIGKILLs the agent's pane before its own `echo $? > exit_code` can run, so there is no clobber.
pub