fix(worker): depends_on-Nachfolger schon beim gelandeten Merge freigeben
Der Queue-Picker gatete eine task_dependencies-Kante auf status='done'. review_task(skipVerify) laesst einen erfolgreich gemergten Task aber bewusst auf WaitingForReview stehen, bis verify_merges einmal zentral laeuft -- damit blockierte jeder Nachfolger ueber den gesamten Batch plus Full-Suite-Verify hinweg, bei freien Slots. Eine Kante gilt jetzt als erfuellt, wenn der Vorgaenger 'done' ist ODER sein Merge gelandet ist (worktrees.state = 'merged'). TaskBlocking (get_task/list_tasks/wait_for_task_change) und der UI-Wartehinweis folgen derselben Regel, damit "blocked" nicht meldet, was der Picker claimt. Abgeleitet: revert_merge/abort_merge setzen den Worktree auf Active und blockieren wieder; reject_rerun/reject_park haben nie gemergt und bleiben unerfuellt; ein Task ohne Worktree wird nur ueber 'done' erfuellt; ein fehlgeschlagener verify_merges gibt Nachfolger frei, weil der Code so oder so auf main liegt. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
committed by
mika kuns
co-authored by
Claude Opus 5
parent
50b6b56f87
commit
c874bf7e52
@@ -472,6 +472,34 @@ public sealed class ExternalMcpServiceTests : IDisposable
|
||||
Assert.Null(dto.BlockedReason);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetTask_QueuedWithMergedButUnverifiedDependsOn_ReportsBlockedFalse()
|
||||
{
|
||||
// Same rule as QueuePicker: a predecessor merged with skipVerify sits in
|
||||
// WaitingForReview until the batch verify, but the picker already claims the successor --
|
||||
// get_task must not contradict that by still calling it blocked.
|
||||
var listId = await SeedListAsync();
|
||||
var predecessor = await SeedTaskAsync(listId, status: TaskStatus.WaitingForReview);
|
||||
_ctx.Worktrees.Add(new WorktreeEntity
|
||||
{
|
||||
TaskId = predecessor.Id,
|
||||
Path = $"/tmp/{predecessor.Id}",
|
||||
BranchName = $"claudedo/{predecessor.Id}",
|
||||
BaseCommit = "abc123",
|
||||
State = WorktreeState.Merged,
|
||||
CreatedAt = DateTime.UtcNow,
|
||||
});
|
||||
await _ctx.SaveChangesAsync();
|
||||
var task = await SeedTaskAsync(listId, status: TaskStatus.Queued);
|
||||
await _ctx.SeedDependsOnAsync(task.Id, predecessor.Id);
|
||||
var sut = BuildSut(CreateQueue());
|
||||
|
||||
var dto = await sut.GetTask(task.Id, CancellationToken.None);
|
||||
|
||||
Assert.False(dto.Blocked);
|
||||
Assert.Null(dto.BlockedReason);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task GetTask_IdleWithDependsOnTaskId_ReportsBlockedFalse_NotYetQueued()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user