Skip to content

fix(doctor): sweeps.alive reports unknown, not FAIL, for a root the service does not serve (model_performance-jyg) - #77

Merged
Brian Krabach (bkrabach) merged 2 commits into
mainfrom
lane/jyg-doctor-sweep-heartbeat
Sep 6, 2026
Merged

fix(doctor): sweeps.alive reports unknown, not FAIL, for a root the service does not serve (model_performance-jyg)#77
Brian Krabach (bkrabach) merged 2 commits into
mainfrom
lane/jyg-doctor-sweep-heartbeat

Conversation

@bkrabach

Copy link
Copy Markdown
Collaborator

Closes model_performance-jyg.

The defect

cli._check_sweeps_alive joins two facts of different scope:

fact scope source
"the service is installed and active" host — one singleton --user unit service.describe_service()
"this root has a fresh sweep heartbeat" per workspace root — one file per root heartbeat.heartbeat_path(root)

That join is only sound when both refer to the same root. It never checked. doctor runs against whichever root it was pointed at (AMPLIFIER_WORK_TRACKER_ROOT, --root); the heartbeat is written by the supervisor under the root it was given. Against any other root the file is absent by construction, so its absence proves nothing about the loops — and the check reported it as [FAIL] sweeps.alive, exit 1, on machines whose sweep loops were provably healthy.

Measured on the dev host:

ExecStart=... amplifier-work-tracker serve --root /home/bkrabach/.amplifier-work-tracker ...

while tests/conftest.py:299 points every run_cli call at a fresh tmp_path_factory root.

