diff --git a/src/agent_comms/todos.py b/src/agent_comms/todos.py index c6876fbc1f..3e155a81a1 100644 --- a/src/agent_comms/todos.py +++ b/src/agent_comms/todos.py @@ -49,6 +49,7 @@ ) from .goals import CheckedCommit, OrderCheck, ProblemGoalOrder from .launch_runtime import BuildIdentity, UnrecordedBuildIdentity +from .maintenance_barrier import MaintenanceBarrier from .order_story import ProblemStory, StoryEvent, StoryLine, StorySource from .plan_phases import OrderPhase, UnplannedPhase from .recorded_time import EventTime, RecordedEventTime, UnrecordedEventTime @@ -328,7 +329,7 @@ def belongs_to(self, todo: Todo) -> bool: return (todo.id in self.problems or any(identity in self.orders for identity in todo.held_order_ids)) - def merged_commits(self) -> Iterator[str]: + def merged_commits(self, since: float) -> Iterator[str]: return iter(()) async def delivery_merges(self, delivery: CommitDelivery, @@ -345,8 +346,9 @@ class MergedPullRequest(PullRequest): merge: str merged_at: float - def merged_commits(self) -> Iterator[str]: - yield self.merge + def merged_commits(self, since: float) -> Iterator[str]: + if self.merged_at >= since: + yield self.merge async def delivery_merges(self, delivery: CommitDelivery, check: OrderCheck) -> tuple[DeliveryMerge, ...]: @@ -930,7 +932,7 @@ class MergedProgress(FoundProgress): @classmethod def found(cls, source: ProgressSource) -> Iterator[Self]: return (cls(sha) for pr in source.requests("merged") - for sha in pr.merged_commits()) + for sha in pr.merged_commits(source.since)) @property def state(self) -> str: diff --git a/tests/test_order_progress.py b/tests/test_order_progress.py index 4cddca923c..e3d1eb8c1d 100644 --- a/tests/test_order_progress.py +++ b/tests/test_order_progress.py @@ -119,6 +119,30 @@ def test_unfinished_check_keeps_other_overdue_orders_visible( todo.order.check.result.require(run) +@pytest.mark.parametrize('merged_at', (200.0, 201.0)) +def test_reissued_order_rejects_earlier_merge_and_accepts_its_own( + checkout, commander, merged_at): + first, unit = checkout + sha = commit(unit) + earlier = MergedPullRequest(7, 'fix/p1', sha, merge=sha, merged_at=150.0, + updated_at=150.0, orders=(first.order.id,)) + comms, caller = commander + following = replace(first.order, id='resent-P1', at=RecordedEventTime(200.0)) + CommsOrderTool(owner='worker', order=OrderGoalAction( + problem='P1', order=following, request='request', deadline=RecordedEventTime(3000), + commander='lead', expected_revision=first.revision, + assigner=comms.registry.require('lead').incarnation)).apply(comms, caller) + current = comms.goals.todos.get('P1') + assert current.prior_orders == (first.order,) + assert not isinstance(read((current, unit), Listed(merged=(earlier,))), MergedProgress) + assert comms.goals.todos.get('P1') == current and current.state.open + assert tuple(earlier.merged_commits(200.0)) == () + later = replace(earlier, number=8, merged_at=merged_at, updated_at=merged_at, + orders=(following.id,)) + assert tuple(later.merged_commits(200.0)) == (sha,) + assert read((current, unit), Listed(merged=(earlier, later))) == MergedProgress(sha) + + def test_no_commit_since_the_order_is_explicit(checkout): progress = read(checkout) assert progress == NoCommitProgress()