fix(issue-34): merge review - the remote runner's deadline wording counts as an unconfirmed close
remote.py closes a job whose end it could not see with `error --detail "deadline_timeout (remote runner)"`; the sub-job table matched the reason exactly and filed it as a plain failure, losing the unconfirmed count and the late-write warning (merge review, codex R2). The kind is the first word of the reason now. Test T14 replays the remote runner's close through the real registry and producer; it fails without the fix. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
This commit is contained in:
1 parent
8a9101ed30
commit
e80186f560
2 files changed
+24
-1
No files matched your search
@@ -691,7 +691,10 @@ class LoopRunner:
|
|||||||
events=("completed", "error", "cancelled")) or ""
|
events=("completed", "error", "cancelled")) or ""
|
||||||
if status == "completed":
|
if status == "completed":
|
||||||
return "completed", reason or "-"
|
return "completed", reason or "-"
|
||||||
if reason in ORCHESTRATOR_CLOSED or (status == "error" and not reason):
|
# merge review R2 (codex): the remote runner phrases its deadline as
|
||||||
|
# "deadline_timeout (remote runner)", so the kind is the first word
|
||||||
|
closed_kind = reason.split(" ", 1)[0] if reason else ""
|
||||||
|
if closed_kind in ORCHESTRATOR_CLOSED or (status == "error" and not reason):
|
||||||
# no recorded reason is not the agent's own report either
|
# no recorded reason is not the agent's own report either
|
||||||
return "CLOSED-UNCONFIRMED", reason or "-"
|
return "CLOSED-UNCONFIRMED", reason or "-"
|
||||||
if status == "cancelled" and (reason in ("session_busy", "target_not_found") or reason.startswith("rolled back")):
|
if status == "cancelled" and (reason in ("session_busy", "target_not_found") or reason.startswith("rolled back")):
|
||||||
|
|||||||
@@ -251,6 +251,26 @@ def test_t13_a_sub_job_cancelled_before_injection_is_not_dispatched_in_the_table
|
|||||||
assert f"| NOT-DISPATCHED | {reason} |" in block, block
|
assert f"| NOT-DISPATCHED | {reason} |" in block, block
|
||||||
|
|
||||||
|
|
||||||
|
def test_t14_the_remote_runners_deadline_wording_is_closed_unconfirmed(tmp_path, monkeypatch):
|
||||||
|
"""Merge review R2 (codex): remote.py closes a job it could not see finish
|
||||||
|
with `error --detail "deadline_timeout (remote runner)"`; the exact-match
|
||||||
|
classifier filed it as a plain failure and the unconfirmed count and its
|
||||||
|
warning were lost."""
|
||||||
|
env = _env(tmp_path)
|
||||||
|
reg = tmp_path / "reg"
|
||||||
|
p = _jid(_submit(env, reg))
|
||||||
|
c = _jid(_submit(env, reg, "--parent-job", p))
|
||||||
|
tok = _record(reg, c)["dispatch_token"]
|
||||||
|
res = subprocess.run([sys.executable, str(REGISTRY), "--registry-dir", str(reg), "close", "--job", c,
|
||||||
|
"--request", "deadline_timeout", "--expect-dispatch-token", tok],
|
||||||
|
capture_output=True, text=True, env=env, timeout=120)
|
||||||
|
assert res.returncode == 0, res.stderr
|
||||||
|
_publish(env, reg, c, "error", "deadline_timeout (remote runner)")
|
||||||
|
block = _runner(tmp_path, monkeypatch)._subjobs_block([p])
|
||||||
|
assert f"| {c} | " in block and "| CLOSED-UNCONFIRMED | deadline_timeout (remote runner) |" in block, block
|
||||||
|
assert "미확인 종결 1" in block, block
|
||||||
|
|
||||||
|
|
||||||
def test_t7_a_job_without_children_is_waited_for_as_before(tmp_path, monkeypatch):
|
def test_t7_a_job_without_children_is_waited_for_as_before(tmp_path, monkeypatch):
|
||||||
env = _env(tmp_path)
|
env = _env(tmp_path)
|
||||||
reg = tmp_path / "reg"
|
reg = tmp_path / "reg"
|
||||||
|
|||||||
Reference in new issue
Block a user