Bug: Bad reschedule behavior when "ignore reviews before certain date" is on

I read through the Anki code, and there’s a bunch of logic which reschedules cards largely based on the user’s first review:

The problem comes when you ignore reviews before a certain date in the options. Case in point below. In this deck, I have ignored all reviews before 1/1/2022. It is thus treating the first review interval as the the 5/1/2022 one, with an interval of 8.11 years, and rescheduling based on that. This reschedules it with a massive interval of 18 years, even though I just got it wrong a few months ago.

When I use the “ignore reviews before date” option, I am using it primarily because it yields more accurate FSRS parameters (10 years ago I had a more erratic and bad study plan). But when I reschedule, I don’t care if it still uses the first ever review from 10 years ago as a benchmark – and I don’t think anyone else would mind either.

I’m pretty sure this isn’t the case. The card is completely ignored if it had been reviewed before that date. It’s not that a part of the revlog will be ignored, but actually the entire log and card.

That is true when optimizing parameters. My topic though concerns force rescheduling of the cards (either through pressing “Update memory state and reschedule” or having “reschedule cards on change” on in the options). It uses the “starting state” as the first review after the ignore date. I have debugged this with print statements and almost sure this is true. Hence in my revlog up above, the reschedule is >10 years when the last interval was only a few months. It’s because it’s using the 8.11 year interval from 2022 as a first review basis point.


I’ll note that I’ve been able to workaround this by optimizing parameters with the ignore date set, then resetting the ignore date back to 1970 and then force updating the cards. Not ideal though.

I don’t know the code that well, but it’s calling “compute_memory_state” in memory_state.rs, and passing in “ignore_revlogs_before_ms_from_config(&config)” to “single_card_revlog_to_item” when it shouldn’t be

pub fn compute_memory_state(&mut self, card_id: CardId) -> Result<ComputeMemoryStateResponse> {
        // println!("Starting compute_memory_state for card_id: {:?}", card_id);

        let mut card = self.storage.get_card(card_id)?.or_not_found(card_id)?;
        // println!("Retrieved card: {:?}", card);

        let deck_id = card.original_deck_id.or(card.deck_id);
        // println!("Using deck_id: {:?}", deck_id);

        let deck = self.get_deck(deck_id)?.or_not_found(card.deck_id)?;
        // println!("Retrieved deck: {:?}", deck);

        let conf_id = DeckConfigId(deck.normal()?.config_id);
        // println!("Using deck config_id: {:?}", conf_id);

        let config = self
            .storage
            .get_deck_config(conf_id)?
            .or_not_found(conf_id)?;
        // println!("Retrieved deck config: {:?}", config);

        let desired_retention = config.inner.desired_retention;
        let historical_retention = config.inner.historical_retention;
        // println!("Desired retention: {}, Historical retention: {}", desired_retention, historical_retention);

        let fsrs = FSRS::new(Some(config.fsrs_params()))?;
        // println!("FSRS initialized");

        let revlog = self.revlog_for_srs(SearchNode::CardIds(card.id.to_string()))?;
        // println!("Retrieved revlog: {:?}", revlog);

        let item = single_card_revlog_to_item(
            &fsrs,
            revlog,
            self.timing_today()?.next_day_at,
            historical_retention,
            ignore_revlogs_before_ms_from_config(&config)?,
        )?;
        // println!("Generated item from revlog: {:?}", item);

        card.set_memory_state(&fsrs, item, historical_retention)?;
        // println!("Memory state set for card");

        Ok(ComputeMemoryStateResponse {
            state: card.memory_state.map(Into::into),
            desired_retention,
        })
    }
1 Like

I’m sorry, I can’t find the “Ease Factor to Difficulty” section in the manual if that’s what you’re talking about. Could you link me? Edit: I found what you’re talking about and it doesn’t seem to address anything about the “ignore reviews before date” option, which is causing this bug

Unless I’m misusing Anki incredibly, I think this is clearly a bug in some form of another, when rescheduling a card with a 2.83 month interval gives it an interval of 13.3 years (see the revlog I posted above).

I’m 90% sure this issue is due to “starting state”. Starting state should ALWAYS be set based on the ease factor and interval of the first EVER review of a card, NOT the first review of a card after the ignore date.

@L.M.Sherlock How does this sound to you?