diff --git a/lib/compute/crossday_pipeline.dart b/lib/compute/crossday_pipeline.dart index fbf0bf9b..b8ac75fb 100644 --- a/lib/compute/crossday_pipeline.dart +++ b/lib/compute/crossday_pipeline.dart @@ -182,11 +182,17 @@ Map buildCrossDayBundle( final gbInputs = []; final gbRmssd = _glassInput('hrv', rmssdList, ana.wHrv, lowerIsBetter: false); if (gbRmssd != null) gbInputs.add(gbRmssd); - final gbRhr = _glassInput('rhr', rhrList, ana.wRhr, lowerIsBetter: true); + final gbRhr = + _glassInput('rhr', rhrList, ana.wRhr, lowerIsBetter: true, quantum: 1); if (gbRhr != null) gbInputs.add(gbRhr); final gbResp = _glassInput('resp', respList, ana.wResp, lowerIsBetter: true); if (gbResp != null) gbInputs.add(gbResp); - // temp: use absolute z so "further from your baseline" is worse. + // temp: use absolute z so "further from your baseline" is worse. `tempList` + // here is `skin_temp_z` — already a z-score against the raw-ADC baseline + // (onehz_pipeline.dart's `skinTempZ`, which has its OWN quantum:1 guard on + // the raw-ADC dispersion before the z is computed at all). It's continuous, + // not integer-quantized, so no quantum here (unlike readiness_composite's + // `tempInput`, which is fed the raw ADC mean and genuinely needs quantum:1). final gbTemp = _glassInput( 'temp', _absList(tempList), @@ -795,6 +801,7 @@ ana.GlassBoxInput? _glassInput( List series, double weight, { required bool lowerIsBetter, + double quantum = 0, }) { if (series.isEmpty || series.last == null) return null; final history = [ @@ -807,6 +814,7 @@ ana.GlassBoxInput? _glassInput( history: history, weight: weight, lowerIsBetter: lowerIsBetter, + quantum: quantum, ); } diff --git a/lib/compute/derivation_engine.dart b/lib/compute/derivation_engine.dart index b0e89730..e0dc49cb 100644 --- a/lib/compute/derivation_engine.dart +++ b/lib/compute/derivation_engine.dart @@ -1690,7 +1690,17 @@ import 'substrate.dart'; // illness_cusum/readiness_composite/event_detection. Without it, a 1bpm rise // could clear the gate and fire the "both facts point the same way" card on // nothing. kAnalyticsPin repinned to analytics PR #73's merged main SHA. -const int kAlgoVersion = 94; +// +// 94 → 95 (`glassBoxReadiness` rhr/temp quantum guard, analytics PR #75): +// same gap as #73, but on the stored "readiness_glassbox" narrative/drivers +// key crossday_pipeline still writes — glassBoxReadiness never gated its +// 0.5*scale rhr/temp standardization with dispersionBelowQuantum, so a +// quantized baseline (e.g. alternating 58/59 bpm) could get named a driver +// off rounding noise. edge's `_glassInput` calls now pass `quantum: 1` on +// both channels. kAnalyticsPin repinned to analytics PR #75's merged main +// SHA. This changes the stored drivers list for real users, so it gets a +// version bump despite being narrative-only, not a headline-score change. +const int kAlgoVersion = 95; /// The sibling SHAs this version was derived against, asserted against /// pubspec.yaml in test/db_serve_version_and_reads_test.dart. /// @@ -1859,7 +1869,7 @@ const int kAlgoVersion = 94; // picking one single-device SHA over the other. Verified: `1cf8e61` (this // branch's own pin) IS an ancestor of `fe1464d` — the wearfit protocol // commit is already folded in, nothing is lost by moving to the tip. -const String kAnalyticsPin = 'eed6dc92375ce1336fc4e31d13a0718f45e163cf'; +const String kAnalyticsPin = '01e8b6e02b2370ae42490a678e6a0a4e3569104c'; // Repinned to analytics main's tip, which carries BOTH PR #72 (hrv_freq // Welch gap guard) and PR #73 (overreachingConjunction rhr quantum guard) — // the two independent kAlgoVersion bumps above (93 and 94). Verified both diff --git a/pubspec.lock b/pubspec.lock index 096af89e..9c9ec0da 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -937,8 +937,8 @@ packages: dependency: "direct main" description: path: "." - ref: eed6dc92375ce1336fc4e31d13a0718f45e163cf - resolved-ref: eed6dc92375ce1336fc4e31d13a0718f45e163cf + ref: "01e8b6e02b2370ae42490a678e6a0a4e3569104c" + resolved-ref: "01e8b6e02b2370ae42490a678e6a0a4e3569104c" url: "https://github.com/OpenStrap/analytics.git" source: git version: "1.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 98fcf3aa..b8b0f444 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -462,7 +462,21 @@ dependencies: # rounding noise. Verified: # `git show eed6dc9:lib/src/onehz/human/overreaching_conjunction.dart | # grep dispersionBelowQuantum` - ref: eed6dc92375ce1336fc4e31d13a0718f45e163cf + # + # analytics PR #75 (MERGED to main @ 01e8b6e): readiness_glassbox's SWC + # gate had the same gap #73 fixed on overreaching_conjunction -- + # glassBoxReadiness does the identical 0.5*scale standardization on the + # same rhr/temp channels edge wires in below (`_glassInput('rhr', ...)` + # / `_glassInput('temp', ...)`), never gated by dispersionBelowQuantum. + # Adds `GlassBoxInput.quantum`. Re-pinned from #75's branch head to main + # now that it's merged. Verified: + # `git show 01e8b6e:lib/src/onehz/human/readiness_glassbox.dart | + # grep dispersionBelowQuantum` + # Changes the stored "readiness_glassbox" drivers list for real users + # (see derivation_engine.dart's 94 -> 95 changelog entry), so this got + # a kAlgoVersion bump despite being narrative-only, not a headline-score + # change. + ref: 01e8b6e02b2370ae42490a678e6a0a4e3569104c # BLE — flutter_blue_plus is the maintained cross-platform GATT client. flutter_blue_plus: ^1.36.8