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:
GodopuandClaude Fable 5.1 committed 2026-10-10 17:28:09 +00:00
1 parent 05bffc6475
commit 3705bc72a8
4 files changed
+56 -23

No files matched your search

+23 -9
View File
@@ -209,24 +209,38 @@ def _start_pane(box: Box, name=SESSION, cwd=None) -> None:
assert box.agent_status(name) == "idle", box.herdr("agent", "list").stdout
def _teardown(box: Box) -> None:
if os.environ.get("MAM_T50_KEEP_BOX"): # debugging aid: leave the box and the server in place
print("KEEP_BOX", box.home, box.sess)
return
for sub in (("session", "stop", box.sess), ("session", "delete", box.sess)):
subprocess.run([HERDR, *sub], capture_output=True, text=True, env={"HOME": str(box.home), "PATH": os.environ["PATH"]},
timeout=30)
time.sleep(0.5)
def _kill_servers(box: Box) -> None:
for pid in box.server_pids():
try:
os.kill(pid, signal.SIGKILL)
except OSError:
pass
def _teardown(box: Box) -> None:
if os.environ.get("MAM_T50_KEEP_BOX"): # debugging aid: leave the box and the server in place
print("KEEP_BOX", box.home, box.sess)
return
for sub in (("session", "stop", box.sess), ("session", "delete", box.sess)):
try:
subprocess.run([HERDR, *sub], capture_output=True, text=True,
env={"HOME": str(box.home), "PATH": os.environ["PATH"]}, timeout=30)
except subprocess.TimeoutExpired:
pass # the kill below is what must run (review F2)
time.sleep(0.5)
_kill_servers(box)
shutil.rmtree(box.home, ignore_errors=True)
# herdr writes its agent-detection state under $HOME/.local/state a moment
# after the server is gone: sweep once more
# after the server is gone, and a late client call can bootstrap a new
# server: sweep and kill once more, then prove the server is gone
time.sleep(1)
_kill_servers(box)
shutil.rmtree(box.home, ignore_errors=True)
deadline = time.time() + 5
while box.server_pids() and time.time() < deadline:
time.sleep(0.2)
assert not box.server_pids(), f"a server of {box.sess} survived teardown"
assert not box.home.exists(), f"{box.home} survived teardown"
@pytest.fixture