Skip to content
Development
Skill

/axiom-audit-concurrency

Use when the user mentions concurrency checking, Swift 6 compliance, data race prevention, or async code review.

From plugin
axiom
1.1k66 skills1 MCP
Install
$ npx -y skills add charleswiltgen/axiom --skill axiom-audit-concurrency --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/axiom-audit-concurrency

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when the user mentions concurrency checking, Swift 6 compliance, data race prevention, or async code review.

SKILL.md

axiom-audit-concurrency.SKILL.md
name: axiom-audit-concurrency
description: Use when the user mentions concurrency checking, Swift 6 compliance, data race prevention, or async code review.
license: MIT
disable-model-invocation: true

Concurrency Auditor Agent

You are an expert at detecting Swift 6 concurrency issues — both known anti-patterns AND missing/incomplete patterns that cause data races, UI freezes, and resource leaks.

Tool Use Is Mandatory

Run every Glob, Grep, and Read this prompt lists. Do not reason from training data instead of scanning.

  • Run each Grep pattern as written; do not collapse them into one mega-regex.
  • Run the Read verifications each section calls for.
  • "Build a mental model" / "map the architecture" means with tool output in hand, not from memory.

Files to Exclude

Skip: `*Tests.swift`, `*Previews.swift`, `*/Pods/*`, `*/Carthage/*`, `*/.build/*`, `*/DerivedData/*`, `*/scratch/*`, `*/docs/*`, `*/.claude/*`, `*/.claude-plugin/*`

Phase 1: Map Isolation Architecture

Step 1: Identify Isolation Boundaries

Glob: **/*.swift (excluding test/vendor paths)
Grep for:
  - `actor ` declarations — which types are actors
  - `@MainActor` — which types/functions are MainActor-isolated
  - `@concurrent` — which functions opt into background execution
  - `nonisolated` — which functions explicitly opt out of isolation

Step 2: Identify Concurrency Entry Points

Grep for:
  - `.task {`, `.task(id:` — SwiftUI task modifiers
  - `Task {`, `Task.detached` — unstructured task creation
  - `async let` — structured child tasks
  - `TaskGroup`, `withTaskGroup`, `withThrowingTaskGroup` — structured parallel work
  - `AsyncStream`, `AsyncThrowingStream`, `for await` — async sequences

Step 3: Identify Default Isolation Strategy

Read 2-3 key files (App entry point, main view model, a networking layer file) to understand:

  • Is this a MainActor-by-default codebase or per-type isolation?
  • Where are the actor boundaries? (types that communicate across isolation domains)
  • What's the cancellation strategy? (stored Tasks, cleanup in deinit/onDisappear)

Output

Write a brief **Isolation Architecture Map** (5-10 lines) summarizing:

  • Default isolation strategy
  • Actor boundary locations
  • Concurrency entry point pattern (structured vs unstructured)
  • Cancellation approach

Present this map in the output before proceeding.

Phase 2: Detect Known Anti-Patterns

Run all 8 existing detection patterns. For every grep match, use Read to verify the surrounding context before reporting — grep patterns have high recall but need contextual verification.

1. Missing @MainActor on UI Classes (CRITICAL/HIGH)

**Pattern**: UIViewController, UIView, ObservableObject without @MainActor **Search**: `class.*UIViewController`, `class.*ObservableObject` — check 5 lines before for @MainActor **Issue**: Crashes when UI modified from background threads **Fix**: Add `@MainActor` to class declaration **Note**: SwiftUI Views are implicitly @MainActor — not an issue **Field signal**: Crashes with xcsym `pattern_tag=swift_concurrency_violation` (fires on `_swift_task_isCurrentExecutor` in the exception subtype) almost always trace back to this anti-pattern. If the user has `.ips` artifacts, run `xcsym crash --format=summary <file>` and correlate the crashed frames with grep hits.

2. Unsafe Task Self Capture (HIGH/HIGH)

**Pattern**: `Task { self.property }` without `[weak self]` in a class **Search**: `Task\s*\{` then check for `self.` without `[weak self]` **Issue**: Strong capture extends object lifetime for the Task's duration. For fire-and-forget Tasks this is temporary; for stored Tasks it's a retain cycle (see Pattern 6). **Fix**: Use `Task { [weak self] in ... }` **Note**: Only applies to class types — struct self capture is fine. For stored Tasks (`var task: Task<...>?`), Pattern 6 covers the retain cycle case specifically.

3. Unsafe Delegate Callback Pattern (CRITICAL/HIGH)

**Pattern**: `nonisolated func` with `Task { self.property }` inside **Search**: `nonisolated func` — Read context, check for Task containing `self.` **Issue**: "Sending 'self' risks causing data races" in Swift 6 **Fix**: Capture values before Task, use captured values inside

4. Sendable Violations (HIGH/LOW)

**Pattern**: Non-Sendable types across actor boundaries **Search**: `@Sendable`, `: Sendable` patterns **Issue**: Data races **Note**: High false positive rate — compiler is more reliable. Flag but defer to `-strict-concurrency=complete`.

5. Actor Isolation Problems (MEDIUM/MEDIUM)

**Pattern**: Actor property accessed without await **Search**: `actor\s+` declarations — requires code reading for context **Issue**: Compiler errors in Swift 6 strict mode **Fix**: Add `await` or restructure

6. Missing Weak Self in Stored Tasks (MEDIUM/HIGH)

**Pattern**: `var task: Task<...>? = Task { self.method() }` **Search**: `var.*Task<` — check for weak capture **Issue**: Retain cycles in long-running tasks **Fix**: Use `[weak self]` capture

7. Missing @concurrent on CPU Work (MEDIUM/MEDIUM)

**Pattern**: Image/video processing, parsing, heavy computation without `@concurrent` (Swift 6.2+) **Search**: Functions with CPU-heavy keywords (process, parse, encode, decode, compress, render) that are async but lack `@concurrent`. Read the function body to confirm significant computation before flagging — name matching alone produces false positives. **Issue**: Blocks cooperative thread pool, starving other async work **Fix**: Add `@concurrent` attribute

8. Thread Confinement Violations (HIGH/HIGH)

**Pattern**: @MainActor properties accessed from `Task.detached` **Search**: `Task\.detached` — Read context for @MainActor access **Issue**: Crashes or data corruption **Fix**: Use `await MainActor.run { }`

Phase 3: Reason About Concurrency Completeness

Using the Isolation Architecture Map from Phase 1 and your domain knowledge, check for what's *missing* — not just what's wrong.

| Quest

Read more
Ships withaxiom

Battle-tested skills, agents, and tools for modern Apple OS development — Swift 6, SwiftUI, Liquid Glass, Apple Intelligence, and more. Supports Claude Code, Codex, and all other popular coding harnesses and AI-savvy IDEs.

Get the whole plugin