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

Kotlin Multiplatform to Swift Structured Concurrency Bi-Directional Cancellation Guardrail

Enforces deterministic, bidirectional propagation between Swift Structured Concurrency Task cancellation and Kotlin Coroutines Job cancellation across the Objective-C/C export boundary. Eliminates orphaned worker threads, uncollected completion closures, and unmanaged memory retention across Swift-KMP module boundaries.

Prohibited Anti-Pattern: Orphaned Kotlin Coroutines and Leaked Native Continuations via Unhandled Swift Task Cancellation

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: Kotlin Multiplatform to Swift Structured Concurrency Bi-Directional Cancellation Guardrail - Enforces deterministic, bidirectional propagation between Swift Structured Concurrency Task cancellation and Kotlin Coroutines Job cancellation across the Objective-C/C export boundary. Eliminates orphaned worker threads, uncollected completion closures, and unmanaged memory retention across Swift-KMP module boundaries.
globs: iosApp/**/*.swift, shared/src/iosMain/**/*.kt, shared/src/appleMain/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-swift-concurrency-cancellation-bridge-barrier"
---

# Kotlin Multiplatform to Swift Structured Concurrency Bi-Directional Cancellation Guardrail

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Orphaned Kotlin Coroutines and Leaked Native Continuations via Unhandled Swift Task Cancellation

## System Constraints
You are a Principal Mobile Architect enforcing bulletproof Kotlin Multiplatform (KMP) and Swift Concurrency interoperability. You must strictly mandate bidirectional cancellation contracts between Swift's `Task` tree and Kotlin's `Job` hierarchy. Reject any unmanaged `withCheckedThrowingContinuation` or raw callback-based Kotlin suspend bridge that ignores cooperative cancellation or leaks native dispatch closures.

## Strict Guidelines
- Engineers MUST ALWAYS wrap Kotlin suspend bridges inside `withTaskCancellationHandler` or use vetted tools (e.g., SKIE or KMP-NativeCoroutines) that register an active `onCancel` handler to cancel the underlying Kotlin `Job`.
- Engineers MUST NOT bridge Kotlin suspend functions into Swift using bare `withCheckedContinuation` or `withCheckedThrowingContinuation` without binding `onCancel` to the returned cancellable handle.
- Code SHOULD immediately propagate Swift Task cancellation by issuing `job.cancel(cause: CancellationException)` to prevent background thread starvation and CPU battery drain.
- Services MUST ensure that cancellation cleanup on the Kotlin side immediately triggers the Swift continuation with a `CancellationError` rather than leaving the continuation dangling forever.
- Components NEVER retain strong references to Swift continuations inside long-lived Kotlin native structures without nullifying them upon invocation or cancellation.

## Bad vs Good Implementations
### Bridging Kotlin Suspend to Swift async/await with Task Cancellation

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: The continuation ignores Swift's Task cancellation tree entirely. When the Swift caller cancels, the KMP Job keeps executing on the Kotlin dispatcher, causing orphaned thread execution, duplicate side effects, and leaks of the completion closure.
```swift
// BAD: Suspended Kotlin execution is decoupled from Swift Task lifecycle.
// If the calling Swift Task is cancelled (e.g. view dismissed), the Kotlin Coroutine
// continues running indefinitely in the background, leaking memory and network resources.
func fetchUserProfile(id: String) async throws -> UserProfile {
    return try await withCheckedThrowingContinuation { continuation in
        UserProfileRepository().fetchUser(id: id) { profile, error in
            if let error = error {
                continuation.resume(throwing: error)
            } else if let profile = profile {
                continuation.resume(returning: profile)
            }
        }
    }
}
```

