registry/skills/kotlin-development/SKILL.md
This skill should be used when the user asks to "write Kotlin code", "create a Kotlin class", "set up a Kotlin project", "review Kotlin code", "refactor Kotlin", "use coroutines", "fix Kotlin style", or when generating any Kotlin source code. Provides modern Kotlin 2.1+ best practices covering null safety, coroutines, data modeling, error handling, and idiomatic patterns. Does not cover any specific library or framework.
npx skillsauth add provectus/awos-recruitment kotlin-developmentInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Modern Kotlin best practices for writing concise, safe, and idiomatic code. Targets Kotlin 2.1+ on the JVM — language and stdlib only, no frameworks or libraries.
references/type-system.md — Generics, variance, smart casts, inline/value classes, Nothing, SAM conversionsreferences/patterns.md — Scope functions, sealed hierarchies, delegation, extensions, DSL builders, domain modeling, error handling guidereferences/coroutines.md — Flow, StateFlow/SharedFlow, Channels, exception handling, cancellation, testingreferences/project-structure.md — build.gradle.kts, multi-module, compiler options, testing setupjava.time.LocalDateTime) in the code body. Use import aliases for naming conflicts. No wildcard imports.| Element | Convention | Example |
|---|---|---|
| Package | lowercase | com.example.userdata |
| Class / Object | PascalCase | UserAccount, JsonParser |
| Function / Property | camelCase | getUserById(), isActive |
| Constant (const val) | UPPER_SNAKE | MAX_RETRIES |
| Type parameter | Single uppercase | T, K, V |
| Enum entry | UPPER_SNAKE | Status.ACTIVE |
| Backing property | _prefixed | private val _items |
| File name | PascalCase.kt | UserService.kt |
| Boolean | Prefix is, has, can, should | isValid, hasPermission |
val name: String? = findUser()?.name // safe call
val length = name?.length ?: 0 // elvis — default for null
NEVER use !! to silence the compiler — it crashes at runtime. Acceptable only with a provable invariant and a comment explaining why.
user?.let { sendEmail(it) } // nullable transform
requireNotNull(id) { "id must not be null" } // precondition + smart cast
val names: List<String> = users.mapNotNull { it.name } // filter nulls
Kotlin infers types aggressively. Annotate explicitly for public API, when the inferred type is too broad, or when readability benefits.
// Inferred — fine for locals
val count = items.size
// Explicit — public API
fun findUser(id: String): User? { ... }
For generics (in/out variance, star projection, reified types), type aliases, smart casts, and value classes, see references/type-system.md.
data class — value containersdata class User(val id: String, val name: String, val email: String)
MUST use val properties. ALWAYS prefer data classes over Map<String, Any> — maps lose type safety, autocompletion, and refactoring support.
sealed class / sealed interface — restricted hierarchiessealed interface Result<out T> {
data class Success<T>(val value: T) : Result<T>
data class Failure(val error: Throwable) : Result<Nothing>
}
Enables exhaustive when. Prefer sealed interface when subtypes don't share state.
value class — zero-cost wrappers@JvmInline
value class UserId(val value: String)
@JvmInline
value class Email(val value: String) {
init { require(value.contains("@")) { "Invalid email: $value" } }
}
Use to prevent primitive obsession — the compiler catches swapped parameters.
Never use Double/Float for monetary values. Use BigDecimal (construct from String, never Double) with explicit MathContext, or Long (cents) with a value class wrapper. See references/patterns.md for full patterns.
// Custom hierarchy
open class AppException(message: String, cause: Throwable? = null) : RuntimeException(message, cause)
class ValidationException(message: String) : AppException(message)
class NotFoundException(message: String) : AppException(message)
// runCatching for functional error handling
val name = runCatching { fetchUser(id) }.map { it.name }.getOrDefault("Unknown")
// Sealed result for expected business outcomes
sealed interface FetchResult {
data class Found(val user: User) : FetchResult
data object NotFound : FetchResult
data class Error(val reason: String) : FetchResult
}
Rules:
require() for argument validation, check() for state validation.Throwable unless re-throwing.references/patterns.md for the full error handling decision guide.suspend fun fetchUser(id: String): User = httpClient.get("users/$id")
suspend fun loadDashboard(): Dashboard = coroutineScope {
val user = async { fetchUser(userId) }
val orders = async { fetchOrders(userId) }
Dashboard(user.await(), orders.await())
}
Rules:
GlobalScope.coroutineScope when all must succeed; supervisorScope when partial failure is OK.launch for fire-and-forget; async when you need the result.CancellationException — ALWAYS rethrow it.withContext(Dispatchers.IO) for blocking I/O; Dispatchers.Default for CPU work.For Flow, Channels, exception handling, cancellation patterns, timeouts, and testing, see references/coroutines.md.
project-name/
├── build.gradle.kts
├── settings.gradle.kts
├── gradle/libs.versions.toml
├── src/
│ ├── main/kotlin/com/example/project/
│ └── test/kotlin/com/example/project/
└── gradlew
libs.versions.toml).For build.gradle.kts config, multi-module setup, compiler options, and testing, see references/project-structure.md.
buildList / buildMap / buildString for constructing collections and strings.groupBy, associateBy, partition, flatMap for collection transformations.Sequence for lazy evaluation of large collections.use for auto-closeable resource management.users.filter { it.age >= 18 }.map { it.name }| Function | Receiver | Returns | Use for |
|---|---|---|---|
| apply | this | receiver | Object configuration |
| let | it | lambda result | Nullable transforms, scoping |
| run | this | lambda result | Object computation |
| also | it | receiver | Side effects |
| with | this | lambda result | Grouping calls |
For the complete decision guide, see references/patterns.md.
For full patterns, see references/patterns.md.
| Mistake | Fix |
|---|---|
| Using !! to silence nullability | Use ?., ?:, let, or redesign to be non-null |
| Platform types without annotation | Add explicit nullability at Java boundaries |
| var in data classes | Use val — copy with copy() |
| Catching Throwable | Catch specific exceptions; rethrow CancellationException |
| GlobalScope.launch | Use structured concurrency |
| Mutable collections in public API | Expose List, not MutableList; backing property pattern |
| Inline fully-qualified types | Import at top; use aliases for conflicts |
| Map<String, Any> as data holder | Define a data class |
| Double for money | BigDecimal with MathContext, or Long (cents) |
| Long functions (>15 lines) | Extract named private functions |
| Hard-coded dependencies | Constructor injection; depend on interfaces |
| when without exhaustive check | Use sealed types or add else branch |
development
Insurance underwriting domain knowledge for building automated submission processing systems. Covers submission-to-bind lifecycle, document extraction patterns, compliance gates (sanctions, licensing, clearance), human-in-the-loop design for regulated financial services, confidence calibration for extracted fields, operating mode progression (manual to automated), and evidence traceability requirements. Use when designing or implementing underwriting pipelines, extraction agents, compliance workflows, HITL review systems, or decision package assembly for insurance or MGA operations.
development
This skill should be used when the user asks to "write TypeScript code", "create a TypeScript module", "define TypeScript types", "add type annotations", "use generics", "handle errors in TypeScript", "set up tsconfig", "organize TypeScript project", or when writing any TypeScript code that is not tied to a specific library or framework. Covers type system, strict mode, naming conventions, error handling, async patterns, and project structure.
development
Use when working with Terraform or OpenTofu - creating modules, writing tests (native test framework, Terratest), setting up CI/CD pipelines, reviewing configurations, choosing between testing approaches, debugging state issues, implementing security scanning (trivy, checkov), or making infrastructure-as-code architecture decisions. Enforces Provectus opinionated conventions (exact version pinning, etc.) on top of community best practices.
development
This skill should be used when the user asks to "write Swift code", "create a Swift type", "set up a Swift package", "review Swift code", "refactor Swift", "use async/await in Swift", "fix Swift style", or when generating any Swift source code regardless of target platform. Provides modern Swift 6+ best practices covering type system, optionals, concurrency, error handling, protocols, generics, and idiomatic patterns. Does not cover any specific platform or framework.