[Habits] Add Habit Strength Decay & Half-Life Calculator in src/lib/habits/habit-decay.ts
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 88/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- node.js, typescript
Research direction
Create src/lib/habits/habit-decay.ts and tests/habit-decay.test.ts as specified. Start by checking the project’s TypeScript configuration and existing node:test tests, then run the requested test suite and npx tsc --noEmit. Done means the specified decay, floor, status, and validation cases pass with no external dependencies.
Written by the indexing model from the issue text.
Description
🎯 Feature Overview & Context
In PACT OS, users build habit strength through consistent streaks. When check-ins are missed, habits do not instantly reset to zero in human psychology; instead, neurological pathways experience gradual decay modeled by an exponential half-life ($S(t) = S_0 \cdot 2^{-t / t_{1/2}}$). This utility calculates residual habit strength, retention percentage, and status tier to combat the demoralizing "all-or-nothing" psychological pitfall.
🧩 Scope & Deliverables
- Module Implementation: Create
src/lib/habits/habit-decay.ts - Unit Test Suite: Create
tests/habit-decay.test.tsusing nativenode:testandnode:assert/strict.
📐 Specification & Interface Contracts
export interface HabitDecayOptions {
/** Half-life in days before strength decays by 50% (default: 7) */
halfLifeDays?: number;
/** Minimum residual strength floor between 0 and 100 (default: 0) */
minStrengthFloor?: number;
}
export type HabitDecayStatus = 'solid' | 'fading' | 'at_risk' | 'dormant';
export interface HabitDecayAssessment {
/** Current calculated strength score (0.0 to 100.0, rounded to 1 decimal) */
currentStrength: number;
/** Ratio of original strength retained (0.0 to 1.0, 4 decimals) */
retentionFraction: number;
/** Categorized retention status tier */
status: HabitDecayStatus;
/** Guidance recommendation */
recommendation: string;
}
export function calculateHabitStrengthDecay(
initialStrength: number,
daysSinceLastCheckIn: number,
options?: HabitDecayOptions
): HabitDecayAssessment;
Calculation & Decay Rules:
- Decay Formula:
$$\text{rawStrength} = \text{initialStrength} \times 2^{-\frac{\text{daysSinceLastCheckIn}}{\text{halfLifeDays}}}$$ - Floor Clamping:
$$\text{currentStrength} = \text{roundTo1Decimal}(\max(\text{minStrengthFloor}, \min(\text{initialStrength}, \text{rawStrength})))$$ - Retention Fraction:
$$\text{retentionFraction} = \text{initialStrength} === 0 ? 0.0 : \text{roundTo4Decimals}(\text{currentStrength} / \text{initialStrength})$$ - Status Tiers:
currentStrength >= 80:'solid'(e.g."Habit neural pathway is well-preserved.")50 <= currentStrength < 80:'fading'(e.g."Strength is fading. A quick check-in will restore momentum.")20 <= currentStrength < 50:'at_risk'(e.g."High risk of habit drop-off. Initiate a two-minute comeback.")currentStrength < 20:'dormant'(e.g."Habit has become dormant. Re-anchor with a tiny trigger.")
- Validation:
- Throws
TypeErrorifinitialStrengthordaysSinceLastCheckInis not a finite number. - Throws
RangeErrorifinitialStrength < 0or> 100,daysSinceLastCheckIn < 0,halfLifeDays <= 0, orminStrengthFloor < 0or> 100.
- Throws
🧪 Acceptance Criteria
- TypeScript strict mode passes with 0 errors (
npx tsc --noEmit). - Uses extensionless import in test file (
import { calculateHabitStrengthDecay } from '../src/lib/habits/habit-decay'). - Unit tests cover 0 days elapsed (100% retention), exact half-life boundary (50% retention), long periods, min strength floor, and boundary errors.
- Zero external dependencies added.
- Dominant language
- TypeScript
- Stars
- 5
- Forks
- 7
- Avg merge
- 1d 16h
- Merged PRs (30d)
- 79
Getting set up
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from TheVicky1/Pact_OS
-
area:finance difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
[Text] Add Word-Boundary Preserving Smart Text Truncator in src/lib/text/smart-truncate.tsPossibly taken @rudraparmar76 claimed this today. Openarea:data difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 88/100
TheVicky1/Pact_OS#760 · 1 comment ·
Maintainers usually reply within 1 day
-
area:analytics difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 85/100
Maintainers usually reply within 1 day
-
area:data beginner-friendly difficulty:easy enhancement good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
beginner-friendly difficulty:easy enhancement gamification good first issue
Difficulty 2/5 1-3 hours Newbie friendliness 86/100
Maintainers usually reply within 1 day
All issues in TheVicky1/Pact_OS
Similar issues
-
Waiting for: Product Owner
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
getsentry/sentry-javascript#26203 · 1 comment ·
Maintainers usually reply within 1 day
-
bug
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
bytedance/flowgram.ai#1235 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
devswha/herdr-web-ui#3325 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100