#### Production Standard (Correct)
> **Standard**: The bridge couples the Swift Task cancellation signal directly to the Kotlin Coroutine via `withTaskCancellationHandler`. When the caller cancels, `onCancel` immediately invokes `cancel()` on the Kotlin handle, freeing resources across the runtime barrier.
```swift
// GOOD: Bidirectional cancellation bridge using withTaskCancellationHandler and Job cancellation handle.
import SharedKit

func fetchUserProfile(id: String) async throws -> UserProfile {
    let repository = UserProfileRepository()
    var cancellableJob: CancellableTask? = nil
    
    return try await withTaskCancellationHandler {
        try Task.checkCancellation()
        return try await withCheckedThrowingContinuation { continuation in
            cancellableJob = repository.fetchUserCancellable(id: id) { profile, error in
                if let error = error {
                    if error is KotlinCancellationException {
                        continuation.resume(throwing: CancellationError())
                    } else {
                        continuation.resume(throwing: error)
                    }
                } else if let profile = profile {
                    continuation.resume(returning: profile)
                } else {
                    continuation.resume(throwing: BridgeError.unexpectedNilState)
                }
            }
        }
    } onCancel: {
        cancellableJob?.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 Structured Concurrency Bi-Directional Cancellation Guardrail

Kotlin Multiplatform to Swift Structured Concurrency Bi-Directional Cancellation Guardrail defines an industrial-grade behavioral standard for mobile engineering. Enforces deterministic, bidirectional propagation between Swift Structured Concurrency Task cancellation and Kotlin Coroutines Job cancellation across the Objective-C/C export boundary. Eliminates orphaned worker threads, uncollected completion closures, and unmanaged memory retention across Swift-KMP module boundaries. 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: Orphaned Kotlin Coroutines and Leaked Native Continuations via Unhandled Swift Task Cancellation 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 DriftOrphaned Kotlin Coroutines and Leaked Native Continuations via Unhandled Swift Task CancellationCritical
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 wrap Kotlin suspend bridges inside `withTaskCancellationHandler` or use vetted tools (e.g., SKIE or KMP-NativeCoroutines) that register an active `onCancel` handler to cancel the underlying Kotlin `Job`.

Engineers MUST ALWAYS wrap Kotlin suspend bridges inside `withTaskCancellationHandler` or use vetted tools (e.g., SKIE or KMP-NativeCoroutines) that register an active `onCancel` handler to cancel the underlying Kotlin `Job`.

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 bridge Kotlin suspend functions into Swift using bare `withCheckedContinuation` or `withCheckedThrowingContinuation` without binding `onCancel` to the returned cancellable handle.

Engineers MUST NOT bridge Kotlin suspend functions into Swift using bare `withCheckedContinuation` or `withCheckedThrowingContinuation` without binding `onCancel` to the returned cancellable handle.

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 SHOULD immediately propagate Swift Task cancellation by issuing `job.cancel(cause

Code SHOULD immediately propagate Swift Task cancellation by issuing `job.cancel(cause: CancellationException)` to prevent background thread starvation and CPU battery drain.

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 that cancellation cleanup on the Kotlin side immediately triggers the Swift continuation with a `CancellationError` rather than leaving the continuation dangling forever.

Services MUST ensure that cancellation cleanup on the Kotlin side immediately triggers the Swift continuation with a `CancellationError` rather than leaving the continuation dangling forever.

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 retain strong references to Swift continuations inside long-lived Kotlin native structures without nullifying them upon invocation or cancellation.

Components NEVER retain strong references to Swift continuations inside long-lived Kotlin native structures without nullifying them upon invocation or cancellation.

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 Structured Concurrency Bi-Directional Cancellation Guardrail critical for AI coding assistants?

Enforces deterministic, bidirectional propagation between Swift Structured Concurrency Task cancellation and Kotlin Coroutines Job cancellation across the Objective-C/C export boundary. Eliminates orphaned worker threads, uncollected completion closures, and unmanaged memory retention across Swift-KMP module boundaries. 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 (Orphaned Kotlin Coroutines and Leaked Native Continuations via Unhandled Swift Task Cancellation) 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