Anki Scheduler Fixes: Comprehensive Guide
Let's dive into the nitty-gritty of fixing some critical bugs in an Anki-compatible spaced repetition scheduler. The goal here is to squash those bugs while keeping everything backward compatible. No breaking changes, got it? This means we're preserving existing code, database schemas, and user configurations. Let's get started, guys!
Core Requirements: The Foundation of Our Fixes
The primary objective is to fix the critical bugs without disrupting the existing infrastructure.
Preserve Existing Infrastructure
- Database Integrity: We're talking no touching of database table structures or column names. Seriously, leave them alone.
- Function Signatures: Function signatures and return types? Hands off! We're not changing those.
- API Contracts: Any existing API contracts that other components rely on must remain unbroken. Think of it as a delicate ecosystemβdon't go messing with it.
- Configuration Parameters: All existing configuration parameter names and types must stay the same. We don't want to confuse anyone, do we?
- Test Cases: Ensure all existing test cases continue to pass. This is our safety net.
Critical Bug Fixes Required
Time to roll up our sleeves and tackle those pesky bugs. We'll start with the high-priority ones and work our way down.
Fix Hard-coded Ease Deltas (HIGH PRIORITY)
The Problem: The current calculateAnkiEase
function uses hard-coded -0.15/+0.15 values instead of user-configurable settings. That's a big no-no! We need to make this dynamic.
The Solution:
- Revert to Settings: We need to go back to using
settings.HARD_INTERVAL_FACTOR
,settings.EASY_INTERVAL_FACTOR
, andsettings.LAPSE_EASE_PENALTY
. These are our friends. - Maintain Parameter Names: Keep those existing settings parameter names exactly as they are. No changes allowed!
- Multiplicative Factors: Apply ease changes as multiplicative factors, not additive constants. This is crucial for getting the right behavior.
- Valid Bounds: Ensure ease values stay within the valid range, typically 1.3 to 2.5. We don't want any crazy ease values.
This ensures that the ease values are dynamically adjusted based on user settings, providing a more personalized and effective learning experience. By using multiplicative factors and enforcing valid bounds, we maintain the integrity of the spaced repetition algorithm while adhering to user preferences. The goal here is to make the scheduler smarter and more adaptable.
Fix New Card "Good" Rating Path (HIGH PRIORITY)
The Problem: When a user rates a new card as "Good," it incorrectly jumps to learning step index 1. This is not how it should work. New cards need a little more love before they jump ahead.
The Solution:
- New Card Logic: For new cards, ratings 0 (Again), 1 (Hard), and 2 (Good) should always go to learning step 0. No exceptions!
- Easy Rating: Only rating 3 (Easy) should skip learning and go directly to the review state. This is the fast track for those easy-peasy cards.
- Preserve Existing Logic: Maintain existing learning step arrays and indexing logic. We don't want to break anything else while fixing this.
- Maintain Compatibility: Keep things compatible with existing card states. Consistency is key.
By ensuring that new cards rated as "Good" correctly proceed to learning step 0, we're maintaining the integrity of the learning process. This prevents premature advancement and ensures that users have ample opportunity to reinforce their understanding. This fix aligns the scheduler with the intended behavior and supports a more effective learning experience. Maintaining the learning step arrays and indexing logic is crucial for backward compatibility.
Fix Interval Calculation Formula (CRITICAL)
The Problem: The review interval logic has incorrect branching conditions and applies rules too broadly. This can lead to cards being shown too frequently or not frequently enough.
The Solution:
- Exact Anki Algorithm: We need to implement the exact Anki algorithm. No shortcuts here!
- Repetition 1 β interval = 1 day
- Repetition 2 β interval = previousInterval Γ ease
- Repetition > 2 β interval = previousInterval Γ ease Γ intervalModifier
- Hard/Easy Multipliers: Apply hard/easy interval multipliers after the base calculation. Order matters!
- Days-Late Bonus: Add a days-late bonus if applicable. This rewards users for staying on top of their reviews, even if they're a little late.
- Global Interval Modifier: Apply the global interval modifier. This allows for fine-tuning of the scheduling algorithm.
- Clamping: Clamp the interval to reasonable bounds. We don't want intervals that are too short or too long.
- Minimum Interval: Enforce a minimum of
previousInterval + 1
(skip this rule for the rep 1β2 transition only). This prevents intervals from shrinking too much.
This fix ensures that the review intervals are calculated with precision, adhering to the established Anki algorithm. By correctly implementing the repetition-based logic and applying modifiers in the proper sequence, we optimize the scheduling process for maximum retention. The inclusion of a days-late bonus incentivizes timely reviews, further enhancing the learning experience. Clamping intervals and enforcing minimums ensures that the intervals remain within reasonable bounds, preventing scheduling anomalies.
Fix Relearning Step Progression (MEDIUM PRIORITY)
The Problem: The learning step counter isn't properly incremented during relearning. This can cause cards to get stuck in relearning mode or skip steps.
The Solution:
- Again Action: On "Again" during relearning β reset to step 0. Back to basics!
- Hard Action: On "Hard" during relearning β stay at the current step. Keep grinding!
- Good Action: On "Good" during relearning β increment to the next step (or graduate if it's the final step). Progress is good!
- Maintain Arrays: Maintain existing relearning step arrays. Don't mess with what works.
Ensuring proper incrementing and resetting of the learning step counter during relearning is crucial for effective card management. By resetting to step 0 on "Again," staying at the current step on "Hard," and incrementing on "Good," we optimize the relearning process. This fix guarantees that cards progress through the relearning steps as intended, facilitating knowledge reinforcement and retention. Maintaining existing relearning step arrays ensures seamless integration with the current system.
Clean Up Settings Usage (MEDIUM PRIORITY)
The Problem: There's inconsistent parameter naming and usage across ease vs interval calculations. This can lead to confusion and errors.
The Solution:
- EASY_BONUS: Use
EASY_BONUS
for ease modifications (a multiplicative factor for ease changes). - EASY_INTERVAL_FACTOR: Use
EASY_INTERVAL_FACTOR
for interval time multipliers. - No Cross-Contamination: Ensure no cross-contamination between ease and interval calculations. Keep them separate!
- Maintain Names: Maintain all existing setting names for backward compatibility. We don't want to rename variables and cause chaos, do we?
By standardizing the usage of EASY_BONUS
for ease modifications and EASY_INTERVAL_FACTOR
for interval time multipliers, we eliminate confusion and ensure consistency in the scheduling algorithm. Separating ease and interval calculations prevents unintended side effects and maintains the integrity of the system. Preserving all existing setting names guarantees backward compatibility and minimizes disruption. This cleanup contributes to a more robust and maintainable codebase.
Testing Requirements: Ensuring Quality
Now that we've fixed the bugs, we need to make sure everything works as expected. Testing is our friend!
Preserve Existing Tests
All current test cases must continue passing. This is non-negotiable! We're not allowed to break existing functionality.
Add Comprehensive New Test Coverage
We need to add unit tests for various scenarios to ensure our fixes are robust and don't introduce new bugs. Here's what we need to cover:
- New Card Scenarios:
- New β Again (should go to learning step 0)
- New β Hard (should go to learning step 0)
- New β Good (should go to learning step 0)
- New β Easy (should skip to review with an interval based on the easy factor)
- Learning Chain Progression:
- Multi-step learning sequences
- Failures during learning (reset to step 0)
- Graduation from learning to review
- Review Chain Across Multiple Repetitions:
- Rep 1: interval = 1 day
- Rep 2: interval = ease Γ 1
- Rep 3+: interval = previousInterval Γ ease
- Mixed ratings (Again, Hard, Good, Easy) at each repetition
- Late Review Scenarios:
- Cards reviewed late get an appropriate interval bonus
- The bonus calculation doesn't break minimum interval rules
- Edge Cases:
- Ease bounds enforcement
- Interval clamping
- Transition between learning and review states
Implementation Strategy: A Step-by-Step Approach
Let's talk about how we're going to implement these fixes. A well-thought-out strategy is essential for success.
Incremental Approach
- One Bug at a Time: Fix one bug category at a time. Don't try to do everything at once.
- Full Test Suite: Run the full test suite after each fix. This ensures we haven't broken anything.
- Verify No Regressions: Verify that there are no regressions in existing functionality. We want to make things better, not worse.
- Add New Tests: Add new tests to prevent future regressions. This is how we build a robust system.
Code Organization
- Existing Names: Keep existing function names and signatures. We're not renaming anything unless absolutely necessary.
- Helper Functions: Add private helper functions if needed for clarity. Make the code easier to understand.
- Document Changes: Document any behavioral changes in code comments. Explain why you did what you did.
- Error Handling: Maintain existing error handling patterns. Consistency is key.
Configuration Compatibility
- Support Old and New: Support both old and new configuration formats during the transition. Don't force users to upgrade immediately.
- Migration Path: Provide a clear migration path if settings need to change. Make it easy for users to upgrade.
- Default Behavior: Default to existing behavior if new settings are missing. Don't break things if users haven't upgraded yet.
Validation Checklist
Before we call it a day, let's make sure we've covered all our bases.
- All existing tests pass
- All new test scenarios pass
- Configuration parameters work as documented
- No breaking changes to public APIs
- Database operations remain unchanged
- Performance characteristics maintained or improved
- Error handling preserved
- Logging/debugging output remains consistent
Integration Requirements
Database Compatibility
- Card State Fields: Use existing card state fields (
due
,interval
,ease
, etc.). - Data Types and Constraints: Maintain existing data types and constraints.
- Efficient Queries: Ensure queries remain efficient.
UI/UX Compatibility
- Rating Buttons: Rating buttons continue to work as expected.
- Consistent Behavior: Card scheduling behavior feels consistent to users.
- Improvements, Not Disruptions: Any behavioral changes are improvements, not disruptions.
Import/Export Compatibility
- Anki Deck Imports: Maintain compatibility with Anki deck imports.
- Exported Data: Ensure exported data works with standard Anki.
Documentation Updates
- Clear documentation of all fixes applied
- Before/after behavior examples
- Updated configuration parameter descriptions
- Migration notes if any settings changed
Success Criteria
We've hit the jackpot when:
- All bugs listed above are fixed
- Scheduler behavior matches official Anki for equivalent scenarios
- Existing codebase integration remains seamless
- All tests pass (existing + new comprehensive coverage)
- No performance regressions
- User experience is improved, not disrupted