This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-swift-concurrency-actor-thread-confinement

KMP 2.1 Swift Concurrency Direct Interop Actor Thread Confinement

Enforces strict thread-confinement boundaries and explicit cooperative dispatch when bridging Kotlin Multiplatform (KMP 2.1+) suspend functions into Swift structured actors. Prevents cooperative thread-pool exhaustion, unmanaged continuation context switching, and cross-runtime reentrancy deadlocks between Swift's actor executors and Kotlin's Dispatchers.Default/Main thread pools.

Prohibited Anti-Pattern: Unchecked Suspension Bridging Across Isolated Swift Actors and Kotlin Coroutine Dispatchers Causing Thread-Pool Starvation and Reentrancy Deadlocks

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: KMP 2.1 Swift Concurrency Direct Interop Actor Thread Confinement - Enforces strict thread-confinement boundaries and explicit cooperative dispatch when bridging Kotlin Multiplatform (KMP 2.1+) suspend functions into Swift structured actors. Prevents cooperative thread-pool exhaustion, unmanaged continuation context switching, and cross-runtime reentrancy deadlocks between Swift's actor executors and Kotlin's Dispatchers.Default/Main thread pools.
globs: iosApp/**/*.swift, shared/src/iosMain/**/*.kt, shared/src/commonMain/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-swift-concurrency-actor-thread-confinement"
---

# KMP 2.1 Swift Concurrency Direct Interop Actor Thread Confinement

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Unchecked Suspension Bridging Across Isolated Swift Actors and Kotlin Coroutine Dispatchers Causing Thread-Pool Starvation and Reentrancy Deadlocks

## System Constraints
You are a Principal Mobile Architect enforcing rock-solid concurrency safety between Kotlin Multiplatform 2.1+ and Apple Swift Concurrency. You mandate non-blocking cross-runtime interop, non-reentrant actor execution, explicit cancellation propagation, and explicit thread hop management between Kotlin Native's worker runtimes and Swift's cooperative pool.

## Strict Guidelines
- Engineers MUST ALWAYS isolate Kotlin Coroutine suspend bridge calls within dedicated Swift nonisolated async contexts or decouple actor state mutations before invoking foreign Kotlin suspend functions.
- Engineers MUST NOT synchronously await a Kotlin suspend function directly inside a Swift actor's synchronized execution boundary without yielding actor-isolated state or handling reentrant state mutations across suspension points.
- Code MUST explicitly propagate Swift Task cancellation tokens down to Kotlin's kotlinx.coroutines.Job instances via Kotlin's CoroutineScope cancellation interop mechanisms.
- Services MUST ensure Kotlin Native suspend entry points exposed via ObjC/Swift export dispatch onto appropriate thread pools (Dispatchers.Default or Dispatchers.Main) and never block cooperative Swift worker threads.
- Components NEVER hold mutual cross-runtime references (e.g., an actor holding a direct StrongReference to a Kotlin stateful engine that simultaneously retains a Swift completion continuation handler) to eliminate deadlocks and retain cycles.

## Bad vs Good Implementations
### Cross-Runtime Suspension on Swift Actor with State Invalidation Protection

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Directly awaiting a Kotlin suspend interop function within an isolated actor boundary leaves the actor open to reentrancy bugs and cooperative thread starvation if Kotlin's dispatcher blocks on an operation awaiting Swift's runtime.
```swift
import Shared

actor AccountSessionManager {
    private var sessionState: SessionState = .idle
    private let kotlinAuthRepository: KotlinAuthRepository

    init(repository: KotlinAuthRepository) {
        self.kotlinAuthRepository = repository
    }

    // CRITICAL BUG: Calling foreign Kotlin suspend interop directly inside actor-isolated method
    // while holding mutable state. An interleaved call across suspension points violates invariant
    // and can cause deadlock if Kotlin dispatches back onto Swift's main/cooperative queue.
    func authenticate(token: String) async throws -> SessionState {
        sessionState = .authenticating
        // Direct call to Kotlin suspend export bridging as async throws
        let result = try await kotlinAuthRepository.authenticateUser(token: token)
        sessionState = .authenticated(user: result.user)
        return sessionState
    }
}
```

