This specification is maintained by the AgentRules Working Group. Have enhancements or want to claim maintainership?Submit Specification →
mobilecritical PriorityID: kmp-skie-flow-backpressure-guardrail

KMP SKIE Flow-to-AsyncSequence Backpressure & Bounded Buffer Guardrail

Enforces strict bounded buffering and explicit overflow policies on Kotlin Multiplatform Flows exposed to Swift via SKIE. Without explicit backpressure boundaries, mismatched production-consumption rates across the Kotlin/Native and Swift async boundary cause unmonitored queue accumulation, rapid heap exhaustion, and iOS Jetsam terminations during high-frequency streaming.

Prohibited Anti-Pattern: Unbounded Flow Bridging to Swift AsyncSequence Triggering Uncontrolled Memory Growth and Jetsam Kills

Export Ready-to-Drop Configuration

Select format below to copy code or download file directly.

---
description: KMP SKIE Flow-to-AsyncSequence Backpressure & Bounded Buffer Guardrail - Enforces strict bounded buffering and explicit overflow policies on Kotlin Multiplatform Flows exposed to Swift via SKIE. Without explicit backpressure boundaries, mismatched production-consumption rates across the Kotlin/Native and Swift async boundary cause unmonitored queue accumulation, rapid heap exhaustion, and iOS Jetsam terminations during high-frequency streaming.
globs: **/commonMain/**/domain/**/*.kt, **/commonMain/**/presentation/**/*.kt, **/iosApp/**/*.swift, **/iosMain/**/*.kt
alwaysApply: true
verified_by: "agentrules.org"
license: "CC-BY-4.0"
source: "https://agentrules.org/rules/kmp-skie-flow-backpressure-guardrail"
---

# KMP SKIE Flow-to-AsyncSequence Backpressure & Bounded Buffer Guardrail

> **Severity**: CRITICAL | **Category**: mobile
> **Anti-Pattern Warning**: Unbounded Flow Bridging to Swift AsyncSequence Triggering Uncontrolled Memory Growth and Jetsam Kills

## System Constraints
You are a Principal Mobile Architect specializing in Kotlin Multiplatform (KMP) and Swift concurrency interop. You enforce bounded flow control across the SKIE bridge between Kotlin Coroutines (Flow) and Swift (AsyncSequence). Reject any unbounded streaming primitives exposed across the KMP API boundary that lack deterministic backpressure buffer contracts.

## Strict Guidelines
- Engineers MUST ALWAYS declare an explicit bounded buffer strategy (via .buffer() or SharedFlow replay/extraBufferCapacity) with a designated BufferOverflow policy (DROP_OLDEST or DROP_LATEST) on any Flow exported to Swift via SKIE.
- Engineers MUST NOT expose raw unbounded channelFlow, callbackFlow, or default MutableSharedFlow instances directly to iOS consumers without wrapping them in a bounded operator.
- Engineers MUST ensure Swift consumers manage lifecycle-scoped Task cancellation, preventing zombie subscriptions from hanging Kotlin CoroutineScope instances across the Darwin runtime boundary.
- High-frequency event streams (e.g., location, BLE telemetry, real-time WebSockets) MUST specify a maximum buffer capacity not exceeding 64 items unless an explicit high-capacity ring-buffer architecture is formally documented.
- Code SHOULD leverage SKIE's native cancellation propagation by pairing Task cancellation in SwiftUI (.task modifier) with cooperative CoroutineScope cancellation in Kotlin.
- Services MUST NEVER rely on Swift's AsyncSequence consumer consumption rate to backpressure native Kotlin upstream emitters without explicit cooperative suspension verification.

## Bad vs Good Implementations
### Kotlin KMP Flow Boundary: Unbounded vs Bounded Flow for SKIE Swift Interop

#### Bad Antipattern (AI Common Hallucination)
> **Why it fails**: Exposing a raw callbackFlow directly across the SKIE boundary without an explicit bounded buffer policy allows events to accumulate indefinitely in bridge memory if Swift's AsyncSequence loop is delayed or suspended, triggering an iOS Jetsam memory kill.
```kotlin
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow

class SensorTelemetryRepository {
    // ANTI-PATTERN: Default callbackFlow uses Channel.BUFFERED (64) but suspends or
    // silently queues unbounded bridge events when consumed via Swift AsyncSequence,
    // leading to Jetsam OOM when Swift UI thread stalls consumer iteration.
    fun observeLiveTelemetry(): Flow<TelemetryData> = callbackFlow {
        val listener = object : HardwareSensorListener {
            override fun onData(data: TelemetryData) {
                // trySend might drop or fail silently, but regular send suspends
                // the sensor thread while SKIE bridging queues unbounded elements.
                trySend(data)
            }
        }
        registerSensorListener(listener)
        awaitClose { unregisterSensorListener(listener) }
    }
}
```

