From acdf5ae06dfe93868bb62ca700830d0f2c857614 Mon Sep 17 00:00:00 2001 From: fy59 Date: Fri, 25 Sep 2026 05:00:12 +0200 Subject: [PATCH] chore: open 0.1.7 stabilization --- CHANGELOG.md | 7 +++++++ README.md | 2 +- android/app/build.gradle.kts | 4 ++-- docs/assets/trainlog-badges.svg | 4 ++-- docs/current_state.md | 5 +++-- docs/roadmap.md | 15 +++++++++++++-- meson.build | 2 +- tests/test_sync_deployment_tools.py | 4 ++-- tools/package_sync_candidate.py | 2 +- tui/tests/test_web_server.c | 2 +- 10 files changed, 33 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 833b2cc..473e19e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## Unreleased — 0.1.7 + +Development opened after the stable v0.1.6 release. This line is restricted to +observed bug fixes, regression fixes, directly related small UI corrections, +documentation corrections, robustness, and associated tests. It does not admit +new features, modules, protocols, or speculative refactors. + ## 0.1.6 — 2026-09-25 - Corrected delayed session finalization so a heart-rate capture cannot extend diff --git a/README.md b/README.md index f5a36ab..6b5c448 100644 --- a/README.md +++ b/README.md @@ -231,7 +231,7 @@ chronological detail in the [`CHANGELOG`](CHANGELOG.md). | Boundary | Current state | | ------------------- | --------------------------------------------------------------------------------------------------------- | -| Product | `0.1.6` stable | +| Product | `0.1.7` bugfix-only development; latest stable release `v0.1.6` | | Desktop persistence | SQLite schema v36 | | Android persistence | SQLite schema v33 | | Mobile exchange | V3 active; V1/V2 readable; V4 staged only | diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 1a4be6c..2a6da72 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -44,7 +44,7 @@ val trainlogVersionCode = providers.environmentVariable("TRAINLOG_ANDROID_VERSION_CODE").orNull?.let { raw -> raw.toIntOrNull()?.takeIf { it in 1..Int.MAX_VALUE } ?: throw GradleException("TRAINLOG_ANDROID_VERSION_CODE must be a positive integer") - } ?: 7 + } ?: 8 /* * WHY: a user may need to finish one preserved draft after a completion bug @@ -87,7 +87,7 @@ android { targetSdk = 36 versionCode = trainlogVersionCode - versionName = "0.1.6" + versionName = "0.1.7" buildConfigField("String", "ACTIVE_SESSION_RECOVERY_ID", "\"$recoverySessionId\"") buildConfigField("String", "ACTIVE_SESSION_RECOVERY_ENDED_AT", "\"$recoveryEndedAt\"") testInstrumentationRunner = diff --git a/docs/assets/trainlog-badges.svg b/docs/assets/trainlog-badges.svg index e804505..35314d5 100644 --- a/docs/assets/trainlog-badges.svg +++ b/docs/assets/trainlog-badges.svg @@ -1,6 +1,6 @@ Trainlog technology badges - Local-first, C17, Android, local Web, GPLv3, and development version 0.1.6. + Local-first, C17, Android, local Web, GPLv3, and development version 0.1.7. @@ -32,6 +32,6 @@ - v0.1.6 + 0.1.7 DEV diff --git a/docs/current_state.md b/docs/current_state.md index 94e181b..d98092b 100644 --- a/docs/current_state.md +++ b/docs/current_state.md @@ -132,7 +132,7 @@ parallel implementation of its rules. | Android SQLite | schema v33; v33 makes Sleep revision payload tables append-only; v32 gives every Sleep medication intake a structured `quantity` (1..99), defaults historical rows to 1, and records a distinct quick-publication tip | | Mobile snapshot | V3 active; V1/V2 readable legacy inputs; explicit V4 codec staged, not selected by transport | | Desktop terminal backend | Notcurses only | -| Trainlog product version | `0.1.6` stable, synchronized across Android and desktop; latest stable release: `v0.1.6` | +| Trainlog product version | `0.1.7` bugfix-only development, synchronized across Android and desktop; latest stable release: `v0.1.6` | | Interface language | `TRAINLOG_I18N_V0_1_1=PASS`: French default; English selectable in Settings → Language on both surfaces | | AI history export | `TRAINLOG_AI_EXPORT_V1` active | | AI session proposals | `TRAINLOG_AI_SESSION_DRAFT_V1=VALIDATION_PENDING` | @@ -177,7 +177,7 @@ parallel implementation of its rules. | 0.1.5 validation | `TRAINLOG_0_1_5_VALIDATION_V1=PASS`: native 111/111; Android unit-test task and APK build; Web 191/191 plus typecheck/build; JSON/import, C-format and diff checks pass. Private vc47 preserves real data through schema v32, renders pre-bed medication quantity controls, reconnects the CYCPLUS and presents the multi-night Web Sleep agenda. | | Tomorrow session readiness | `TRAINLOG_TOMORROW_SESSION_CARDIO_READINESS_V1=PASS`: the private vc46 is clean on schema v31 with fresh CYCPLUS BPM and the next Program session is unambiguous; one combined regression proves two ordered occurrences loaded from the synchronized Program, Program provenance, factual timeline/HR ownership, finalization, full generation, desktop import, replay and correlated ACK | | 0.1.6 validation | `TRAINLOG_0_1_6_VALIDATION_V1=PASS`: native Meson 114/114 and Clang ASan/UBSan 114/114; Android 317 tests (312 passed, five documented optional skips), debug APK and signed release APK; Web 32 files / 209 tests plus typecheck/build; JSON/import, changed-C formatting and diff checks pass. | -| Current operational cursor | Stable v0.1.6 closes the Web refinement, Sleep timeline, synchronization recovery and factual session-finalization cycle; subsequent stabilization opens as 0.1.7 after the immutable release tag. | +| Current operational cursor | 0.1.7 stabilization is open after immutable stable v0.1.6. Only observed bug fixes, regression fixes, directly related small UI corrections, documentation corrections, robustness, and associated tests are in scope. | | Sleep awake/selection/PDF refinement | `TRAINLOG_SLEEP_AWAKE_SELECTION_PDF_V1=PASS`: one temporal projection drives agenda and selected HR detail; a separate inclusive night-start date range drives preview/export from the loaded period. The agenda axis and rows share 24 exact hour columns; estimated sleep duration is consistent and remains non-persistent. | | Sleep Réveil interval policy | Android Réveil creates a revisioned 30-minute `long_awake` window; repeated taps extend it and Levé clamps it. The real 2026-09-23 night is causally repaired on Android/desktop and renders two orange intervals in agenda, HR and PDF; Android 307 passed plus five optional skips, and Web 208/208 passed. | | Sleep revision collision recovery | `TRAINLOG_SLEEP_REVISION_COLLISION_RECOVERY_V1=PASS`: one unpublished divergent desktop tip was re-identified without payload loss, the immutable Android identity was restored exactly, and a fresh successor retained the non-conflicting union. The original generation was consumed with a full SQLite ACK; the real 24/09 session, Sleep facts, cardio samples, timeline, feedback, and Program provenance are visible on Desktop/Web. Schema v36/v33 and importer payload checks prevent recurrence. | @@ -514,6 +514,7 @@ unchanged at ten pre-existing errors: one `NewApi`, one `LocalContextConfigurationRead`, and eight bilingual `StringFormatMatches` diagnostics. This UI tranche adds no lint error and changes no lint policy. The stable Android v0.1.6 tag uses `versionName=0.1.6` and public versionCode 7. +The v0.1.7 stabilization source starts at `versionName=0.1.7` and versionCode 8. Private validation builds may still supply only a strictly increasing `versionCode` as a build-time override; that does not create a public release or change schemas and protocols. diff --git a/docs/roadmap.md b/docs/roadmap.md index b3d2671..38f3ac3 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -30,7 +30,7 @@ estimates. ## Current baseline -Stable v0.1.6 is the release baseline for the next stabilization cycle. +Stable v0.1.6 is the release baseline for the v0.1.7 stabilization cycle. Desktop schema v36, Android schema v33, Notcurses, direct `Documents/Trainlog` storage, mobile export V3, Training Knowledge V1, Body Zones V1, Training Feedback V1/V2, STATS V1, and Session Generator V1 are implemented. Session @@ -76,9 +76,20 @@ release closes this implementation cycle without reopening its frozen contracts. ```text -CURRENT_OPERATIONAL_CURSOR=Stable v0.1.6 published; open 0.1.7 stabilization after the immutable release tag. +CURRENT_OPERATIONAL_CURSOR=0.1.7 bugfix-only stabilization open after immutable stable v0.1.6. ``` +### 0.1.7 stabilization scope + +The 0.1.7 line is restricted to observed bug fixes, regression fixes, small UI +inconsistencies directly caused by a bug, documentation corrections, robustness, +and tests associated with those corrections. + +New features, new modules, architectural refactors not required to fix a bug, +protocol evolution, new Android/Web/TUI capabilities, and speculative +optimization are out of scope. Work outside this boundary waits for a later +feature cycle rather than widening 0.1.7. + Sleep Diary V1 stays frozen/readable while active capable peers require `sleep-diary-v2`. The Web’s relative HR rise/fall overlays remain descriptive measured-series presentation only, never inferred sleep states or causes. diff --git a/meson.build b/meson.build index 5bea99e..0638d99 100644 --- a/meson.build +++ b/meson.build @@ -1,7 +1,7 @@ project( 'trainlog', 'c', - version: '0.1.6', + version: '0.1.7', meson_version: '>=1.3.0', default_options: [ 'c_std=c17', diff --git a/tests/test_sync_deployment_tools.py b/tests/test_sync_deployment_tools.py index 9e6edb7..6b60915 100644 --- a/tests/test_sync_deployment_tools.py +++ b/tests/test_sync_deployment_tools.py @@ -76,7 +76,7 @@ class DeploymentToolsTest(unittest.TestCase): ) self.assertEqual(result.returncode, 0, result.stderr) inventory = json.loads((output / "candidate-inventory.json").read_text()) - self.assertEqual(inventory["product_version"], "0.1.6") + self.assertEqual(inventory["product_version"], "0.1.7") self.assertEqual(inventory["desktop_schema"], 36) self.assertEqual(inventory["android_schema"], 32) self.assertIn("session-preparations-v2", inventory["protocols"]) @@ -114,7 +114,7 @@ class DeploymentToolsTest(unittest.TestCase): text=True, ) self.assertEqual(linked.returncode, 0, linked.stderr) - self.assertIn("trainlog 0.1.6", linked.stdout) + self.assertIn("trainlog 0.1.7", linked.stdout) imported = subprocess.run( [ "python3", diff --git a/tools/package_sync_candidate.py b/tools/package_sync_candidate.py index 56fb5ff..baea370 100644 --- a/tools/package_sync_candidate.py +++ b/tools/package_sync_candidate.py @@ -119,7 +119,7 @@ def main() -> int: "source_commit": subprocess.check_output( ["git", "rev-parse", "HEAD"], cwd=ROOT, text=True ).strip(), - "product_version": "0.1.6", + "product_version": "0.1.7", "desktop_schema": 36, "android_schema": 32, "protocols": [ diff --git a/tui/tests/test_web_server.c b/tui/tests/test_web_server.c index 39048a3..8d7ccac 100644 --- a/tui/tests/test_web_server.c +++ b/tui/tests/test_web_server.c @@ -308,7 +308,7 @@ static bool test_http_contract(TrainlogDatabase *database) { CHECK(strstr(response, "Access-Control-Allow-Origin") == NULL); CHECK(strstr(response, "{\"api_version\":1,\"status\":\"ok\",\"product\":\"trainlog\"," - "\"version\":\"0.1.6\"}") != NULL); + "\"version\":\"0.1.7\"}") != NULL); { char token[80]; CHECK(exchange(port,