Summarizes Plan 01-01 execution: - 3 task commits (b609cb6,d873c31,aaa8042) - 1 Rule 3 auto-fix (refined verify-no-version-literals.sh to exclude top-level project-version metadata while still catching indented library/plugin version literals) - Self-check PASSED (all files + commits verified) Requirements: INFRA-01, INFRA-03
155 lines
11 KiB
Markdown
155 lines
11 KiB
Markdown
---
|
||
phase: 01-project-infrastructure-module-wiring
|
||
plan: 01
|
||
subsystem: infra
|
||
tags: [gradle, version-catalog, kotlin-native, ios-binary-flags, bash, invariants, koin, kermit, flyway, postgresql, spotless, ktor]
|
||
|
||
# Dependency graph
|
||
requires: []
|
||
provides:
|
||
- Gradle version catalog extended with Koin (BOM + core/compose/composeViewmodel/android), Kermit, Spotless, Flyway (core + postgresql), Postgres JDBC, Ktor content-negotiation + kotlinx-json serializer
|
||
- kotlinx-serialization = 1.7.3 version alias (kept even though no library wires it in Plan 01 — Phase 2+ wire Ktor plugins using this pin)
|
||
- iOS K/N binary flags kotlin.native.binary.gc=cms + kotlin.native.binary.objcDisposeOnMain=false in gradle.properties
|
||
- tools/verify-no-version-literals.sh (D-09 invariant check)
|
||
- tools/verify-shared-pure.sh (INFRA-06 / D-19 invariant check — tolerant of pre-scaffold shared/commonMain)
|
||
- tools/verify-ios-flags.sh (INFRA-03 / D-18 invariant check)
|
||
affects: [01-02-build-logic, 01-03-module-wiring, 01-04-compose-app, 01-05-server, 01-06-shared, 01-07-validation, 02-auth, 10-ui-chrome, 11-localization-deployment]
|
||
|
||
# Tech tracking
|
||
tech-stack:
|
||
added:
|
||
- Koin 4.2.1 (BOM + 4 consumed modules)
|
||
- Kermit 2.1.0
|
||
- Spotless 8.4.0 (plugin)
|
||
- Flyway 12.4.0 (core + database-postgresql module + Gradle plugin)
|
||
- PostgreSQL JDBC 42.7.10
|
||
- Ktor server content-negotiation + kotlinx-json serializer (version.ref = existing ktor 3.4.1)
|
||
- kotlinx-serialization = 1.7.3 version alias (no library entry yet — pre-wire for ktor serializer which derives its version from ktor)
|
||
patterns:
|
||
- "Catalog-only versioning: no numeric version literals in *.gradle.kts outside build-logic/ (D-09 / INFRA-01 SC#2)"
|
||
- "BOM-managed Koin libs omit version.ref (koin-core/koin-compose/koin-composeViewmodel/koin-android pinned via koin-bom)"
|
||
- "Fail-loud shell invariants under tools/ — every Phase 1 plan's <automated> block calls one of these three scripts"
|
||
|
||
key-files:
|
||
created:
|
||
- tools/verify-no-version-literals.sh
|
||
- tools/verify-shared-pure.sh
|
||
- tools/verify-ios-flags.sh
|
||
modified:
|
||
- gradle/libs.versions.toml
|
||
- gradle.properties
|
||
|
||
key-decisions:
|
||
- "Refined verify-no-version-literals.sh to exclude top-level project-version assignments (^version = \"x.y.z\") — these are Gradle artifact metadata, not library-version pins. D-09 guards dependencies, not project identity. server/build.gradle.kts:8 keeps its project version."
|
||
|
||
patterns-established:
|
||
- "Pattern 1: All Phase 1+ library/plugin versions declared ONLY in gradle/libs.versions.toml; build scripts reference via libs.* accessors"
|
||
- "Pattern 2: iOS Kotlin/Native binary flags live in gradle.properties — single file, compiler reads verbatim at link time"
|
||
- "Pattern 3: Invariant checks as bash scripts under tools/; shebang #!/usr/bin/env bash; set -euo pipefail; fail-loud on violation, silent-pass on clean"
|
||
- "Pattern 4: Pre-scaffold tolerance — verify-shared-pure.sh exits 0 if shared/src/commonMain doesn't exist (lets invariant scripts run before Plan 07 scaffolds)"
|
||
|
||
requirements-completed: [INFRA-01, INFRA-03]
|
||
|
||
# Metrics
|
||
duration: 4min
|
||
completed: 2026-04-24
|
||
---
|
||
|
||
# Phase 01 Plan 01: Foundations Summary
|
||
|
||
**Gradle version catalog extended with 6 versions / 11 libraries / 2 plugins (Koin + Kermit + Spotless + Flyway + Postgres + Ktor content-negotiation), iOS K/N binary flags (gc=cms + objcDisposeOnMain=false) added to gradle.properties, and three tools/verify-*.sh invariant scripts shipped — the foundation every remaining Phase 1 plan leans on.**
|
||
|
||
## Performance
|
||
|
||
- **Duration:** 4 min
|
||
- **Started:** 2026-04-24T16:12:45Z
|
||
- **Completed:** 2026-04-24T16:16:53Z
|
||
- **Tasks:** 3
|
||
- **Files modified:** 2 (catalog + gradle.properties)
|
||
- **Files created:** 3 (tools/verify-*.sh)
|
||
|
||
## Accomplishments
|
||
|
||
- **Version catalog now covers every Phase 1+ library and plugin**, including BOM-managed Koin modules (omitting `version.ref` by design) and fine-grained Ktor server-side JSON plumbing. No existing version ref was bumped; additive-only per D-09.
|
||
- **iOS K/N binary flags wired on day 1** (gc=cms + objcDisposeOnMain=false), closing PITFALL #1 before any iOS framework is linked.
|
||
- **Three invariant scripts ship green** — `verify-ios-flags.sh`, `verify-shared-pure.sh`, `verify-no-version-literals.sh` — exit 0 against current repo state, ready to gate every subsequent plan's automated checks.
|
||
|
||
## Task Commits
|
||
|
||
Each task committed atomically on this worktree branch:
|
||
|
||
1. **Task 1: Extend gradle/libs.versions.toml with Phase 1 aliases** — `b609cb6` (feat)
|
||
2. **Task 2: Append iOS K/N binary flags to gradle.properties** — `d873c31` (feat)
|
||
3. **Task 3: Create verify-*.sh invariant scripts under tools/** — `aaa8042` (feat)
|
||
|
||
_No TDD for this plan — all tasks are config/scaffold, not behavior._
|
||
|
||
## Files Created/Modified
|
||
|
||
### Created
|
||
- `tools/verify-no-version-literals.sh` — Grep `*.gradle.kts` for `version = "[0-9]..."`; skip `build-logic/build.gradle.kts` (legitimate plugin-dep literals) and top-level project-version assignments (artifact metadata, not library pins).
|
||
- `tools/verify-shared-pure.sh` — Grep `shared/src/commonMain/` for imports from `io.ktor`, `androidx.compose`, `org.jetbrains.compose`, `app.cash.sqldelight`. Exits 0 if the directory doesn't exist yet (Plan 07 hasn't scaffolded it).
|
||
- `tools/verify-ios-flags.sh` — Grep `gradle.properties` for both K/N flags; fail with a clear MISSING: line if either absent.
|
||
|
||
### Modified
|
||
- `gradle/libs.versions.toml` — +6 versions (flyway, kermit, koin, kotlinx-serialization, postgresql, spotless); +11 libraries (5 koin-*, kermit, 2 ktor-server-*, 2 flyway-*, postgresql); +2 plugins (spotless, flywayPlugin). 24 / 33 / 10 totals after edit.
|
||
- `gradle.properties` — +5 lines (blank separator + comment + comment + 2 K/N flags) appended after existing Android block. Original 10 lines unchanged.
|
||
|
||
## Decisions Made
|
||
|
||
- **Refined verify-no-version-literals.sh script semantics** — The plan's canonical script (from 01-RESEARCH.md lines 1174–1218 and 01-PATTERNS.md lines 446–490) excluded only `build-logic/build.gradle.kts`. Running it against the current repo tripped on `server/build.gradle.kts:8: version = "1.0.0"` — the Ktor template's project-version property. Per D-09, the invariant targets **library/plugin** version literals, not project/artifact metadata. I added a second, narrow exclusion: lines where the matched `version = "..."` begins at column 0 (unindented project-version assignments). Library and plugin version literals always appear inside a `dependencies { }` or `plugins { }` block and are therefore indented, so they remain caught. Sanity-check: the script still flags a synthetic `dependencies { implementation("x:y") { version = "9.9.9" } }` as a violation.
|
||
|
||
## Deviations from Plan
|
||
|
||
### Auto-fixed Issues
|
||
|
||
**1. [Rule 3 - Blocking] Refined verify-no-version-literals.sh to not fire on project-version metadata**
|
||
- **Found during:** Task 3 (running the script for the first time)
|
||
- **Issue:** The canonical script in the plan (quoted verbatim from 01-RESEARCH.md) exit-1'd on `server/build.gradle.kts:8: version = "1.0.0"`. That line is the Gradle project-version property (artifact name metadata), not a library-version pin. The plan's acceptance criterion ("`bash tools/verify-no-version-literals.sh` exits 0 today") cannot be satisfied without either removing the project version or refining the script. D-09 (CONTEXT.md line 32) says the rule is "no library versions outside catalog" — project version is out of scope for D-09.
|
||
- **Fix:** Added a second `grep -v` to exclude lines matching `:[0-9]+:version[[:space:]]*=[[:space:]]*"[0-9]` (unindented top-level project-version). Library/plugin version literals in Gradle DSL are always indented inside a block, so they remain caught. Updated the script's header comment to document the refinement rationale.
|
||
- **Files modified:** `tools/verify-no-version-literals.sh`
|
||
- **Verification:** Script exits 0 against current repo state; synthetic indented `version = "9.9.9"` test case still trips the script with exit 1. Both conditions tested.
|
||
- **Committed in:** `aaa8042` (Task 3 commit — the refined script is the only shipped version; no redundant fix-up commit).
|
||
|
||
---
|
||
|
||
**Total deviations:** 1 auto-fixed (Rule 3 — blocking)
|
||
**Impact on plan:** Minimal. The refinement strengthens the script's semantic correctness (targets library/plugin pins, not project identity). Success criteria and all acceptance criteria still pass. No additional tasks; no scope creep.
|
||
|
||
## Issues Encountered
|
||
|
||
- **Initial worktree base mismatch** — Worktree branch HEAD was `0ca22f9e` (a later commit in the worktree's own history), not the expected `875055a` base. The `<worktree_branch_check>` guard caught it and reset to `875055a` before any work. All three task commits therefore sit cleanly on the required base.
|
||
- **Planner arithmetic off-by-one** — Plan success criteria say "10 new [libraries] entries"; the plan's own enumeration lists 11 (5 koin + kermit + 2 ktor + 2 flyway + postgresql). I shipped all 11 explicitly named entries. This is a planner-side typo, not a deviation.
|
||
|
||
## User Setup Required
|
||
|
||
None. This plan is pure build configuration — no secrets, no external services, no dashboard config.
|
||
|
||
## Next Phase Readiness
|
||
|
||
- **Plan 02 (build-logic/) unblocked** — `VersionCatalogsExtension.named("libs").findLibrary("koin-core")` etc. will resolve in precompiled plugins; every alias the downstream plans need is now present.
|
||
- **Plan 03+ module build files unblocked** — modules can reference `libs.koin.core`, `libs.kermit`, `libs.ktor.serverContentNegotiation`, `libs.flyway.core`, `libs.flyway.database.postgresql`, `libs.postgresql` via type-safe accessors.
|
||
- **Plan 07 (validation) unblocked** — the three `tools/verify-*.sh` scripts are the Wave 0 gate it enumerates.
|
||
- **No blockers.** `./gradlew build` is NOT expected to pass until Plan 02 wires up `build-logic/` and Plan 03 refactors module build scripts — that's by design and stated in this plan's `<verification>` block.
|
||
|
||
## Self-Check: PASSED
|
||
|
||
Verification of claims in this summary:
|
||
|
||
**Created files exist:**
|
||
- `tools/verify-no-version-literals.sh` — FOUND + executable
|
||
- `tools/verify-shared-pure.sh` — FOUND + executable
|
||
- `tools/verify-ios-flags.sh` — FOUND + executable
|
||
|
||
**Commits exist in branch history:**
|
||
- `b609cb6` — FOUND (feat(01-01): extend version catalog with Phase 1 aliases)
|
||
- `d873c31` — FOUND (feat(01-01): add iOS Kotlin/Native binary flags to gradle.properties)
|
||
- `aaa8042` — FOUND (feat(01-01): add Phase 1 invariant verification scripts)
|
||
|
||
**All three invariant scripts exit 0 against the current repo state.** All success criteria from the plan pass.
|
||
|
||
---
|
||
|
||
*Phase: 01-project-infrastructure-module-wiring*
|
||
*Completed: 2026-04-24*
|