Skip to content

crossday: guard glassbox SWC gate against quantized rhr/temp - #441

Merged
abdulsaheel merged 4 commits into
mainfrom
fix/glassbox-swc-quantum
Sep 19, 2026
Merged

abdulsaheel merged 4 commits into
mainfrom
fix/glassbox-swc-quantum

Conversation

@abdulsaheel

@abdulsaheel abdulsaheel commented Sep 19, 2026 •

Copy link
Copy Markdown
Collaborator

readiness_composite and overreaching_conjunction both already skip naming a driver when the baseline's dispersion is below the input's own measurement quantum (whole-bpm rhr, integer-adc temp). glassBoxReadiness did the same 0.5*scale check on the same two channels crossday_pipeline wires in (_glassInput('rhr', ...), _glassInput('temp', ...)) but never got that guard, so a baseline alternating between two adjacent bpm/adc values could get named a narrative driver off rounding noise.

wires quantum: 1 into both _glassInput calls, matching readiness_composite's quantum on the same channels.

depends on analytics#75 (now merged) — repinned kAnalyticsPin to its merged main sha.

bumps kAlgoVersion 94 -> 95: this changes the stored readiness_glassbox drivers list for real users, so it needs one despite being narrative-only, not a headline-score change. db_serve_version_and_reads_test.dart's pin/version consistency check caught the first version of this PR missing the bump.

