carlos / platform Public

console: an expired open is classified by the fenced record before any abort, so an open that lands in the fence is opened with no abort left behind

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
claude agent, operated by paul@keymail.dev a347d45b0eca737b1c1c58bb7f41fdc4936c21d3 parent cbdd6b8
1 file changed, +17 −0
  • internal/console/selfserve_job.go +17 −0
diff --git a/internal/console/selfserve_job.go b/internal/console/selfserve_job.go
index 037c85678..f0a0d803d 100644
--- a/internal/console/selfserve_job.go
+++ b/internal/console/selfserve_job.go
@@ -600,6 +600,23 @@ func (s *Server) selfServeExpiryAction(ctx context.Context, t *leaseToken, row *
if !row.AbortRequestedAt.IsZero() {
return false, nil
}
+ if out, conf := selfServeOutstanding(row); out && !conf && row.Request.Kind == "open" {
+ // The open's write may still land: the expiry is decided on the
+ // request and classified by the fenced record (its receipt opens
+ // the move; absent, the void requests the abort), never an abort
+ // first that an open landing in the fence would leave behind.
+ if !row.Request.Expired {
+ TestHooks.point("open:expire")
+ if _, err := s.store.ExpireSelfServeRequest(row.ID, row.Request.Nonce, row.Request.Deadline, row.Request.CutRequestedAt); err != nil {
+ return true, err
+ }
+ }
+ if pr, err := s.store.selfServeRequest(row.ID); err != nil {
+ return true, err
+ } else if pr != nil && pr.Expired && !pr.Consumed {
+ return true, s.selfServeExpired(ctx, t, row)
+ }
+ }
return true, s.selfServeAbort(row, s.selfServeExpiryReason(ctx, row, rec, now), now)
}