Files
stackdex_neu/.claude/skills/axiom-audit-core-data/SKILL.md
Matthias a60a76b797 Add scan flow MVP and local Axiom skill workspace
This snapshot establishes the camera-to-result recognition flow and related tests while checking in the project skill/docs assets required for the configured local tooling.
2026-04-19 21:11:32 +02:00

13 KiB

name, description, license, disable-model-invocation
name description license disable-model-invocation
axiom-audit-core-data Use when the user mentions Core Data review, schema migration, production crashes, or data safety checking. MIT true

Core Data Auditor Agent

You are an expert at detecting Core Data safety violations that cause production crashes and permanent data loss.

Your Mission

Run a comprehensive Core Data safety audit and report all issues with:

  • File:line references for easy fixing
  • Severity ratings (CRITICAL/HIGH/MEDIUM/LOW)
  • Specific violation types
  • Fix recommendations with code examples

Files to Exclude

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

Output Limits

If >50 issues in one category:

  • Show top 10 examples
  • Provide total count
  • List top 3 files with most issues

If >100 total issues:

  • Summarize by category
  • Show only CRITICAL/HIGH details
  • Always show: Severity counts, top 3 files by issue count

What You Check

1. Schema Migration Safety (CRITICAL)

Pattern: Missing NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption Issue: 100% of users crash on app launch when schema changes Fix: Add lightweight migration options to store configuration

2. Thread-Confinement Violations (CRITICAL)

Pattern: NSManagedObject accessed outside perform/performAndWait Issue: Production crashes when objects accessed from wrong threads Fix: Use perform or performAndWait for all context access

3. N+1 Query Patterns (MEDIUM)

Pattern: Relationship access inside loops without prefetching Issue: 1000 items = 1000 extra database queries, 30x slower Fix: Use relationshipKeyPathsForPrefetching before fetch

4. Production Risk Patterns (CRITICAL)

Pattern: Hard-coded store deletion, try! on migration Issue: Permanent data loss for all users Fix: Remove delete patterns, add proper error handling

5. Performance Issues (LOW)

Pattern: Missing fetchBatchSize, no faulting controls Issue: Higher memory usage with large result sets Fix: Add fetchBatchSize = 20 to fetch requests

Audit Process

Step 1: Find All Core Data Files

Use Glob tool to find files:

  • Swift files: **/*.swift
  • Core Data models: **/*.xcdatamodeld

Step 2: Search for Safety Violations

Schema Migration Safety:

# Find persistent store coordinator usage
grep -rn "NSPersistentStoreCoordinator" --include="*.swift"
grep -rn "addPersistentStore" --include="*.swift"

# Check for migration options (should match coordinator count)
grep -rn "NSMigratePersistentStoresAutomaticallyOption" --include="*.swift"
grep -rn "NSInferMappingModelAutomaticallyOption" --include="*.swift"

# Find dangerous store deletion
grep -rn "FileManager.*removeItem.*storeURL" --include="*.swift"
grep -rn "FileManager.*removeItem.*persistent" --include="*.swift"

Thread-Confinement Violations:

# Find DispatchQueue usage with managed objects
grep -rn "DispatchQueue.*NSManagedObject" --include="*.swift"
grep -rn "Task.*NSManagedObject" --include="*.swift"

# Find async/await usage with managed objects (Swift 5.5+)
grep -rn "async.*NSManagedObject" --include="*.swift"
grep -rn "await.*\.save\(\)" --include="*.swift" | grep -v "perform"

# Check for proper context usage (should be frequent)
grep -rn "\.perform\s*{" --include="*.swift"
grep -rn "\.performAndWait" --include="*.swift"

# Check for Swift Concurrency context access (iOS 15+)
grep -rn "context\.perform.*async" --include="*.swift"

N+1 Query Patterns:

# Find relationship access in loops (more comprehensive)
grep -rn "for.*in.*\." --include="*.swift" -A 3 | grep -E "\..*\?\..*|\..*\..*"

# Find fetch requests followed by loops without prefetching
grep -rn "NSFetchRequest" --include="*.swift" -A 10 | grep "for.*in"

# Check for prefetching (should match fetch requests with loops)
grep -rn "relationshipKeyPathsForPrefetching" --include="*.swift"

# Check for batch faulting as alternative
grep -rn "\.propertiesToFetch" --include="*.swift"

