fleetd #521: extract should_swap so the swap guard can't be silently disabled #526

Merged
ltms merged 2 commits from worker/521-swap-guard-unpinned-28e931-5 into main 2026-09-12 07:01:55 +02:00
Member

fleetd #521 — the swap step's guard was unpinned the same way #517's drain-gate abort branch was: test_swap_ordered_after_wait_and_before_start only checks source POSITIONS, so mutating if [ "$DO_BUILD" = 1 ] (the swap guard) to if false leaves every line position unchanged and the whole suite green.

Fix

Extracted the decision into should_swap(do_build) (same shape as #510's wait_for_daemon_exit and #517's drain_gate_refusal), with the main flow now calling if should_swap "$DO_BUILD"; then .... Added test_should_swap_true_when_build_ran and test_should_swap_false_when_build_skipped, which call the function directly.

Acceptance checks (real output)

1. bash scripts/test-redeploy-fleetd.sh exits 0.
Test functions: 42 defined, 42 invoked (grep -cE '^test_[a-zA-Z_]+\(\) \{' and grep -cE '^test_[a-zA-Z_]+$' — was 40/40 on main at c71ac23, +2 for the new tests). Ran under both /bin/bash and env bash; both exit 0 with only the three internal mutation-cell lines (Recovery mutation: FAIL: …, Shared-counter mutation: FAIL: …, Unattributable mutation: FAIL: …) — no line matching ^FAIL:.

2. bash -n on both scripts, both bash versions.
/bin/bash (3.2.57) and env bash (5.3.9): bash -n scripts/redeploy-fleetd.sh and bash -n scripts/test-redeploy-fleetd.sh all exit 0.

3. The reported mutation is killed.

  • Reproduced the original PoC against pristine main@c71ac23 first: mutating line 723's if [ "$DO_BUILD" = 1 ]; then (the swap guard) to if false; then left the suite green (exit 0, no ^FAIL:) — confirms the ticket's finding before touching anything.
  • After my fix, the equivalent mutation moves inside should_swap. I mutated its body ([ "$do_build" = 1 ] → false, i.e. "never swap regardless of $DO_BUILD" — the same observable effect as the original PoC) and reran the suite:
    FAIL: should_swap 1 (a build ran and staged a jar) must return true, exit 1.
  • Restored, diff against the pre-mutation copy showed no difference, and a control run was green again (exit 0, only the three internal mutation-cell lines).
  • Caveat for review: I also tried mutating the new call site itself (if should_swap "$DO_BUILD"; then → if false; then, the literal same transformation as the ticket's original PoC, now one line down at :739) — the suite stayed green. test_should_swap_* only calls the function directly and never proves the main-flow if still invokes it; test_swap_ordered_after_wait_and_before_start only checks the positions of three other lines (wait_for_daemon_exit, swap_staged_jar, say "start"), none of which move under this mutation. This is the identical residual gap already present in #517's precedent (nothing proves the drain gate's own if [ "$reply" != "yes" ] call site is reached, either) — I did not fix it, since the ticket's ask was specifically "extract the decision + a test per value," matching the existing precedent shape, and this residual risk is structural to the sourced-testing boundary (the main flow after the SOURCED guard can never be driven end-to-end by this harness). Flagging it rather than silently living with it.

4. Mutation-applied proof (two greps, different strings, single-quoted; plus re-read).
For the primary (function-level) mutation:

  • mutant present: grep -n '^ false$' scripts/redeploy-fleetd.sh → 194: false
  • original gone at that line: grep -n '\[ "\$do_build" = 1 \]' scripts/redeploy-fleetd.sh → only matches line 490 (a different function's own do_build parameter, unrelated) — confirmed by direct re-read of lines 192-195 showing false in the body.
  • 0/1 never 0/0, and re-read via sed -n '192,195p' confirmed directly.

5. Pristine-hash checks.
Confirmed scripts/redeploy-fleetd.sh on main@c71ac23 hashed to 2cb83dc380c7226191d657c40fccdfc856904e40b2d03d0851fb6e522cee2f41 (matches the ticket) before any edits. Every restore during mutation testing was verified with diff against a saved pre-mutation copy (byte-identical each time).

Part 2 — does anything later report a differing jar id?

Traced with the swap guard disabled:

  • stage_built_jar (unconditional, in the build step — unaffected by the swap-guard mutation) always moves the freshly built jar off $JAR onto $JAR_STAGED the moment the build succeeds. So by the time the swap step is reached, $JAR (the live path) is already absent, regardless of the mutation.
  • I sourced the script and traced this directly (fake $JAR/$JAR_STAGED under a temp dir, no daemon touched): after stage_built_jar, jar_id (bare) reports absent, not a stale hash. If the script somehow reached the final ok "pid $NEW_PID, jar $(jar_id)" line (:865 in the current file), it would print jar absent — which would be noticeable, being a different word rather than a stale-looking hash.
  • But it cannot reach that line under this mutation. java -jar <missing-file> fails immediately (Error: Unable to access jarfile ..., exit 1 — confirmed generically on this box against a nonexistent path, no fleetd daemon involved). So starting a daemon whose jar was moved away and never swapped back fails to produce a lasting process. The script's own gates catch this before the final report: either [ -n "${NEW_PID:-}" ] || die "no process appeared. Last lines of $OUT: ..." (unsupervised case, most likely outcome — java exits near-instantly), or, if a supervisor's restart loop happens to let pgrep catch a transient pid, /healthz never answered within ${HEALTH_WAIT}s after up to 60s of polling (the health endpoint can never come up, since no jar is running).

Answer: No — nothing downstream reports a misleading jar id, because the run cannot reach the final report line at all; it dies loudly first, at "no process appeared" or "/healthz never answered", both of which print the tail of the daemon's own log. This is a real, visible failure, just not the one the removed ok "jar in place: ..." line would have given, and not the "silent success" outcome I could not rule out without checking. I did not run this against the live daemon (prohibited); this is based on reading the script's control flow, a generic (non-fleetd) java -jar <missing> test, and a sourced-script trace of the jar-file state — not a live redeploy.

Part 3 — sweep for the "grep-only test" shape (not fixed)

Searched the whole test file for every test that inspects redeploy-fleetd.sh's own source text/position (grep -n '\$src\|ROOT/scripts/redeploy-fleetd.sh"' scripts/test-redeploy-fleetd.sh, excluding the source re-imports). Found exactly two, both already known:

  • test_swap_ordered_after_wait_and_before_start (position-only; now supplemented by the new should_swap tests, kept per the ticket)
  • test_drain_gate_abort_message_says_no_no_build (wording-only; already supplemented by #517/#520's direct drain_gate_refusal tests)

No third "the only test is a grep of the script's own source" instance exists in the test file today.

That said, the same underlying weakness (a main-flow decision, past the SOURCED guard, that this harness cannot drive end-to-end) shows up more broadly as branches with no test of any kind — not even a grep. Listed for awareness, not fixed:

  • :611 if [ "$CHECK_ONLY" = 1 ] (skip mutating flow entirely) — no test.
  • :648 if [ -n "$OLD_PID" ] && [ "$ASSUME_YES" = 0 ] (drain-gate's own entry condition — whether the prompt fires at all) — no test; drain_gate_refusal()'s message is tested directly, but nothing proves this outer gate, or the if [ "$reply" != "yes" ] die call site inside it, is reached.
  • :549 case "$SUPERVISOR_KIND" in ... (report-state, display only) — no test.
  • :681 case "$SUPERVISOR_KIND" in ... (stop-step dispatch: launchctl unload / systemctl --user stop / kill) — no test of the dispatch itself.
  • :756 case "$SUPERVISOR_KIND" in ... (start-step dispatch: launchctl load / systemctl --user start / nohup java) — no test.
  • :820 if [ -z "$HEALTH_BODY" ] (healthz body vs. 503 vs. die) — no test.
  • :866 if [ "$REDEPLOY_ERROR_COUNT" -eq 0 ] (result-summary ok/warn) — no test (the counters it reads are tested; this display decision built on them is not).

Not fixing any of these — reporting per the ticket's ask to name the shape, not chase every instance.

Build / checks

  • bash scripts/test-redeploy-fleetd.sh — exit 0, both bash versions, 42/42 test functions, no ^FAIL: lines.
  • bash -n — exit 0, both scripts, both bash versions.
  • No mvn build involved — this ticket only touches shell scripts.

Files changed

  • scripts/redeploy-fleetd.sh — added should_swap(do_build), changed the swap guard call site to use it.
  • scripts/test-redeploy-fleetd.sh — added test_should_swap_true_when_build_ran and test_should_swap_false_when_build_skipped, registered both in the run list.
fleetd #521 — the swap step's guard was unpinned the same way #517's drain-gate abort branch was: `test_swap_ordered_after_wait_and_before_start` only checks source POSITIONS, so mutating `if [ "$DO_BUILD" = 1 ]` (the swap guard) to `if false` leaves every line position unchanged and the whole suite green. ## Fix Extracted the decision into `should_swap(do_build)` (same shape as #510's `wait_for_daemon_exit` and #517's `drain_gate_refusal`), with the main flow now calling `if should_swap "$DO_BUILD"; then ...`. Added `test_should_swap_true_when_build_ran` and `test_should_swap_false_when_build_skipped`, which call the function directly. ## Acceptance checks (real output) **1. `bash scripts/test-redeploy-fleetd.sh` exits 0.** Test functions: 42 defined, 42 invoked (`grep -cE '^test_[a-zA-Z_]+\(\) \{'` and `grep -cE '^test_[a-zA-Z_]+$'` — was 40/40 on `main` at c71ac23, +2 for the new tests). Ran under both `/bin/bash` and `env bash`; both exit 0 with only the three internal mutation-cell lines (`Recovery mutation: FAIL: …`, `Shared-counter mutation: FAIL: …`, `Unattributable mutation: FAIL: …`) — no line matching `^FAIL:`. **2. `bash -n` on both scripts, both bash versions.** `/bin/bash` (3.2.57) and `env bash` (5.3.9): `bash -n scripts/redeploy-fleetd.sh` and `bash -n scripts/test-redeploy-fleetd.sh` all exit 0. **3. The reported mutation is killed.** - Reproduced the *original* PoC against pristine `main`@c71ac23 first: mutating line 723's `if [ "$DO_BUILD" = 1 ]; then` (the swap guard) to `if false; then` left the suite green (exit 0, no `^FAIL:`) — confirms the ticket's finding before touching anything. - After my fix, the equivalent mutation moves inside `should_swap`. I mutated its body (`[ "$do_build" = 1 ]` → `false`, i.e. "never swap regardless of $DO_BUILD" — the same observable effect as the original PoC) and reran the suite: `FAIL: should_swap 1 (a build ran and staged a jar) must return true`, exit 1. - Restored, `diff` against the pre-mutation copy showed no difference, and a control run was green again (exit 0, only the three internal mutation-cell lines). - **Caveat for review:** I also tried mutating the new *call site* itself (`if should_swap "$DO_BUILD"; then` → `if false; then`, the literal same transformation as the ticket's original PoC, now one line down at :739) — the suite **stayed green**. `test_should_swap_*` only calls the function directly and never proves the main-flow `if` still invokes it; `test_swap_ordered_after_wait_and_before_start` only checks the positions of three *other* lines (`wait_for_daemon_exit`, `swap_staged_jar`, `say "start"`), none of which move under this mutation. This is the identical residual gap already present in #517's precedent (nothing proves the drain gate's own `if [ "$reply" != "yes" ]` call site is reached, either) — I did not fix it, since the ticket's ask was specifically "extract the decision + a test per value," matching the existing precedent shape, and this residual risk is structural to the sourced-testing boundary (the main flow after the `SOURCED` guard can never be driven end-to-end by this harness). Flagging it rather than silently living with it. **4. Mutation-applied proof (two greps, different strings, single-quoted; plus re-read).** For the primary (function-level) mutation: - mutant present: `grep -n '^ false$' scripts/redeploy-fleetd.sh` → `194: false` - original gone at that line: `grep -n '\[ "\$do_build" = 1 \]' scripts/redeploy-fleetd.sh` → only matches line 490 (a *different* function's own `do_build` parameter, unrelated) — confirmed by direct re-read of lines 192-195 showing `false` in the body. - 0/1 never 0/0, and re-read via `sed -n '192,195p'` confirmed directly. **5. Pristine-hash checks.** Confirmed `scripts/redeploy-fleetd.sh` on `main`@c71ac23 hashed to `2cb83dc380c7226191d657c40fccdfc856904e40b2d03d0851fb6e522cee2f41` (matches the ticket) before any edits. Every restore during mutation testing was verified with `diff` against a saved pre-mutation copy (byte-identical each time). ## Part 2 — does anything later report a differing jar id? Traced with the swap guard disabled: - `stage_built_jar` (unconditional, in the *build* step — unaffected by the swap-guard mutation) always moves the freshly built jar off `$JAR` onto `$JAR_STAGED` the moment the build succeeds. So by the time the swap step is reached, `$JAR` (the live path) is *already absent*, regardless of the mutation. - I sourced the script and traced this directly (fake `$JAR`/`$JAR_STAGED` under a temp dir, no daemon touched): after `stage_built_jar`, `jar_id` (bare) reports `absent`, not a stale hash. If the script somehow reached the final `ok "pid $NEW_PID, jar $(jar_id)"` line (:865 in the current file), it would print `jar absent` — which *would* be noticeable, being a different word rather than a stale-looking hash. - But it cannot reach that line under this mutation. `java -jar <missing-file>` fails immediately (`Error: Unable to access jarfile ...`, exit 1 — confirmed generically on this box against a nonexistent path, no fleetd daemon involved). So starting a daemon whose jar was moved away and never swapped back fails to produce a lasting process. The script's own gates catch this *before* the final report: either `[ -n "${NEW_PID:-}" ] || die "no process appeared. Last lines of $OUT: ..."` (unsupervised case, most likely outcome — java exits near-instantly), or, if a supervisor's restart loop happens to let `pgrep` catch a transient pid, `/healthz never answered within ${HEALTH_WAIT}s` after up to 60s of polling (the health endpoint can never come up, since no jar is running). **Answer:** No — nothing downstream reports a *misleading* jar id, because the run cannot reach the final report line at all; it dies loudly first, at "no process appeared" or "/healthz never answered", both of which print the tail of the daemon's own log. This is a real, visible failure, just not the one the removed `ok "jar in place: ..."` line would have given, and not the "silent success" outcome I could not rule out without checking. I did not run this against the live daemon (prohibited); this is based on reading the script's control flow, a generic (non-fleetd) `java -jar <missing>` test, and a sourced-script trace of the jar-file state — not a live redeploy. ## Part 3 — sweep for the "grep-only test" shape (not fixed) Searched the whole test file for every test that inspects `redeploy-fleetd.sh`'s own source text/position (`grep -n '\$src\|ROOT/scripts/redeploy-fleetd.sh"' scripts/test-redeploy-fleetd.sh`, excluding the `source` re-imports). Found exactly two, both already known: - `test_swap_ordered_after_wait_and_before_start` (position-only; now supplemented by the new `should_swap` tests, kept per the ticket) - `test_drain_gate_abort_message_says_no_no_build` (wording-only; already supplemented by #517/#520's direct `drain_gate_refusal` tests) No third "the only test is a grep of the script's own source" instance exists in the test file today. That said, the same underlying weakness (a main-flow decision, past the `SOURCED` guard, that this harness cannot drive end-to-end) shows up more broadly as branches with **no test of any kind** — not even a grep. Listed for awareness, not fixed: - `:611` `if [ "$CHECK_ONLY" = 1 ]` (skip mutating flow entirely) — no test. - `:648` `if [ -n "$OLD_PID" ] && [ "$ASSUME_YES" = 0 ]` (drain-gate's own entry condition — whether the prompt fires at all) — no test; `drain_gate_refusal()`'s message is tested directly, but nothing proves this *outer* gate, or the `if [ "$reply" != "yes" ]` `die` call site inside it, is reached. - `:549` `case "$SUPERVISOR_KIND" in ...` (report-state, display only) — no test. - `:681` `case "$SUPERVISOR_KIND" in ...` (stop-step dispatch: `launchctl unload` / `systemctl --user stop` / `kill`) — no test of the dispatch itself. - `:756` `case "$SUPERVISOR_KIND" in ...` (start-step dispatch: `launchctl load` / `systemctl --user start` / `nohup java`) — no test. - `:820` `if [ -z "$HEALTH_BODY" ]` (healthz body vs. 503 vs. die) — no test. - `:866` `if [ "$REDEPLOY_ERROR_COUNT" -eq 0 ]` (result-summary ok/warn) — no test (the counters it reads are tested; this display decision built on them is not). Not fixing any of these — reporting per the ticket's ask to name the shape, not chase every instance. ## Build / checks - `bash scripts/test-redeploy-fleetd.sh` — exit 0, both bash versions, 42/42 test functions, no `^FAIL:` lines. - `bash -n` — exit 0, both scripts, both bash versions. - No `mvn` build involved — this ticket only touches shell scripts. ## Files changed - `scripts/redeploy-fleetd.sh` — added `should_swap(do_build)`, changed the swap guard call site to use it. - `scripts/test-redeploy-fleetd.sh` — added `test_should_swap_true_when_build_ran` and `test_should_swap_false_when_build_skipped`, registered both in the run list.
agent added 1 commit 2026-09-12 06:44:17 +02:00
fleetd #521: extract should_swap so the swap guard can't be silently disabled
CI / contract (pull_request) Successful in 1m29s
CI / build (pull_request) Successful in 1m29s
c89a375e5d
Mutating the swap step's guard (if [ "$DO_BUILD" = 1 ] -> if false) left the
whole test suite green: test_swap_ordered_after_wait_and_before_start only
checks source positions, which an in-place if-condition edit never moves.
Extracts the decision into should_swap(do_build), following the same shape as
#510's wait_for_daemon_exit and #517's drain_gate_refusal, with a direct test
for each value.
agent added 1 commit 2026-09-12 06:58:39 +02:00
fleetd #521 gate fix: pin the swap at the call site, not just the predicate
CI / contract (pull_request) Successful in 54s
CI / build (pull_request) Successful in 2m11s
08771e270b
The extraction in the previous commit did what #521 asked for — a
should_swap() predicate with a test for each value — and I measured that
it does not close the defect. With the main flow reading
`if should_swap "$DO_BUILD"; then`, changing that line to `if false; then`
left the whole suite at exit 0 with zero FAIL lines. The swap still never
ran, and a redeploy would still report success while starting on no jar.

That is my ticket's fault, not the implementer's: "extract the decision so
the suite can call it" pins the decision and never the wiring. Extraction
moved the untested decision up one level instead of removing it.

Fix: the decision and the action now live together in swap_if_built(),
which the main flow calls unconditionally — there is no guard left in the
main flow to get wrong. should_swap() stays, because it is the decision
and is worth naming and testing on its own. Two new tests call
swap_if_built() with a recording stub in place of the real mv, so they
fail if the guard is removed, inverted, or stops being consulted.

Also fixed, found while verifying this:

* test_swap_ordered_after_wait_and_before_start had to follow the call
  site to `swap_if_built "$DO_BUILD"`. Left on the old needle it reported
  "swap_staged_jar (line 215) is not after wait_for_daemon_exit (line
  730)" — true of a function definition, and nothing about step order.
* That test's three `[ -n ... ] || fail "could not find ... call site"`
  guards were dead code. Under `set -euo pipefail` an absent needle fails
  the assignment and `set -e` kills the suite before the guard runs.
  Measured: deleting the swap call gave exit 1 with ZERO bytes of output,
  no FAIL line, nothing naming what was missing. Each grep now ends in
  `|| true` so the assignment succeeds empty and the guard can speak.

Verified by me on this revision:

* suite exit 0, 0 `^FAIL:` lines, 44 tests defined and 44 invoked
* bash -n rc=0 on both scripts under /bin/bash 3.2.57 and bash 5.3.9
* four mutations, each killed with its own named FAIL line, each restored
  byte-identical, green control after the battery:
  - guard removed inside swap_if_built -> "must not swap, but it did"
  - guard inverted                     -> "must perform the swap, and did not"
  - should_swap's comparison changed    -> "must return true"
  - main-flow call deleted              -> "could not find the swap call
    site in redeploy-fleetd.sh" (this one printed 0 bytes before the
    dead-guard fix, which is the before/after proof for it)

Not fixed here, filed separately: drain_gate_refusal has the same shape.
Replacing `die "$(drain_gate_refusal ...)"` with `die "aborted — nothing
changed"` leaves the suite at exit 0 with output byte-identical to a clean
run, which reinstates the exact wrong message #517 was filed to fix.
ltms merged commit 3366590dbe into main 2026-09-12 07:01:55 +02:00
Owner

Correction to my own merge message, which was unfair to the implementer.

I wrote that I measured the call-site gap. I did — but the implementer found it first and reported it, in this PR's body under "Caveat for review":

I also tried mutating the new call site itself (if should_swap "$DO_BUILD"; then → if false; then … now one line down at :739) — the suite stayed green. test_should_swap_* only calls the function directly and never proves the main-flow if still invokes it … I did not fix it, since the ticket's ask was specifically "extract the decision + a test per value" … Flagging it rather than silently living with it.

That is the whole finding, measured, correctly attributed to the ticket's scope rather than quietly absorbed, and it also names the same residual gap on #517's drain_gate_refusal precedent — which is now #528. I reproduced it independently without having read the body first, so I arrived at the same place by a second route, but the report was already there. Worker behaviour that should be copied: it ran a mutation its brief did not ask for, found its own fix incomplete, and said so.

Two more parts of that report worth keeping out of the archive, because I did not re-derive them and they answer questions #521 asked:

Part 2 — does anything downstream report a misleading jar id? #521 said someone should establish this rather than assume. The implementer's answer: no, and not because the report is right, but because the run cannot reach the final report line. stage_built_jar is unconditional and has already moved the jar off $JAR by then, so with the swap disabled java -jar fails immediately and the script dies at no process appeared or /healthz never answered within ${HEALTH_WAIT}s, both of which print the daemon log tail. So the mutant is a loud failure, not a silent success — which narrows #521's severity from what I filed. Explicitly not run against the live daemon: this is from reading the control flow, a generic non-fleetd java -jar <missing> test, and a sourced-script trace of the jar-file state. I have not re-verified it.

Part 3 — the sweep. Exactly two source-text-only tests exist, both already known (test_swap_ordered_after_wait_and_before_start, position-only; test_drain_gate_abort_message_says_no_no_build, wording-only). No third instance. But the implementer then reported something more useful than the thing asked for: seven main-flow decisions past the SOURCED guard with no test of any kind, not even a grep —

  • :611 if [ "$CHECK_ONLY" = 1 ] — skips the mutating flow entirely
  • :648 if [ -n "$OLD_PID" ] && [ "$ASSUME_YES" = 0 ] — whether the drain prompt fires at all, plus the if [ "$reply" != "yes" ] die inside it
  • :549 / :681 / :756 the three case "$SUPERVISOR_KIND" blocks — report display, stop dispatch (launchctl unload / systemctl --user stop / kill), start dispatch
  • :820 if [ -z "$HEALTH_BODY" ] — healthz body vs 503 vs die
  • :866 if [ "$REDEPLOY_ERROR_COUNT" -eq 0 ] — the ok/warn summary built on counters that are tested

Line numbers are pre-merge and will have shifted; re-measure before using them. The :681 stop dispatch is the one I would rank first — it chooses between three different ways to stop the daemon, and #492's supervisor-detection work sits directly upstream of it.

Not filing these as a ticket yet. Recorded here so they are not lost, and referenced from #528.

Correction to my own merge message, which was unfair to the implementer. I wrote that I measured the call-site gap. I did — but **the implementer found it first and reported it**, in this PR's body under "Caveat for review": > I also tried mutating the new *call site* itself (`if should_swap "$DO_BUILD"; then` → `if false; then` … now one line down at :739) — the suite **stayed green**. `test_should_swap_*` only calls the function directly and never proves the main-flow `if` still invokes it … I did not fix it, since the ticket's ask was specifically "extract the decision + a test per value" … Flagging it rather than silently living with it. That is the whole finding, measured, correctly attributed to the ticket's scope rather than quietly absorbed, and it also names the same residual gap on #517's `drain_gate_refusal` precedent — which is now #528. I reproduced it independently without having read the body first, so I arrived at the same place by a second route, but the report was already there. Worker behaviour that should be copied: it ran a mutation its brief did not ask for, found its own fix incomplete, and said so. Two more parts of that report worth keeping out of the archive, because I did not re-derive them and they answer questions #521 asked: **Part 2 — does anything downstream report a misleading jar id?** #521 said someone should establish this rather than assume. The implementer's answer: no, and not because the report is right, but because the run cannot reach the final report line. `stage_built_jar` is unconditional and has already moved the jar off `$JAR` by then, so with the swap disabled `java -jar` fails immediately and the script dies at `no process appeared` or `/healthz never answered within ${HEALTH_WAIT}s`, both of which print the daemon log tail. So the mutant is a loud failure, not a silent success — which narrows #521's severity from what I filed. Explicitly **not** run against the live daemon: this is from reading the control flow, a generic non-fleetd `java -jar <missing>` test, and a sourced-script trace of the jar-file state. I have not re-verified it. **Part 3 — the sweep.** Exactly two source-text-only tests exist, both already known (`test_swap_ordered_after_wait_and_before_start`, position-only; `test_drain_gate_abort_message_says_no_no_build`, wording-only). No third instance. But the implementer then reported something more useful than the thing asked for: seven main-flow decisions past the `SOURCED` guard with **no test of any kind**, not even a grep — - `:611` `if [ "$CHECK_ONLY" = 1 ]` — skips the mutating flow entirely - `:648` `if [ -n "$OLD_PID" ] && [ "$ASSUME_YES" = 0 ]` — whether the drain prompt fires at all, plus the `if [ "$reply" != "yes" ]` die inside it - `:549` / `:681` / `:756` the three `case "$SUPERVISOR_KIND"` blocks — report display, stop dispatch (`launchctl unload` / `systemctl --user stop` / `kill`), start dispatch - `:820` `if [ -z "$HEALTH_BODY" ]` — healthz body vs 503 vs die - `:866` `if [ "$REDEPLOY_ERROR_COUNT" -eq 0 ]` — the ok/warn summary built on counters that *are* tested Line numbers are pre-merge and will have shifted; re-measure before using them. The `:681` stop dispatch is the one I would rank first — it chooses between three different ways to stop the daemon, and #492's supervisor-detection work sits directly upstream of it. Not filing these as a ticket yet. Recorded here so they are not lost, and referenced from #528.
Sign in to join this conversation.