This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-swift-export-memory-boundary-guardrail

KMP 2.1 Swift-Export and Swift 6 Actor Memory Domain Isolation

Enforces strict memory domain boundaries between Kotlin Native garbage collection and Swift 6 Sendable/Actor concurrency domains across direct Swift-Export bridges. Prevents illegal cross-thread mutation of Kotlin reference types, ARC race conditions, and InvalidMutability/Segmentation Faults by mandating value-semantic DTO transfers, explicit @Sendable wrapping, and cancellation token propagation across the bridge.

Prohibited Anti-Pattern: Leaking Mutable Kotlin Native Object Graphs Directly into Swift 6 Concurrency Domains Without Boundary Freezing or Value Projection

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: KMP 2.1 Swift-Export and Swift 6 Actor Memory Domain Isolation - Enforces strict memory domain boundaries between Kotlin Native garbage collection and Swift 6 Sendable/Actor concurrency domains across direct Swift-Export bridges. Prevents illegal cross-thread mutation of Kotlin reference types, ARC race conditions, and InvalidMutability/Segmentation Faults by mandating value-semantic DTO transfers, explicit @Sendable wrapping, and cancellation token propagation across the bridge.
globs: **/*.kt, **/*.swift, **/swiftExportConfig.json, **/build.gradle.kts
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-swift-export-memory-boundary-guardrail"
---

# KMP 2.1 Swift-Export and Swift 6 Actor Memory Domain Isolation

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Leaking Mutable Kotlin Native Object Graphs Directly into Swift 6 Concurrency Domains Without Boundary Freezing or Value Projection

## System Constraints
You are a Principal Mobile Architect enforcing strict memory domain isolation between Kotlin Native (KMP 2.1+) and Swift 6 via Swift-Export. You must prevent invalid reference sharing, ARC/GC synchronization deadlocks, and cross-thread mutation across the FFI runtime bridge.

## Strict Guidelines
- Engineers MUST ALWAYS project public cross-platform bridge APIs using immutable data classes or value-typed structs (`Sendable` structs in Swift, `@Immutable` data classes in Kotlin) rather than sharing stateful class instances across the bridge boundary.
- Engineers MUST NOT expose mutable Kotlin collections (e.g., `MutableList`, `MutableMap`, `Array`) or mutable shared state (`MutableStateFlow`) directly to Swift 6 actors.
- Engineers MUST ALWAYS bridge asynchronous streams via explicit unbuffered snapshot sequences or unidirectional snapshot protocols, ensuring each emitted element satisfies `Sendable` conformance in Swift.
- Engineers MUST encapsulate any bridged Kotlin reference type held inside a Swift 6 `actor` using `@preconcurrency import` with explicit synchronization, or isolate it within a dedicated single-threaded executor if Swift-Export treats it as non-Sendable.
- Engineers MUST NEVER allow bi-directional long-lived object references across the Swift-Kotlin bridge without explicit lifecycle management (`AtomicReference` or deterministic `close()` / dispose methods) to avoid native memory leaks between Darwin ARC and Kotlin Native GC.

## Bad vs Good Implementations
### Direct Bridging of Mutable Flow vs Value-Isolated Swift-Export Boundary

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Directly exposing a mutable reference (or mutable flow) across the KMP Swift-Export boundary allows Swift actors to interact concurrently with Kotlin Native internal locks, breaking Swift 6 data-race safety invariants and risking undefined behavior in Kotlin's memory manager.
```kotlin
// BAD: Exposing mutable state reference across the Swift-Export bridge
package com.example.analytics

import kotlinx.coroutines.flow.MutableStateFlow

class SessionManager {
    // Exposes a mutable state engine directly across the bridge.
    // Swift 6 actors modifying or collecting this will trigger cross-arena ARC race conditions.
    val currentSessionFlow = MutableStateFlow<SessionMetadata?>(null)

    fun mutateSession(token: String) {
        currentSessionFlow.value = currentSessionFlow.value?.copy(token = token)
    }
}
```

#### Production Standard (Correct)
> **Standard**: Kotlin Native provides immutable data snapshots across the boundary. Operations are mediated through explicit coroutine suspension points rather than raw shared mutable state flows, preventing illegal memory mutations from foreign threads.
```kotlin
// GOOD: Boundary isolation with immutable DTO projections and structured suspension
package com.example.analytics

import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.MutableStateFlow

// Explicitly value-like and immutable
data class SessionSnapshot(
    val sessionId: String,
    val token: String,
    val issuedAtEpochMs: Long
)

class SessionManager private constructor() {
    private val _sessions = MutableStateFlow<SessionSnapshot?>(null)

    // Expose only immutable projection via suspend functions or snapshot getters
    suspend fun getActiveSession(): SessionSnapshot? = _sessions.value

    suspend fun updateToken(newToken: String): SessionSnapshot {
        val current = _sessions.value ?: throw IllegalStateException("Session uninitialized")
        val updated = current.copy(token = newToken)
        _sessions.value = updated
        return updated // Returns immutable value snapshot safe for Swift Sendable adoption
    }

    companion object {
        fun create(): SessionManager = SessionManager()
    }
}
```

