This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-swift6-strict-concurrency-actor-bridge-kotlin-multiplat-967

Kotlin Multiplatform to Swift 6 Strict Concurrency Actor Bridge Protocol

Eliminates cross-runtime data races and Swift 6 complete concurrency diagnostics when bridging Kotlin Coroutines StateFlow emissions to native iOS UI layers. Mandates explicit actor isolation, Sendable boundary enforcement, and AsyncStream-based ingestion to prevent non-isolated memory corruption across the Kotlin/Native and Swift runtime boundary.

Prohibited Anti-Pattern: Unchecked Raw Interop Flow Collection Across Swift 6 Actor Boundaries Causing Thread Sanitizer Violations and UI State Corruption

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Kotlin Multiplatform to Swift 6 Strict Concurrency Actor Bridge Protocol - Eliminates cross-runtime data races and Swift 6 complete concurrency diagnostics when bridging Kotlin Coroutines StateFlow emissions to native iOS UI layers. Mandates explicit actor isolation, Sendable boundary enforcement, and AsyncStream-based ingestion to prevent non-isolated memory corruption across the Kotlin/Native and Swift runtime boundary.
globs: iosApp/**/*.swift, shared/**/*.kt, **/*ViewModel*.swift, **/*Bridge*.swift, **/*Adapter*.swift
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-swift6-strict-concurrency-actor-bridge-kotlin-multiplat-967"
---

# Kotlin Multiplatform to Swift 6 Strict Concurrency Actor Bridge Protocol

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Unchecked Raw Interop Flow Collection Across Swift 6 Actor Boundaries Causing Thread Sanitizer Violations and UI State Corruption

## System Constraints
You are a Principal Mobile Architect enforcing Swift 6 Strict Concurrency safety across Kotlin Multiplatform interop boundaries. You mandate that no Kotlin/Native interop object is passed across Swift actor boundaries without Sendable verification, and that all Kotlin Coroutine Flows are consumed through isolated AsyncStreams bound to @MainActor.

## Strict Guidelines
- Engineers MUST ALWAYS map mutable or reference-type Kotlin interop states into immutable Swift 'Sendable' structs at the interop entry boundary before passing across actor boundaries.
- Engineers MUST NEVER mutate Swift UI state or assign to @Published / @Observable properties directly from raw Kotlin/Native Flow callback closures.
- Bridge adapters MUST wrap Kotlin CommonFlow/StateFlow into a native Swift 'AsyncStream' or 'AsyncThrowingStream' handling cooperative cancellation and Kotlin disposable handles.
- UI-bound consumer ViewModels in Swift MUST be isolated to '@MainActor' and collect bridged AsyncStreams within a managed, cancellable Task.
- Interop bridge layers MUST NOT use '@unchecked Sendable' on Kotlin/Native interop wrappers unless deep immutability is proven and thread sanitizer passes under Swift 6 strict checking.

## Bad vs Good Implementations
### Bridging Kotlin StateFlow to Swift 6 MainActor ViewModel

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Kotlin/Native Coroutine emissions invoke the collector closure on background runtime threads. Mutating @Published state from an arbitrary thread violates Swift 6 actor isolation, and KotlinUiState is not marked Sendable, triggering compiler diagnostics and data races.
```swift
import SwiftUI
import SharedKit

// ANTI-PATTERN: Direct callback from Kotlin/Native background thread escaping into UI state
class BadBridgeViewModel: ObservableObject {
    @Published var uiState: KotlinUiState = KotlinUiState(items: [])
    private let sharedViewModel: KotlinSharedViewModel = KotlinSharedViewModel()

    func startObserving() {
        // Violates Swift 6 strict concurrency: raw closure invokes non-Sendable Kotlin state
        // across thread boundaries and mutates UI state off the main actor.
        sharedViewModel.stateFlow.collect(collector: FlowCollector { [weak self] rawState in
            self?.uiState = rawState as! KotlinUiState // Thread Sanitizer crash & compiler diagnostic
        })
    }
}
```

#### Production Standard (Correct)
> **Standard**: Encapsulates state emission inside a cancellable Task isolated to @MainActor. Transforms the non-Sendable Kotlin object into an immutable, Sendable Swift struct at the edge, satisfying Swift 6 complete concurrency rules without data races.
```swift
import SwiftUI
import SharedKit

// PRODUCTION FIX: Immutable Sendable Swift representation
public struct SwiftUiState: Sendable, Equatable {
    public let items: [String]

    init(from kotlinState: KotlinUiState) {
        self.items = kotlinState.items.map { String($0) }
    }
}

@MainActor
public final class SafeBridgeViewModel: ObservableObject {
    @Published private(set) var uiState: SwiftUiState = .init(items: [])
    private let sharedViewModel: KotlinSharedViewModel
    private var collectionTask: Task<Void, Never>?

    public init(sharedViewModel: KotlinSharedViewModel) {
        self.sharedViewModel = sharedViewModel
    }

    public func startObserving() {
        collectionTask?.cancel()
        collectionTask = Task { [weak self, sharedViewModel] in
            // Safely stream emissions through an AsyncStream bridge
            for await rawState in sharedViewModel.stateFlow.asAsyncStream() {
                guard !Task.isCancelled else { break }
                let sendableState = SwiftUiState(from: rawState)
                self?.uiState = sendableState
            }
        }
    }

    deinit {
        collectionTask?.cancel()
    }
}
```

Recommended MCP Servers (mcp-serverlist.com)

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

Recommended Agent Skills (askills.dev)

Ready-to-use executable skill functions tailored to this stack.

Architectural Specification & Invariant Rationale

Architectural Invariant Design: Kotlin Multiplatform to Swift 6 Strict Concurrency Actor Bridge Protocol

Kotlin Multiplatform to Swift 6 Strict Concurrency Actor Bridge Protocol defines an industrial-grade behavioral standard for mobile engineering. Eliminates cross-runtime data races and Swift 6 complete concurrency diagnostics when bridging Kotlin Coroutines StateFlow emissions to native iOS UI layers. Mandates explicit actor isolation, Sendable boundary enforcement, and AsyncStream-based ingestion to prevent non-isolated memory corruption across the Kotlin/Native and Swift runtime boundary. 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 Raw Interop Flow Collection Across Swift 6 Actor Boundaries Causing Thread Sanitizer Violations and UI State Corruption 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 Raw Interop Flow Collection Across Swift 6 Actor Boundaries Causing Thread Sanitizer Violations and UI State CorruptionCritical
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 map mutable or reference-type Kotlin interop states into immutable Swift 'Sendable' structs at the interop entry boundary before passing across actor boundaries.

Engineers MUST ALWAYS map mutable or reference-type Kotlin interop states into immutable Swift 'Sendable' structs at the interop entry boundary before passing across actor boundaries.

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 NEVER mutate Swift UI state or assign to @Published / @Observable properties directly from raw Kotlin/Native Flow callback closures.

Engineers MUST NEVER mutate Swift UI state or assign to @Published / @Observable properties directly from raw Kotlin/Native Flow callback closures.

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

Bridge adapters MUST wrap Kotlin CommonFlow/StateFlow into a native Swift 'AsyncStream' or 'AsyncThrowingStream' handling cooperative cancellation and Kotlin disposable handles.

Bridge adapters MUST wrap Kotlin CommonFlow/StateFlow into a native Swift 'AsyncStream' or 'AsyncThrowingStream' handling cooperative cancellation and Kotlin disposable handles.

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

UI-bound consumer ViewModels in Swift MUST be isolated to '@MainActor' and collect bridged AsyncStreams within a managed, cancellable Task.

UI-bound consumer ViewModels in Swift MUST be isolated to '@MainActor' and collect bridged AsyncStreams within a managed, cancellable Task.

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

Interop bridge layers MUST NOT use '@unchecked Sendable' on Kotlin/Native interop wrappers unless deep immutability is proven and thread sanitizer passes under Swift 6 strict checking.

Interop bridge layers MUST NOT use '@unchecked Sendable' on Kotlin/Native interop wrappers unless deep immutability is proven and thread sanitizer passes under Swift 6 strict checking.

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 Kotlin Multiplatform to Swift 6 Strict Concurrency Actor Bridge Protocol critical for AI coding assistants?

Eliminates cross-runtime data races and Swift 6 complete concurrency diagnostics when bridging Kotlin Coroutines StateFlow emissions to native iOS UI layers. Mandates explicit actor isolation, Sendable boundary enforcement, and AsyncStream-based ingestion to prevent non-isolated memory corruption across the Kotlin/Native and Swift runtime boundary. 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 Raw Interop Flow Collection Across Swift 6 Actor Boundaries Causing Thread Sanitizer Violations and UI State Corruption) 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

Kotlin