en un clic
kotlin-engineer
// Kotlin 2.x policy and pitfalls. Use when writing, reviewing, or refactoring Kotlin code — enforces coroutine-safety, Flow correctness, null-safety, and API-design rules that LLMs frequently get wrong.
// Kotlin 2.x policy and pitfalls. Use when writing, reviewing, or refactoring Kotlin code — enforces coroutine-safety, Flow correctness, null-safety, and API-design rules that LLMs frequently get wrong.
Senior Android engineer workflows — Kotlin-first (Java legacy supported), Jetpack Compose + View system, MVVM, Coroutines/Flow, Room, Retrofit, Hilt, plus device orchestration via plugin tools (device management, logcat, crash reports, app run) and mobile-mcp for UI interaction (element tree, taps, swipes). Use when implementing features, debugging crashes, fixing builds, writing tests, reviewing Android code, or running QA on an emulator.
Use when working on Laravel projects. Covers architecture decisions (Services vs Actions), thin controllers, Form Requests, API Resources, and API versioning. Enforces Larastan verification after code generation.
Up-to-date library and framework documentation via Context7 MCP. Use when setup, API, or version-specific questions require current documentation.
Modern PHP 8.x policy and pitfalls. Use when writing, reviewing, or refactoring PHP code — enforces strict types, enum/readonly/match/DNF policy, PHPStan discipline, and catches the subtle traps (type coercion, mixed abuse, readonly mutation through references, enum serialization, fiber lifecycle, PDO emulation) that LLMs get wrong by default.
Redis policy & pitfalls — key naming, atomicity, TTL strategy, distributed locks, cache patterns, production traps. Use when designing Redis-backed caches, locks, queues, rate limiters, or sessions. Covers the traps LLMs get wrong by default: SETNX + EX (deprecated), KEYS on production, Pub/Sub no-persistence, HGETALL on big hashes, maxmemory-policy defaults, cluster hash tags, RDB fork memory.
SQL policy & pitfalls — query correctness, indexing strategy, safe migrations. Use when writing SQL, diagnosing slow queries, designing schemas, or reviewing Flyway/Liquibase migrations. Covers the traps LLMs miss by default: NOT IN with NULLs, function-on-column breaking indexes, OFFSET on large tables, NOT NULL column lock, CREATE INDEX blocking writes, immutable migrations.
| name | kotlin-engineer |
| description | Kotlin 2.x policy and pitfalls. Use when writing, reviewing, or refactoring Kotlin code — enforces coroutine-safety, Flow correctness, null-safety, and API-design rules that LLMs frequently get wrong. |
Baseline Kotlin knowledge (data/sealed/value classes, scope functions, null-safety operators, extension functions, suspend, Flow, when exhaustiveness) is assumed. This skill does not teach the language — it encodes the project policy and the traps that keep appearing in code review.
Before writing non-trivial code:
build.gradle(.kts) (kotlin("jvm") version "2.x") or libs.versions.toml.kotlin { jvmToolchain(21) } or compileOptions { targetCompatibility = JavaVersion.VERSION_21 }. Matters for virtual threads (21+) and records interop (17+).kotlin("plugin.spring"), kotlin("plugin.jpa"), kotlinx-serialization, kotlin("kapt") vs com.google.devtools.ksp. Missing plugin.spring → final Spring classes can't be proxied. Missing plugin.jpa → InstantiationException: No default constructor.detekt / ktlint configured? Follow the existing rules; don't introduce new violations../gradlew?, ?., ?:, let, requireNotNull. Use !! only when null is a true contract violation — document why on the same line.sealed interface Result { data class Success(...); data class Failure(...) }) + exhaustive when without else.@JvmInline value class) for domain identifiers (UserId, Email) — zero-overhead type-safety.data class only for pure value types. Not for entities, services, or anything with behavior / lifecycle.CoroutineScope, use coroutineScope { } / framework scopes (viewModelScope). Never GlobalScope.launch.CancellationException in generic catch (e: Exception) blocks — swallowing it disables cancellation.val state: StateFlow<X> = _state.asStateFlow(). Never leak MutableStateFlow / MutableSharedFlow from an API.withContext(Dispatchers.IO) / Default for blocking / CPU work inside suspend. Encapsulate dispatcher choice in the repository / data-source layer — not at call sites.val over var, List over MutableList in public API, copy() on data classes instead of mutation.!! without a commented reason. Refactor to ?.let { } / requireNotNull(x) { "why" }.runBlocking in production — only in main and tests. Inside a suspend function it's always a bug.GlobalScope.launch / GlobalScope.async — leaks, no structured cancellation.CancellationException. try/catch(Exception) without a cancellation rethrow silently disables cancellation..first() / .single() on a hot Flow without a timeout — a source that never emits hangs the coroutine forever.async { }.await() sequentially when you want parallelism — it's the same as calling suspend directly. Use coroutineScope { val a = async { .. }; val b = async { .. }; a.await() + b.await() }.Dispatchers.Main / Dispatchers.IO references from common / multiplatform code unless the module is JVM-only.String!) in public API — annotate Java interop returns with @NotNull / @Nullable on the Java side, or cast explicitly.Throwable — you'll catch OutOfMemoryError, StackOverflowError, and cancellation. Use Exception and rethrow cancellation.lateinit var on primitives or nullable types — compile error. Use Delegates.notNull() for primitives.| Load when | File |
|---|---|
| Async / reactive code — coroutines, Flow, StateFlow/SharedFlow, cancellation, testing | references/coroutines.md |
API design — scope functions, value/data/sealed classes, extension functions, inline/reified, delegates, Result<T> | references/idioms.md |
| Gradle / tooling — Kotlin DSL, version catalogs, KSP vs kapt, multi-module layout, compiler plugins | references/build-setup.md |
When producing code:
When reviewing code: call out MUST-DO / MUST-NOT violations explicitly and suggest the minimal fix.