home / skills / tomkrikorian / visionosagents / coding-standards-enforcer

coding-standards-enforcer skill

/skills/coding-standards-enforcer

This skill enforces Swift 6.2 concurrency and language standards across the repository, identifying violations and suggesting fixes during reviews.

npx playbooks add skill tomkrikorian/visionosagents --skill coding-standards-enforcer

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
5.8 KB
---
name: coding-standards-enforcer
description: Enforce repository coding standards for Swift 6.2 concurrency, Swift language rules. Use when reviewing or implementing Swift code changes.
---

# Coding Standards Enforcer

## Description and Goals

This skill enforces repository-wide coding standards for Swift 6.2 concurrency, Swift language rules, and best practices. It ensures all Swift code in the repository follows consistent patterns, uses modern Swift APIs, and adheres to strict concurrency requirements.

### Goals

- Ensure compliance with Swift 6.2 strict concurrency rules
- Enforce modern Swift language patterns and APIs
- Prevent common concurrency mistakes and anti-patterns
- Maintain consistent code style across the repository
- Support Swift 6 migration and best practices

## What This Skill Should Do

When reviewing or implementing Swift code changes, this skill should:

1. **Enforce concurrency rules** - Ensure all code follows Swift 6.2 strict concurrency requirements
2. **Check language standards** - Verify use of modern Swift APIs and patterns
3. **Identify violations** - Scan for common mistakes and anti-patterns
4. **Suggest fixes** - Provide guidance on how to correct violations
5. **Maintain consistency** - Ensure code follows repository-wide standards

Use this skill whenever you add, modify, or review Swift code in this repo.

## Information About the Skill

### Workflow

1. Identify the files and changes in scope.
2. Scan for violations of the rules below.
3. Apply fixes or call out deviations explicitly.

### Swift Concurrency Guidelines

#### Core Mental Model

Think in isolation domains rather than threads:

- `MainActor` is the UI lane and must own UI state.
- `actor` types protect their own mutable state.
- `nonisolated` code is shared and cannot touch actor state.
- `Sendable` types are safe to move across domains.

#### Strict Concurrency

Swift 6.2 defaults to `@MainActor` isolation for Views and UI logic. Assume strict isolation checks are active. Everything is `@MainActor` by default.

#### Async and Parallel Work

```swift
func fetchUser(id: Int) async throws -> User {
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode(User.self, from: data)
}

async let avatar = fetchImage("avatar.jpg")
async let banner = fetchImage("banner.jpg")
let profile = Profile(avatar: try await avatar, banner: try await banner)
```

#### Tasks and Task Groups

```swift
.task { avatar = await downloadAvatar() }

Task { await saveProfile() }

try await withThrowingTaskGroup(of: Void.self) { group in
    group.addTask { avatar = try await downloadAvatar() }
    group.addTask { bio = try await fetchBio() }
    try await group.waitForAll()
}
```

#### Isolation Domains

```swift
@MainActor
final class ViewModel {
    var items: [Item] = []
}

actor BankAccount {
    var balance: Double = 0
    func deposit(_ amount: Double) { balance += amount }
}
```

#### Approachable Concurrency Settings (Swift 6.2+)

- `SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor` keeps UI code on the main actor by default.
- `SWIFT_APPROACHABLE_CONCURRENCY = YES` keeps nonisolated async on the caller's actor.

```swift
@concurrent func processLargeFile() async { }
```

#### Sendable

```swift
struct User: Sendable {
    let id: Int
    let name: String
}

final class ThreadSafeCache: @unchecked Sendable {
    private let lock = NSLock()
    private var storage: [String: Data] = [:]
}
```

#### Isolation Inheritance

- `Task { }` inherits the current actor.
- `Task.detached { }` does not inherit isolation and should be rare.

#### Background Tasks

Move heavy physics/data work off the main actor using `@concurrent` functions or dedicated actors.

#### Task Management

Cancel long-running tasks on teardown.

#### Common Mistakes to Avoid

- Treating `async` as automatic background work.
- Creating many actors when `@MainActor` is sufficient.
- Using `MainActor.run` when the enclosing function can be annotated.
- Blocking async code with `DispatchSemaphore` or `DispatchGroup.wait()`.
- Spawning unstructured `Task` instances instead of `async let` or task groups.

#### Quick Reference

- `async` and `await` for suspension points.
- `Task { }` for structured async work.
- `actor` for isolated mutable state.
- `Sendable` for cross-actor data transfer.

### Swift Language Standards

#### Observable Classes

`@Observable` classes are `@MainActor` by default, so explicit `@MainActor` annotation is not needed and should always be removed.

#### Observation vs Combine

- Prefer `@Observable` + `@State` for reference-type models.
- Avoid `ObservableObject`, `@StateObject`, and `@ObservedObject` unless interacting with legacy code that still requires Combine.

#### Swift-Native APIs

Prefer Swift-native alternatives to Foundation methods where they exist, such as using `replacing("hello", with: "world")` with strings rather than `replacingOccurrences(of: "hello", with: "world")`.

#### Modern Foundation API

Prefer modern Foundation API, for example `URL.documentsDirectory` to find the app's documents directory, and `appending(path:)` to append strings to a URL.

#### Number Formatting

Never use C-style number formatting such as `Text(String(format: "%.2f", abs(myNumber)))`; always use `Text(abs(change), format: .number.precision(.fractionLength(2)))` instead.

#### Static Member Lookup

Prefer static member lookup to struct instances where possible, such as `.circle` rather than `Circle()`, and `.borderedProminent` rather than `BorderedProminentButtonStyle()`.

#### Modern Concurrency

Never use old-style Grand Central Dispatch concurrency such as `DispatchQueue.main.async()`. If behavior like this is needed, always use modern Swift concurrency.

#### Text Filtering

Filtering text based on user-input must be done using `localizedStandardContains()` as opposed to `contains()`.

#### Force Unwraps

Avoid force unwraps and force `try` unless it is unrecoverable.

Overview

This skill enforces repository-wide Swift 6.2 coding standards with a focus on strict concurrency and modern language patterns. It scans Swift changes, identifies violations, and suggests concrete fixes to keep code safe, consistent, and migration-ready. Use it when reviewing or implementing Swift code for visionOS or other Swift 6.2 projects.

How this skill works

The skill inspects changed Swift files and evaluates concurrency annotations, actor usage, Sendable conformance, async patterns, and modern API usage. It flags anti-patterns (legacy GCD, force unwraps, improper observation types), explains the violation, and provides code-level recommendations or replacements. It also enforces repository conventions like avoiding explicit @MainActor on @Observable classes and preferring Swift-native APIs.

When to use it

  • When adding or modifying Swift UI, view models, or business logic code
  • During pull request reviews to enforce Swift 6.2 strict concurrency rules
  • When migrating legacy code to modern Swift concurrency and APIs
  • Before merging changes that touch cross-thread or stateful code
  • When implementing background or parallel work for performance

Best practices

  • Prefer actor types or @MainActor for state isolation; avoid sharing mutable state across domains
  • Use async let, Task, and task groups for structured concurrency; reserve Task.detached for rare cases
  • Mark value types Sendable and prefer immutable data for cross-actor transfer
  • Replace GCD/DispatchQueue usage with modern async/await and @concurrent where appropriate
  • Avoid force unwraps and force try; prefer safe error handling and formatted Text APIs

Example use cases

  • Validate a pull request that introduces network calls and ensure correct await/task usage
  • Refactor a ViewModel to remove Combine ObservableObject in favor of @Observable and @State patterns
  • Scan code for data races and suggest actor or Sendable conversions for shared state
  • Convert string and URL API usages to Swift-native and modern Foundation equivalents
  • Review background workload to ensure heavy tasks run off the main actor and cancel on teardown

FAQ

Will this skill rewrite code automatically?

It can suggest precise fixes and small automated edits, but large refactors should be reviewed and applied by maintainers.

How does it handle legacy Combine-based code?

It flags Combine types like ObservableObject/@StateObject as legacy where modern @Observable patterns exist, and recommends migration guidance while allowing exceptions when legacy integration is required.