#### Production Standard (Correct)
> **Standard**: Decouples the Kotlin Native suspend invocation onto a detached Swift task, protects actor-isolated state invariants against reentrancy mutations across suspensions, and guarantees clear error unwinding and cancellation propagation.
```swift
import Shared

actor AccountSessionManager {
    private var sessionState: SessionState = .idle
    private var activeAuthTask: Task<UserProfile, Error>?
    private let kotlinAuthRepository: KotlinAuthRepository

    init(repository: KotlinAuthRepository) {
        self.kotlinAuthRepository = repository
    }

    func authenticate(token: String) async throws -> SessionState {
        // Cooperative deduplication / cancellation check
        if let currentTask = activeAuthTask {
            _ = try await currentTask.value
            return sessionState
        }

        sessionState = .authenticating
        let repo = self.kotlinAuthRepository

        // Confinement boundary: Execute foreign Kotlin suspend call in decoupled nonisolated Task
        let task = Task.detached {
            try Task.checkCancellation()
            return try await repo.authenticateUser(token: token)
        }
        self.activeAuthTask = task

        do {
            let user = try await task.value
            self.activeAuthTask = nil
            // Guard against actor reentrancy: check state is still valid post-suspension
            guard case .authenticating = self.sessionState else {
                throw CancellationError()
            }
            self.sessionState = .authenticated(user: user)
            return self.sessionState
        } catch {
            self.activeAuthTask = nil
            self.sessionState = .idle
            throw error
        }
    }
}
```

Recommended MCP Servers (mcp-serverlist.com)

Equip agent with system tools to verify code for this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: KMP 2.1 Swift Concurrency Direct Interop Actor Thread Confinement

KMP 2.1 Swift Concurrency Direct Interop Actor Thread Confinement defines an industrial-grade behavioral standard for mobile engineering. Enforces strict thread-confinement boundaries and explicit cooperative dispatch when bridging Kotlin Multiplatform (KMP 2.1+) suspend functions into Swift structured actors. Prevents cooperative thread-pool exhaustion, unmanaged continuation context switching, and cross-runtime reentrancy deadlocks between Swift's actor executors and Kotlin's Dispatchers.Default/Main thread pools. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.

Framework Paradigm Shift & Drift MechanicsLLMs are trained on millions of open-source repositories containing outdated code, legacy idioms, and unpatched antipatterns. When coding assistants generate implementations for this stack, they default to common statistical tokens: Unchecked Suspension Bridging Across Isolated Swift Actors and Kotlin Coroutine Dispatchers Causing Thread-Pool Starvation and Reentrancy Deadlocks Without an explicit system instruction file, developers spend hours debugging silent failures.
Failure Modes & Production Blast Radius

Hazard Analysis: What Breaks Without This Rule

The following failure modes have been cataloged from hundreds of hours of production code reviews where AI assistants produced non-compliant implementations:

Failure ModeAI Symptom (The Anti-Pattern)SeverityProduction Impact & Remedy
AI Hallucination & Deprecation DriftUnchecked Suspension Bridging Across Isolated Swift Actors and Kotlin Coroutine Dispatchers Causing Thread-Pool Starvation and Reentrancy DeadlocksCritical
Violating this industrial standard introduces regression bugs, security risks, and unexpected runtime failures in production.
Enforce explicit behavioral system directives across all AI coding assistants in your repository.
Silent Architecture InconsistencyAI assistants produce mixed paradigms across files, creating fragmented codebase conventions.Medium
Increases cognitive load during code reviews and leads to maintenance debt across engineering teams.
Pin project conventions in .cursor/rules, CLAUDE.md, and AGENTS.md so all team agents follow identical guardrails.
Architectural Directives in Detail

Step-by-Step Production Directives

Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:

1

Engineers MUST ALWAYS isolate Kotlin Coroutine suspend bridge calls within dedicated Swift nonisolated async contexts or decouple actor state mutations before invoking foreign Kotlin suspend functions.

Engineers MUST ALWAYS isolate Kotlin Coroutine suspend bridge calls within dedicated Swift nonisolated async contexts or decouple actor state mutations before invoking foreign Kotlin suspend functions.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
2