#### Production Standard (Correct)
> **Standard**: Adding an explicit .buffer(capacity = 32, onBufferOverflow = BufferOverflow.DROP_OLDEST) caps downstream native queue allocations, preventing Swift main-actor bottlenecks from causing unbounded memory growth across the SKIE boundary.
```kotlin
import kotlinx.coroutines.channels.BufferOverflow
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.buffer
import kotlinx.coroutines.flow.callbackFlow

class SensorTelemetryRepository {
    // PRODUCTION FIX: Explicit bounded capacity with DROP_OLDEST guarantees memory
    // safety across the SKIE Kotlin-to-Swift AsyncSequence runtime bridge.
    fun observeLiveTelemetry(): Flow<TelemetryData> = callbackFlow {
        val listener = object : HardwareSensorListener {
            override fun onData(data: TelemetryData) {
                trySend(data)
            }
        }
        registerSensorListener(listener)
        awaitClose { unregisterSensorListener(listener) }
    }.buffer(
        capacity = 32,
        onBufferOverflow = BufferOverflow.DROP_OLDEST
    )
}
```

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 SKIE Flow-to-AsyncSequence Backpressure & Bounded Buffer Guardrail

KMP SKIE Flow-to-AsyncSequence Backpressure & Bounded Buffer Guardrail defines an industrial-grade behavioral standard for mobile engineering. Enforces strict bounded buffering and explicit overflow policies on Kotlin Multiplatform Flows exposed to Swift via SKIE. Without explicit backpressure boundaries, mismatched production-consumption rates across the Kotlin/Native and Swift async boundary cause unmonitored queue accumulation, rapid heap exhaustion, and iOS Jetsam terminations during high-frequency streaming. 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: Unbounded Flow Bridging to Swift AsyncSequence Triggering Uncontrolled Memory Growth and Jetsam Kills 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 DriftUnbounded Flow Bridging to Swift AsyncSequence Triggering Uncontrolled Memory Growth and Jetsam KillsCritical
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 declare an explicit bounded buffer strategy (via .buffer() or SharedFlow replay/extraBufferCapacity) with a designated BufferOverflow policy (DROP_OLDEST or DROP_LATEST) on any Flow exported to Swift via SKIE.

Engineers MUST ALWAYS declare an explicit bounded buffer strategy (via .buffer() or SharedFlow replay/extraBufferCapacity) with a designated BufferOverflow policy (DROP_OLDEST or DROP_LATEST) on any Flow exported to Swift via SKIE.

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 raw unbounded channelFlow, callbackFlow, or default MutableSharedFlow instances directly to iOS consumers without wrapping them in a bounded operator.

Engineers MUST NOT expose raw unbounded channelFlow, callbackFlow, or default MutableSharedFlow instances directly to iOS consumers without wrapping them in a bounded operator.

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 ensure Swift consumers manage lifecycle-scoped Task cancellation, preventing zombie subscriptions from hanging Kotlin CoroutineScope instances across the Darwin runtime boundary.

Engineers MUST ensure Swift consumers manage lifecycle-scoped Task cancellation, preventing zombie subscriptions from hanging Kotlin CoroutineScope instances across the Darwin runtime 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.
4

High-frequency event streams (e.g., location, BLE telemetry, real-time WebSockets) MUST specify a maximum buffer capacity not exceeding 64 items unless an explicit high-capacity ring-buffer architecture is formally documented.

High-frequency event streams (e.g., location, BLE telemetry, real-time WebSockets) MUST specify a maximum buffer capacity not exceeding 64 items unless an explicit high-capacity ring-buffer architecture is formally documented.

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

Code SHOULD leverage SKIE's native cancellation propagation by pairing Task cancellation in SwiftUI (.task modifier) with cooperative CoroutineScope cancellation in Kotlin.

Code SHOULD leverage SKIE's native cancellation propagation by pairing Task cancellation in SwiftUI (.task modifier) with cooperative CoroutineScope cancellation in Kotlin.

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.
6

Services MUST NEVER rely on Swift's AsyncSequence consumer consumption rate to backpressure native Kotlin upstream emitters without explicit cooperative suspension verification.

Services MUST NEVER rely on Swift's AsyncSequence consumer consumption rate to backpressure native Kotlin upstream emitters without explicit cooperative suspension verification.

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 SKIE Flow-to-AsyncSequence Backpressure & Bounded Buffer Guardrail critical for AI coding assistants?

Enforces strict bounded buffering and explicit overflow policies on Kotlin Multiplatform Flows exposed to Swift via SKIE. Without explicit backpressure boundaries, mismatched production-consumption rates across the Kotlin/Native and Swift async boundary cause unmonitored queue accumulation, rapid heap exhaustion, and iOS Jetsam terminations during high-frequency streaming. 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 (Unbounded Flow Bridging to Swift AsyncSequence Triggering Uncontrolled Memory Growth and Jetsam Kills) 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