The cost was masking, not noise. test_doctor_quick_succeeds_against_the_real_installed_bd asserts returncode == 0 first, so this environmental exit-1 killed the test before its two later assertions ran — hiding real defects twice: model_performance-wp6 (announcement-predicate collision; invisible locally, CI-only, blocked #70 for days) and model_performance-kxk.

Is sweeps.alive right?

Yes — the assumption is correct, and an isolated root is not a legitimate place to evaluate it. The honest report is neither PASS (claiming proof we lack) nor FAIL (red-lining a healthy service): it is unknown, the third option sweeps.reclaiming already established in model_performance-oy4 (46d7da4).

Detectable because _serve_argv_tail bakes --root into the unit as an explicit argument (deliberately, per the unit template's own comment) — so the served root is readable, and the mismatch is decidable rather than guessed.

The "have the TEST provision a heartbeat" option was rejected: it makes the test manufacture the evidence it then asserts on, and leaves every other doctor caller unable to tell a wrong-root from a dead loop.

Changes

  • service.py: ServiceInfo.served_root; pure readers parse_systemd_served_root / parse_launchd_served_root (None = "cannot tell", never a guess); _read_served_root never raises.
  • cli.py: _served_root_mismatch gate — both sweep checks report unknown on a mismatch. Dependency ordering unchanged.
  • tests/_util.py + tests/cli/test_cli_surface.py: the test's three properties are now checked independently and reported together. assert_no_silent_failure and its announcement predicate are called unchanged — nothing narrowed, test neither deleted nor skipped.

The FAIL path still fails

situation verdict
served root, no heartbeat at all FAIL
served root, stale heartbeat FAIL
served root, dead-pid heartbeat FAIL
served root, sweep failed on every project FAIL (sweeps.reclaiming)
served root undeterminable evaluate anyway; can still FAIL
a root the service does not serve unknown

Row five is the point: "cannot tell" must never become a way to make a real dead-loop failure disappear. Pinned as a test so it cannot be quietly inverted.

Evidence

doctor — MEASURED, never computed: 38/38, unchanged (no AGENTS.md edit needed)

run lines sweeps.alive exit
before, isolated root 38 FAILno heartbeat ever recorded 1
after, isolated root 38 unknown -- the installed service serves --root /home/.../.amplifier-work-tracker, not /tmp/... 0
after, real served root 38 reap sweep completed 64s ago (threshold 900s); notify sweep completed 261s ago 0

The third row is load-bearing: against the served root the assumption is still genuinely evaluated, not skipped.

Target test, same box

before FAILED at assert result.returncode == 01 failed in 49.67s
after PASSED (evidence/tier-cli.log:89)

Masking demonstration (injected wp6-shaped defect, same box, reverted before commit)

BEFORE (pristine 46d7da4): the injected defect appears 0 times in the whole log; silent-failure guard appears 0 times — the guard never ran. The reader sees only the sweeps.alive FAIL.

AFTER:

E  AssertionError: `doctor --quick` failed 1 independent check(s)
   (all of them reported, none masked by the first):
     1. silent-failure guard: command printed an error announcement but
        exited 0 ... shape=error-colon matched='Error:'

Also pinned permanently by test_an_exit_1_does_not_hide_a_silent_failure_announcement (no bd, no subprocess).

All four documented tiers + the modules suite, by name

tier command result
1 — unit make test-unit 912 passed (45.2s)
2 — integration make test-integration 374 passed, 3 skipped (18:24)
3 — cli make test-cli 89 passed (5:17)
4 — ledger make test-ledger 26 passed (0.6s)
4b — ledger mutation make ledger-mutate proven 15 / 15
5 — modules make test-module 119 passed (7:37)

ruff check / ruff format --check / pyright clean (0 errors, 0 warnings). The known test_supervisor_web.py port-binding flake did not occur.

31 new tests across test_sweeps_root_scope.py, test_served_root.py, test_doctor_surface_failures.py. Raw logs committed under docs/lanes/jyg-doctor-sweep-heartbeat/evidence/; full write-up in that lane's DONE-NOTE.md.

Spend

$0.00 against a $0.00 authority (0 runs x 0 arms x $0 / 1.00 = $0.00). Pure code/test change; no infrastructure created.

@bkrabach
Brian Krabach (bkrabach) force-pushed the lane/jyg-doctor-sweep-heartbeat branch from 627f648 to 1dbce0f Compare September 6, 2026 00:40
@bkrabach
Brian Krabach (bkrabach) marked this pull request as ready for review September 6, 2026 00:40
@bkrabach

Copy link
Copy Markdown
Collaborator Author

Manager verification — FIX. Rebased onto current main (which moved 7 commits). Merging.

Head 1dbce0f (rebased from 627f648), base = current origin/main 065da04. Clean rebase, no conflicts.

Fail-before, against current main

24 failed, 7 passed

The target this lane was filed for

test_doctor_quick_succeeds_against_the_real_installed_bd — the pre-existing failure wp6 unmasked, which has been red on this host for many cycles and forced me to hand-verify "that one cli failure is jyg, not mine" every single time:

1 passed in 63.67s

That is the first time it has passed here.

The root cause is a scope join, and the fix follows the right precedent

cli._check_sweeps_alive joined a HOST-scoped fact (one singleton --user service unit) to a ROOT-scoped one (a heartbeat file under whichever workspace root doctor was pointed at) without checking the two referred to the same root. Against any other root the heartbeat is absent by construction, so its absence proved nothing — yet was reported as a hard FAIL with exit 1.

Fixed by reading the served root back out of the unit's own --root argument (ServiceInfo.served_root) and reporting unknown on a mismatch — following sweeps.reclaiming's oy4 precedent exactly. The FAIL path is untouched against the served root, which is the property that matters: this scopes the assumption, it does not delete it.

Gates

gate result
fail-before vs current main 24 failed, 7 passed
unit + ledger (rebased) 1027 passed
target cli test 1 passed (was failing)
ruff check clean
CI test:SUCCESS, license/cla:SUCCESS

doctor MEASURED, and I checked the one FAIL against main rather than assuming: sweeps.alive now PASSES here (this host is the served root). sweeps.reclaiming FAILs — "swept 36 project(s) and FAILED on 1: sd_it_e1beb7b2" — and that is pre-existing and environmental, reproduced byte-identically on origin/main with the same foreign project id. Not this branch's, and not a regression.

Squash + --admin per the base-branch policy.

@bkrabach

Copy link
Copy Markdown
Collaborator Author

Manager verification — the masking defect that hid two real bugs this batch. Merging.

Rebased onto current origin/main (065da04) — main had moved 7 commits (the whole operator-surface wave) while this sat. Clean rebase, no conflicts. New head 1dbce0f.

The mechanism, and why it was never a test bug

cli._check_sweeps_alive joined a HOST-scoped fact (one singleton --user service unit) to a ROOT-scoped one (a heartbeat file under whichever workspace root doctor was pointed at) without checking the two referred to the same root. Against any other root the heartbeat is absent by construction, so its absence proved nothing — and was reported as a hard FAIL, exit 1.

Fixed by reading the served root back out of the unit's own --root argument (ServiceInfo.served_root) and reporting unknown on a mismatch, following sweeps.reclaiming's oy4 precedent.

The conservative case is the part I checked hardest, because this is where a fix like this usually goes wrong — silencing the real signal to make a test pass:

# when `served_root` is None (unit unreadable, no --root at all, or the caller
# passed a path we cannot resolve) -> goes on to evaluate the heartbeat and can still FAIL

So "cannot tell" resolves toward still evaluating, and the FAIL path is untouched against the served root. A genuinely dead sweep on a real installation still fails loudly.

Gates

gate result
fail-before vs current main 24 failed, 7 passed
unit + ledger (rebased) 1027 passed
cli tier 94 passed, 0 failed
ruff clean
doctor 37 PASS + 1 FAIL — MEASURED

The cli tier is the headline. test_doctor_quick_succeeds_against_the_real_installed_bd has failed on this host every single cycle of this batch, and it passes now. That test dies at its first assertion (returncode == 0), which masked every later assertion in it — it hid wp6's \berror\b collision until CI (blocking PR #70 for days) and kxk's defect the same way. Every cycle since, I have had to hand-verify "that one cli failure is jyg, not mine". That judgement is now automatic again.

The one remaining doctor FAIL is sweeps.reclaiming, and it is environmental, not this branch: I measured it on origin/main too, identical message — the live service's last sweep failed on project sd_it_e1beb7b2. Real, worth chasing separately, and nothing to do with this change.

Squash + --admin per the base-branch policy.

…he service does not serve

`_check_sweeps_alive` joined a SERVICE-scoped fact (`describe_service()` --
one singleton unit per user) to a ROOT-scoped one (a heartbeat file under
whichever workspace root `doctor` was pointed at). That join is only sound
when the two refer to the same root. Against any other root the heartbeat is
absent BY CONSTRUCTION, and the check reported that absence as "no heartbeat
ever recorded ... the loop may never have started" -- a hard FAIL, exit 1, on
a machine whose sweep loops were provably running fine.

Every isolated test root is such a root, so
tests/cli/test_cli_surface.py::test_doctor_quick_succeeds_against_the_real_
installed_bd failed on any developer machine whose service serves a real
workspace -- and, because `assert returncode == 0` came first, it MASKED
every later assertion in that test. Measured twice: model_performance-wp6
(announcement-predicate collision, invisible locally, CI-only, blocked PR #70
for days) and model_performance-kxk.

The assumption is right; it is simply not evaluable against a root the
supervisor was never given. `_serve_argv_tail` already bakes `--root` into
the unit as an explicit argument, so the served root is readable:
`ServiceInfo.served_root` reads it back (systemd ExecStart, launchd
ProgramArguments), and both sweep checks report `unknown` on a mismatch --
following the precedent `sweeps.reclaiming` set in model_performance-oy4
(46d7da4) for exactly this shape.

The FAIL path is untouched where it matters: against the SERVED root, a
missing, stale, or dead-pid heartbeat is still a loud failure, and a sweep
that failed on every project still fails `sweeps.reclaiming`. When the served
root cannot be determined at all, the checks evaluate the heartbeat anyway
and can still FAIL -- "cannot tell" must never become a way to make a real
dead-loop failure disappear.

Separately, the masking itself is fixed: the cli test now checks its three
properties independently and reports them together
(`_util.assert_doctor_run_is_clean`), so the next environmental exit-1 from
any cause cannot hide the next real defect. `assert_no_silent_failure` and
its announcement predicate are called unchanged.

doctor MEASURED at 38/38 (unchanged).
@bkrabach
Brian Krabach (bkrabach) force-pushed the lane/jyg-doctor-sweep-heartbeat branch from 1dbce0f to 8efd055 Compare September 6, 2026 01:13
@bkrabach
Brian Krabach (bkrabach) merged commit 0055cd2 into main Sep 6, 2026
2 checks passed
@bkrabach
Brian Krabach (bkrabach) deleted the lane/jyg-doctor-sweep-heartbeat branch September 6, 2026 02:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants