muse-crew 0.6.6 → 0.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,276 +0,0 @@
1
- #!/usr/bin/env bash
2
- # test-orphan-sweep.sh — regression tests for orphan-sweep.sh
3
- #
4
- # Self-contained: builds throwaway git fixtures in a temp dir and drives
5
- # lib/orphan-sweep.sh through the CREW_ACTIVE_TASKS / CREW_ACTIVE_TASKS_FILE
6
- # seam (no network, no dashboard). Exits 0 only if every case passes.
7
- #
8
- # Format contract: clean mode validates every active-set entry is a full
9
- # lowercase task UUID and exits 2 with a BLOCKED line otherwise (cases 9, 10).
10
- # Report mode has no format expectation and keeps current behavior.
11
-
12
- set -uo pipefail
13
-
14
- SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
15
- SWEEP="$SCRIPT_DIR/orphan-sweep.sh"
16
-
17
- pass=0
18
- fail=0
19
- ok() { echo "PASS: $1"; pass=$((pass + 1)); }
20
- no() { echo "FAIL: $1"; fail=$((fail + 1)); }
21
-
22
- TMPBASE="$(mktemp -d)"
23
- trap 'rm -rf "$TMPBASE"' EXIT
24
-
25
- # Keep merge-lock.sh's audit log out of the real $CREW_HOME during tests.
26
- export CREW_HOME="$TMPBASE/home"
27
-
28
- # new_fixture <name> — fresh git repo, one commit on main; exports CREW_REPO.
29
- new_fixture() {
30
- local dir="$TMPBASE/$1"
31
- mkdir -p "$dir"
32
- git init -q -b main "$dir" >/dev/null
33
- git -C "$dir" config user.email "test@example.com"
34
- git -C "$dir" config user.name "test"
35
- echo base > "$dir/seed.txt"
36
- git -C "$dir" add seed.txt
37
- git -C "$dir" commit -qm "initial"
38
- export CREW_REPO="$dir"
39
- cd "$dir" || exit 1
40
- }
41
-
42
- # merged_worktree <task_id> — worktree whose branch gets a real merge commit.
43
- merged_worktree() {
44
- local t="$1"
45
- git worktree add -q ".worktrees/$t" -b "task/$t" >/dev/null
46
- echo "$t" > ".worktrees/$t/work.txt"
47
- git -C ".worktrees/$t" add work.txt
48
- git -C ".worktrees/$t" commit -qm "work for $t"
49
- git merge -q --no-ff "task/$t" -m "merge $t" >/dev/null
50
- }
51
-
52
- # --- Case 1: live run protected (the incident's exact case) ---
53
- # Active-set fixtures must be full lowercase UUIDs: clean mode fails closed
54
- # (exit 2) on any active-set entry that is not one, and exact matching means
55
- # the worktree dir / lock holder / pin dir names use the same UUIDs.
56
- UUID_ACTIVE="8e951fb5-cddd-479f-87e9-9423539c08a3" # live-run guard + incident case
57
- UUID_LOCK="bc5a1654-cddd-479f-87e9-9423539c08a3" # merge-lock holder
58
- UUID_PIN="1c4b0e7b-cddd-479f-87e9-9423539c08a3" # lifecycle pin owner
59
- SHORT_ACTIVE="8e951fb5" # 8-char prefix of UUID_ACTIVE
60
- new_fixture case1
61
- git worktree add -q ".worktrees/$UUID_ACTIVE" -b "task/$UUID_ACTIVE" >/dev/null
62
- out=$(CREW_ACTIVE_TASKS="$UUID_ACTIVE" "$SWEEP" clean 2>&1); code=$?
63
- [ "$code" -eq 0 ] && ok "1: clean exits 0 with only an active run present" || no "1: exit $code, want 0"
64
- [ -d ".worktrees/$UUID_ACTIVE" ] && ok "1: active worktree dir preserved" || no "1: active worktree dir removed"
65
- git show-ref --verify --quiet "refs/heads/task/$UUID_ACTIVE" && ok "1: active branch preserved" || no "1: active branch deleted"
66
- echo "$out" | grep -q "ACTIVE: $UUID_ACTIVE" && ok "1: ACTIVE line printed" || no "1: no ACTIVE line in output"
67
-
68
- # --- Case 2: dead run cleaned ---
69
- new_fixture case2
70
- merged_worktree T2
71
- out=$(CREW_ACTIVE_TASKS="" "$SWEEP" clean 2>&1); code=$?
72
- [ "$code" -eq 0 ] && ok "2: clean exits 0" || no "2: exit $code, want 0"
73
- [ ! -d .worktrees/T2 ] && ok "2: merged worktree dir removed" || no "2: merged worktree dir still present"
74
- git show-ref --verify --quiet refs/heads/task/T2 && no "2: merged branch still present" || ok "2: merged branch deleted"
75
- echo "$out" | grep -q "→ removed" && ok "2: removal reported" || no "2: no removal line in output"
76
-
77
- # --- Case 3: fail closed ---
78
- new_fixture case3
79
- merged_worktree T3
80
- out=$(env -u CREW_ACTIVE_TASKS -u CREW_ACTIVE_TASKS_FILE "$SWEEP" clean 2>&1); code=$?
81
- [ "$code" -eq 2 ] && ok "3: clean without active data exits 2" || no "3: exit $code, want 2"
82
- echo "$out" | grep -q "BLOCKED" && ok "3: BLOCKED line printed" || no "3: no BLOCKED line in output"
83
- [ -d .worktrees/T3 ] && ok "3: worktree left alone (dir)" || no "3: worktree removed despite BLOCKED"
84
- git show-ref --verify --quiet refs/heads/task/T3 && ok "3: worktree left alone (branch)" || no "3: branch deleted despite BLOCKED"
85
-
86
- # --- Case 4: false report impossible (forced removal failure via worktree lock) ---
87
- new_fixture case4
88
- merged_worktree T4
89
- git worktree lock .worktrees/T4
90
- out=$(CREW_ACTIVE_TASKS="" "$SWEEP" clean 2>&1); code=$?
91
- [ "$code" -eq 1 ] && ok "4: clean with failed removal exits 1" || no "4: exit $code, want 1"
92
- echo "$out" | grep -q "→ FAILED" && ok "4: FAILED line printed (no false 'removed')" || no "4: no FAILED line — false report!"
93
- [ -d .worktrees/T4 ] && ok "4: failed worktree left in place" || no "4: worktree gone despite failed removal"
94
- git worktree unlock .worktrees/T4 2>/dev/null || true
95
-
96
- # --- Case 5: lock path (lease-based; bug 2fc8f52f) ---
97
- new_fixture case5
98
- mkdir -p .worktrees
99
- # 5a: expired lease, no running session → released (logged to the audit log).
100
- printf 'task_id=T5\nholder=T5/run-old\nacquired_at=1577836800\nlease_seconds=600\n' > .worktrees/.merge-lock
101
- out=$(CREW_ACTIVE_TASKS="" "$SWEEP" clean 2>&1); code=$?
102
- [ ! -f .worktrees/.merge-lock ] && ok "5a: expired-lease lock released" || no "5a: lock file still present"
103
- echo "$out" | grep -q "STALE_LOCK" && ok "5a: STALE_LOCK line printed" || no "5a: no STALE_LOCK line in output"
104
- echo "$out" | grep -q "released (lease expired)" && ok "5a: release reported" || no "5a: no release line in output"
105
- [ "$code" -eq 0 ] && ok "5a: exit 0" || no "5a: exit $code, want 0"
106
-
107
- # 5b: valid lease held by an active run → untouched regardless of lease age.
108
- now=$(date +%s)
109
- printf 'task_id=%s\nholder=%s/run-live\nacquired_at=%s\nlease_seconds=600\n' "$UUID_LOCK" "$UUID_LOCK" "$now" > .worktrees/.merge-lock
110
- out=$(CREW_ACTIVE_TASKS="$UUID_LOCK" "$SWEEP" clean 2>&1); code=$?
111
- [ -f .worktrees/.merge-lock ] && ok "5b: active holder's lock not released" || no "5b: active holder's lock was released"
112
- echo "$out" | grep -q "ACTIVE_LOCK" && ok "5b: ACTIVE_LOCK line printed" || no "5b: no ACTIVE_LOCK line in output"
113
- [ "$code" -eq 0 ] && ok "5b: exit 0" || no "5b: exit $code, want 0"
114
-
115
- # 5c: valid lease, no running session → held, NOT released (lease not expired).
116
- printf 'task_id=T6\nholder=T6/run-live\nacquired_at=%s\nlease_seconds=600\n' "$now" > .worktrees/.merge-lock
117
- out=$(CREW_ACTIVE_TASKS="" "$SWEEP" clean 2>&1); code=$?
118
- [ -f .worktrees/.merge-lock ] && ok "5c: unexpired-lease lock not released" || no "5c: unexpired-lease lock was released"
119
- echo "$out" | grep -q "HELD_LOCK" && ok "5c: HELD_LOCK line printed" || no "5c: no HELD_LOCK line in output"
120
- [ "$code" -eq 0 ] && ok "5c: exit 0" || no "5c: exit $code, want 0"
121
-
122
- # --- Case 6: report mode without active data ---
123
- new_fixture case6
124
- merged_worktree T7
125
- out=$(env -u CREW_ACTIVE_TASKS -u CREW_ACTIVE_TASKS_FILE "$SWEEP" report 2>&1); code=$?
126
- [ "$code" -eq 0 ] && ok "6: report exits 0" || no "6: exit $code, want 0"
127
- echo "$out" | grep -q "NOTE: no active-run data provided; ACTIVE checks skipped" && ok "6: NOTE banner printed" || no "6: no NOTE banner in output"
128
- [ -d .worktrees/T7 ] && ok "6: report mode removes nothing" || no "6: report mode removed a worktree"
129
- echo "$out" | grep -q "MERGED: T7" && ok "6: MERGED line still listed" || no "6: MERGED line missing from report"
130
-
131
- # --- Case 7: lifecycle pins — active kept, stale reaped ---
132
- # A stale pin now needs ORPHAN_SWEEP_REAP_AFTER consecutive observations;
133
- # set 1 here to exercise the immediate-reap path directly.
134
- new_fixture case7
135
- export CREW_HOME="$TMPBASE/case7home"
136
- mkdir -p "$CREW_HOME/.pins/$UUID_PIN" "$CREW_HOME/.pins/STALEPIN"
137
- echo x > "$CREW_HOME/.pins/$UUID_PIN/worktree-lifecycle.sh"
138
- echo x > "$CREW_HOME/.pins/STALEPIN/worktree-lifecycle.sh"
139
- out=$(CREW_ACTIVE_TASKS="$UUID_PIN" ORPHAN_SWEEP_REAP_AFTER=1 "$SWEEP" clean 2>&1); code=$?
140
- [ "$code" -eq 0 ] && ok "7: clean exits 0 with pins present" || no "7: exit $code, want 0"
141
- [ -d "$CREW_HOME/.pins/$UUID_PIN" ] && ok "7: active task's pin kept" || no "7: active task's pin removed"
142
- [ ! -d "$CREW_HOME/.pins/STALEPIN" ] && ok "7: stale pin removed" || no "7: stale pin still present"
143
- echo "$out" | grep -q "ACTIVE_PIN: $UUID_PIN" && ok "7: ACTIVE_PIN line printed" || no "7: no ACTIVE_PIN line in output"
144
- echo "$out" | grep -q "STALE_PIN: STALEPIN" && ok "7: STALE_PIN line printed" || no "7: no STALE_PIN line in output"
145
- [ "$code" -eq 0 ] && ok "7: clean exits 0 with pins present" || no "7: exit $code, want 0"
146
- [ -d "$CREW_HOME/.pins/$UUID_PIN" ] && ok "7: active task's pin kept" || no "7: active task's pin removed"
147
- [ ! -d "$CREW_HOME/.pins/STALEPIN" ] && ok "7: stale pin removed" || no "7: stale pin still present"
148
- echo "$out" | grep -q "ACTIVE_PIN: $UUID_PIN" && ok "7: ACTIVE_PIN line printed" || no "7: no ACTIVE_PIN line in output"
149
- echo "$out" | grep -q "STALE_PIN: STALEPIN" && ok "7: STALE_PIN line printed" || no "7: no STALE_PIN line in output"
150
-
151
- # --- Case 8: pins — report mode removes nothing; clean without active data fails closed ---
152
- new_fixture case8
153
- export CREW_HOME="$TMPBASE/case8home"
154
- mkdir -p "$CREW_HOME/.pins/R1"
155
- out=$(CREW_ACTIVE_TASKS="" "$SWEEP" report 2>&1); code=$?
156
- [ "$code" -eq 0 ] && ok "8a: report exits 0" || no "8a: exit $code, want 0"
157
- [ -d "$CREW_HOME/.pins/R1" ] && ok "8a: report mode removes no pins" || no "8a: report mode removed a pin"
158
- echo "$out" | grep -q "STALE_PIN: R1" && ok "8a: STALE_PIN listed in report" || no "8a: STALE_PIN missing from report"
159
-
160
- out=$(env -u CREW_ACTIVE_TASKS -u CREW_ACTIVE_TASKS_FILE "$SWEEP" clean 2>&1); code=$?
161
- [ "$code" -eq 2 ] && ok "8b: clean without active data exits 2" || no "8b: exit $code, want 2"
162
- [ -d "$CREW_HOME/.pins/R1" ] && ok "8b: pin left alone when BLOCKED" || no "8b: pin removed despite BLOCKED"
163
-
164
- # --- Case 9: fail closed on a short ID in CREW_ACTIVE_TASKS (the incident) ---
165
- # The sweep worker once passed 8-char prefixes; the guard would never match
166
- # them exactly, so clean must refuse instead of silently defeating the
167
- # active-run guard.
168
- new_fixture case9
169
- export CREW_HOME="$TMPBASE/case9home"
170
- merged_worktree "$UUID_ACTIVE"
171
- mkdir -p "$CREW_HOME/.pins/$UUID_ACTIVE"
172
- out=$(CREW_ACTIVE_TASKS="$SHORT_ACTIVE" "$SWEEP" clean 2>&1); code=$?
173
- [ "$code" -eq 2 ] && ok "9: short ID in CREW_ACTIVE_TASKS exits 2" || no "9: exit $code, want 2"
174
- echo "$out" | grep -q "BLOCKED" && ok "9: BLOCKED line printed" || no "9: no BLOCKED line in output"
175
- echo "$out" | grep -q "$SHORT_ACTIVE" && ok "9: BLOCKED line names the bad entry" || no "9: BLOCKED line does not name the entry"
176
- [ -d ".worktrees/$UUID_ACTIVE" ] && ok "9: worktree preserved" || no "9: worktree removed despite BLOCKED"
177
- git show-ref --verify --quiet "refs/heads/task/$UUID_ACTIVE" && ok "9: branch preserved" || no "9: branch deleted despite BLOCKED"
178
- [ -d "$CREW_HOME/.pins/$UUID_ACTIVE" ] && ok "9: pin preserved" || no "9: pin removed despite BLOCKED"
179
-
180
- # --- Case 10: fail closed on a short ID in CREW_ACTIVE_TASKS_FILE ---
181
- new_fixture case10
182
- export CREW_HOME="$TMPBASE/case10home"
183
- merged_worktree "$UUID_ACTIVE"
184
- mkdir -p "$CREW_HOME/.pins/$UUID_ACTIVE"
185
- printf '%s\n' "$SHORT_ACTIVE" > "$TMPBASE/case10-active.txt"
186
- out=$(env -u CREW_ACTIVE_TASKS CREW_ACTIVE_TASKS_FILE="$TMPBASE/case10-active.txt" "$SWEEP" clean 2>&1); code=$?
187
- [ "$code" -eq 2 ] && ok "10: short ID in CREW_ACTIVE_TASKS_FILE exits 2" || no "10: exit $code, want 2"
188
- echo "$out" | grep -q "BLOCKED" && ok "10: BLOCKED line printed" || no "10: no BLOCKED line in output"
189
- echo "$out" | grep -q "$SHORT_ACTIVE" && ok "10: BLOCKED line names the bad entry" || no "10: no BLOCKED line naming the entry"
190
- [ -d ".worktrees/$UUID_ACTIVE" ] && ok "10: worktree preserved" || no "10: worktree removed despite BLOCKED"
191
- git show-ref --verify --quiet "refs/heads/task/$UUID_ACTIVE" && ok "10: branch preserved" || no "10: branch deleted despite BLOCKED"
192
- [ -d "$CREW_HOME/.pins/$UUID_ACTIVE" ] && ok "10: pin preserved" || no "10: pin removed despite BLOCKED"
193
-
194
- # --- Case 11: one bad observation doesn't reap (the incident's exact case) ---
195
- # REAP_AFTER=2: first clean with the task absent only plants a tombstone;
196
- # the second consecutive absence reaps the pin and clears the marker.
197
- UUID_TOMB="3472bf36-1549-44bd-bc06-e0c80aef0007"
198
- new_fixture case11
199
- export CREW_HOME="$TMPBASE/case11home"
200
- mkdir -p "$CREW_HOME/.pins/$UUID_TOMB"
201
- echo x > "$CREW_HOME/.pins/$UUID_TOMB/worktree-lifecycle.sh"
202
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
203
- [ "$code" -eq 0 ] && ok "11: first clean exits 0" || no "11: first clean exit $code, want 0"
204
- [ -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "11: pin intact after one bad observation" || no "11: pin reaped after ONE observation — the bug"
205
- echo "$out" | grep -q "SUSPECT_PIN: $UUID_TOMB — no running session (observation 1/2)" && ok "11: SUSPECT_PIN 1/2 line printed" || no "11: no SUSPECT_PIN 1/2 line in output"
206
- [ "$(cat "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" 2>/dev/null)" = "1" ] && ok "11: tombstone marker holds count 1" || no "11: tombstone marker missing or wrong"
207
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
208
- [ "$code" -eq 0 ] && ok "11: second clean exits 0" || no "11: second clean exit $code, want 0"
209
- [ ! -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "11: pin reaped after second consecutive absence" || no "11: pin still present after two observations"
210
- echo "$out" | grep -q "no running session for 2 consecutive observations" && ok "11: reap line cites consecutive observations" || no "11: no consecutive-observations line in output"
211
- [ ! -f "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" ] && ok "11: marker removed after reap" || no "11: marker left behind after reap"
212
-
213
- # --- Case 12: recovery clears the tombstone ---
214
- new_fixture case12
215
- export CREW_HOME="$TMPBASE/case12home"
216
- mkdir -p "$CREW_HOME/.pins/$UUID_TOMB"
217
- echo x > "$CREW_HOME/.pins/$UUID_TOMB/worktree-lifecycle.sh"
218
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
219
- [ "$(cat "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" 2>/dev/null)" = "1" ] && ok "12: tombstone planted on first absence" || no "12: no tombstone after first absence"
220
- out=$(CREW_ACTIVE_TASKS="$UUID_TOMB" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
221
- [ "$code" -eq 0 ] && ok "12: recovery clean exits 0" || no "12: recovery clean exit $code, want 0"
222
- [ -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "12: pin intact after recovery" || no "12: pin removed despite task being active"
223
- [ ! -f "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" ] && ok "12: tombstone cleared on recovery" || no "12: tombstone left behind after recovery"
224
- echo "$out" | grep -q "ACTIVE_PIN: $UUID_TOMB" && ok "12: ACTIVE_PIN line printed" || no "12: no ACTIVE_PIN line in output"
225
-
226
- # --- Case 13: report mode never counts as an observation ---
227
- new_fixture case13
228
- export CREW_HOME="$TMPBASE/case13home"
229
- mkdir -p "$CREW_HOME/.pins/$UUID_TOMB"
230
- echo x > "$CREW_HOME/.pins/$UUID_TOMB/worktree-lifecycle.sh"
231
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
232
- [ "$(cat "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" 2>/dev/null)" = "1" ] && ok "13: tombstone planted by clean" || no "13: no tombstone after clean"
233
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" report 2>&1); code=$?
234
- [ "$code" -eq 0 ] && ok "13: report exits 0" || no "13: report exit $code, want 0"
235
- [ "$(cat "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" 2>/dev/null)" = "1" ] && ok "13: marker still 1 after report" || no "13: report mode counted as an observation"
236
- [ -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "13: pin intact after report" || no "13: report mode removed a pin"
237
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
238
- [ ! -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "13: report did not advance the count (second clean reaps at 2/2)" || no "13: pin not reaped after two clean observations"
239
-
240
- # --- Case 14: BLOCKED (no active data) never counts as an observation ---
241
- new_fixture case14
242
- export CREW_HOME="$TMPBASE/case14home"
243
- mkdir -p "$CREW_HOME/.pins/$UUID_TOMB"
244
- echo x > "$CREW_HOME/.pins/$UUID_TOMB/worktree-lifecycle.sh"
245
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
246
- [ "$(cat "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" 2>/dev/null)" = "1" ] && ok "14: tombstone planted by clean" || no "14: no tombstone after clean"
247
- out=$(env -u CREW_ACTIVE_TASKS -u CREW_ACTIVE_TASKS_FILE ORPHAN_SWEEP_REAP_AFTER=2 "$SWEEP" clean 2>&1); code=$?
248
- [ "$code" -eq 2 ] && ok "14: clean without active data exits 2" || no "14: exit $code, want 2"
249
- echo "$out" | grep -q "BLOCKED" && ok "14: BLOCKED line printed" || no "14: no BLOCKED line in output"
250
- [ "$(cat "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" 2>/dev/null)" = "1" ] && ok "14: marker still 1 after BLOCKED" || no "14: BLOCKED counted as an observation"
251
- [ -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "14: pin intact after BLOCKED" || no "14: pin removed despite BLOCKED"
252
-
253
- # --- Case 15: markers for pins that no longer exist are pruned ---
254
- new_fixture case15
255
- export CREW_HOME="$TMPBASE/case15home"
256
- mkdir -p "$CREW_HOME/.pins/.sweep-suspects"
257
- printf '1\n' > "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" # pin dir gone (run cleaned it up itself)
258
- out=$(CREW_ACTIVE_TASKS="" "$SWEEP" clean 2>&1); code=$?
259
- [ "$code" -eq 0 ] && ok "15: clean exits 0" || no "15: exit $code, want 0"
260
- [ ! -f "$CREW_HOME/.pins/.sweep-suspects/$UUID_TOMB" ] && ok "15: orphaned marker pruned" || no "15: orphaned marker still present"
261
-
262
- # --- Case 16: invalid ORPHAN_SWEEP_REAP_AFTER fails closed ---
263
- new_fixture case16
264
- export CREW_HOME="$TMPBASE/case16home"
265
- mkdir -p "$CREW_HOME/.pins/$UUID_TOMB"
266
- echo x > "$CREW_HOME/.pins/$UUID_TOMB/worktree-lifecycle.sh"
267
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=foo "$SWEEP" clean 2>&1); code=$?
268
- [ "$code" -eq 2 ] && ok "16: non-numeric override exits 2" || no "16: exit $code, want 2"
269
- echo "$out" | grep -q "BLOCKED" && ok "16: BLOCKED line printed" || no "16: no BLOCKED line in output"
270
- [ -d "$CREW_HOME/.pins/$UUID_TOMB" ] && ok "16: pin untouched on invalid override" || no "16: pin removed despite invalid override"
271
- out=$(CREW_ACTIVE_TASKS="" ORPHAN_SWEEP_REAP_AFTER=0 "$SWEEP" clean 2>&1); code=$?
272
- [ "$code" -eq 2 ] && ok "16: zero override exits 2" || no "16: zero override exit $code, want 2"
273
-
274
- echo ""
275
- echo "== $pass passed, $fail failed =="
276
- [ "$fail" -eq 0 ]
@@ -1,11 +0,0 @@
1
- ## Muse Crew Orphan Sweep
2
-
3
- 1. Call artifact_invoke_action on slug "{dashboardSlug}", action "getdispatchstate", args {}.
4
- 2. From the response, extract the `id` field of each `ready_tasks` entry whose
5
- latest_session.status is "running", verbatim — copy the full ID exactly
6
- as it appears; do not shorten, truncate, or reformat it. Return them as a
7
- JSON array of strings. Do NOT reproduce any other part of the response.
8
- (Sessions older than 1h are already reclassified as timed_out by the dashboard — no extra math.)
9
- 3. Run: CREW_ACTIVE_TASKS="<space-separated ids>" {crewHome}/lib/orphan-sweep.sh clean
10
- If the list is empty, pass an empty string — do NOT omit the variable (the sweep fails closed without it).
11
- 4. Report the output. If it says CLEAN, no action was needed.