desk: request_id_conflict is the answer's alone; on read and list it is unavailable

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
Heimdall 2026-11-11 01:02:35 +00:00
commit 97ddba0cf5
2 changed files with 20 additions and 2 deletions

View file

@ -173,7 +173,7 @@ public static class DeskEndpoints
{
await WriteJsonAsync(http, DeskRefusals.ForkTooLargeStatus, DeskRefusals.ForkTooLargeDocument(largeId, largeOrder));
}
else if (listed is DeskListOutcome.NotListed(var listCode) && DoorMayRefuse(listCode))
else if (listed is DeskListOutcome.NotListed(var listCode) && DoorMayRefuse(listCode) && listCode != DeskRefusals.RequestIdConflict)
{
await WriteRefusalAsync(http, ReadListCode(listCode));
}
@ -189,7 +189,7 @@ public static class DeskEndpoints
{
await WriteJsonAsync(http, 200, IsDecider(context) ? entry : DeskNotes.Strip(entry));
}
else if (found is DeskReadOutcome.NotFound(var readCode) && DoorMayRefuse(readCode))
else if (found is DeskReadOutcome.NotFound(var readCode) && DoorMayRefuse(readCode) && readCode != DeskRefusals.RequestIdConflict)
{
await WriteRefusalAsync(http, ReadListCode(readCode));
}
@ -251,6 +251,8 @@ public static class DeskEndpoints
code is not (DeskRefusals.Unauthenticated or DeskRefusals.InsufficientScope or DeskRefusals.Forbidden) &&
DeskRefusals.IsKnown(code);
// request_id_conflict is the answer's alone (Libby): a read or list carries no request_id, so the door saying it
// there is a door fault and the edge says `unavailable`.
// A read or list sends no body. A door that refuses one for its body (an `authority` field among them) is
// refusing the request, which is request_invalid; it is not an outage.
private static string ReadListCode(string code) =>

View file

@ -196,6 +196,22 @@ public sealed class DeskReadTests
}
}
[Fact]
public async Task request_id_conflict_is_the_answers_alone_on_read_and_list_it_is_a_door_fault()
{
using var factory = new DeskWebApplicationFactory();
await factory.EnsureAccountAsync(DeskWebApplicationFactory.Alice, true);
factory.Door.ReadScript = (_, _) => new DeskReadOutcome.NotFound(DeskRefusals.RequestIdConflict);
factory.Door.ListScript = (_, _) => new DeskListOutcome.NotListed(DeskRefusals.RequestIdConflict);
foreach (var target in new[] { "/api/desk/nibu/forks", DeskReplay.Target("read", "nibu", "nibu:question:glow-order") })
{
var reply = await factory.SendAsync("GET", target, null, ReadToken(factory));
Assert.Equal(503, reply.Status);
Assert.Equal("unavailable", (string?)JsonNode.Parse(reply.Body)!["code"]);
}
}
[Fact]
public async Task Door_failure_on_list_and_read_is_unavailable()
{