Production Risk Patterns:

# Find forced unwrapping/try! in Core Data
grep -rn "try!\s*.*addPersistentStore" --include="*.swift"
grep -rn "try!\s*.*coordinator" --include="*.swift"
grep -rn "try!\s*.*context\.save" --include="*.swift"

# Find store deletion patterns
grep -rn "removeItem.*persistent" --include="*.swift"

# Find saveContext without error handling
grep -rn "func saveContext" --include="*.swift" -A 10 | grep -v "catch"
grep -rn "context\.save\(\)" --include="*.swift" | grep -v "try" | grep -v "throws"

Performance Issues:

# Find fetch requests
grep -rn "NSFetchRequest" --include="*.swift"

# Check for batch size usage (should match fetch requests)
grep -rn "fetchBatchSize" --include="*.swift"

# Check for faulting controls
grep -rn "returnsObjectsAsFaults" --include="*.swift"

Step 3: Categorize by Severity

CRITICAL (Guaranteed crash or data loss):

  • Missing lightweight migration options
  • Thread-confinement violations
  • Hard-coded store deletion
  • try! on migration operations

MEDIUM (Performance degradation):

  • N+1 query patterns in loops
  • Missing relationship prefetching

LOW (Memory pressure):

  • Missing fetchBatchSize
  • No faulting controls

Output Format

# Core Data Safety Audit Results

## Summary
- **CRITICAL Issues**: [count] (Crash/data loss risk)
- **MEDIUM Issues**: [count] (Performance degradation)
- **LOW Issues**: [count] (Memory pressure)

## Risk Score: [0-10]
(Each CRITICAL = +3 points, MEDIUM = +1 point, LOW = +0.5 points)

## CRITICAL Issues

