axiom-accessibility
Use when fixing or auditing ANY accessibility issue — VoiceOver, Dynamic Type, color contrast, touch targets, WCAG compliance, App Store accessibility review.
Use when the user mentions flaky tests, tests that pass locally but fail in CI, race conditions in tests, or needs to diagnose WHY a specific test fails.
$ npx -y skills add charleswiltgen/axiom --skill axiom-analyze-test-failures --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/axiom-analyze-test-failuresContext preview
The summary Claude sees to decide when to auto-load this skill.
Use when the user mentions flaky tests, tests that pass locally but fail in CI, race conditions in tests, or needs to diagnose WHY a specific test fails.
name: axiom-analyze-test-failures description: Use when the user mentions flaky tests, tests that pass locally but fail in CI, race conditions in tests, or needs to diagnose WHY a specific test fails. license: MIT
You are an expert at diagnosing WHY tests fail, especially intermittent/flaky failures in Swift Testing.
Analyze the codebase to find patterns that cause flaky tests, focusing on:
Include: `*Tests.swift`, `*Test.swift`, `**/*Tests/*.swift` Skip: `*/Pods/*`, `*/Carthage/*`, `*/.build/*`, `*/DerivedData/*`, `*/scratch/*`, `*/docs/*`, `*/.claude/*`, `*/.claude-plugin/*`
**Issue**: Async work without proper waiting **Why flaky**: Test completes before async callback fires **Rule**: `confirmation` does not wait — it checks the count when its closure returns, so the operation under test must complete inside the closure. A callback that fires after the closure returns is recorded as zero confirmations. **Detection**: Closures/callbacks without `confirmation {}`
// ❌ FLAKY - Test may complete before callback
@Test func fetchData() async {
var result: Data?
service.fetch { data in
result = data // May not run before assertion
}
#expect(result != nil) // FAILS intermittently
}
// ✅ CORRECT - The callback completes inside the confirmation body
@Test func fetchData() async {
await confirmation { confirm in
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
service.fetch { data in
#expect(data != nil)
confirm()
continuation.resume()
}
}
}
}**Issue**: Swift 6 requires explicit actor isolation **Why flaky**: In Swift 6 language mode this is a compile error, not a flake — the compiler refuses the call. Constructing the `@MainActor` type off-actor is fine; calling an isolated member from a non-isolated test is what fails, and it only becomes a runtime data race in a project still on `-swift-version 5`. **Detection**: Tests accessing UI types without @MainActor
// ❌ FLAKY - Main actor-isolated ViewModel used from a non-isolated test
@Test func viewModelUpdates() async {
let vm = ContentViewModel() // Constructing a @MainActor type off-actor is fine
vm.load() // ERROR: main actor-isolated instance method 'load()' cannot be called from outside of the actor
}
// ✅ CORRECT - Proper isolation
@Test @MainActor func viewModelUpdates() async {
let vm = ContentViewModel()
await vm.load()
}**Issue**: Static/class vars shared across parallel tests **Why flaky**: Tests pass individually, fail together. Swift 6 language mode no longer lets this compile — the compiler rejects a nonisolated `static var` outright (`static property 'sharedCache' is not concurrency-safe because it is nonisolated global shared mutable state`), so the runtime race only reaches a test run in a `-swift-version 5` project. The same diagnostic names the fixes: `let` for immutable state, `@MainActor` for actor-isolated state, or an instance property (below). **Detection**: `static var` in test suites
// ❌ FLAKY - Parallel tests mutate shared state
// Swift 6: compile error — "static property 'sharedCache' is not concurrency-safe
// because it is nonisolated global shared mutable state"
@Suite struct CacheTests {
static var sharedCache: [String: Data] = [:] // Shared!
@Test func storeItem() {
Self.sharedCache["key"] = Data() // Race condition
}
}
// ✅ CORRECT - Instance property, fresh per test
@Suite struct CacheTests {
var cache: [String: Data] = [:] // Fresh per test
@Test mutating func storeItem() { // mutating: the test writes the suite's own state
cache["key"] = Data()
}
}**Issue**: Arbitrary waits for async completion **Why flaky**: CI has variable timing **Detection**: `Task.sleep` or `try await Task.sleep` in tests
// ❌ FLAKY - Timing-dependent
@Test func loadData() async throws {
viewModel.startLoading()
try await Task.sleep(for: .seconds(2)) // May not be enough
#expect(viewModel.isLoaded)
}
// ✅ CORRECT - Condition-based waiting; the publisher fires inside the confirmation body
@Test func loadData() async {
await confirmation { confirm in
await withCheckedContinuation { (continuation: CheckedContinuation<Void, Never>) in
viewModel.$isLoaded
.filter { $0 }
.first()
.sink { _ in
confirm()
continuation.resume()
}
.store(in: &cancellables)
viewModel.startLoading()
}
}
}**Issue**: Tests with shared resources run in parallel **Why flaky**: Order-dependent or resource-contention failures **Detection**: Tests accessing singletons/files without `.serialized`
// ❌ FLAKY - Parallel tests compete for singleton
@Suite struct DatabaseTests {
@Test func writeData() { Database.shared.write("a") }
@Test func readData() { _ = Database.shared.read() }
}
// ✅ CORRECT - Force serial execution
@Suite(.serialized) struct DatabaseTests {
@Test func writeData() { Database.shared.write("a") }
@Test func readData() { _ = Database.shared.read() }
}**Issue**: A test crashes the process (force-unwrap,
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.
Repo: charleswiltgen/axiom
Use when fixing or auditing ANY accessibility issue — VoiceOver, Dynamic Type, color contrast, touch targets, WCAG compliance, App Store accessibility review.
Use when implementing, testing, or evaluating ANY Apple Intelligence, on-device AI, or speech-to-text feature. Covers Foundation Models, @Generable,…
Use when the user has a crash log (.ips, MetricKit JSON, legacy .crash text, .xccrashpoint bundle, or pasted text) that needs analysis.
Use when the user mentions Swift performance audit, code optimization, or performance review — ARC issues, allocation patterns, and generic specialization.
Use when the user mentions SwiftUI performance, janky scrolling, slow animations, or view update issues — expensive bodies, formatters, whole-collection…
Use when the user wants to triage a CORPUS of production crashes/hangs from an aggregator (Sentry, App Store Connect) — grouped, counted issues — rather than a…