KMP Code One Task Group
| This documentation was generated with the assistance of AI. Please report any inaccuracies. |
Implement one bucket of Kotlin Multiplatform tasks from a plan’s task group end to end: detect the project shape and
the bucket’s validation scope once, capture a single pre-change quality baseline, run iru-kmp-code-one-task once
per task (in parallel when the group allows it), then validate the entire bucket once — cheapest checks first,
the iOS simulator stage last and behind a repository-wide lock.
Purpose
iru-kmp-code-one-task-group is the Kotlin Multiplatform counterpart to iru-android-code-one-task-group and
iru-swift-code-one-task-group. It detects once the layout (shared/ + androidApp/ + iosApp/, or the wizard’s
composeApp/), the Android plugin, the UI mode, and the host’s iOS capability (macOS, full Xcode, an iOS simulator
runtime), then scopes validation by module and source set: a commonMain change runs every target’s tests,
androidMain only the Android host tests, iosMain only the iOS tests, and iosApp Swift only the XCTest bundle.
After one baseline capture via iru-kmp-code-quality, it dispatches each task to iru-kmp-code-one-task (all at
once when the bucket is Parallelizable: yes, otherwise one at a time; tasks that share an expect/actual set,
a Gradle build file, iosApp/project.yml, or a Koin module always run sequentially, declaration first). Validation
then runs once for the bucket, every check delegated to an iru-gate-runner agent: license headers, KDoc via
iru-kmp-dokka, scoped Android/JVM tests, an 80% line-coverage gate measured from JVM/Android runs only (Kotlin/Native
iOS code is reported "not measurable" and never fails the gate), the full Android/JVM suite, and a quality diff
against the baseline. Only then does the iOS stage run — Kotlin/Native simulator tests plus the iosApp XCTest
bundle via iru-kmp-test with target: ios — serialized behind the shared atomic-mkdir .integration-test.lock
(stale after 60 minutes, bounded wait of about 45 minutes, released on every exit path) and passed to the gate as
lock: held. An iOS stage that cannot run (not macOS, no full Xcode, no simulator runtime, lock wait timeout) is
reported "unverified", never skipped silently or reported as passed.
When the bucket touched UI (a @Composable, an androidApp screen, a SwiftUI view or a navigation graph), Step 1 also builds a UI inventory from the tasks' reported Screen › Region › Component decompositions and reads .ui-quality.yml (missing file means accessibility: enforce, directions: [ltr, rtl], themes: [light, dark]). The iOS gate call then also reports the iOS captures and accessibility violations (they are produced inside the locked run), and a new Step 3.8 UI stage runs the Android/JVM UI tests through iru-kmp-test’s `ui selector, checks that every inventoried screen and component has a capture per visual state × direction × theme × platform (--android/--ios) under .ui-screenshots/, and applies the accessibility results at the configured enforce/report/off/none level. Cells of a platform whose stage was unverified are reported unverified, not missing, and device flow tests with no emulator attached are unverified (no device), never passed. See Building user interfaces. With accessibility: none in .ui-quality.yml (opted out entirely), the accessibility rules and checks are neither applied nor required and are reported as "accessibility: opted out" in the group report, never unverified or failed; off still applies the rules but skips the automated checks. When .ui-quality.yml is missing in a repository that already has UI code, it doesn’t assume enforce: before the first UI task it asks once, pre-selected from iru-explore’s `Accessibility: line, and writes the file.
Plugin
Shipped by the iru-kmp plugin of the ai-catalog marketplace (install with /plugin install iru-kmp@ai-catalog; see Plugins).
Inputs
| Argument | Required | Description | Default |
|---|---|---|---|
Bucket text |
Yes |
Every |
None — this skill is always invoked with a specific bucket’s text, by |
Outputs
-
Source, test, Swift, and
project.ymlchanges per task, viairu-kmp-code-one-task. -
License headers and KDoc kept current across every file the bucket touched, checked once for the whole bucket.
-
Unit tests achieving at least 80% line coverage for the bucket’s changed/new classes in measurable source sets (
commonMain,androidMain,androidApp), verified against the real Kover report;iosMainclasses reported as not measurable, with any real logic in them flagged as belonging incommonMain. -
A green Android/JVM suite and, on a capable macOS host, a green iOS stage (Kotlin/Native simulator tests and the
iosAppXCTest bundle) — or an explicit "unverified" with the reason. -
For a UI-touched bucket:
.ui-screenshots/captures for every added/changed screen and component across states × directions × themes × platforms, the capture-matrix result (gaps fixed, or unverified with the reason), and accessibility results at the.ui-quality.ymllevel. -
.integration-test.lock/taken and released around the iOS stage only (and.gitignoreextended with it if missing). -
implementation_plan.mdwith each task’s checkbox checked and a note first saying "group validation pending" (written byiru-kmp-code-one-task, backfilled here if a concurrent-write race dropped it), then replaced with the final outcome quoting JVM-measured coverage and the iOS result separately; blocked tasks left unchecked with their blocker note. -
User-facing notifications per task as its implementation lands and once when group validation completes.
-
A summary handed back to
iru-code-one-task-group: shape detected and validation scope, per-task details, Android/JVM and iOS results (naming any single-target failure), the UI outcome for UI-touched tasks (for exampleUI: 12 android + 12 ios captures, matrix complete, accessibility enforce — 0 violations), accepted coverage exceptions, lock behavior, unwired tools, and any task that stopped on a blocker.
Execution flow
Dependencies
Invokes
-
KMP Code One Task — Step 2, once per task in the bucket (concurrently or sequentially per the group’s
Parallelizableverdict, with sequential ordering forced forexpect/actual-dependent tasks), via theiru-isolated-skill-executoragent. Each run implements exactly what its task specifies, writes/updates its tests, compile-checks, and checks off its own checkbox with a "group validation pending" note.
Each of the following is invoked via the iru-gate-runner agent rather than
directly, so verbose report output stays out of this skill’s own context:
-
KMP Code Quality — Step 1 (pre-change baseline) and Step 3.6 (regression check against it).
-
Check License — Step 3.1, license headers for every Kotlin, Swift, and build-script file the bucket touched.
-
KMP Dokka — Step 3.2, KDoc and a passing Dokka build for every declaration touched.
-
KMP Test — Step 3.3 (scoped Android/JVM tests per module), Step 3.5 (full Android/JVM suite), Step 3.7 (iOS stage,
target: ios, withlock: held, plusui: yesfor a UI-touched bucket so the iOS captures are produced inside the locked run), and Step 3.8 (Android/JVM UI tests with theuiselector). -
KMP Coverage — Step 3.4, JVM-measured line/branch coverage with an 80% bar.
Invoked by
-
Code One Task Group — Step 2, bucket for key kmp.
Related agents
-
iru-isolated-skill-executor— spawned once per task in the bucket (Step 2), potentially many at once when the group is parallelizable, so each task’s own implementation transcript doesn’t accumulate in this skill’s context. -
iru-gate-runner— spawned for the baseline capture (Step 1) and every validation check (Step 3), including the single iOS-stage call, keeping full reports out of this skill’s context.
Source
SKILL.md on GitHub — the file this page was generated from.