← ClaudeAtlas

swift-concurrency-reviewlisted

Use when reviewing Swift 5.5+ code containing `await`, `actor`, `Task { }`, `@MainActor`, `@unchecked Sendable`, cancellable timer/deadline handles, or long-lived `for await` AsyncStream consumers — especially diffs extending existing actors with new methods. Catches post-`await` state-overwrite races, TOCTOU around Task spawn, cancellation-not-honoured, terminal-state clobber, and consumer-Task-ownership bugs that hang Swift Testing at exit.
stuartshields/claude-setup · ★ 2 · Code & Development · score 73
Install: claude install-skill stuartshields/claude-setup
<!-- Last updated: 2026-05-10T20:55+10:00 --> # Swift Concurrency Review ## Overview Swift 6 strict concurrency catches data races at compile time but lets a class of semantic bugs through: state-overwrite races, TOCTOU around `Task { }`, and cancellation that doesn't actually prevent firing. This is a reviewer's checklist for those bug classes. Apply on any diff touching `actor`, `@MainActor`, `await`, `Task {`, lock-protected state, or deadline timers. ## The Five Questions ### 1. After every `await`, is **state** re-checked — not just the index? When an actor method suspends at `await`, any other method on the actor can run to completion before it resumes. Re-finding a record by id ≠ verifying its state is still what you expected. ```swift // BAD try await transport.send(message) guard let idx = outbound.firstIndex(where: { $0.id == id }) else { return } outbound[idx].direction = .delivered // overwrites .cancelled / .deadlineMissed // GOOD try await transport.send(message) guard let idx = outbound.firstIndex(where: { $0.id == id }), outbound[idx].direction == .sending else { return } outbound[idx].direction = .delivered ``` **Invariant: terminal states are sticky.** Once a record is `.cancelled` / `.expired` / `.deadlineMissed`, no later success path may overwrite it. The guard encodes this invariant. ### 2. Is `Task { }` body reading mutable state, or is it snapshotted at spawn? A `Task { }` body runs later, on some executor. Reading `clock.now`, `self.co