Architectural Invariant Design: Kotlin/Native GC and Swift ARC Bidirectional Retain Cycle Interlock
Kotlin/Native GC and Swift ARC Bidirectional Retain Cycle Interlock defines an industrial-grade behavioral standard for mobile engineering. Enforces deterministic lifecycle boundaries between Kotlin/Native's garbage-collected runtime and Swift's Automatic Reference Counting engine across the Objective-C export bridge. Eliminates hidden circular strong references across runtime boundaries that blind tracing collectors and reference counting from reclamation, preventing cross-runtime memory leaks and zombie pointer dereferences in multi-threaded bridges. Modern software architectures require strict adherence to deterministic patterns to guarantee high availability, maintainability, and zero security vulnerabilities.
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 Mode | AI Symptom (The Anti-Pattern) | Severity | Production Impact & Remedy |
|---|---|---|---|
| AI Hallucination & Deprecation Drift | Cross-Boundary Strong Reference Pinning and Unsynchronized StableRef Leaks | Critical | 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 Inconsistency | AI 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. |
Step-by-Step Production Directives
Each rule constraint below is injected into the AI agent's system prompt to establish deterministic boundaries:
Engineers MUST ALWAYS declare Swift delegate protocols or listener callbacks passed into Kotlin objects with weak semantics on the Kotlin/Native boundary or wrap them inside an explicit disposable container.
Engineers MUST ALWAYS declare Swift delegate protocols or listener callbacks passed into Kotlin objects with weak semantics on the Kotlin/Native boundary or wrap them inside an explicit disposable container.
Engineers MUST NOT hold strong references from long-lived Kotlin singletons/presenters to Swift closures or UIViewController instances across the C/Objective-C interop boundary.
Engineers MUST NOT hold strong references from long-lived Kotlin singletons/presenters to Swift closures or UIViewController instances across the C/Objective-C interop boundary.
Swift client code MUST ALWAYS break cross-boundary cycles using [weak self] captures when passing closures into Kotlin Flow collectors or async coroutine bridges.
Swift client code MUST ALWAYS break cross-boundary cycles using [weak self] captures when passing closures into Kotlin Flow collectors or async coroutine bridges.
Kotlin/Native bridges using StableRef.create() MUST ALWAYS pair with an explicit StableRef.dispose() invocation in a deterministic lifecycle block (e.g., deinit, Closeable, or Job cancellation).
Kotlin/Native bridges using StableRef.create() MUST ALWAYS pair with an explicit StableRef.dispose() invocation in a deterministic lifecycle block (e.g., deinit, Closeable, or Job cancellation).
Services exposing CoroutineScope or Observable pipelines to Swift MUST provide explicit cancellation methods (e.g., cancel(), close(), or detach()) that Swift callers invoke inside deinit or viewDidDisappear.
Services exposing CoroutineScope or Observable pipelines to Swift MUST provide explicit cancellation methods (e.g., cancel(), close(), or detach()) that Swift callers invoke inside deinit or viewDidDisappear.
Components NEVER store direct strong references to Swift ARC objects inside Kotlin heap properties without an intermediate WeakReference<T> or nullable clearing hook.
Components NEVER store direct strong references to Swift ARC objects inside Kotlin heap properties without an intermediate WeakReference<T> or nullable clearing hook.
Frequently Asked Technical Questions
Common questions developers face when configuring AI coding assistants for this stack:
Q:Why is Kotlin/Native GC and Swift ARC Bidirectional Retain Cycle Interlock critical for AI coding assistants?
Enforces deterministic lifecycle boundaries between Kotlin/Native's garbage-collected runtime and Swift's Automatic Reference Counting engine across the Objective-C export bridge. Eliminates hidden circular strong references across runtime boundaries that blind tracing collectors and reference counting from reclamation, preventing cross-runtime memory leaks and zombie pointer dereferences in multi-threaded bridges. 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 (Cross-Boundary Strong Reference Pinning and Unsynchronized StableRef Leaks) 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.