Hmbown/CodeWhale · error

Compaction coverage floor: prior summaries were duplicated…

Error message

Compaction coverage floor: prior summaries were duplicated; history was not replaced.

What it means

Thrown by validate_survival_contract when a compaction replacement history does not satisfy the survival contract: it must contain exactly one checkpoint receipt (prior summary), and any pinned /anchor text must survive. The 'duplicated' variant fires when more than one prior summary was carried into the replacement, meaning compaction duplicated summaries instead of replacing history. Compaction must swap old history for the replacement, not copy summaries forward multiple times.

Solutions

  1. Fix build_replacement_history so it emits exactly one checkpoint receipt for prior summaries.
  2. Ensure the replacement replaces (not appends to) the summarized history — remove the original summary entries before inserting the new one.
  3. Run the fixture matrix / survival contract tests to confirm exactly one checkpoint survives per replacement.

Example fix

// before
replacement.push(old_summary_receipt);
replacement.push(new_summary_receipt);
// after
replacement.clear_summarized_history();
replacement.push(new_summary_receipt); // single checkpoint receipt
Defensive patterns

Strategy: validation

Validate before calling

let checkpoints = replacement.checkpoint_receipts();
if checkpoints != 1 {
    return Err(format!("replacement must carry exactly 1 checkpoint receipt, got {checkpoints}"));
}

Prevention

When it happens

Trigger: build_replacement_history produced a replacement containing >1 checkpoint receipt while dropping original history; also triggered directly by tests survival_contract_rejects_dropped_anchors_and_receipts and fixture_matrix_enforces_survival_contract to enforce the invariant. Specifically the `checkpoints > 1` branch at last_round.rs:460.

Common situations: A compaction implementation bug that appends prior summaries into the new history alongside the original summary; refactoring compaction logic and accidentally keeping both the old summary entry and a newly generated one; fixtures that assemble replacement histories by concatenation.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/49e5253dfd453242. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/compaction/last_round.rs:460

}

pub(crate) fn validate_survival_contract(
    original: &[Message],
    replacement: &[Message],
    anchors: Option<&str>,
) -> Result<()> {
    validate_last_round_coverage(original, replacement)?;
    let checkpoints = replacement
        .iter()
        .filter(|message| is_compaction_checkpoint_message(message))
        .count();
    if checkpoints == 0 {
        anyhow::bail!(
            "Compaction coverage floor: checkpoint receipt was dropped; history was not replaced."
        );
    }
    if checkpoints > 1 {
        anyhow::bail!(
            "Compaction coverage floor: prior summaries were duplicated; history was not replaced."
        );
    }
    if let Some(anchors) = anchors {
        require_text_survives(replacement, anchors, "pinned /anchor text")?;
    }
    Ok(())
}

pub(super) fn measure_coverage(
    original: &[Message],
    replacement: &[Message],
    path: CompactionPath,
    anchors_chars: usize,
) -> CompactionCoverage {
    let last_round = last_round_slice(replacement);
    CompactionCoverage {
        path,

View on GitHub (pinned to 73e0f67d83)