Part of the Detour Kotlin guidelines. Section numbers are stable across files — a reference like §8.4 always means §8.4, wherever it lives.
Anything here that fails is a finding, not a preference.
The items CI enforces — public MutableStateFlow, Dispatchers in commonMain,
data/drive → presentation imports, unregistered commonMain interfaces, and
the §8 size limits — live in app/src/test/.../arch/ArchitectureTest.kt.
Placement
commonMain, or a comment names what blocks it.shared/ from the worse of two copies — diff
the copies for named constants, re-entry guards, and I/O off the collector
before choosing (detour-shared-core §6).app/↔car/ duplicate was fixed by a shared file under app/, not by
a trip through :shared.Boundaries (§8)
State
MutableStateFlow is publicly visible.update { it.copy(…) }.@Composable or a Service if its
inputs are just numbers.null and empty are distinguished wherever “not loaded yet” is possible.Core constraints
expect concern (a new bag of an existing concern is fine).commonMain interface with one implementation.Dispatchers reference added to commonMain; new core APIs are
suspend and let the caller choose.StateFlow element type either reuses a FlowWatcher subclass or
adds one.Concurrency and correctness
StateFlow
collector — it gets its own job with an in-flight guard.withContext(Dispatchers.IO).Hygiene
docs/refactor/mapscreen/15-divergence-register.md.commonTest test callable with literals.versionName in app/build.gradle.kts bumped per CLAUDE.md.