### Swift 6 Actor Ingestion of Kotlin Exported Types

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The Kotlin `SessionManager` class is not recognized as `Sendable` under Swift 6 compiler modes. Retaining and mutating it directly inside a Swift actor triggers concurrency diagnostic errors or runtime race conditions between Darwin threads and Kotlin memory runtimes.
```swift
// BAD: Ingesting bridged non-Sendable Kotlin reference directly across an actor boundary
import SharedExport

actor AnalyticsStore {
    private var sessionManager: SessionManager? = nil

    func bind(manager: SessionManager) {
        // Error in Swift 6: Passing non-Sendable parameter `SessionManager` across actor isolation
        self.sessionManager = manager
    }

    func performBackgroundSync() async {
        // Unsafe concurrent access to Kotlin reference from Swift actor thread pool
        sessionManager?.mutateSession(token: "new_token")
    }
}
```

#### Production Standard (Correct)
> **Standard**: The Swift actor never manages live cross-runtime references directly. It only ingests immutable value DTOs (`SessionSnapshot`), safely crossing the actor domain and preventing Kotlin Native concurrent pointer mutations.
```swift
// GOOD: Boundary isolation with Sendable value transfer and isolated bridge wrappers
import SharedExport

// Conform bridged Kotlin data class to Sendable via extension when fields are immutable
extension SessionSnapshot: @unchecked Sendable {}

actor AnalyticsStore {
    // The actor stores strictly Sendable value snapshots, not the live Kotlin object engine
    private var currentSession: SessionSnapshot? = nil

    func ingest(snapshot: SessionSnapshot) {
        self.currentSession = snapshot
    }

    func sync(using bridge: SessionManager) async throws {
        // Execution occurs on caller's context or strictly isolated task,
        // receiving only an immutable snapshot into actor memory domain
        let updatedSnapshot = try await bridge.updateToken(newToken: "new_token")
        self.currentSession = updatedSnapshot
    }
}
```

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: KMP 2.1 Swift-Export and Swift 6 Actor Memory Domain Isolation

KMP 2.1 Swift-Export and Swift 6 Actor Memory Domain Isolation defines an industrial-grade behavioral standard for mobile engineering. Enforces strict memory domain boundaries between Kotlin Native garbage collection and Swift 6 Sendable/Actor concurrency domains across direct Swift-Export bridges. Prevents illegal cross-thread mutation of Kotlin reference types, ARC race conditions, and InvalidMutability/Segmentation Faults by mandating value-semantic DTO transfers, explicit @Sendable wrapping, and cancellation token propagation across the bridge. 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: Leaking Mutable Kotlin Native Object Graphs Directly into Swift 6 Concurrency Domains Without Boundary Freezing or Value Projection 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 DriftLeaking Mutable Kotlin Native Object Graphs Directly into Swift 6 Concurrency Domains Without Boundary Freezing or Value ProjectionCritical
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 project public cross-platform bridge APIs using immutable data classes or value-typed structs (`Sendable` structs in Swift, `@Immutable` data classes in Kotlin) rather than sharing stateful class instances across the bridge boundary.

Engineers MUST ALWAYS project public cross-platform bridge APIs using immutable data classes or value-typed structs (`Sendable` structs in Swift, `@Immutable` data classes in Kotlin) rather than sharing stateful class instances across the bridge boundary.

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 expose mutable Kotlin collections (e.g., `MutableList`, `MutableMap`, `Array`) or mutable shared state (`MutableStateFlow`) directly to Swift 6 actors.

Engineers MUST NOT expose mutable Kotlin collections (e.g., `MutableList`, `MutableMap`, `Array`) or mutable shared state (`MutableStateFlow`) directly to Swift 6 actors.

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

Engineers MUST ALWAYS bridge asynchronous streams via explicit unbuffered snapshot sequences or unidirectional snapshot protocols, ensuring each emitted element satisfies `Sendable` conformance in Swift.

Engineers MUST ALWAYS bridge asynchronous streams via explicit unbuffered snapshot sequences or unidirectional snapshot protocols, ensuring each emitted element satisfies `Sendable` conformance in Swift.

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

Engineers MUST encapsulate any bridged Kotlin reference type held inside a Swift 6 `actor` using `@preconcurrency import` with explicit synchronization, or isolate it within a dedicated single-threaded executor if Swift-Export treats it as non-Sendable.

Engineers MUST encapsulate any bridged Kotlin reference type held inside a Swift 6 `actor` using `@preconcurrency import` with explicit synchronization, or isolate it within a dedicated single-threaded executor if Swift-Export treats it as non-Sendable.

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

Engineers MUST NEVER allow bi-directional long-lived object references across the Swift-Kotlin bridge without explicit lifecycle management (`AtomicReference` or deterministic `close()` / dispose methods) to avoid native memory leaks between Darwin ARC and Kotlin Native GC.

Engineers MUST NEVER allow bi-directional long-lived object references across the Swift-Kotlin bridge without explicit lifecycle management (`AtomicReference` or deterministic `close()` / dispose methods) to avoid native memory leaks between Darwin ARC and Kotlin Native GC.

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-Export and Swift 6 Actor Memory Domain Isolation critical for AI coding assistants?

Enforces strict memory domain boundaries between Kotlin Native garbage collection and Swift 6 Sendable/Actor concurrency domains across direct Swift-Export bridges. Prevents illegal cross-thread mutation of Kotlin reference types, ARC race conditions, and InvalidMutability/Segmentation Faults by mandating value-semantic DTO transfers, explicit @Sendable wrapping, and cancellation token propagation across the bridge. 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 (Leaking Mutable Kotlin Native Object Graphs Directly into Swift 6 Concurrency Domains Without Boundary Freezing or Value Projection) 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