Plan phase 1
This commit is contained in:
@@ -0,0 +1,342 @@
|
||||
---
|
||||
phase: 01-project-infrastructure-module-wiring
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- gradle/libs.versions.toml
|
||||
- gradle.properties
|
||||
- tools/verify-no-version-literals.sh
|
||||
- tools/verify-shared-pure.sh
|
||||
- tools/verify-ios-flags.sh
|
||||
autonomous: true
|
||||
requirements: [INFRA-01, INFRA-03]
|
||||
requirements_addressed: [INFRA-01, INFRA-03]
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "gradle/libs.versions.toml is the sole source of library/plugin versions (D-09 / INFRA-01 SC#2)"
|
||||
- "iOS K/N binary flags kotlin.native.binary.gc=cms and kotlin.native.binary.objcDisposeOnMain=false are set in gradle.properties (D-18 / INFRA-03)"
|
||||
- "Shell-based invariant checks (no-version-literals, shared-pure, ios-flags) are executable and fail-loud"
|
||||
artifacts:
|
||||
- path: "gradle/libs.versions.toml"
|
||||
provides: "Version + library + plugin aliases for Koin, Kermit, Spotless, Flyway, PostgreSQL JDBC, Ktor content-negotiation, Ktor JSON serializer"
|
||||
contains: "koin = ", "kermit = ", "spotless = ", "flyway = ", "postgresql ="
|
||||
- path: "gradle.properties"
|
||||
provides: "iOS K/N binary flags"
|
||||
contains: "kotlin.native.binary.gc=cms", "kotlin.native.binary.objcDisposeOnMain=false"
|
||||
- path: "tools/verify-no-version-literals.sh"
|
||||
provides: "Invariant check — no numeric version literals outside catalog in any *.gradle.kts (except build-logic/build.gradle.kts bootstrap coordinates)"
|
||||
- path: "tools/verify-shared-pure.sh"
|
||||
provides: "Invariant check — shared/src/commonMain must not import Ktor / Compose / SQLDelight"
|
||||
- path: "tools/verify-ios-flags.sh"
|
||||
provides: "Invariant check — both iOS K/N flags present in gradle.properties"
|
||||
key_links:
|
||||
- from: "build-logic/ (Plan 02)"
|
||||
to: "gradle/libs.versions.toml"
|
||||
via: "VersionCatalogsExtension.named(\"libs\").findLibrary(...) inside precompiled plugins"
|
||||
pattern: "findLibrary\\(\"koin-core\"\\)"
|
||||
- from: "gradle.properties"
|
||||
to: ":composeApp:linkDebugFrameworkIosSimulatorArm64"
|
||||
via: "Kotlin/Native compiler reads project properties at link time"
|
||||
pattern: "kotlin\\.native\\.binary\\."
|
||||
---
|
||||
|
||||
<objective>
|
||||
Extend the Gradle version catalog with every new alias required by Phase 1 (Koin, Kermit, Spotless, Flyway, Postgres JDBC, ktor-serverContentNegotiation, ktor-serializationKotlinxJson), append the two mandatory iOS Kotlin/Native binary flags to `gradle.properties`, and ship three shell-based invariant scripts under `tools/` that Plan 07 will use as phase-gate checks.
|
||||
|
||||
Purpose: This plan creates the **foundation** on which every other Phase 1 plan rests. Without these catalog entries, `build-logic/` (Plan 02) cannot resolve `findLibrary("koin-core")`; without the iOS flags, INFRA-03 fails silently. The verification scripts are required by 01-VALIDATION.md Wave 0 — every subsequent plan's `<automated>` block calls one of them.
|
||||
|
||||
Output: An extended `gradle/libs.versions.toml` (additive only, no version bumps to existing entries), extended `gradle.properties` with exactly two new lines, and three executable `.sh` scripts under a new `tools/` directory.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@$HOME/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@$HOME/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/REQUIREMENTS.md
|
||||
@.planning/phases/01-project-infrastructure-module-wiring/01-CONTEXT.md
|
||||
@.planning/phases/01-project-infrastructure-module-wiring/01-RESEARCH.md
|
||||
@.planning/phases/01-project-infrastructure-module-wiring/01-PATTERNS.md
|
||||
@.planning/phases/01-project-infrastructure-module-wiring/01-VALIDATION.md
|
||||
@gradle/libs.versions.toml
|
||||
@gradle.properties
|
||||
@CLAUDE.md
|
||||
|
||||
<interfaces>
|
||||
<!-- Existing catalog aliases (do NOT rename or remove — only add new entries alongside) -->
|
||||
|
||||
From gradle/libs.versions.toml (current state, to extend):
|
||||
```toml
|
||||
[versions]
|
||||
kotlin = "2.3.20"
|
||||
ktor = "3.4.1"
|
||||
composeMultiplatform = "1.10.3"
|
||||
# (plus agp, androidx-*, composeHotReload, junit, kotlinx-coroutines, logback, material3)
|
||||
|
||||
[libraries]
|
||||
# Existing: kotlin-test, kotlin-testJunit, junit, androidx-*, compose-*, kotlinx-coroutinesSwing,
|
||||
# logback, ktor-serverCore, ktor-serverNetty, ktor-serverTestHost
|
||||
|
||||
[plugins]
|
||||
# Existing: androidApplication, androidLibrary, composeHotReload, composeMultiplatform,
|
||||
# composeCompiler, kotlinJvm, ktor, kotlinMultiplatform
|
||||
```
|
||||
|
||||
From gradle.properties (current state — 10 lines of Kotlin + Gradle + Android config):
|
||||
```properties
|
||||
kotlin.code.style=official
|
||||
kotlin.daemon.jvmargs=-Xmx3072M
|
||||
org.gradle.jvmargs=-Xmx4096M -Dfile.encoding=UTF-8
|
||||
org.gradle.configuration-cache=true
|
||||
org.gradle.caching=true
|
||||
android.nonTransitiveRClass=true
|
||||
android.useAndroidX=true
|
||||
```
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Extend gradle/libs.versions.toml with Phase 1 aliases</name>
|
||||
<files>gradle/libs.versions.toml</files>
|
||||
<read_first>
|
||||
- gradle/libs.versions.toml (see current state of versions/libraries/plugins tables)
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-RESEARCH.md lines 110-175 (§ Standard Stack + Installation TOML fragments)
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-PATTERNS.md lines 446-490 (delta blocks for [versions] / [libraries] / [plugins])
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-CONTEXT.md D-09 (catalog-only hard rule), D-14 (Koin deps needed), D-15 (Kermit), D-10 (Spotless), D-16 (Flyway + Postgres + content-negotiation)
|
||||
</read_first>
|
||||
<action>
|
||||
Extend `gradle/libs.versions.toml` with the new aliases for Phase 1. Preserve every existing entry verbatim (do NOT rename, remove, or bump any existing version).
|
||||
|
||||
Append the following to `[versions]`, in the existing alphabetical-ish order:
|
||||
|
||||
```toml
|
||||
flyway = "12.4.0"
|
||||
kermit = "2.1.0"
|
||||
koin = "4.2.1"
|
||||
kotlinx-serialization = "1.7.3"
|
||||
postgresql = "42.7.10"
|
||||
spotless = "8.4.0"
|
||||
```
|
||||
|
||||
Append the following to `[libraries]`:
|
||||
|
||||
```toml
|
||||
# Koin (client DI — D-14)
|
||||
koin-bom = { module = "io.insert-koin:koin-bom", version.ref = "koin" }
|
||||
koin-core = { module = "io.insert-koin:koin-core" }
|
||||
koin-compose = { module = "io.insert-koin:koin-compose" }
|
||||
koin-composeViewmodel = { module = "io.insert-koin:koin-compose-viewmodel" }
|
||||
koin-android = { module = "io.insert-koin:koin-android" }
|
||||
|
||||
# Kermit (client logger — D-15)
|
||||
kermit = { module = "co.touchlab:kermit", version.ref = "kermit" }
|
||||
|
||||
# Server: Ktor content-negotiation + JSON serializer + Flyway + Postgres (D-16)
|
||||
ktor-serverContentNegotiation = { module = "io.ktor:ktor-server-content-negotiation-jvm", version.ref = "ktor" }
|
||||
ktor-serializationKotlinxJson = { module = "io.ktor:ktor-serialization-kotlinx-json-jvm", version.ref = "ktor" }
|
||||
flyway-core = { module = "org.flywaydb:flyway-core", version.ref = "flyway" }
|
||||
flyway-database-postgresql = { module = "org.flywaydb:flyway-database-postgresql", version.ref = "flyway" }
|
||||
postgresql = { module = "org.postgresql:postgresql", version.ref = "postgresql" }
|
||||
```
|
||||
|
||||
Append the following to `[plugins]`:
|
||||
|
||||
```toml
|
||||
spotless = { id = "com.diffplug.spotless", version.ref = "spotless" }
|
||||
flywayPlugin = { id = "org.flywaydb.flyway", version.ref = "flyway" }
|
||||
```
|
||||
|
||||
IMPORTANT invariants:
|
||||
- `koin-core`, `koin-compose`, `koin-compose-viewmodel`, `koin-android` have NO `version.ref` — they are BOM-managed by `koin-bom`.
|
||||
- `kotlin-test` is already in the catalog (line 22) — do NOT re-add.
|
||||
- Do NOT bump any existing version alias (kotlin, ktor, composeMultiplatform, logback, etc.).
|
||||
- The `koin-composeViewmodel` alias name uses camelCase (Gradle converts dashes-to-dots for accessors, but camelCase preserves `koin.composeViewmodel.get()`).
|
||||
</action>
|
||||
<verify>
|
||||
<automated>grep -E '^(flyway|kermit|koin|kotlinx-serialization|postgresql|spotless)\s*=' gradle/libs.versions.toml | wc -l | grep -q '^6$' && grep -E '^koin-bom\s*=' gradle/libs.versions.toml && grep -E '^koin-core\s*=' gradle/libs.versions.toml && grep -E '^koin-compose\s*=' gradle/libs.versions.toml && grep -E '^koin-composeViewmodel\s*=' gradle/libs.versions.toml && grep -E '^koin-android\s*=' gradle/libs.versions.toml && grep -E '^kermit\s*=' gradle/libs.versions.toml && grep -E '^ktor-serverContentNegotiation\s*=' gradle/libs.versions.toml && grep -E '^ktor-serializationKotlinxJson\s*=' gradle/libs.versions.toml && grep -E '^flyway-core\s*=' gradle/libs.versions.toml && grep -E '^flyway-database-postgresql\s*=' gradle/libs.versions.toml && grep -E '^postgresql\s*=' gradle/libs.versions.toml && grep -E '^spotless\s*=\s*\{\s*id\s*=' gradle/libs.versions.toml && grep -E '^flywayPlugin\s*=\s*\{\s*id\s*=' gradle/libs.versions.toml</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `grep -E '^kotlin\s*=\s*"2\.3\.20"' gradle/libs.versions.toml` returns exactly 1 line (existing, unmodified)
|
||||
- `grep -E '^ktor\s*=\s*"3\.4\.1"' gradle/libs.versions.toml` returns exactly 1 line (existing, unmodified)
|
||||
- `grep -E '^koin\s*=\s*"4\.2\.1"' gradle/libs.versions.toml` returns exactly 1 line (new)
|
||||
- `grep -E '^kermit\s*=\s*"2\.1\.0"' gradle/libs.versions.toml` returns exactly 1 line (new)
|
||||
- `grep -E '^spotless\s*=\s*"8\.4\.0"' gradle/libs.versions.toml` returns exactly 1 line (new)
|
||||
- `grep -E '^flyway\s*=\s*"12\.4\.0"' gradle/libs.versions.toml` returns exactly 1 line (new)
|
||||
- `grep -E '^postgresql\s*=\s*"42\.7\.10"' gradle/libs.versions.toml` returns exactly 1 line (new)
|
||||
- `grep -c '^koin-' gradle/libs.versions.toml` returns `5` (koin-bom, koin-core, koin-compose, koin-composeViewmodel, koin-android)
|
||||
- `grep -c '^flyway-' gradle/libs.versions.toml` returns `2` (flyway-core, flyway-database-postgresql)
|
||||
- `grep -E '^\s*module\s*=\s*"io.insert-koin:koin-core"' gradle/libs.versions.toml` returns 1 line with NO `version.ref` attribute on same line (BOM-managed)
|
||||
</acceptance_criteria>
|
||||
<done>All Phase 1 catalog aliases present; no existing aliases modified; file parses as valid TOML.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Append iOS K/N binary flags to gradle.properties</name>
|
||||
<files>gradle.properties</files>
|
||||
<read_first>
|
||||
- gradle.properties (see current 10-line content)
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-RESEARCH.md lines 1082-1107 (§ `gradle.properties` — iOS binary flags — exact content to append)
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-CONTEXT.md D-18 (INFRA-03, PITFALL #1)
|
||||
- CLAUDE.md convention #7 (iOS binary flags on day 1)
|
||||
</read_first>
|
||||
<action>
|
||||
Append the following 5 lines to `gradle.properties` exactly as shown (including the blank separator line and both comment lines). Do NOT modify any existing line:
|
||||
|
||||
```properties
|
||||
|
||||
# Kotlin/Native iOS (PITFALLS.md #1; D-18; INFRA-03) — MANDATORY day 1
|
||||
# CMS GC + non-main-thread Obj-C deinit to avoid UI-thread pause spikes in Compose Multiplatform.
|
||||
kotlin.native.binary.gc=cms
|
||||
kotlin.native.binary.objcDisposeOnMain=false
|
||||
```
|
||||
|
||||
IMPORTANT:
|
||||
- Place AT THE END of the file (append). The existing `android.useAndroidX=true` stays as the last non-iOS line.
|
||||
- Use EXACTLY the property keys `kotlin.native.binary.gc` and `kotlin.native.binary.objcDisposeOnMain`. Do not add quotes, spaces, or alternate spellings (the K/N compiler reads these keys literally).
|
||||
- Value `cms` is lowercase. Value `false` is lowercase.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>grep -E '^kotlin\.native\.binary\.gc=cms$' gradle.properties | wc -l | grep -q '^1$' && grep -E '^kotlin\.native\.binary\.objcDisposeOnMain=false$' gradle.properties | wc -l | grep -q '^1$'</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `grep -cE '^kotlin\.native\.binary\.gc=cms$' gradle.properties` returns `1`
|
||||
- `grep -cE '^kotlin\.native\.binary\.objcDisposeOnMain=false$' gradle.properties` returns `1`
|
||||
- `grep -c '^kotlin\.code\.style=official$' gradle.properties` returns `1` (unmodified existing)
|
||||
- `grep -c '^android\.useAndroidX=true$' gradle.properties` returns `1` (unmodified existing)
|
||||
- No duplicate of either flag (run grep twice — expect `1` each time, not `2`)
|
||||
</acceptance_criteria>
|
||||
<done>Both iOS K/N flags present once; original 10 lines unchanged.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Create verify-*.sh invariant scripts under tools/</name>
|
||||
<files>tools/verify-no-version-literals.sh, tools/verify-shared-pure.sh, tools/verify-ios-flags.sh</files>
|
||||
<read_first>
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-RESEARCH.md lines 1174-1218 (§ tools/verify-*.sh — canonical shell sketches)
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-PATTERNS.md lines 1174-1218 (same scripts, same content — Pattern Map confirms no in-repo analog)
|
||||
- .planning/phases/01-project-infrastructure-module-wiring/01-VALIDATION.md lines 62-79 (Wave 0 Requirements — these three scripts gate every task's `<automated>` check)
|
||||
</read_first>
|
||||
<action>
|
||||
Create the three executable bash scripts under `tools/` (create the directory — it does not exist yet). Each must be marked executable (`chmod +x`).
|
||||
|
||||
**File 1: `tools/verify-no-version-literals.sh`** (enforces D-09 / INFRA-01 SC#2):
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env bash
|
||||
# Enforces INFRA-01 SC#2 / D-09: no literal version strings outside catalog.
|
||||
# Scans every *.gradle.kts for numeric version literals (e.g. version = "1.2.3"),
|
||||
# excluding build-logic/build.gradle.kts which needs literal asDependency() coordinates.
|
||||
set -euo pipefail
|
||||
VIOLATIONS=$(grep -rn -E 'version[[:space:]]*=[[:space:]]*"[0-9]' --include='*.gradle.kts' . 2>/dev/null | grep -v 'build-logic/build.gradle.kts' || true)
|
||||
if [ -n "$VIOLATIONS" ]; then
|
||||
echo "ERROR: version literals found outside catalog:" >&2
|
||||
echo "$VIOLATIONS" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "OK: no version literals outside catalog."
|
||||
```
|
||||
|
||||
**File 2: `tools/verify-shared-pure.sh`** (enforces INFRA-06 / D-19):
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env bash
|
||||
# Enforces INFRA-06 / D-19: shared/commonMain must not import Ktor, Compose, SQLDelight.
|
||||
# Runs grep against shared/src/commonMain/ only. Allowed imports: kotlin.*, kotlinx.serialization, kotlinx.datetime.
|
||||
set -euo pipefail
|
||||
if [ ! -d shared/src/commonMain ]; then
|
||||
echo "OK: shared/src/commonMain does not exist yet (pre-scaffold)."
|
||||
exit 0
|
||||
fi
|
||||
VIOLATIONS=$(grep -rn -E '^import[[:space:]]+(io\.ktor|androidx\.compose|org\.jetbrains\.compose|app\.cash\.sqldelight)' shared/src/commonMain/ 2>/dev/null || true)
|
||||
if [ -n "$VIOLATIONS" ]; then
|
||||
echo "ERROR: shared/commonMain has forbidden imports:" >&2
|
||||
echo "$VIOLATIONS" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "OK: shared/commonMain is pure."
|
||||
```
|
||||
|
||||
**File 3: `tools/verify-ios-flags.sh`** (enforces INFRA-03 / D-18):
|
||||
|
||||
```sh
|
||||
#!/usr/bin/env bash
|
||||
# Enforces INFRA-03 / D-18: iOS K/N flags present in gradle.properties.
|
||||
set -euo pipefail
|
||||
grep -q '^kotlin\.native\.binary\.gc=cms$' gradle.properties || { echo "MISSING: kotlin.native.binary.gc=cms" >&2; exit 1; }
|
||||
grep -q '^kotlin\.native\.binary\.objcDisposeOnMain=false$' gradle.properties || { echo "MISSING: kotlin.native.binary.objcDisposeOnMain=false" >&2; exit 1; }
|
||||
echo "OK: iOS binary flags present."
|
||||
```
|
||||
|
||||
After writing all three files, run: `chmod +x tools/verify-no-version-literals.sh tools/verify-shared-pure.sh tools/verify-ios-flags.sh`.
|
||||
|
||||
IMPORTANT:
|
||||
- Use `#!/usr/bin/env bash` (not `#!/bin/sh`) — `set -euo pipefail` requires bash semantics.
|
||||
- `tools/verify-shared-pure.sh` deliberately returns 0 if `shared/src/commonMain` does not exist (pre-scaffold state). This lets Plan 07 run the script before Plan 07 itself creates the scaffold.
|
||||
- `tools/verify-no-version-literals.sh` excludes `build-logic/build.gradle.kts` (its `asDependency()` trick requires literal plugin version coordinates — D-09 acknowledged exception).
|
||||
</action>
|
||||
<verify>
|
||||
<automated>test -x tools/verify-no-version-literals.sh && test -x tools/verify-shared-pure.sh && test -x tools/verify-ios-flags.sh && bash tools/verify-ios-flags.sh && bash tools/verify-shared-pure.sh && bash tools/verify-no-version-literals.sh</automated>
|
||||
</verify>
|
||||
<acceptance_criteria>
|
||||
- `test -f tools/verify-no-version-literals.sh && test -x tools/verify-no-version-literals.sh` succeeds
|
||||
- `test -f tools/verify-shared-pure.sh && test -x tools/verify-shared-pure.sh` succeeds
|
||||
- `test -f tools/verify-ios-flags.sh && test -x tools/verify-ios-flags.sh` succeeds
|
||||
- `bash tools/verify-ios-flags.sh` exits 0 and prints `OK: iOS binary flags present.` (proves Task 2 wrote flags)
|
||||
- `bash tools/verify-shared-pure.sh` exits 0 (current `shared/src/commonMain/kotlin/dev/ulfrx/recipe/` has only Greeting.kt/Platform.kt/Constants.kt — no ktor/compose imports)
|
||||
- `bash tools/verify-no-version-literals.sh` exits 0 (current *.gradle.kts files use `libs.plugins.*` aliases — no literal versions)
|
||||
- Each script has `#!/usr/bin/env bash` as line 1
|
||||
- Each script uses `set -euo pipefail`
|
||||
</acceptance_criteria>
|
||||
<done>Three executable verification scripts exist, each runs green against the current repo state.</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<threat_model>
|
||||
## Trust Boundaries
|
||||
|
||||
| Boundary | Description |
|
||||
|----------|-------------|
|
||||
| developer → Gradle build | Local-only; Gradle reads `libs.versions.toml` + `gradle.properties` verbatim. No untrusted input. |
|
||||
| Gradle → Maven Central + Gradle Plugin Portal | Existing repository declarations in `settings.gradle.kts` (Plan 03 doesn't change them). Pinned versions via catalog reduce supply-chain drift. |
|
||||
|
||||
## STRIDE Threat Register
|
||||
|
||||
| Threat ID | Category | Component | Disposition | Mitigation Plan |
|
||||
|-----------|----------|-----------|-------------|-----------------|
|
||||
| T-01-01-01 | Tampering (supply chain) | `gradle/libs.versions.toml` new entries | mitigate | All new version refs are pinned to specific stable releases (`koin = "4.2.1"`, `kermit = "2.1.0"`, `flyway = "12.4.0"`, `spotless = "8.4.0"`, `postgresql = "42.7.10"`) — no version ranges, no `latest.release`. Gradle verifies SHA-256 via `gradle/verification-metadata.xml` if enabled in later phases. |
|
||||
| T-01-01-02 | Tampering | `tools/*.sh` scripts | accept | Scripts live in repo and run locally; their only effect is exit 0/1. Read `gradle.properties` and `*.gradle.kts` only — no network I/O, no write. Risk = low. |
|
||||
| T-01-01-03 | Information Disclosure | `gradle.properties` iOS flags | accept | Flag values (`cms`, `false`) are build configuration, not secrets. Public in every iOS KMP tutorial. |
|
||||
| T-01-01-04 | Denial of Service | wrong catalog syntax breaks build | mitigate | Task 1 `<acceptance_criteria>` greps for exact alias presence; Wave 2 plans that consume the catalog will fail fast if an alias is misspelled. |
|
||||
</threat_model>
|
||||
|
||||
<verification>
|
||||
Phase-level verification for this plan:
|
||||
- All three `tools/verify-*.sh` scripts run green against the post-plan repo.
|
||||
- `gradle/libs.versions.toml` parses (Gradle will surface a TOML parse error at next `./gradlew` invocation in Plan 02).
|
||||
- `gradle.properties` has exactly two new iOS K/N flag lines and is otherwise byte-identical to its pre-plan content.
|
||||
|
||||
No Gradle build is expected to run fully in this plan — we have not yet scaffolded `build-logic/` (Plan 02) nor refactored modules (Plan 03), so `./gradlew build` would fail to resolve the new library aliases. Catalog additions ARE safe for Gradle configuration though (unused entries are inert).
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- `tools/verify-ios-flags.sh` exits 0
|
||||
- `tools/verify-no-version-literals.sh` exits 0
|
||||
- `tools/verify-shared-pure.sh` exits 0
|
||||
- Catalog contains 6 new `[versions]` keys (flyway, kermit, koin, kotlinx-serialization, postgresql, spotless)
|
||||
- Catalog contains 10 new `[libraries]` entries (5 koin-*, kermit, 2 ktor-*, 2 flyway-*, postgresql)
|
||||
- Catalog contains 2 new `[plugins]` entries (spotless, flywayPlugin)
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/01-project-infrastructure-module-wiring/01-01-SUMMARY.md` recording: catalog entries added (count), gradle.properties append location, shell-script paths, and any deviation from the planned version pins (if Maven Central shows a newer stable, record the downgrade decision).
|
||||
</output>
|
||||
Reference in New Issue
Block a user