fix(issue-50): the loop path waits by the registry on its pending record (review F1-F3)
F1: from phase two on, the loop's `_registry_wait` ran before the record was reset to pending, so the waiter held a terminal record: the engine refused its dispatch_wait_at merge and other waiters never saw it in the FIFO. The wait (and the idle wait after it) now follows the `--status pending` update; s1 pins the order and u3c shows why a terminal self record cannot signal. F2: the real-herdr box teardown survives a hung stop/delete, kills a server bootstrapped by a late client call, and asserts the server and HOME are gone. F3: the delegate-job SKILL.md exit 5 row names the registry wait. Also drops the dead loop in s1. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
05bffc6475
commit
3705bc72a8
4 files changed
+56
-23
No files matched your search
@@ -185,6 +185,21 @@ def test_u3_the_waiter_signals_on_its_own_record(tmp_path):
|
||||
assert me in {j for _c, j, _s in live}
|
||||
|
||||
|
||||
def test_u3c_a_terminal_self_record_cannot_carry_the_signal(tmp_path):
|
||||
# why the loop path resets its record to pending before it waits (s1):
|
||||
# the engine refuses a merge into a terminal record, so the waiter would
|
||||
# stay invisible to every other waiter's FIFO
|
||||
a = _register(tmp_path, status="running")
|
||||
_event(tmp_path, a, time.time())
|
||||
me = _register(tmp_path, status="completed")
|
||||
assert decide.wait_open_jobs(_ns(tmp_path, me, wait_s=1)) == f"busy {a}"
|
||||
after = json.loads((tmp_path / f"{me}.json").read_text())
|
||||
assert after["status"] == "completed" and "dispatch_wait_at" not in after
|
||||
later = _register(tmp_path)
|
||||
live, _stale = decide.open_jobs(str(tmp_path), "herdr:s", later)
|
||||
assert me not in {j for _c, j, _s in live}
|
||||
|
||||
|
||||
def test_u3b_the_signal_is_a_registry_merge(tmp_path, monkeypatch):
|
||||
me = _register(tmp_path)
|
||||
seen = {}
|
||||
@@ -262,12 +277,14 @@ def test_s1_both_dispatch_paths_wait_by_the_registry_before_the_idle_wait():
|
||||
src = WRAPPER.read_text()
|
||||
assert src.count('_registry_wait "$JOB_ID" "$AGENT_SESSION"') == 1
|
||||
assert src.count('_registry_wait "$JOB_ID" "$current_session"') == 1
|
||||
for block in src.split("wait_for_agent_idle ")[1:]:
|
||||
pass
|
||||
direct = src.index('_registry_wait "$JOB_ID" "$AGENT_SESSION"')
|
||||
assert direct < src.index('wait_for_agent_idle "$AGENT_SESSION"')
|
||||
loop = src.index('_registry_wait "$JOB_ID" "$current_session"')
|
||||
assert loop < src.index('wait_for_agent_idle "$current_session"')
|
||||
# the loop path waits on the record already reset to pending for this
|
||||
# phase (review F1): a terminal self record cannot carry the signal (u3c)
|
||||
assert src.count('--status "pending"') == 1
|
||||
assert src.index('--status "pending"') < loop
|
||||
body = src.split("_registry_wait() {")[1].split("\n}\n")[0]
|
||||
assert "wait-open-jobs" in body and 'finalize_unfinished "$job_id" "error" "$SUB_RC_ERROR" "registry_wait"' in body
|
||||
assert "exit 5" in body and "mam_int_knob MAM_DISPATCH_WAIT_S 600 0" in body
|
||||
Reference in new issue
Block a user