From 2c3a51df672793746ab81c39a65b28805eeca44a Mon Sep 17 00:00:00 2001 From: Renn F Date: Sun, 28 Jun 2026 10:56:42 +0200 Subject: [PATCH] [F032] test: unknown-assignee claim reaches release-to-pending path F031's role_for_slug_or_none fix made the unknown-assignee release branch in _dispatch_claimed_without_agent reachable (the human-only guard no longer raises/short-circuits on a stale slug). Lock that reachability in: a claimed task with an unknown-assignee UUID past grace returns the slug (not None) so get_agent_role -> 'unknown' releases the claim to pending for a role-matched reclaim. --- .../test_blocker_and_claimed_dispatch.py | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/unit/runtime/test_blocker_and_claimed_dispatch.py b/tests/unit/runtime/test_blocker_and_claimed_dispatch.py index c25adc21..153b84f6 100644 --- a/tests/unit/runtime/test_blocker_and_claimed_dispatch.py +++ b/tests/unit/runtime/test_blocker_and_claimed_dispatch.py @@ -15,6 +15,7 @@ from __future__ import annotations from datetime import UTC, datetime, timedelta from typing import Any from unittest.mock import AsyncMock, MagicMock, patch +from uuid import uuid4 import pytest from roboco.models.runtime import AgentInstance @@ -194,6 +195,29 @@ def test_in_progress_task_with_no_agent_returns_assignee() -> None: assert orch._claimed_task_needs_agent(task) == "fe-dev-2" +def test_claimed_task_with_unknown_assignee_returns_slug_for_release() -> None: + # F032: a claimed/in_progress task whose assignee is a stale/unknown UUID + # (no seeded agent) must reach the release-to-pending path. The human-only + # guard (role_for_slug_or_none) returns None for an unknown slug, and + # ``None in (CEO, PROMPTER, SECRETARY)`` is False — so it does NOT + # short-circuit, the slug falls through the grace window, and the resolver + # returns the unknown slug. _dispatch_claimed_without_agent then sees + # get_agent_role(slug) == "unknown" and releases the claim to pending for + # a role-matched reclaim. Before F031's role_for_slug_or_none fix the guard + # raised KeyError on the unknown slug, crashing the whole tick before the + # release path could run. + orch = _orch() + unknown_uuid = str(uuid4()) + task: dict[str, Any] = { + "id": "t1", + "status": "claimed", + "assigned_to": unknown_uuid, + "updated_at": _STALE, + } + # Returns the (unknown) slug, NOT None — the release path is reachable. + assert orch._claimed_task_needs_agent(task) == unknown_uuid + + # --------------------------------------------------------------------------- # _get_prompt_for_agent — role-appropriate respawn prompt (#19) # ---------------------------------------------------------------------------