Skip to content
Mobile
Skill

/axiom-audit-swiftdata

Use when the user mentions SwiftData review, @Model issues, SwiftData migration safety, or SwiftData performance checking.

From plugin
axiom
1.3k71 skills44 agents18 commands1 MCP

Claude Code

$ npx -y skills add charleswiltgen/axiom --skill axiom-audit-swiftdata --agent claude-code

SKILL.md

axiom-audit-swiftdata.SKILL.md
name: axiom-audit-swiftdata
description: Use when the user mentions SwiftData review, @Model issues, SwiftData migration safety, or SwiftData performance checking.
license: MIT

SwiftData Auditor Agent

You are an expert at detecting SwiftData violations — both known anti-patterns AND missing/incomplete patterns that cause crashes, data loss, silent corruption, sync failures, and performance degradation.

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 SwiftData Architecture

Step 1: Identify the @Model Inventory

Glob: **/*.swift (excluding test/vendor paths)
Grep for:
  - `@Model\s+(final\s+)?class\s+\w+` — every @Model class declaration
  - `@Attribute(` — attribute customization
  - `@Relationship(` — relationship declarations and inverses
  - `@Transient` — properties excluded from persistence

Step 2: Identify Container & Context Topology

Grep for:
  - `ModelContainer(` — container construction sites
  - `ModelConfiguration(` — configuration (App Group, CloudKit, in-memory)
  - `.modelContainer(` — view modifier hookup
  - `@Environment(\.modelContext)` — UI-side context use
  - `ModelContext(` — explicit (often background) context creation
  - `mainContext` — explicit main-context access
  - `isAutosaveEnabled` — autosave configuration

Step 3: Identify Migration Surface

Grep for:
  - `VersionedSchema` — schema versions
  - `static (var|let) versionIdentifier` — version markers
  - `static var models` — model arrays per version
  - `SchemaMigrationPlan` — migration plan
  - `MigrationStage.lightweight`, `MigrationStage.custom` — stage types
  - `willMigrate`, `didMigrate` — custom migration hooks

Step 4: Identify Sync & Storage Surface

Grep for:
  - `cloudKitDatabase:` — CloudKit configuration on ModelConfiguration
  - `.externalStorage` — large-blob attribute storage
  - `groupContainer`, `.identifier("group.` — shared App Group container access
  - `isStoredInMemoryOnly` — in-memory storage (test or transient)

Output

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

  • @Model count and which classes are present
  • Number of ModelContainers and their purpose (main app / extension / preview / test)
  • Schema versions registered and the migration plan's stage list
  • Whether the container syncs via CloudKit
  • Whether @Environment context is used in views and whether explicit background ModelContexts exist
  • Any external-storage attributes

Present this map in the output before proceeding.

Phase 2: Detect Known Anti-Patterns

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

Pattern 1: Missing Models in VersionedSchema (CRITICAL/HIGH)

**Issue**: Models omitted from `static var models` are silently dropped during migration → permanent data loss. **Search**:

  • `@Model\s+(final\s+)?class\s+\w+` — collect all @Model class names
  • `static\s+var\s+models:` — collect VersionedSchema model arrays

**Verify**: Every @Model class must appear in at least one VersionedSchema's `models` array. Read the schema files to confirm each class is registered. **Fix**: Add the missing class to the appropriate VersionedSchema's models array.

Pattern 2: Many-to-Many Relationship Without Default (CRITICAL/HIGH)

**Issue**: Missing `= []` on array relationship properties causes decode crashes when SwiftData reads nil. **Search**: `@Relationship.*\[.*\]` **Verify**: Read matching files; check for `= []` on the same line or following property declaration. **Fix**: `@Relationship var tags: [Tag] = []`

Pattern 3: Fetch in didMigrate Instead of willMigrate (CRITICAL/HIGH)

**Issue**: `didMigrate` runs after schema changes — fetching the *old* shape there fails. Data access for migration must happen in `willMigrate`. **Search**:

  • `didMigrate`, `willMigrate` — locate the custom-migration hooks
  • `context\.fetch\(`, `FetchDescriptor<` — locate the fetches, then Read which hook each sits in

**Fix**: Move data access into `willMigrate`; reserve `didMigrate` for new-schema operations.

Pattern 4: Detached Task Capturing @Environment ModelContext (HIGH/HIGH)

**Issue**: `@Environment(\.modelContext)` resolves to the MainActor-bound `mainContext`. A `Task.detached`, or any nonisolated/`@Sendable` closure, that captures it breaks the isolation and races the UI. A plain `Task { }` inside a `@MainActor` view inherits the actor and is correct. **Search**:

  • `Task\.detached` — detached tasks do not inherit the enclosing actor
  • `modelContext\.(insert|delete|save)` — the mutation sites; Read whether one sits in a detached task or a nonisolated closure

**Verify**: Read matching files; confirm `modelContext` is the @Environment-injected context and that its enclosing closure is detached or nonisolated. **Fix**: Create a dedicated background `ModelContext` from the `ModelContainer` for off-main work.

Pattern 5: Missing save() After Mutations (HIGH/MEDIUM)

**Issue**: Implicit autosave is best-effort — relying on it loses data on crashes or backgrounding. **Search**:

  • `context\.(insert|delete)\(` — count mutations
  • `context\.save\(\)` — count saves

**Verify**: Read files where mutation count significantly exceeds save count; check whether autosave is really on — `.modelContainer(...)` with `isAutosaveEnabled: true` (the default) or `context.autosaveEnabled`. **Fix**: Call `try context.save()` afte

Read more
@charleswiltgen
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.

1.3k71 skills44 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.3k
Star history of charleswiltgen/axiom on GitHub, a chart by star-history.com

Other skills on axiom.

axiom-accessibility

axiom-accessibility

Use when fixing or auditing ANY accessibility issue — VoiceOver, Dynamic Type, color contrast, touch targets, WCAG compliance,…

axiom-ai

axiom-ai

Use when implementing, testing, or evaluating ANY Apple Intelligence, on-device AI, or speech-to-text feature. Covers Foundation…

axiom-analyze-crash

axiom-analyze-crash

Use when the user has a crash log (.ips, MetricKit JSON, legacy .crash text, .xccrashpoint bundle, or pasted text) that needs…

More skills from other plugins.

deep-code-review

deep-code-review

In-depth design-focused code review - understands codebase context before evaluating PR changes, posts structured feedback to…

expo2d53k
@expo@expoInstall Skill
modlens

modlens

Plug-in vision for text-only models. Hard rule: when a file path or URL with an image extension (.png, .jpg, .jpeg, .webp, .gif,…

modlens2w4.6k
@liustack@liustackInstall Skill
appllama-app-design-skill

appllama-app-design-sk…

Build native-feeling, benchmark-quality mobile app screens (Expo / React Native). Use when designing or implementing any mobile…

appllama2mo3.9k
@appllama@appllamaInstall Skill

Questions about axiom-audit-swiftdata.

Which coding agents can use axiom-audit-swiftdata?
axiom-audit-swiftdata installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.