golden fixture regenerated, zero diff (this fixture's rhr/temp baseline doesn't hit the quantized-alternating pattern this fix targets, same as analytics#73 earlier).

Summary by Sourcery

Guard cross-day GlassBox readiness drivers against quantized resting-heart-rate measurements and update the supporting analytics revision.

Bug Fixes:

  • Prevent quantized resting-heart-rate baselines from producing spurious GlassBox narrative drivers from rounding noise.

Enhancements:

  • Propagate measurement quantum handling through GlassBox inputs and update the analytics dependency pin to include the corresponding guard.

Chores:

  • Bump the algorithm version to 95 to reflect changes to stored readiness GlassBox driver results.

analytics#75 added GlassBoxInput.quantum to guard the SWC 'worth mentioning'
gate against quantized baselines (same fix #73 already made to
overreaching_conjunction on this same rhr channel). repin + wire quantum:1
on the rhr and temp _glassInput calls, matching readiness_composite's
quantum:1 on the same two channels.

no kAlgoVersion bump: this only changes whether a driver gets NAMED in
glassBoxReadiness's deprecated narrative, not the score.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @abdulsaheel, you've used your own review budget of 250,000 diff characters for the last 7 days.

You can request another review in 6 days and 5 hours by commenting @sourcery-ai review. Upgrade to get a review now.

@sourcery-ai

sourcery-ai Bot commented Sep 19, 2026

Copy link
Copy Markdown
Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

The PR prevents deprecated glassbox narrative drivers for rhr and temperature when baseline dispersion is only quantization noise by passing quantum 1 through crossday_pipeline and pinning the compatible analytics implementation; the headline readiness score and algorithm version remain unchanged.

Sequence diagram for quantization-gated glassbox drivers

sequenceDiagram
    participant Pipeline as crossday_pipeline
    participant Input as _glassInput
    participant Glassbox as glassBoxReadiness
    participant Driver as NarrativeDriver

    Pipeline->>Input: _glassInput('rhr', ..., quantum: 1)
    Pipeline->>Input: _glassInput('temp', ..., quantum: 1)
    Input->>Glassbox: GlassBoxInput(quantum: 1)
    Glassbox->>Glassbox: dispersionBelowQuantum
    alt quantization noise
        Glassbox-->>Driver: skip rhr/temp driver
    else meaningful dispersion
        Glassbox-->>Driver: name narrative driver
    end
Loading

File-Level Changes

Change Details Files
Propagate measurement quantum into glassbox inputs for resting heart rate and temperature.
  • Set quantum to 1 for the rhr and temp glassbox channels.
  • Add an optional quantum parameter to the local glassbox-input helper and pass it to GlassBoxInput.
  • Keep other channels at the existing default behavior.
lib/compute/crossday_pipeline.dart
Upgrade the analytics dependency to the implementation that applies the quantum-aware glassbox SWC gate.
  • Pin analytics to the fixed branch-head commit containing GlassBoxInput.quantum and dispersionBelowQuantum handling.
  • Document the temporary pin and the required re-pin to main after the upstream PR merges.
  • Update the lockfile for the dependency revision.
pubspec.yaml
pubspec.lock

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

Review Change StackReview Change Stack

Warning

Review limit reached

Next included review available in 18 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 4 included reviews currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Repository: OpenStrap/edge/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: d2b0c862-97d2-4e6f-b8da-07bf51547d21

📥 Commits

Reviewing files that changed from the base of the PR and between 4e330d4 and 51f6bd7.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • lib/compute/crossday_pipeline.dart
  • lib/compute/derivation_engine.dart
  • pubspec.yaml

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: OpenStrap/edge/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: bd8c7910-a852-4cf2-b13c-dcbca423ed0f

📥 Commits

Reviewing files that changed from the base of the PR and between 4648966 and 4e330d4.

⛔ Files ignored due to path filters (1)
  • pubspec.lock is excluded by !**/*.lock
📒 Files selected for processing (2)
  • lib/compute/crossday_pipeline.dart
  • pubspec.yaml

Included review availability: Your plan provides up to 4 included reviews per hour; 0 remain after this review.


📝 Walkthrough

Walkthrough

The analytics dependency is repinned to support GlassBoxInput.quantum. The cross-day pipeline forwards this value and sets it to 1 for RHR and skin-temperature inputs.

Changes

GlassBox quantum support

Layer / File(s) Summary
Analytics quantum dependency
pubspec.yaml
The openstrap_analytics dependency is repinned to the revision that provides GlassBoxInput.quantum.
Pipeline quantum wiring
lib/compute/crossday_pipeline.dart
_glassInput accepts and forwards quantum. RHR and skin-temperature inputs pass quantum: 1; other inputs retain the default.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: svssathvik7

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: guarding the GlassBox SWC gate for quantized RHR and temperature inputs.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown
Contributor

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Branch-head pin

The analytics sibling is pinned to a branch-head SHA (2a624b97...) from fix/glassbox-swc-quantum, not a commit on main. Per AGENTS.md §3.6, siblings must be pinned to full commit SHAs on main, never branch refs. While this is a fixed SHA (not a floating ref: main), it is explicitly a pre-merge branch commit. If the upstream branch is force-pushed or rebased before the re-pin happens, the SHA becomes unreachable. More critically, the PR description says "re-pin to main once #75 merges" — this is a known temporary state that is easy to forget, and the repo has a documented history (v43/v46) of exactly this: a changelog citing a sibling fix whose pin never actually contained it. The risk here is that analytics#75 merges with a different final SHA, the re-pin never happens, and pubspec.lock continues resolving the branch-head commit indefinitely.

ref: 2a624b97303f38877841df9068c72a52b67e5dc9
No kAlgoVersion bump

The PR description asserts no kAlgoVersion bump is needed because glassbox is "deprecated" and "narrative-only." However, glassBoxReadiness still produces output that is stored and displayed. If the quantum guard causes a previously-named narrative driver to be suppressed (e.g., RHR no longer named as a driver when baseline alternates 58/59 bpm), that is a change in persisted day_result content for affected days. AGENTS.md §3.4 requires a bump whenever any analytics output changes. The "narrative only, not headline score" argument does not exempt stored narrative fields from the invariant. Without a bump, existing rows computed under the old logic will not be recomputed, leaving stale (potentially misleading) driver attributions in the DB for users who already synced.

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.
final gbTemp = _glassInput(
  'temp',
  _absList(tempList),
  ana.wTemp,
  lowerIsBetter: true,
  quantum: 1,

@github-actions

github-actions Bot commented Sep 19, 2026 •

Copy link
Copy Markdown
Contributor

PR Code Suggestions ✨

Latest suggestions up to 51f6bd7

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
General
Apply quantum guard to respiratory rate input

The comment explains that tempList is already a continuous z-score and needs no
quantum, but _absList folds the sign away — the resulting series is still
continuous. However, gbResp (respiratory rate) is also an integer-quantized
physiological signal (breaths per minute, whole numbers) and is passed without a
quantum argument, leaving it exposed to the same rounding-noise gate failure that
motivated this PR for RHR. Pass quantum: 1 to the gbResp call as well.

lib/compute/crossday_pipeline.dart [188]

-  final gbTemp = _glassInput(
-    'temp',
-    _absList(tempList),
-    ana.wTemp,
+  final gbResp = _glassInput('resp', respList, ana.wResp, lowerIsBetter: true, quantum: 1);
Suggestion importance[1-10]: 4

__

Why: The suggestion raises a valid concern about respiratory rate being integer-quantized (breaths per minute), which could be susceptible to the same rounding-noise issue. However, this is speculative — the PR authors explicitly chose not to add quantum: 1 to gbResp, and the suggestion goes beyond the scope of the PR without strong evidence that respList values are whole-number quantized in the same way as RHR.

Low

Previous suggestions

Suggestions up to commit 385675d
CategorySuggestion                                                                                                                                    Impact
Possible issue
Ensure required parameter is explicitly passed

The comment explains that tempList is already a continuous z-score and needs no
quantum, but _absList folds the sign away — the resulting values are still
continuous floats. However, the lowerIsBetter argument is missing from this call,
which means it falls back to whatever the named parameter default is in _glassInput.
Since lowerIsBetter is required, this would be a compile error — but if the
signature was recently changed to make it optional, verify the correct value (true,
since lower absolute deviation is better) is explicitly passed here as it is for
every other _glassInput call.

lib/compute/crossday_pipeline.dart [196-200]

   final gbTemp = _glassInput(
     'temp',
     _absList(tempList),
     ana.wTemp,
+    lowerIsBetter: true,
Suggestion importance[1-10]: 2

__

Why: The diff only shows the first 4 lines of the gbTemp call; the lowerIsBetter: true argument is almost certainly present in the lines that follow (outside the shown diff hunk). Since lowerIsBetter is required, the code would not compile without it, making this a non-issue in practice.

Low
Suggestions up to commit c1d54dc
CategorySuggestion                                                                                                                                    Impact
Possible issue
Analytics output change requires version bump

Adding quantum: 1 to the RHR glass-box input changes which readiness scores the SWC
gate suppresses — scores that previously fired on rounding noise will now abstain.
This is a change in analytics output (different persisted day_result rows for
affected days), which per invariant §3.4 requires a kAlgoVersion bump so existing
stale rows are recomputed rather than served from cache.

pubspec.yaml [475]

-      # Narrative-only change, no kAlgoVersion bump needed.
+      # kAlgoVersion bump required: the quantum guard changes which readiness
+      # scores are emitted vs. abstained for integer-quantized RHR baselines.
+      # Bump kAlgoVersion in compute/derivation_engine.dart and add a changelog
+      # entry before merging.
Suggestion importance[1-10]: 5

__

Why: This raises a potentially valid concern that adding quantum: 1 to the RHR glass-box input could change analytics output and may require a kAlgoVersion bump. However, the PR explicitly states "Narrative-only change, no kAlgoVersion bump needed," suggesting the author has considered this. The improved_code only replaces a comment with another comment without any code change.

Low
Sibling pinned to unmerged branch head SHA

The comment explicitly states this is pinned to a branch head SHA ("PR open, not yet
merged to main") and instructs to "Re-pin to main once #75 merges." Per invariant
§3.6, siblings must be pinned to full commit SHAs on merged commits, never to a
branch head that can advance. More critically, §3.5 requires that a bump citing a
sibling change be backed by the pin — if this SHA is a branch tip that gets
force-pushed or rebased before the re-pin, the cited fix may silently disappear. The
PR should not land until analytics #75 is merged and the SHA is a stable, merged
commit.

pubspec.yaml [476]

+      # Re-pin this to the merged commit SHA once analytics PR #75 lands on main.
+      # Do not merge edge until that SHA is stable (merged, not a branch head).
       ref: 2a624b97303f38877841df9068c72a52b67e5dc9
Suggestion importance[1-10]: 4

__

Why: The suggestion raises a valid concern about pinning to an unmerged branch head SHA, but the PR comment already explicitly acknowledges this ("PR open, not yet merged to main") and instructs to re-pin once merged. The improved_code only adds comments without changing the actual ref value, making it a documentation-only change with limited actionable impact.

Low
Suggestions up to commit 4e330d4
CategorySuggestion                                                                                                                                    Impact
Possible issue
Wrong quantum applied to continuous temp channel

Skin temperature z-scores are continuous floating-point values (typically in the
range ±3), not integer-quantized like RHR (whole BPM). Passing quantum: 1 to the SWC
gate for temp will suppress real dispersion signals — a 0.3 z-unit shift is
meaningful for temp but would be swallowed by a 1-unit quantum. The quantum for temp
should reflect the actual resolution of the z-score channel (e.g. 0.0 to leave the
gate inactive, or a small value matching the channel's noise floor), not the integer
quantum appropriate for BPM.

lib/compute/crossday_pipeline.dart [191-197]

   final gbTemp = _glassInput(
     'temp',
     _absList(tempList),
     ana.wTemp,
     lowerIsBetter: true,
-    quantum: 1,
   );
Suggestion importance[1-10]: 7

__

Why: This is a valid concern — skin temperature z-scores are continuous floating-point values, and applying quantum: 1 would suppress meaningful sub-unit signals. The improved_code correctly removes the quantum parameter (defaulting to 0), which aligns with the function signature's default of double quantum = 0.

Medium
Pin sibling only to merged commit SHA

The comment explicitly states this is pinned to a branch head SHA ("PR open, not yet
merged to main") and instructs to "Re-pin to main once #75 merges." Per AGENTS.md §3
invariant 6, siblings must be pinned to full commit SHAs of merged commits, never
branch refs or unmerged branch heads. Pinning to an unmerged branch head SHA means
the analytics dependency can be silently replaced if the branch is force-pushed, and
the changelog entry for kAlgoVersion (if added) would reference a commit that may
never land as-is. The comment also says "Narrative-only change, no kAlgoVersion bump
needed" — but adding GlassBoxInput.quantum and wiring it into glassBoxReadiness
changes analytics output, which requires a kAlgoVersion bump per §3 invariant 4.

pubspec.yaml [476]

-      ref: 2a624b97303f38877841df9068c72a52b67e5dc9
+      # Pin only after analytics PR #75 merges to main; use the post-merge SHA.
+      # Also bump kAlgoVersion in derivation_engine.dart — glassBoxReadiness
+      # output changes when quantum gates are active.
+      ref: <post-merge-SHA-of-analytics-main>
Suggestion importance[1-10]: 5

__

Why: The suggestion raises a valid concern about pinning to an unmerged branch SHA, but the PR comment explicitly acknowledges this is temporary and instructs re-pinning after merge. The kAlgoVersion concern is debatable since the comment says "Narrative-only change, no kAlgoVersion bump needed." The improved_code uses a placeholder <post-merge-SHA-of-analytics-main> which isn't actionable code.

Low

skin_temp_z is already a z-score (onehz_pipeline's skinTempZ, computed
against the raw-ADC baseline with its own quantum:1 guard on that raw
dispersion before the z exists) -- continuous, not integer-quantized. Applying
quantum:1 again here stood the units up wrong, unlike readiness_composite's
tempInput which genuinely gets the raw ADC mean. rhr stays quantum:1 (it's
whole-bpm raw). caught by review on #441.
@github-actions

Copy link
Copy Markdown
Contributor

Standalone PR Review

PR-Agent could not safely update the persistent review. This standalone result will not replace the canonical review.

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Branch-head pin

The analytics sibling is pinned to 2a624b97303f38877841df9068c72a52b67e5dc9, which is described as the branch head of fix/glassbox-swc-quantum — not a merged commit on main. Per AGENTS.md §3.6, siblings must be pinned to full commit SHAs (this satisfies that), but §3.5 warns that a bump citing a sibling change must be backed by the pin actually containing the cited change. The PR explicitly acknowledges the branch is not yet merged and plans to re-pin later. The risk is that if the branch is force-pushed or rebased before re-pinning, the SHA becomes stale or unreachable, breaking flutter pub get in CI and for other developers. This is the same class of issue as the v43 changelog/pin mismatch described in AGENTS.md §4.9. The re-pin step needs a tracking mechanism (e.g., a TODO comment with a linked issue) to ensure it actually happens before release.

ref: 2a624b97303f38877841df9068c72a52b67e5dc9
Missing quantum for resp

gbResp is built with _glassInput('resp', respList, ana.wResp, lowerIsBetter: true) and no quantum argument, so it defaults to 0. If respiratory rate is also integer-quantized (whole breaths per minute, as is typical for WHOOP-style devices), the same rounding-noise narrative driver problem that motivated this PR applies equally to the resp channel. The PR fixes rhr and temp but leaves resp unguarded. This is a capability-wired-into-one-call-site-but-not-all-N issue (AGENTS.md §4.7). If resp is indeed integer-quantized, omitting quantum: 1 here is inconsistent with the fix's own rationale.

final gbResp = _glassInput('resp', respList, ana.wResp, lowerIsBetter: true);

updated kAnalyticsPin/pubspec ref from the branch-head pin to the merged
main sha now that analytics#75 landed. also bumping kAlgoVersion since
this changes the stored readiness_glassbox drivers list for real users,
even though it's narrative-only not a headline score change - caught by
db_serve_version_and_reads_test's pin/version consistency check.
@github-actions

Copy link
Copy Markdown
Contributor

Standalone PR Review

PR-Agent could not safely update the persistent review. This standalone result will not replace the canonical review.

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Missing quantum on temp

The PR description and changelog say quantum: 1 is wired into both _glassInput('rhr', ...) and _glassInput('temp', ...). The gbRhr call correctly passes quantum: 1. However, the gbTemp call (which feeds _absList(tempList) — the absolute z-score values) does NOT pass quantum:. The new comment block explicitly argues this is intentional because skin_temp_z is continuous, not integer-quantized. That reasoning is sound for the z-score path, but the PR description says "wires quantum: 1 into both _glassInput calls, matching readiness_composite's quantum on the same channels" — which contradicts the implementation. If the intent is truly no quantum on temp, the PR description is misleading and the changelog entry at 94→95 is inaccurate ("rhr/temp quantum guard"). If the intent is quantum on temp, the code is missing it. This discrepancy should be resolved explicitly to avoid a future re-introduction of the bug on the temp channel.

final gbTemp = _glassInput(
  'temp',
  _absList(tempList),
  ana.wTemp,
  lowerIsBetter: true,
Stale pin comment

The comment block immediately following the new kAnalyticsPin value still says "Repinned to analytics main's tip, which carries BOTH PR #72 (hrv_freq Welch gap guard) and PR #73 (overreachingConjunction rhr quantum guard)" — it does not mention PR #75 (the change this PR is actually about). A reviewer or future engineer checking whether the pin contains the expected fix will find the comment misleading. Per AGENTS.md §3.5, a bump citing a sibling change must be backed by the pin and the comment is the primary audit trail for that verification.

// 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
// fixes are present at this SHA:

@github-actions

Copy link
Copy Markdown
Contributor

Standalone PR Review

PR-Agent could not safely update the persistent review. This standalone result will not replace the canonical review.

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Pin/Changelog Mismatch

The comment block immediately following the new kAnalyticsPin value still says it was "Repinned to analytics main's tip, which carries BOTH PR #72 (hrv_freq Welch gap guard) and PR #73 (overreachingConjunction rhr quantum guard)" — it does not mention PR #75, which is the change this PR is actually pinning. Per AGENTS.md §3.5, a bump citing a sibling change must be backed by the pin, and the changelog must accurately describe what the pin contains. A reviewer or future engineer reading the comment will believe the pin is at the PR #73 tip, not the PR #75 tip, which is exactly the kind of drift that caused the v43 bug (a fix described in the changelog that the pin never actually contained). The comment should be updated to reference PR #75 and the new SHA.

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
// fixes are present at this SHA:
Missing quantum for temp

The PR description and code comment argue that skin_temp_z is already a continuous z-score and therefore does not need quantum: 1. However, readiness_composite's tempInput is described as needing quantum: 1 because it receives the raw ADC mean. The PR description says the glassbox temp channel receives skin_temp_z (already z-scored), not the raw ADC value. If that is correct, omitting quantum here is intentional and fine. But if tempList in any code path is ever the raw ADC mean rather than the z-score (e.g. a future refactor or a different caller), the guard would be silently absent. The comment is the only protection. This is low-severity given the current wiring, but worth confirming that tempList is always skin_temp_z and never the raw ADC value at this call site, since the PR title and description both claim quantum: 1 is wired into "both channels" but the code only wires it into rhr.

final gbTemp = _glassInput(
  'temp',
  _absList(tempList),
  ana.wTemp,
  lowerIsBetter: true,

@abdulsaheel
abdulsaheel merged commit c1a67b3 into main Sep 19, 2026
4 checks passed
@abdulsaheel
abdulsaheel deleted the fix/glassbox-swc-quantum branch September 19, 2026 09:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant