axiom-concurrency について
axiom-concurrency は、async/await からアクター分離、同期、プロファイリングまでを扱う Swift 開発者向けスキルです。課題に応じた資料への案内や、自動監査の手順を提供します。
主な機能
- 01Swift 並行処理パターンの案内
- 02アクター分離と Sendable の解説
- 03同期とロック選択の指針
- 04並行処理のプロファイル手順
- 05並行処理監査への案内
活用シーン
- 01Swift 6 のデータ競合エラーの診断
- 02ミューテックスとアクターの選択
- 03アクター競合の調査
- 04実行時の分離クラッシュの追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ charleswiltgen/ axiom --skill axiom-concurrencyインストール後、Claude Code で/axiom-concurrencyを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
skills/assume-isolated.mdconcurrency-auditor.mdconcurrency-profiling.mdisolation-inheritance-diag.mdswift-concurrency-ref.mdswift-concurrency.mdsynchronization.md詳細
並行処理
並行処理、async/await、スレッド処理、または Swift 6 の並行処理に関する作業では、必ずこのスキルを使用してください。
Claude Code にバンドルされたツールの場合: command -v <tool> で何も見つからない場合(フックが無効、または --bare の場合)は、単独の名前の代わりに <plugin-root>/tools/<tool> を使用してください。<plugin-root> は、このスキルの Base directory for this skill: パスから2階層上です。
Axiom エージェントを起動できませんか? このルーターがエージェントを案内する箇所では、その手順をインラインで実行してください。MCP 経由では、
axiom_get_agentがその内容を返します。それ以外の場合は、以下のファイルを読み取ってください。ファイル検索と読み取りだけで実行できます。ここで利用可能:
skills/concurrency-auditor.md。それ以外のエージェントについても、MCP 経由では
axiom_get_agentが内容を返します。そのxclog、xcsym、xcprofの手順をaxiom_xclog_*、axiom_xcsym_*、axiom_xcprof_*ツールで実行してください。それ以外の場合は、Axiom のスキルからskills/<agent>.mdを検索してください。見つからない場合は、このスイートのスキルと、PATH上にある Axiom ツールを使って自分で作業してください。
クイックリファレンス
| 症状 / タスク | リファレンス |
|---|---|
| async/await パターン、@MainActor、アクター | skills/swift-concurrency.md を参照 |
| データ競合エラー、Sendable への適合 | skills/swift-concurrency.md を参照 |
| Swift 6 への移行、@concurrent 属性 | skills/swift-concurrency.md を参照 |
| アクターの定義、再入性、グローバルアクター | skills/swift-concurrency-ref.md を参照 |
| Task/TaskGroup/キャンセル API | skills/swift-concurrency-ref.md を参照 |
| AsyncStream、継続 | skills/swift-concurrency-ref.md を参照 |
| DispatchQueue からアクターへの移行 | skills/swift-concurrency-ref.md を参照 |
| Mutex(iOS 18 以降)、OSAllocatedUnfairLock | skills/synchronization.md を参照 |
| アトミック型、ロックとアクターの選択 | skills/synchronization.md を参照 |
| MainActor.assumeIsolated | skills/assume-isolated.md を参照 |
| @preconcurrency プロトコル適合 | skills/assume-isolated.md を参照 |
| レガシーなデリゲートコールバック | skills/assume-isolated.md を参照 |
警告なしのビルドで _dispatch_assert_queue_fail が発生するクラッシュ | skills/isolation-inheritance-diag.md を参照 |
クラッシュシグネチャ _swift_task_checkIsolatedSwift | skills/isolation-inheritance-diag.md を参照 |
@MainActor クラス内の Core Data context.perform で発生する実行時クラッシュ | skills/isolation-inheritance-diag.md を参照 |
receive(on:) の配置に起因する Combine .map/.sink のクラッシュ | skills/isolation-inheritance-diag.md を参照 |
| 分離性の継承に起因するデリゲートメソッドのクラッシュ(CLLocationManager、NSDocument、AVAudioPlayerDelegate、WKNavigationDelegate、PHPhotoLibraryChangeObserver) | skills/isolation-inheritance-diag.md を参照 |
PhotoKit の performChanges ブロックが PhotoKit のキューでトラップする | skills/isolation-inheritance-diag.md を参照 |
| アクターの再入性 / await をまたぐ古い状態 | skills/isolation-inheritance-diag.md を参照 |
| Swift Concurrency Instruments テンプレート | skills/concurrency-profiling.md を参照 |
| アクターの競合の診断 | skills/concurrency-profiling.md を参照 |
| スレッドプールの枯渇 | skills/concurrency-profiling.md を参照 |
意思決定ツリー
digraph concurrency {
start [label="Concurrency task" shape=ellipse];
what [label="What do you need?" shape=diamond];
start -> what;
what -> "skills/swift-concurrency.md" [label="async/await, actors,\nSendable, data races,\nSwift 6 migration"];
what -> "skills/swift-concurrency-ref.md" [label="API syntax lookup\n(TaskGroup, AsyncStream,\ncontinuations, migration)"];
what -> "skills/synchronization.md" [label="Mutex, locks,\natomic types"];
what -> "skills/assume-isolated.md" [label="assumeIsolated,\n@preconcurrency"];
what -> "skills/isolation-inheritance-diag.md" [label="warning-free build crashes\n_dispatch_assert_queue_fail\n_swift_task_checkIsolatedSwift"];
what -> "skills/concurrency-profiling.md" [label="profile async perf,\nactor contention"];
}
- データ競合/アクター分離/@MainActor/Sendable/Swift 6 への移行ですか? →
skills/swift-concurrency.md1a. 特定の API 構文(actor の定義、TaskGroup、AsyncStream、continuations)が必要ですか? →skills/swift-concurrency-ref.md1b. NotificationCenter のオブザーバー、userInfoのキャスト、または通知のアンパック時に発生する Sendable エラーですか? →skills/swift-concurrency-ref.md(Typed Notifications —MainActorMessage/AsyncMessage、iOS 26 以降) - async/await コードを書いていますか? →
skills/swift-concurrency.md - assumeIsolated / @preconcurrency ですか? →
skills/assume-isolated.md3a. 警告なしでビルドできる Swift 6 アプリが、本番環境で_dispatch_assert_queue_failまたは_swift_task_checkIsolatedSwiftによってクラッシュしますか? →skills/isolation-inheritance-diag.md - Mutex/ロック/同期ですか? →
skills/synchronization.md - 非同期パフォーマンス/アクターの競合をプロファイリングしますか? →
skills/concurrency-profiling.md - 値型/ARC/ジェネリックの最適化ですか? → axiom-performance を参照(skills/swift-performance.md)
- borrowing/consuming/~Copyable ですか? → axiom-swift を参照(skills/ownership-conventions.md)
- Combine/@Published/AnyCancellable/リアクティブストリームですか? → axiom-uikit を参照(skills/combine-patterns.md)
- 自動化された並行処理スキャンが必要ですか? → concurrency-auditor(Agent)
実践における並行処理
- Swift Concurrency を使った HealthKit クエリ(標準的なブリッジング例)→ axiom-health を参照(skills/queries.md)
競合時の優先順位
concurrency と axiom-performance:アプリがフリーズしたり、動作が遅く感じられたりする場合:
- まず concurrency を試してください — UI フリーズの最大の原因はメインスレッドのブロックです。プロファイリングの前に、@MainActor 上で同期処理が行われていないか確認してください。
- axiom-performance を使うのは、concurrency による修正で改善しない場合に限ります — 明らかなブロックを除外してからプロファイリングしてください。
- 特定のフリーズがアプリのコードに起因するか特定するには、axiom-performance の Hang Window Workflow を参照してください(skills/hang-diagnostics.md)。
--start-ms/--end-ms --user-binaryを指定してxcprof analyzeの対象をハングした時間帯に絞り込み、メインスレッド上のアプリ所有フレームを表示します。
concurrency と axiom-build:Swift 6 の並行処理エラーが発生した場合:
- axiom-build ではなく concurrency を使ってください — 並行処理エラーは環境の問題ではなく、コードの問題です。
concurrency と axiom-data:並行処理エラーが Core Data または SwiftData に関係する場合:
- Core Data のスレッド処理(NSManagedObjectContext のスレッド制約)→ まず axiom-data を使ってください
- SwiftData と @MainActor ModelContext → concurrency を使ってください
- 一般的な「バックグラウンド保存でデータが失われる」問題 → まず axiom-data を使ってください
- GRDB の Sendable パターン(struct レコード、計算プロパティとしての
databaseSelection、Swift 6 の適合性)→ axiom-data を参照(skills/grdb-performance.md)§8
重要なパターン
Swift Concurrency(skills/swift-concurrency.md):
- 段階的な学習:シングルスレッド → async → 並行処理 → アクター
- バックグラウンドでの実行を強制する @concurrent 属性
- 分離された適合、メインアクターモード
- デリゲート値のキャプチャ、Tasks 内の weak self など、コピーして使える 12 のパターン
- よくある 7 種類のエラーメッセージに対応する包括的な決定木
API リファレンス(skills/swift-concurrency-ref.md):
- アクターの定義、再入性、グローバルアクター、nonisolated
- Sendable のパターン、@unchecked Sendable、sending パラメーター
- Task/TaskGroup/キャンセル、async let、withDiscardingTaskGroup
- AsyncStream、継続、バッファリングポリシー
- 分離のパターン(#isolation、@preconcurrency、nonisolated(unsafe))
- DispatchQueue/DispatchGroup/完了ハンドラーからの移行
同期(skills/synchronization.md):
- Mutex(iOS 18+)、OSAllocatedUnfairLock(iOS 16+)、Atomic 型
- ロックとアクターの選択を支援する決定木
- 危険なパターン:await をまたぐロック、async コンテキストでのセマフォ
プロファイリング(skills/concurrency-profiling.md):
- Swift Concurrency Instruments テンプレート
- メインスレッドのブロック、アクターの競合、スレッドプールの枯渇を診断
- 協調スレッドプールで安全なプリミティブと危険なプリミティブ
ランタイムの分離クラッシュ(skills/isolation-inheritance-diag.md):
_dispatch_assert_queue_failと_swift_task_checkIsolatedSwiftのシグネチャ- クロージャの分離継承(Core Data
perform、Combine.map、NotificationCenter.sink) - デリゲートメソッドの分離継承(CLLocationManager、NSDocument、AVAudioPlayerDelegate、WKNavigationDelegate)
MainActor.assumeIsolatedの誤用- アクター再入性による状態の陳腐化
自動スキャン
並行処理の監査 → concurrency-auditor エージェントまたは /axiom:audit concurrency を起動します(5 フェーズのセマンティック監査:分離アーキテクチャのマッピング、8 つのアンチパターンの検出、不足している並行処理パターンの推論、複合リスクの相関、Swift 6.4 への対応状況の評価)
自己正当化への対処
| 考え | 実態 |
|---|---|
| 「@MainActor を追加すれば動く」 | @MainActor には分離の継承ルールがあります。skills/swift-concurrency.md ですべてのパターンを説明しています。 |
| 「警告を消すために nonisolated(unsafe) を使おう」 | 警告を消すとデータ競合が隠れてしまいます。skills/swift-concurrency.md では安全なパターンを示しています。 |
| 「async の呼び出しは 1 回だけ」 | async の呼び出しが 1 回だけでも、キャンセルと分離への影響があります。 |
| 「アクターの仕組みは分かっている」 | アクターの再入性と分離のルールは Swift 6.2 で変更されました。 |
| 「Sendable の警告は後で直そう」 | Sendable 違反はランタイムクラッシュを引き起こします。今すぐ修正してください。 |
| 「Swift 6 のビルドで警告がゼロだから、分離は正しい」 | 静的チェックでは SDK コールバックを検出できません。それでもランタイムチェックでクラッシュします。skills/isolation-inheritance-diag.md を参照してください。 |
「クラッシュを MainActor.assumeIsolated で囲もう」 | assumeIsolated はランタイムトラップであり、警告を消すものではありません。誤った前提はクラッシュにつながります。 |
| 「Combine はもう使われていないから、async/await を使おう」 | Combine には非推奨の告知はありません。動作しているパイプラインを書き直すのは時間の無駄です。axiom-uikit(skills/combine-patterns.md)を参照してください。 |
| 「これを黙らせるために @unchecked Sendable を使おう」 | コンパイラーにデータ競合を隠すことになります。本番環境でクラッシュします。 |
| 「この async 関数はバックグラウンドスレッドで実行される」 | 決めつけず、分離を確認してください。@MainActor の async 関数はメインアクター上で完全に実行されます。また、NonisolatedNonsendingByDefault のもとでは、nonisolated async は呼び出し元のアクター上で実行されます(Swift 6.2+。新しい Xcode プロジェクトでは SWIFT_APPROACHABLE_CONCURRENCY = YES が設定されますが、この設定自体のデフォルトは NO で、SwiftPM では有効になりません)。これらがメインスレッドのフリーズの原因です。この設定がない場合、nonisolated async はグローバルエグゼキューターに切り替わります。@concurrent はどちらの場合もアクター外での実行を強制します。 |
呼び出し例
ユーザー:「Swift 6 で『data race』エラーが発生しています」
→ 参照:skills/swift-concurrency.md
ユーザー:「@MainActor を正しく使うにはどうすればよいですか?」
→ 参照:skills/swift-concurrency.md
ユーザー:「TaskGroup を作成するにはどうすればよいですか?」
→ 参照:skills/swift-concurrency-ref.md
ユーザー:「AsyncStream API について教えてください」
→ 参照:skills/swift-concurrency-ref.md
ユーザー:「assumeIsolated を使うにはどうすればよいですか?」
→ 参照:skills/assume-isolated.md
ユーザー:「Mutex と actor のどちらを使うべきですか?」
→ 参照:skills/synchronization.md
ユーザー:「async コードの速度が遅いのですが、プロファイルするにはどうすればよいですか?」
→ 参照:skills/concurrency-profiling.md
ユーザー:「警告のない Swift 6 ビルドが、本番環境で _dispatch_assert_queue_fail によりクラッシュします」
→ 参照:skills/isolation-inheritance-diag.md
ユーザー:「Core Data の context.perform が @MainActor のビューモデル内でクラッシュします」
→ 参照:skills/isolation-inheritance-diag.md
ユーザー:「CLLocationManager のデリゲートメソッドが _swift_task_checkIsolatedSwift によりクラッシュします」
→ 参照:skills/isolation-inheritance-diag.md
ユーザー:「不要なコピーが原因でアプリの動作が遅くなっています」 → axiom-performance を参照(skills/swift-performance.md)
ユーザー:「コードに Swift 6 の並行処理に関する問題がないか確認してください」
→ concurrency-auditor エージェントを呼び出す