fix(worker): document and test Queued→Failed guard in FailAsync

OverrideSlotService dispatches RunAsync before calling StartRunningAsync,
so a preflight failure (list not found, worktree setup) can reach MarkFailed
while the task is still Queued. The guard is intentional, not dead code.

- Add comment in FailAsync explaining the OverrideSlotService preflight gap
- Add FailAsync_FromQueued_TransitionsToFailed test
- Update CLAUDE.md transition table with the precise rationale

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
mika kuns
2026-06-09 23:41:12 +02:00
parent eee5c99e2f
commit fe73f45b74
3 changed files with 19 additions and 1 deletions

View File

@@ -198,6 +198,9 @@ public sealed class TaskStateService : ITaskStateService
{
await using (var ctx = await _dbFactory.CreateDbContextAsync(ct))
{
// Queued is intentional: OverrideSlotService dispatches RunAsync before calling
// StartRunningAsync, so a preflight failure (list not found, worktree setup) can
// reach MarkFailed while the task is still Queued in the DB.
var affected = await ctx.Tasks
.Where(t => t.Id == taskId &&
(t.Status == TaskStatus.Running || t.Status == TaskStatus.Queued))