swift-concurrency-pro — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited swift-concurrency-pro (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Write correct, data-race-free concurrent Swift. Target Swift 6 strict concurrency.
Sendable / data-race / actor-isolation errors.Trigger: /swift-concurrency-pro.
real bug, not noise.
@MainActor. Background work runs off the main actor.actor, never a lock + global.Sendable.❌
func loadUser(completion: @escaping (Result<User, Error>) -> Void) { ... }✅
func loadUser() async throws -> User { ... }Wrap legacy callbacks with continuations:
func loadUser() async throws -> User {
try await withCheckedThrowingContinuation { cont in
legacyLoad { result in cont.resume(with: result) }
}
}Resume a continuation exactly once — never zero, never twice.
❌ Lock around shared dictionary
final class Cache {
private var store: [String: Data] = [:]
private let lock = NSLock()
func set(_ d: Data, _ k: String) { lock.lock(); store[k] = d; lock.unlock() }
}✅
actor Cache {
private var store: [String: Data] = [:]
func set(_ d: Data, for k: String) { store[k] = d }
func get(_ k: String) -> Data? { store[k] }
}Access is await cache.set(...). Don't expose var actor state directly across actors.
@MainActor
@Observable
final class FeedModel {
var posts: [Post] = []
func refresh() async {
let fetched = await api.posts() // api hops off main as needed
posts = fetched // back on main, safe
}
}Don't sprinkle DispatchQueue.main.async — annotate with @MainActor instead.
struct/enum of Sendable members → automatically Sendable.Sendable.actor, or isolate it.❌
class Settings { var theme = "light" } // shared across tasks → data race✅
actor Settings { var theme = "light" }
// or, if truly immutable:
struct Settings: Sendable { let theme: String }Use async let / TaskGroup for parallel work; they auto-cancel and propagate errors.
✅
async let a = api.profile()
async let b = api.feed()
let (profile, feed) = try await (a, b)Avoid unstructured Task { } for work tied to a view's lifetime — use .task so it cancels on disappear.
DispatchQueue.main.async instead of @MainActor.actor.Sendable type sent across a concurrency boundary.Task {} for view-scoped work (won't cancel).Per issue: file:line, the isolation/Sendable rule violated, before/after fix. End with the highest-risk data races first.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.