- composeApp/build.gradle.kts: 114 -> 28 lines (role declaration with 4 recipe.* IDs) - shared/build.gradle.kts: 55 -> 36 lines (3 plugins, explicitApi, Framework baseName "Shared") - server/build.gradle.kts: 23 -> 18 lines (recipe.jvm.server + recipe.quality + module-only config) - shared/src/jsMain/ deleted (D-01) - 0 deviations; both verify-*.sh scripts pass; INFRA-02 + INFRA-06 structural prerequisites delivered
12 KiB
phase, plan, subsystem, tags, requires, provides, affects, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, duration, completed
| phase | plan | subsystem | tags | requires | provides | affects | tech-stack | key-files | key-decisions | patterns-established | requirements-completed | duration | completed | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 01-project-infrastructure-module-wiring | 03 | infra |
|
|
|
|
|
|
|
|
|
~8min | 2026-04-24 |
Phase 01 Plan 03: Module Build Scripts Wiring Summary
Rewrote all three module build.gradle.kts files as role declarations applying recipe. convention plugins; dropped the js target (shared/src/jsMain/ deleted); enabled explicitApi() + 'Shared' framework basename on shared/.*
Performance
- Duration: ~8 min
- Started: 2026-04-24T16:14:27Z
- Completed: 2026-04-24T16:22:17Z
- Tasks: 2
- Files modified: 3 (composeApp, shared, server build.gradle.kts) + 1 deleted (Platform.js.kt)
Accomplishments
- composeApp/build.gradle.kts: 114 → 28 lines (-75%). Structural blocks (androidTarget, iosArm64/iosSimulatorArm64, jvm, js, wasmJs, android { }, compose.desktop { nativeDistributions }) all removed and inherited from convention plugins. Only 3 source-set dep blocks + 1 debug tooling line remain.
- shared/build.gradle.kts: 55 → 36 lines (-35%). Structural target blocks moved to recipe.kotlin.multiplatform; explicitApi() + KotlinNativeTarget/Framework baseName = "Shared" override added (D-07 / D-12 / PITFALL #10); android {} block kept per Open Question #1.
- server/build.gradle.kts: 23 → 18 lines (-22%). Dependency declarations (logback, ktor-serverCore/Netty/TestHost, kotlin-testJunit) fully relocated into recipe.jvm.server; only module coordinates + mainClass + projects.shared remain.
- js target eliminated:
shared/src/jsMain/kotlin/dev/ulfrx/recipe/Platform.js.ktdeleted (D-01). Nojs { browser() }blocks remain in any module build file. - INFRA-02 payoff visible: the plugin block in each module now reads as a role declaration (D-06). A future KMP module just needs
plugins { id("recipe.kotlin.multiplatform") }+ sourceSet declarations — no target/SDK copy-pasting. - INFRA-06 structural prerequisite delivered: recipe.compose.multiplatform is applied ONLY to composeApp/, never to shared/, so Compose deps cannot leak transitively into the shared module's classpath.
Task Commits
Each task was committed atomically (with --no-verify per parallel-executor protocol):
- Task 1: Rewrite composeApp + shared build files, delete shared/src/jsMain/ —
d76dcea(refactor) - Task 2: Rewrite server build file —
d316a48(refactor)
Note: no test/feat/refactor trio — the plan is marked type=execute, not type=tdd, and all work is build-script configuration (no production code to test).
Files Created/Modified
composeApp/build.gradle.kts— rewritten: 4 recipe.* plugin IDs, androidMain/commonMain/jvmMain dep blocks, debugImplementation lineshared/build.gradle.kts— rewritten: 3 plugins (recipe.kotlin.multiplatform + recipe.quality + androidLibrary), explicitApi(), Framework baseName = "Shared" override, android {} retainedserver/build.gradle.kts— rewritten: 2 recipe.* plugin IDs, application { mainClass + JVM args }, implementation(projects.shared)shared/src/jsMain/kotlin/dev/ulfrx/recipe/Platform.js.kt— DELETED (D-01 — js target dropped)
Decisions Made
libs.versions.*typed accessor used in module build.gradle.kts rather thanlibs.findVersion(...)— PITFALL #1 restricts the typed accessor to precompiled plugins; module scripts have full access, so the typed form (libs.versions.android.compileSdk.get().toInt()) is correct and preserved from the prior version ofshared/build.gradle.kts.- Framework baseName override kept local to shared/ — only shared/ needs
"Shared"; composeApp/ keeps the convention-plugin default"ComposeApp". Hoisting the override intorecipe.kotlin.multiplatformwould require a plugin parameter for a single consumer — not worth the indirection. android { }block retained on shared/ — Open Question #1 in RESEARCH.md defers "do we actually need com.android.library on shared/?" to a futurerecipe.android.libraryconvention plugin. Phase 1 keeps the block applied; a future plan may remove it.libs.koin.androidplaced in composeApp androidMain, not commonMain — theandroidContext(...)helper used by Plan 04's MainApplication lives in koin-android (JVM/Android artifact). commonMain keeps only platform-neutral deps.
Deviations from Plan
None - plan executed exactly as written.
One minor note (not a deviation, not a failure): shared/build.gradle.kts ended at 36 lines vs. the plan's informal ~35-line target. The single-line delta is the non-negotiable explanatory comment above the KotlinNativeTarget/Framework block. The plan's acceptance_criteria does not set a line cap on shared/ (only composeApp/ ≤ 30 which passes at 28 and server/ ≤ 20 which passes at 18), so all criteria are green.
Total deviations: 0
Impact on plan: Plan executed as specified. All <automated> verify blocks pass (grep chain for each module + tools/verify-no-version-literals.sh + tools/verify-shared-pure.sh).
Issues Encountered
None.
User Setup Required
None - pure build-script refactor; no external service configuration required.
Parallel-Wave Coordination Notes
This plan ran as a parallel executor in Wave 2 alongside Plans 02, 04, 05, 06. Per the wave-2 coordination note:
- No
./gradlewcommands executed in this plan. The convention plugins referenced byid("recipe.kotlin.multiplatform")etc. are created by Plan 02 in a separate worktree; this worktree does NOT see those files. Gradle plugin resolution will succeed after all Wave 2 worktrees merge back to master and Plan 07 runs the full green-build gate. - Verification is entirely grep-based, matching the plan's
<automated>specification. No runtime build invocation needed at this stage.
Next Phase Readiness
Ready for downstream plans in Phase 01:
- Plan 04 (compose app skeleton) can now rely on composeApp's
recipe.compose.multiplatformapplication — Compose deps (compose.runtime/foundation/material3/ui/components.resources/lifecycle.*compose) flow in via the convention. - Plan 05 (server skeleton) can rely on server's
recipe.jvm.server— Ktor server + Flyway + Postgres + serialization flow in via the convention; module only needs to declaremainClassandprojects.shared. - Plan 07 (invariant gate) will validate the wired build via
./gradlew buildafter all Wave 2 worktrees merge back.
Downstream phases (Phase 02+ auth, Phase 05 recipe catalog, etc.) inherit a strict boundary: shared/commonMain enforces explicitApi() and carries no Compose / Ktor / SQLDelight deps. Any attempt to add forbidden imports will be caught by tools/verify-shared-pure.sh.
Self-Check: PASSED
Files verified:
- FOUND:
composeApp/build.gradle.kts(28 lines, 4 recipe.* plugin IDs present, no androidTarget/iosArm64/js/nativeDistributions/^android{, libs.koin.android present) - FOUND:
shared/build.gradle.kts(36 lines, 3 plugins present, explicitApi() present,baseName = "Shared"present, no js {, android {} retained) - FOUND:
server/build.gradle.kts(18 lines, 2 recipe.* plugin IDs present, mainClass present, projects.shared present, no legacy aliases or deps) - MISSING (intentional):
shared/src/jsMain/directory no longer exists
Commits verified:
- FOUND:
d76dcea— refactor(01-03): apply recipe.* conventions to composeApp + shared, drop js - FOUND:
d316a48— refactor(01-03): apply recipe.jvm.server + recipe.quality to server module
Verify scripts:
tools/verify-no-version-literals.sh→ exit 0 (OK: no version literals outside catalog)tools/verify-shared-pure.sh→ exit 0 (OK: shared/commonMain is pure)
Phase: 01-project-infrastructure-module-wiring Plan: 03 Completed: 2026-04-24