Repository navigation
[2G-Bug-03]: Credit habit_completions rows toward evaluate_frequency_step_down "Already done" rate on expired nudges - #197
Merged
Conversation
…ency_step_down (#185) Mirrors D5 from #184 on the step-down surface. For each expired nudge with no response in the LIMIT-14 window, credit the rate if a HabitCompletion row exists for the same date. Completion range is bounded by the scheduled_at span of the fetched notifications, so it adapts naturally to the habit's current frequency. Explicit responses still win: 'Already done' counts on its own, and explicit non-'Already done' responses ('Skip today' etc.) are never overridden. FrequencyStepResult shape unchanged; denominator stays at nudge count. Transitively improves _assess_habit_stability's first criterion for routine-cascade-completed habits — verified via integration test. Duplication with evaluate_graduation (#184) is expected and retained; the shared read_completion_history helper refactor is Wave 3 #186.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Verification
ruff check .— ✅ Pass (All checks passed!)pytest -v— ✅ Pass (1299 passed, 4 skipped)Ran locally against develop HEAD at
2d0a13aimmediately before opening this PR.Summary
evaluate_frequency_step_downnow credits a same-datehabit_completionsrow when an expired nudge in the LIMIT-14 window has no response. This mirrors the D5 fix from #184 on the step-down surface so users whose habits complete via routine cascade (or any non-nudge path) can actually step down from daily nudges — the ADHD quality lens again: multiple low-friction completion paths all feel like "I did it", and scaffolding should fade regardless of which channel recorded the completion.Explicit responses still win.
"Already done"counts on its own (back-compat preserved). An explicit non-"Already done"response (e.g.,"Skip today") is never overridden by a completion row.The completion range is bounded by the
scheduled_atspan of the 14 most recent notifications, so it adapts naturally to the habit's current frequency — a daily habit looks at ~2 weeks of completions; a weekly habit looks at ~14 weeks.FrequencyStepResultshape unchanged; the denominator stays at nudge count (completions do not inflate it)._assess_habit_stability's first OR'd criterion callsevaluate_frequency_step_down, so stacking stability transitively inherits this rate improvement for routine-cascade-completed habits. No local change at that call site; an integration test verifies the transitive effect.Changes
app/services/graduation.py—evaluate_frequency_step_downnow querieshabit_completionsover thescheduled_atspan of the LIMIT-14 window. Thealready_done_countderivation iterates notifications:"Already done"responses count as before; expired notifications withresponse IS NULLcount if a same-date completion exists; all other explicit responses are untouched.FrequencyStepResultshape unchanged.tests/test_graduation.py— newTestEvaluateFrequencyStepDownHybridCreditclass with 7 cases covering: routine-cascade credit, no-credit-without-row, mixed explicit+completion 100%, same-day de-dup, explicit-negative override guard, denominator-invariant guard, and the transitive stacking-stability integration test.How to Verify
git checkout feature/2G-Bug-03-step-down-hybrid-creditruff check .— passes cleanpytest -v tests/test_graduation.py— all 167 graduation tests pass, including the 7 new hybrid-credit testspytest -v— full suite: 1299 passed, 4 skippedDeviations
None. Implementation matches the GitHub issue acceptance criteria and
[2G-03]v2 Amendment 15.Per Wave 2 brief guidance (D7, Wave 3 #186): the hybrid-credit logic here is deliberately inline and near-identical to the #184 implementation on
evaluate_graduation. The duplication is expected and retained — the sharedread_completion_historyhelper refactor lands in Wave 3 as #186.Test Results
```
$ ruff check .
All checks passed!
$ pytest -v
====================== 1299 passed, 4 skipped in 22.91s =======================
```
New tests in
TestEvaluateFrequencyStepDownHybridCredit:test_routine_cascade_completion_credited_toward_step_downtest_no_credit_when_no_completion_row_step_downtest_mixed_response_and_completion_step_downtest_same_day_nudge_and_completion_not_double_countedtest_explicit_negative_response_not_overridden_by_completion_step_downtest_extra_completions_outside_nudge_range_do_not_inflate_denominatortest_stacking_stability_inherits_step_down_rate_changeAll existing step-down and stacking tests continue to pass (AC #8).
Acceptance Checklist
evaluate_frequency_step_downreads bothnotification_queue.response='Already done'andhabit_completionsrows dated to expired-nudge dates"Already done"continues to count regardless of completion-row presence (AC TICKET-03: Alembic setup, ORM models, and initial migration #3, back-compat)"Not yet","Skip today") are NOT overridden by completion rows (AC TICKET-04: CRUD endpoints for Domains and Goals #4)FrequencyStepResultresponse shape unchanged; onlycurrent_rate/recommend_step_downdiffer (AC TICKET-05: CRUD endpoints for Projects and Tasks #5)Closes #185