KMPCharts/.paul/phases
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
..
v0.2.0-plan-SUMMARY.md feat(chart-realtime): v0.3.0 — dirty flag render, targetFps=30, iOS targets, KDoc, README 2026-05-21 11:11:37 +02:00
v0.2.0-plan.md Initial commit: chart-realtime KMP library v0.4.1-SNAPSHOT 2026-05-21 01:48:51 +02:00
v0.3.0-ios-build-plan.md feat(ios): iOS build pipeline + XCFramework, fix K/Native source bugs 2026-05-21 12:45:21 +02:00
v0.4.0-portfolio-hardening-plan.md feat(chart): v0.4.0 portfolio hardening 2026-05-21 16:27:15 +02:00
v0.5.0-architecture-plan.md feat(chart): v0.4.0 portfolio hardening 2026-05-21 16:27:15 +02:00
v1.0.0-public-release-plan.md feat(chart): v0.4.0 portfolio hardening 2026-05-21 16:27:15 +02:00