Engineers MUST NOT synchronously await a Kotlin suspend function directly inside a Swift actor's synchronized execution boundary without yielding actor-isolated state or handling reentrant state mutations across suspension points.

Engineers MUST NOT synchronously await a Kotlin suspend function directly inside a Swift actor's synchronized execution boundary without yielding actor-isolated state or handling reentrant state mutations across suspension points.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
3

Code MUST explicitly propagate Swift Task cancellation tokens down to Kotlin's kotlinx.coroutines.Job instances via Kotlin's CoroutineScope cancellation interop mechanisms.

Code MUST explicitly propagate Swift Task cancellation tokens down to Kotlin's kotlinx.coroutines.Job instances via Kotlin's CoroutineScope cancellation interop mechanisms.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
4

Services MUST ensure Kotlin Native suspend entry points exposed via ObjC/Swift export dispatch onto appropriate thread pools (Dispatchers.Default or Dispatchers.Main) and never block cooperative Swift worker threads.

Services MUST ensure Kotlin Native suspend entry points exposed via ObjC/Swift export dispatch onto appropriate thread pools (Dispatchers.Default or Dispatchers.Main) and never block cooperative Swift worker threads.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
5

Components NEVER hold mutual cross-runtime references (e.g., an actor holding a direct StrongReference to a Kotlin stateful engine that simultaneously retains a Swift completion continuation handler) to eliminate deadlocks and retain cycles.

Components NEVER hold mutual cross-runtime references (e.g., an actor holding a direct StrongReference to a Kotlin stateful engine that simultaneously retains a Swift completion continuation handler) to eliminate deadlocks and retain cycles.

Rationale:AI models frequently generate unconstrained code here because statistical language distributions lack project-specific architectural context. Mandating this directive ensures that generated code adheres to verified industrial production requirements.
Enforcement:Integrated into the Agent Pack rule file. When Cursor, Claude Code, or Codex processes this prompt, it applies this constraint before emitting syntax.
Technical Questions & Answers

Frequently Asked Technical Questions

Common questions developers face when configuring AI coding assistants for this stack:

Q:Why is KMP 2.1 Swift Concurrency Direct Interop Actor Thread Confinement critical for AI coding assistants?

Enforces strict thread-confinement boundaries and explicit cooperative dispatch when bridging Kotlin Multiplatform (KMP 2.1+) suspend functions into Swift structured actors. Prevents cooperative thread-pool exhaustion, unmanaged continuation context switching, and cross-runtime reentrancy deadlocks between Swift's actor executors and Kotlin's Dispatchers.Default/Main thread pools. Without explicit behavioral boundaries, AI coding assistants (Cursor, Claude Code, Windsurf, Codex) rely on training data averages, which frequently produce deprecated, inefficient, or vulnerable code patterns.

Q:How does adopting this rule prevent AI hallucinations?

This rule explicitly declares what the AI must avoid (Unchecked Suspension Bridging Across Isolated Swift Actors and Kotlin Coroutine Dispatchers Causing Thread-Pool Starvation and Reentrancy Deadlocks) and prescribes verified positive examples. Grounding the LLM with negative and positive pairs eliminates guesswork.

Q:Which AI coding environments are supported?

This specification is multi-platform compatible: Cursor (.cursor/rules/*.mdc & .cursorrules), Anthropic Claude Code (CLAUDE.md), Windsurf (.windsurfrules), Codex / Cline (AGENTS.md), and GitHub Copilot (.github/copilot-instructions.md).

Q:Can I combine this rule with other technology stacks?

Yes. Use the Interactive Stack Builder or download an Agent Pack to merge this rule with other frontend, backend, database, security, and DevOps rules without syntax collision.

Open Specification · CC BY 4.0·Free for Personal, Team & Commercial In-Repo Use

Citation & Open Source Attribution Guidelines

This specification is licensed under Creative Commons Attribution 4.0 International (CC BY 4.0). You are completely free to adapt and share this rule in your workspace. If citing, including in public AI benchmark datasets, or redistributing, attribution to AgentRules.org is required.

Related MOBILE Rules

View all rules →
1 Rule in Stack

KMP