KMPCharts/.paul/phases/v1.0.0-public-release-plan.md
Trentin Davide 0e3b79e2da feat(chart): v0.4.0 portfolio hardening
Ship 15-task plan via kmp-manager group-by-group flow. Library moves
from "prototype" to "senior-engineer-built KMP library" per 3-reviewer
audit (android-reviewer + mobile-performance-reviewer + mobile-architect).

Critical fixes:
- LICENSE MIT (T1) — legal blocker resolved
- explicitApi() Strict + BCV 0.16.3 + klib enabled (T2) — ABI locked
  baseline: chart-realtime.api 161 LOC + chart-realtime.klib.api 211 LOC
- Internal lockdown: CircularBuffer, TieredBuffer, LodDecimator,
  dataVersion, rememberFrameTick (T3)
- kotlinx-datetime 0.6.2 replaces expect/actual currentTimeMs (T4)
  Platform.kt + .android.kt + .ios.kt deleted
- CircularBuffer.writeIndex Int -> Long (T5) — fix 124d overflow @ 200Hz
- Remove !! and @Suppress("UNUSED_EXPRESSION") from commonMain (T6)
- Remove dead config: maxBufferSeconds, xLabelDecimals,
  SignalConfig.label (T7)

Correctness:
- POSITIVE_INFINITY/Float.MAX_VALUE sentinels -> hasData flag (T8)
- Snapshot.withMutableSnapshot + SnapshotApplyConflictException retry
  in push/addSignal/removeSignal (T9)
- dataVersion mutableLongStateOf — Compose-observable, idle = 0
  recompositions (T10) — RenderLoop.kt deleted, targetFps @Deprecated
- Single buffer.snapshot() per signal per frame via SignalEntry
  per-signal scratch arrays (T11) — render-time snapshot cost halved
- M4 binning Tier1/Tier2: firstTs/V + minTs/V + maxTs/V + lastTs/V
  with chronological dedup (T12) — no C7 vertical spike artifacts.
  TIER1/TIER2 CAPACITY x2 -> x4 (TOTAL 77.4k -> 94.8k)
- NaN/Inf/backward-timestamp guards on push (T13) — silent drop,
  per-signal lastPushedTs tracking, KDoc contract

Test gap fill:
- NumberFormat extracted from AxisRenderer to internal object (T14)
  +38 tests pinning rounding/scientific/time-format behavior
- TieredBufferTest +15 tests: tier roll, window-crossing, clear,
  edge cases (T15)
- LodDecimatorTest +10 LTTB-specific branch coverage tests (T15)

Test count: 33 -> 107 (+74).
ABI: 211/272 -> 161/211 LOC (locked, baseline committed).

Deferred to v0.5.0:
- Bump kotlinx-datetime 0.6.2 -> 0.7.x (needs Kotlin 2.1.20+)
- Remove ChartConfig.targetFps (currently @Deprecated, ignored)
- NumberFormat Long overflow @ 1e19 (safe via current routing)
- LTTB upper-bound inclusive vs snapshot half-open semantic mismatch
- Macrobench setup for -30% frame-time verification

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 16:27:15 +02:00

169 lines
7.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# v1.0.0 — Public Release Plan
## Source
Action plan 2026-05-21. Fase 4 "Marketing portfolio".
## Goal
Portare `chart-realtime` da private repo a libreria pubblica consumibile + portfolio piece. Maven Central publish, CI, demo iOS, benchmark numerici vs competitors, README professionale.
## Prereq
v0.4.0 + v0.5.0 shipped.
## Scope IN
- Maven Central / GitHub Packages publishing
- GitHub Actions CI (Android + iOS)
- SwiftUI demo app consuming XCFramework
- Benchmark vs Vico, KoalaPlot, MPAndroidChart numeri reali
- README professionale: screenshot/GIF, badge, limitazioni oneste
- CHANGELOG.md, CONTRIBUTING.md
## Scope OUT
- CocoaPods publication → backlog
- SPM (Swift Package Manager) → backlog
- Wasm/desktop targets → backlog
---
## Tasks
### T1 — Maven Central publishing
- Files: `chart-realtime/build.gradle.kts`, root `build.gradle.kts`, `gradle/libs.versions.toml`
- Action:
- Sonatype OSSRH account setup (manual, user side)
- Plugin `com.vanniktech.maven.publish` (modern Maven Central plugin)
- POM metadata: name, description, url, licenses, developers, scm
- GPG signing
- `dev.dtrentin:chart-realtime:1.0.0` published per Android AAR + iOS klibs + KMP metadata
- Agent: gradle-expert
- Verify: `./gradlew :chart-realtime:publishToMavenCentral` succeed
- User action: registrare dev.dtrentin namespace su Sonatype OSSRH, fornire GPG key
### T2 — GitHub Actions CI (Android + iOS)
- New files:
- `.github/workflows/ci.yml`
- `.github/workflows/release.yml`
- Action:
- PR: `assembleDebug` + `testReleaseUnitTest` + `iosSimulatorArm64Test` su macos-latest runner
- Push master: above + `assembleChartRealtimeXCFramework`
- Tag v* : publish to Maven Central + GitHub release con XCFramework artifact
- Caching gradle + konan
- Agent: gradle-expert
- Verify: PR mostra CI green badge, push tag triggera release
- Pattern: [Vico CI workflow](https://github.com/patrykandpatrick/vico/tree/master/.github/workflows)
### T3 — SwiftUI demo iOS app
- New dir: `samples/ios/`
- Action:
- Xcode project consuming `ChartRealtime.xcframework` da maven local (sviluppo) o CocoaPods/SPM (release)
- SwiftUI view che embedding compose RealtimeChart via `UIKitView`
- Demo: 4 segnali fake (sine, square, noise, triangle) a 200Hz
- Pinch/pan/crosshair test reale
- Agent: ui-impl (manual + scripted)
- Verify: app gira su iPhone simulator, 60fps, no crash
- Justification: senza demo iOS reale "iOS targets" claim è solo build artifact
### T4 — Benchmark vs competitors
- New files:
- `benchmark/build.gradle.kts` (modulo separato)
- `benchmark/src/main/kotlin/.../BufferBench.kt` (microbench JMH)
- `benchmark/src/main/kotlin/.../RenderBench.kt` (androidx.benchmark macrobench)
- `benchmark/RESULTS.md`
- Comparativi:
- Push throughput: chart-realtime vs Vico vs KoalaPlot vs MPAndroidChart
- Frame time 4×200Hz × 60s sustained
- Memory steady-state dopo 30 min
- Agent: mobile-performance-reviewer
- Verify: numeri pubblicati su `benchmark/RESULTS.md`, embedded in README
- Onesto: se chart-realtime perde, dichiararlo. "Library wins at sustained 200Hz multi-signal; loses at static dataset rendering vs Vico."
### T5 — README professionale
- File: `chart-realtime/README.md` (rewrite)
- Sections:
- Banner GIF (chart real-time animato 8 segnali — screen record da demo)
- Badges: Maven Central, CI build, license, Kotlin version, Compose version
- One-line pitch: "Real-time line chart per Compose Multiplatform, ottimizzato per sensor data 200Hz+ multi-signal"
- Why exists (gap nel mercato KMP charts)
- Quick start (gradle dep + 20 LoC example)
- Architecture diagram (TieredBuffer + LodStrategy + interaction state)
- Performance numbers (benchmark.md link)
- Limitations (onestamente: no multi-Y, no log scale, line-only)
- Comparison table vs Vico/KoalaPlot
- Roadmap
- License
- Agent: manager direct (markdown)
- Verify: rendered su GitHub mostra GIF, badge verdi
### T6 — CHANGELOG + CONTRIBUTING + CODE_OF_CONDUCT
- New files:
- `CHANGELOG.md` — Keep-a-changelog format, retroactive entries v0.1-v0.5
- `CONTRIBUTING.md` — how to build, test, submit PR, code style
- `CODE_OF_CONDUCT.md` — Contributor Covenant v2.1
- Agent: manager direct
- Verify: GitHub mostra "Insights → Community Standards" all checkmarks
### T7 — Logo / asset visuale
- New file: `docs/logo.svg`, `docs/banner.png`, `docs/demo.gif`
- Action: logo minimale (single signal sine wave + "ChartRealtime" wordmark). Demo GIF da SwiftUI app o screen recording Android.
- Agent: manager direct (user provides assets or generates with tool)
- Verify: embedded in README, mostra correttamente su GitHub
### T8 — Sample Android app polish
- File: `app/src/main/kotlin/.../MainActivity.kt`
- Action: aggiungi UI controls (slider per Hz, picker per # signals, toggle pan/zoom), make it portfolio-grade demo not just sandbox
- Agent: ui-impl
- Verify: app installa, dimostrazione visiva clean del library capability
### T9 — Performance budget docs
- File: `docs/PERFORMANCE.md`
- Content: "Frame budget per 200Hz × N signals su Pixel 6 / iPhone 13", "Memory cost per signal", "Allocation tracking results", "Battery impact su 1h sessione".
- Source: benchmark dati T4.
- Agent: manager direct
- Verify: claim README sono backed by numeri qui
### T10 — Tag v1.0.0 + GitHub release
- Action manuale:
- Git tag `v1.0.0`, push
- CI release workflow triggers Maven publish
- GitHub release con XCFramework + AAR artifact attachments
- Release notes from CHANGELOG.md v1.0.0 section
- Agent: manager direct (git ops)
- Verify: Maven Central search shows `dev.dtrentin:chart-realtime:1.0.0`, GitHub release page populated
---
## Acceptance v1.0.0
- A1: `dev.dtrentin:chart-realtime:1.0.0` consumibile via `implementation("dev.dtrentin:chart-realtime:1.0.0")` da progetto esterno (Android)
- A2: XCFramework consumibile da SwiftUI demo app (zip artifact in release page)
- A3: CI green su PR + tag triggers Maven publish
- A4: README ha GIF + 5 badge verdi + benchmark numeri
- A5: Benchmark `benchmark/RESULTS.md` confronta vs almeno Vico + KoalaPlot
- A6: SwiftUI iOS demo app gira reale, 60fps
- A7: GitHub Community Standards 100% (LICENSE, README, CONTRIBUTING, CoC, CHANGELOG)
- A8: GitHub release v1.0.0 con artifact attachments
## Parallelism
| Group | Tasks |
|-------|-------|
| P0 | T1 (Maven setup) |
| P1 | T2 (CI), T4 (benchmark) parallel |
| P2 | T3 (SwiftUI demo), T8 (Android demo polish) parallel |
| P3 | T5 (README), T6 (CHANGELOG etc), T9 (perf docs) parallel |
| P4 | T7 (assets) |
| P5 | T10 (release, manual) |
## Estimated agent calls
~10 agent calls + manual ops. ~2-3 giorni full-time.
## Risks
- Sonatype OSSRH account approval può richiedere giorni
- SwiftUI demo richiede Xcode skill non automatizzabili
- Maven Central namespace `dev.dtrentin` deve essere claimed via DNS TXT record o GitHub ownership proof
## Verification commands
```bash
./gradlew :chart-realtime:publishToMavenCentral --dry-run
gh workflow run ci.yml
xcodebuild -project samples/ios/ChartRealtimeDemo.xcodeproj test
gh release create v1.0.0 chart-realtime/build/XCFrameworks/release/ChartRealtime.xcframework.zip --notes-from-tag
```