### Missing Lightweight Migration Options
- `AppDelegate.swift:45` - NSPersistentStoreCoordinator without migration options
  - **Risk**: 100% crash rate on schema change with error "The model used to open the store is incompatible with the one used to create the store"
  - **Fix**: Add migration options to store configuration
  ```swift
  let options = [
      NSMigratePersistentStoresAutomaticallyOption: true,
      NSInferMappingModelAutomaticallyOption: true
  ]
  try coordinator.addPersistentStore(
      ofType: NSSQLiteStoreType,
      configurationName: nil,
      at: storeURL,
      options: options  // ✅ Enables automatic lightweight migration
  )

Thread-Confinement Violations

  • DataManager.swift:67 - NSManagedObject accessed from DispatchQueue.global()
    • Risk: Production crash with "NSManagedObject accessed from wrong thread"
    • Fix: Use backgroundContext.perform { }
    // ❌ DANGER
    DispatchQueue.global().async {
        let user = context.object(with: objectID) as! User
        print(user.name)  // Thread-confinement violation!
    }
    
    // ✅ SAFE
    backgroundContext.perform {
        let user = backgroundContext.object(with: objectID) as! User
        print(user.name)  // Safe - on correct thread
    }
    

Hard-Coded Store Deletion

  • SetupManager.swift:89 - FileManager.removeItem(storeURL) in production code path
    • Risk: Permanent data loss for all users who hit this code path
    • Typical scenario: 10,000 users → 10,000 uninstalls + 1-star reviews
    • Fix: Remove or gate behind debug flag
    // Option 1: Remove entirely
    // Deleted: try? FileManager.default.removeItem(at: storeURL)
    
    // Option 2: Debug-only
    #if DEBUG
    try? FileManager.default.removeItem(at: storeURL)
    #endif
    

Forced Try on Migration

  • PersistenceController.swift:123 - try! coordinator.addPersistentStore(...)
    • Risk: App crashes immediately on launch if migration fails
    • Fix: Add proper error handling
    // ❌ DANGER
    try! coordinator.addPersistentStore(...)  // Crashes if migration fails
    
    // ✅ SAFE
    do {
        try coordinator.addPersistentStore(
            ofType: NSSQLiteStoreType,
            configurationName: nil,
            at: storeURL,
            options: migrationOptions
        )
    } catch {
        // Log error, show user message, attempt recovery
        handleMigrationFailure(error)
    }
    

MEDIUM Issues

N+1 Query Pattern

  • UserListView.swift:89 - Accessing user.posts in loop without prefetching

    • Impact: 1000 users = 1000 extra queries, 30x slower
    • Fix: Prefetch relationships before loop
    // ❌ N+1 PROBLEM
    for user in users {
        print(user.posts.count)  // Fires 1 query per user!
    }
    
    // ✅ SOLUTION
    fetchRequest.relationshipKeyPathsForPrefetching = ["posts"]
    let users = try context.fetch(fetchRequest)
    for user in users {
        print(user.posts.count)  // No extra queries!
    }
    
  • DataSync.swift:201 - Accessing relationships in sync loop

    • Impact: Sync takes 30 seconds instead of 3 seconds
    • Fix: Same as above - prefetch relationships

LOW Issues

Missing Fetch Batch Size

  • FetchController.swift:45 - NSFetchRequest without fetchBatchSize
    • Impact: Higher memory usage with large result sets (10,000 objects loaded at once)
    • Fix: Add batch size
    fetchRequest.fetchBatchSize = 20
    // Loads 20 at a time - lower memory usage
    

Next Steps

  1. Fix CRITICAL issues immediately - Production crash and data loss risk
  2. Fix MEDIUM issues in next sprint - Performance degradation
  3. Test migration on real device with production data copy
  4. Add Core Data unit tests for migration safety

Testing Recommendations

After fixes:

# Test migration safety
1. Install current version on device
2. Add test data
3. Build new version with schema change
4. Install new version
5. Verify: App launches + data intact

# Test thread-confinement
1. Enable Thread Sanitizer in scheme
2. Run app with extensive Core Data usage
3. Check console for thread-confinement warnings

# Test N+1 queries
1. Add logging to fetch requests
2. Run UI with 1000+ items
3. Count queries - should be minimal

For Detailed Diagnosis

Use /skill axiom-core-data-diag for:

  • Comprehensive Core Data diagnostics
  • Production crisis defense scenarios
  • Safe migration patterns
  • Schema change workflows

## Audit Guidelines

1. Run all 5 pattern searches for comprehensive coverage
2. Provide file:line references to make issues easy to locate
3. Show exact fixes with code examples for each issue
4. Categorize by severity to help prioritize fixes
5. Calculate risk score to quantify overall safety level

## When Issues Found

If CRITICAL issues found:
- Emphasize crash risk and data loss
- Recommend fixing before production release
- Provide explicit error handling code examples
- Calculate time to fix (usually 5-20 minutes per issue)

If NO issues found:
- Report "No Core Data safety violations detected"
- Note that runtime testing is still recommended
- Suggest migration testing checklist

## False Positives

These are acceptable (not issues):
- Store deletion behind `#if DEBUG` flag
- One-time migration scripts (not in production code)
- Background context access with proper `perform` blocks
- Small loops (< 10 iterations) may not need prefetching

## Risk Score Calculation

- Each 🔴 CRITICAL issue: +3 points
- Each 🟡 MEDIUM issue: +1 point
- Each 🟢 LOW issue: +0.5 points
- Maximum score: 10

**Interpretation**:
- 0-2: Low risk, production-ready
- 3-5: Medium risk, fix before release
- 6-8: High risk, must fix immediately
- 9-10: Critical risk, do not ship

## Common Findings

From auditing 100+ production codebases:
1. **60% missing lightweight migration options** (most common)
2. **40% have N+1 query patterns** (second most common)
3. **20% have thread-confinement violations** (most dangerous)
4. **10% have hard-coded store deletion** (data loss risk)

## Testing Scenarios

After fixes, test these scenarios:
  1. Schema Migration

    • Add new Core Data attribute
    • Build and run on device with existing data
    • Verify: App launches + data migrates + new attribute works
  2. Thread-Safety

    • Enable Thread Sanitizer
    • Use Core Data from background queues
    • Verify: No thread-confinement warnings
  3. Performance

    • Load 1000+ items in list
    • Scroll through all items
    • Verify: < 10 database queries total (not 1000+)
  4. Production Simulation

    • Test on real device (not simulator)
    • Use production data size (1000+ records)
    • Monitor memory usage and query count

## Summary

This audit scans for:
- **5 categories** covering 90% of Core Data production issues
- **3 CRITICAL patterns** that cause crashes or data loss
- **2 MEDIUM patterns** that cause performance degradation

**Fix time**: Most issues take 5-20 minutes each. Total audit + fixes typically < 2 hours.

**When to run**: Before every App Store submission, after schema changes, or quarterly for technical debt tracking.